blob: 0edabe391bbc18219a5ce157f2917cb16f32983c [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
[email protected]034df0f32013-01-07 23:17:4869// Make sure |handle| sets load times correctly when it has been assigned a
70// reused socket.
71void TestLoadTimingInfoConnectedReused(const ClientSocketHandle& handle) {
72 LoadTimingInfo load_timing_info;
73 // Only pass true in as |is_reused|, as in general, HttpStream types should
74 // have stricter concepts of reuse than socket pools.
75 EXPECT_TRUE(handle.GetLoadTimingInfo(true, &load_timing_info));
76
77 EXPECT_EQ(true, load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:1978 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]034df0f32013-01-07 23:17:4879
[email protected]b258e0792013-01-12 07:11:5980 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
81 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:4882}
83
84// Make sure |handle| sets load times correctly when it has been assigned a
[email protected]b021ece62013-06-11 11:06:3385// fresh socket. Also runs TestLoadTimingInfoConnectedReused, since the owner
[email protected]034df0f32013-01-07 23:17:4886// of a connection where |is_reused| is false may consider the connection
87// reused.
88void TestLoadTimingInfoConnectedNotReused(const ClientSocketHandle& handle) {
89 EXPECT_FALSE(handle.is_reused());
90
91 LoadTimingInfo load_timing_info;
92 EXPECT_TRUE(handle.GetLoadTimingInfo(false, &load_timing_info));
93
94 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:1995 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]034df0f32013-01-07 23:17:4896
[email protected]b258e0792013-01-12 07:11:5997 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
98 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
99 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:48100
101 TestLoadTimingInfoConnectedReused(handle);
102}
103
104// Make sure |handle| sets load times correctly, in the case that it does not
105// currently have a socket.
106void TestLoadTimingInfoNotConnected(const ClientSocketHandle& handle) {
107 // Should only be set to true once a socket is assigned, if at all.
108 EXPECT_FALSE(handle.is_reused());
109
110 LoadTimingInfo load_timing_info;
111 EXPECT_FALSE(handle.GetLoadTimingInfo(false, &load_timing_info));
112
113 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19114 EXPECT_EQ(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]034df0f32013-01-07 23:17:48115
[email protected]b258e0792013-01-12 07:11:59116 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
117 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:48118}
119
[email protected]df4b4ef2010-07-12 18:25:21120class TestSocketParams : public base::RefCounted<TestSocketParams> {
[email protected]5acdce12011-03-30 13:00:20121 public:
Chris Watkins7a41d3552017-12-01 02:13:27122 explicit TestSocketParams() = default;
[email protected]51fdc7c2012-04-10 19:19:48123
[email protected]df4b4ef2010-07-12 18:25:21124 private:
125 friend class base::RefCounted<TestSocketParams>;
Chris Watkins7a41d3552017-12-01 02:13:27126 ~TestSocketParams() = default;
[email protected]df4b4ef2010-07-12 18:25:21127};
[email protected]7fc5b09a2010-02-27 00:07:38128typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
[email protected]d80a4322009-08-14 07:07:49129
[email protected]3268023f2011-05-05 00:08:10130class MockClientSocket : public StreamSocket {
[email protected]f6d1d6eb2009-06-24 20:16:09131 public:
[email protected]034df0f32013-01-07 23:17:48132 explicit MockClientSocket(net::NetLog* net_log)
133 : connected_(false),
[email protected]0dc88b32014-03-26 20:12:28134 has_unread_data_(false),
tfarina428341112016-09-22 13:38:20135 net_log_(NetLogWithSource::Make(net_log, NetLogSourceType::SOCKET)),
Charlie Harrison3e4c0622018-05-13 15:44:30136 was_used_to_convey_data_(false) {}
[email protected]f6d1d6eb2009-06-24 20:16:09137
[email protected]0dc88b32014-03-26 20:12:28138 // Sets whether the socket has unread data. If true, the next call to Read()
139 // will return 1 byte and IsConnectedAndIdle() will return false.
140 void set_has_unread_data(bool has_unread_data) {
141 has_unread_data_ = has_unread_data;
142 }
143
[email protected]3f55aa12011-12-07 02:03:33144 // Socket implementation.
dchengb03027d2014-10-21 12:00:20145 int Read(IOBuffer* /* buf */,
146 int len,
Brad Lassey3a814172018-04-26 03:30:21147 CompletionOnceCallback /* callback */) override {
[email protected]0dc88b32014-03-26 20:12:28148 if (has_unread_data_ && len > 0) {
149 has_unread_data_ = false;
150 was_used_to_convey_data_ = true;
151 return 1;
152 }
[email protected]e86df8dc2013-03-30 13:18:28153 return ERR_UNEXPECTED;
[email protected]3f55aa12011-12-07 02:03:33154 }
[email protected]ab838892009-06-30 18:49:05155
[email protected]a2b2cfc2017-12-06 09:06:08156 int Write(
157 IOBuffer* /* buf */,
158 int len,
Brad Lassey3a814172018-04-26 03:30:21159 CompletionOnceCallback /* callback */,
[email protected]a2b2cfc2017-12-06 09:06:08160 const NetworkTrafficAnnotationTag& /*traffic_annotation*/) override {
[email protected]0f873e82010-09-02 16:09:01161 was_used_to_convey_data_ = true;
162 return len;
[email protected]ab838892009-06-30 18:49:05163 }
Avi Drissman13fc8932015-12-20 04:40:46164 int SetReceiveBufferSize(int32_t size) override { return OK; }
165 int SetSendBufferSize(int32_t size) override { return OK; }
[email protected]ab838892009-06-30 18:49:05166
[email protected]dbf036f2011-12-06 23:33:24167 // StreamSocket implementation.
Brad Lassey3a814172018-04-26 03:30:21168 int Connect(CompletionOnceCallback callback) override {
[email protected]dbf036f2011-12-06 23:33:24169 connected_ = true;
170 return OK;
171 }
[email protected]f6d1d6eb2009-06-24 20:16:09172
dchengb03027d2014-10-21 12:00:20173 void Disconnect() override { connected_ = false; }
174 bool IsConnected() const override { return connected_; }
175 bool IsConnectedAndIdle() const override {
[email protected]0dc88b32014-03-26 20:12:28176 return connected_ && !has_unread_data_;
177 }
[email protected]0b7648c2009-07-06 20:14:01178
dchengb03027d2014-10-21 12:00:20179 int GetPeerAddress(IPEndPoint* /* address */) const override {
[email protected]9f864b32010-01-20 15:01:16180 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:09181 }
[email protected]f6d1d6eb2009-06-24 20:16:09182
dchengb03027d2014-10-21 12:00:20183 int GetLocalAddress(IPEndPoint* /* address */) const override {
[email protected]e7f74da2011-04-19 23:49:35184 return ERR_UNEXPECTED;
185 }
186
tfarina428341112016-09-22 13:38:20187 const NetLogWithSource& NetLog() const override { return net_log_; }
[email protected]a2006ece2010-04-23 16:44:02188
dchengb03027d2014-10-21 12:00:20189 bool WasEverUsed() const override { return was_used_to_convey_data_; }
tfarina2846404c2016-12-25 14:31:37190 bool WasAlpnNegotiated() const override { return false; }
dchengb03027d2014-10-21 12:00:20191 NextProto GetNegotiatedProtocol() const override { return kProtoUnknown; }
192 bool GetSSLInfo(SSLInfo* ssl_info) override { return false; }
ttuttle23fdb7b2015-05-15 01:28:03193 void GetConnectionAttempts(ConnectionAttempts* out) const override {
194 out->clear();
195 }
196 void ClearConnectionAttempts() override {}
197 void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
tbansalf82cc8e2015-10-14 20:05:49198 int64_t GetTotalReceivedBytes() const override {
199 NOTIMPLEMENTED();
200 return 0;
201 }
Paul Jensen0f49dec2017-12-12 23:39:58202 void ApplySocketTag(const SocketTag& tag) override {}
[email protected]9b5614a2010-08-25 20:29:45203
[email protected]f6d1d6eb2009-06-24 20:16:09204 private:
205 bool connected_;
[email protected]0dc88b32014-03-26 20:12:28206 bool has_unread_data_;
tfarina428341112016-09-22 13:38:20207 NetLogWithSource net_log_;
[email protected]0f873e82010-09-02 16:09:01208 bool was_used_to_convey_data_;
[email protected]f6d1d6eb2009-06-24 20:16:09209
[email protected]ab838892009-06-30 18:49:05210 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:09211};
212
[email protected]5fc08e32009-07-15 17:09:57213class TestConnectJob;
214
[email protected]f6d1d6eb2009-06-24 20:16:09215class MockClientSocketFactory : public ClientSocketFactory {
216 public:
[email protected]ab838892009-06-30 18:49:05217 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:09218
danakj655b66c2016-04-16 00:51:38219 std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
[email protected]5370c012011-06-29 03:47:04220 DatagramSocket::BindType bind_type,
[email protected]98b0e582011-06-22 14:31:41221 NetLog* net_log,
mikecironef22f9812016-10-04 03:40:19222 const NetLogSource& source) override {
[email protected]98b0e582011-06-22 14:31:41223 NOTREACHED();
danakj655b66c2016-04-16 00:51:38224 return std::unique_ptr<DatagramClientSocket>();
[email protected]98b0e582011-06-22 14:31:41225 }
226
Helen Lid5bb9222018-04-12 15:33:09227 std::unique_ptr<TransportClientSocket> CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07228 const AddressList& addresses,
danakj655b66c2016-04-16 00:51:38229 std::unique_ptr<
230 SocketPerformanceWatcher> /* socket_performance_watcher */,
[email protected]0a0b7682010-08-25 17:08:07231 NetLog* /* net_log */,
mikecironef22f9812016-10-04 03:40:19232 const NetLogSource& /*source*/) override {
[email protected]f6d1d6eb2009-06-24 20:16:09233 allocation_count_++;
Helen Lid5bb9222018-04-12 15:33:09234 return nullptr;
[email protected]f6d1d6eb2009-06-24 20:16:09235 }
236
danakj655b66c2016-04-16 00:51:38237 std::unique_ptr<SSLClientSocket> CreateSSLClientSocket(
238 std::unique_ptr<ClientSocketHandle> transport_socket,
[email protected]4f4de7e62010-11-12 19:55:27239 const HostPortPair& host_and_port,
[email protected]7ab5bbd12010-10-19 13:33:21240 const SSLConfig& ssl_config,
mostynbba063d6032014-10-09 11:01:13241 const SSLClientSocketContext& context) override {
[email protected]f6d1d6eb2009-06-24 20:16:09242 NOTIMPLEMENTED();
danakj655b66c2016-04-16 00:51:38243 return std::unique_ptr<SSLClientSocket>();
[email protected]f6d1d6eb2009-06-24 20:16:09244 }
Matt Menkefd956922019-02-04 23:44:03245
246 std::unique_ptr<SSLClientSocket> CreateSSLClientSocket(
247 std::unique_ptr<StreamSocket> nested_socket,
248 const HostPortPair& host_and_port,
249 const SSLConfig& ssl_config,
250 const SSLClientSocketContext& context) override {
251 NOTIMPLEMENTED();
252 return std::unique_ptr<SSLClientSocket>();
253 }
254
Helen Liac3c51e2018-04-24 00:02:13255 std::unique_ptr<ProxyClientSocket> CreateProxyClientSocket(
256 std::unique_ptr<ClientSocketHandle> transport_socket,
257 const std::string& user_agent,
258 const HostPortPair& endpoint,
Wojciech Dzierżanowski1f823562019-01-18 11:26:00259 const ProxyServer& proxy_server,
Helen Liac3c51e2018-04-24 00:02:13260 HttpAuthController* http_auth_controller,
261 bool tunnel,
262 bool using_spdy,
263 NextProto negotiated_protocol,
Wojciech Dzierżanowski1f823562019-01-18 11:26:00264 ProxyDelegate* proxy_delegate,
Helen Liac3c51e2018-04-24 00:02:13265 bool is_https_proxy,
266 const NetworkTrafficAnnotationTag& traffic_annotation) override {
267 NOTIMPLEMENTED();
268 return nullptr;
269 }
[email protected]f6d1d6eb2009-06-24 20:16:09270
Matt Menke52cd95a2019-02-08 06:16:27271 std::unique_ptr<ProxyClientSocket> CreateProxyClientSocket(
272 std::unique_ptr<StreamSocket> stream_socket,
273 const std::string& user_agent,
274 const HostPortPair& endpoint,
275 const ProxyServer& proxy_server,
276 HttpAuthController* http_auth_controller,
277 bool tunnel,
278 bool using_spdy,
279 NextProto negotiated_protocol,
280 ProxyDelegate* proxy_delegate,
281 bool is_https_proxy,
282 const NetworkTrafficAnnotationTag& traffic_annotation) override {
283 NOTIMPLEMENTED();
284 return nullptr;
285 }
286
[email protected]5fc08e32009-07-15 17:09:57287 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
[email protected]03b7c8c2013-07-20 04:38:55288
[email protected]5fc08e32009-07-15 17:09:57289 void SignalJobs();
290
[email protected]03b7c8c2013-07-20 04:38:55291 void SignalJob(size_t job);
292
293 void SetJobLoadState(size_t job, LoadState load_state);
294
Matt Menke141b87f22019-01-30 02:43:03295 // Sets the HasConnectionEstablished value of the specified job to true,
296 // without invoking the callback.
297 void SetJobHasEstablishedConnection(size_t job);
298
[email protected]f6d1d6eb2009-06-24 20:16:09299 int allocation_count() const { return allocation_count_; }
300
[email protected]f6d1d6eb2009-06-24 20:16:09301 private:
302 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:57303 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09304};
305
[email protected]ab838892009-06-30 18:49:05306class TestConnectJob : public ConnectJob {
307 public:
308 enum JobType {
309 kMockJob,
310 kMockFailingJob,
311 kMockPendingJob,
312 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57313 kMockWaitingJob,
Matt Menkeb57663b32019-03-01 17:17:10314
315 // Certificate errors return a socket in addition to an error code.
316 kMockCertErrorJob,
317 kMockPendingCertErrorJob,
318
[email protected]e60e47a2010-07-14 03:37:18319 kMockAdditionalErrorStateJob,
320 kMockPendingAdditionalErrorStateJob,
[email protected]0dc88b32014-03-26 20:12:28321 kMockUnreadDataJob,
Matt Menkeb57663b32019-03-01 17:17:10322
323 kMockAuthChallengeOnceJob,
324 kMockAuthChallengeTwiceJob,
325 kMockAuthChallengeOnceFailingJob,
326 kMockAuthChallengeTwiceFailingJob,
[email protected]ab838892009-06-30 18:49:05327 };
328
[email protected]994d4932010-07-12 17:55:13329 // The kMockPendingJob uses a slight delay before allowing the connect
330 // to complete.
331 static const int kPendingConnectDelay = 2;
332
[email protected]ab838892009-06-30 18:49:05333 TestConnectJob(JobType job_type,
334 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49335 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34336 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05337 ConnectJob::Delegate* delegate,
[email protected]fd7b7c92009-08-20 19:38:30338 MockClientSocketFactory* client_socket_factory,
[email protected]06650c52010-06-03 00:49:17339 NetLog* net_log)
Matt Menke1a6c92d2019-02-23 00:25:38340 : ConnectJob(request.priority(),
341 timeout_duration,
342 CommonConnectJobParams(
343 group_name,
344 request.socket_tag(),
Matt Menke1a6c92d2019-02-23 00:25:38345 nullptr /* client_socket_factory */,
346 nullptr /* host_resolver */,
347 nullptr /* proxy_delegate */,
348 SSLClientSocketContext(),
349 SSLClientSocketContext(),
350 nullptr /* socket_performance_watcher_factory */,
351 nullptr /* network_quality_estimator */,
352 net_log,
353 nullptr /* websocket_endpoint_lock_manager */),
354 delegate,
355 nullptr /* net_log */,
356 NetLogSourceType::TRANSPORT_CONNECT_JOB,
357 NetLogEventType::TRANSPORT_CONNECT_JOB_CONNECT),
[email protected]2ab05b52009-07-01 23:57:58358 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05359 client_socket_factory_(client_socket_factory),
[email protected]e60e47a2010-07-14 03:37:18360 load_state_(LOAD_STATE_IDLE),
Matt Menke141b87f22019-01-30 02:43:03361 has_established_connection_(false),
[email protected]d5492c52013-11-10 20:44:39362 store_additional_error_state_(false),
mmenked3641e12016-01-28 16:06:15363 weak_factory_(this) {}
[email protected]ab838892009-06-30 18:49:05364
[email protected]974ebd62009-08-03 23:14:34365 void Signal() {
[email protected]e772db3f2010-07-12 18:11:13366 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
[email protected]974ebd62009-08-03 23:14:34367 }
368
[email protected]03b7c8c2013-07-20 04:38:55369 void set_load_state(LoadState load_state) { load_state_ = load_state; }
370
Matt Menke141b87f22019-01-30 02:43:03371 void set_has_established_connection() {
372 DCHECK(!has_established_connection_);
373 has_established_connection_ = true;
374 }
375
[email protected]03b7c8c2013-07-20 04:38:55376 // From ConnectJob:
377
dchengb03027d2014-10-21 12:00:20378 LoadState GetLoadState() const override { return load_state_; }
[email protected]46451352009-09-01 14:54:21379
Matt Menke141b87f22019-01-30 02:43:03380 bool HasEstablishedConnection() const override {
381 return has_established_connection_;
382 }
383
dchengb03027d2014-10-21 12:00:20384 void GetAdditionalErrorState(ClientSocketHandle* handle) override {
[email protected]e60e47a2010-07-14 03:37:18385 if (store_additional_error_state_) {
386 // Set all of the additional error state fields in some way.
387 handle->set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43388 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:45389 info.headers = new HttpResponseHeaders(std::string());
[email protected]8b498692010-07-16 17:11:43390 handle->set_ssl_error_response_info(info);
[email protected]e60e47a2010-07-14 03:37:18391 }
392 }
393
[email protected]974ebd62009-08-03 23:14:34394 private:
[email protected]03b7c8c2013-07-20 04:38:55395 // From ConnectJob:
[email protected]ab838892009-06-30 18:49:05396
dchengb03027d2014-10-21 12:00:20397 int ConnectInternal() override {
[email protected]ab838892009-06-30 18:49:05398 AddressList ignored;
tbansal7b403bcc2016-04-13 22:33:21399 client_socket_factory_->CreateTransportClientSocket(ignored, NULL, NULL,
mikecironef22f9812016-10-04 03:40:19400 NetLogSource());
[email protected]ab838892009-06-30 18:49:05401 switch (job_type_) {
402 case kMockJob:
[email protected]e772db3f2010-07-12 18:11:13403 return DoConnect(true /* successful */, false /* sync */,
Matt Menkeb57663b32019-03-01 17:17:10404 false /* cert_error */);
[email protected]ab838892009-06-30 18:49:05405 case kMockFailingJob:
[email protected]e772db3f2010-07-12 18:11:13406 return DoConnect(false /* error */, false /* sync */,
Matt Menkeb57663b32019-03-01 17:17:10407 false /* cert_error */);
[email protected]ab838892009-06-30 18:49:05408 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57409 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47410
411 // Depending on execution timings, posting a delayed task can result
412 // in the task getting executed the at the earliest possible
413 // opportunity or only after returning once from the message loop and
414 // then a second call into the message loop. In order to make behavior
415 // more deterministic, we change the default delay to 2ms. This should
416 // always require us to wait for the second call into the message loop.
417 //
418 // N.B. The correct fix for this and similar timing problems is to
419 // abstract time for the purpose of unittests. Unfortunately, we have
420 // a lot of third-party components that directly call the various
421 // time functions, so this change would be rather invasive.
skyostil4891b25b2015-06-11 11:43:45422 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05423 FROM_HERE,
kylecharf4fe5172019-02-15 18:53:49424 base::BindOnce(base::IgnoreResult(&TestConnectJob::DoConnect),
425 weak_factory_.GetWeakPtr(), true /* successful */,
Matt Menkeb57663b32019-03-01 17:17:10426 true /* async */, false /* cert_error */),
[email protected]5761ab9c2012-02-04 16:44:53427 base::TimeDelta::FromMilliseconds(kPendingConnectDelay));
[email protected]ab838892009-06-30 18:49:05428 return ERR_IO_PENDING;
429 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57430 set_load_state(LOAD_STATE_CONNECTING);
skyostil4891b25b2015-06-11 11:43:45431 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05432 FROM_HERE,
kylecharf4fe5172019-02-15 18:53:49433 base::BindOnce(base::IgnoreResult(&TestConnectJob::DoConnect),
434 weak_factory_.GetWeakPtr(), false /* error */,
Matt Menkeb57663b32019-03-01 17:17:10435 true /* async */, false /* cert_error */),
[email protected]5761ab9c2012-02-04 16:44:53436 base::TimeDelta::FromMilliseconds(2));
[email protected]ab838892009-06-30 18:49:05437 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57438 case kMockWaitingJob:
[email protected]03b7c8c2013-07-20 04:38:55439 set_load_state(LOAD_STATE_CONNECTING);
[email protected]5fc08e32009-07-15 17:09:57440 client_socket_factory_->WaitForSignal(this);
441 waiting_success_ = true;
442 return ERR_IO_PENDING;
Matt Menkeb57663b32019-03-01 17:17:10443 case kMockCertErrorJob:
[email protected]e772db3f2010-07-12 18:11:13444 return DoConnect(false /* error */, false /* sync */,
Matt Menkeb57663b32019-03-01 17:17:10445 true /* cert_error */);
446 case kMockPendingCertErrorJob:
[email protected]e772db3f2010-07-12 18:11:13447 set_load_state(LOAD_STATE_CONNECTING);
skyostil4891b25b2015-06-11 11:43:45448 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]e772db3f2010-07-12 18:11:13449 FROM_HERE,
kylecharf4fe5172019-02-15 18:53:49450 base::BindOnce(base::IgnoreResult(&TestConnectJob::DoConnect),
451 weak_factory_.GetWeakPtr(), false /* error */,
Matt Menkeb57663b32019-03-01 17:17:10452 true /* async */, true /* cert_error */),
[email protected]5761ab9c2012-02-04 16:44:53453 base::TimeDelta::FromMilliseconds(2));
[email protected]e772db3f2010-07-12 18:11:13454 return ERR_IO_PENDING;
[email protected]e60e47a2010-07-14 03:37:18455 case kMockAdditionalErrorStateJob:
456 store_additional_error_state_ = true;
457 return DoConnect(false /* error */, false /* sync */,
Matt Menkeb57663b32019-03-01 17:17:10458 false /* cert_error */);
[email protected]e60e47a2010-07-14 03:37:18459 case kMockPendingAdditionalErrorStateJob:
460 set_load_state(LOAD_STATE_CONNECTING);
461 store_additional_error_state_ = true;
skyostil4891b25b2015-06-11 11:43:45462 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]e60e47a2010-07-14 03:37:18463 FROM_HERE,
kylecharf4fe5172019-02-15 18:53:49464 base::BindOnce(base::IgnoreResult(&TestConnectJob::DoConnect),
465 weak_factory_.GetWeakPtr(), false /* error */,
Matt Menkeb57663b32019-03-01 17:17:10466 true /* async */, false /* cert_error */),
[email protected]5761ab9c2012-02-04 16:44:53467 base::TimeDelta::FromMilliseconds(2));
[email protected]e60e47a2010-07-14 03:37:18468 return ERR_IO_PENDING;
[email protected]0dc88b32014-03-26 20:12:28469 case kMockUnreadDataJob: {
470 int ret = DoConnect(true /* successful */, false /* sync */,
Matt Menkeb57663b32019-03-01 17:17:10471 false /* cert_error */);
[email protected]0dc88b32014-03-26 20:12:28472 static_cast<MockClientSocket*>(socket())->set_has_unread_data(true);
473 return ret;
474 }
Matt Menkeb57663b32019-03-01 17:17:10475 case kMockAuthChallengeOnceJob:
Matt Menke4b69f932019-03-04 16:20:01476 set_load_state(LOAD_STATE_CONNECTING);
Matt Menkeb57663b32019-03-01 17:17:10477 DoAdvanceAuthChallenge(1, true /* succeed_after_last_challenge */);
478 return ERR_IO_PENDING;
479 case kMockAuthChallengeTwiceJob:
Matt Menke4b69f932019-03-04 16:20:01480 set_load_state(LOAD_STATE_CONNECTING);
Matt Menkeb57663b32019-03-01 17:17:10481 DoAdvanceAuthChallenge(2, true /* succeed_after_last_challenge */);
482 return ERR_IO_PENDING;
483 case kMockAuthChallengeOnceFailingJob:
Matt Menke4b69f932019-03-04 16:20:01484 set_load_state(LOAD_STATE_CONNECTING);
Matt Menkeb57663b32019-03-01 17:17:10485 DoAdvanceAuthChallenge(1, false /* succeed_after_last_challenge */);
486 return ERR_IO_PENDING;
487 case kMockAuthChallengeTwiceFailingJob:
Matt Menke4b69f932019-03-04 16:20:01488 set_load_state(LOAD_STATE_CONNECTING);
Matt Menkeb57663b32019-03-01 17:17:10489 DoAdvanceAuthChallenge(2, false /* succeed_after_last_challenge */);
490 return ERR_IO_PENDING;
[email protected]ab838892009-06-30 18:49:05491 default:
492 NOTREACHED();
danakj655b66c2016-04-16 00:51:38493 SetSocket(std::unique_ptr<StreamSocket>());
[email protected]ab838892009-06-30 18:49:05494 return ERR_FAILED;
495 }
496 }
497
Lily Chen02ef29a2018-11-30 16:31:43498 void ChangePriorityInternal(RequestPriority priority) override {}
499
Matt Menkeb57663b32019-03-01 17:17:10500 int DoConnect(bool succeed, bool was_async, bool cert_error) {
[email protected]e772db3f2010-07-12 18:11:13501 int result = OK;
Matt Menke141b87f22019-01-30 02:43:03502 has_established_connection_ = true;
[email protected]ab838892009-06-30 18:49:05503 if (succeed) {
Matt Menkeb57663b32019-03-01 17:17:10504 SetSocket(std::make_unique<MockClientSocket>(net_log().net_log()));
Bence Békybdbb0e72018-08-07 21:42:59505 socket()->Connect(CompletionOnceCallback());
Matt Menkeb57663b32019-03-01 17:17:10506 } else if (cert_error) {
507 SetSocket(std::make_unique<MockClientSocket>(net_log().net_log()));
508 result = ERR_CERT_COMMON_NAME_INVALID;
[email protected]6e713f02009-08-06 02:56:40509 } else {
[email protected]e772db3f2010-07-12 18:11:13510 result = ERR_CONNECTION_FAILED;
danakj655b66c2016-04-16 00:51:38511 SetSocket(std::unique_ptr<StreamSocket>());
[email protected]ab838892009-06-30 18:49:05512 }
[email protected]2ab05b52009-07-01 23:57:58513
514 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30515 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05516 return result;
517 }
518
Matt Menkeb57663b32019-03-01 17:17:10519 void DoAdvanceAuthChallenge(int remaining_challenges,
520 bool succeed_after_last_challenge) {
521 base::ThreadTaskRunnerHandle::Get()->PostTask(
522 FROM_HERE,
523 base::BindOnce(&TestConnectJob::InvokeNextProxyAuthCallback,
524 weak_factory_.GetWeakPtr(), remaining_challenges,
525 succeed_after_last_challenge));
526 }
527
528 void InvokeNextProxyAuthCallback(int remaining_challenges,
529 bool succeed_after_last_challenge) {
Matt Menke4b69f932019-03-04 16:20:01530 set_load_state(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL);
Matt Menkeb57663b32019-03-01 17:17:10531 if (remaining_challenges == 0) {
532 DoConnect(succeed_after_last_challenge, true /* was_async */,
533 false /* cert_error */);
534 return;
535 }
536
537 // Integration tests make sure HttpResponseInfo and HttpAuthController work.
538 // The auth tests here are just focused on ConnectJob bookkeeping.
539 HttpResponseInfo info;
540 NotifyDelegateOfProxyAuth(
541 info, nullptr /* http_auth_controller */,
542 base::BindOnce(&TestConnectJob::DoAdvanceAuthChallenge,
543 weak_factory_.GetWeakPtr(), remaining_challenges - 1,
544 succeed_after_last_challenge));
545 }
546
[email protected]5fc08e32009-07-15 17:09:57547 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05548 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57549 MockClientSocketFactory* const client_socket_factory_;
[email protected]46451352009-09-01 14:54:21550 LoadState load_state_;
Matt Menke141b87f22019-01-30 02:43:03551 bool has_established_connection_;
[email protected]e60e47a2010-07-14 03:37:18552 bool store_additional_error_state_;
[email protected]ab838892009-06-30 18:49:05553
[email protected]d5492c52013-11-10 20:44:39554 base::WeakPtrFactory<TestConnectJob> weak_factory_;
555
[email protected]ab838892009-06-30 18:49:05556 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
557};
558
[email protected]d80a4322009-08-14 07:07:49559class TestConnectJobFactory
560 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05561 public:
[email protected]034df0f32013-01-07 23:17:48562 TestConnectJobFactory(MockClientSocketFactory* client_socket_factory,
563 NetLog* net_log)
[email protected]ab838892009-06-30 18:49:05564 : job_type_(TestConnectJob::kMockJob),
[email protected]51fdc7c2012-04-10 19:19:48565 job_types_(NULL),
[email protected]034df0f32013-01-07 23:17:48566 client_socket_factory_(client_socket_factory),
Raul Tambre8335a6d2019-02-21 16:57:43567 net_log_(net_log) {}
[email protected]ab838892009-06-30 18:49:05568
Chris Watkins7a41d3552017-12-01 02:13:27569 ~TestConnectJobFactory() override = default;
[email protected]ab838892009-06-30 18:49:05570
571 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
572
[email protected]51fdc7c2012-04-10 19:19:48573 void set_job_types(std::list<TestConnectJob::JobType>* job_types) {
574 job_types_ = job_types;
575 CHECK(!job_types_->empty());
576 }
577
[email protected]974ebd62009-08-03 23:14:34578 void set_timeout_duration(base::TimeDelta timeout_duration) {
579 timeout_duration_ = timeout_duration;
580 }
581
[email protected]3f55aa12011-12-07 02:03:33582 // ConnectJobFactory implementation.
[email protected]83039bb2011-12-09 18:43:55583
danakj655b66c2016-04-16 00:51:38584 std::unique_ptr<ConnectJob> NewConnectJob(
[email protected]ab838892009-06-30 18:49:05585 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49586 const TestClientSocketPoolBase::Request& request,
mostynbba063d6032014-10-09 11:01:13587 ConnectJob::Delegate* delegate) const override {
[email protected]51fdc7c2012-04-10 19:19:48588 EXPECT_TRUE(!job_types_ || !job_types_->empty());
589 TestConnectJob::JobType job_type = job_type_;
590 if (job_types_ && !job_types_->empty()) {
591 job_type = job_types_->front();
592 job_types_->pop_front();
593 }
danakj655b66c2016-04-16 00:51:38594 return std::unique_ptr<ConnectJob>(
595 new TestConnectJob(job_type, group_name, request, timeout_duration_,
596 delegate, client_socket_factory_, net_log_));
[email protected]ab838892009-06-30 18:49:05597 }
598
599 private:
600 TestConnectJob::JobType job_type_;
[email protected]51fdc7c2012-04-10 19:19:48601 std::list<TestConnectJob::JobType>* job_types_;
[email protected]974ebd62009-08-03 23:14:34602 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57603 MockClientSocketFactory* const client_socket_factory_;
[email protected]034df0f32013-01-07 23:17:48604 NetLog* net_log_;
[email protected]ab838892009-06-30 18:49:05605
606 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
607};
608
609class TestClientSocketPool : public ClientSocketPool {
610 public:
[email protected]12322e7e2013-08-15 17:49:26611 typedef TestSocketParams SocketParams;
612
[email protected]ab838892009-06-30 18:49:05613 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53614 int max_sockets,
[email protected]ab838892009-06-30 18:49:05615 int max_sockets_per_group,
[email protected]9bf28db2009-08-29 01:35:16616 base::TimeDelta unused_idle_socket_timeout,
617 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49618 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
Matt Menke833678642019-03-05 22:05:51619 : base_(max_sockets,
rkaplowd90695c2015-03-25 22:12:41620 max_sockets_per_group,
621 unused_idle_socket_timeout,
622 used_idle_socket_timeout,
[email protected]66761b952010-06-25 21:30:38623 connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05624
Chris Watkins7a41d3552017-12-01 02:13:27625 ~TestClientSocketPool() override = default;
[email protected]2431756e2010-09-29 20:26:13626
dchengb03027d2014-10-21 12:00:20627 int RequestSocket(const std::string& group_name,
628 const void* params,
ttuttle859dc7a2015-04-23 19:42:29629 RequestPriority priority,
Paul Jensen8d6f87ec2018-01-13 00:46:54630 const SocketTag& socket_tag,
mmenked3641e12016-01-28 16:06:15631 RespectLimits respect_limits,
dchengb03027d2014-10-21 12:00:20632 ClientSocketHandle* handle,
Bence Béky5a8662b2018-07-03 13:04:03633 CompletionOnceCallback callback,
Matt Menke28ac03e2019-02-25 22:25:50634 const ProxyAuthCallback& proxy_auth_callback,
tfarina428341112016-09-22 13:38:20635 const NetLogWithSource& net_log) override {
[email protected]df4b4ef2010-07-12 18:25:21636 const scoped_refptr<TestSocketParams>* casted_socket_params =
637 static_cast<const scoped_refptr<TestSocketParams>*>(params);
Matt Menke28ac03e2019-02-25 22:25:50638 return base_.RequestSocket(
639 group_name, *casted_socket_params, priority, socket_tag, respect_limits,
640 handle, std::move(callback), proxy_auth_callback, net_log);
[email protected]ab838892009-06-30 18:49:05641 }
642
dchengb03027d2014-10-21 12:00:20643 void RequestSockets(const std::string& group_name,
644 const void* params,
645 int num_sockets,
Charlie Harrison55ce6082018-05-14 02:25:57646 const NetLogWithSource& net_log) override {
[email protected]2c2bef152010-10-13 00:55:03647 const scoped_refptr<TestSocketParams>* casted_params =
648 static_cast<const scoped_refptr<TestSocketParams>*>(params);
649
Charlie Harrison55ce6082018-05-14 02:25:57650 base_.RequestSockets(group_name, *casted_params, num_sockets, net_log);
[email protected]2c2bef152010-10-13 00:55:03651 }
652
rdsmith29dbad12017-02-17 02:22:18653 void SetPriority(const std::string& group_name,
654 ClientSocketHandle* handle,
655 RequestPriority priority) override {
656 base_.SetPriority(group_name, handle, priority);
657 }
658
dchengb03027d2014-10-21 12:00:20659 void CancelRequest(const std::string& group_name,
660 ClientSocketHandle* handle) override {
[email protected]d80a4322009-08-14 07:07:49661 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05662 }
663
dchengb03027d2014-10-21 12:00:20664 void ReleaseSocket(const std::string& group_name,
danakj655b66c2016-04-16 00:51:38665 std::unique_ptr<StreamSocket> socket,
dchengb03027d2014-10-21 12:00:20666 int id) override {
dchengc7eeda422015-12-26 03:56:48667 base_.ReleaseSocket(group_name, std::move(socket), id);
[email protected]a7e38572010-06-07 18:22:24668 }
669
dchengb03027d2014-10-21 12:00:20670 void FlushWithError(int error) override { base_.FlushWithError(error); }
[email protected]ab838892009-06-30 18:49:05671
dchengb03027d2014-10-21 12:00:20672 bool IsStalled() const override { return base_.IsStalled(); }
[email protected]51fdc7c2012-04-10 19:19:48673
dchengb03027d2014-10-21 12:00:20674 void CloseIdleSockets() override { base_.CloseIdleSockets(); }
[email protected]ab838892009-06-30 18:49:05675
xunjieli92feb332017-03-03 17:19:23676 void CloseIdleSocketsInGroup(const std::string& group_name) override {
677 base_.CloseIdleSocketsInGroup(group_name);
678 }
679
dchengb03027d2014-10-21 12:00:20680 int IdleSocketCount() const override { return base_.idle_socket_count(); }
[email protected]ab838892009-06-30 18:49:05681
Raul Tambre8335a6d2019-02-21 16:57:43682 size_t IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]d80a4322009-08-14 07:07:49683 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05684 }
685
dchengb03027d2014-10-21 12:00:20686 LoadState GetLoadState(const std::string& group_name,
687 const ClientSocketHandle* handle) const override {
[email protected]d80a4322009-08-14 07:07:49688 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05689 }
690
dchengb03027d2014-10-21 12:00:20691 void AddHigherLayeredPool(HigherLayeredPool* higher_pool) override {
[email protected]043b68c82013-08-22 23:41:52692 base_.AddHigherLayeredPool(higher_pool);
[email protected]51fdc7c2012-04-10 19:19:48693 }
694
dchengb03027d2014-10-21 12:00:20695 void RemoveHigherLayeredPool(HigherLayeredPool* higher_pool) override {
[email protected]043b68c82013-08-22 23:41:52696 base_.RemoveHigherLayeredPool(higher_pool);
[email protected]51fdc7c2012-04-10 19:19:48697 }
698
danakj655b66c2016-04-16 00:51:38699 std::unique_ptr<base::DictionaryValue> GetInfoAsValue(
[email protected]d4dfdab2011-12-07 16:56:59700 const std::string& name,
Matt Menke833678642019-03-05 22:05:51701 const std::string& type) const override {
[email protected]59d7a5a2010-08-30 16:44:27702 return base_.GetInfoAsValue(name, type);
703 }
704
[email protected]d80a4322009-08-14 07:07:49705 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20706
Raul Tambre8335a6d2019-02-21 16:57:43707 size_t NumNeverAssignedConnectJobsInGroup(
708 const std::string& group_name) const {
Lily Chenecebf932018-11-02 17:15:43709 return base_.NumNeverAssignedConnectJobsInGroup(group_name);
710 }
711
Raul Tambre8335a6d2019-02-21 16:57:43712 size_t NumUnassignedConnectJobsInGroup(const std::string& group_name) const {
[email protected]8159a1c2012-06-07 00:00:10713 return base_.NumUnassignedConnectJobsInGroup(group_name);
714 }
715
Raul Tambre8335a6d2019-02-21 16:57:43716 size_t NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49717 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34718 }
719
[email protected]2c2bef152010-10-13 00:55:03720 int NumActiveSocketsInGroup(const std::string& group_name) const {
721 return base_.NumActiveSocketsInGroup(group_name);
722 }
723
Lily Chenecebf932018-11-02 17:15:43724 bool RequestInGroupWithHandleHasJobForTesting(
725 const std::string& group_name,
726 const ClientSocketHandle* handle) const {
727 return base_.RequestInGroupWithHandleHasJobForTesting(group_name, handle);
728 }
729
[email protected]2abfe90a2010-08-25 17:49:51730 bool HasGroup(const std::string& group_name) const {
731 return base_.HasGroup(group_name);
732 }
733
[email protected]9bf28db2009-08-29 01:35:16734 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
735
[email protected]06d94042010-08-25 01:45:22736 void EnableConnectBackupJobs() { base_.EnableConnectBackupJobs(); }
[email protected]43a21b82010-06-10 21:30:54737
[email protected]ab838892009-06-30 18:49:05738 private:
[email protected]d80a4322009-08-14 07:07:49739 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05740
741 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
742};
743
[email protected]a937a06d2009-08-19 21:19:24744} // namespace
745
[email protected]a937a06d2009-08-19 21:19:24746namespace {
747
[email protected]5fc08e32009-07-15 17:09:57748void MockClientSocketFactory::SignalJobs() {
jdoerrie22a91d8b92018-10-05 08:43:26749 for (auto it = waiting_jobs_.begin(); it != waiting_jobs_.end(); ++it) {
[email protected]5fc08e32009-07-15 17:09:57750 (*it)->Signal();
751 }
752 waiting_jobs_.clear();
753}
754
[email protected]03b7c8c2013-07-20 04:38:55755void MockClientSocketFactory::SignalJob(size_t job) {
756 ASSERT_LT(job, waiting_jobs_.size());
757 waiting_jobs_[job]->Signal();
758 waiting_jobs_.erase(waiting_jobs_.begin() + job);
759}
760
761void MockClientSocketFactory::SetJobLoadState(size_t job,
762 LoadState load_state) {
763 ASSERT_LT(job, waiting_jobs_.size());
764 waiting_jobs_[job]->set_load_state(load_state);
765}
766
Matt Menke141b87f22019-01-30 02:43:03767void MockClientSocketFactory::SetJobHasEstablishedConnection(size_t job) {
768 ASSERT_LT(job, waiting_jobs_.size());
769 waiting_jobs_[job]->set_has_established_connection();
770}
771
Bence Béky98447b12018-05-08 03:14:01772class ClientSocketPoolBaseTest : public TestWithScopedTaskEnvironment {
[email protected]f6d1d6eb2009-06-24 20:16:09773 protected:
Alex Clarke0def2092018-12-10 12:01:45774 ClientSocketPoolBaseTest()
775 : TestWithScopedTaskEnvironment(
776 base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME),
777 params_(new TestSocketParams()) {
[email protected]636b8252011-04-08 19:56:54778 connect_backup_jobs_enabled_ =
779 internal::ClientSocketPoolBaseHelper::connect_backup_jobs_enabled();
780 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(true);
781 }
[email protected]2431756e2010-09-29 20:26:13782
dcheng67be2b1f2014-10-27 21:47:29783 ~ClientSocketPoolBaseTest() override {
[email protected]636b8252011-04-08 19:56:54784 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
785 connect_backup_jobs_enabled_);
786 }
[email protected]c9d6a1d2009-07-14 16:15:20787
[email protected]211d21722009-07-22 15:48:53788 void CreatePool(int max_sockets, int max_sockets_per_group) {
Tarun Bansala7635092019-02-20 10:00:59789 CreatePoolWithIdleTimeouts(max_sockets, max_sockets_per_group,
790 kUnusedIdleSocketTimeout,
791 ClientSocketPool::used_idle_socket_timeout());
[email protected]9bf28db2009-08-29 01:35:16792 }
793
794 void CreatePoolWithIdleTimeouts(
795 int max_sockets, int max_sockets_per_group,
796 base::TimeDelta unused_idle_socket_timeout,
797 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20798 DCHECK(!pool_.get());
[email protected]034df0f32013-01-07 23:17:48799 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_,
800 &net_log_);
[email protected]2431756e2010-09-29 20:26:13801 pool_.reset(new TestClientSocketPool(max_sockets,
802 max_sockets_per_group,
[email protected]2431756e2010-09-29 20:26:13803 unused_idle_socket_timeout,
804 used_idle_socket_timeout,
805 connect_job_factory_));
[email protected]c9d6a1d2009-07-14 16:15:20806 }
[email protected]f6d1d6eb2009-06-24 20:16:09807
mmenked3641e12016-01-28 16:06:15808 int StartRequestWithIgnoreLimits(
[email protected]b021ece62013-06-11 11:06:33809 const std::string& group_name,
810 RequestPriority priority,
mmenked3641e12016-01-28 16:06:15811 ClientSocketPool::RespectLimits respect_limits) {
812 return test_base_.StartRequestUsingPool(pool_.get(), group_name, priority,
813 respect_limits, params_);
[email protected]b021ece62013-06-11 11:06:33814 }
815
816 int StartRequest(const std::string& group_name, RequestPriority priority) {
mmenked3641e12016-01-28 16:06:15817 return StartRequestWithIgnoreLimits(
818 group_name, priority, ClientSocketPool::RespectLimits::ENABLED);
[email protected]f6d1d6eb2009-06-24 20:16:09819 }
820
[email protected]2431756e2010-09-29 20:26:13821 int GetOrderOfRequest(size_t index) const {
822 return test_base_.GetOrderOfRequest(index);
[email protected]f6d1d6eb2009-06-24 20:16:09823 }
824
[email protected]2431756e2010-09-29 20:26:13825 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
826 return test_base_.ReleaseOneConnection(keep_alive);
827 }
828
829 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
830 test_base_.ReleaseAllConnections(keep_alive);
831 }
832
833 TestSocketRequest* request(int i) { return test_base_.request(i); }
834 size_t requests_size() const { return test_base_.requests_size(); }
danakj655b66c2016-04-16 00:51:38835 std::vector<std::unique_ptr<TestSocketRequest>>* requests() {
olli.raula9d66b7d2015-11-23 08:30:42836 return test_base_.requests();
837 }
rdsmith29dbad12017-02-17 02:22:18838 // Only counts the requests that get sockets asynchronously;
839 // synchronous completions are not registered by this count.
[email protected]2431756e2010-09-29 20:26:13840 size_t completion_count() const { return test_base_.completion_count(); }
841
vishal.b62985ca92015-04-17 08:45:51842 TestNetLog net_log_;
[email protected]636b8252011-04-08 19:56:54843 bool connect_backup_jobs_enabled_;
[email protected]f6d1d6eb2009-06-24 20:16:09844 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04845 TestConnectJobFactory* connect_job_factory_;
[email protected]df4b4ef2010-07-12 18:25:21846 scoped_refptr<TestSocketParams> params_;
danakj655b66c2016-04-16 00:51:38847 std::unique_ptr<TestClientSocketPool> pool_;
[email protected]2431756e2010-09-29 20:26:13848 ClientSocketPoolTest test_base_;
[email protected]f6d1d6eb2009-06-24 20:16:09849};
850
[email protected]5fc08e32009-07-15 17:09:57851TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53852 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20853
[email protected]6ecf2b92011-12-15 01:14:52854 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06855 ClientSocketHandle handle;
vishal.b62985ca92015-04-17 08:45:51856 BoundTestNetLog log;
[email protected]034df0f32013-01-07 23:17:48857 TestLoadTimingInfoNotConnected(handle);
[email protected]9e743cd2010-03-16 07:03:53858
Paul Jensen8d6f87ec2018-01-13 00:46:54859 EXPECT_EQ(OK, handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:15860 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:50861 callback.callback(),
862 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
863 log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09864 EXPECT_TRUE(handle.is_initialized());
865 EXPECT_TRUE(handle.socket());
[email protected]034df0f32013-01-07 23:17:48866 TestLoadTimingInfoConnectedNotReused(handle);
867
[email protected]f6d1d6eb2009-06-24 20:16:09868 handle.Reset();
[email protected]034df0f32013-01-07 23:17:48869 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:30870
mmenke43758e62015-05-04 21:09:46871 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40872 log.GetEntries(&entries);
873
874 EXPECT_EQ(4u, entries.size());
mikecirone8b85c432016-09-08 19:11:00875 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKET_POOL));
[email protected]9e743cd2010-03-16 07:03:53876 EXPECT_TRUE(LogContainsEvent(
mikecirone8b85c432016-09-08 19:11:00877 entries, 1, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
878 NetLogEventPhase::NONE));
879 EXPECT_TRUE(LogContainsEvent(entries, 2,
880 NetLogEventType::SOCKET_POOL_BOUND_TO_SOCKET,
881 NetLogEventPhase::NONE));
882 EXPECT_TRUE(LogContainsEndEvent(entries, 3, NetLogEventType::SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09883}
884
[email protected]ab838892009-06-30 18:49:05885TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53886 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20887
[email protected]ab838892009-06-30 18:49:05888 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
vishal.b62985ca92015-04-17 08:45:51889 BoundTestNetLog log;
[email protected]9e743cd2010-03-16 07:03:53890
[email protected]2431756e2010-09-29 20:26:13891 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:52892 TestCompletionCallback callback;
[email protected]e60e47a2010-07-14 03:37:18893 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:13894 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43895 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:45896 info.headers = new HttpResponseHeaders(std::string());
[email protected]2431756e2010-09-29 20:26:13897 handle.set_ssl_error_response_info(info);
Matt Menke28ac03e2019-02-25 22:25:50898 EXPECT_EQ(
899 ERR_CONNECTION_FAILED,
900 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
901 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
902 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
903 log.bound()));
[email protected]2431756e2010-09-29 20:26:13904 EXPECT_FALSE(handle.socket());
905 EXPECT_FALSE(handle.is_ssl_error());
906 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]034df0f32013-01-07 23:17:48907 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:30908
mmenke43758e62015-05-04 21:09:46909 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40910 log.GetEntries(&entries);
911
912 EXPECT_EQ(3u, entries.size());
mikecirone8b85c432016-09-08 19:11:00913 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:17914 EXPECT_TRUE(LogContainsEvent(
mikecirone8b85c432016-09-08 19:11:00915 entries, 1, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
916 NetLogEventPhase::NONE));
917 EXPECT_TRUE(LogContainsEndEvent(entries, 2, NetLogEventType::SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09918}
919
[email protected]211d21722009-07-22 15:48:53920TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
921 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
922
[email protected]9e743cd2010-03-16 07:03:53923 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30924
robpercival214763f2016-07-01 23:27:01925 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
926 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
927 EXPECT_THAT(StartRequest("c", DEFAULT_PRIORITY), IsOk());
928 EXPECT_THAT(StartRequest("d", DEFAULT_PRIORITY), IsOk());
[email protected]211d21722009-07-22 15:48:53929
[email protected]2431756e2010-09-29 20:26:13930 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53931 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13932 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53933
robpercival214763f2016-07-01 23:27:01934 EXPECT_THAT(StartRequest("e", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
935 EXPECT_THAT(StartRequest("f", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
936 EXPECT_THAT(StartRequest("g", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:53937
[email protected]2431756e2010-09-29 20:26:13938 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53939
[email protected]2431756e2010-09-29 20:26:13940 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53941 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13942 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53943
944 EXPECT_EQ(1, GetOrderOfRequest(1));
945 EXPECT_EQ(2, GetOrderOfRequest(2));
946 EXPECT_EQ(3, GetOrderOfRequest(3));
947 EXPECT_EQ(4, GetOrderOfRequest(4));
948 EXPECT_EQ(5, GetOrderOfRequest(5));
949 EXPECT_EQ(6, GetOrderOfRequest(6));
950 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17951
952 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13953 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53954}
955
956TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
957 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
958
[email protected]9e743cd2010-03-16 07:03:53959 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30960
[email protected]211d21722009-07-22 15:48:53961 // Reach all limits: max total sockets, and max sockets per group.
robpercival214763f2016-07-01 23:27:01962 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
963 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
964 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
965 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
[email protected]211d21722009-07-22 15:48:53966
[email protected]2431756e2010-09-29 20:26:13967 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53968 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13969 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53970
971 // Now create a new group and verify that we don't starve it.
robpercival214763f2016-07-01 23:27:01972 EXPECT_THAT(StartRequest("c", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:53973
[email protected]2431756e2010-09-29 20:26:13974 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53975
[email protected]2431756e2010-09-29 20:26:13976 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53977 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13978 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53979
980 EXPECT_EQ(1, GetOrderOfRequest(1));
981 EXPECT_EQ(2, GetOrderOfRequest(2));
982 EXPECT_EQ(3, GetOrderOfRequest(3));
983 EXPECT_EQ(4, GetOrderOfRequest(4));
984 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17985
986 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13987 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53988}
989
990TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
991 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
992
robpercival214763f2016-07-01 23:27:01993 EXPECT_THAT(StartRequest("b", LOWEST), IsOk());
994 EXPECT_THAT(StartRequest("a", MEDIUM), IsOk());
995 EXPECT_THAT(StartRequest("b", HIGHEST), IsOk());
996 EXPECT_THAT(StartRequest("a", LOWEST), IsOk());
[email protected]211d21722009-07-22 15:48:53997
[email protected]2431756e2010-09-29 20:26:13998 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53999 client_socket_factory_.allocation_count());
1000
robpercival214763f2016-07-01 23:27:011001 EXPECT_THAT(StartRequest("c", LOWEST), IsError(ERR_IO_PENDING));
1002 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1003 EXPECT_THAT(StartRequest("b", HIGHEST), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531004
[email protected]2431756e2010-09-29 20:26:131005 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531006
[email protected]2431756e2010-09-29 20:26:131007 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:531008
1009 // First 4 requests don't have to wait, and finish in order.
1010 EXPECT_EQ(1, GetOrderOfRequest(1));
1011 EXPECT_EQ(2, GetOrderOfRequest(2));
1012 EXPECT_EQ(3, GetOrderOfRequest(3));
1013 EXPECT_EQ(4, GetOrderOfRequest(4));
1014
[email protected]ac790b42009-12-02 04:31:311015 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
1016 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:531017 EXPECT_EQ(7, GetOrderOfRequest(5));
1018 EXPECT_EQ(6, GetOrderOfRequest(6));
1019 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171020
1021 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131022 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]211d21722009-07-22 15:48:531023}
1024
rdsmith29dbad12017-02-17 02:22:181025// Test reprioritizing a request before completion doesn't interfere with
1026// its completion.
1027TEST_F(ClientSocketPoolBaseTest, ReprioritizeOne) {
1028 CreatePool(kDefaultMaxSockets, 1);
1029
1030 EXPECT_THAT(StartRequest("a", LOWEST), IsError(OK));
1031 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1032 EXPECT_TRUE(request(0)->handle()->socket());
1033 EXPECT_FALSE(request(1)->handle()->socket());
1034
Lily Chenecebf932018-11-02 17:15:431035 request(1)->handle()->SetPriority(HIGHEST);
rdsmith29dbad12017-02-17 02:22:181036
1037 ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE);
1038
1039 EXPECT_TRUE(request(1)->handle()->socket());
1040}
1041
1042// Reprioritize a request up past another one and make sure that changes the
1043// completion order.
1044TEST_F(ClientSocketPoolBaseTest, ReprioritizeUpReorder) {
1045 CreatePool(kDefaultMaxSockets, 1);
1046
1047 EXPECT_THAT(StartRequest("a", LOWEST), IsError(OK));
1048 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1049 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
1050 EXPECT_TRUE(request(0)->handle()->socket());
1051 EXPECT_FALSE(request(1)->handle()->socket());
1052 EXPECT_FALSE(request(2)->handle()->socket());
1053
1054 request(2)->handle()->SetPriority(HIGHEST);
1055
1056 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1057
1058 EXPECT_EQ(1, GetOrderOfRequest(1));
1059 EXPECT_EQ(3, GetOrderOfRequest(2));
1060 EXPECT_EQ(2, GetOrderOfRequest(3));
1061}
1062
1063// Reprioritize a request without changing relative priorities and check
1064// that the order doesn't change.
1065TEST_F(ClientSocketPoolBaseTest, ReprioritizeUpNoReorder) {
1066 CreatePool(kDefaultMaxSockets, 1);
1067
1068 EXPECT_THAT(StartRequest("a", LOWEST), IsError(OK));
1069 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1070 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1071 EXPECT_TRUE(request(0)->handle()->socket());
1072 EXPECT_FALSE(request(1)->handle()->socket());
1073 EXPECT_FALSE(request(2)->handle()->socket());
1074
1075 request(2)->handle()->SetPriority(MEDIUM);
1076
1077 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1078
1079 EXPECT_EQ(1, GetOrderOfRequest(1));
1080 EXPECT_EQ(2, GetOrderOfRequest(2));
1081 EXPECT_EQ(3, GetOrderOfRequest(3));
1082}
1083
1084// Reprioritize a request past down another one and make sure that changes the
1085// completion order.
1086TEST_F(ClientSocketPoolBaseTest, ReprioritizeDownReorder) {
1087 CreatePool(kDefaultMaxSockets, 1);
1088
1089 EXPECT_THAT(StartRequest("a", LOWEST), IsError(OK));
1090 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
1091 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1092 EXPECT_TRUE(request(0)->handle()->socket());
1093 EXPECT_FALSE(request(1)->handle()->socket());
1094 EXPECT_FALSE(request(2)->handle()->socket());
1095
1096 request(1)->handle()->SetPriority(LOW);
1097
1098 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1099
1100 EXPECT_EQ(1, GetOrderOfRequest(1));
1101 EXPECT_EQ(3, GetOrderOfRequest(2));
1102 EXPECT_EQ(2, GetOrderOfRequest(3));
1103}
1104
1105// Reprioritize a request to the same level as another and confirm it is
1106// put after the old request.
1107TEST_F(ClientSocketPoolBaseTest, ReprioritizeResetFIFO) {
1108 CreatePool(kDefaultMaxSockets, 1);
1109
1110 EXPECT_THAT(StartRequest("a", LOWEST), IsError(OK));
1111 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
1112 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1113 EXPECT_TRUE(request(0)->handle()->socket());
1114 EXPECT_FALSE(request(1)->handle()->socket());
1115 EXPECT_FALSE(request(2)->handle()->socket());
1116
1117 request(1)->handle()->SetPriority(MEDIUM);
1118
1119 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1120
1121 EXPECT_EQ(1, GetOrderOfRequest(1));
1122 EXPECT_EQ(3, GetOrderOfRequest(2));
1123 EXPECT_EQ(2, GetOrderOfRequest(3));
1124}
1125
[email protected]211d21722009-07-22 15:48:531126TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
1127 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1128
robpercival214763f2016-07-01 23:27:011129 EXPECT_THAT(StartRequest("a", LOWEST), IsOk());
1130 EXPECT_THAT(StartRequest("a", LOW), IsOk());
1131 EXPECT_THAT(StartRequest("b", HIGHEST), IsOk());
1132 EXPECT_THAT(StartRequest("b", MEDIUM), IsOk());
[email protected]211d21722009-07-22 15:48:531133
[email protected]2431756e2010-09-29 20:26:131134 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531135 client_socket_factory_.allocation_count());
1136
robpercival214763f2016-07-01 23:27:011137 EXPECT_THAT(StartRequest("c", MEDIUM), IsError(ERR_IO_PENDING));
1138 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1139 EXPECT_THAT(StartRequest("b", HIGHEST), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531140
[email protected]2431756e2010-09-29 20:26:131141 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531142
[email protected]2431756e2010-09-29 20:26:131143 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531144 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131145 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:531146
1147 // First 4 requests don't have to wait, and finish in order.
1148 EXPECT_EQ(1, GetOrderOfRequest(1));
1149 EXPECT_EQ(2, GetOrderOfRequest(2));
1150 EXPECT_EQ(3, GetOrderOfRequest(3));
1151 EXPECT_EQ(4, GetOrderOfRequest(4));
1152
1153 // Request ("b", 7) has the highest priority, but we can't make new socket for
1154 // group "b", because it has reached the per-group limit. Then we make
1155 // socket for ("c", 6), because it has higher priority than ("a", 4),
1156 // and we still can't make a socket for group "b".
1157 EXPECT_EQ(5, GetOrderOfRequest(5));
1158 EXPECT_EQ(6, GetOrderOfRequest(6));
1159 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171160
1161 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131162 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:531163}
1164
1165// Make sure that we count connecting sockets against the total limit.
1166TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
1167 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1168
robpercival214763f2016-07-01 23:27:011169 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1170 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
1171 EXPECT_THAT(StartRequest("c", DEFAULT_PRIORITY), IsOk());
[email protected]211d21722009-07-22 15:48:531172
1173 // Create one asynchronous request.
1174 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
robpercival214763f2016-07-01 23:27:011175 EXPECT_THAT(StartRequest("d", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531176
[email protected]6b175382009-10-13 06:47:471177 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1178 // actually become pending until 2ms after they have been created. In order
1179 // to flush all tasks, we need to wait so that we know there are no
1180 // soon-to-be-pending tasks waiting.
Alex Clarke0def2092018-12-10 12:01:451181 FastForwardBy(base::TimeDelta::FromMilliseconds(10));
[email protected]6b175382009-10-13 06:47:471182
[email protected]211d21722009-07-22 15:48:531183 // The next synchronous request should wait for its turn.
1184 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
robpercival214763f2016-07-01 23:27:011185 EXPECT_THAT(StartRequest("e", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531186
[email protected]2431756e2010-09-29 20:26:131187 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531188
[email protected]2431756e2010-09-29 20:26:131189 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531190 client_socket_factory_.allocation_count());
1191
1192 EXPECT_EQ(1, GetOrderOfRequest(1));
1193 EXPECT_EQ(2, GetOrderOfRequest(2));
1194 EXPECT_EQ(3, GetOrderOfRequest(3));
1195 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:171196 EXPECT_EQ(5, GetOrderOfRequest(5));
1197
1198 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131199 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:531200}
1201
[email protected]6427fe22010-04-16 22:27:411202TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
1203 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1204 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1205
robpercival214763f2016-07-01 23:27:011206 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1207 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1208 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1209 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
[email protected]6427fe22010-04-16 22:27:411210
1211 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1212
1213 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1214
robpercival214763f2016-07-01 23:27:011215 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1216 EXPECT_THAT(StartRequest("c", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]6427fe22010-04-16 22:27:411217
1218 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1219
[email protected]2431756e2010-09-29 20:26:131220 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411221 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131222 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411223 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131224 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1225 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411226 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
1227}
1228
[email protected]d7027bb2010-05-10 18:58:541229TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
1230 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1231 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1232
1233 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521234 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:501235 EXPECT_EQ(
1236 ERR_IO_PENDING,
1237 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
1238 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1239 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
1240 NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:541241
1242 ClientSocketHandle handles[4];
Avi Drissman4365a4782018-12-28 19:26:241243 for (size_t i = 0; i < base::size(handles); ++i) {
[email protected]6ecf2b92011-12-15 01:14:521244 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:501245 EXPECT_EQ(ERR_IO_PENDING,
1246 handles[i].Init("b", params_, DEFAULT_PRIORITY, SocketTag(),
1247 ClientSocketPool::RespectLimits::ENABLED,
1248 callback.callback(),
1249 ClientSocketPool::ProxyAuthCallback(),
1250 pool_.get(), NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:541251 }
1252
1253 // One will be stalled, cancel all the handles now.
1254 // This should hit the OnAvailableSocketSlot() code where we previously had
1255 // stalled groups, but no longer have any.
Avi Drissman4365a4782018-12-28 19:26:241256 for (size_t i = 0; i < base::size(handles); ++i)
[email protected]d7027bb2010-05-10 18:58:541257 handles[i].Reset();
1258}
1259
[email protected]eb5a99382010-07-11 03:18:261260TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:541261 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1262 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1263
[email protected]eb5a99382010-07-11 03:18:261264 {
1265 ClientSocketHandle handles[kDefaultMaxSockets];
[email protected]6ecf2b92011-12-15 01:14:521266 TestCompletionCallback callbacks[kDefaultMaxSockets];
[email protected]eb5a99382010-07-11 03:18:261267 for (int i = 0; i < kDefaultMaxSockets; ++i) {
Raul Tambre8c1981d2019-02-08 02:22:261268 EXPECT_EQ(OK, handles[i].Init(base::NumberToString(i), params_,
Paul Jensen8d6f87ec2018-01-13 00:46:541269 DEFAULT_PRIORITY, SocketTag(),
1270 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501271 callbacks[i].callback(),
1272 ClientSocketPool::ProxyAuthCallback(),
1273 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261274 }
1275
1276 // Force a stalled group.
1277 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521278 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201279 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541280 stalled_handle.Init("foo", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:201281 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501282 callback.callback(),
1283 ClientSocketPool::ProxyAuthCallback(),
1284 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261285
1286 // Cancel the stalled request.
1287 stalled_handle.Reset();
1288
1289 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1290 EXPECT_EQ(0, pool_->IdleSocketCount());
1291
1292 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541293 }
1294
[email protected]43a21b82010-06-10 21:30:541295 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1296 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:261297}
[email protected]43a21b82010-06-10 21:30:541298
[email protected]eb5a99382010-07-11 03:18:261299TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
1300 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1301 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1302
1303 {
1304 ClientSocketHandle handles[kDefaultMaxSockets];
1305 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521306 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201307 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541308 handles[i].Init(
Raul Tambre8c1981d2019-02-08 02:22:261309 base::NumberToString(i), params_, DEFAULT_PRIORITY,
Paul Jensen8d6f87ec2018-01-13 00:46:541310 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501311 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1312 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261313 }
1314
1315 // Force a stalled group.
1316 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1317 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521318 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201319 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541320 stalled_handle.Init("foo", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:201321 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501322 callback.callback(),
1323 ClientSocketPool::ProxyAuthCallback(),
1324 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261325
1326 // Since it is stalled, it should have no connect jobs.
Raul Tambre8335a6d2019-02-21 16:57:431327 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("foo"));
1328 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("foo"));
1329 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261330
1331 // Cancel the stalled request.
1332 handles[0].Reset();
1333
[email protected]eb5a99382010-07-11 03:18:261334 // Now we should have a connect job.
Raul Tambre8335a6d2019-02-21 16:57:431335 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("foo"));
1336 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("foo"));
1337 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261338
1339 // The stalled socket should connect.
robpercival214763f2016-07-01 23:27:011340 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:261341
1342 EXPECT_EQ(kDefaultMaxSockets + 1,
1343 client_socket_factory_.allocation_count());
1344 EXPECT_EQ(0, pool_->IdleSocketCount());
Raul Tambre8335a6d2019-02-21 16:57:431345 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("foo"));
1346 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("foo"));
1347 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261348
1349 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541350 }
1351
[email protected]eb5a99382010-07-11 03:18:261352 EXPECT_EQ(1, pool_->IdleSocketCount());
1353}
[email protected]43a21b82010-06-10 21:30:541354
[email protected]eb5a99382010-07-11 03:18:261355TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1356 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1357 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:541358
[email protected]eb5a99382010-07-11 03:18:261359 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521360 TestCompletionCallback callback;
[email protected]eb5a99382010-07-11 03:18:261361 {
[email protected]51fdc7c2012-04-10 19:19:481362 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261363 ClientSocketHandle handles[kDefaultMaxSockets];
1364 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521365 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201366 EXPECT_EQ(OK, handles[i].Init(base::StringPrintf("Take 2: %d", i),
Paul Jensen8d6f87ec2018-01-13 00:46:541367 params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:201368 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501369 callback.callback(),
1370 ClientSocketPool::ProxyAuthCallback(),
1371 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261372 }
1373
1374 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1375 EXPECT_EQ(0, pool_->IdleSocketCount());
[email protected]51fdc7c2012-04-10 19:19:481376 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261377
1378 // Now we will hit the socket limit.
tfarina428341112016-09-22 13:38:201379 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541380 stalled_handle.Init("foo", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:201381 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501382 callback.callback(),
1383 ClientSocketPool::ProxyAuthCallback(),
1384 pool_.get(), NetLogWithSource()));
[email protected]51fdc7c2012-04-10 19:19:481385 EXPECT_TRUE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261386
1387 // Dropping out of scope will close all handles and return them to idle.
1388 }
[email protected]43a21b82010-06-10 21:30:541389
1390 // But if we wait for it, the released idle sockets will be closed in
1391 // preference of the waiting request.
robpercival214763f2016-07-01 23:27:011392 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:261393
1394 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1395 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:541396}
1397
1398// Regression test for http://crbug.com/40952.
1399TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1400 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]06d94042010-08-25 01:45:221401 pool_->EnableConnectBackupJobs();
[email protected]43a21b82010-06-10 21:30:541402 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1403
1404 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1405 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521406 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201407 EXPECT_EQ(
Matt Menke28ac03e2019-02-25 22:25:501408 OK,
1409 handle.Init(base::NumberToString(i), params_, DEFAULT_PRIORITY,
1410 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1411 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1412 pool_.get(), NetLogWithSource()));
[email protected]43a21b82010-06-10 21:30:541413 }
1414
1415 // Flush all the DoReleaseSocket tasks.
fdoray5eeb7642016-06-22 16:11:281416 base::RunLoop().RunUntilIdle();
[email protected]43a21b82010-06-10 21:30:541417
1418 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1419 // reuse a socket.
1420 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1421 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521422 TestCompletionCallback callback;
[email protected]43a21b82010-06-10 21:30:541423
1424 // "0" is special here, since it should be the first entry in the sorted map,
1425 // which is the one which we would close an idle socket for. We shouldn't
1426 // close an idle socket though, since we should reuse the idle socket.
Matt Menke28ac03e2019-02-25 22:25:501427 EXPECT_EQ(OK, handle.Init("0", params_, DEFAULT_PRIORITY, SocketTag(),
1428 ClientSocketPool::RespectLimits::ENABLED,
1429 callback.callback(),
1430 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
1431 NetLogWithSource()));
[email protected]43a21b82010-06-10 21:30:541432
1433 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1434 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1435}
1436
[email protected]ab838892009-06-30 18:49:051437TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531438 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091439
robpercival214763f2016-07-01 23:27:011440 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1441 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1442 EXPECT_THAT(StartRequest("a", IDLE), IsError(ERR_IO_PENDING));
1443 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
1444 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1445 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
1446 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1447 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091448
[email protected]2431756e2010-09-29 20:26:131449 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]c9d6a1d2009-07-14 16:15:201450 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1451 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131452 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1453 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091454
[email protected]c9d6a1d2009-07-14 16:15:201455 EXPECT_EQ(1, GetOrderOfRequest(1));
1456 EXPECT_EQ(2, GetOrderOfRequest(2));
[email protected]c9c6f5c2010-07-31 01:30:031457 EXPECT_EQ(8, GetOrderOfRequest(3));
1458 EXPECT_EQ(6, GetOrderOfRequest(4));
1459 EXPECT_EQ(4, GetOrderOfRequest(5));
1460 EXPECT_EQ(3, GetOrderOfRequest(6));
1461 EXPECT_EQ(5, GetOrderOfRequest(7));
1462 EXPECT_EQ(7, GetOrderOfRequest(8));
[email protected]75439d3b2009-07-23 22:11:171463
1464 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131465 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]f6d1d6eb2009-06-24 20:16:091466}
1467
[email protected]ab838892009-06-30 18:49:051468TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531469 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091470
robpercival214763f2016-07-01 23:27:011471 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1472 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1473 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
1474 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1475 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
1476 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1477 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091478
[email protected]2431756e2010-09-29 20:26:131479 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091480
[email protected]2431756e2010-09-29 20:26:131481 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
robpercival214763f2016-07-01 23:27:011482 EXPECT_THAT(request(i)->WaitForResult(), IsOk());
[email protected]c9d6a1d2009-07-14 16:15:201483
[email protected]2431756e2010-09-29 20:26:131484 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]c9d6a1d2009-07-14 16:15:201485 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131486 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1487 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091488}
1489
1490// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:051491// The pending connect job will be cancelled and should not call back into
1492// ClientSocketPoolBase.
1493TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531494 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201495
[email protected]ab838892009-06-30 18:49:051496 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131497 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521498 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:501499 EXPECT_EQ(
1500 ERR_IO_PENDING,
1501 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
1502 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1503 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
1504 NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:131505 handle.Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091506}
1507
[email protected]ab838892009-06-30 18:49:051508TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531509 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201510
[email protected]ab838892009-06-30 18:49:051511 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061512 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521513 TestCompletionCallback callback;
[email protected]f6d1d6eb2009-06-24 20:16:091514
Matt Menke28ac03e2019-02-25 22:25:501515 EXPECT_EQ(
1516 ERR_IO_PENDING,
1517 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
1518 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1519 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
1520 NetLogWithSource()));
[email protected]f6d1d6eb2009-06-24 20:16:091521
1522 handle.Reset();
1523
[email protected]6ecf2b92011-12-15 01:14:521524 TestCompletionCallback callback2;
Matt Menke28ac03e2019-02-25 22:25:501525 EXPECT_EQ(
1526 ERR_IO_PENDING,
1527 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
1528 ClientSocketPool::RespectLimits::ENABLED,
1529 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
1530 pool_.get(), NetLogWithSource()));
[email protected]f6d1d6eb2009-06-24 20:16:091531
robpercival214763f2016-07-01 23:27:011532 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]f6d1d6eb2009-06-24 20:16:091533 EXPECT_FALSE(callback.have_result());
1534
1535 handle.Reset();
1536}
1537
[email protected]ab838892009-06-30 18:49:051538TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531539 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091540
robpercival214763f2016-07-01 23:27:011541 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1542 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1543 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
1544 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1545 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
1546 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1547 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091548
1549 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201550 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]2431756e2010-09-29 20:26:131551 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1552 (*requests())[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091553
[email protected]2431756e2010-09-29 20:26:131554 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091555
[email protected]c9d6a1d2009-07-14 16:15:201556 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1557 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131558 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1559 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091560
[email protected]c9d6a1d2009-07-14 16:15:201561 EXPECT_EQ(1, GetOrderOfRequest(1));
1562 EXPECT_EQ(2, GetOrderOfRequest(2));
1563 EXPECT_EQ(5, GetOrderOfRequest(3));
1564 EXPECT_EQ(3, GetOrderOfRequest(4));
[email protected]2431756e2010-09-29 20:26:131565 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1566 GetOrderOfRequest(5)); // Canceled request.
[email protected]c9d6a1d2009-07-14 16:15:201567 EXPECT_EQ(4, GetOrderOfRequest(6));
1568 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171569
1570 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131571 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091572}
1573
mmenke33d24423d2015-05-19 19:41:091574// Function to be used as a callback on socket request completion. It first
1575// disconnects the successfully connected socket from the first request, and
1576// then reuses the ClientSocketHandle to request another socket.
1577//
1578// |nested_callback| is called with the result of the second socket request.
1579void RequestSocketOnComplete(ClientSocketHandle* handle,
1580 TestClientSocketPool* pool,
1581 TestConnectJobFactory* test_connect_job_factory,
1582 TestConnectJob::JobType next_job_type,
Bence Békya4a50932018-08-10 13:39:411583 TestCompletionCallback* nested_callback,
mmenke33d24423d2015-05-19 19:41:091584 int first_request_result) {
robpercival214763f2016-07-01 23:27:011585 EXPECT_THAT(first_request_result, IsOk());
mmenke33d24423d2015-05-19 19:41:091586
1587 test_connect_job_factory->set_job_type(next_job_type);
1588
1589 // Don't allow reuse of the socket. Disconnect it and then release it.
1590 if (handle->socket())
1591 handle->socket()->Disconnect();
1592 handle->Reset();
1593
mmenked3641e12016-01-28 16:06:151594 scoped_refptr<TestSocketParams> params(new TestSocketParams());
mmenke33d24423d2015-05-19 19:41:091595 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:501596 int rv = handle->Init(
1597 "a", params, LOWEST, SocketTag(),
1598 ClientSocketPool::RespectLimits::ENABLED, nested_callback->callback(),
1599 ClientSocketPool::ProxyAuthCallback(), pool, NetLogWithSource());
mmenke33d24423d2015-05-19 19:41:091600 if (rv != ERR_IO_PENDING) {
1601 DCHECK_EQ(TestConnectJob::kMockJob, next_job_type);
Bence Békya4a50932018-08-10 13:39:411602 nested_callback->callback().Run(rv);
mmenke33d24423d2015-05-19 19:41:091603 } else {
1604 DCHECK_EQ(TestConnectJob::kMockPendingJob, next_job_type);
[email protected]6ecf2b92011-12-15 01:14:521605 }
mmenke33d24423d2015-05-19 19:41:091606}
[email protected]f6d1d6eb2009-06-24 20:16:091607
mmenke33d24423d2015-05-19 19:41:091608// Tests the case where a second socket is requested in a completion callback,
1609// and the second socket connects asynchronously. Reuses the same
1610// ClientSocketHandle for the second socket, after disconnecting the first.
[email protected]2ab05b52009-07-01 23:57:581611TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531612 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201613
[email protected]0b7648c2009-07-06 20:14:011614 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061615 ClientSocketHandle handle;
mmenke33d24423d2015-05-19 19:41:091616 TestCompletionCallback second_result_callback;
1617 int rv = handle.Init(
Paul Jensen8d6f87ec2018-01-13 00:46:541618 "a", params_, DEFAULT_PRIORITY, SocketTag(),
1619 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501620 base::BindOnce(&RequestSocketOnComplete, &handle, pool_.get(),
1621 connect_job_factory_, TestConnectJob::kMockPendingJob,
1622 &second_result_callback),
1623 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011624 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091625
robpercival214763f2016-07-01 23:27:011626 EXPECT_THAT(second_result_callback.WaitForResult(), IsOk());
[email protected]2ab05b52009-07-01 23:57:581627}
[email protected]f6d1d6eb2009-06-24 20:16:091628
mmenke33d24423d2015-05-19 19:41:091629// Tests the case where a second socket is requested in a completion callback,
1630// and the second socket connects synchronously. Reuses the same
1631// ClientSocketHandle for the second socket, after disconnecting the first.
[email protected]2ab05b52009-07-01 23:57:581632TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531633 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201634
[email protected]0b7648c2009-07-06 20:14:011635 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061636 ClientSocketHandle handle;
mmenke33d24423d2015-05-19 19:41:091637 TestCompletionCallback second_result_callback;
1638 int rv = handle.Init(
Paul Jensen8d6f87ec2018-01-13 00:46:541639 "a", params_, DEFAULT_PRIORITY, SocketTag(),
1640 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501641 base::BindOnce(&RequestSocketOnComplete, &handle, pool_.get(),
1642 connect_job_factory_, TestConnectJob::kMockPendingJob,
1643 &second_result_callback),
1644 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011645 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2ab05b52009-07-01 23:57:581646
robpercival214763f2016-07-01 23:27:011647 EXPECT_THAT(second_result_callback.WaitForResult(), IsOk());
[email protected]f6d1d6eb2009-06-24 20:16:091648}
1649
1650// Make sure that pending requests get serviced after active requests get
1651// cancelled.
[email protected]ab838892009-06-30 18:49:051652TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531653 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201654
[email protected]0b7648c2009-07-06 20:14:011655 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091656
robpercival214763f2016-07-01 23:27:011657 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1658 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1659 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1660 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1661 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1662 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1663 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091664
[email protected]c9d6a1d2009-07-14 16:15:201665 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1666 // Let's cancel them.
1667 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]2431756e2010-09-29 20:26:131668 ASSERT_FALSE(request(i)->handle()->is_initialized());
1669 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091670 }
1671
[email protected]f6d1d6eb2009-06-24 20:16:091672 // Let's wait for the rest to complete now.
[email protected]2431756e2010-09-29 20:26:131673 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
robpercival214763f2016-07-01 23:27:011674 EXPECT_THAT(request(i)->WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:131675 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091676 }
1677
[email protected]2431756e2010-09-29 20:26:131678 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1679 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091680}
1681
1682// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051683TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531684 const size_t kMaxSockets = 5;
1685 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201686
[email protected]0b7648c2009-07-06 20:14:011687 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091688
[email protected]211d21722009-07-22 15:48:531689 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1690 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091691
1692 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531693 for (size_t i = 0; i < kNumberOfRequests; ++i)
robpercival214763f2016-07-01 23:27:011694 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091695
[email protected]211d21722009-07-22 15:48:531696 for (size_t i = 0; i < kNumberOfRequests; ++i)
robpercival214763f2016-07-01 23:27:011697 EXPECT_THAT(request(i)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]f6d1d6eb2009-06-24 20:16:091698}
1699
mmenke9d72fe42017-05-18 22:36:071700// Make sure that pending requests that complete synchronously get serviced
1701// after active requests fail. See https://crbug.com/723748
1702TEST_F(ClientSocketPoolBaseTest, HandleMultipleSyncFailuresAfterAsyncFailure) {
1703 const size_t kNumberOfRequests = 10;
1704 const size_t kMaxSockets = 1;
1705 CreatePool(kMaxSockets, kMaxSockets);
1706
1707 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1708
1709 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1710
1711 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
1712
1713 // Queue up all the other requests
1714 for (size_t i = 1; i < kNumberOfRequests; ++i)
1715 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1716
1717 // Make sure all requests fail, instead of hanging.
1718 for (size_t i = 0; i < kNumberOfRequests; ++i)
1719 EXPECT_THAT(request(i)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
1720}
1721
[email protected]5fc08e32009-07-15 17:09:571722TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531723 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571724
1725 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1726
[email protected]2431756e2010-09-29 20:26:131727 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521728 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:501729 int rv = handle.Init(
1730 "a", params_, DEFAULT_PRIORITY, SocketTag(),
1731 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1732 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011733 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:571734
1735 // Cancel the active request.
[email protected]2431756e2010-09-29 20:26:131736 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571737
Paul Jensen8d6f87ec2018-01-13 00:46:541738 rv = handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151739 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501740 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1741 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011742 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1743 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]5fc08e32009-07-15 17:09:571744
[email protected]2431756e2010-09-29 20:26:131745 EXPECT_FALSE(handle.is_reused());
[email protected]034df0f32013-01-07 23:17:481746 TestLoadTimingInfoConnectedNotReused(handle);
[email protected]5fc08e32009-07-15 17:09:571747 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1748}
1749
xunjieli26619e72016-11-23 19:39:551750TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsForced) {
xunjieli26619e72016-11-23 19:39:551751 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1752 ClientSocketHandle handle;
1753 TestCompletionCallback callback;
1754 BoundTestNetLog log;
Matt Menke28ac03e2019-02-25 22:25:501755 int rv = handle.Init(
1756 "a", params_, LOWEST, SocketTag(),
1757 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1758 ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound());
xunjieli26619e72016-11-23 19:39:551759 EXPECT_THAT(rv, IsOk());
1760 handle.Reset();
1761 EXPECT_EQ(1, pool_->IdleSocketCount());
1762 pool_->CloseIdleSockets();
xunjieli26619e72016-11-23 19:39:551763}
1764
xunjieli92feb332017-03-03 17:19:231765TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsInGroupForced) {
xunjieli92feb332017-03-03 17:19:231766 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1767 TestCompletionCallback callback;
1768 BoundTestNetLog log;
1769 ClientSocketHandle handle1;
Matt Menke28ac03e2019-02-25 22:25:501770 int rv = handle1.Init(
1771 "a", params_, LOWEST, SocketTag(),
1772 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1773 ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound());
xunjieli92feb332017-03-03 17:19:231774 EXPECT_THAT(rv, IsOk());
1775 ClientSocketHandle handle2;
Paul Jensen8d6f87ec2018-01-13 00:46:541776 rv = handle2.Init("a", params_, LOWEST, SocketTag(),
xunjieli92feb332017-03-03 17:19:231777 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501778 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1779 pool_.get(), log.bound());
xunjieli92feb332017-03-03 17:19:231780 ClientSocketHandle handle3;
Paul Jensen8d6f87ec2018-01-13 00:46:541781 rv = handle3.Init("b", params_, LOWEST, SocketTag(),
xunjieli92feb332017-03-03 17:19:231782 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501783 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1784 pool_.get(), log.bound());
xunjieli92feb332017-03-03 17:19:231785 EXPECT_THAT(rv, IsOk());
1786 handle1.Reset();
1787 handle2.Reset();
1788 handle3.Reset();
1789 EXPECT_EQ(3, pool_->IdleSocketCount());
1790 pool_->CloseIdleSocketsInGroup("a");
1791 EXPECT_EQ(1, pool_->IdleSocketCount());
xunjieli92feb332017-03-03 17:19:231792}
1793
xunjieli26619e72016-11-23 19:39:551794TEST_F(ClientSocketPoolBaseTest, CleanUpUnusableIdleSockets) {
xunjieli26619e72016-11-23 19:39:551795 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1796 ClientSocketHandle handle;
1797 TestCompletionCallback callback;
1798 BoundTestNetLog log;
Matt Menke28ac03e2019-02-25 22:25:501799 int rv = handle.Init(
1800 "a", params_, LOWEST, SocketTag(),
1801 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1802 ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound());
xunjieli26619e72016-11-23 19:39:551803 EXPECT_THAT(rv, IsOk());
1804 StreamSocket* socket = handle.socket();
1805 handle.Reset();
1806 EXPECT_EQ(1, pool_->IdleSocketCount());
1807
1808 // Disconnect socket now to make the socket unusable.
1809 socket->Disconnect();
1810 ClientSocketHandle handle2;
Paul Jensen8d6f87ec2018-01-13 00:46:541811 rv = handle2.Init("a", params_, LOWEST, SocketTag(),
xunjieli26619e72016-11-23 19:39:551812 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501813 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1814 pool_.get(), log.bound());
xunjieli26619e72016-11-23 19:39:551815 EXPECT_THAT(rv, IsOk());
1816 EXPECT_FALSE(handle2.is_reused());
xunjieli26619e72016-11-23 19:39:551817}
1818
[email protected]2b7523d2009-07-29 20:29:231819// Regression test for http://crbug.com/17985.
1820TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1821 const int kMaxSockets = 3;
1822 const int kMaxSocketsPerGroup = 2;
1823 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1824
[email protected]ac790b42009-12-02 04:31:311825 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231826
robpercival214763f2016-07-01 23:27:011827 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1828 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
[email protected]2b7523d2009-07-29 20:29:231829
1830 // This is going to be a pending request in an otherwise empty group.
robpercival214763f2016-07-01 23:27:011831 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]2b7523d2009-07-29 20:29:231832
1833 // Reach the maximum socket limit.
robpercival214763f2016-07-01 23:27:011834 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
[email protected]2b7523d2009-07-29 20:29:231835
1836 // Create a stalled group with high priorities.
robpercival214763f2016-07-01 23:27:011837 EXPECT_THAT(StartRequest("c", kHighPriority), IsError(ERR_IO_PENDING));
1838 EXPECT_THAT(StartRequest("c", kHighPriority), IsError(ERR_IO_PENDING));
[email protected]2b7523d2009-07-29 20:29:231839
[email protected]eb5a99382010-07-11 03:18:261840 // Release the first two sockets from "a". Because this is a keepalive,
1841 // the first release will unblock the pending request for "a". The
1842 // second release will unblock a request for "c", becaue it is the next
1843 // high priority socket.
[email protected]2431756e2010-09-29 20:26:131844 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1845 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]2b7523d2009-07-29 20:29:231846
1847 // Closing idle sockets should not get us into trouble, but in the bug
1848 // we were hitting a CHECK here.
Raul Tambre8335a6d2019-02-21 16:57:431849 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]43a21b82010-06-10 21:30:541850 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261851
[email protected]2da659e2013-05-23 20:51:341852 // Run the released socket wakeups.
fdoray5eeb7642016-06-22 16:11:281853 base::RunLoop().RunUntilIdle();
[email protected]2b7523d2009-07-29 20:29:231854}
1855
[email protected]4d3b05d2010-01-27 21:27:291856TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531857 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571858
1859 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131860 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521861 TestCompletionCallback callback;
vishal.b62985ca92015-04-17 08:45:511862 BoundTestNetLog log;
Matt Menke28ac03e2019-02-25 22:25:501863 int rv = handle.Init(
1864 "a", params_, LOWEST, SocketTag(),
1865 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1866 ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound());
robpercival214763f2016-07-01 23:27:011867 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2431756e2010-09-29 20:26:131868 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
[email protected]034df0f32013-01-07 23:17:481869 TestLoadTimingInfoNotConnected(handle);
1870
robpercival214763f2016-07-01 23:27:011871 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:131872 EXPECT_TRUE(handle.is_initialized());
1873 EXPECT_TRUE(handle.socket());
[email protected]034df0f32013-01-07 23:17:481874 TestLoadTimingInfoConnectedNotReused(handle);
1875
[email protected]2431756e2010-09-29 20:26:131876 handle.Reset();
[email protected]034df0f32013-01-07 23:17:481877 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:301878
mmenke43758e62015-05-04 21:09:461879 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:401880 log.GetEntries(&entries);
1881
1882 EXPECT_EQ(4u, entries.size());
mikecirone8b85c432016-09-08 19:11:001883 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171884 EXPECT_TRUE(LogContainsEvent(
mikecirone8b85c432016-09-08 19:11:001885 entries, 1, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1886 NetLogEventPhase::NONE));
1887 EXPECT_TRUE(LogContainsEvent(entries, 2,
1888 NetLogEventType::SOCKET_POOL_BOUND_TO_SOCKET,
1889 NetLogEventPhase::NONE));
1890 EXPECT_TRUE(LogContainsEndEvent(entries, 3, NetLogEventType::SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571891}
1892
[email protected]4d3b05d2010-01-27 21:27:291893TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571894 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531895 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571896
1897 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2431756e2010-09-29 20:26:131898 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521899 TestCompletionCallback callback;
vishal.b62985ca92015-04-17 08:45:511900 BoundTestNetLog log;
[email protected]e60e47a2010-07-14 03:37:181901 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:131902 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:431903 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:451904 info.headers = new HttpResponseHeaders(std::string());
[email protected]2431756e2010-09-29 20:26:131905 handle.set_ssl_error_response_info(info);
Matt Menke28ac03e2019-02-25 22:25:501906 EXPECT_EQ(
1907 ERR_IO_PENDING,
1908 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
1909 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1910 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
1911 log.bound()));
[email protected]2431756e2010-09-29 20:26:131912 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
robpercival214763f2016-07-01 23:27:011913 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]2431756e2010-09-29 20:26:131914 EXPECT_FALSE(handle.is_ssl_error());
1915 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:301916
mmenke43758e62015-05-04 21:09:461917 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:401918 log.GetEntries(&entries);
1919
1920 EXPECT_EQ(3u, entries.size());
mikecirone8b85c432016-09-08 19:11:001921 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171922 EXPECT_TRUE(LogContainsEvent(
mikecirone8b85c432016-09-08 19:11:001923 entries, 1, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1924 NetLogEventPhase::NONE));
1925 EXPECT_TRUE(LogContainsEndEvent(entries, 2, NetLogEventType::SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571926}
1927
mmenke6be122f2015-03-09 22:22:471928// Check that an async ConnectJob failure does not result in creation of a new
1929// ConnectJob when there's another pending request also waiting on its own
1930// ConnectJob. See http://crbug.com/463960.
1931TEST_F(ClientSocketPoolBaseTest, AsyncFailureWithPendingRequestWithJob) {
1932 CreatePool(2, 2);
1933 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1934
robpercival214763f2016-07-01 23:27:011935 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1936 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
mmenke6be122f2015-03-09 22:22:471937
robpercival214763f2016-07-01 23:27:011938 EXPECT_THAT(request(0)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
1939 EXPECT_THAT(request(1)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
mmenke6be122f2015-03-09 22:22:471940
1941 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1942}
1943
[email protected]4d3b05d2010-01-27 21:27:291944TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101945 // TODO(eroman): Add back the log expectations! Removed them because the
1946 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531947 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571948
1949 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131950 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521951 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131952 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:521953 TestCompletionCallback callback2;
[email protected]5fc08e32009-07-15 17:09:571954
Matt Menke28ac03e2019-02-25 22:25:501955 EXPECT_EQ(
1956 ERR_IO_PENDING,
1957 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
1958 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1959 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
1960 NetLogWithSource()));
vishal.b62985ca92015-04-17 08:45:511961 BoundTestNetLog log2;
tfarina428341112016-09-22 13:38:201962 EXPECT_EQ(
1963 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541964 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:201965 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501966 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
1967 pool_.get(), NetLogWithSource()));
[email protected]5fc08e32009-07-15 17:09:571968
[email protected]2431756e2010-09-29 20:26:131969 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571970
[email protected]fd7b7c92009-08-20 19:38:301971
1972 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301973
robpercival214763f2016-07-01 23:27:011974 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:131975 handle2.Reset();
[email protected]fd7b7c92009-08-20 19:38:301976
1977 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531978 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571979}
1980
[email protected]4d3b05d2010-01-27 21:27:291981TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341982 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1983
[email protected]17a0c6c2009-08-04 00:07:041984 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1985
robpercival214763f2016-07-01 23:27:011986 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
1987 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1988 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1989 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
[email protected]974ebd62009-08-03 23:14:341990
Raul Tambre8335a6d2019-02-21 16:57:431991 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1992 static_cast<int>(pool_->NumConnectJobsInGroup("a")));
[email protected]2431756e2010-09-29 20:26:131993 (*requests())[2]->handle()->Reset();
1994 (*requests())[3]->handle()->Reset();
Raul Tambre8335a6d2019-02-21 16:57:431995 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1996 static_cast<int>(pool_->NumConnectJobsInGroup("a")));
[email protected]974ebd62009-08-03 23:14:341997
[email protected]2431756e2010-09-29 20:26:131998 (*requests())[1]->handle()->Reset();
Raul Tambre8335a6d2019-02-21 16:57:431999 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
2000 static_cast<int>(pool_->NumConnectJobsInGroup("a")));
[email protected]974ebd62009-08-03 23:14:342001
[email protected]2431756e2010-09-29 20:26:132002 (*requests())[0]->handle()->Reset();
Raul Tambre8335a6d2019-02-21 16:57:432003 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
2004 static_cast<int>(pool_->NumConnectJobsInGroup("a")));
[email protected]974ebd62009-08-03 23:14:342005}
2006
[email protected]5fc08e32009-07-15 17:09:572007// When requests and ConnectJobs are not coupled, the request will get serviced
2008// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:292009TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:532010 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:572011
2012 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:322013 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:572014
[email protected]2431756e2010-09-29 20:26:132015 std::vector<TestSocketRequest*> request_order;
2016 size_t completion_count; // unused
2017 TestSocketRequest req1(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502018 int rv = req1.handle()->Init(
2019 "a", params_, DEFAULT_PRIORITY, SocketTag(),
2020 ClientSocketPool::RespectLimits::ENABLED, req1.callback(),
2021 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012022 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2023 EXPECT_THAT(req1.WaitForResult(), IsOk());
[email protected]5fc08e32009-07-15 17:09:572024
2025 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
2026 // without a job.
2027 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2028
[email protected]2431756e2010-09-29 20:26:132029 TestSocketRequest req2(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502030 rv = req2.handle()->Init(
2031 "a", params_, DEFAULT_PRIORITY, SocketTag(),
2032 ClientSocketPool::RespectLimits::ENABLED, req2.callback(),
2033 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012034 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2431756e2010-09-29 20:26:132035 TestSocketRequest req3(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502036 rv = req3.handle()->Init(
2037 "a", params_, DEFAULT_PRIORITY, SocketTag(),
2038 ClientSocketPool::RespectLimits::ENABLED, req3.callback(),
2039 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012040 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572041
2042 // Both Requests 2 and 3 are pending. We release socket 1 which should
2043 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:332044 req1.handle()->Reset();
[email protected]2da659e2013-05-23 20:51:342045 // Run the released socket wakeups.
fdoray5eeb7642016-06-22 16:11:282046 base::RunLoop().RunUntilIdle();
[email protected]a6c59f62009-07-29 16:33:332047 ASSERT_TRUE(req2.handle()->socket());
robpercival214763f2016-07-01 23:27:012048 EXPECT_THAT(req2.WaitForResult(), IsOk());
[email protected]a6c59f62009-07-29 16:33:332049 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:572050
2051 // Signal job 2, which should service request 3.
2052
2053 client_socket_factory_.SignalJobs();
robpercival214763f2016-07-01 23:27:012054 EXPECT_THAT(req3.WaitForResult(), IsOk());
[email protected]5fc08e32009-07-15 17:09:572055
Raul Tambre8335a6d2019-02-21 16:57:432056 ASSERT_EQ(3u, request_order.size());
[email protected]2431756e2010-09-29 20:26:132057 EXPECT_EQ(&req1, request_order[0]);
2058 EXPECT_EQ(&req2, request_order[1]);
2059 EXPECT_EQ(&req3, request_order[2]);
Raul Tambre8335a6d2019-02-21 16:57:432060 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]5fc08e32009-07-15 17:09:572061}
2062
2063// The requests are not coupled to the jobs. So, the requests should finish in
2064// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:292065TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:532066 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:572067 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:322068 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:572069
[email protected]2431756e2010-09-29 20:26:132070 std::vector<TestSocketRequest*> request_order;
2071 size_t completion_count; // unused
2072 TestSocketRequest req1(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502073 int rv = req1.handle()->Init(
2074 "a", params_, DEFAULT_PRIORITY, SocketTag(),
2075 ClientSocketPool::RespectLimits::ENABLED, req1.callback(),
2076 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012077 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572078
[email protected]2431756e2010-09-29 20:26:132079 TestSocketRequest req2(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502080 rv = req2.handle()->Init(
2081 "a", params_, DEFAULT_PRIORITY, SocketTag(),
2082 ClientSocketPool::RespectLimits::ENABLED, req2.callback(),
2083 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012084 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572085
2086 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:322087 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:572088
[email protected]2431756e2010-09-29 20:26:132089 TestSocketRequest req3(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502090 rv = req3.handle()->Init(
2091 "a", params_, DEFAULT_PRIORITY, SocketTag(),
2092 ClientSocketPool::RespectLimits::ENABLED, req3.callback(),
2093 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012094 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572095
robpercival214763f2016-07-01 23:27:012096 EXPECT_THAT(req1.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
2097 EXPECT_THAT(req2.WaitForResult(), IsOk());
2098 EXPECT_THAT(req3.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]5fc08e32009-07-15 17:09:572099
Raul Tambre8335a6d2019-02-21 16:57:432100 ASSERT_EQ(3u, request_order.size());
[email protected]2431756e2010-09-29 20:26:132101 EXPECT_EQ(&req1, request_order[0]);
2102 EXPECT_EQ(&req2, request_order[1]);
2103 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:572104}
2105
[email protected]03b7c8c2013-07-20 04:38:552106// Test GetLoadState in the case there's only one socket request.
2107TEST_F(ClientSocketPoolBaseTest, LoadStateOneRequest) {
[email protected]211d21722009-07-22 15:48:532108 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]03b7c8c2013-07-20 04:38:552109 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]5fc08e32009-07-15 17:09:572110
[email protected]2431756e2010-09-29 20:26:132111 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522112 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502113 int rv = handle.Init(
2114 "a", params_, DEFAULT_PRIORITY, SocketTag(),
2115 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2116 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012117 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552118 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:572119
[email protected]03b7c8c2013-07-20 04:38:552120 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2121 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
2122
2123 // No point in completing the connection, since ClientSocketHandles only
2124 // expect the LoadState to be checked while connecting.
2125}
2126
2127// Test GetLoadState in the case there are two socket requests.
2128TEST_F(ClientSocketPoolBaseTest, LoadStateTwoRequests) {
2129 CreatePool(2, 2);
2130 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2131
2132 ClientSocketHandle handle;
2133 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502134 int rv = handle.Init(
2135 "a", params_, DEFAULT_PRIORITY, SocketTag(),
2136 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2137 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012138 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
haavardm835c1d62015-04-22 08:18:002139 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
2140
2141 ClientSocketHandle handle2;
2142 TestCompletionCallback callback2;
Paul Jensen8d6f87ec2018-01-13 00:46:542143 rv = handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152144 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502145 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2146 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012147 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
haavardm835c1d62015-04-22 08:18:002148 client_socket_factory_.SetJobLoadState(1, LOAD_STATE_RESOLVING_HOST);
2149
Matt Menke4b69f932019-03-04 16:20:012150 // Each handle should reflect the state of its own job.
haavardm835c1d62015-04-22 08:18:002151 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle.GetLoadState());
2152 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle2.GetLoadState());
2153
Matt Menke4b69f932019-03-04 16:20:012154 // Update the state of the first job.
haavardm835c1d62015-04-22 08:18:002155 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_CONNECTING);
2156
Matt Menke4b69f932019-03-04 16:20:012157 // Only the state of the first request should have changed.
haavardm835c1d62015-04-22 08:18:002158 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
haavardm835c1d62015-04-22 08:18:002159 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle2.GetLoadState());
Matt Menke4b69f932019-03-04 16:20:012160
2161 // Update the state of the second job.
2162 client_socket_factory_.SetJobLoadState(1, LOAD_STATE_SSL_HANDSHAKE);
2163
2164 // Only the state of the second request should have changed.
2165 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2166 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle2.GetLoadState());
2167
2168 // Second job connects and the first request gets the socket. The
2169 // second handle switches to the state of the remaining ConnectJob.
2170 client_socket_factory_.SignalJob(1);
2171 EXPECT_THAT(callback.WaitForResult(), IsOk());
2172 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
[email protected]03b7c8c2013-07-20 04:38:552173}
2174
2175// Test GetLoadState in the case the per-group limit is reached.
2176TEST_F(ClientSocketPoolBaseTest, LoadStateGroupLimit) {
2177 CreatePool(2, 1);
2178 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2179
2180 ClientSocketHandle handle;
2181 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502182 int rv = handle.Init(
2183 "a", params_, MEDIUM, SocketTag(),
2184 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2185 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012186 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552187 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2188
2189 // Request another socket from the same pool, buth with a higher priority.
2190 // The first request should now be stalled at the socket group limit.
2191 ClientSocketHandle handle2;
2192 TestCompletionCallback callback2;
Paul Jensen8d6f87ec2018-01-13 00:46:542193 rv = handle2.Init("a", params_, HIGHEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152194 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502195 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2196 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012197 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552198 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2199 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
2200
2201 // The first handle should remain stalled as the other socket goes through
2202 // the connect process.
2203
2204 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2205 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2206 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle2.GetLoadState());
2207
2208 client_socket_factory_.SignalJob(0);
robpercival214763f2016-07-01 23:27:012209 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]03b7c8c2013-07-20 04:38:552210 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2211
2212 // Closing the second socket should cause the stalled handle to finally get a
2213 // ConnectJob.
2214 handle2.socket()->Disconnect();
2215 handle2.Reset();
2216 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2217}
2218
2219// Test GetLoadState in the case the per-pool limit is reached.
2220TEST_F(ClientSocketPoolBaseTest, LoadStatePoolLimit) {
2221 CreatePool(2, 2);
2222 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2223
2224 ClientSocketHandle handle;
2225 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502226 int rv = handle.Init(
2227 "a", params_, DEFAULT_PRIORITY, SocketTag(),
2228 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2229 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012230 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552231
2232 // Request for socket from another pool.
2233 ClientSocketHandle handle2;
2234 TestCompletionCallback callback2;
Paul Jensen8d6f87ec2018-01-13 00:46:542235 rv = handle2.Init("b", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152236 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502237 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2238 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012239 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552240
2241 // Request another socket from the first pool. Request should stall at the
2242 // socket pool limit.
2243 ClientSocketHandle handle3;
2244 TestCompletionCallback callback3;
Paul Jensen8d6f87ec2018-01-13 00:46:542245 rv = handle3.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152246 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502247 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2248 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012249 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552250
2251 // The third handle should remain stalled as the other sockets in its group
2252 // goes through the connect process.
2253
2254 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2255 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2256
2257 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2258 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
2259 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2260
2261 client_socket_factory_.SignalJob(0);
robpercival214763f2016-07-01 23:27:012262 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]03b7c8c2013-07-20 04:38:552263 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2264
2265 // Closing a socket should allow the stalled handle to finally get a new
2266 // ConnectJob.
2267 handle.socket()->Disconnect();
2268 handle.Reset();
2269 EXPECT_EQ(LOAD_STATE_CONNECTING, handle3.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:572270}
2271
Matt Menkeb57663b32019-03-01 17:17:102272TEST_F(ClientSocketPoolBaseTest, CertError) {
[email protected]e772db3f2010-07-12 18:11:132273 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
Matt Menkeb57663b32019-03-01 17:17:102274 connect_job_factory_->set_job_type(TestConnectJob::kMockCertErrorJob);
[email protected]e772db3f2010-07-12 18:11:132275
[email protected]2431756e2010-09-29 20:26:132276 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522277 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502278 EXPECT_EQ(
Matt Menkeb57663b32019-03-01 17:17:102279 ERR_CERT_COMMON_NAME_INVALID,
Matt Menke28ac03e2019-02-25 22:25:502280 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2281 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2282 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2283 NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:132284 EXPECT_TRUE(handle.is_initialized());
2285 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:132286}
2287
Matt Menkeb57663b32019-03-01 17:17:102288TEST_F(ClientSocketPoolBaseTest, AsyncCertError) {
[email protected]e772db3f2010-07-12 18:11:132289 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2290
Matt Menkeb57663b32019-03-01 17:17:102291 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingCertErrorJob);
[email protected]2431756e2010-09-29 20:26:132292 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522293 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502294 EXPECT_EQ(
2295 ERR_IO_PENDING,
2296 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2297 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2298 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2299 NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:132300 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
Matt Menkeb57663b32019-03-01 17:17:102301 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CERT_COMMON_NAME_INVALID));
[email protected]2431756e2010-09-29 20:26:132302 EXPECT_TRUE(handle.is_initialized());
2303 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:132304}
2305
[email protected]e60e47a2010-07-14 03:37:182306TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
2307 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2308 connect_job_factory_->set_job_type(
2309 TestConnectJob::kMockAdditionalErrorStateJob);
2310
[email protected]2431756e2010-09-29 20:26:132311 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522312 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502313 EXPECT_EQ(
2314 ERR_CONNECTION_FAILED,
2315 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2316 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2317 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2318 NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:132319 EXPECT_FALSE(handle.is_initialized());
2320 EXPECT_FALSE(handle.socket());
2321 EXPECT_TRUE(handle.is_ssl_error());
2322 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182323}
2324
2325TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
2326 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2327
2328 connect_job_factory_->set_job_type(
2329 TestConnectJob::kMockPendingAdditionalErrorStateJob);
[email protected]2431756e2010-09-29 20:26:132330 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522331 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502332 EXPECT_EQ(
2333 ERR_IO_PENDING,
2334 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2335 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2336 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2337 NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:132338 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
robpercival214763f2016-07-01 23:27:012339 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]2431756e2010-09-29 20:26:132340 EXPECT_FALSE(handle.is_initialized());
2341 EXPECT_FALSE(handle.socket());
2342 EXPECT_TRUE(handle.is_ssl_error());
2343 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182344}
2345
martijn003cd612016-05-19 22:24:382346// Make sure we can reuse sockets.
2347TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSocketsReuse) {
[email protected]64770b7d2011-11-16 04:30:412348 CreatePoolWithIdleTimeouts(
2349 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
[email protected]e7b1c6d2c2012-05-05 00:54:032350 base::TimeDelta(), // Time out unused sockets immediately.
2351 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2352
2353 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2354
2355 ClientSocketHandle handle;
2356 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502357 int rv = handle.Init(
2358 "a", params_, LOWEST, SocketTag(),
2359 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2360 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012361 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e7b1c6d2c2012-05-05 00:54:032362 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
robpercival214763f2016-07-01 23:27:012363 ASSERT_THAT(callback.WaitForResult(), IsOk());
[email protected]e7b1c6d2c2012-05-05 00:54:032364
2365 // Use and release the socket.
Bence Békybdbb0e72018-08-07 21:42:592366 EXPECT_EQ(1, handle.socket()->Write(NULL, 1, CompletionOnceCallback(),
Ramin Halavati0a08cc82018-02-06 07:46:382367 TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]034df0f32013-01-07 23:17:482368 TestLoadTimingInfoConnectedNotReused(handle);
[email protected]e7b1c6d2c2012-05-05 00:54:032369 handle.Reset();
2370
2371 // Should now have one idle socket.
2372 ASSERT_EQ(1, pool_->IdleSocketCount());
2373
2374 // Request a new socket. This should reuse the old socket and complete
2375 // synchronously.
vishal.b62985ca92015-04-17 08:45:512376 BoundTestNetLog log;
Matt Menke28ac03e2019-02-25 22:25:502377 rv = handle.Init(
2378 "a", params_, LOWEST, SocketTag(),
2379 ClientSocketPool::RespectLimits::ENABLED, CompletionOnceCallback(),
2380 ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound());
robpercival214763f2016-07-01 23:27:012381 ASSERT_THAT(rv, IsOk());
[email protected]e7b1c6d2c2012-05-05 00:54:032382 EXPECT_TRUE(handle.is_reused());
[email protected]034df0f32013-01-07 23:17:482383 TestLoadTimingInfoConnectedReused(handle);
[email protected]e7b1c6d2c2012-05-05 00:54:032384
2385 ASSERT_TRUE(pool_->HasGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:432386 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]e7b1c6d2c2012-05-05 00:54:032387 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2388
mmenke43758e62015-05-04 21:09:462389 TestNetLogEntry::List entries;
[email protected]e7b1c6d2c2012-05-05 00:54:032390 log.GetEntries(&entries);
2391 EXPECT_TRUE(LogContainsEntryWithType(
mikecirone8b85c432016-09-08 19:11:002392 entries, 1, NetLogEventType::SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]e7b1c6d2c2012-05-05 00:54:032393}
2394
martijn003cd612016-05-19 22:24:382395// Make sure we cleanup old unused sockets.
Eric Romanb49715e2018-04-24 22:41:172396TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSocketsNoReuse) {
[email protected]e7b1c6d2c2012-05-05 00:54:032397 CreatePoolWithIdleTimeouts(
2398 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2399 base::TimeDelta(), // Time out unused sockets immediately
2400 base::TimeDelta()); // Time out used sockets immediately
[email protected]64770b7d2011-11-16 04:30:412401
2402 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2403
2404 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2405
2406 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522407 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502408 int rv = handle.Init(
2409 "a", params_, LOWEST, SocketTag(),
2410 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2411 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012412 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]64770b7d2011-11-16 04:30:412413 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2414
2415 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522416 TestCompletionCallback callback2;
Paul Jensen8d6f87ec2018-01-13 00:46:542417 rv = handle2.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152418 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502419 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2420 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012421 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]64770b7d2011-11-16 04:30:412422 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
2423
2424 // Cancel one of the requests. Wait for the other, which will get the first
2425 // job. Release the socket. Run the loop again to make sure the second
2426 // socket is sitting idle and the first one is released (since ReleaseSocket()
2427 // just posts a DoReleaseSocket() task).
2428
2429 handle.Reset();
robpercival214763f2016-07-01 23:27:012430 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]64770b7d2011-11-16 04:30:412431 // Use the socket.
Bence Békybdbb0e72018-08-07 21:42:592432 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, CompletionOnceCallback(),
Ramin Halavati0a08cc82018-02-06 07:46:382433 TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]64770b7d2011-11-16 04:30:412434 handle2.Reset();
2435
[email protected]e7b1c6d2c2012-05-05 00:54:032436 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2437 // actually become pending until 2ms after they have been created. In order
2438 // to flush all tasks, we need to wait so that we know there are no
2439 // soon-to-be-pending tasks waiting.
Alex Clarke0def2092018-12-10 12:01:452440 FastForwardBy(base::TimeDelta::FromMilliseconds(10));
[email protected]64770b7d2011-11-16 04:30:412441
[email protected]e7b1c6d2c2012-05-05 00:54:032442 // Both sockets should now be idle.
[email protected]64770b7d2011-11-16 04:30:412443 ASSERT_EQ(2, pool_->IdleSocketCount());
2444
2445 // Request a new socket. This should cleanup the unused and timed out ones.
2446 // A new socket will be created rather than reusing the idle one.
vishal.b62985ca92015-04-17 08:45:512447 BoundTestNetLog log;
[email protected]6ecf2b92011-12-15 01:14:522448 TestCompletionCallback callback3;
Paul Jensen8d6f87ec2018-01-13 00:46:542449 rv = handle.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152450 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502451 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
2452 pool_.get(), log.bound());
robpercival214763f2016-07-01 23:27:012453 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
2454 ASSERT_THAT(callback3.WaitForResult(), IsOk());
[email protected]64770b7d2011-11-16 04:30:412455 EXPECT_FALSE(handle.is_reused());
2456
[email protected]e7b1c6d2c2012-05-05 00:54:032457 // Make sure the idle socket is closed.
[email protected]64770b7d2011-11-16 04:30:412458 ASSERT_TRUE(pool_->HasGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:432459 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]64770b7d2011-11-16 04:30:412460 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2461
mmenke43758e62015-05-04 21:09:462462 TestNetLogEntry::List entries;
[email protected]64770b7d2011-11-16 04:30:412463 log.GetEntries(&entries);
2464 EXPECT_FALSE(LogContainsEntryWithType(
mikecirone8b85c432016-09-08 19:11:002465 entries, 1, NetLogEventType::SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]64770b7d2011-11-16 04:30:412466}
2467
[email protected]2041cf342010-02-19 03:15:592468// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:162469// because of multiple releasing disconnected sockets.
2470TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
2471 CreatePoolWithIdleTimeouts(
2472 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2473 base::TimeDelta(), // Time out unused sockets immediately.
2474 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2475
2476 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2477
2478 // Startup 4 connect jobs. Two of them will be pending.
2479
[email protected]2431756e2010-09-29 20:26:132480 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522481 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502482 int rv = handle.Init(
2483 "a", params_, LOWEST, SocketTag(),
2484 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2485 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012486 EXPECT_THAT(rv, IsOk());
[email protected]4f2abec2010-02-03 18:10:162487
[email protected]2431756e2010-09-29 20:26:132488 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522489 TestCompletionCallback callback2;
Paul Jensen8d6f87ec2018-01-13 00:46:542490 rv = handle2.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152491 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502492 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2493 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012494 EXPECT_THAT(rv, IsOk());
[email protected]4f2abec2010-02-03 18:10:162495
[email protected]2431756e2010-09-29 20:26:132496 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:522497 TestCompletionCallback callback3;
Paul Jensen8d6f87ec2018-01-13 00:46:542498 rv = handle3.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152499 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502500 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
2501 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012502 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4f2abec2010-02-03 18:10:162503
[email protected]2431756e2010-09-29 20:26:132504 ClientSocketHandle handle4;
[email protected]6ecf2b92011-12-15 01:14:522505 TestCompletionCallback callback4;
Paul Jensen8d6f87ec2018-01-13 00:46:542506 rv = handle4.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152507 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502508 callback4.callback(), ClientSocketPool::ProxyAuthCallback(),
2509 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012510 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4f2abec2010-02-03 18:10:162511
2512 // Release two disconnected sockets.
2513
[email protected]2431756e2010-09-29 20:26:132514 handle.socket()->Disconnect();
2515 handle.Reset();
2516 handle2.socket()->Disconnect();
2517 handle2.Reset();
[email protected]4f2abec2010-02-03 18:10:162518
robpercival214763f2016-07-01 23:27:012519 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132520 EXPECT_FALSE(handle3.is_reused());
robpercival214763f2016-07-01 23:27:012521 EXPECT_THAT(callback4.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132522 EXPECT_FALSE(handle4.is_reused());
[email protected]4f2abec2010-02-03 18:10:162523}
2524
[email protected]d7027bb2010-05-10 18:58:542525// Regression test for http://crbug.com/42267.
2526// When DoReleaseSocket() is processed for one socket, it is blocked because the
2527// other stalled groups all have releasing sockets, so no progress can be made.
2528TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
2529 CreatePoolWithIdleTimeouts(
2530 4 /* socket limit */, 4 /* socket limit per group */,
2531 base::TimeDelta(), // Time out unused sockets immediately.
2532 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2533
2534 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2535
2536 // Max out the socket limit with 2 per group.
2537
[email protected]2431756e2010-09-29 20:26:132538 ClientSocketHandle handle_a[4];
[email protected]6ecf2b92011-12-15 01:14:522539 TestCompletionCallback callback_a[4];
[email protected]2431756e2010-09-29 20:26:132540 ClientSocketHandle handle_b[4];
[email protected]6ecf2b92011-12-15 01:14:522541 TestCompletionCallback callback_b[4];
[email protected]d7027bb2010-05-10 18:58:542542
2543 for (int i = 0; i < 2; ++i) {
Paul Jensen8d6f87ec2018-01-13 00:46:542544 EXPECT_EQ(OK, handle_a[i].Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152545 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502546 callback_a[i].callback(),
2547 ClientSocketPool::ProxyAuthCallback(),
2548 pool_.get(), NetLogWithSource()));
Paul Jensen8d6f87ec2018-01-13 00:46:542549 EXPECT_EQ(OK, handle_b[i].Init("b", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152550 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502551 callback_b[i].callback(),
2552 ClientSocketPool::ProxyAuthCallback(),
2553 pool_.get(), NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:542554 }
[email protected]b89f7e42010-05-20 20:37:002555
[email protected]d7027bb2010-05-10 18:58:542556 // Make 4 pending requests, 2 per group.
2557
2558 for (int i = 2; i < 4; ++i) {
tfarina428341112016-09-22 13:38:202559 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542560 handle_a[i].Init("a", params_, LOWEST, SocketTag(),
tfarina428341112016-09-22 13:38:202561 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502562 callback_a[i].callback(),
2563 ClientSocketPool::ProxyAuthCallback(),
2564 pool_.get(), NetLogWithSource()));
tfarina428341112016-09-22 13:38:202565 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542566 handle_b[i].Init("b", params_, LOWEST, SocketTag(),
tfarina428341112016-09-22 13:38:202567 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502568 callback_b[i].callback(),
2569 ClientSocketPool::ProxyAuthCallback(),
2570 pool_.get(), NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:542571 }
2572
2573 // Release b's socket first. The order is important, because in
2574 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2575 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2576 // first, which has a releasing socket, so it refuses to start up another
2577 // ConnectJob. So, we used to infinite loop on this.
[email protected]2431756e2010-09-29 20:26:132578 handle_b[0].socket()->Disconnect();
2579 handle_b[0].Reset();
2580 handle_a[0].socket()->Disconnect();
2581 handle_a[0].Reset();
[email protected]d7027bb2010-05-10 18:58:542582
2583 // Used to get stuck here.
fdoray5eeb7642016-06-22 16:11:282584 base::RunLoop().RunUntilIdle();
[email protected]d7027bb2010-05-10 18:58:542585
[email protected]2431756e2010-09-29 20:26:132586 handle_b[1].socket()->Disconnect();
2587 handle_b[1].Reset();
2588 handle_a[1].socket()->Disconnect();
2589 handle_a[1].Reset();
[email protected]d7027bb2010-05-10 18:58:542590
2591 for (int i = 2; i < 4; ++i) {
robpercival214763f2016-07-01 23:27:012592 EXPECT_THAT(callback_b[i].WaitForResult(), IsOk());
2593 EXPECT_THAT(callback_a[i].WaitForResult(), IsOk());
[email protected]d7027bb2010-05-10 18:58:542594 }
2595}
2596
[email protected]fd4fe0b2010-02-08 23:02:152597TEST_F(ClientSocketPoolBaseTest,
2598 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2599 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2600
2601 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2602
robpercival214763f2016-07-01 23:27:012603 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
2604 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
2605 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
2606 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]fd4fe0b2010-02-08 23:02:152607
robpercival214763f2016-07-01 23:27:012608 EXPECT_THAT((*requests())[0]->WaitForResult(), IsOk());
2609 EXPECT_THAT((*requests())[1]->WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132610 EXPECT_EQ(2u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152611
2612 // Releases one connection.
[email protected]2431756e2010-09-29 20:26:132613 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
robpercival214763f2016-07-01 23:27:012614 EXPECT_THAT((*requests())[2]->WaitForResult(), IsOk());
[email protected]fd4fe0b2010-02-08 23:02:152615
[email protected]2431756e2010-09-29 20:26:132616 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
robpercival214763f2016-07-01 23:27:012617 EXPECT_THAT((*requests())[3]->WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132618 EXPECT_EQ(4u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152619
2620 EXPECT_EQ(1, GetOrderOfRequest(1));
2621 EXPECT_EQ(2, GetOrderOfRequest(2));
2622 EXPECT_EQ(3, GetOrderOfRequest(3));
2623 EXPECT_EQ(4, GetOrderOfRequest(4));
2624
2625 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:132626 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
[email protected]fd4fe0b2010-02-08 23:02:152627}
2628
[email protected]6ecf2b92011-12-15 01:14:522629class TestReleasingSocketRequest : public TestCompletionCallbackBase {
[email protected]4f1e4982010-03-02 18:31:042630 public:
[email protected]2431756e2010-09-29 20:26:132631 TestReleasingSocketRequest(TestClientSocketPool* pool,
2632 int expected_result,
[email protected]e60e47a2010-07-14 03:37:182633 bool reset_releasing_handle)
2634 : pool_(pool),
2635 expected_result_(expected_result),
Bence Béky8ddc2492018-06-13 01:02:042636 reset_releasing_handle_(reset_releasing_handle) {}
[email protected]6ecf2b92011-12-15 01:14:522637
Chris Watkins7a41d3552017-12-01 02:13:272638 ~TestReleasingSocketRequest() override = default;
[email protected]4f1e4982010-03-02 18:31:042639
2640 ClientSocketHandle* handle() { return &handle_; }
2641
Bence Béky8ddc2492018-06-13 01:02:042642 CompletionOnceCallback callback() {
2643 return base::BindOnce(&TestReleasingSocketRequest::OnComplete,
2644 base::Unretained(this));
2645 }
[email protected]4f1e4982010-03-02 18:31:042646
2647 private:
[email protected]6ecf2b92011-12-15 01:14:522648 void OnComplete(int result) {
2649 SetResult(result);
2650 if (reset_releasing_handle_)
2651 handle_.Reset();
2652
mmenked3641e12016-01-28 16:06:152653 scoped_refptr<TestSocketParams> con_params(new TestSocketParams());
Matt Menke28ac03e2019-02-25 22:25:502654 EXPECT_EQ(expected_result_,
2655 handle2_.Init("a", con_params, DEFAULT_PRIORITY, SocketTag(),
2656 ClientSocketPool::RespectLimits::ENABLED,
2657 CompletionOnceCallback(),
2658 ClientSocketPool::ProxyAuthCallback(), pool_,
2659 NetLogWithSource()));
[email protected]6ecf2b92011-12-15 01:14:522660 }
2661
[email protected]2431756e2010-09-29 20:26:132662 TestClientSocketPool* const pool_;
[email protected]e60e47a2010-07-14 03:37:182663 int expected_result_;
2664 bool reset_releasing_handle_;
[email protected]4f1e4982010-03-02 18:31:042665 ClientSocketHandle handle_;
2666 ClientSocketHandle handle2_;
[email protected]4f1e4982010-03-02 18:31:042667};
2668
[email protected]e60e47a2010-07-14 03:37:182669
2670TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2671 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2672
robpercival214763f2016-07-01 23:27:012673 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
2674 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
2675 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
[email protected]e60e47a2010-07-14 03:37:182676
[email protected]2431756e2010-09-29 20:26:132677 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]e60e47a2010-07-14 03:37:182678 client_socket_factory_.allocation_count());
2679
2680 connect_job_factory_->set_job_type(
2681 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2682 TestReleasingSocketRequest req(pool_.get(), OK, false);
tfarina428341112016-09-22 13:38:202683 EXPECT_EQ(
2684 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542685 req.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:202686 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502687 req.callback(), ClientSocketPool::ProxyAuthCallback(),
2688 pool_.get(), NetLogWithSource()));
[email protected]e60e47a2010-07-14 03:37:182689 // The next job should complete synchronously
2690 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2691
robpercival214763f2016-07-01 23:27:012692 EXPECT_THAT(req.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:182693 EXPECT_FALSE(req.handle()->is_initialized());
2694 EXPECT_FALSE(req.handle()->socket());
2695 EXPECT_TRUE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:432696 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182697}
2698
[email protected]b6501d3d2010-06-03 23:53:342699// http://crbug.com/44724 regression test.
2700// We start releasing the pool when we flush on network change. When that
2701// happens, the only active references are in the ClientSocketHandles. When a
2702// ConnectJob completes and calls back into the last ClientSocketHandle, that
2703// callback can release the last reference and delete the pool. After the
2704// callback finishes, we go back to the stack frame within the now-deleted pool.
2705// Executing any code that refers to members of the now-deleted pool can cause
2706// crashes.
2707TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2708 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2709 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2710
2711 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522712 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502713 EXPECT_EQ(
2714 ERR_IO_PENDING,
2715 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2716 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2717 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2718 NetLogWithSource()));
[email protected]b6501d3d2010-06-03 23:53:342719
[email protected]7af985a2012-12-14 22:40:422720 pool_->FlushWithError(ERR_NETWORK_CHANGED);
[email protected]b6501d3d2010-06-03 23:53:342721
2722 // We'll call back into this now.
2723 callback.WaitForResult();
2724}
2725
[email protected]a7e38572010-06-07 18:22:242726TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2727 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2728 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2729
2730 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522731 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502732 EXPECT_EQ(
2733 ERR_IO_PENDING,
2734 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2735 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2736 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2737 NetLogWithSource()));
robpercival214763f2016-07-01 23:27:012738 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]a7e38572010-06-07 18:22:242739 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2740
[email protected]7af985a2012-12-14 22:40:422741 pool_->FlushWithError(ERR_NETWORK_CHANGED);
[email protected]a7e38572010-06-07 18:22:242742
2743 handle.Reset();
fdoray5eeb7642016-06-22 16:11:282744 base::RunLoop().RunUntilIdle();
[email protected]a7e38572010-06-07 18:22:242745
Matt Menke28ac03e2019-02-25 22:25:502746 EXPECT_EQ(
2747 ERR_IO_PENDING,
2748 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2749 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2750 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2751 NetLogWithSource()));
robpercival214763f2016-07-01 23:27:012752 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]a7e38572010-06-07 18:22:242753 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2754}
2755
[email protected]6ecf2b92011-12-15 01:14:522756class ConnectWithinCallback : public TestCompletionCallbackBase {
[email protected]06f92462010-08-31 19:24:142757 public:
Bence Béky8ddc2492018-06-13 01:02:042758 ConnectWithinCallback(const std::string& group_name,
2759 const scoped_refptr<TestSocketParams>& params,
2760 TestClientSocketPool* pool)
2761 : group_name_(group_name), params_(params), pool_(pool) {}
[email protected]06f92462010-08-31 19:24:142762
Chris Watkins7a41d3552017-12-01 02:13:272763 ~ConnectWithinCallback() override = default;
[email protected]06f92462010-08-31 19:24:142764
2765 int WaitForNestedResult() {
2766 return nested_callback_.WaitForResult();
2767 }
2768
Bence Béky8ddc2492018-06-13 01:02:042769 CompletionOnceCallback callback() {
2770 return base::BindOnce(&ConnectWithinCallback::OnComplete,
2771 base::Unretained(this));
2772 }
[email protected]6ecf2b92011-12-15 01:14:522773
[email protected]06f92462010-08-31 19:24:142774 private:
[email protected]6ecf2b92011-12-15 01:14:522775 void OnComplete(int result) {
2776 SetResult(result);
Matt Menke28ac03e2019-02-25 22:25:502777 EXPECT_EQ(ERR_IO_PENDING,
2778 handle_.Init(group_name_, params_, DEFAULT_PRIORITY, SocketTag(),
2779 ClientSocketPool::RespectLimits::ENABLED,
2780 nested_callback_.callback(),
2781 ClientSocketPool::ProxyAuthCallback(), pool_,
2782 NetLogWithSource()));
[email protected]6ecf2b92011-12-15 01:14:522783 }
2784
[email protected]06f92462010-08-31 19:24:142785 const std::string group_name_;
2786 const scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:132787 TestClientSocketPool* const pool_;
[email protected]06f92462010-08-31 19:24:142788 ClientSocketHandle handle_;
[email protected]6ecf2b92011-12-15 01:14:522789 TestCompletionCallback nested_callback_;
2790
2791 DISALLOW_COPY_AND_ASSIGN(ConnectWithinCallback);
[email protected]06f92462010-08-31 19:24:142792};
2793
2794TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
2795 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2796
2797 // First job will be waiting until it gets aborted.
2798 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2799
2800 ClientSocketHandle handle;
[email protected]2431756e2010-09-29 20:26:132801 ConnectWithinCallback callback("a", params_, pool_.get());
Matt Menke28ac03e2019-02-25 22:25:502802 EXPECT_EQ(
2803 ERR_IO_PENDING,
2804 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2805 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2806 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2807 NetLogWithSource()));
[email protected]06f92462010-08-31 19:24:142808
2809 // Second job will be started during the first callback, and will
2810 // asynchronously complete with OK.
2811 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]7af985a2012-12-14 22:40:422812 pool_->FlushWithError(ERR_NETWORK_CHANGED);
robpercival214763f2016-07-01 23:27:012813 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NETWORK_CHANGED));
2814 EXPECT_THAT(callback.WaitForNestedResult(), IsOk());
[email protected]06f92462010-08-31 19:24:142815}
2816
Matt Menke141b87f22019-01-30 02:43:032817TEST_F(ClientSocketPoolBaseTest, BackupSocketWaitsForHostResolution) {
2818 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2819 pool_->EnableConnectBackupJobs();
2820
2821 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2822 ClientSocketHandle handle;
2823 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502824 EXPECT_EQ(
2825 ERR_IO_PENDING,
2826 handle.Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
2827 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2828 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2829 NetLogWithSource()));
Matt Menke141b87f22019-01-30 02:43:032830 // The backup timer fires but doesn't start a new ConnectJob while resolving
2831 // the hostname.
2832 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
2833 FastForwardBy(base::TimeDelta::FromMilliseconds(
2834 ClientSocketPool::kMaxConnectRetryIntervalMs * 100));
2835 EXPECT_EQ(1, client_socket_factory_.allocation_count());
2836
2837 // Once the ConnectJob has finished resolving the hostname, the backup timer
2838 // will create a ConnectJob when it fires.
2839 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_CONNECTING);
2840 FastForwardBy(base::TimeDelta::FromMilliseconds(
2841 ClientSocketPool::kMaxConnectRetryIntervalMs));
2842 EXPECT_EQ(2, client_socket_factory_.allocation_count());
2843}
2844
2845// Test that no backup socket is created when a ConnectJob connects before it
2846// completes.
2847TEST_F(ClientSocketPoolBaseTest, NoBackupSocketWhenConnected) {
2848 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2849 pool_->EnableConnectBackupJobs();
2850
2851 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2852 ClientSocketHandle handle;
2853 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502854 EXPECT_EQ(
2855 ERR_IO_PENDING,
2856 handle.Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
2857 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2858 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2859 NetLogWithSource()));
Matt Menke141b87f22019-01-30 02:43:032860 // The backup timer fires but doesn't start a new ConnectJob while resolving
2861 // the hostname.
2862 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
2863 FastForwardBy(base::TimeDelta::FromMilliseconds(
2864 ClientSocketPool::kMaxConnectRetryIntervalMs * 100));
2865 EXPECT_EQ(1, client_socket_factory_.allocation_count());
2866
2867 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2868 client_socket_factory_.SetJobHasEstablishedConnection(0);
2869 FastForwardBy(base::TimeDelta::FromMilliseconds(
2870 ClientSocketPool::kMaxConnectRetryIntervalMs * 100));
2871 EXPECT_EQ(1, client_socket_factory_.allocation_count());
2872}
2873
[email protected]25eea382010-07-10 23:55:262874// Cancel a pending socket request while we're at max sockets,
2875// and verify that the backup socket firing doesn't cause a crash.
2876TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
2877 // Max 4 sockets globally, max 4 sockets per group.
2878 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
[email protected]06d94042010-08-25 01:45:222879 pool_->EnableConnectBackupJobs();
[email protected]25eea382010-07-10 23:55:262880
[email protected]4baaf9d2010-08-31 15:15:442881 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2882 // timer.
[email protected]25eea382010-07-10 23:55:262883 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2884 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522885 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502886 EXPECT_EQ(
2887 ERR_IO_PENDING,
2888 handle.Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
2889 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2890 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2891 NetLogWithSource()));
[email protected]25eea382010-07-10 23:55:262892
2893 // Start (MaxSockets - 1) connected sockets to reach max sockets.
2894 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2895 ClientSocketHandle handles[kDefaultMaxSockets];
2896 for (int i = 1; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:522897 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:542898 EXPECT_EQ(OK, handles[i].Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:202899 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502900 callback.callback(),
2901 ClientSocketPool::ProxyAuthCallback(),
2902 pool_.get(), NetLogWithSource()));
[email protected]25eea382010-07-10 23:55:262903 }
2904
fdoray5eeb7642016-06-22 16:11:282905 base::RunLoop().RunUntilIdle();
[email protected]25eea382010-07-10 23:55:262906
2907 // Cancel the pending request.
2908 handle.Reset();
2909
2910 // Wait for the backup timer to fire (add some slop to ensure it fires)
Alex Clarke0def2092018-12-10 12:01:452911 FastForwardBy(base::TimeDelta::FromMilliseconds(
[email protected]26b9973962012-01-28 00:57:002912 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]25eea382010-07-10 23:55:262913
[email protected]25eea382010-07-10 23:55:262914 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
2915}
2916
[email protected]3f00be82010-09-27 19:50:022917TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
[email protected]4baaf9d2010-08-31 15:15:442918 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2919 pool_->EnableConnectBackupJobs();
2920
2921 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2922 // timer.
2923 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2924 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522925 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502926 EXPECT_EQ(
2927 ERR_IO_PENDING,
2928 handle.Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
2929 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2930 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2931 NetLogWithSource()));
[email protected]4baaf9d2010-08-31 15:15:442932 ASSERT_TRUE(pool_->HasGroup("bar"));
Raul Tambre8335a6d2019-02-21 16:57:432933 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("bar"));
2934 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("bar"));
2935 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("bar"));
[email protected]4baaf9d2010-08-31 15:15:442936
2937 // Cancel the socket request. This should cancel the backup timer. Wait for
2938 // the backup time to see if it indeed got canceled.
2939 handle.Reset();
2940 // Wait for the backup timer to fire (add some slop to ensure it fires)
Alex Clarke0def2092018-12-10 12:01:452941 FastForwardBy(base::TimeDelta::FromMilliseconds(
[email protected]26b9973962012-01-28 00:57:002942 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]4baaf9d2010-08-31 15:15:442943 ASSERT_TRUE(pool_->HasGroup("bar"));
Raul Tambre8335a6d2019-02-21 16:57:432944 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("bar"));
[email protected]4baaf9d2010-08-31 15:15:442945}
2946
[email protected]3f00be82010-09-27 19:50:022947TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
2948 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2949 pool_->EnableConnectBackupJobs();
2950
2951 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2952 // timer.
2953 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2954 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522955 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502956 EXPECT_EQ(
2957 ERR_IO_PENDING,
2958 handle.Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
2959 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2960 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2961 NetLogWithSource()));
[email protected]3f00be82010-09-27 19:50:022962 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2963 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522964 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:202965 EXPECT_EQ(
2966 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542967 handle2.Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:202968 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502969 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2970 pool_.get(), NetLogWithSource()));
[email protected]3f00be82010-09-27 19:50:022971 ASSERT_TRUE(pool_->HasGroup("bar"));
Raul Tambre8335a6d2019-02-21 16:57:432972 EXPECT_EQ(2u, pool_->NumConnectJobsInGroup("bar"));
[email protected]3f00be82010-09-27 19:50:022973
2974 // Cancel request 1 and then complete request 2. With the requests finished,
2975 // the backup timer should be cancelled.
2976 handle.Reset();
robpercival214763f2016-07-01 23:27:012977 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]3f00be82010-09-27 19:50:022978 // Wait for the backup timer to fire (add some slop to ensure it fires)
Alex Clarke0def2092018-12-10 12:01:452979 FastForwardBy(base::TimeDelta::FromMilliseconds(
[email protected]26b9973962012-01-28 00:57:002980 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]3f00be82010-09-27 19:50:022981}
2982
[email protected]eb5a99382010-07-11 03:18:262983// Test delayed socket binding for the case where we have two connects,
2984// and while one is waiting on a connect, the other frees up.
2985// The socket waiting on a connect should switch immediately to the freed
2986// up socket.
2987TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
2988 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2989 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2990
2991 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522992 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502993 EXPECT_EQ(
2994 ERR_IO_PENDING,
2995 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2996 ClientSocketPool::RespectLimits::ENABLED,
2997 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2998 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:012999 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263000
3001 // No idle sockets, no pending jobs.
3002 EXPECT_EQ(0, pool_->IdleSocketCount());
Raul Tambre8335a6d2019-02-21 16:57:433003 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
[email protected]eb5a99382010-07-11 03:18:263004
3005 // Create a second socket to the same host, but this one will wait.
3006 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3007 ClientSocketHandle handle2;
Matt Menke28ac03e2019-02-25 22:25:503008 EXPECT_EQ(
3009 ERR_IO_PENDING,
3010 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3011 ClientSocketPool::RespectLimits::ENABLED,
3012 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3013 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:263014 // No idle sockets, and one connecting job.
3015 EXPECT_EQ(0, pool_->IdleSocketCount());
Raul Tambre8335a6d2019-02-21 16:57:433016 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
[email protected]eb5a99382010-07-11 03:18:263017
3018 // Return the first handle to the pool. This will initiate the delayed
3019 // binding.
3020 handle1.Reset();
3021
fdoray5eeb7642016-06-22 16:11:283022 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263023
3024 // Still no idle sockets, still one pending connect job.
3025 EXPECT_EQ(0, pool_->IdleSocketCount());
Raul Tambre8335a6d2019-02-21 16:57:433026 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
[email protected]eb5a99382010-07-11 03:18:263027
3028 // The second socket connected, even though it was a Waiting Job.
robpercival214763f2016-07-01 23:27:013029 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263030
3031 // And we can see there is still one job waiting.
Raul Tambre8335a6d2019-02-21 16:57:433032 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
[email protected]eb5a99382010-07-11 03:18:263033
3034 // Finally, signal the waiting Connect.
3035 client_socket_factory_.SignalJobs();
Raul Tambre8335a6d2019-02-21 16:57:433036 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
[email protected]eb5a99382010-07-11 03:18:263037
fdoray5eeb7642016-06-22 16:11:283038 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263039}
3040
3041// Test delayed socket binding when a group is at capacity and one
3042// of the group's sockets frees up.
3043TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
3044 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3045 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3046
3047 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523048 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503049 EXPECT_EQ(
3050 ERR_IO_PENDING,
3051 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3052 ClientSocketPool::RespectLimits::ENABLED,
3053 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3054 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013055 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263056
3057 // No idle sockets, no pending jobs.
3058 EXPECT_EQ(0, pool_->IdleSocketCount());
Raul Tambre8335a6d2019-02-21 16:57:433059 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
[email protected]eb5a99382010-07-11 03:18:263060
3061 // Create a second socket to the same host, but this one will wait.
3062 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3063 ClientSocketHandle handle2;
Matt Menke28ac03e2019-02-25 22:25:503064 EXPECT_EQ(
3065 ERR_IO_PENDING,
3066 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3067 ClientSocketPool::RespectLimits::ENABLED,
3068 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3069 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:263070 // No idle sockets, and one connecting job.
3071 EXPECT_EQ(0, pool_->IdleSocketCount());
Raul Tambre8335a6d2019-02-21 16:57:433072 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
[email protected]eb5a99382010-07-11 03:18:263073
3074 // Return the first handle to the pool. This will initiate the delayed
3075 // binding.
3076 handle1.Reset();
3077
fdoray5eeb7642016-06-22 16:11:283078 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263079
3080 // Still no idle sockets, still one pending connect job.
3081 EXPECT_EQ(0, pool_->IdleSocketCount());
Raul Tambre8335a6d2019-02-21 16:57:433082 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
[email protected]eb5a99382010-07-11 03:18:263083
3084 // The second socket connected, even though it was a Waiting Job.
robpercival214763f2016-07-01 23:27:013085 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263086
3087 // And we can see there is still one job waiting.
Raul Tambre8335a6d2019-02-21 16:57:433088 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
[email protected]eb5a99382010-07-11 03:18:263089
3090 // Finally, signal the waiting Connect.
3091 client_socket_factory_.SignalJobs();
Raul Tambre8335a6d2019-02-21 16:57:433092 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
[email protected]eb5a99382010-07-11 03:18:263093
fdoray5eeb7642016-06-22 16:11:283094 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263095}
3096
3097// Test out the case where we have one socket connected, one
3098// connecting, when the first socket finishes and goes idle.
[email protected]2abfe90a2010-08-25 17:49:513099// Although the second connection is pending, the second request
[email protected]eb5a99382010-07-11 03:18:263100// should complete, by taking the first socket's idle socket.
3101TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
3102 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3103 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3104
3105 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523106 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503107 EXPECT_EQ(
3108 ERR_IO_PENDING,
3109 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3110 ClientSocketPool::RespectLimits::ENABLED,
3111 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3112 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013113 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263114
3115 // No idle sockets, no pending jobs.
3116 EXPECT_EQ(0, pool_->IdleSocketCount());
Raul Tambre8335a6d2019-02-21 16:57:433117 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
[email protected]eb5a99382010-07-11 03:18:263118
3119 // Create a second socket to the same host, but this one will wait.
3120 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3121 ClientSocketHandle handle2;
Matt Menke28ac03e2019-02-25 22:25:503122 EXPECT_EQ(
3123 ERR_IO_PENDING,
3124 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3125 ClientSocketPool::RespectLimits::ENABLED,
3126 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3127 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:263128 // No idle sockets, and one connecting job.
3129 EXPECT_EQ(0, pool_->IdleSocketCount());
Raul Tambre8335a6d2019-02-21 16:57:433130 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
[email protected]eb5a99382010-07-11 03:18:263131
3132 // Return the first handle to the pool. This will initiate the delayed
3133 // binding.
3134 handle1.Reset();
3135
fdoray5eeb7642016-06-22 16:11:283136 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263137
3138 // Still no idle sockets, still one pending connect job.
3139 EXPECT_EQ(0, pool_->IdleSocketCount());
Raul Tambre8335a6d2019-02-21 16:57:433140 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
[email protected]eb5a99382010-07-11 03:18:263141
3142 // The second socket connected, even though it was a Waiting Job.
robpercival214763f2016-07-01 23:27:013143 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263144
3145 // And we can see there is still one job waiting.
Raul Tambre8335a6d2019-02-21 16:57:433146 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
[email protected]eb5a99382010-07-11 03:18:263147
3148 // Finally, signal the waiting Connect.
3149 client_socket_factory_.SignalJobs();
Raul Tambre8335a6d2019-02-21 16:57:433150 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
[email protected]eb5a99382010-07-11 03:18:263151
fdoray5eeb7642016-06-22 16:11:283152 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263153}
3154
[email protected]2abfe90a2010-08-25 17:49:513155// Cover the case where on an available socket slot, we have one pending
3156// request that completes synchronously, thereby making the Group empty.
3157TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
3158 const int kUnlimitedSockets = 100;
3159 const int kOneSocketPerGroup = 1;
3160 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
3161
3162 // Make the first request asynchronous fail.
3163 // This will free up a socket slot later.
3164 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
3165
3166 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523167 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203168 EXPECT_EQ(
3169 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543170 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203171 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503172 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3173 pool_.get(), NetLogWithSource()));
Raul Tambre8335a6d2019-02-21 16:57:433174 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
[email protected]2abfe90a2010-08-25 17:49:513175
3176 // Make the second request synchronously fail. This should make the Group
3177 // empty.
3178 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3179 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523180 TestCompletionCallback callback2;
[email protected]2abfe90a2010-08-25 17:49:513181 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
3182 // when created.
tfarina428341112016-09-22 13:38:203183 EXPECT_EQ(
3184 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543185 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203186 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503187 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3188 pool_.get(), NetLogWithSource()));
[email protected]2abfe90a2010-08-25 17:49:513189
Raul Tambre8335a6d2019-02-21 16:57:433190 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
[email protected]2abfe90a2010-08-25 17:49:513191
robpercival214763f2016-07-01 23:27:013192 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
3193 EXPECT_THAT(callback2.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]2abfe90a2010-08-25 17:49:513194 EXPECT_FALSE(pool_->HasGroup("a"));
3195}
3196
[email protected]e1b54dc2010-10-06 21:27:223197TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
3198 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3199
3200 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3201
3202 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523203 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203204 EXPECT_EQ(
3205 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543206 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203207 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503208 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3209 pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223210
3211 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523212 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203213 EXPECT_EQ(
3214 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543215 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203216 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503217 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3218 pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223219 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:523220 TestCompletionCallback callback3;
tfarina428341112016-09-22 13:38:203221 EXPECT_EQ(
3222 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543223 handle3.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203224 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503225 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
3226 pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223227
robpercival214763f2016-07-01 23:27:013228 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3229 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3230 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]e1b54dc2010-10-06 21:27:223231
3232 // Use the socket.
Bence Békybdbb0e72018-08-07 21:42:593233 EXPECT_EQ(1, handle1.socket()->Write(NULL, 1, CompletionOnceCallback(),
Ramin Halavati0a08cc82018-02-06 07:46:383234 TRAFFIC_ANNOTATION_FOR_TESTS));
Bence Békybdbb0e72018-08-07 21:42:593235 EXPECT_EQ(1, handle3.socket()->Write(NULL, 1, CompletionOnceCallback(),
Ramin Halavati0a08cc82018-02-06 07:46:383236 TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]e1b54dc2010-10-06 21:27:223237
3238 handle1.Reset();
3239 handle2.Reset();
3240 handle3.Reset();
3241
Matt Menke28ac03e2019-02-25 22:25:503242 EXPECT_EQ(OK, handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3243 ClientSocketPool::RespectLimits::ENABLED,
3244 callback1.callback(),
3245 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
3246 NetLogWithSource()));
3247 EXPECT_EQ(OK, handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3248 ClientSocketPool::RespectLimits::ENABLED,
3249 callback2.callback(),
3250 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
3251 NetLogWithSource()));
3252 EXPECT_EQ(OK, handle3.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3253 ClientSocketPool::RespectLimits::ENABLED,
3254 callback3.callback(),
3255 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
3256 NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223257
3258 EXPECT_TRUE(handle1.socket()->WasEverUsed());
3259 EXPECT_TRUE(handle2.socket()->WasEverUsed());
3260 EXPECT_FALSE(handle3.socket()->WasEverUsed());
3261}
3262
[email protected]2c2bef152010-10-13 00:55:033263TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
3264 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3265 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3266
Charlie Harrison55ce6082018-05-14 02:25:573267 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033268
3269 ASSERT_TRUE(pool_->HasGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433270 EXPECT_EQ(2u, pool_->NumConnectJobsInGroup("a"));
3271 EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3272 EXPECT_EQ(2u, pool_->NumUnassignedConnectJobsInGroup("a"));
3273 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033274
3275 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523276 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203277 EXPECT_EQ(
3278 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543279 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203280 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503281 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3282 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033283
3284 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523285 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203286 EXPECT_EQ(
3287 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543288 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203289 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503290 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3291 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033292
Raul Tambre8335a6d2019-02-21 16:57:433293 EXPECT_EQ(2u, pool_->NumConnectJobsInGroup("a"));
3294 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3295 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3296 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033297
robpercival214763f2016-07-01 23:27:013298 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3299 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033300 handle1.Reset();
3301 handle2.Reset();
3302
Raul Tambre8335a6d2019-02-21 16:57:433303 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
3304 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3305 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3306 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033307}
3308
3309TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
3310 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3311 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3312
3313 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523314 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203315 EXPECT_EQ(
3316 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543317 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203318 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503319 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3320 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033321
3322 ASSERT_TRUE(pool_->HasGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433323 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
3324 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3325 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3326 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033327
Charlie Harrison55ce6082018-05-14 02:25:573328 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033329
Raul Tambre8335a6d2019-02-21 16:57:433330 EXPECT_EQ(2u, pool_->NumConnectJobsInGroup("a"));
3331 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3332 EXPECT_EQ(1u, pool_->NumUnassignedConnectJobsInGroup("a"));
3333 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033334
3335 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523336 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203337 EXPECT_EQ(
3338 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543339 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203340 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503341 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3342 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033343
Raul Tambre8335a6d2019-02-21 16:57:433344 EXPECT_EQ(2u, pool_->NumConnectJobsInGroup("a"));
3345 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3346 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3347 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033348
robpercival214763f2016-07-01 23:27:013349 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3350 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033351 handle1.Reset();
3352 handle2.Reset();
3353
Raul Tambre8335a6d2019-02-21 16:57:433354 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
3355 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3356 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3357 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033358}
3359
3360TEST_F(ClientSocketPoolBaseTest,
3361 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
3362 CreatePool(4, 4);
3363 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3364
3365 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523366 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203367 EXPECT_EQ(
3368 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543369 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203370 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503371 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3372 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033373
3374 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523375 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203376 EXPECT_EQ(
3377 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543378 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203379 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503380 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3381 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033382
3383 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:523384 TestCompletionCallback callback3;
tfarina428341112016-09-22 13:38:203385 EXPECT_EQ(
3386 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543387 handle3.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203388 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503389 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
3390 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033391
3392 ASSERT_TRUE(pool_->HasGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433393 EXPECT_EQ(3u, pool_->NumConnectJobsInGroup("a"));
3394 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3395 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3396 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033397
Charlie Harrison55ce6082018-05-14 02:25:573398 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033399
Raul Tambre8335a6d2019-02-21 16:57:433400 EXPECT_EQ(3u, pool_->NumConnectJobsInGroup("a"));
3401 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3402 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3403 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033404
robpercival214763f2016-07-01 23:27:013405 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3406 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3407 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033408 handle1.Reset();
3409 handle2.Reset();
3410 handle3.Reset();
3411
Raul Tambre8335a6d2019-02-21 16:57:433412 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
3413 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3414 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3415 EXPECT_EQ(3u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033416}
3417
3418TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
3419 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3420 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3421
3422 ASSERT_FALSE(pool_->HasGroup("a"));
3423
Charlie Harrison55ce6082018-05-14 02:25:573424 pool_->RequestSockets("a", &params_, kDefaultMaxSockets, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033425
3426 ASSERT_TRUE(pool_->HasGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433427 EXPECT_EQ(kDefaultMaxSockets,
3428 static_cast<int>(pool_->NumConnectJobsInGroup("a")));
3429 EXPECT_EQ(kDefaultMaxSockets,
3430 static_cast<int>(pool_->NumNeverAssignedConnectJobsInGroup("a")));
3431 EXPECT_EQ(kDefaultMaxSockets,
3432 static_cast<int>(pool_->NumUnassignedConnectJobsInGroup("a")));
[email protected]2c2bef152010-10-13 00:55:033433
3434 ASSERT_FALSE(pool_->HasGroup("b"));
3435
Charlie Harrison55ce6082018-05-14 02:25:573436 pool_->RequestSockets("b", &params_, kDefaultMaxSockets, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033437
3438 ASSERT_FALSE(pool_->HasGroup("b"));
3439}
3440
3441TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
3442 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3443 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3444
3445 ASSERT_FALSE(pool_->HasGroup("a"));
3446
3447 pool_->RequestSockets("a", &params_, kDefaultMaxSockets - 1,
Charlie Harrison55ce6082018-05-14 02:25:573448 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033449
3450 ASSERT_TRUE(pool_->HasGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103451 EXPECT_EQ(kDefaultMaxSockets - 1,
Raul Tambre8335a6d2019-02-21 16:57:433452 static_cast<int>(pool_->NumConnectJobsInGroup("a")));
Lily Chenecebf932018-11-02 17:15:433453 EXPECT_EQ(kDefaultMaxSockets - 1,
Raul Tambre8335a6d2019-02-21 16:57:433454 static_cast<int>(pool_->NumNeverAssignedConnectJobsInGroup("a")));
3455 EXPECT_EQ(kDefaultMaxSockets - 1,
3456 static_cast<int>(pool_->NumUnassignedConnectJobsInGroup("a")));
[email protected]51fdc7c2012-04-10 19:19:483457 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033458
3459 ASSERT_FALSE(pool_->HasGroup("b"));
3460
Charlie Harrison55ce6082018-05-14 02:25:573461 pool_->RequestSockets("b", &params_, kDefaultMaxSockets, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033462
3463 ASSERT_TRUE(pool_->HasGroup("b"));
Raul Tambre8335a6d2019-02-21 16:57:433464 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("b"));
[email protected]51fdc7c2012-04-10 19:19:483465 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033466}
3467
3468TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
3469 CreatePool(4, 4);
3470 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3471
3472 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523473 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203474 EXPECT_EQ(
3475 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543476 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203477 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503478 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3479 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013480 ASSERT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033481 handle1.Reset();
3482
3483 ASSERT_TRUE(pool_->HasGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433484 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
3485 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3486 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3487 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033488
Charlie Harrison55ce6082018-05-14 02:25:573489 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033490
Raul Tambre8335a6d2019-02-21 16:57:433491 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
3492 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3493 EXPECT_EQ(1u, pool_->NumUnassignedConnectJobsInGroup("a"));
3494 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033495}
3496
3497TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
3498 CreatePool(4, 4);
3499 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3500
3501 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523502 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203503 EXPECT_EQ(
3504 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543505 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203506 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503507 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3508 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013509 ASSERT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033510
3511 ASSERT_TRUE(pool_->HasGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433512 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
3513 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3514 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3515 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033516 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3517
Charlie Harrison55ce6082018-05-14 02:25:573518 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033519
Raul Tambre8335a6d2019-02-21 16:57:433520 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
3521 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3522 EXPECT_EQ(1u, pool_->NumUnassignedConnectJobsInGroup("a"));
3523 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033524 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3525}
3526
3527TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
3528 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3529 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3530
3531 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
Charlie Harrison55ce6082018-05-14 02:25:573532 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033533
3534 ASSERT_TRUE(pool_->HasGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433535 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
3536 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3537 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3538 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
3539 static_cast<int>(pool_->IdleSocketCountInGroup("a")));
[email protected]2c2bef152010-10-13 00:55:033540
3541 pool_->RequestSockets("b", &params_, kDefaultMaxSocketsPerGroup,
Charlie Harrison55ce6082018-05-14 02:25:573542 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033543
Raul Tambre8335a6d2019-02-21 16:57:433544 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("b"));
3545 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("b"));
3546 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("b"));
3547 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
3548 static_cast<int>(pool_->IdleSocketCountInGroup("b")));
[email protected]2c2bef152010-10-13 00:55:033549}
3550
[email protected]3c819f522010-12-02 02:03:123551TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
3552 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3553 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3554
3555 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
Charlie Harrison55ce6082018-05-14 02:25:573556 NetLogWithSource());
[email protected]3c819f522010-12-02 02:03:123557
3558 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]fd2e53e2011-01-14 20:40:523559
3560 connect_job_factory_->set_job_type(
3561 TestConnectJob::kMockAdditionalErrorStateJob);
3562 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
Charlie Harrison55ce6082018-05-14 02:25:573563 NetLogWithSource());
[email protected]fd2e53e2011-01-14 20:40:523564
3565 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]3c819f522010-12-02 02:03:123566}
3567
[email protected]8159a1c2012-06-07 00:00:103568TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
[email protected]2c2bef152010-10-13 00:55:033569 CreatePool(4, 4);
Lily Chenecebf932018-11-02 17:15:433570 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]2c2bef152010-10-13 00:55:033571
Charlie Harrison55ce6082018-05-14 02:25:573572 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033573
3574 ASSERT_TRUE(pool_->HasGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433575 EXPECT_EQ(2u, pool_->NumConnectJobsInGroup("a"));
3576 EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3577 EXPECT_EQ(2u, pool_->NumUnassignedConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433578 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433579 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033580
Charlie Harrison55ce6082018-05-14 02:25:573581 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
Raul Tambre8335a6d2019-02-21 16:57:433582 EXPECT_EQ(2u, pool_->NumConnectJobsInGroup("a"));
3583 EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3584 EXPECT_EQ(2u, pool_->NumUnassignedConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433585 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433586 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033587
3588 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523589 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203590 EXPECT_EQ(
3591 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543592 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203593 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503594 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3595 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:433596
3597 client_socket_factory_.SignalJob(0);
3598 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3599
Raul Tambre8335a6d2019-02-21 16:57:433600 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
3601 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3602 EXPECT_EQ(1u, pool_->NumUnassignedConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433603 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433604 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033605
3606 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523607 TestCompletionCallback callback2;
Lily Chenecebf932018-11-02 17:15:433608 EXPECT_EQ(
3609 ERR_IO_PENDING,
3610 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3611 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503612 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3613 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:433614 client_socket_factory_.SignalJob(0);
3615 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033616
Raul Tambre8335a6d2019-02-21 16:57:433617 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
3618 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3619 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103620 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433621 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103622
[email protected]2c2bef152010-10-13 00:55:033623 handle1.Reset();
3624 handle2.Reset();
3625
Raul Tambre8335a6d2019-02-21 16:57:433626 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
3627 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3628 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433629 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433630 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033631
Charlie Harrison55ce6082018-05-14 02:25:573632 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
Raul Tambre8335a6d2019-02-21 16:57:433633 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
3634 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3635 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433636 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433637 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033638}
3639
3640TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
3641 CreatePool(4, 4);
3642 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3643
Charlie Harrison55ce6082018-05-14 02:25:573644 pool_->RequestSockets("a", &params_, 1, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033645
3646 ASSERT_TRUE(pool_->HasGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433647 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
3648 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3649 EXPECT_EQ(1u, pool_->NumUnassignedConnectJobsInGroup("a"));
3650 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033651
Charlie Harrison55ce6082018-05-14 02:25:573652 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
Raul Tambre8335a6d2019-02-21 16:57:433653 EXPECT_EQ(2u, pool_->NumConnectJobsInGroup("a"));
3654 EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3655 EXPECT_EQ(2u, pool_->NumUnassignedConnectJobsInGroup("a"));
3656 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033657
Charlie Harrison55ce6082018-05-14 02:25:573658 pool_->RequestSockets("a", &params_, 3, NetLogWithSource());
Raul Tambre8335a6d2019-02-21 16:57:433659 EXPECT_EQ(3u, pool_->NumConnectJobsInGroup("a"));
3660 EXPECT_EQ(3u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3661 EXPECT_EQ(3u, pool_->NumUnassignedConnectJobsInGroup("a"));
3662 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033663
Charlie Harrison55ce6082018-05-14 02:25:573664 pool_->RequestSockets("a", &params_, 1, NetLogWithSource());
Raul Tambre8335a6d2019-02-21 16:57:433665 EXPECT_EQ(3u, pool_->NumConnectJobsInGroup("a"));
3666 EXPECT_EQ(3u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3667 EXPECT_EQ(3u, pool_->NumUnassignedConnectJobsInGroup("a"));
3668 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033669}
3670
3671TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
3672 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
Lily Chenecebf932018-11-02 17:15:433673 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]2c2bef152010-10-13 00:55:033674
Charlie Harrison55ce6082018-05-14 02:25:573675 pool_->RequestSockets("a", &params_, 1, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033676
3677 ASSERT_TRUE(pool_->HasGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433678 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
3679 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3680 EXPECT_EQ(1u, pool_->NumUnassignedConnectJobsInGroup("a"));
3681 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033682
3683 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523684 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203685 EXPECT_EQ(
3686 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543687 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203688 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503689 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3690 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033691
Raul Tambre8335a6d2019-02-21 16:57:433692 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
3693 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3694 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3695 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033696
Lily Chenecebf932018-11-02 17:15:433697 client_socket_factory_.SignalJobs();
3698 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3699
Raul Tambre8335a6d2019-02-21 16:57:433700 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
3701 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3702 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3703 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433704 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033705
[email protected]0dc88b32014-03-26 20:12:283706 // Make sure if a preconnected socket is not fully connected when a request
[email protected]034df0f32013-01-07 23:17:483707 // starts, it has a connect start time.
3708 TestLoadTimingInfoConnectedNotReused(handle1);
[email protected]2c2bef152010-10-13 00:55:033709 handle1.Reset();
3710
Raul Tambre8335a6d2019-02-21 16:57:433711 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033712}
3713
[email protected]034df0f32013-01-07 23:17:483714// Checks that fully connected preconnect jobs have no connect times, and are
3715// marked as reused.
3716TEST_F(ClientSocketPoolBaseTest, ConnectedPreconnectJobsHaveNoConnectTimes) {
3717 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3718 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
Charlie Harrison55ce6082018-05-14 02:25:573719 pool_->RequestSockets("a", &params_, 1, NetLogWithSource());
[email protected]034df0f32013-01-07 23:17:483720
3721 ASSERT_TRUE(pool_->HasGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433722 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
3723 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3724 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3725 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup("a"));
[email protected]034df0f32013-01-07 23:17:483726
3727 ClientSocketHandle handle;
3728 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503729 EXPECT_EQ(OK, handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3730 ClientSocketPool::RespectLimits::ENABLED,
3731 callback.callback(),
3732 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
3733 NetLogWithSource()));
[email protected]034df0f32013-01-07 23:17:483734
3735 // Make sure the idle socket was used.
Raul Tambre8335a6d2019-02-21 16:57:433736 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]034df0f32013-01-07 23:17:483737
3738 TestLoadTimingInfoConnectedReused(handle);
3739 handle.Reset();
3740 TestLoadTimingInfoNotConnected(handle);
3741}
3742
[email protected]dcbe168a2010-12-02 03:14:463743// http://crbug.com/64940 regression test.
3744TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
3745 const int kMaxTotalSockets = 3;
3746 const int kMaxSocketsPerGroup = 2;
3747 CreatePool(kMaxTotalSockets, kMaxSocketsPerGroup);
Lily Chenecebf932018-11-02 17:15:433748 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]dcbe168a2010-12-02 03:14:463749
3750 // Note that group name ordering matters here. "a" comes before "b", so
3751 // CloseOneIdleSocket() will try to close "a"'s idle socket.
3752
3753 // Set up one idle socket in "a".
3754 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523755 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203756 EXPECT_EQ(
3757 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543758 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203759 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503760 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3761 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:433762 ASSERT_TRUE(pool_->HasGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433763 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
3764 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3765 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3766 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]dcbe168a2010-12-02 03:14:463767
Lily Chenecebf932018-11-02 17:15:433768 client_socket_factory_.SignalJobs();
robpercival214763f2016-07-01 23:27:013769 ASSERT_THAT(callback1.WaitForResult(), IsOk());
Raul Tambre8335a6d2019-02-21 16:57:433770 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
3771 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3772 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433773 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3774
[email protected]dcbe168a2010-12-02 03:14:463775 handle1.Reset();
Raul Tambre8335a6d2019-02-21 16:57:433776 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup("a"));
[email protected]dcbe168a2010-12-02 03:14:463777
3778 // Set up two active sockets in "b".
3779 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523780 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203781 EXPECT_EQ(
3782 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543783 handle1.Init("b", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203784 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503785 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3786 pool_.get(), NetLogWithSource()));
tfarina428341112016-09-22 13:38:203787 EXPECT_EQ(
3788 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543789 handle2.Init("b", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203790 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503791 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3792 pool_.get(), NetLogWithSource()));
[email protected]dcbe168a2010-12-02 03:14:463793
Lily Chenecebf932018-11-02 17:15:433794 ASSERT_TRUE(pool_->HasGroup("b"));
Raul Tambre8335a6d2019-02-21 16:57:433795 EXPECT_EQ(2u, pool_->NumConnectJobsInGroup("b"));
3796 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("b"));
3797 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("b"));
3798 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("b"));
Lily Chenecebf932018-11-02 17:15:433799
3800 client_socket_factory_.SignalJobs();
robpercival214763f2016-07-01 23:27:013801 ASSERT_THAT(callback1.WaitForResult(), IsOk());
3802 ASSERT_THAT(callback2.WaitForResult(), IsOk());
Raul Tambre8335a6d2019-02-21 16:57:433803 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("b"));
3804 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("b"));
3805 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463806 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3807
3808 // Now we have 1 idle socket in "a" and 2 active sockets in "b". This means
3809 // we've maxed out on sockets, since we set |kMaxTotalSockets| to 3.
3810 // Requesting 2 preconnected sockets for "a" should fail to allocate any more
3811 // sockets for "a", and "b" should still have 2 active sockets.
3812
Charlie Harrison55ce6082018-05-14 02:25:573813 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
Raul Tambre8335a6d2019-02-21 16:57:433814 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
3815 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3816 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3817 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup("a"));
[email protected]dcbe168a2010-12-02 03:14:463818 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433819 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("b"));
3820 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("b"));
3821 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("b"));
3822 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463823 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3824
3825 // Now release the 2 active sockets for "b". This will give us 1 idle socket
3826 // in "a" and 2 idle sockets in "b". Requesting 2 preconnected sockets for
3827 // "a" should result in closing 1 for "b".
3828 handle1.Reset();
3829 handle2.Reset();
Raul Tambre8335a6d2019-02-21 16:57:433830 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463831 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3832
Charlie Harrison55ce6082018-05-14 02:25:573833 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
Raul Tambre8335a6d2019-02-21 16:57:433834 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
3835 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3836 EXPECT_EQ(1u, pool_->NumUnassignedConnectJobsInGroup("a"));
3837 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup("a"));
[email protected]dcbe168a2010-12-02 03:14:463838 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433839 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("b"));
3840 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("b"));
3841 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("b"));
3842 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463843 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3844}
3845
[email protected]b7b8be42011-07-12 12:46:413846TEST_F(ClientSocketPoolBaseTest, PreconnectWithoutBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073847 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3848 pool_->EnableConnectBackupJobs();
3849
3850 // Make the ConnectJob hang until it times out, shorten the timeout.
3851 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3852 connect_job_factory_->set_timeout_duration(
3853 base::TimeDelta::FromMilliseconds(500));
Charlie Harrison55ce6082018-05-14 02:25:573854 pool_->RequestSockets("a", &params_, 1, NetLogWithSource());
Raul Tambre8335a6d2019-02-21 16:57:433855 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
3856 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3857 EXPECT_EQ(1u, pool_->NumUnassignedConnectJobsInGroup("a"));
3858 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073859
[email protected]b7b8be42011-07-12 12:46:413860 // Verify the backup timer doesn't create a backup job, by making
3861 // the backup job a pending job instead of a waiting job, so it
3862 // *would* complete if it were created.
[email protected]a9fc8fc2011-05-10 02:41:073863 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
skyostil4891b25b2015-06-11 11:43:453864 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
Gabriel Charetteea918012018-05-16 11:53:443865 FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated(),
[email protected]2da659e2013-05-23 20:51:343866 base::TimeDelta::FromSeconds(1));
fdoray5eeb7642016-06-22 16:11:283867 base::RunLoop().Run();
[email protected]a9fc8fc2011-05-10 02:41:073868 EXPECT_FALSE(pool_->HasGroup("a"));
3869}
3870
[email protected]b7b8be42011-07-12 12:46:413871TEST_F(ClientSocketPoolBaseTest, PreconnectWithBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073872 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3873 pool_->EnableConnectBackupJobs();
3874
3875 // Make the ConnectJob hang forever.
3876 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
Charlie Harrison55ce6082018-05-14 02:25:573877 pool_->RequestSockets("a", &params_, 1, NetLogWithSource());
Raul Tambre8335a6d2019-02-21 16:57:433878 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
3879 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3880 EXPECT_EQ(1u, pool_->NumUnassignedConnectJobsInGroup("a"));
3881 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
fdoray5eeb7642016-06-22 16:11:283882 base::RunLoop().RunUntilIdle();
[email protected]a9fc8fc2011-05-10 02:41:073883
3884 // Make the backup job be a pending job, so it completes normally.
3885 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3886 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:523887 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503888 EXPECT_EQ(
3889 ERR_IO_PENDING,
3890 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3891 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
3892 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
3893 NetLogWithSource()));
[email protected]b7b8be42011-07-12 12:46:413894 // Timer has started, but the backup connect job shouldn't be created yet.
Raul Tambre8335a6d2019-02-21 16:57:433895 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
3896 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3897 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3898 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073899 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
robpercival214763f2016-07-01 23:27:013900 ASSERT_THAT(callback.WaitForResult(), IsOk());
[email protected]a9fc8fc2011-05-10 02:41:073901
3902 // The hung connect job should still be there, but everything else should be
3903 // complete.
Raul Tambre8335a6d2019-02-21 16:57:433904 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
3905 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3906 EXPECT_EQ(1u, pool_->NumUnassignedConnectJobsInGroup("a"));
3907 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073908 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3909}
3910
[email protected]0dc88b32014-03-26 20:12:283911// Tests that a preconnect that starts out with unread data can still be used.
3912// http://crbug.com/334467
3913TEST_F(ClientSocketPoolBaseTest, PreconnectWithUnreadData) {
3914 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3915 connect_job_factory_->set_job_type(TestConnectJob::kMockUnreadDataJob);
3916
Charlie Harrison55ce6082018-05-14 02:25:573917 pool_->RequestSockets("a", &params_, 1, NetLogWithSource());
[email protected]0dc88b32014-03-26 20:12:283918
3919 ASSERT_TRUE(pool_->HasGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433920 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
3921 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3922 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3923 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup("a"));
[email protected]0dc88b32014-03-26 20:12:283924
3925 // Fail future jobs to be sure that handle receives the preconnected socket
3926 // rather than closing it and making a new one.
3927 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3928 ClientSocketHandle handle;
3929 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503930 EXPECT_EQ(OK, handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3931 ClientSocketPool::RespectLimits::ENABLED,
3932 callback.callback(),
3933 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
3934 NetLogWithSource()));
[email protected]0dc88b32014-03-26 20:12:283935
3936 ASSERT_TRUE(pool_->HasGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433937 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
3938 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3939 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3940 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433941 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
[email protected]0dc88b32014-03-26 20:12:283942
3943 // Drain the pending read.
Bence Békybdbb0e72018-08-07 21:42:593944 EXPECT_EQ(1, handle.socket()->Read(NULL, 1, CompletionOnceCallback()));
[email protected]0dc88b32014-03-26 20:12:283945
3946 TestLoadTimingInfoConnectedReused(handle);
3947 handle.Reset();
3948
3949 // The socket should be usable now that it's idle again.
Raul Tambre8335a6d2019-02-21 16:57:433950 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup("a"));
[email protected]0dc88b32014-03-26 20:12:283951}
3952
Lily Chenecebf932018-11-02 17:15:433953TEST_F(ClientSocketPoolBaseTest, RequestGetsAssignedJob) {
3954 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3955 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3956
3957 ClientSocketHandle handle1;
3958 TestCompletionCallback callback1;
3959 EXPECT_EQ(
3960 ERR_IO_PENDING,
3961 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3962 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503963 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3964 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:433965
Raul Tambre8335a6d2019-02-21 16:57:433966 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
3967 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3968 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3969 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433970
3971 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle1));
3972}
3973
3974TEST_F(ClientSocketPoolBaseTest, MultipleRequestsGetAssignedJobs) {
3975 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3976 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3977
3978 ClientSocketHandle handle1;
3979 TestCompletionCallback callback1;
3980 EXPECT_EQ(
3981 ERR_IO_PENDING,
3982 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3983 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503984 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3985 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:433986
Raul Tambre8335a6d2019-02-21 16:57:433987 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
3988 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3989 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3990 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433991
3992 ClientSocketHandle handle2;
3993 TestCompletionCallback callback2;
3994 EXPECT_EQ(
3995 ERR_IO_PENDING,
3996 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3997 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503998 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3999 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434000
Raul Tambre8335a6d2019-02-21 16:57:434001 EXPECT_EQ(2u, pool_->NumConnectJobsInGroup("a"));
4002 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4003 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
4004 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:434005
4006 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle1));
4007 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle2));
4008
4009 // One job completes. The other request should still have its job.
4010 client_socket_factory_.SignalJob(0);
4011 EXPECT_THAT(callback1.WaitForResult(), IsOk());
4012
Raul Tambre8335a6d2019-02-21 16:57:434013 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4014 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4015 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:434016 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:434017 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:434018
4019 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle2));
4020}
4021
4022TEST_F(ClientSocketPoolBaseTest, PreconnectJobGetsAssignedToRequest) {
4023 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4024 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4025
4026 pool_->RequestSockets("a", &params_, 1, NetLogWithSource());
4027
4028 ASSERT_TRUE(pool_->HasGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:434029 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4030 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4031 EXPECT_EQ(1u, pool_->NumUnassignedConnectJobsInGroup("a"));
4032 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:434033
4034 ClientSocketHandle handle1;
4035 TestCompletionCallback callback1;
4036 EXPECT_EQ(
4037 ERR_IO_PENDING,
4038 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
4039 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504040 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4041 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434042
Raul Tambre8335a6d2019-02-21 16:57:434043 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4044 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4045 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
4046 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:434047
4048 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle1));
4049}
4050
4051TEST_F(ClientSocketPoolBaseTest, HigherPriorityRequestStealsJob) {
4052 CreatePool(kDefaultMaxSockets, 1);
4053 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4054
4055 ClientSocketHandle handle1;
4056 TestCompletionCallback callback1;
4057 EXPECT_EQ(
4058 ERR_IO_PENDING,
4059 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
4060 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504061 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4062 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434063
Raul Tambre8335a6d2019-02-21 16:57:434064 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4065 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4066 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
4067 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:434068
4069 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle1));
4070
4071 // Insert a higher priority request
4072 ClientSocketHandle handle2;
4073 TestCompletionCallback callback2;
4074 EXPECT_EQ(
4075 ERR_IO_PENDING,
4076 handle2.Init("a", params_, HIGHEST, SocketTag(),
4077 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504078 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4079 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434080
Raul Tambre8335a6d2019-02-21 16:57:434081 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4082 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4083 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
4084 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:434085
4086 // The highest priority request should steal the job from the default priority
4087 // request.
4088 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle2));
4089 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle1));
4090}
4091
4092TEST_F(ClientSocketPoolBaseTest, RequestStealsJobFromLowestRequestWithJob) {
4093 CreatePool(3, 3);
4094 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4095
4096 ClientSocketHandle handle_lowest;
4097 TestCompletionCallback callback_lowest;
4098 EXPECT_EQ(ERR_IO_PENDING,
4099 handle_lowest.Init("a", params_, LOWEST, SocketTag(),
4100 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504101 callback_lowest.callback(),
4102 ClientSocketPool::ProxyAuthCallback(),
4103 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434104
Raul Tambre8335a6d2019-02-21 16:57:434105 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4106 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4107 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
4108 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:434109
4110 ClientSocketHandle handle_highest;
4111 TestCompletionCallback callback_highest;
4112 EXPECT_EQ(ERR_IO_PENDING,
4113 handle_highest.Init("a", params_, HIGHEST, SocketTag(),
4114 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504115 callback_highest.callback(),
4116 ClientSocketPool::ProxyAuthCallback(),
4117 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434118
Raul Tambre8335a6d2019-02-21 16:57:434119 EXPECT_EQ(2u, pool_->NumConnectJobsInGroup("a"));
4120 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4121 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
4122 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:434123
4124 ClientSocketHandle handle_low;
4125 TestCompletionCallback callback_low;
4126 EXPECT_EQ(ERR_IO_PENDING,
4127 handle_low.Init("a", params_, LOW, SocketTag(),
4128 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504129 callback_low.callback(),
4130 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
Lily Chenecebf932018-11-02 17:15:434131 NetLogWithSource()));
4132
Raul Tambre8335a6d2019-02-21 16:57:434133 EXPECT_EQ(3u, pool_->NumConnectJobsInGroup("a"));
4134 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4135 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
4136 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:434137
4138 ClientSocketHandle handle_lowest2;
4139 TestCompletionCallback callback_lowest2;
4140 EXPECT_EQ(ERR_IO_PENDING,
4141 handle_lowest2.Init("a", params_, LOWEST, SocketTag(),
4142 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504143 callback_lowest2.callback(),
4144 ClientSocketPool::ProxyAuthCallback(),
4145 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434146
Raul Tambre8335a6d2019-02-21 16:57:434147 EXPECT_EQ(3u, pool_->NumConnectJobsInGroup("a"));
4148 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4149 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
4150 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:434151
4152 // The top three requests in the queue should have jobs.
4153 EXPECT_TRUE(
4154 pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle_highest));
4155 EXPECT_TRUE(
4156 pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle_low));
4157 EXPECT_TRUE(
4158 pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle_lowest));
4159 EXPECT_FALSE(
4160 pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle_lowest2));
4161
4162 // Add another request with medium priority. It should steal the job from the
4163 // lowest priority request with a job.
4164 ClientSocketHandle handle_medium;
4165 TestCompletionCallback callback_medium;
4166 EXPECT_EQ(ERR_IO_PENDING,
4167 handle_medium.Init("a", params_, MEDIUM, SocketTag(),
4168 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504169 callback_medium.callback(),
4170 ClientSocketPool::ProxyAuthCallback(),
4171 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434172
Raul Tambre8335a6d2019-02-21 16:57:434173 EXPECT_EQ(3u, pool_->NumConnectJobsInGroup("a"));
4174 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4175 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
4176 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:434177 EXPECT_TRUE(
4178 pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle_highest));
4179 EXPECT_TRUE(
4180 pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle_medium));
4181 EXPECT_TRUE(
4182 pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle_low));
4183 EXPECT_FALSE(
4184 pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle_lowest));
4185 EXPECT_FALSE(
4186 pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle_lowest2));
4187}
4188
4189TEST_F(ClientSocketPoolBaseTest, ReprioritizeRequestStealsJob) {
4190 CreatePool(kDefaultMaxSockets, 1);
4191 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4192
4193 ClientSocketHandle handle1;
4194 TestCompletionCallback callback1;
4195 EXPECT_EQ(
4196 ERR_IO_PENDING,
4197 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
4198 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504199 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4200 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434201
Raul Tambre8335a6d2019-02-21 16:57:434202 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4203 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4204 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
4205 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:434206
4207 ClientSocketHandle handle2;
4208 TestCompletionCallback callback2;
4209 EXPECT_EQ(
4210 ERR_IO_PENDING,
4211 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
4212 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504213 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4214 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434215
Raul Tambre8335a6d2019-02-21 16:57:434216 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4217 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4218 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
4219 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:434220
4221 // The second request doesn't get a job because we are at the limit.
4222 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle1));
4223 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle2));
4224
4225 // Reprioritizing the second request places it above the first, and it steals
4226 // the job from the first request.
4227 pool_->SetPriority("a", &handle2, HIGHEST);
4228 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle2));
4229 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle1));
4230}
4231
4232TEST_F(ClientSocketPoolBaseTest, CancelRequestReassignsJob) {
4233 CreatePool(kDefaultMaxSockets, 1);
4234 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4235
4236 ClientSocketHandle handle1;
4237 TestCompletionCallback callback1;
4238 EXPECT_EQ(
4239 ERR_IO_PENDING,
4240 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
4241 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504242 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4243 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434244
Raul Tambre8335a6d2019-02-21 16:57:434245 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4246 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4247 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
4248 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:434249
4250 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle1));
4251
4252 ClientSocketHandle handle2;
4253 TestCompletionCallback callback2;
4254 EXPECT_EQ(
4255 ERR_IO_PENDING,
4256 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
4257 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504258 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4259 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434260
Raul Tambre8335a6d2019-02-21 16:57:434261 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4262 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4263 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
4264 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:434265
4266 // The second request doesn't get a job because we are the limit.
4267 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle1));
4268 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle2));
4269
4270 // The second request should get a job upon cancelling the first request.
4271 handle1.Reset();
Raul Tambre8335a6d2019-02-21 16:57:434272 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4273 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4274 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
4275 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:434276
4277 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle2));
4278}
4279
4280TEST_F(ClientSocketPoolBaseTest, JobCompletionReassignsJob) {
4281 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4282 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4283
4284 ClientSocketHandle handle1;
4285 TestCompletionCallback callback1;
4286 EXPECT_EQ(
4287 ERR_IO_PENDING,
4288 handle1.Init("a", params_, HIGHEST, SocketTag(),
4289 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504290 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4291 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434292
Raul Tambre8335a6d2019-02-21 16:57:434293 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4294 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4295 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
4296 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:434297
4298 ClientSocketHandle handle2;
4299 TestCompletionCallback callback2;
4300 EXPECT_EQ(
4301 ERR_IO_PENDING,
4302 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
4303 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504304 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4305 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434306
Raul Tambre8335a6d2019-02-21 16:57:434307 EXPECT_EQ(2u, pool_->NumConnectJobsInGroup("a"));
4308 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4309 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
4310 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:434311
4312 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle1));
4313 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle2));
4314
4315 // The lower-priority job completes first. The higher-priority request should
4316 // get the socket, and the lower-priority request should get the remaining
4317 // job.
4318 client_socket_factory_.SignalJob(1);
4319 EXPECT_THAT(callback1.WaitForResult(), IsOk());
Raul Tambre8335a6d2019-02-21 16:57:434320 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4321 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4322 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:434323 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:434324 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:434325 EXPECT_TRUE(handle1.socket());
4326 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle2));
4327}
4328
[email protected]043b68c82013-08-22 23:41:524329class MockLayeredPool : public HigherLayeredPool {
[email protected]58e562f2013-04-22 17:32:204330 public:
4331 MockLayeredPool(TestClientSocketPool* pool,
4332 const std::string& group_name)
4333 : pool_(pool),
[email protected]58e562f2013-04-22 17:32:204334 group_name_(group_name),
4335 can_release_connection_(true) {
[email protected]043b68c82013-08-22 23:41:524336 pool_->AddHigherLayeredPool(this);
[email protected]58e562f2013-04-22 17:32:204337 }
4338
Daniel Cheng4496d0822018-04-26 21:52:154339 ~MockLayeredPool() override { pool_->RemoveHigherLayeredPool(this); }
[email protected]58e562f2013-04-22 17:32:204340
4341 int RequestSocket(TestClientSocketPool* pool) {
mmenked3641e12016-01-28 16:06:154342 scoped_refptr<TestSocketParams> params(new TestSocketParams());
Matt Menke28ac03e2019-02-25 22:25:504343 return handle_.Init(
4344 group_name_, params, DEFAULT_PRIORITY, SocketTag(),
4345 ClientSocketPool::RespectLimits::ENABLED, callback_.callback(),
4346 ClientSocketPool::ProxyAuthCallback(), pool, NetLogWithSource());
[email protected]58e562f2013-04-22 17:32:204347 }
4348
4349 int RequestSocketWithoutLimits(TestClientSocketPool* pool) {
mmenked3641e12016-01-28 16:06:154350 scoped_refptr<TestSocketParams> params(new TestSocketParams());
Matt Menke28ac03e2019-02-25 22:25:504351 return handle_.Init(
4352 group_name_, params, MAXIMUM_PRIORITY, SocketTag(),
4353 ClientSocketPool::RespectLimits::DISABLED, callback_.callback(),
4354 ClientSocketPool::ProxyAuthCallback(), pool, NetLogWithSource());
[email protected]58e562f2013-04-22 17:32:204355 }
4356
4357 bool ReleaseOneConnection() {
4358 if (!handle_.is_initialized() || !can_release_connection_) {
4359 return false;
4360 }
4361 handle_.socket()->Disconnect();
4362 handle_.Reset();
4363 return true;
4364 }
4365
4366 void set_can_release_connection(bool can_release_connection) {
4367 can_release_connection_ = can_release_connection;
4368 }
4369
4370 MOCK_METHOD0(CloseOneIdleConnection, bool());
4371
4372 private:
4373 TestClientSocketPool* const pool_;
[email protected]58e562f2013-04-22 17:32:204374 ClientSocketHandle handle_;
4375 TestCompletionCallback callback_;
4376 const std::string group_name_;
4377 bool can_release_connection_;
4378};
4379
[email protected]58e562f2013-04-22 17:32:204380// Tests the basic case of closing an idle socket in a higher layered pool when
4381// a new request is issued and the lower layer pool is stalled.
4382TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsHeldByLayeredPoolWhenNeeded) {
4383 CreatePool(1, 1);
4384 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4385
4386 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
robpercival214763f2016-07-01 23:27:014387 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204388 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4389 .WillOnce(Invoke(&mock_layered_pool,
4390 &MockLayeredPool::ReleaseOneConnection));
4391 ClientSocketHandle handle;
4392 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:504393 EXPECT_EQ(
4394 ERR_IO_PENDING,
4395 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
4396 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
4397 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4398 NetLogWithSource()));
robpercival214763f2016-07-01 23:27:014399 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204400}
4401
Matt Menke833678642019-03-05 22:05:514402// Tests the case that trying to close an idle socket in a higher layered pool
4403// fails.
4404TEST_F(ClientSocketPoolBaseTest,
4405 CloseIdleSocketsHeldByLayeredPoolWhenNeededFails) {
4406 CreatePool(1, 1);
4407 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4408
4409 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
4410 mock_layered_pool.set_can_release_connection(false);
4411 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
4412 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4413 .WillOnce(Invoke(&mock_layered_pool,
4414 &MockLayeredPool::ReleaseOneConnection));
4415 ClientSocketHandle handle;
4416 TestCompletionCallback callback;
4417 EXPECT_EQ(
4418 ERR_IO_PENDING,
4419 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
4420 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
4421 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4422 NetLogWithSource()));
4423 base::RunLoop().RunUntilIdle();
4424 EXPECT_FALSE(callback.have_result());
4425}
4426
[email protected]58e562f2013-04-22 17:32:204427// Same as above, but the idle socket is in the same group as the stalled
4428// socket, and closes the only other request in its group when closing requests
4429// in higher layered pools. This generally shouldn't happen, but it may be
4430// possible if a higher level pool issues a request and the request is
4431// subsequently cancelled. Even if it's not possible, best not to crash.
4432TEST_F(ClientSocketPoolBaseTest,
4433 CloseIdleSocketsHeldByLayeredPoolWhenNeededSameGroup) {
4434 CreatePool(2, 2);
4435 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4436
4437 // Need a socket in another group for the pool to be stalled (If a group
4438 // has the maximum number of connections already, it's not stalled).
4439 ClientSocketHandle handle1;
4440 TestCompletionCallback callback1;
Matt Menke28ac03e2019-02-25 22:25:504441 EXPECT_EQ(OK, handle1.Init("group1", params_, DEFAULT_PRIORITY, SocketTag(),
4442 ClientSocketPool::RespectLimits::ENABLED,
4443 callback1.callback(),
4444 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4445 NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204446
4447 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
robpercival214763f2016-07-01 23:27:014448 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204449 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4450 .WillOnce(Invoke(&mock_layered_pool,
4451 &MockLayeredPool::ReleaseOneConnection));
4452 ClientSocketHandle handle;
4453 TestCompletionCallback callback2;
Matt Menke28ac03e2019-02-25 22:25:504454 EXPECT_EQ(
4455 ERR_IO_PENDING,
4456 handle.Init("group2", params_, DEFAULT_PRIORITY, SocketTag(),
4457 ClientSocketPool::RespectLimits::ENABLED,
4458 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4459 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:014460 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204461}
4462
4463// Tests the case when an idle socket can be closed when a new request is
4464// issued, and the new request belongs to a group that was previously stalled.
4465TEST_F(ClientSocketPoolBaseTest,
4466 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded) {
4467 CreatePool(2, 2);
4468 std::list<TestConnectJob::JobType> job_types;
4469 job_types.push_back(TestConnectJob::kMockJob);
4470 job_types.push_back(TestConnectJob::kMockJob);
4471 job_types.push_back(TestConnectJob::kMockJob);
4472 job_types.push_back(TestConnectJob::kMockJob);
4473 connect_job_factory_->set_job_types(&job_types);
4474
4475 ClientSocketHandle handle1;
4476 TestCompletionCallback callback1;
Matt Menke28ac03e2019-02-25 22:25:504477 EXPECT_EQ(OK, handle1.Init("group1", params_, DEFAULT_PRIORITY, SocketTag(),
4478 ClientSocketPool::RespectLimits::ENABLED,
4479 callback1.callback(),
4480 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4481 NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204482
4483 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
robpercival214763f2016-07-01 23:27:014484 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204485 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4486 .WillRepeatedly(Invoke(&mock_layered_pool,
4487 &MockLayeredPool::ReleaseOneConnection));
4488 mock_layered_pool.set_can_release_connection(false);
4489
4490 // The third request is made when the socket pool is in a stalled state.
4491 ClientSocketHandle handle3;
4492 TestCompletionCallback callback3;
tfarina428341112016-09-22 13:38:204493 EXPECT_EQ(
4494 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:544495 handle3.Init("group3", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:204496 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504497 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
4498 pool_.get(), NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204499
4500 base::RunLoop().RunUntilIdle();
4501 EXPECT_FALSE(callback3.have_result());
4502
4503 // The fourth request is made when the pool is no longer stalled. The third
4504 // request should be serviced first, since it was issued first and has the
4505 // same priority.
4506 mock_layered_pool.set_can_release_connection(true);
4507 ClientSocketHandle handle4;
4508 TestCompletionCallback callback4;
tfarina428341112016-09-22 13:38:204509 EXPECT_EQ(
4510 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:544511 handle4.Init("group3", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:204512 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504513 callback4.callback(), ClientSocketPool::ProxyAuthCallback(),
4514 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:014515 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204516 EXPECT_FALSE(callback4.have_result());
4517
4518 // Closing a handle should free up another socket slot.
4519 handle1.Reset();
robpercival214763f2016-07-01 23:27:014520 EXPECT_THAT(callback4.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204521}
4522
4523// Tests the case when an idle socket can be closed when a new request is
4524// issued, and the new request belongs to a group that was previously stalled.
4525//
4526// The two differences from the above test are that the stalled requests are not
4527// in the same group as the layered pool's request, and the the fourth request
4528// has a higher priority than the third one, so gets a socket first.
4529TEST_F(ClientSocketPoolBaseTest,
4530 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded2) {
4531 CreatePool(2, 2);
4532 std::list<TestConnectJob::JobType> job_types;
4533 job_types.push_back(TestConnectJob::kMockJob);
4534 job_types.push_back(TestConnectJob::kMockJob);
4535 job_types.push_back(TestConnectJob::kMockJob);
4536 job_types.push_back(TestConnectJob::kMockJob);
4537 connect_job_factory_->set_job_types(&job_types);
4538
4539 ClientSocketHandle handle1;
4540 TestCompletionCallback callback1;
Matt Menke28ac03e2019-02-25 22:25:504541 EXPECT_EQ(OK, handle1.Init("group1", params_, DEFAULT_PRIORITY, SocketTag(),
4542 ClientSocketPool::RespectLimits::ENABLED,
4543 callback1.callback(),
4544 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4545 NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204546
4547 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
robpercival214763f2016-07-01 23:27:014548 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204549 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4550 .WillRepeatedly(Invoke(&mock_layered_pool,
4551 &MockLayeredPool::ReleaseOneConnection));
4552 mock_layered_pool.set_can_release_connection(false);
4553
4554 // The third request is made when the socket pool is in a stalled state.
4555 ClientSocketHandle handle3;
4556 TestCompletionCallback callback3;
tfarina428341112016-09-22 13:38:204557 EXPECT_EQ(
4558 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:544559 handle3.Init("group3", params_, MEDIUM, SocketTag(),
tfarina428341112016-09-22 13:38:204560 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504561 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
4562 pool_.get(), NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204563
4564 base::RunLoop().RunUntilIdle();
4565 EXPECT_FALSE(callback3.have_result());
4566
4567 // The fourth request is made when the pool is no longer stalled. This
4568 // request has a higher priority than the third request, so is serviced first.
4569 mock_layered_pool.set_can_release_connection(true);
4570 ClientSocketHandle handle4;
4571 TestCompletionCallback callback4;
tfarina428341112016-09-22 13:38:204572 EXPECT_EQ(
4573 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:544574 handle4.Init("group3", params_, HIGHEST, SocketTag(),
tfarina428341112016-09-22 13:38:204575 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504576 callback4.callback(), ClientSocketPool::ProxyAuthCallback(),
4577 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:014578 EXPECT_THAT(callback4.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204579 EXPECT_FALSE(callback3.have_result());
4580
4581 // Closing a handle should free up another socket slot.
4582 handle1.Reset();
robpercival214763f2016-07-01 23:27:014583 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204584}
4585
4586TEST_F(ClientSocketPoolBaseTest,
4587 CloseMultipleIdleSocketsHeldByLayeredPoolWhenNeeded) {
4588 CreatePool(1, 1);
4589 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4590
4591 MockLayeredPool mock_layered_pool1(pool_.get(), "foo");
robpercival214763f2016-07-01 23:27:014592 EXPECT_THAT(mock_layered_pool1.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204593 EXPECT_CALL(mock_layered_pool1, CloseOneIdleConnection())
4594 .WillRepeatedly(Invoke(&mock_layered_pool1,
4595 &MockLayeredPool::ReleaseOneConnection));
4596 MockLayeredPool mock_layered_pool2(pool_.get(), "bar");
robpercival214763f2016-07-01 23:27:014597 EXPECT_THAT(mock_layered_pool2.RequestSocketWithoutLimits(pool_.get()),
4598 IsOk());
[email protected]58e562f2013-04-22 17:32:204599 EXPECT_CALL(mock_layered_pool2, CloseOneIdleConnection())
4600 .WillRepeatedly(Invoke(&mock_layered_pool2,
4601 &MockLayeredPool::ReleaseOneConnection));
4602 ClientSocketHandle handle;
4603 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:504604 EXPECT_EQ(
4605 ERR_IO_PENDING,
4606 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
4607 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
4608 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4609 NetLogWithSource()));
robpercival214763f2016-07-01 23:27:014610 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204611}
4612
[email protected]b021ece62013-06-11 11:06:334613// Test that when a socket pool and group are at their limits, a request
mmenked3641e12016-01-28 16:06:154614// with RespectLimits::DISABLED triggers creation of a new socket, and gets the
4615// socket instead of a request with the same priority that was issued earlier,
4616// but has RespectLimits::ENABLED.
[email protected]b021ece62013-06-11 11:06:334617TEST_F(ClientSocketPoolBaseTest, IgnoreLimits) {
[email protected]b021ece62013-06-11 11:06:334618 CreatePool(1, 1);
4619
4620 // Issue a request to reach the socket pool limit.
mmenked3641e12016-01-28 16:06:154621 EXPECT_EQ(
4622 OK, StartRequestWithIgnoreLimits(
4623 "a", MAXIMUM_PRIORITY, ClientSocketPool::RespectLimits::ENABLED));
Raul Tambre8335a6d2019-02-21 16:57:434624 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
[email protected]b021ece62013-06-11 11:06:334625
4626 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4627
mmenked3641e12016-01-28 16:06:154628 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
4629 "a", MAXIMUM_PRIORITY,
4630 ClientSocketPool::RespectLimits::ENABLED));
Raul Tambre8335a6d2019-02-21 16:57:434631 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
[email protected]b021ece62013-06-11 11:06:334632
mmenked3641e12016-01-28 16:06:154633 // Issue a request that ignores the limits, so a new ConnectJob is
4634 // created.
4635 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
4636 "a", MAXIMUM_PRIORITY,
4637 ClientSocketPool::RespectLimits::DISABLED));
Raul Tambre8335a6d2019-02-21 16:57:434638 ASSERT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
[email protected]b021ece62013-06-11 11:06:334639
robpercival214763f2016-07-01 23:27:014640 EXPECT_THAT(request(2)->WaitForResult(), IsOk());
[email protected]b021ece62013-06-11 11:06:334641 EXPECT_FALSE(request(1)->have_result());
4642}
4643
[email protected]c55fabd2013-11-04 23:26:564644// Test that when a socket pool and group are at their limits, a ConnectJob
mmenked3641e12016-01-28 16:06:154645// issued for a request with RespectLimits::DISABLED is not cancelled when a
4646// request with RespectLimits::ENABLED issued to the same group is cancelled.
[email protected]c55fabd2013-11-04 23:26:564647TEST_F(ClientSocketPoolBaseTest, IgnoreLimitsCancelOtherJob) {
[email protected]c55fabd2013-11-04 23:26:564648 CreatePool(1, 1);
4649
4650 // Issue a request to reach the socket pool limit.
mmenked3641e12016-01-28 16:06:154651 EXPECT_EQ(
4652 OK, StartRequestWithIgnoreLimits(
4653 "a", MAXIMUM_PRIORITY, ClientSocketPool::RespectLimits::ENABLED));
Raul Tambre8335a6d2019-02-21 16:57:434654 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
[email protected]c55fabd2013-11-04 23:26:564655
4656 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4657
mmenked3641e12016-01-28 16:06:154658 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
4659 "a", MAXIMUM_PRIORITY,
4660 ClientSocketPool::RespectLimits::ENABLED));
Raul Tambre8335a6d2019-02-21 16:57:434661 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
[email protected]c55fabd2013-11-04 23:26:564662
mmenked3641e12016-01-28 16:06:154663 // Issue a request with RespectLimits::DISABLED, so a new ConnectJob is
4664 // created.
4665 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
4666 "a", MAXIMUM_PRIORITY,
4667 ClientSocketPool::RespectLimits::DISABLED));
Raul Tambre8335a6d2019-02-21 16:57:434668 ASSERT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
[email protected]b021ece62013-06-11 11:06:334669
mmenked3641e12016-01-28 16:06:154670 // Cancel the pending request with RespectLimits::ENABLED. The ConnectJob
[email protected]b021ece62013-06-11 11:06:334671 // should not be cancelled.
4672 request(1)->handle()->Reset();
Raul Tambre8335a6d2019-02-21 16:57:434673 ASSERT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
[email protected]b021ece62013-06-11 11:06:334674
robpercival214763f2016-07-01 23:27:014675 EXPECT_THAT(request(2)->WaitForResult(), IsOk());
[email protected]b021ece62013-06-11 11:06:334676 EXPECT_FALSE(request(1)->have_result());
4677}
4678
Matt Menkeb57663b32019-03-01 17:17:104679TEST_F(ClientSocketPoolBaseTest, ProxyAuthNoAuthCallback) {
4680 CreatePool(1, 1);
4681
4682 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
4683
4684 ClientSocketHandle handle;
4685 TestCompletionCallback callback;
4686 EXPECT_EQ(
4687 ERR_IO_PENDING,
4688 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
4689 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
4690 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4691 NetLogWithSource()));
4692
4693 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4694
4695 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_PROXY_AUTH_REQUESTED));
4696 EXPECT_FALSE(handle.is_initialized());
4697 EXPECT_FALSE(handle.socket());
4698
4699 // The group should now be empty, and thus be deleted.
4700 EXPECT_FALSE(pool_->HasGroup("a"));
4701}
4702
4703class TestAuthHelper {
4704 public:
4705 TestAuthHelper() = default;
4706 ~TestAuthHelper() = default;
4707
4708 void InitHandle(scoped_refptr<TestSocketParams> params,
4709 TestClientSocketPool* pool,
4710 RequestPriority priority = DEFAULT_PRIORITY,
4711 ClientSocketPool::RespectLimits respect_limits =
4712 ClientSocketPool::RespectLimits::ENABLED,
4713 const char* group_name = "a") {
4714 EXPECT_EQ(ERR_IO_PENDING,
4715 handle_.Init(group_name, params.get(), priority, SocketTag(),
4716 respect_limits, callback_.callback(),
4717 base::BindRepeating(&TestAuthHelper::AuthCallback,
4718 base::Unretained(this)),
4719 pool, NetLogWithSource()));
4720 }
4721
4722 void WaitForAuth() {
4723 run_loop_ = std::make_unique<base::RunLoop>();
4724 run_loop_->Run();
4725 run_loop_.reset();
4726 }
4727
4728 void WaitForAuthAndRestartSync() {
4729 restart_sync_ = true;
4730 WaitForAuth();
4731 restart_sync_ = false;
4732 }
4733
4734 void WaitForAuthAndResetHandleSync() {
4735 reset_handle_sync_ = true;
4736 WaitForAuth();
4737 reset_handle_sync_ = false;
4738 }
4739
4740 void RestartWithAuth() {
4741 DCHECK(restart_with_auth_callback_);
4742 std::move(restart_with_auth_callback_).Run();
4743 }
4744
4745 int WaitForResult() {
4746 int result = callback_.WaitForResult();
4747 // There shouldn't be any callback waiting to be invoked once the request is
4748 // complete.
4749 EXPECT_FALSE(restart_with_auth_callback_);
4750 // The socket should only be initialized on success.
4751 EXPECT_EQ(result == OK, handle_.is_initialized());
4752 EXPECT_EQ(result == OK, handle_.socket() != nullptr);
4753 return result;
4754 }
4755
4756 ClientSocketHandle* handle() { return &handle_; }
4757 int auth_count() const { return auth_count_; }
4758 int have_result() const { return callback_.have_result(); }
4759
4760 private:
4761 void AuthCallback(const HttpResponseInfo& response,
4762 HttpAuthController* auth_controller,
4763 base::OnceClosure restart_with_auth_callback) {
4764 EXPECT_FALSE(restart_with_auth_callback_);
4765 EXPECT_TRUE(restart_with_auth_callback);
4766
4767 // Once there's a result, this method shouldn't be invoked again.
4768 EXPECT_FALSE(callback_.have_result());
4769
4770 ++auth_count_;
4771 run_loop_->Quit();
4772 if (restart_sync_) {
4773 std::move(restart_with_auth_callback).Run();
4774 return;
4775 }
4776
4777 restart_with_auth_callback_ = std::move(restart_with_auth_callback);
4778
4779 if (reset_handle_sync_) {
4780 handle_.Reset();
4781 return;
4782 }
4783 }
4784
4785 std::unique_ptr<base::RunLoop> run_loop_;
4786 base::OnceClosure restart_with_auth_callback_;
4787
4788 bool restart_sync_ = false;
4789 bool reset_handle_sync_ = false;
4790
4791 ClientSocketHandle handle_;
4792 int auth_count_ = 0;
4793 TestCompletionCallback callback_;
4794
4795 DISALLOW_COPY_AND_ASSIGN(TestAuthHelper);
4796};
4797
4798TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnce) {
4799 CreatePool(1, 1);
4800 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
4801
4802 TestAuthHelper auth_helper;
4803 auth_helper.InitHandle(params_, pool_.get());
4804 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
Matt Menke4b69f932019-03-04 16:20:014805 EXPECT_EQ(LOAD_STATE_CONNECTING,
4806 pool_->GetLoadState("a", auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:104807
4808 auth_helper.WaitForAuth();
4809 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
Matt Menke4b69f932019-03-04 16:20:014810 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
4811 pool_->GetLoadState("a", auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:104812
4813 auth_helper.RestartWithAuth();
4814 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
Matt Menke4b69f932019-03-04 16:20:014815 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
4816 pool_->GetLoadState("a", auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:104817
4818 EXPECT_THAT(auth_helper.WaitForResult(), IsOk());
4819 EXPECT_EQ(1, auth_helper.auth_count());
4820 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
4821 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
4822 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
4823 EXPECT_EQ(0, pool_->IdleSocketCount());
4824}
4825
4826TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceSync) {
4827 CreatePool(1, 1);
4828 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
4829
4830 TestAuthHelper auth_helper;
4831 auth_helper.InitHandle(params_, pool_.get());
4832 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
Matt Menke4b69f932019-03-04 16:20:014833 EXPECT_EQ(LOAD_STATE_CONNECTING,
4834 pool_->GetLoadState("a", auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:104835
4836 auth_helper.WaitForAuthAndRestartSync();
4837 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
Matt Menke4b69f932019-03-04 16:20:014838 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
4839 pool_->GetLoadState("a", auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:104840
4841 EXPECT_THAT(auth_helper.WaitForResult(), IsOk());
4842 EXPECT_EQ(1, auth_helper.auth_count());
4843 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
4844 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
4845 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
4846 EXPECT_EQ(0, pool_->IdleSocketCount());
4847}
4848
4849TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceFails) {
4850 CreatePool(1, 1);
4851 connect_job_factory_->set_job_type(
4852 TestConnectJob::kMockAuthChallengeOnceFailingJob);
4853
4854 TestAuthHelper auth_helper;
4855 auth_helper.InitHandle(params_, pool_.get());
4856 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4857
4858 auth_helper.WaitForAuth();
4859 auth_helper.RestartWithAuth();
4860 EXPECT_THAT(auth_helper.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
4861
4862 EXPECT_EQ(1, auth_helper.auth_count());
4863 EXPECT_FALSE(pool_->HasGroup("a"));
4864 EXPECT_EQ(0, pool_->IdleSocketCount());
4865}
4866
4867TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceSyncFails) {
4868 CreatePool(1, 1);
4869 connect_job_factory_->set_job_type(
4870 TestConnectJob::kMockAuthChallengeOnceFailingJob);
4871
4872 TestAuthHelper auth_helper;
4873 auth_helper.InitHandle(params_, pool_.get());
4874 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4875
4876 auth_helper.WaitForAuthAndRestartSync();
4877 EXPECT_THAT(auth_helper.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
4878
4879 EXPECT_EQ(1, auth_helper.auth_count());
4880 EXPECT_FALSE(pool_->HasGroup("a"));
4881 EXPECT_EQ(0, pool_->IdleSocketCount());
4882}
4883
4884TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceDeleteHandle) {
4885 CreatePool(1, 1);
4886 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
4887
4888 TestAuthHelper auth_helper;
4889 auth_helper.InitHandle(params_, pool_.get());
4890 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4891
4892 auth_helper.WaitForAuth();
4893 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4894
4895 auth_helper.handle()->Reset();
4896
4897 EXPECT_EQ(1, auth_helper.auth_count());
4898 EXPECT_FALSE(pool_->HasGroup("a"));
4899 EXPECT_EQ(0, pool_->IdleSocketCount());
4900 EXPECT_FALSE(auth_helper.handle()->is_initialized());
4901 EXPECT_FALSE(auth_helper.handle()->socket());
4902}
4903
4904TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceDeleteHandleSync) {
4905 CreatePool(1, 1);
4906 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
4907
4908 TestAuthHelper auth_helper;
4909 auth_helper.InitHandle(params_, pool_.get());
4910 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4911
4912 auth_helper.WaitForAuthAndResetHandleSync();
4913 EXPECT_EQ(1, auth_helper.auth_count());
4914 EXPECT_FALSE(pool_->HasGroup("a"));
4915 EXPECT_EQ(0, pool_->IdleSocketCount());
4916 EXPECT_FALSE(auth_helper.handle()->is_initialized());
4917 EXPECT_FALSE(auth_helper.handle()->socket());
4918}
4919
4920TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceFlushWithError) {
4921 CreatePool(1, 1);
4922 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
4923
4924 TestAuthHelper auth_helper;
4925 auth_helper.InitHandle(params_, pool_.get());
4926 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4927
4928 auth_helper.WaitForAuth();
4929
4930 pool_->FlushWithError(ERR_FAILED);
4931 base::RunLoop().RunUntilIdle();
4932
4933 // When flushing the socket pool, bound sockets should delay returning the
4934 // error until completion.
4935 EXPECT_FALSE(auth_helper.have_result());
4936 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4937 EXPECT_EQ(0, pool_->IdleSocketCount());
4938
4939 auth_helper.RestartWithAuth();
4940 // The callback should be called asynchronously.
4941 EXPECT_FALSE(auth_helper.have_result());
4942
4943 EXPECT_THAT(auth_helper.WaitForResult(), IsError(ERR_FAILED));
4944 EXPECT_FALSE(pool_->HasGroup("a"));
4945 EXPECT_EQ(0, pool_->IdleSocketCount());
4946}
4947
4948TEST_F(ClientSocketPoolBaseTest, ProxyAuthTwice) {
4949 CreatePool(1, 1);
4950 connect_job_factory_->set_job_type(
4951 TestConnectJob::kMockAuthChallengeTwiceJob);
4952
4953 TestAuthHelper auth_helper;
4954 auth_helper.InitHandle(params_, pool_.get());
4955 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
Matt Menke4b69f932019-03-04 16:20:014956 EXPECT_EQ(LOAD_STATE_CONNECTING,
4957 pool_->GetLoadState("a", auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:104958
4959 auth_helper.WaitForAuth();
4960 auth_helper.RestartWithAuth();
4961 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4962 EXPECT_EQ(1, auth_helper.auth_count());
Matt Menke4b69f932019-03-04 16:20:014963 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
4964 pool_->GetLoadState("a", auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:104965
4966 auth_helper.WaitForAuth();
Matt Menke4b69f932019-03-04 16:20:014967 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4968 EXPECT_EQ(2, auth_helper.auth_count());
4969 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
4970 pool_->GetLoadState("a", auth_helper.handle()));
4971
Matt Menkeb57663b32019-03-01 17:17:104972 auth_helper.RestartWithAuth();
4973 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4974 EXPECT_EQ(2, auth_helper.auth_count());
Matt Menke4b69f932019-03-04 16:20:014975 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
4976 pool_->GetLoadState("a", auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:104977
4978 EXPECT_THAT(auth_helper.WaitForResult(), IsOk());
4979 EXPECT_EQ(2, auth_helper.auth_count());
4980 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
4981 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
4982 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
4983 EXPECT_EQ(0, pool_->IdleSocketCount());
4984}
4985
4986TEST_F(ClientSocketPoolBaseTest, ProxyAuthTwiceFails) {
4987 CreatePool(1, 1);
4988 connect_job_factory_->set_job_type(
4989 TestConnectJob::kMockAuthChallengeTwiceFailingJob);
4990
4991 TestAuthHelper auth_helper;
4992 auth_helper.InitHandle(params_, pool_.get());
4993 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4994
4995 auth_helper.WaitForAuth();
4996 auth_helper.RestartWithAuth();
4997 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4998 EXPECT_EQ(1, auth_helper.auth_count());
4999
5000 auth_helper.WaitForAuth();
5001 auth_helper.RestartWithAuth();
5002 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
5003 EXPECT_EQ(2, auth_helper.auth_count());
5004
5005 EXPECT_THAT(auth_helper.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
5006 EXPECT_EQ(2, auth_helper.auth_count());
5007 EXPECT_FALSE(pool_->HasGroup("a"));
5008 EXPECT_EQ(0, pool_->IdleSocketCount());
5009}
5010
5011// Makes sure that when a bound request is destroyed, a new ConnectJob is
5012// created, if needed.
5013TEST_F(ClientSocketPoolBaseTest,
5014 ProxyAuthCreateNewConnectJobOnDestroyBoundRequest) {
5015 CreatePool(1 /* max_sockets */, 1 /* max_sockets_per_group */);
5016 connect_job_factory_->set_job_type(
5017 TestConnectJob::kMockAuthChallengeOnceFailingJob);
5018
5019 // First request creates a ConnectJob.
5020 TestAuthHelper auth_helper1;
5021 auth_helper1.InitHandle(params_, pool_.get());
5022 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
5023
5024 // A second request come in, but no new ConnectJob is needed, since the limit
5025 // has been reached.
5026 TestAuthHelper auth_helper2;
5027 auth_helper2.InitHandle(params_, pool_.get());
5028 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
5029
5030 // Run until the auth callback for the first request is invoked.
5031 auth_helper1.WaitForAuth();
5032 EXPECT_EQ(0, auth_helper2.auth_count());
5033 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
5034 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
5035 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
5036
5037 // Make connect jobs succeed, then cancel the first request, which should
5038 // destroy the bound ConnectJob, and cause a new ConnectJob to start.
5039 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
5040 auth_helper1.handle()->Reset();
5041 EXPECT_EQ(0, auth_helper2.auth_count());
5042 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
5043
5044 // The second ConnectJob should succeed.
5045 EXPECT_THAT(auth_helper2.WaitForResult(), IsOk());
5046 EXPECT_EQ(0, auth_helper2.auth_count());
5047 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
5048}
5049
5050// Makes sure that when a bound request is destroyed, a new ConnectJob is
5051// created for another group, if needed.
5052TEST_F(ClientSocketPoolBaseTest,
5053 ProxyAuthCreateNewConnectJobOnDestroyBoundRequestDifferentGroups) {
5054 CreatePool(1 /* max_sockets */, 1 /* max_sockets_per_group */);
5055 connect_job_factory_->set_job_type(
5056 TestConnectJob::kMockAuthChallengeOnceFailingJob);
5057
5058 // First request creates a ConnectJob.
5059 TestAuthHelper auth_helper1;
5060 auth_helper1.InitHandle(params_, pool_.get(), DEFAULT_PRIORITY);
5061 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
5062
5063 // A second request come in, but no new ConnectJob is needed, since the limit
5064 // has been reached.
5065 TestAuthHelper auth_helper2;
5066 auth_helper2.InitHandle(params_, pool_.get(), DEFAULT_PRIORITY,
5067 ClientSocketPool::RespectLimits::ENABLED, "b");
5068 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
5069 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("b"));
5070
5071 // Run until the auth callback for the first request is invoked.
5072 auth_helper1.WaitForAuth();
5073 EXPECT_EQ(0, auth_helper2.auth_count());
5074 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
5075 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
5076 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
5077 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("b"));
5078 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
5079 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("b"));
5080
5081 // Make connect jobs succeed, then cancel the first request, which should
5082 // destroy the bound ConnectJob, and cause a new ConnectJob to start for the
5083 // other group.
5084 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
5085 auth_helper1.handle()->Reset();
5086 EXPECT_EQ(0, auth_helper2.auth_count());
5087 EXPECT_FALSE(pool_->HasGroup("a"));
5088 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("b"));
5089
5090 // The second ConnectJob should succeed.
5091 EXPECT_THAT(auth_helper2.WaitForResult(), IsOk());
5092 EXPECT_EQ(0, auth_helper2.auth_count());
5093 EXPECT_FALSE(pool_->HasGroup("a"));
5094 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("b"));
5095}
5096
5097// Test that once an auth challenge is bound, that's the request that gets all
5098// subsequent calls and the socket itself.
5099TEST_F(ClientSocketPoolBaseTest, ProxyAuthStaysBound) {
5100 CreatePool(1, 1);
5101 connect_job_factory_->set_job_type(
5102 TestConnectJob::kMockAuthChallengeTwiceJob);
5103
5104 // First request creates a ConnectJob.
5105 TestAuthHelper auth_helper1;
5106 auth_helper1.InitHandle(params_, pool_.get(), LOWEST);
5107 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
5108
5109 // A second, higher priority request is made.
5110 TestAuthHelper auth_helper2;
5111 auth_helper2.InitHandle(params_, pool_.get(), LOW);
5112 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
5113
5114 // Run until the auth callback for the second request is invoked.
5115 auth_helper2.WaitForAuth();
5116 EXPECT_EQ(0, auth_helper1.auth_count());
5117 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
5118 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
5119 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
5120
5121 // Start a higher priority job. It shouldn't be able to steal |auth_helper2|'s
5122 // ConnectJob.
5123 TestAuthHelper auth_helper3;
5124 auth_helper3.InitHandle(params_, pool_.get(), HIGHEST);
5125 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
5126
5127 // Start a higher job that ignores limits, creating a hanging socket. It
5128 // shouldn't be able to steal |auth_helper2|'s ConnectJob.
5129 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
5130 TestAuthHelper auth_helper4;
5131 auth_helper4.InitHandle(params_, pool_.get(), HIGHEST,
5132 ClientSocketPool::RespectLimits::DISABLED);
5133 EXPECT_EQ(2u, pool_->NumConnectJobsInGroup("a"));
5134
5135 // Restart with auth, and |auth_helper2|'s auth method should be invoked
5136 // again.
5137 auth_helper2.RestartWithAuth();
5138 auth_helper2.WaitForAuth();
5139 EXPECT_EQ(0, auth_helper1.auth_count());
5140 EXPECT_FALSE(auth_helper1.have_result());
5141 EXPECT_EQ(2, auth_helper2.auth_count());
5142 EXPECT_FALSE(auth_helper2.have_result());
5143 EXPECT_EQ(0, auth_helper3.auth_count());
5144 EXPECT_FALSE(auth_helper3.have_result());
5145 EXPECT_EQ(0, auth_helper4.auth_count());
5146 EXPECT_FALSE(auth_helper4.have_result());
5147
5148 // Advance auth again, and |auth_helper2| should get the socket.
5149 auth_helper2.RestartWithAuth();
5150 EXPECT_THAT(auth_helper2.WaitForResult(), IsOk());
5151 // The hung ConnectJob for the RespectLimits::DISABLED request is still in the
5152 // socket pool.
5153 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
5154 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
5155 EXPECT_EQ(0, auth_helper1.auth_count());
5156 EXPECT_FALSE(auth_helper1.have_result());
5157 EXPECT_EQ(0, auth_helper3.auth_count());
5158 EXPECT_FALSE(auth_helper3.have_result());
5159 EXPECT_EQ(0, auth_helper4.auth_count());
5160 EXPECT_FALSE(auth_helper4.have_result());
5161
5162 // If the socket is returned to the socket pool, the RespectLimits::DISABLED
5163 // socket request should be able to claim it.
5164 auth_helper2.handle()->Reset();
5165 EXPECT_THAT(auth_helper4.WaitForResult(), IsOk());
5166 EXPECT_EQ(0, auth_helper1.auth_count());
5167 EXPECT_FALSE(auth_helper1.have_result());
5168 EXPECT_EQ(0, auth_helper3.auth_count());
5169 EXPECT_FALSE(auth_helper3.have_result());
5170 EXPECT_EQ(0, auth_helper4.auth_count());
5171}
5172
[email protected]f6d1d6eb2009-06-24 20:16:095173} // namespace
5174
5175} // namespace net