blob: b71da06682cdc97e522106116241e3b23d667d49 [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"
Avi Drissman13fc8932015-12-20 04:40:4616#include "base/macros.h"
[email protected]3b63f8f42011-03-28 01:54:1517#include "base/memory/ref_counted.h"
[email protected]6ea7b152011-12-21 21:21:1318#include "base/memory/weak_ptr.h"
[email protected]18b577412013-07-18 04:19:1519#include "base/message_loop/message_loop.h"
[email protected]034df0f32013-01-07 23:17:4820#include "base/run_loop.h"
skyostil4891b25b2015-06-11 11:43:4521#include "base/single_thread_task_runner.h"
[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;
[email protected]0b7648c2009-07-06 20:14:0166
[email protected]034df0f32013-01-07 23:17:4867// Make sure |handle| sets load times correctly when it has been assigned a
68// reused socket.
69void TestLoadTimingInfoConnectedReused(const ClientSocketHandle& handle) {
70 LoadTimingInfo load_timing_info;
71 // Only pass true in as |is_reused|, as in general, HttpStream types should
72 // have stricter concepts of reuse than socket pools.
73 EXPECT_TRUE(handle.GetLoadTimingInfo(true, &load_timing_info));
74
75 EXPECT_EQ(true, load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:1976 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]034df0f32013-01-07 23:17:4877
[email protected]b258e0792013-01-12 07:11:5978 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
79 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:4880}
81
82// Make sure |handle| sets load times correctly when it has been assigned a
[email protected]b021ece62013-06-11 11:06:3383// fresh socket. Also runs TestLoadTimingInfoConnectedReused, since the owner
[email protected]034df0f32013-01-07 23:17:4884// of a connection where |is_reused| is false may consider the connection
85// reused.
86void TestLoadTimingInfoConnectedNotReused(const ClientSocketHandle& handle) {
87 EXPECT_FALSE(handle.is_reused());
88
89 LoadTimingInfo load_timing_info;
90 EXPECT_TRUE(handle.GetLoadTimingInfo(false, &load_timing_info));
91
92 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:1993 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]034df0f32013-01-07 23:17:4894
[email protected]b258e0792013-01-12 07:11:5995 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
96 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
97 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:4898
99 TestLoadTimingInfoConnectedReused(handle);
100}
101
102// Make sure |handle| sets load times correctly, in the case that it does not
103// currently have a socket.
104void TestLoadTimingInfoNotConnected(const ClientSocketHandle& handle) {
105 // Should only be set to true once a socket is assigned, if at all.
106 EXPECT_FALSE(handle.is_reused());
107
108 LoadTimingInfo load_timing_info;
109 EXPECT_FALSE(handle.GetLoadTimingInfo(false, &load_timing_info));
110
111 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19112 EXPECT_EQ(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]034df0f32013-01-07 23:17:48113
[email protected]b258e0792013-01-12 07:11:59114 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
115 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:48116}
117
[email protected]df4b4ef2010-07-12 18:25:21118class TestSocketParams : public base::RefCounted<TestSocketParams> {
[email protected]5acdce12011-03-30 13:00:20119 public:
Chris Watkins7a41d3552017-12-01 02:13:27120 explicit TestSocketParams() = default;
[email protected]51fdc7c2012-04-10 19:19:48121
[email protected]df4b4ef2010-07-12 18:25:21122 private:
123 friend class base::RefCounted<TestSocketParams>;
Chris Watkins7a41d3552017-12-01 02:13:27124 ~TestSocketParams() = default;
[email protected]df4b4ef2010-07-12 18:25:21125};
[email protected]7fc5b09a2010-02-27 00:07:38126typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
[email protected]d80a4322009-08-14 07:07:49127
[email protected]3268023f2011-05-05 00:08:10128class MockClientSocket : public StreamSocket {
[email protected]f6d1d6eb2009-06-24 20:16:09129 public:
[email protected]034df0f32013-01-07 23:17:48130 explicit MockClientSocket(net::NetLog* net_log)
131 : connected_(false),
[email protected]0dc88b32014-03-26 20:12:28132 has_unread_data_(false),
tfarina428341112016-09-22 13:38:20133 net_log_(NetLogWithSource::Make(net_log, NetLogSourceType::SOCKET)),
Charlie Harrison3e4c0622018-05-13 15:44:30134 was_used_to_convey_data_(false) {}
[email protected]f6d1d6eb2009-06-24 20:16:09135
[email protected]0dc88b32014-03-26 20:12:28136 // Sets whether the socket has unread data. If true, the next call to Read()
137 // will return 1 byte and IsConnectedAndIdle() will return false.
138 void set_has_unread_data(bool has_unread_data) {
139 has_unread_data_ = has_unread_data;
140 }
141
[email protected]3f55aa12011-12-07 02:03:33142 // Socket implementation.
dchengb03027d2014-10-21 12:00:20143 int Read(IOBuffer* /* buf */,
144 int len,
Brad Lassey3a814172018-04-26 03:30:21145 CompletionOnceCallback /* callback */) override {
[email protected]0dc88b32014-03-26 20:12:28146 if (has_unread_data_ && len > 0) {
147 has_unread_data_ = false;
148 was_used_to_convey_data_ = true;
149 return 1;
150 }
[email protected]e86df8dc2013-03-30 13:18:28151 return ERR_UNEXPECTED;
[email protected]3f55aa12011-12-07 02:03:33152 }
[email protected]ab838892009-06-30 18:49:05153
[email protected]a2b2cfc2017-12-06 09:06:08154 int Write(
155 IOBuffer* /* buf */,
156 int len,
Brad Lassey3a814172018-04-26 03:30:21157 CompletionOnceCallback /* callback */,
[email protected]a2b2cfc2017-12-06 09:06:08158 const NetworkTrafficAnnotationTag& /*traffic_annotation*/) override {
[email protected]0f873e82010-09-02 16:09:01159 was_used_to_convey_data_ = true;
160 return len;
[email protected]ab838892009-06-30 18:49:05161 }
Avi Drissman13fc8932015-12-20 04:40:46162 int SetReceiveBufferSize(int32_t size) override { return OK; }
163 int SetSendBufferSize(int32_t size) override { return OK; }
[email protected]ab838892009-06-30 18:49:05164
[email protected]dbf036f2011-12-06 23:33:24165 // StreamSocket implementation.
Brad Lassey3a814172018-04-26 03:30:21166 int Connect(CompletionOnceCallback callback) override {
[email protected]dbf036f2011-12-06 23:33:24167 connected_ = true;
168 return OK;
169 }
[email protected]f6d1d6eb2009-06-24 20:16:09170
dchengb03027d2014-10-21 12:00:20171 void Disconnect() override { connected_ = false; }
172 bool IsConnected() const override { return connected_; }
173 bool IsConnectedAndIdle() const override {
[email protected]0dc88b32014-03-26 20:12:28174 return connected_ && !has_unread_data_;
175 }
[email protected]0b7648c2009-07-06 20:14:01176
dchengb03027d2014-10-21 12:00:20177 int GetPeerAddress(IPEndPoint* /* address */) const override {
[email protected]9f864b32010-01-20 15:01:16178 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:09179 }
[email protected]f6d1d6eb2009-06-24 20:16:09180
dchengb03027d2014-10-21 12:00:20181 int GetLocalAddress(IPEndPoint* /* address */) const override {
[email protected]e7f74da2011-04-19 23:49:35182 return ERR_UNEXPECTED;
183 }
184
tfarina428341112016-09-22 13:38:20185 const NetLogWithSource& NetLog() const override { return net_log_; }
[email protected]a2006ece2010-04-23 16:44:02186
dchengb03027d2014-10-21 12:00:20187 bool WasEverUsed() const override { return was_used_to_convey_data_; }
tfarina2846404c2016-12-25 14:31:37188 bool WasAlpnNegotiated() const override { return false; }
dchengb03027d2014-10-21 12:00:20189 NextProto GetNegotiatedProtocol() const override { return kProtoUnknown; }
190 bool GetSSLInfo(SSLInfo* ssl_info) override { return false; }
ttuttle23fdb7b2015-05-15 01:28:03191 void GetConnectionAttempts(ConnectionAttempts* out) const override {
192 out->clear();
193 }
194 void ClearConnectionAttempts() override {}
195 void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
tbansalf82cc8e2015-10-14 20:05:49196 int64_t GetTotalReceivedBytes() const override {
197 NOTIMPLEMENTED();
198 return 0;
199 }
Paul Jensen0f49dec2017-12-12 23:39:58200 void ApplySocketTag(const SocketTag& tag) override {}
[email protected]9b5614a2010-08-25 20:29:45201
[email protected]f6d1d6eb2009-06-24 20:16:09202 private:
203 bool connected_;
[email protected]0dc88b32014-03-26 20:12:28204 bool has_unread_data_;
tfarina428341112016-09-22 13:38:20205 NetLogWithSource net_log_;
[email protected]0f873e82010-09-02 16:09:01206 bool was_used_to_convey_data_;
[email protected]f6d1d6eb2009-06-24 20:16:09207
[email protected]ab838892009-06-30 18:49:05208 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:09209};
210
[email protected]5fc08e32009-07-15 17:09:57211class TestConnectJob;
212
[email protected]f6d1d6eb2009-06-24 20:16:09213class MockClientSocketFactory : public ClientSocketFactory {
214 public:
[email protected]ab838892009-06-30 18:49:05215 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:09216
danakj655b66c2016-04-16 00:51:38217 std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
[email protected]5370c012011-06-29 03:47:04218 DatagramSocket::BindType bind_type,
[email protected]98b0e582011-06-22 14:31:41219 NetLog* net_log,
mikecironef22f9812016-10-04 03:40:19220 const NetLogSource& source) override {
[email protected]98b0e582011-06-22 14:31:41221 NOTREACHED();
danakj655b66c2016-04-16 00:51:38222 return std::unique_ptr<DatagramClientSocket>();
[email protected]98b0e582011-06-22 14:31:41223 }
224
Helen Lid5bb9222018-04-12 15:33:09225 std::unique_ptr<TransportClientSocket> CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07226 const AddressList& addresses,
danakj655b66c2016-04-16 00:51:38227 std::unique_ptr<
228 SocketPerformanceWatcher> /* socket_performance_watcher */,
[email protected]0a0b7682010-08-25 17:08:07229 NetLog* /* net_log */,
mikecironef22f9812016-10-04 03:40:19230 const NetLogSource& /*source*/) override {
[email protected]f6d1d6eb2009-06-24 20:16:09231 allocation_count_++;
Helen Lid5bb9222018-04-12 15:33:09232 return nullptr;
[email protected]f6d1d6eb2009-06-24 20:16:09233 }
234
danakj655b66c2016-04-16 00:51:38235 std::unique_ptr<SSLClientSocket> CreateSSLClientSocket(
236 std::unique_ptr<ClientSocketHandle> transport_socket,
[email protected]4f4de7e62010-11-12 19:55:27237 const HostPortPair& host_and_port,
[email protected]7ab5bbd12010-10-19 13:33:21238 const SSLConfig& ssl_config,
mostynbba063d6032014-10-09 11:01:13239 const SSLClientSocketContext& context) override {
[email protected]f6d1d6eb2009-06-24 20:16:09240 NOTIMPLEMENTED();
danakj655b66c2016-04-16 00:51:38241 return std::unique_ptr<SSLClientSocket>();
[email protected]f6d1d6eb2009-06-24 20:16:09242 }
Helen Liac3c51e2018-04-24 00:02:13243 std::unique_ptr<ProxyClientSocket> CreateProxyClientSocket(
244 std::unique_ptr<ClientSocketHandle> transport_socket,
245 const std::string& user_agent,
246 const HostPortPair& endpoint,
247 HttpAuthController* http_auth_controller,
248 bool tunnel,
249 bool using_spdy,
250 NextProto negotiated_protocol,
251 bool is_https_proxy,
252 const NetworkTrafficAnnotationTag& traffic_annotation) override {
253 NOTIMPLEMENTED();
254 return nullptr;
255 }
[email protected]f6d1d6eb2009-06-24 20:16:09256
dchengb03027d2014-10-21 12:00:20257 void ClearSSLSessionCache() override { NOTIMPLEMENTED(); }
[email protected]25f47352011-02-25 16:31:59258
[email protected]5fc08e32009-07-15 17:09:57259 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
[email protected]03b7c8c2013-07-20 04:38:55260
[email protected]5fc08e32009-07-15 17:09:57261 void SignalJobs();
262
[email protected]03b7c8c2013-07-20 04:38:55263 void SignalJob(size_t job);
264
265 void SetJobLoadState(size_t job, LoadState load_state);
266
[email protected]f6d1d6eb2009-06-24 20:16:09267 int allocation_count() const { return allocation_count_; }
268
[email protected]f6d1d6eb2009-06-24 20:16:09269 private:
270 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:57271 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09272};
273
[email protected]ab838892009-06-30 18:49:05274class TestConnectJob : public ConnectJob {
275 public:
276 enum JobType {
277 kMockJob,
278 kMockFailingJob,
279 kMockPendingJob,
280 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57281 kMockWaitingJob,
[email protected]e772db3f2010-07-12 18:11:13282 kMockRecoverableJob,
283 kMockPendingRecoverableJob,
[email protected]e60e47a2010-07-14 03:37:18284 kMockAdditionalErrorStateJob,
285 kMockPendingAdditionalErrorStateJob,
[email protected]0dc88b32014-03-26 20:12:28286 kMockUnreadDataJob,
[email protected]ab838892009-06-30 18:49:05287 };
288
[email protected]994d4932010-07-12 17:55:13289 // The kMockPendingJob uses a slight delay before allowing the connect
290 // to complete.
291 static const int kPendingConnectDelay = 2;
292
[email protected]ab838892009-06-30 18:49:05293 TestConnectJob(JobType job_type,
294 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49295 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34296 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05297 ConnectJob::Delegate* delegate,
[email protected]fd7b7c92009-08-20 19:38:30298 MockClientSocketFactory* client_socket_factory,
[email protected]06650c52010-06-03 00:49:17299 NetLog* net_log)
tfarina428341112016-09-22 13:38:20300 : ConnectJob(
301 group_name,
302 timeout_duration,
303 request.priority(),
Paul Jensen8d6f87ec2018-01-13 00:46:54304 request.socket_tag(),
tfarina428341112016-09-22 13:38:20305 request.respect_limits(),
306 delegate,
davidbenb7048f092016-11-30 21:20:26307 NetLogWithSource::Make(net_log,
308 NetLogSourceType::TRANSPORT_CONNECT_JOB)),
[email protected]2ab05b52009-07-01 23:57:58309 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05310 client_socket_factory_(client_socket_factory),
[email protected]e60e47a2010-07-14 03:37:18311 load_state_(LOAD_STATE_IDLE),
[email protected]d5492c52013-11-10 20:44:39312 store_additional_error_state_(false),
mmenked3641e12016-01-28 16:06:15313 weak_factory_(this) {}
[email protected]ab838892009-06-30 18:49:05314
[email protected]974ebd62009-08-03 23:14:34315 void Signal() {
[email protected]e772db3f2010-07-12 18:11:13316 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
[email protected]974ebd62009-08-03 23:14:34317 }
318
[email protected]03b7c8c2013-07-20 04:38:55319 void set_load_state(LoadState load_state) { load_state_ = load_state; }
320
321 // From ConnectJob:
322
dchengb03027d2014-10-21 12:00:20323 LoadState GetLoadState() const override { return load_state_; }
[email protected]46451352009-09-01 14:54:21324
dchengb03027d2014-10-21 12:00:20325 void GetAdditionalErrorState(ClientSocketHandle* handle) override {
[email protected]e60e47a2010-07-14 03:37:18326 if (store_additional_error_state_) {
327 // Set all of the additional error state fields in some way.
328 handle->set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43329 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:45330 info.headers = new HttpResponseHeaders(std::string());
[email protected]8b498692010-07-16 17:11:43331 handle->set_ssl_error_response_info(info);
[email protected]e60e47a2010-07-14 03:37:18332 }
333 }
334
[email protected]974ebd62009-08-03 23:14:34335 private:
[email protected]03b7c8c2013-07-20 04:38:55336 // From ConnectJob:
[email protected]ab838892009-06-30 18:49:05337
dchengb03027d2014-10-21 12:00:20338 int ConnectInternal() override {
[email protected]ab838892009-06-30 18:49:05339 AddressList ignored;
tbansal7b403bcc2016-04-13 22:33:21340 client_socket_factory_->CreateTransportClientSocket(ignored, NULL, NULL,
mikecironef22f9812016-10-04 03:40:19341 NetLogSource());
danakj655b66c2016-04-16 00:51:38342 SetSocket(std::unique_ptr<StreamSocket>(
343 new MockClientSocket(net_log().net_log())));
[email protected]ab838892009-06-30 18:49:05344 switch (job_type_) {
345 case kMockJob:
[email protected]e772db3f2010-07-12 18:11:13346 return DoConnect(true /* successful */, false /* sync */,
347 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05348 case kMockFailingJob:
[email protected]e772db3f2010-07-12 18:11:13349 return DoConnect(false /* error */, false /* sync */,
350 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05351 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57352 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47353
354 // Depending on execution timings, posting a delayed task can result
355 // in the task getting executed the at the earliest possible
356 // opportunity or only after returning once from the message loop and
357 // then a second call into the message loop. In order to make behavior
358 // more deterministic, we change the default delay to 2ms. This should
359 // always require us to wait for the second call into the message loop.
360 //
361 // N.B. The correct fix for this and similar timing problems is to
362 // abstract time for the purpose of unittests. Unfortunately, we have
363 // a lot of third-party components that directly call the various
364 // time functions, so this change would be rather invasive.
skyostil4891b25b2015-06-11 11:43:45365 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05366 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13367 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
skyostil4891b25b2015-06-11 11:43:45368 weak_factory_.GetWeakPtr(), true /* successful */,
369 true /* async */, false /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53370 base::TimeDelta::FromMilliseconds(kPendingConnectDelay));
[email protected]ab838892009-06-30 18:49:05371 return ERR_IO_PENDING;
372 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57373 set_load_state(LOAD_STATE_CONNECTING);
skyostil4891b25b2015-06-11 11:43:45374 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05375 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13376 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
skyostil4891b25b2015-06-11 11:43:45377 weak_factory_.GetWeakPtr(), false /* error */,
378 true /* async */, false /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53379 base::TimeDelta::FromMilliseconds(2));
[email protected]ab838892009-06-30 18:49:05380 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57381 case kMockWaitingJob:
[email protected]03b7c8c2013-07-20 04:38:55382 set_load_state(LOAD_STATE_CONNECTING);
[email protected]5fc08e32009-07-15 17:09:57383 client_socket_factory_->WaitForSignal(this);
384 waiting_success_ = true;
385 return ERR_IO_PENDING;
[email protected]e772db3f2010-07-12 18:11:13386 case kMockRecoverableJob:
387 return DoConnect(false /* error */, false /* sync */,
388 true /* recoverable */);
389 case kMockPendingRecoverableJob:
390 set_load_state(LOAD_STATE_CONNECTING);
skyostil4891b25b2015-06-11 11:43:45391 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]e772db3f2010-07-12 18:11:13392 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13393 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
skyostil4891b25b2015-06-11 11:43:45394 weak_factory_.GetWeakPtr(), false /* error */,
395 true /* async */, true /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53396 base::TimeDelta::FromMilliseconds(2));
[email protected]e772db3f2010-07-12 18:11:13397 return ERR_IO_PENDING;
[email protected]e60e47a2010-07-14 03:37:18398 case kMockAdditionalErrorStateJob:
399 store_additional_error_state_ = true;
400 return DoConnect(false /* error */, false /* sync */,
401 false /* recoverable */);
402 case kMockPendingAdditionalErrorStateJob:
403 set_load_state(LOAD_STATE_CONNECTING);
404 store_additional_error_state_ = true;
skyostil4891b25b2015-06-11 11:43:45405 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]e60e47a2010-07-14 03:37:18406 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13407 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
skyostil4891b25b2015-06-11 11:43:45408 weak_factory_.GetWeakPtr(), false /* error */,
409 true /* async */, false /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53410 base::TimeDelta::FromMilliseconds(2));
[email protected]e60e47a2010-07-14 03:37:18411 return ERR_IO_PENDING;
[email protected]0dc88b32014-03-26 20:12:28412 case kMockUnreadDataJob: {
413 int ret = DoConnect(true /* successful */, false /* sync */,
414 false /* recoverable */);
415 static_cast<MockClientSocket*>(socket())->set_has_unread_data(true);
416 return ret;
417 }
[email protected]ab838892009-06-30 18:49:05418 default:
419 NOTREACHED();
danakj655b66c2016-04-16 00:51:38420 SetSocket(std::unique_ptr<StreamSocket>());
[email protected]ab838892009-06-30 18:49:05421 return ERR_FAILED;
422 }
423 }
424
[email protected]e772db3f2010-07-12 18:11:13425 int DoConnect(bool succeed, bool was_async, bool recoverable) {
426 int result = OK;
[email protected]ab838892009-06-30 18:49:05427 if (succeed) {
[email protected]83039bb2011-12-09 18:43:55428 socket()->Connect(CompletionCallback());
[email protected]e772db3f2010-07-12 18:11:13429 } else if (recoverable) {
430 result = ERR_PROXY_AUTH_REQUESTED;
[email protected]6e713f02009-08-06 02:56:40431 } else {
[email protected]e772db3f2010-07-12 18:11:13432 result = ERR_CONNECTION_FAILED;
danakj655b66c2016-04-16 00:51:38433 SetSocket(std::unique_ptr<StreamSocket>());
[email protected]ab838892009-06-30 18:49:05434 }
[email protected]2ab05b52009-07-01 23:57:58435
436 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30437 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05438 return result;
439 }
440
[email protected]5fc08e32009-07-15 17:09:57441 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05442 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57443 MockClientSocketFactory* const client_socket_factory_;
[email protected]46451352009-09-01 14:54:21444 LoadState load_state_;
[email protected]e60e47a2010-07-14 03:37:18445 bool store_additional_error_state_;
[email protected]ab838892009-06-30 18:49:05446
[email protected]d5492c52013-11-10 20:44:39447 base::WeakPtrFactory<TestConnectJob> weak_factory_;
448
[email protected]ab838892009-06-30 18:49:05449 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
450};
451
[email protected]d80a4322009-08-14 07:07:49452class TestConnectJobFactory
453 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05454 public:
[email protected]034df0f32013-01-07 23:17:48455 TestConnectJobFactory(MockClientSocketFactory* client_socket_factory,
456 NetLog* net_log)
[email protected]ab838892009-06-30 18:49:05457 : job_type_(TestConnectJob::kMockJob),
[email protected]51fdc7c2012-04-10 19:19:48458 job_types_(NULL),
[email protected]034df0f32013-01-07 23:17:48459 client_socket_factory_(client_socket_factory),
460 net_log_(net_log) {
[email protected]b021ece62013-06-11 11:06:33461 }
[email protected]ab838892009-06-30 18:49:05462
Chris Watkins7a41d3552017-12-01 02:13:27463 ~TestConnectJobFactory() override = default;
[email protected]ab838892009-06-30 18:49:05464
465 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
466
[email protected]51fdc7c2012-04-10 19:19:48467 void set_job_types(std::list<TestConnectJob::JobType>* job_types) {
468 job_types_ = job_types;
469 CHECK(!job_types_->empty());
470 }
471
[email protected]974ebd62009-08-03 23:14:34472 void set_timeout_duration(base::TimeDelta timeout_duration) {
473 timeout_duration_ = timeout_duration;
474 }
475
[email protected]3f55aa12011-12-07 02:03:33476 // ConnectJobFactory implementation.
[email protected]83039bb2011-12-09 18:43:55477
danakj655b66c2016-04-16 00:51:38478 std::unique_ptr<ConnectJob> NewConnectJob(
[email protected]ab838892009-06-30 18:49:05479 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49480 const TestClientSocketPoolBase::Request& request,
mostynbba063d6032014-10-09 11:01:13481 ConnectJob::Delegate* delegate) const override {
[email protected]51fdc7c2012-04-10 19:19:48482 EXPECT_TRUE(!job_types_ || !job_types_->empty());
483 TestConnectJob::JobType job_type = job_type_;
484 if (job_types_ && !job_types_->empty()) {
485 job_type = job_types_->front();
486 job_types_->pop_front();
487 }
danakj655b66c2016-04-16 00:51:38488 return std::unique_ptr<ConnectJob>(
489 new TestConnectJob(job_type, group_name, request, timeout_duration_,
490 delegate, client_socket_factory_, net_log_));
[email protected]ab838892009-06-30 18:49:05491 }
492
dchengb03027d2014-10-21 12:00:20493 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26494 return timeout_duration_;
495 }
496
[email protected]ab838892009-06-30 18:49:05497 private:
498 TestConnectJob::JobType job_type_;
[email protected]51fdc7c2012-04-10 19:19:48499 std::list<TestConnectJob::JobType>* job_types_;
[email protected]974ebd62009-08-03 23:14:34500 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57501 MockClientSocketFactory* const client_socket_factory_;
[email protected]034df0f32013-01-07 23:17:48502 NetLog* net_log_;
[email protected]ab838892009-06-30 18:49:05503
504 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
505};
506
507class TestClientSocketPool : public ClientSocketPool {
508 public:
[email protected]12322e7e2013-08-15 17:49:26509 typedef TestSocketParams SocketParams;
510
[email protected]ab838892009-06-30 18:49:05511 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53512 int max_sockets,
[email protected]ab838892009-06-30 18:49:05513 int max_sockets_per_group,
[email protected]9bf28db2009-08-29 01:35:16514 base::TimeDelta unused_idle_socket_timeout,
515 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49516 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
rkaplowd90695c2015-03-25 22:12:41517 : base_(NULL,
518 max_sockets,
519 max_sockets_per_group,
520 unused_idle_socket_timeout,
521 used_idle_socket_timeout,
[email protected]66761b952010-06-25 21:30:38522 connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05523
Chris Watkins7a41d3552017-12-01 02:13:27524 ~TestClientSocketPool() override = default;
[email protected]2431756e2010-09-29 20:26:13525
dchengb03027d2014-10-21 12:00:20526 int RequestSocket(const std::string& group_name,
527 const void* params,
ttuttle859dc7a2015-04-23 19:42:29528 RequestPriority priority,
Paul Jensen8d6f87ec2018-01-13 00:46:54529 const SocketTag& socket_tag,
mmenked3641e12016-01-28 16:06:15530 RespectLimits respect_limits,
dchengb03027d2014-10-21 12:00:20531 ClientSocketHandle* handle,
532 const CompletionCallback& callback,
tfarina428341112016-09-22 13:38:20533 const NetLogWithSource& net_log) override {
[email protected]df4b4ef2010-07-12 18:25:21534 const scoped_refptr<TestSocketParams>* casted_socket_params =
535 static_cast<const scoped_refptr<TestSocketParams>*>(params);
536 return base_.RequestSocket(group_name, *casted_socket_params, priority,
Paul Jensen8d6f87ec2018-01-13 00:46:54537 socket_tag, respect_limits, handle, callback,
538 net_log);
[email protected]ab838892009-06-30 18:49:05539 }
540
dchengb03027d2014-10-21 12:00:20541 void RequestSockets(const std::string& group_name,
542 const void* params,
543 int num_sockets,
Alexandr Ilin65ec9582017-10-02 14:50:31544 const NetLogWithSource& net_log,
545 HttpRequestInfo::RequestMotivation motivation) override {
[email protected]2c2bef152010-10-13 00:55:03546 const scoped_refptr<TestSocketParams>* casted_params =
547 static_cast<const scoped_refptr<TestSocketParams>*>(params);
548
Alexandr Ilin65ec9582017-10-02 14:50:31549 base_.RequestSockets(group_name, *casted_params, num_sockets, net_log,
550 motivation);
[email protected]2c2bef152010-10-13 00:55:03551 }
552
rdsmith29dbad12017-02-17 02:22:18553 void SetPriority(const std::string& group_name,
554 ClientSocketHandle* handle,
555 RequestPriority priority) override {
556 base_.SetPriority(group_name, handle, priority);
557 }
558
dchengb03027d2014-10-21 12:00:20559 void CancelRequest(const std::string& group_name,
560 ClientSocketHandle* handle) override {
[email protected]d80a4322009-08-14 07:07:49561 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05562 }
563
dchengb03027d2014-10-21 12:00:20564 void ReleaseSocket(const std::string& group_name,
danakj655b66c2016-04-16 00:51:38565 std::unique_ptr<StreamSocket> socket,
dchengb03027d2014-10-21 12:00:20566 int id) override {
dchengc7eeda422015-12-26 03:56:48567 base_.ReleaseSocket(group_name, std::move(socket), id);
[email protected]a7e38572010-06-07 18:22:24568 }
569
dchengb03027d2014-10-21 12:00:20570 void FlushWithError(int error) override { base_.FlushWithError(error); }
[email protected]ab838892009-06-30 18:49:05571
dchengb03027d2014-10-21 12:00:20572 bool IsStalled() const override { return base_.IsStalled(); }
[email protected]51fdc7c2012-04-10 19:19:48573
dchengb03027d2014-10-21 12:00:20574 void CloseIdleSockets() override { base_.CloseIdleSockets(); }
[email protected]ab838892009-06-30 18:49:05575
xunjieli92feb332017-03-03 17:19:23576 void CloseIdleSocketsInGroup(const std::string& group_name) override {
577 base_.CloseIdleSocketsInGroup(group_name);
578 }
579
dchengb03027d2014-10-21 12:00:20580 int IdleSocketCount() const override { return base_.idle_socket_count(); }
[email protected]ab838892009-06-30 18:49:05581
dchengb03027d2014-10-21 12:00:20582 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]d80a4322009-08-14 07:07:49583 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05584 }
585
dchengb03027d2014-10-21 12:00:20586 LoadState GetLoadState(const std::string& group_name,
587 const ClientSocketHandle* handle) const override {
[email protected]d80a4322009-08-14 07:07:49588 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05589 }
590
dchengb03027d2014-10-21 12:00:20591 void AddHigherLayeredPool(HigherLayeredPool* higher_pool) override {
[email protected]043b68c82013-08-22 23:41:52592 base_.AddHigherLayeredPool(higher_pool);
[email protected]51fdc7c2012-04-10 19:19:48593 }
594
dchengb03027d2014-10-21 12:00:20595 void RemoveHigherLayeredPool(HigherLayeredPool* higher_pool) override {
[email protected]043b68c82013-08-22 23:41:52596 base_.RemoveHigherLayeredPool(higher_pool);
[email protected]51fdc7c2012-04-10 19:19:48597 }
598
danakj655b66c2016-04-16 00:51:38599 std::unique_ptr<base::DictionaryValue> GetInfoAsValue(
[email protected]d4dfdab2011-12-07 16:56:59600 const std::string& name,
601 const std::string& type,
mostynbba063d6032014-10-09 11:01:13602 bool include_nested_pools) const override {
[email protected]59d7a5a2010-08-30 16:44:27603 return base_.GetInfoAsValue(name, type);
604 }
605
dchengb03027d2014-10-21 12:00:20606 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26607 return base_.ConnectionTimeout();
608 }
609
[email protected]d80a4322009-08-14 07:07:49610 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20611
[email protected]8159a1c2012-06-07 00:00:10612 int NumUnassignedConnectJobsInGroup(const std::string& group_name) const {
613 return base_.NumUnassignedConnectJobsInGroup(group_name);
614 }
615
[email protected]974ebd62009-08-03 23:14:34616 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49617 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34618 }
619
[email protected]2c2bef152010-10-13 00:55:03620 int NumActiveSocketsInGroup(const std::string& group_name) const {
621 return base_.NumActiveSocketsInGroup(group_name);
622 }
623
[email protected]2abfe90a2010-08-25 17:49:51624 bool HasGroup(const std::string& group_name) const {
625 return base_.HasGroup(group_name);
626 }
627
[email protected]9bf28db2009-08-29 01:35:16628 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
629
[email protected]06d94042010-08-25 01:45:22630 void EnableConnectBackupJobs() { base_.EnableConnectBackupJobs(); }
[email protected]43a21b82010-06-10 21:30:54631
[email protected]043b68c82013-08-22 23:41:52632 bool CloseOneIdleConnectionInHigherLayeredPool() {
633 return base_.CloseOneIdleConnectionInHigherLayeredPool();
[email protected]51fdc7c2012-04-10 19:19:48634 }
635
[email protected]ab838892009-06-30 18:49:05636 private:
[email protected]d80a4322009-08-14 07:07:49637 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05638
639 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
640};
641
[email protected]a937a06d2009-08-19 21:19:24642} // namespace
643
[email protected]a937a06d2009-08-19 21:19:24644namespace {
645
[email protected]5fc08e32009-07-15 17:09:57646void MockClientSocketFactory::SignalJobs() {
647 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
648 it != waiting_jobs_.end(); ++it) {
649 (*it)->Signal();
650 }
651 waiting_jobs_.clear();
652}
653
[email protected]03b7c8c2013-07-20 04:38:55654void MockClientSocketFactory::SignalJob(size_t job) {
655 ASSERT_LT(job, waiting_jobs_.size());
656 waiting_jobs_[job]->Signal();
657 waiting_jobs_.erase(waiting_jobs_.begin() + job);
658}
659
660void MockClientSocketFactory::SetJobLoadState(size_t job,
661 LoadState load_state) {
662 ASSERT_LT(job, waiting_jobs_.size());
663 waiting_jobs_[job]->set_load_state(load_state);
664}
665
[email protected]974ebd62009-08-03 23:14:34666class TestConnectJobDelegate : public ConnectJob::Delegate {
667 public:
668 TestConnectJobDelegate()
669 : have_result_(false), waiting_for_result_(false), result_(OK) {}
Chris Watkins7a41d3552017-12-01 02:13:27670 ~TestConnectJobDelegate() override = default;
[email protected]974ebd62009-08-03 23:14:34671
dchengb03027d2014-10-21 12:00:20672 void OnConnectJobComplete(int result, ConnectJob* job) override {
[email protected]974ebd62009-08-03 23:14:34673 result_ = result;
danakj655b66c2016-04-16 00:51:38674 std::unique_ptr<ConnectJob> owned_job(job);
675 std::unique_ptr<StreamSocket> socket = owned_job->PassSocket();
[email protected]9b6fee12009-09-29 18:13:07676 // socket.get() should be NULL iff result != OK
[email protected]18ccfdb2013-08-15 00:13:44677 EXPECT_EQ(socket == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34678 have_result_ = true;
679 if (waiting_for_result_)
Gabriel Charette53a9ef812017-07-26 12:36:23680 base::RunLoop::QuitCurrentWhenIdleDeprecated();
[email protected]974ebd62009-08-03 23:14:34681 }
682
683 int WaitForResult() {
684 DCHECK(!waiting_for_result_);
685 while (!have_result_) {
686 waiting_for_result_ = true;
fdoray5eeb7642016-06-22 16:11:28687 base::RunLoop().Run();
[email protected]974ebd62009-08-03 23:14:34688 waiting_for_result_ = false;
689 }
690 have_result_ = false; // auto-reset for next callback
691 return result_;
692 }
693
694 private:
695 bool have_result_;
696 bool waiting_for_result_;
697 int result_;
698};
699
Bence Béky98447b12018-05-08 03:14:01700class ClientSocketPoolBaseTest : public TestWithScopedTaskEnvironment {
[email protected]f6d1d6eb2009-06-24 20:16:09701 protected:
mmenked3641e12016-01-28 16:06:15702 ClientSocketPoolBaseTest() : params_(new TestSocketParams()) {
[email protected]636b8252011-04-08 19:56:54703 connect_backup_jobs_enabled_ =
704 internal::ClientSocketPoolBaseHelper::connect_backup_jobs_enabled();
705 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(true);
706 }
[email protected]2431756e2010-09-29 20:26:13707
dcheng67be2b1f2014-10-27 21:47:29708 ~ClientSocketPoolBaseTest() override {
[email protected]636b8252011-04-08 19:56:54709 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
710 connect_backup_jobs_enabled_);
711 }
[email protected]c9d6a1d2009-07-14 16:15:20712
[email protected]211d21722009-07-22 15:48:53713 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16714 CreatePoolWithIdleTimeouts(
715 max_sockets,
716 max_sockets_per_group,
[email protected]82b8c962011-10-12 09:17:30717 ClientSocketPool::unused_idle_socket_timeout(),
718 ClientSocketPool::used_idle_socket_timeout());
[email protected]9bf28db2009-08-29 01:35:16719 }
720
721 void CreatePoolWithIdleTimeouts(
722 int max_sockets, int max_sockets_per_group,
723 base::TimeDelta unused_idle_socket_timeout,
724 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20725 DCHECK(!pool_.get());
[email protected]034df0f32013-01-07 23:17:48726 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_,
727 &net_log_);
[email protected]2431756e2010-09-29 20:26:13728 pool_.reset(new TestClientSocketPool(max_sockets,
729 max_sockets_per_group,
[email protected]2431756e2010-09-29 20:26:13730 unused_idle_socket_timeout,
731 used_idle_socket_timeout,
732 connect_job_factory_));
[email protected]c9d6a1d2009-07-14 16:15:20733 }
[email protected]f6d1d6eb2009-06-24 20:16:09734
mmenked3641e12016-01-28 16:06:15735 int StartRequestWithIgnoreLimits(
[email protected]b021ece62013-06-11 11:06:33736 const std::string& group_name,
737 RequestPriority priority,
mmenked3641e12016-01-28 16:06:15738 ClientSocketPool::RespectLimits respect_limits) {
739 return test_base_.StartRequestUsingPool(pool_.get(), group_name, priority,
740 respect_limits, params_);
[email protected]b021ece62013-06-11 11:06:33741 }
742
743 int StartRequest(const std::string& group_name, RequestPriority priority) {
mmenked3641e12016-01-28 16:06:15744 return StartRequestWithIgnoreLimits(
745 group_name, priority, ClientSocketPool::RespectLimits::ENABLED);
[email protected]f6d1d6eb2009-06-24 20:16:09746 }
747
[email protected]2431756e2010-09-29 20:26:13748 int GetOrderOfRequest(size_t index) const {
749 return test_base_.GetOrderOfRequest(index);
[email protected]f6d1d6eb2009-06-24 20:16:09750 }
751
[email protected]2431756e2010-09-29 20:26:13752 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
753 return test_base_.ReleaseOneConnection(keep_alive);
754 }
755
756 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
757 test_base_.ReleaseAllConnections(keep_alive);
758 }
759
760 TestSocketRequest* request(int i) { return test_base_.request(i); }
761 size_t requests_size() const { return test_base_.requests_size(); }
danakj655b66c2016-04-16 00:51:38762 std::vector<std::unique_ptr<TestSocketRequest>>* requests() {
olli.raula9d66b7d2015-11-23 08:30:42763 return test_base_.requests();
764 }
rdsmith29dbad12017-02-17 02:22:18765 // Only counts the requests that get sockets asynchronously;
766 // synchronous completions are not registered by this count.
[email protected]2431756e2010-09-29 20:26:13767 size_t completion_count() const { return test_base_.completion_count(); }
768
vishal.b62985ca92015-04-17 08:45:51769 TestNetLog net_log_;
[email protected]636b8252011-04-08 19:56:54770 bool connect_backup_jobs_enabled_;
[email protected]f6d1d6eb2009-06-24 20:16:09771 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04772 TestConnectJobFactory* connect_job_factory_;
[email protected]df4b4ef2010-07-12 18:25:21773 scoped_refptr<TestSocketParams> params_;
danakj655b66c2016-04-16 00:51:38774 std::unique_ptr<TestClientSocketPool> pool_;
[email protected]2431756e2010-09-29 20:26:13775 ClientSocketPoolTest test_base_;
[email protected]f6d1d6eb2009-06-24 20:16:09776};
777
[email protected]974ebd62009-08-03 23:14:34778// Even though a timeout is specified, it doesn't time out on a synchronous
779// completion.
780TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
781 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06782 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49783 TestClientSocketPoolBase::Request request(
Paul Jensen8d6f87ec2018-01-13 00:46:54784 &ignored, CompletionCallback(), DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:15785 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:20786 internal::ClientSocketPoolBaseHelper::NORMAL, params_,
787 NetLogWithSource());
danakj655b66c2016-04-16 00:51:38788 std::unique_ptr<TestConnectJob> job(
789 new TestConnectJob(TestConnectJob::kMockJob, "a", request,
790 base::TimeDelta::FromMicroseconds(1), &delegate,
791 &client_socket_factory_, NULL));
robpercival214763f2016-07-01 23:27:01792 EXPECT_THAT(job->Connect(), IsOk());
[email protected]974ebd62009-08-03 23:14:34793}
794
795TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
796 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06797 ClientSocketHandle ignored;
vishal.b62985ca92015-04-17 08:45:51798 TestNetLog log;
[email protected]9e743cd2010-03-16 07:03:53799
[email protected]d80a4322009-08-14 07:07:49800 TestClientSocketPoolBase::Request request(
Paul Jensen8d6f87ec2018-01-13 00:46:54801 &ignored, CompletionCallback(), DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:15802 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:20803 internal::ClientSocketPoolBaseHelper::NORMAL, params_,
804 NetLogWithSource());
[email protected]974ebd62009-08-03 23:14:34805 // Deleted by TestConnectJobDelegate.
806 TestConnectJob* job =
807 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12808 "a",
[email protected]974ebd62009-08-03 23:14:34809 request,
810 base::TimeDelta::FromMicroseconds(1),
811 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30812 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17813 &log);
robpercival214763f2016-07-01 23:27:01814 ASSERT_THAT(job->Connect(), IsError(ERR_IO_PENDING));
[email protected]26b9973962012-01-28 00:57:00815 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
robpercival214763f2016-07-01 23:27:01816 EXPECT_THAT(delegate.WaitForResult(), IsError(ERR_TIMED_OUT));
[email protected]fd7b7c92009-08-20 19:38:30817
mmenke43758e62015-05-04 21:09:46818 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40819 log.GetEntries(&entries);
820
821 EXPECT_EQ(6u, entries.size());
mikecirone8b85c432016-09-08 19:11:00822 EXPECT_TRUE(LogContainsBeginEvent(entries, 0,
823 NetLogEventType::SOCKET_POOL_CONNECT_JOB));
[email protected]e9002a92010-01-29 07:10:46824 EXPECT_TRUE(LogContainsBeginEvent(
mikecirone8b85c432016-09-08 19:11:00825 entries, 1, NetLogEventType::SOCKET_POOL_CONNECT_JOB_CONNECT));
826 EXPECT_TRUE(LogContainsEvent(entries, 2,
827 NetLogEventType::CONNECT_JOB_SET_SOCKET,
828 NetLogEventPhase::NONE));
[email protected]e9002a92010-01-29 07:10:46829 EXPECT_TRUE(LogContainsEvent(
mikecirone8b85c432016-09-08 19:11:00830 entries, 3, NetLogEventType::SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
831 NetLogEventPhase::NONE));
[email protected]e9002a92010-01-29 07:10:46832 EXPECT_TRUE(LogContainsEndEvent(
mikecirone8b85c432016-09-08 19:11:00833 entries, 4, NetLogEventType::SOCKET_POOL_CONNECT_JOB_CONNECT));
834 EXPECT_TRUE(LogContainsEndEvent(entries, 5,
835 NetLogEventType::SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34836}
837
[email protected]5fc08e32009-07-15 17:09:57838TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53839 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20840
[email protected]6ecf2b92011-12-15 01:14:52841 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06842 ClientSocketHandle handle;
vishal.b62985ca92015-04-17 08:45:51843 BoundTestNetLog log;
[email protected]034df0f32013-01-07 23:17:48844 TestLoadTimingInfoNotConnected(handle);
[email protected]9e743cd2010-03-16 07:03:53845
Paul Jensen8d6f87ec2018-01-13 00:46:54846 EXPECT_EQ(OK, handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:15847 ClientSocketPool::RespectLimits::ENABLED,
848 callback.callback(), pool_.get(), log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09849 EXPECT_TRUE(handle.is_initialized());
850 EXPECT_TRUE(handle.socket());
[email protected]034df0f32013-01-07 23:17:48851 TestLoadTimingInfoConnectedNotReused(handle);
852
[email protected]f6d1d6eb2009-06-24 20:16:09853 handle.Reset();
[email protected]034df0f32013-01-07 23:17:48854 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:30855
mmenke43758e62015-05-04 21:09:46856 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40857 log.GetEntries(&entries);
858
859 EXPECT_EQ(4u, entries.size());
mikecirone8b85c432016-09-08 19:11:00860 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKET_POOL));
[email protected]9e743cd2010-03-16 07:03:53861 EXPECT_TRUE(LogContainsEvent(
mikecirone8b85c432016-09-08 19:11:00862 entries, 1, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
863 NetLogEventPhase::NONE));
864 EXPECT_TRUE(LogContainsEvent(entries, 2,
865 NetLogEventType::SOCKET_POOL_BOUND_TO_SOCKET,
866 NetLogEventPhase::NONE));
867 EXPECT_TRUE(LogContainsEndEvent(entries, 3, NetLogEventType::SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09868}
869
[email protected]ab838892009-06-30 18:49:05870TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53871 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20872
[email protected]ab838892009-06-30 18:49:05873 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
vishal.b62985ca92015-04-17 08:45:51874 BoundTestNetLog log;
[email protected]9e743cd2010-03-16 07:03:53875
[email protected]2431756e2010-09-29 20:26:13876 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:52877 TestCompletionCallback callback;
[email protected]e60e47a2010-07-14 03:37:18878 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:13879 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43880 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:45881 info.headers = new HttpResponseHeaders(std::string());
[email protected]2431756e2010-09-29 20:26:13882 handle.set_ssl_error_response_info(info);
883 EXPECT_EQ(ERR_CONNECTION_FAILED,
Paul Jensen8d6f87ec2018-01-13 00:46:54884 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:15885 ClientSocketPool::RespectLimits::ENABLED,
886 callback.callback(), pool_.get(), log.bound()));
[email protected]2431756e2010-09-29 20:26:13887 EXPECT_FALSE(handle.socket());
888 EXPECT_FALSE(handle.is_ssl_error());
889 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]034df0f32013-01-07 23:17:48890 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:30891
mmenke43758e62015-05-04 21:09:46892 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40893 log.GetEntries(&entries);
894
895 EXPECT_EQ(3u, entries.size());
mikecirone8b85c432016-09-08 19:11:00896 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:17897 EXPECT_TRUE(LogContainsEvent(
mikecirone8b85c432016-09-08 19:11:00898 entries, 1, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
899 NetLogEventPhase::NONE));
900 EXPECT_TRUE(LogContainsEndEvent(entries, 2, NetLogEventType::SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09901}
902
[email protected]211d21722009-07-22 15:48:53903TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
904 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
905
[email protected]9e743cd2010-03-16 07:03:53906 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30907
robpercival214763f2016-07-01 23:27:01908 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
909 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
910 EXPECT_THAT(StartRequest("c", DEFAULT_PRIORITY), IsOk());
911 EXPECT_THAT(StartRequest("d", DEFAULT_PRIORITY), IsOk());
[email protected]211d21722009-07-22 15:48:53912
[email protected]2431756e2010-09-29 20:26:13913 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53914 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13915 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53916
robpercival214763f2016-07-01 23:27:01917 EXPECT_THAT(StartRequest("e", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
918 EXPECT_THAT(StartRequest("f", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
919 EXPECT_THAT(StartRequest("g", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:53920
[email protected]2431756e2010-09-29 20:26:13921 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53922
[email protected]2431756e2010-09-29 20:26:13923 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53924 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13925 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53926
927 EXPECT_EQ(1, GetOrderOfRequest(1));
928 EXPECT_EQ(2, GetOrderOfRequest(2));
929 EXPECT_EQ(3, GetOrderOfRequest(3));
930 EXPECT_EQ(4, GetOrderOfRequest(4));
931 EXPECT_EQ(5, GetOrderOfRequest(5));
932 EXPECT_EQ(6, GetOrderOfRequest(6));
933 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17934
935 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13936 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53937}
938
939TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
940 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
941
[email protected]9e743cd2010-03-16 07:03:53942 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30943
[email protected]211d21722009-07-22 15:48:53944 // Reach all limits: max total sockets, and max sockets per group.
robpercival214763f2016-07-01 23:27:01945 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
946 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
947 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
948 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
[email protected]211d21722009-07-22 15:48:53949
[email protected]2431756e2010-09-29 20:26:13950 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53951 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13952 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53953
954 // Now create a new group and verify that we don't starve it.
robpercival214763f2016-07-01 23:27:01955 EXPECT_THAT(StartRequest("c", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:53956
[email protected]2431756e2010-09-29 20:26:13957 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53958
[email protected]2431756e2010-09-29 20:26:13959 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53960 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13961 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53962
963 EXPECT_EQ(1, GetOrderOfRequest(1));
964 EXPECT_EQ(2, GetOrderOfRequest(2));
965 EXPECT_EQ(3, GetOrderOfRequest(3));
966 EXPECT_EQ(4, GetOrderOfRequest(4));
967 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17968
969 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13970 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53971}
972
973TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
974 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
975
robpercival214763f2016-07-01 23:27:01976 EXPECT_THAT(StartRequest("b", LOWEST), IsOk());
977 EXPECT_THAT(StartRequest("a", MEDIUM), IsOk());
978 EXPECT_THAT(StartRequest("b", HIGHEST), IsOk());
979 EXPECT_THAT(StartRequest("a", LOWEST), IsOk());
[email protected]211d21722009-07-22 15:48:53980
[email protected]2431756e2010-09-29 20:26:13981 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53982 client_socket_factory_.allocation_count());
983
robpercival214763f2016-07-01 23:27:01984 EXPECT_THAT(StartRequest("c", LOWEST), IsError(ERR_IO_PENDING));
985 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
986 EXPECT_THAT(StartRequest("b", HIGHEST), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:53987
[email protected]2431756e2010-09-29 20:26:13988 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53989
[email protected]2431756e2010-09-29 20:26:13990 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53991
992 // First 4 requests don't have to wait, and finish in order.
993 EXPECT_EQ(1, GetOrderOfRequest(1));
994 EXPECT_EQ(2, GetOrderOfRequest(2));
995 EXPECT_EQ(3, GetOrderOfRequest(3));
996 EXPECT_EQ(4, GetOrderOfRequest(4));
997
[email protected]ac790b42009-12-02 04:31:31998 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
999 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:531000 EXPECT_EQ(7, GetOrderOfRequest(5));
1001 EXPECT_EQ(6, GetOrderOfRequest(6));
1002 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171003
1004 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131005 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]211d21722009-07-22 15:48:531006}
1007
rdsmith29dbad12017-02-17 02:22:181008// Test reprioritizing a request before completion doesn't interfere with
1009// its completion.
1010TEST_F(ClientSocketPoolBaseTest, ReprioritizeOne) {
1011 CreatePool(kDefaultMaxSockets, 1);
1012
1013 EXPECT_THAT(StartRequest("a", LOWEST), IsError(OK));
1014 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1015 EXPECT_TRUE(request(0)->handle()->socket());
1016 EXPECT_FALSE(request(1)->handle()->socket());
1017
1018 request(1)->handle()->SetPriority(MEDIUM);
1019
1020 ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE);
1021
1022 EXPECT_TRUE(request(1)->handle()->socket());
1023}
1024
1025// Reprioritize a request up past another one and make sure that changes the
1026// completion order.
1027TEST_F(ClientSocketPoolBaseTest, ReprioritizeUpReorder) {
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_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
1033 EXPECT_TRUE(request(0)->handle()->socket());
1034 EXPECT_FALSE(request(1)->handle()->socket());
1035 EXPECT_FALSE(request(2)->handle()->socket());
1036
1037 request(2)->handle()->SetPriority(HIGHEST);
1038
1039 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1040
1041 EXPECT_EQ(1, GetOrderOfRequest(1));
1042 EXPECT_EQ(3, GetOrderOfRequest(2));
1043 EXPECT_EQ(2, GetOrderOfRequest(3));
1044}
1045
1046// Reprioritize a request without changing relative priorities and check
1047// that the order doesn't change.
1048TEST_F(ClientSocketPoolBaseTest, ReprioritizeUpNoReorder) {
1049 CreatePool(kDefaultMaxSockets, 1);
1050
1051 EXPECT_THAT(StartRequest("a", LOWEST), IsError(OK));
1052 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1053 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1054 EXPECT_TRUE(request(0)->handle()->socket());
1055 EXPECT_FALSE(request(1)->handle()->socket());
1056 EXPECT_FALSE(request(2)->handle()->socket());
1057
1058 request(2)->handle()->SetPriority(MEDIUM);
1059
1060 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1061
1062 EXPECT_EQ(1, GetOrderOfRequest(1));
1063 EXPECT_EQ(2, GetOrderOfRequest(2));
1064 EXPECT_EQ(3, GetOrderOfRequest(3));
1065}
1066
1067// Reprioritize a request past down another one and make sure that changes the
1068// completion order.
1069TEST_F(ClientSocketPoolBaseTest, ReprioritizeDownReorder) {
1070 CreatePool(kDefaultMaxSockets, 1);
1071
1072 EXPECT_THAT(StartRequest("a", LOWEST), IsError(OK));
1073 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
1074 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1075 EXPECT_TRUE(request(0)->handle()->socket());
1076 EXPECT_FALSE(request(1)->handle()->socket());
1077 EXPECT_FALSE(request(2)->handle()->socket());
1078
1079 request(1)->handle()->SetPriority(LOW);
1080
1081 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1082
1083 EXPECT_EQ(1, GetOrderOfRequest(1));
1084 EXPECT_EQ(3, GetOrderOfRequest(2));
1085 EXPECT_EQ(2, GetOrderOfRequest(3));
1086}
1087
1088// Reprioritize a request to the same level as another and confirm it is
1089// put after the old request.
1090TEST_F(ClientSocketPoolBaseTest, ReprioritizeResetFIFO) {
1091 CreatePool(kDefaultMaxSockets, 1);
1092
1093 EXPECT_THAT(StartRequest("a", LOWEST), IsError(OK));
1094 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
1095 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1096 EXPECT_TRUE(request(0)->handle()->socket());
1097 EXPECT_FALSE(request(1)->handle()->socket());
1098 EXPECT_FALSE(request(2)->handle()->socket());
1099
1100 request(1)->handle()->SetPriority(MEDIUM);
1101
1102 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1103
1104 EXPECT_EQ(1, GetOrderOfRequest(1));
1105 EXPECT_EQ(3, GetOrderOfRequest(2));
1106 EXPECT_EQ(2, GetOrderOfRequest(3));
1107}
1108
[email protected]211d21722009-07-22 15:48:531109TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
1110 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1111
robpercival214763f2016-07-01 23:27:011112 EXPECT_THAT(StartRequest("a", LOWEST), IsOk());
1113 EXPECT_THAT(StartRequest("a", LOW), IsOk());
1114 EXPECT_THAT(StartRequest("b", HIGHEST), IsOk());
1115 EXPECT_THAT(StartRequest("b", MEDIUM), IsOk());
[email protected]211d21722009-07-22 15:48:531116
[email protected]2431756e2010-09-29 20:26:131117 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531118 client_socket_factory_.allocation_count());
1119
robpercival214763f2016-07-01 23:27:011120 EXPECT_THAT(StartRequest("c", MEDIUM), IsError(ERR_IO_PENDING));
1121 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1122 EXPECT_THAT(StartRequest("b", HIGHEST), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531123
[email protected]2431756e2010-09-29 20:26:131124 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531125
[email protected]2431756e2010-09-29 20:26:131126 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531127 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131128 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:531129
1130 // First 4 requests don't have to wait, and finish in order.
1131 EXPECT_EQ(1, GetOrderOfRequest(1));
1132 EXPECT_EQ(2, GetOrderOfRequest(2));
1133 EXPECT_EQ(3, GetOrderOfRequest(3));
1134 EXPECT_EQ(4, GetOrderOfRequest(4));
1135
1136 // Request ("b", 7) has the highest priority, but we can't make new socket for
1137 // group "b", because it has reached the per-group limit. Then we make
1138 // socket for ("c", 6), because it has higher priority than ("a", 4),
1139 // and we still can't make a socket for group "b".
1140 EXPECT_EQ(5, GetOrderOfRequest(5));
1141 EXPECT_EQ(6, GetOrderOfRequest(6));
1142 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171143
1144 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131145 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:531146}
1147
1148// Make sure that we count connecting sockets against the total limit.
1149TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
1150 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1151
robpercival214763f2016-07-01 23:27:011152 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1153 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
1154 EXPECT_THAT(StartRequest("c", DEFAULT_PRIORITY), IsOk());
[email protected]211d21722009-07-22 15:48:531155
1156 // Create one asynchronous request.
1157 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
robpercival214763f2016-07-01 23:27:011158 EXPECT_THAT(StartRequest("d", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531159
[email protected]6b175382009-10-13 06:47:471160 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1161 // actually become pending until 2ms after they have been created. In order
1162 // to flush all tasks, we need to wait so that we know there are no
1163 // soon-to-be-pending tasks waiting.
[email protected]26b9973962012-01-28 00:57:001164 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
fdoray5eeb7642016-06-22 16:11:281165 base::RunLoop().RunUntilIdle();
[email protected]6b175382009-10-13 06:47:471166
[email protected]211d21722009-07-22 15:48:531167 // The next synchronous request should wait for its turn.
1168 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
robpercival214763f2016-07-01 23:27:011169 EXPECT_THAT(StartRequest("e", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531170
[email protected]2431756e2010-09-29 20:26:131171 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531172
[email protected]2431756e2010-09-29 20:26:131173 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531174 client_socket_factory_.allocation_count());
1175
1176 EXPECT_EQ(1, GetOrderOfRequest(1));
1177 EXPECT_EQ(2, GetOrderOfRequest(2));
1178 EXPECT_EQ(3, GetOrderOfRequest(3));
1179 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:171180 EXPECT_EQ(5, GetOrderOfRequest(5));
1181
1182 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131183 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:531184}
1185
[email protected]6427fe22010-04-16 22:27:411186TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
1187 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1188 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1189
robpercival214763f2016-07-01 23:27:011190 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1191 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1192 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1193 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
[email protected]6427fe22010-04-16 22:27:411194
1195 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1196
1197 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1198
robpercival214763f2016-07-01 23:27:011199 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1200 EXPECT_THAT(StartRequest("c", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]6427fe22010-04-16 22:27:411201
1202 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1203
[email protected]2431756e2010-09-29 20:26:131204 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411205 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131206 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411207 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131208 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1209 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411210 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
1211}
1212
[email protected]d7027bb2010-05-10 18:58:541213TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
1214 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1215 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1216
1217 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521218 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131219 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541220 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151221 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201222 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:541223
1224 ClientSocketHandle handles[4];
1225 for (size_t i = 0; i < arraysize(handles); ++i) {
[email protected]6ecf2b92011-12-15 01:14:521226 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201227 EXPECT_EQ(
1228 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541229 handles[i].Init("b", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:201230 ClientSocketPool::RespectLimits::ENABLED,
1231 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:541232 }
1233
1234 // One will be stalled, cancel all the handles now.
1235 // This should hit the OnAvailableSocketSlot() code where we previously had
1236 // stalled groups, but no longer have any.
1237 for (size_t i = 0; i < arraysize(handles); ++i)
1238 handles[i].Reset();
1239}
1240
[email protected]eb5a99382010-07-11 03:18:261241TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:541242 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1243 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1244
[email protected]eb5a99382010-07-11 03:18:261245 {
1246 ClientSocketHandle handles[kDefaultMaxSockets];
[email protected]6ecf2b92011-12-15 01:14:521247 TestCompletionCallback callbacks[kDefaultMaxSockets];
[email protected]eb5a99382010-07-11 03:18:261248 for (int i = 0; i < kDefaultMaxSockets; ++i) {
Paul Jensen8d6f87ec2018-01-13 00:46:541249 EXPECT_EQ(OK, handles[i].Init(base::IntToString(i), params_,
1250 DEFAULT_PRIORITY, SocketTag(),
1251 ClientSocketPool::RespectLimits::ENABLED,
1252 callbacks[i].callback(), pool_.get(),
1253 NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261254 }
1255
1256 // Force a stalled group.
1257 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521258 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201259 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541260 stalled_handle.Init("foo", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:201261 ClientSocketPool::RespectLimits::ENABLED,
1262 callback.callback(), pool_.get(),
1263 NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261264
1265 // Cancel the stalled request.
1266 stalled_handle.Reset();
1267
1268 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1269 EXPECT_EQ(0, pool_->IdleSocketCount());
1270
1271 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541272 }
1273
[email protected]43a21b82010-06-10 21:30:541274 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1275 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:261276}
[email protected]43a21b82010-06-10 21:30:541277
[email protected]eb5a99382010-07-11 03:18:261278TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
1279 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1280 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1281
1282 {
1283 ClientSocketHandle handles[kDefaultMaxSockets];
1284 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521285 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201286 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541287 handles[i].Init(
1288 base::IntToString(i), params_, DEFAULT_PRIORITY,
1289 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1290 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261291 }
1292
1293 // Force a stalled group.
1294 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1295 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521296 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201297 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541298 stalled_handle.Init("foo", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:201299 ClientSocketPool::RespectLimits::ENABLED,
1300 callback.callback(), pool_.get(),
1301 NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261302
1303 // Since it is stalled, it should have no connect jobs.
1304 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101305 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261306
1307 // Cancel the stalled request.
1308 handles[0].Reset();
1309
[email protected]eb5a99382010-07-11 03:18:261310 // Now we should have a connect job.
1311 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101312 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261313
1314 // The stalled socket should connect.
robpercival214763f2016-07-01 23:27:011315 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:261316
1317 EXPECT_EQ(kDefaultMaxSockets + 1,
1318 client_socket_factory_.allocation_count());
1319 EXPECT_EQ(0, pool_->IdleSocketCount());
1320 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101321 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261322
1323 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541324 }
1325
[email protected]eb5a99382010-07-11 03:18:261326 EXPECT_EQ(1, pool_->IdleSocketCount());
1327}
[email protected]43a21b82010-06-10 21:30:541328
[email protected]eb5a99382010-07-11 03:18:261329TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1330 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1331 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:541332
[email protected]eb5a99382010-07-11 03:18:261333 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521334 TestCompletionCallback callback;
[email protected]eb5a99382010-07-11 03:18:261335 {
[email protected]51fdc7c2012-04-10 19:19:481336 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261337 ClientSocketHandle handles[kDefaultMaxSockets];
1338 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521339 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201340 EXPECT_EQ(OK, handles[i].Init(base::StringPrintf("Take 2: %d", i),
Paul Jensen8d6f87ec2018-01-13 00:46:541341 params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:201342 ClientSocketPool::RespectLimits::ENABLED,
1343 callback.callback(), pool_.get(),
1344 NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261345 }
1346
1347 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1348 EXPECT_EQ(0, pool_->IdleSocketCount());
[email protected]51fdc7c2012-04-10 19:19:481349 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261350
1351 // Now we will hit the socket limit.
tfarina428341112016-09-22 13:38:201352 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541353 stalled_handle.Init("foo", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:201354 ClientSocketPool::RespectLimits::ENABLED,
1355 callback.callback(), pool_.get(),
1356 NetLogWithSource()));
[email protected]51fdc7c2012-04-10 19:19:481357 EXPECT_TRUE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261358
1359 // Dropping out of scope will close all handles and return them to idle.
1360 }
[email protected]43a21b82010-06-10 21:30:541361
1362 // But if we wait for it, the released idle sockets will be closed in
1363 // preference of the waiting request.
robpercival214763f2016-07-01 23:27:011364 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:261365
1366 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1367 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:541368}
1369
1370// Regression test for http://crbug.com/40952.
1371TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1372 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]06d94042010-08-25 01:45:221373 pool_->EnableConnectBackupJobs();
[email protected]43a21b82010-06-10 21:30:541374 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1375
1376 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1377 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521378 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201379 EXPECT_EQ(
1380 OK, handle.Init(base::IntToString(i), params_, DEFAULT_PRIORITY,
Paul Jensen8d6f87ec2018-01-13 00:46:541381 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201382 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]43a21b82010-06-10 21:30:541383 }
1384
1385 // Flush all the DoReleaseSocket tasks.
fdoray5eeb7642016-06-22 16:11:281386 base::RunLoop().RunUntilIdle();
[email protected]43a21b82010-06-10 21:30:541387
1388 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1389 // reuse a socket.
1390 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1391 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521392 TestCompletionCallback callback;
[email protected]43a21b82010-06-10 21:30:541393
1394 // "0" is special here, since it should be the first entry in the sorted map,
1395 // which is the one which we would close an idle socket for. We shouldn't
1396 // close an idle socket though, since we should reuse the idle socket.
tfarina428341112016-09-22 13:38:201397 EXPECT_EQ(OK,
Paul Jensen8d6f87ec2018-01-13 00:46:541398 handle.Init("0", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:201399 ClientSocketPool::RespectLimits::ENABLED,
1400 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]43a21b82010-06-10 21:30:541401
1402 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1403 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1404}
1405
[email protected]ab838892009-06-30 18:49:051406TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531407 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091408
robpercival214763f2016-07-01 23:27:011409 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1410 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1411 EXPECT_THAT(StartRequest("a", IDLE), IsError(ERR_IO_PENDING));
1412 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
1413 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1414 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
1415 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1416 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091417
[email protected]2431756e2010-09-29 20:26:131418 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]c9d6a1d2009-07-14 16:15:201419 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1420 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131421 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1422 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091423
[email protected]c9d6a1d2009-07-14 16:15:201424 EXPECT_EQ(1, GetOrderOfRequest(1));
1425 EXPECT_EQ(2, GetOrderOfRequest(2));
[email protected]c9c6f5c2010-07-31 01:30:031426 EXPECT_EQ(8, GetOrderOfRequest(3));
1427 EXPECT_EQ(6, GetOrderOfRequest(4));
1428 EXPECT_EQ(4, GetOrderOfRequest(5));
1429 EXPECT_EQ(3, GetOrderOfRequest(6));
1430 EXPECT_EQ(5, GetOrderOfRequest(7));
1431 EXPECT_EQ(7, GetOrderOfRequest(8));
[email protected]75439d3b2009-07-23 22:11:171432
1433 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131434 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]f6d1d6eb2009-06-24 20:16:091435}
1436
[email protected]ab838892009-06-30 18:49:051437TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[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", LOWEST), IsError(ERR_IO_PENDING));
1443 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1444 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
1445 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1446 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091447
[email protected]2431756e2010-09-29 20:26:131448 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091449
[email protected]2431756e2010-09-29 20:26:131450 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
robpercival214763f2016-07-01 23:27:011451 EXPECT_THAT(request(i)->WaitForResult(), IsOk());
[email protected]c9d6a1d2009-07-14 16:15:201452
[email protected]2431756e2010-09-29 20:26:131453 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]c9d6a1d2009-07-14 16:15:201454 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131455 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1456 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091457}
1458
1459// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:051460// The pending connect job will be cancelled and should not call back into
1461// ClientSocketPoolBase.
1462TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531463 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201464
[email protected]ab838892009-06-30 18:49:051465 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131466 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521467 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:151468 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541469 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151470 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201471 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:131472 handle.Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091473}
1474
[email protected]ab838892009-06-30 18:49:051475TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531476 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201477
[email protected]ab838892009-06-30 18:49:051478 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061479 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521480 TestCompletionCallback callback;
[email protected]f6d1d6eb2009-06-24 20:16:091481
mmenked3641e12016-01-28 16:06:151482 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541483 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151484 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201485 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]f6d1d6eb2009-06-24 20:16:091486
1487 handle.Reset();
1488
[email protected]6ecf2b92011-12-15 01:14:521489 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:131490 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541491 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151492 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201493 callback2.callback(), pool_.get(), NetLogWithSource()));
[email protected]f6d1d6eb2009-06-24 20:16:091494
robpercival214763f2016-07-01 23:27:011495 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]f6d1d6eb2009-06-24 20:16:091496 EXPECT_FALSE(callback.have_result());
1497
1498 handle.Reset();
1499}
1500
[email protected]ab838892009-06-30 18:49:051501TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531502 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091503
robpercival214763f2016-07-01 23:27:011504 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1505 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1506 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
1507 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1508 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
1509 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1510 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091511
1512 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201513 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]2431756e2010-09-29 20:26:131514 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1515 (*requests())[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091516
[email protected]2431756e2010-09-29 20:26:131517 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091518
[email protected]c9d6a1d2009-07-14 16:15:201519 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1520 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131521 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1522 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091523
[email protected]c9d6a1d2009-07-14 16:15:201524 EXPECT_EQ(1, GetOrderOfRequest(1));
1525 EXPECT_EQ(2, GetOrderOfRequest(2));
1526 EXPECT_EQ(5, GetOrderOfRequest(3));
1527 EXPECT_EQ(3, GetOrderOfRequest(4));
[email protected]2431756e2010-09-29 20:26:131528 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1529 GetOrderOfRequest(5)); // Canceled request.
[email protected]c9d6a1d2009-07-14 16:15:201530 EXPECT_EQ(4, GetOrderOfRequest(6));
1531 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171532
1533 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131534 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091535}
1536
mmenke33d24423d2015-05-19 19:41:091537// Function to be used as a callback on socket request completion. It first
1538// disconnects the successfully connected socket from the first request, and
1539// then reuses the ClientSocketHandle to request another socket.
1540//
1541// |nested_callback| is called with the result of the second socket request.
1542void RequestSocketOnComplete(ClientSocketHandle* handle,
1543 TestClientSocketPool* pool,
1544 TestConnectJobFactory* test_connect_job_factory,
1545 TestConnectJob::JobType next_job_type,
1546 const CompletionCallback& nested_callback,
1547 int first_request_result) {
robpercival214763f2016-07-01 23:27:011548 EXPECT_THAT(first_request_result, IsOk());
mmenke33d24423d2015-05-19 19:41:091549
1550 test_connect_job_factory->set_job_type(next_job_type);
1551
1552 // Don't allow reuse of the socket. Disconnect it and then release it.
1553 if (handle->socket())
1554 handle->socket()->Disconnect();
1555 handle->Reset();
1556
mmenked3641e12016-01-28 16:06:151557 scoped_refptr<TestSocketParams> params(new TestSocketParams());
mmenke33d24423d2015-05-19 19:41:091558 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:541559 int rv = handle->Init("a", params, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:151560 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201561 nested_callback, pool, NetLogWithSource());
mmenke33d24423d2015-05-19 19:41:091562 if (rv != ERR_IO_PENDING) {
1563 DCHECK_EQ(TestConnectJob::kMockJob, next_job_type);
1564 nested_callback.Run(rv);
1565 } else {
1566 DCHECK_EQ(TestConnectJob::kMockPendingJob, next_job_type);
[email protected]6ecf2b92011-12-15 01:14:521567 }
mmenke33d24423d2015-05-19 19:41:091568}
[email protected]f6d1d6eb2009-06-24 20:16:091569
mmenke33d24423d2015-05-19 19:41:091570// Tests the case where a second socket is requested in a completion callback,
1571// and the second socket connects asynchronously. Reuses the same
1572// ClientSocketHandle for the second socket, after disconnecting the first.
[email protected]2ab05b52009-07-01 23:57:581573TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531574 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201575
[email protected]0b7648c2009-07-06 20:14:011576 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061577 ClientSocketHandle handle;
mmenke33d24423d2015-05-19 19:41:091578 TestCompletionCallback second_result_callback;
1579 int rv = handle.Init(
Paul Jensen8d6f87ec2018-01-13 00:46:541580 "a", params_, DEFAULT_PRIORITY, SocketTag(),
1581 ClientSocketPool::RespectLimits::ENABLED,
mmenke33d24423d2015-05-19 19:41:091582 base::Bind(&RequestSocketOnComplete, &handle, pool_.get(),
1583 connect_job_factory_, TestConnectJob::kMockPendingJob,
1584 second_result_callback.callback()),
tfarina428341112016-09-22 13:38:201585 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011586 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091587
robpercival214763f2016-07-01 23:27:011588 EXPECT_THAT(second_result_callback.WaitForResult(), IsOk());
[email protected]2ab05b52009-07-01 23:57:581589}
[email protected]f6d1d6eb2009-06-24 20:16:091590
mmenke33d24423d2015-05-19 19:41:091591// Tests the case where a second socket is requested in a completion callback,
1592// and the second socket connects synchronously. Reuses the same
1593// ClientSocketHandle for the second socket, after disconnecting the first.
[email protected]2ab05b52009-07-01 23:57:581594TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531595 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201596
[email protected]0b7648c2009-07-06 20:14:011597 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061598 ClientSocketHandle handle;
mmenke33d24423d2015-05-19 19:41:091599 TestCompletionCallback second_result_callback;
1600 int rv = handle.Init(
Paul Jensen8d6f87ec2018-01-13 00:46:541601 "a", params_, DEFAULT_PRIORITY, SocketTag(),
1602 ClientSocketPool::RespectLimits::ENABLED,
mmenke33d24423d2015-05-19 19:41:091603 base::Bind(&RequestSocketOnComplete, &handle, pool_.get(),
1604 connect_job_factory_, TestConnectJob::kMockPendingJob,
1605 second_result_callback.callback()),
tfarina428341112016-09-22 13:38:201606 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011607 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2ab05b52009-07-01 23:57:581608
robpercival214763f2016-07-01 23:27:011609 EXPECT_THAT(second_result_callback.WaitForResult(), IsOk());
[email protected]f6d1d6eb2009-06-24 20:16:091610}
1611
1612// Make sure that pending requests get serviced after active requests get
1613// cancelled.
[email protected]ab838892009-06-30 18:49:051614TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531615 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201616
[email protected]0b7648c2009-07-06 20:14:011617 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091618
robpercival214763f2016-07-01 23:27:011619 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1620 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1621 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1622 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1623 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1624 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1625 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091626
[email protected]c9d6a1d2009-07-14 16:15:201627 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1628 // Let's cancel them.
1629 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]2431756e2010-09-29 20:26:131630 ASSERT_FALSE(request(i)->handle()->is_initialized());
1631 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091632 }
1633
[email protected]f6d1d6eb2009-06-24 20:16:091634 // Let's wait for the rest to complete now.
[email protected]2431756e2010-09-29 20:26:131635 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
robpercival214763f2016-07-01 23:27:011636 EXPECT_THAT(request(i)->WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:131637 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091638 }
1639
[email protected]2431756e2010-09-29 20:26:131640 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1641 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091642}
1643
1644// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051645TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531646 const size_t kMaxSockets = 5;
1647 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201648
[email protected]0b7648c2009-07-06 20:14:011649 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091650
[email protected]211d21722009-07-22 15:48:531651 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1652 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091653
1654 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531655 for (size_t i = 0; i < kNumberOfRequests; ++i)
robpercival214763f2016-07-01 23:27:011656 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091657
[email protected]211d21722009-07-22 15:48:531658 for (size_t i = 0; i < kNumberOfRequests; ++i)
robpercival214763f2016-07-01 23:27:011659 EXPECT_THAT(request(i)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]f6d1d6eb2009-06-24 20:16:091660}
1661
mmenke9d72fe42017-05-18 22:36:071662// Make sure that pending requests that complete synchronously get serviced
1663// after active requests fail. See https://crbug.com/723748
1664TEST_F(ClientSocketPoolBaseTest, HandleMultipleSyncFailuresAfterAsyncFailure) {
1665 const size_t kNumberOfRequests = 10;
1666 const size_t kMaxSockets = 1;
1667 CreatePool(kMaxSockets, kMaxSockets);
1668
1669 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1670
1671 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1672
1673 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
1674
1675 // Queue up all the other requests
1676 for (size_t i = 1; i < kNumberOfRequests; ++i)
1677 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1678
1679 // Make sure all requests fail, instead of hanging.
1680 for (size_t i = 0; i < kNumberOfRequests; ++i)
1681 EXPECT_THAT(request(i)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
1682}
1683
[email protected]5fc08e32009-07-15 17:09:571684TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531685 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571686
1687 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1688
[email protected]2431756e2010-09-29 20:26:131689 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521690 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:541691 int rv = handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151692 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201693 callback.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011694 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:571695
1696 // Cancel the active request.
[email protected]2431756e2010-09-29 20:26:131697 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571698
Paul Jensen8d6f87ec2018-01-13 00:46:541699 rv = handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151700 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201701 callback.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011702 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1703 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]5fc08e32009-07-15 17:09:571704
[email protected]2431756e2010-09-29 20:26:131705 EXPECT_FALSE(handle.is_reused());
[email protected]034df0f32013-01-07 23:17:481706 TestLoadTimingInfoConnectedNotReused(handle);
[email protected]5fc08e32009-07-15 17:09:571707 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1708}
1709
xunjieli26619e72016-11-23 19:39:551710TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsForced) {
xunjieli26619e72016-11-23 19:39:551711 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1712 ClientSocketHandle handle;
1713 TestCompletionCallback callback;
1714 BoundTestNetLog log;
Paul Jensen8d6f87ec2018-01-13 00:46:541715 int rv = handle.Init("a", params_, LOWEST, SocketTag(),
xunjieli26619e72016-11-23 19:39:551716 ClientSocketPool::RespectLimits::ENABLED,
1717 callback.callback(), pool_.get(), log.bound());
1718 EXPECT_THAT(rv, IsOk());
1719 handle.Reset();
1720 EXPECT_EQ(1, pool_->IdleSocketCount());
1721 pool_->CloseIdleSockets();
xunjieli26619e72016-11-23 19:39:551722}
1723
xunjieli92feb332017-03-03 17:19:231724TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsInGroupForced) {
xunjieli92feb332017-03-03 17:19:231725 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1726 TestCompletionCallback callback;
1727 BoundTestNetLog log;
1728 ClientSocketHandle handle1;
Paul Jensen8d6f87ec2018-01-13 00:46:541729 int rv = handle1.Init("a", params_, LOWEST, SocketTag(),
xunjieli92feb332017-03-03 17:19:231730 ClientSocketPool::RespectLimits::ENABLED,
1731 callback.callback(), pool_.get(), log.bound());
1732 EXPECT_THAT(rv, IsOk());
1733 ClientSocketHandle handle2;
Paul Jensen8d6f87ec2018-01-13 00:46:541734 rv = handle2.Init("a", params_, LOWEST, SocketTag(),
xunjieli92feb332017-03-03 17:19:231735 ClientSocketPool::RespectLimits::ENABLED,
1736 callback.callback(), pool_.get(), log.bound());
1737 ClientSocketHandle handle3;
Paul Jensen8d6f87ec2018-01-13 00:46:541738 rv = handle3.Init("b", params_, LOWEST, SocketTag(),
xunjieli92feb332017-03-03 17:19:231739 ClientSocketPool::RespectLimits::ENABLED,
1740 callback.callback(), pool_.get(), log.bound());
1741 EXPECT_THAT(rv, IsOk());
1742 handle1.Reset();
1743 handle2.Reset();
1744 handle3.Reset();
1745 EXPECT_EQ(3, pool_->IdleSocketCount());
1746 pool_->CloseIdleSocketsInGroup("a");
1747 EXPECT_EQ(1, pool_->IdleSocketCount());
xunjieli92feb332017-03-03 17:19:231748}
1749
xunjieli26619e72016-11-23 19:39:551750TEST_F(ClientSocketPoolBaseTest, CleanUpUnusableIdleSockets) {
xunjieli26619e72016-11-23 19:39:551751 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1752 ClientSocketHandle handle;
1753 TestCompletionCallback callback;
1754 BoundTestNetLog log;
Paul Jensen8d6f87ec2018-01-13 00:46:541755 int rv = handle.Init("a", params_, LOWEST, SocketTag(),
xunjieli26619e72016-11-23 19:39:551756 ClientSocketPool::RespectLimits::ENABLED,
1757 callback.callback(), pool_.get(), log.bound());
1758 EXPECT_THAT(rv, IsOk());
1759 StreamSocket* socket = handle.socket();
1760 handle.Reset();
1761 EXPECT_EQ(1, pool_->IdleSocketCount());
1762
1763 // Disconnect socket now to make the socket unusable.
1764 socket->Disconnect();
1765 ClientSocketHandle handle2;
Paul Jensen8d6f87ec2018-01-13 00:46:541766 rv = handle2.Init("a", params_, LOWEST, SocketTag(),
xunjieli26619e72016-11-23 19:39:551767 ClientSocketPool::RespectLimits::ENABLED,
1768 callback.callback(), pool_.get(), log.bound());
1769 EXPECT_THAT(rv, IsOk());
1770 EXPECT_FALSE(handle2.is_reused());
xunjieli26619e72016-11-23 19:39:551771}
1772
[email protected]2b7523d2009-07-29 20:29:231773// Regression test for http://crbug.com/17985.
1774TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1775 const int kMaxSockets = 3;
1776 const int kMaxSocketsPerGroup = 2;
1777 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1778
[email protected]ac790b42009-12-02 04:31:311779 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231780
robpercival214763f2016-07-01 23:27:011781 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1782 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
[email protected]2b7523d2009-07-29 20:29:231783
1784 // This is going to be a pending request in an otherwise empty group.
robpercival214763f2016-07-01 23:27:011785 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]2b7523d2009-07-29 20:29:231786
1787 // Reach the maximum socket limit.
robpercival214763f2016-07-01 23:27:011788 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
[email protected]2b7523d2009-07-29 20:29:231789
1790 // Create a stalled group with high priorities.
robpercival214763f2016-07-01 23:27:011791 EXPECT_THAT(StartRequest("c", kHighPriority), IsError(ERR_IO_PENDING));
1792 EXPECT_THAT(StartRequest("c", kHighPriority), IsError(ERR_IO_PENDING));
[email protected]2b7523d2009-07-29 20:29:231793
[email protected]eb5a99382010-07-11 03:18:261794 // Release the first two sockets from "a". Because this is a keepalive,
1795 // the first release will unblock the pending request for "a". The
1796 // second release will unblock a request for "c", becaue it is the next
1797 // high priority socket.
[email protected]2431756e2010-09-29 20:26:131798 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1799 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]2b7523d2009-07-29 20:29:231800
1801 // Closing idle sockets should not get us into trouble, but in the bug
1802 // we were hitting a CHECK here.
[email protected]93054cc12010-06-08 06:12:411803 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]43a21b82010-06-10 21:30:541804 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261805
[email protected]2da659e2013-05-23 20:51:341806 // Run the released socket wakeups.
fdoray5eeb7642016-06-22 16:11:281807 base::RunLoop().RunUntilIdle();
[email protected]2b7523d2009-07-29 20:29:231808}
1809
[email protected]4d3b05d2010-01-27 21:27:291810TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531811 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571812
1813 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131814 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521815 TestCompletionCallback callback;
vishal.b62985ca92015-04-17 08:45:511816 BoundTestNetLog log;
Paul Jensen8d6f87ec2018-01-13 00:46:541817 int rv = handle.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:151818 ClientSocketPool::RespectLimits::ENABLED,
1819 callback.callback(), pool_.get(), log.bound());
robpercival214763f2016-07-01 23:27:011820 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2431756e2010-09-29 20:26:131821 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
[email protected]034df0f32013-01-07 23:17:481822 TestLoadTimingInfoNotConnected(handle);
1823
robpercival214763f2016-07-01 23:27:011824 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:131825 EXPECT_TRUE(handle.is_initialized());
1826 EXPECT_TRUE(handle.socket());
[email protected]034df0f32013-01-07 23:17:481827 TestLoadTimingInfoConnectedNotReused(handle);
1828
[email protected]2431756e2010-09-29 20:26:131829 handle.Reset();
[email protected]034df0f32013-01-07 23:17:481830 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:301831
mmenke43758e62015-05-04 21:09:461832 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:401833 log.GetEntries(&entries);
1834
1835 EXPECT_EQ(4u, entries.size());
mikecirone8b85c432016-09-08 19:11:001836 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171837 EXPECT_TRUE(LogContainsEvent(
mikecirone8b85c432016-09-08 19:11:001838 entries, 1, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1839 NetLogEventPhase::NONE));
1840 EXPECT_TRUE(LogContainsEvent(entries, 2,
1841 NetLogEventType::SOCKET_POOL_BOUND_TO_SOCKET,
1842 NetLogEventPhase::NONE));
1843 EXPECT_TRUE(LogContainsEndEvent(entries, 3, NetLogEventType::SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571844}
1845
[email protected]4d3b05d2010-01-27 21:27:291846TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571847 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531848 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571849
1850 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2431756e2010-09-29 20:26:131851 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521852 TestCompletionCallback callback;
vishal.b62985ca92015-04-17 08:45:511853 BoundTestNetLog log;
[email protected]e60e47a2010-07-14 03:37:181854 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:131855 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:431856 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:451857 info.headers = new HttpResponseHeaders(std::string());
[email protected]2431756e2010-09-29 20:26:131858 handle.set_ssl_error_response_info(info);
mmenked3641e12016-01-28 16:06:151859 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541860 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151861 ClientSocketPool::RespectLimits::ENABLED,
1862 callback.callback(), pool_.get(), log.bound()));
[email protected]2431756e2010-09-29 20:26:131863 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
robpercival214763f2016-07-01 23:27:011864 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]2431756e2010-09-29 20:26:131865 EXPECT_FALSE(handle.is_ssl_error());
1866 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:301867
mmenke43758e62015-05-04 21:09:461868 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:401869 log.GetEntries(&entries);
1870
1871 EXPECT_EQ(3u, entries.size());
mikecirone8b85c432016-09-08 19:11:001872 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171873 EXPECT_TRUE(LogContainsEvent(
mikecirone8b85c432016-09-08 19:11:001874 entries, 1, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1875 NetLogEventPhase::NONE));
1876 EXPECT_TRUE(LogContainsEndEvent(entries, 2, NetLogEventType::SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571877}
1878
mmenke6be122f2015-03-09 22:22:471879// Check that an async ConnectJob failure does not result in creation of a new
1880// ConnectJob when there's another pending request also waiting on its own
1881// ConnectJob. See http://crbug.com/463960.
1882TEST_F(ClientSocketPoolBaseTest, AsyncFailureWithPendingRequestWithJob) {
1883 CreatePool(2, 2);
1884 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1885
robpercival214763f2016-07-01 23:27:011886 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1887 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
mmenke6be122f2015-03-09 22:22:471888
robpercival214763f2016-07-01 23:27:011889 EXPECT_THAT(request(0)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
1890 EXPECT_THAT(request(1)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
mmenke6be122f2015-03-09 22:22:471891
1892 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1893}
1894
[email protected]4d3b05d2010-01-27 21:27:291895TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101896 // TODO(eroman): Add back the log expectations! Removed them because the
1897 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531898 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571899
1900 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131901 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521902 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131903 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:521904 TestCompletionCallback callback2;
[email protected]5fc08e32009-07-15 17:09:571905
[email protected]2431756e2010-09-29 20:26:131906 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541907 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151908 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201909 callback.callback(), pool_.get(), NetLogWithSource()));
vishal.b62985ca92015-04-17 08:45:511910 BoundTestNetLog log2;
tfarina428341112016-09-22 13:38:201911 EXPECT_EQ(
1912 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541913 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:201914 ClientSocketPool::RespectLimits::ENABLED,
1915 callback2.callback(), pool_.get(), NetLogWithSource()));
[email protected]5fc08e32009-07-15 17:09:571916
[email protected]2431756e2010-09-29 20:26:131917 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571918
[email protected]fd7b7c92009-08-20 19:38:301919
1920 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301921
robpercival214763f2016-07-01 23:27:011922 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:131923 handle2.Reset();
[email protected]fd7b7c92009-08-20 19:38:301924
1925 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531926 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571927}
1928
[email protected]4d3b05d2010-01-27 21:27:291929TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341930 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1931
[email protected]17a0c6c2009-08-04 00:07:041932 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1933
robpercival214763f2016-07-01 23:27:011934 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
1935 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1936 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1937 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
[email protected]974ebd62009-08-03 23:14:341938
1939 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]2431756e2010-09-29 20:26:131940 (*requests())[2]->handle()->Reset();
1941 (*requests())[3]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341942 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1943
[email protected]2431756e2010-09-29 20:26:131944 (*requests())[1]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341945 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1946
[email protected]2431756e2010-09-29 20:26:131947 (*requests())[0]->handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261948 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]974ebd62009-08-03 23:14:341949}
1950
[email protected]5fc08e32009-07-15 17:09:571951// When requests and ConnectJobs are not coupled, the request will get serviced
1952// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291953TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531954 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571955
1956 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321957 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571958
[email protected]2431756e2010-09-29 20:26:131959 std::vector<TestSocketRequest*> request_order;
1960 size_t completion_count; // unused
1961 TestSocketRequest req1(&request_order, &completion_count);
Paul Jensen8d6f87ec2018-01-13 00:46:541962 int rv =
1963 req1.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
1964 ClientSocketPool::RespectLimits::ENABLED,
1965 req1.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011966 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1967 EXPECT_THAT(req1.WaitForResult(), IsOk());
[email protected]5fc08e32009-07-15 17:09:571968
1969 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1970 // without a job.
1971 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1972
[email protected]2431756e2010-09-29 20:26:131973 TestSocketRequest req2(&request_order, &completion_count);
Paul Jensen8d6f87ec2018-01-13 00:46:541974 rv = req2.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151975 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201976 req2.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011977 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2431756e2010-09-29 20:26:131978 TestSocketRequest req3(&request_order, &completion_count);
Paul Jensen8d6f87ec2018-01-13 00:46:541979 rv = req3.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151980 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201981 req3.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011982 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:571983
1984 // Both Requests 2 and 3 are pending. We release socket 1 which should
1985 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331986 req1.handle()->Reset();
[email protected]2da659e2013-05-23 20:51:341987 // Run the released socket wakeups.
fdoray5eeb7642016-06-22 16:11:281988 base::RunLoop().RunUntilIdle();
[email protected]a6c59f62009-07-29 16:33:331989 ASSERT_TRUE(req2.handle()->socket());
robpercival214763f2016-07-01 23:27:011990 EXPECT_THAT(req2.WaitForResult(), IsOk());
[email protected]a6c59f62009-07-29 16:33:331991 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571992
1993 // Signal job 2, which should service request 3.
1994
1995 client_socket_factory_.SignalJobs();
robpercival214763f2016-07-01 23:27:011996 EXPECT_THAT(req3.WaitForResult(), IsOk());
[email protected]5fc08e32009-07-15 17:09:571997
[email protected]2431756e2010-09-29 20:26:131998 ASSERT_EQ(3U, request_order.size());
1999 EXPECT_EQ(&req1, request_order[0]);
2000 EXPECT_EQ(&req2, request_order[1]);
2001 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:572002 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2003}
2004
2005// The requests are not coupled to the jobs. So, the requests should finish in
2006// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:292007TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:532008 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:572009 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:322010 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:572011
[email protected]2431756e2010-09-29 20:26:132012 std::vector<TestSocketRequest*> request_order;
2013 size_t completion_count; // unused
2014 TestSocketRequest req1(&request_order, &completion_count);
Paul Jensen8d6f87ec2018-01-13 00:46:542015 int rv =
2016 req1.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2017 ClientSocketPool::RespectLimits::ENABLED,
2018 req1.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012019 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572020
[email protected]2431756e2010-09-29 20:26:132021 TestSocketRequest req2(&request_order, &completion_count);
Paul Jensen8d6f87ec2018-01-13 00:46:542022 rv = req2.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152023 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202024 req2.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012025 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572026
2027 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:322028 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:572029
[email protected]2431756e2010-09-29 20:26:132030 TestSocketRequest req3(&request_order, &completion_count);
Paul Jensen8d6f87ec2018-01-13 00:46:542031 rv = req3.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152032 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202033 req3.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012034 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572035
robpercival214763f2016-07-01 23:27:012036 EXPECT_THAT(req1.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
2037 EXPECT_THAT(req2.WaitForResult(), IsOk());
2038 EXPECT_THAT(req3.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]5fc08e32009-07-15 17:09:572039
[email protected]2431756e2010-09-29 20:26:132040 ASSERT_EQ(3U, request_order.size());
2041 EXPECT_EQ(&req1, request_order[0]);
2042 EXPECT_EQ(&req2, request_order[1]);
2043 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:572044}
2045
[email protected]03b7c8c2013-07-20 04:38:552046// Test GetLoadState in the case there's only one socket request.
2047TEST_F(ClientSocketPoolBaseTest, LoadStateOneRequest) {
[email protected]211d21722009-07-22 15:48:532048 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]03b7c8c2013-07-20 04:38:552049 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]5fc08e32009-07-15 17:09:572050
[email protected]2431756e2010-09-29 20:26:132051 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522052 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:542053 int rv = handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152054 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202055 callback.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012056 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552057 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:572058
[email protected]03b7c8c2013-07-20 04:38:552059 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2060 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
2061
2062 // No point in completing the connection, since ClientSocketHandles only
2063 // expect the LoadState to be checked while connecting.
2064}
2065
2066// Test GetLoadState in the case there are two socket requests.
haavardm835c1d62015-04-22 08:18:002067// Only the first connection in the pool should affect the pool's load status.
[email protected]03b7c8c2013-07-20 04:38:552068TEST_F(ClientSocketPoolBaseTest, LoadStateTwoRequests) {
2069 CreatePool(2, 2);
2070 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2071
2072 ClientSocketHandle handle;
2073 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:542074 int rv = handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152075 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202076 callback.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012077 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
haavardm835c1d62015-04-22 08:18:002078 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
2079
2080 ClientSocketHandle handle2;
2081 TestCompletionCallback callback2;
Paul Jensen8d6f87ec2018-01-13 00:46:542082 rv = handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152083 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202084 callback2.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012085 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
haavardm835c1d62015-04-22 08:18:002086 client_socket_factory_.SetJobLoadState(1, LOAD_STATE_RESOLVING_HOST);
2087
2088 // Check that both handles report the state of the first job.
2089 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle.GetLoadState());
2090 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle2.GetLoadState());
2091
2092 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_CONNECTING);
2093
2094 // Check that both handles change to LOAD_STATE_CONNECTING.
2095 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2096 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
2097}
2098
2099// Test that the second connection request does not affect the pool's load
2100// status.
2101TEST_F(ClientSocketPoolBaseTest, LoadStateTwoRequestsChangeSecondRequestState) {
2102 CreatePool(2, 2);
2103 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2104
2105 ClientSocketHandle handle;
2106 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:542107 int rv = handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152108 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202109 callback.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012110 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572111
[email protected]2431756e2010-09-29 20:26:132112 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522113 TestCompletionCallback callback2;
Paul Jensen8d6f87ec2018-01-13 00:46:542114 rv = handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152115 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202116 callback2.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012117 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
haavardm835c1d62015-04-22 08:18:002118 client_socket_factory_.SetJobLoadState(1, LOAD_STATE_RESOLVING_HOST);
[email protected]03b7c8c2013-07-20 04:38:552119
[email protected]03b7c8c2013-07-20 04:38:552120 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2121 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
2122
haavardm835c1d62015-04-22 08:18:002123 // First job connects and the first request gets the socket. The
[email protected]03b7c8c2013-07-20 04:38:552124 // second handle switches to the state of the remaining ConnectJob.
2125 client_socket_factory_.SignalJob(0);
robpercival214763f2016-07-01 23:27:012126 EXPECT_THAT(callback.WaitForResult(), IsOk());
haavardm835c1d62015-04-22 08:18:002127 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle2.GetLoadState());
[email protected]03b7c8c2013-07-20 04:38:552128}
2129
2130// Test GetLoadState in the case the per-group limit is reached.
2131TEST_F(ClientSocketPoolBaseTest, LoadStateGroupLimit) {
2132 CreatePool(2, 1);
2133 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2134
2135 ClientSocketHandle handle;
2136 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:542137 int rv = handle.Init("a", params_, MEDIUM, SocketTag(),
mmenked3641e12016-01-28 16:06:152138 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202139 callback.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012140 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552141 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2142
2143 // Request another socket from the same pool, buth with a higher priority.
2144 // The first request should now be stalled at the socket group limit.
2145 ClientSocketHandle handle2;
2146 TestCompletionCallback callback2;
Paul Jensen8d6f87ec2018-01-13 00:46:542147 rv = handle2.Init("a", params_, HIGHEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152148 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202149 callback2.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012150 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552151 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2152 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
2153
2154 // The first handle should remain stalled as the other socket goes through
2155 // the connect process.
2156
2157 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2158 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2159 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle2.GetLoadState());
2160
2161 client_socket_factory_.SignalJob(0);
robpercival214763f2016-07-01 23:27:012162 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]03b7c8c2013-07-20 04:38:552163 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2164
2165 // Closing the second socket should cause the stalled handle to finally get a
2166 // ConnectJob.
2167 handle2.socket()->Disconnect();
2168 handle2.Reset();
2169 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2170}
2171
2172// Test GetLoadState in the case the per-pool limit is reached.
2173TEST_F(ClientSocketPoolBaseTest, LoadStatePoolLimit) {
2174 CreatePool(2, 2);
2175 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2176
2177 ClientSocketHandle handle;
2178 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:542179 int rv = handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152180 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202181 callback.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012182 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552183
2184 // Request for socket from another pool.
2185 ClientSocketHandle handle2;
2186 TestCompletionCallback callback2;
Paul Jensen8d6f87ec2018-01-13 00:46:542187 rv = handle2.Init("b", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152188 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202189 callback2.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012190 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552191
2192 // Request another socket from the first pool. Request should stall at the
2193 // socket pool limit.
2194 ClientSocketHandle handle3;
2195 TestCompletionCallback callback3;
Paul Jensen8d6f87ec2018-01-13 00:46:542196 rv = handle3.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152197 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202198 callback2.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012199 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552200
2201 // The third handle should remain stalled as the other sockets in its group
2202 // goes through the connect process.
2203
2204 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2205 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2206
2207 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2208 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
2209 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2210
2211 client_socket_factory_.SignalJob(0);
robpercival214763f2016-07-01 23:27:012212 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]03b7c8c2013-07-20 04:38:552213 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2214
2215 // Closing a socket should allow the stalled handle to finally get a new
2216 // ConnectJob.
2217 handle.socket()->Disconnect();
2218 handle.Reset();
2219 EXPECT_EQ(LOAD_STATE_CONNECTING, handle3.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:572220}
2221
[email protected]e772db3f2010-07-12 18:11:132222TEST_F(ClientSocketPoolBaseTest, Recoverable) {
2223 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2224 connect_job_factory_->set_job_type(TestConnectJob::kMockRecoverableJob);
2225
[email protected]2431756e2010-09-29 20:26:132226 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522227 TestCompletionCallback callback;
2228 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED,
Paul Jensen8d6f87ec2018-01-13 00:46:542229 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152230 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202231 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:132232 EXPECT_TRUE(handle.is_initialized());
2233 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:132234}
2235
2236TEST_F(ClientSocketPoolBaseTest, AsyncRecoverable) {
2237 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2238
2239 connect_job_factory_->set_job_type(
2240 TestConnectJob::kMockPendingRecoverableJob);
[email protected]2431756e2010-09-29 20:26:132241 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522242 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132243 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542244 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152245 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202246 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:132247 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
robpercival214763f2016-07-01 23:27:012248 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_PROXY_AUTH_REQUESTED));
[email protected]2431756e2010-09-29 20:26:132249 EXPECT_TRUE(handle.is_initialized());
2250 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:132251}
2252
[email protected]e60e47a2010-07-14 03:37:182253TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
2254 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2255 connect_job_factory_->set_job_type(
2256 TestConnectJob::kMockAdditionalErrorStateJob);
2257
[email protected]2431756e2010-09-29 20:26:132258 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522259 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132260 EXPECT_EQ(ERR_CONNECTION_FAILED,
Paul Jensen8d6f87ec2018-01-13 00:46:542261 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152262 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202263 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:132264 EXPECT_FALSE(handle.is_initialized());
2265 EXPECT_FALSE(handle.socket());
2266 EXPECT_TRUE(handle.is_ssl_error());
2267 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182268}
2269
2270TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
2271 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2272
2273 connect_job_factory_->set_job_type(
2274 TestConnectJob::kMockPendingAdditionalErrorStateJob);
[email protected]2431756e2010-09-29 20:26:132275 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522276 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132277 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542278 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152279 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202280 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:132281 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
robpercival214763f2016-07-01 23:27:012282 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]2431756e2010-09-29 20:26:132283 EXPECT_FALSE(handle.is_initialized());
2284 EXPECT_FALSE(handle.socket());
2285 EXPECT_TRUE(handle.is_ssl_error());
2286 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182287}
2288
martijn003cd612016-05-19 22:24:382289// Make sure we can reuse sockets.
2290TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSocketsReuse) {
[email protected]64770b7d2011-11-16 04:30:412291 CreatePoolWithIdleTimeouts(
2292 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
[email protected]e7b1c6d2c2012-05-05 00:54:032293 base::TimeDelta(), // Time out unused sockets immediately.
2294 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2295
2296 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2297
2298 ClientSocketHandle handle;
2299 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:542300 int rv = handle.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152301 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202302 callback.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012303 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e7b1c6d2c2012-05-05 00:54:032304 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
robpercival214763f2016-07-01 23:27:012305 ASSERT_THAT(callback.WaitForResult(), IsOk());
[email protected]e7b1c6d2c2012-05-05 00:54:032306
2307 // Use and release the socket.
Ramin Halavati0a08cc82018-02-06 07:46:382308 EXPECT_EQ(1, handle.socket()->Write(NULL, 1, CompletionCallback(),
2309 TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]034df0f32013-01-07 23:17:482310 TestLoadTimingInfoConnectedNotReused(handle);
[email protected]e7b1c6d2c2012-05-05 00:54:032311 handle.Reset();
2312
2313 // Should now have one idle socket.
2314 ASSERT_EQ(1, pool_->IdleSocketCount());
2315
2316 // Request a new socket. This should reuse the old socket and complete
2317 // synchronously.
vishal.b62985ca92015-04-17 08:45:512318 BoundTestNetLog log;
Paul Jensen8d6f87ec2018-01-13 00:46:542319 rv = handle.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152320 ClientSocketPool::RespectLimits::ENABLED,
2321 CompletionCallback(), pool_.get(), log.bound());
robpercival214763f2016-07-01 23:27:012322 ASSERT_THAT(rv, IsOk());
[email protected]e7b1c6d2c2012-05-05 00:54:032323 EXPECT_TRUE(handle.is_reused());
[email protected]034df0f32013-01-07 23:17:482324 TestLoadTimingInfoConnectedReused(handle);
[email protected]e7b1c6d2c2012-05-05 00:54:032325
2326 ASSERT_TRUE(pool_->HasGroup("a"));
2327 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2328 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2329
mmenke43758e62015-05-04 21:09:462330 TestNetLogEntry::List entries;
[email protected]e7b1c6d2c2012-05-05 00:54:032331 log.GetEntries(&entries);
2332 EXPECT_TRUE(LogContainsEntryWithType(
mikecirone8b85c432016-09-08 19:11:002333 entries, 1, NetLogEventType::SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]e7b1c6d2c2012-05-05 00:54:032334}
2335
martijn003cd612016-05-19 22:24:382336// Make sure we cleanup old unused sockets.
Eric Romanb49715e2018-04-24 22:41:172337TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSocketsNoReuse) {
[email protected]e7b1c6d2c2012-05-05 00:54:032338 CreatePoolWithIdleTimeouts(
2339 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2340 base::TimeDelta(), // Time out unused sockets immediately
2341 base::TimeDelta()); // Time out used sockets immediately
[email protected]64770b7d2011-11-16 04:30:412342
2343 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2344
2345 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2346
2347 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522348 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:542349 int rv = handle.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152350 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202351 callback.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012352 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]64770b7d2011-11-16 04:30:412353 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2354
2355 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522356 TestCompletionCallback callback2;
Paul Jensen8d6f87ec2018-01-13 00:46:542357 rv = handle2.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152358 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202359 callback2.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012360 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]64770b7d2011-11-16 04:30:412361 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
2362
2363 // Cancel one of the requests. Wait for the other, which will get the first
2364 // job. Release the socket. Run the loop again to make sure the second
2365 // socket is sitting idle and the first one is released (since ReleaseSocket()
2366 // just posts a DoReleaseSocket() task).
2367
2368 handle.Reset();
robpercival214763f2016-07-01 23:27:012369 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]64770b7d2011-11-16 04:30:412370 // Use the socket.
Ramin Halavati0a08cc82018-02-06 07:46:382371 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, CompletionCallback(),
2372 TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]64770b7d2011-11-16 04:30:412373 handle2.Reset();
2374
[email protected]e7b1c6d2c2012-05-05 00:54:032375 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2376 // actually become pending until 2ms after they have been created. In order
2377 // to flush all tasks, we need to wait so that we know there are no
2378 // soon-to-be-pending tasks waiting.
2379 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
fdoray5eeb7642016-06-22 16:11:282380 base::RunLoop().RunUntilIdle();
[email protected]64770b7d2011-11-16 04:30:412381
[email protected]e7b1c6d2c2012-05-05 00:54:032382 // Both sockets should now be idle.
[email protected]64770b7d2011-11-16 04:30:412383 ASSERT_EQ(2, pool_->IdleSocketCount());
2384
2385 // Request a new socket. This should cleanup the unused and timed out ones.
2386 // A new socket will be created rather than reusing the idle one.
vishal.b62985ca92015-04-17 08:45:512387 BoundTestNetLog log;
[email protected]6ecf2b92011-12-15 01:14:522388 TestCompletionCallback callback3;
Paul Jensen8d6f87ec2018-01-13 00:46:542389 rv = handle.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152390 ClientSocketPool::RespectLimits::ENABLED,
2391 callback3.callback(), pool_.get(), log.bound());
robpercival214763f2016-07-01 23:27:012392 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
2393 ASSERT_THAT(callback3.WaitForResult(), IsOk());
[email protected]64770b7d2011-11-16 04:30:412394 EXPECT_FALSE(handle.is_reused());
2395
[email protected]e7b1c6d2c2012-05-05 00:54:032396 // Make sure the idle socket is closed.
[email protected]64770b7d2011-11-16 04:30:412397 ASSERT_TRUE(pool_->HasGroup("a"));
2398 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2399 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2400
mmenke43758e62015-05-04 21:09:462401 TestNetLogEntry::List entries;
[email protected]64770b7d2011-11-16 04:30:412402 log.GetEntries(&entries);
2403 EXPECT_FALSE(LogContainsEntryWithType(
mikecirone8b85c432016-09-08 19:11:002404 entries, 1, NetLogEventType::SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]64770b7d2011-11-16 04:30:412405}
2406
[email protected]2041cf342010-02-19 03:15:592407// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:162408// because of multiple releasing disconnected sockets.
2409TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
2410 CreatePoolWithIdleTimeouts(
2411 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2412 base::TimeDelta(), // Time out unused sockets immediately.
2413 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2414
2415 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2416
2417 // Startup 4 connect jobs. Two of them will be pending.
2418
[email protected]2431756e2010-09-29 20:26:132419 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522420 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:542421 int rv = handle.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152422 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202423 callback.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012424 EXPECT_THAT(rv, IsOk());
[email protected]4f2abec2010-02-03 18:10:162425
[email protected]2431756e2010-09-29 20:26:132426 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522427 TestCompletionCallback callback2;
Paul Jensen8d6f87ec2018-01-13 00:46:542428 rv = handle2.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152429 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202430 callback2.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012431 EXPECT_THAT(rv, IsOk());
[email protected]4f2abec2010-02-03 18:10:162432
[email protected]2431756e2010-09-29 20:26:132433 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:522434 TestCompletionCallback callback3;
Paul Jensen8d6f87ec2018-01-13 00:46:542435 rv = handle3.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152436 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202437 callback3.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012438 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4f2abec2010-02-03 18:10:162439
[email protected]2431756e2010-09-29 20:26:132440 ClientSocketHandle handle4;
[email protected]6ecf2b92011-12-15 01:14:522441 TestCompletionCallback callback4;
Paul Jensen8d6f87ec2018-01-13 00:46:542442 rv = handle4.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152443 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202444 callback4.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012445 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4f2abec2010-02-03 18:10:162446
2447 // Release two disconnected sockets.
2448
[email protected]2431756e2010-09-29 20:26:132449 handle.socket()->Disconnect();
2450 handle.Reset();
2451 handle2.socket()->Disconnect();
2452 handle2.Reset();
[email protected]4f2abec2010-02-03 18:10:162453
robpercival214763f2016-07-01 23:27:012454 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132455 EXPECT_FALSE(handle3.is_reused());
robpercival214763f2016-07-01 23:27:012456 EXPECT_THAT(callback4.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132457 EXPECT_FALSE(handle4.is_reused());
[email protected]4f2abec2010-02-03 18:10:162458}
2459
[email protected]d7027bb2010-05-10 18:58:542460// Regression test for http://crbug.com/42267.
2461// When DoReleaseSocket() is processed for one socket, it is blocked because the
2462// other stalled groups all have releasing sockets, so no progress can be made.
2463TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
2464 CreatePoolWithIdleTimeouts(
2465 4 /* socket limit */, 4 /* socket limit per group */,
2466 base::TimeDelta(), // Time out unused sockets immediately.
2467 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2468
2469 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2470
2471 // Max out the socket limit with 2 per group.
2472
[email protected]2431756e2010-09-29 20:26:132473 ClientSocketHandle handle_a[4];
[email protected]6ecf2b92011-12-15 01:14:522474 TestCompletionCallback callback_a[4];
[email protected]2431756e2010-09-29 20:26:132475 ClientSocketHandle handle_b[4];
[email protected]6ecf2b92011-12-15 01:14:522476 TestCompletionCallback callback_b[4];
[email protected]d7027bb2010-05-10 18:58:542477
2478 for (int i = 0; i < 2; ++i) {
Paul Jensen8d6f87ec2018-01-13 00:46:542479 EXPECT_EQ(OK, handle_a[i].Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152480 ClientSocketPool::RespectLimits::ENABLED,
2481 callback_a[i].callback(), pool_.get(),
tfarina428341112016-09-22 13:38:202482 NetLogWithSource()));
Paul Jensen8d6f87ec2018-01-13 00:46:542483 EXPECT_EQ(OK, handle_b[i].Init("b", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152484 ClientSocketPool::RespectLimits::ENABLED,
2485 callback_b[i].callback(), pool_.get(),
tfarina428341112016-09-22 13:38:202486 NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:542487 }
[email protected]b89f7e42010-05-20 20:37:002488
[email protected]d7027bb2010-05-10 18:58:542489 // Make 4 pending requests, 2 per group.
2490
2491 for (int i = 2; i < 4; ++i) {
tfarina428341112016-09-22 13:38:202492 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542493 handle_a[i].Init("a", params_, LOWEST, SocketTag(),
tfarina428341112016-09-22 13:38:202494 ClientSocketPool::RespectLimits::ENABLED,
2495 callback_a[i].callback(), pool_.get(),
2496 NetLogWithSource()));
2497 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542498 handle_b[i].Init("b", params_, LOWEST, SocketTag(),
tfarina428341112016-09-22 13:38:202499 ClientSocketPool::RespectLimits::ENABLED,
2500 callback_b[i].callback(), pool_.get(),
2501 NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:542502 }
2503
2504 // Release b's socket first. The order is important, because in
2505 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2506 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2507 // first, which has a releasing socket, so it refuses to start up another
2508 // ConnectJob. So, we used to infinite loop on this.
[email protected]2431756e2010-09-29 20:26:132509 handle_b[0].socket()->Disconnect();
2510 handle_b[0].Reset();
2511 handle_a[0].socket()->Disconnect();
2512 handle_a[0].Reset();
[email protected]d7027bb2010-05-10 18:58:542513
2514 // Used to get stuck here.
fdoray5eeb7642016-06-22 16:11:282515 base::RunLoop().RunUntilIdle();
[email protected]d7027bb2010-05-10 18:58:542516
[email protected]2431756e2010-09-29 20:26:132517 handle_b[1].socket()->Disconnect();
2518 handle_b[1].Reset();
2519 handle_a[1].socket()->Disconnect();
2520 handle_a[1].Reset();
[email protected]d7027bb2010-05-10 18:58:542521
2522 for (int i = 2; i < 4; ++i) {
robpercival214763f2016-07-01 23:27:012523 EXPECT_THAT(callback_b[i].WaitForResult(), IsOk());
2524 EXPECT_THAT(callback_a[i].WaitForResult(), IsOk());
[email protected]d7027bb2010-05-10 18:58:542525 }
2526}
2527
[email protected]fd4fe0b2010-02-08 23:02:152528TEST_F(ClientSocketPoolBaseTest,
2529 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2530 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2531
2532 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2533
robpercival214763f2016-07-01 23:27:012534 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
2535 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
2536 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
2537 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]fd4fe0b2010-02-08 23:02:152538
robpercival214763f2016-07-01 23:27:012539 EXPECT_THAT((*requests())[0]->WaitForResult(), IsOk());
2540 EXPECT_THAT((*requests())[1]->WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132541 EXPECT_EQ(2u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152542
2543 // Releases one connection.
[email protected]2431756e2010-09-29 20:26:132544 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
robpercival214763f2016-07-01 23:27:012545 EXPECT_THAT((*requests())[2]->WaitForResult(), IsOk());
[email protected]fd4fe0b2010-02-08 23:02:152546
[email protected]2431756e2010-09-29 20:26:132547 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
robpercival214763f2016-07-01 23:27:012548 EXPECT_THAT((*requests())[3]->WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132549 EXPECT_EQ(4u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152550
2551 EXPECT_EQ(1, GetOrderOfRequest(1));
2552 EXPECT_EQ(2, GetOrderOfRequest(2));
2553 EXPECT_EQ(3, GetOrderOfRequest(3));
2554 EXPECT_EQ(4, GetOrderOfRequest(4));
2555
2556 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:132557 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
[email protected]fd4fe0b2010-02-08 23:02:152558}
2559
[email protected]6ecf2b92011-12-15 01:14:522560class TestReleasingSocketRequest : public TestCompletionCallbackBase {
[email protected]4f1e4982010-03-02 18:31:042561 public:
[email protected]2431756e2010-09-29 20:26:132562 TestReleasingSocketRequest(TestClientSocketPool* pool,
2563 int expected_result,
[email protected]e60e47a2010-07-14 03:37:182564 bool reset_releasing_handle)
2565 : pool_(pool),
2566 expected_result_(expected_result),
[email protected]6ecf2b92011-12-15 01:14:522567 reset_releasing_handle_(reset_releasing_handle),
[email protected]aa249b52013-04-30 01:04:322568 callback_(base::Bind(&TestReleasingSocketRequest::OnComplete,
2569 base::Unretained(this))) {
[email protected]6ecf2b92011-12-15 01:14:522570 }
2571
Chris Watkins7a41d3552017-12-01 02:13:272572 ~TestReleasingSocketRequest() override = default;
[email protected]4f1e4982010-03-02 18:31:042573
2574 ClientSocketHandle* handle() { return &handle_; }
2575
[email protected]6ecf2b92011-12-15 01:14:522576 const CompletionCallback& callback() const { return callback_; }
[email protected]4f1e4982010-03-02 18:31:042577
2578 private:
[email protected]6ecf2b92011-12-15 01:14:522579 void OnComplete(int result) {
2580 SetResult(result);
2581 if (reset_releasing_handle_)
2582 handle_.Reset();
2583
mmenked3641e12016-01-28 16:06:152584 scoped_refptr<TestSocketParams> con_params(new TestSocketParams());
[email protected]6ecf2b92011-12-15 01:14:522585 EXPECT_EQ(expected_result_,
Paul Jensen8d6f87ec2018-01-13 00:46:542586 handle2_.Init("a", con_params, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152587 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202588 callback2_.callback(), pool_, NetLogWithSource()));
[email protected]6ecf2b92011-12-15 01:14:522589 }
2590
[email protected]2431756e2010-09-29 20:26:132591 TestClientSocketPool* const pool_;
[email protected]e60e47a2010-07-14 03:37:182592 int expected_result_;
2593 bool reset_releasing_handle_;
[email protected]4f1e4982010-03-02 18:31:042594 ClientSocketHandle handle_;
2595 ClientSocketHandle handle2_;
[email protected]6ecf2b92011-12-15 01:14:522596 CompletionCallback callback_;
2597 TestCompletionCallback callback2_;
[email protected]4f1e4982010-03-02 18:31:042598};
2599
[email protected]e60e47a2010-07-14 03:37:182600
2601TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2602 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2603
robpercival214763f2016-07-01 23:27:012604 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
2605 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
2606 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
[email protected]e60e47a2010-07-14 03:37:182607
[email protected]2431756e2010-09-29 20:26:132608 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]e60e47a2010-07-14 03:37:182609 client_socket_factory_.allocation_count());
2610
2611 connect_job_factory_->set_job_type(
2612 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2613 TestReleasingSocketRequest req(pool_.get(), OK, false);
tfarina428341112016-09-22 13:38:202614 EXPECT_EQ(
2615 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542616 req.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:202617 ClientSocketPool::RespectLimits::ENABLED,
2618 req.callback(), pool_.get(), NetLogWithSource()));
[email protected]e60e47a2010-07-14 03:37:182619 // The next job should complete synchronously
2620 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2621
robpercival214763f2016-07-01 23:27:012622 EXPECT_THAT(req.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:182623 EXPECT_FALSE(req.handle()->is_initialized());
2624 EXPECT_FALSE(req.handle()->socket());
2625 EXPECT_TRUE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:432626 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182627}
2628
[email protected]b6501d3d2010-06-03 23:53:342629// http://crbug.com/44724 regression test.
2630// We start releasing the pool when we flush on network change. When that
2631// happens, the only active references are in the ClientSocketHandles. When a
2632// ConnectJob completes and calls back into the last ClientSocketHandle, that
2633// callback can release the last reference and delete the pool. After the
2634// callback finishes, we go back to the stack frame within the now-deleted pool.
2635// Executing any code that refers to members of the now-deleted pool can cause
2636// crashes.
2637TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2638 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2639 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2640
2641 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522642 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:152643 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542644 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152645 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202646 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]b6501d3d2010-06-03 23:53:342647
[email protected]7af985a2012-12-14 22:40:422648 pool_->FlushWithError(ERR_NETWORK_CHANGED);
[email protected]b6501d3d2010-06-03 23:53:342649
2650 // We'll call back into this now.
2651 callback.WaitForResult();
2652}
2653
[email protected]a7e38572010-06-07 18:22:242654TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2655 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2656 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2657
2658 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522659 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:152660 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542661 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152662 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202663 callback.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:012664 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]a7e38572010-06-07 18:22:242665 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2666
[email protected]7af985a2012-12-14 22:40:422667 pool_->FlushWithError(ERR_NETWORK_CHANGED);
[email protected]a7e38572010-06-07 18:22:242668
2669 handle.Reset();
fdoray5eeb7642016-06-22 16:11:282670 base::RunLoop().RunUntilIdle();
[email protected]a7e38572010-06-07 18:22:242671
mmenked3641e12016-01-28 16:06:152672 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542673 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152674 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202675 callback.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:012676 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]a7e38572010-06-07 18:22:242677 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2678}
2679
[email protected]6ecf2b92011-12-15 01:14:522680class ConnectWithinCallback : public TestCompletionCallbackBase {
[email protected]06f92462010-08-31 19:24:142681 public:
2682 ConnectWithinCallback(
2683 const std::string& group_name,
2684 const scoped_refptr<TestSocketParams>& params,
[email protected]2431756e2010-09-29 20:26:132685 TestClientSocketPool* pool)
[email protected]6ecf2b92011-12-15 01:14:522686 : group_name_(group_name),
2687 params_(params),
2688 pool_(pool),
[email protected]aa249b52013-04-30 01:04:322689 callback_(base::Bind(&ConnectWithinCallback::OnComplete,
2690 base::Unretained(this))) {
[email protected]06f92462010-08-31 19:24:142691 }
2692
Chris Watkins7a41d3552017-12-01 02:13:272693 ~ConnectWithinCallback() override = default;
[email protected]06f92462010-08-31 19:24:142694
2695 int WaitForNestedResult() {
2696 return nested_callback_.WaitForResult();
2697 }
2698
[email protected]6ecf2b92011-12-15 01:14:522699 const CompletionCallback& callback() const { return callback_; }
2700
[email protected]06f92462010-08-31 19:24:142701 private:
[email protected]6ecf2b92011-12-15 01:14:522702 void OnComplete(int result) {
2703 SetResult(result);
tfarina428341112016-09-22 13:38:202704 EXPECT_EQ(
2705 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542706 handle_.Init(group_name_, params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:202707 ClientSocketPool::RespectLimits::ENABLED,
2708 nested_callback_.callback(), pool_, NetLogWithSource()));
[email protected]6ecf2b92011-12-15 01:14:522709 }
2710
[email protected]06f92462010-08-31 19:24:142711 const std::string group_name_;
2712 const scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:132713 TestClientSocketPool* const pool_;
[email protected]06f92462010-08-31 19:24:142714 ClientSocketHandle handle_;
[email protected]6ecf2b92011-12-15 01:14:522715 CompletionCallback callback_;
2716 TestCompletionCallback nested_callback_;
2717
2718 DISALLOW_COPY_AND_ASSIGN(ConnectWithinCallback);
[email protected]06f92462010-08-31 19:24:142719};
2720
2721TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
2722 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2723
2724 // First job will be waiting until it gets aborted.
2725 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2726
2727 ClientSocketHandle handle;
[email protected]2431756e2010-09-29 20:26:132728 ConnectWithinCallback callback("a", params_, pool_.get());
mmenked3641e12016-01-28 16:06:152729 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542730 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152731 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202732 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]06f92462010-08-31 19:24:142733
2734 // Second job will be started during the first callback, and will
2735 // asynchronously complete with OK.
2736 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]7af985a2012-12-14 22:40:422737 pool_->FlushWithError(ERR_NETWORK_CHANGED);
robpercival214763f2016-07-01 23:27:012738 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NETWORK_CHANGED));
2739 EXPECT_THAT(callback.WaitForNestedResult(), IsOk());
[email protected]06f92462010-08-31 19:24:142740}
2741
[email protected]25eea382010-07-10 23:55:262742// Cancel a pending socket request while we're at max sockets,
2743// and verify that the backup socket firing doesn't cause a crash.
2744TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
2745 // Max 4 sockets globally, max 4 sockets per group.
2746 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
[email protected]06d94042010-08-25 01:45:222747 pool_->EnableConnectBackupJobs();
[email protected]25eea382010-07-10 23:55:262748
[email protected]4baaf9d2010-08-31 15:15:442749 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2750 // timer.
[email protected]25eea382010-07-10 23:55:262751 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2752 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522753 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:152754 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542755 handle.Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152756 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202757 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]25eea382010-07-10 23:55:262758
2759 // Start (MaxSockets - 1) connected sockets to reach max sockets.
2760 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2761 ClientSocketHandle handles[kDefaultMaxSockets];
2762 for (int i = 1; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:522763 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:542764 EXPECT_EQ(OK, handles[i].Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:202765 ClientSocketPool::RespectLimits::ENABLED,
2766 callback.callback(), pool_.get(),
2767 NetLogWithSource()));
[email protected]25eea382010-07-10 23:55:262768 }
2769
fdoray5eeb7642016-06-22 16:11:282770 base::RunLoop().RunUntilIdle();
[email protected]25eea382010-07-10 23:55:262771
2772 // Cancel the pending request.
2773 handle.Reset();
2774
2775 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]26b9973962012-01-28 00:57:002776 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2777 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]25eea382010-07-10 23:55:262778
fdoray5eeb7642016-06-22 16:11:282779 base::RunLoop().RunUntilIdle();
[email protected]25eea382010-07-10 23:55:262780 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
2781}
2782
[email protected]3f00be82010-09-27 19:50:022783TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
[email protected]4baaf9d2010-08-31 15:15:442784 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2785 pool_->EnableConnectBackupJobs();
2786
2787 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2788 // timer.
2789 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2790 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522791 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:152792 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542793 handle.Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152794 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202795 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]4baaf9d2010-08-31 15:15:442796 ASSERT_TRUE(pool_->HasGroup("bar"));
2797 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
[email protected]8159a1c2012-06-07 00:00:102798 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("bar"));
[email protected]4baaf9d2010-08-31 15:15:442799
2800 // Cancel the socket request. This should cancel the backup timer. Wait for
2801 // the backup time to see if it indeed got canceled.
2802 handle.Reset();
2803 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]26b9973962012-01-28 00:57:002804 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2805 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
fdoray5eeb7642016-06-22 16:11:282806 base::RunLoop().RunUntilIdle();
[email protected]4baaf9d2010-08-31 15:15:442807 ASSERT_TRUE(pool_->HasGroup("bar"));
2808 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2809}
2810
[email protected]3f00be82010-09-27 19:50:022811TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
2812 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2813 pool_->EnableConnectBackupJobs();
2814
2815 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2816 // timer.
2817 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2818 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522819 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:152820 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542821 handle.Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152822 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202823 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]3f00be82010-09-27 19:50:022824 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2825 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522826 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:202827 EXPECT_EQ(
2828 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542829 handle2.Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:202830 ClientSocketPool::RespectLimits::ENABLED,
2831 callback2.callback(), pool_.get(), NetLogWithSource()));
[email protected]3f00be82010-09-27 19:50:022832 ASSERT_TRUE(pool_->HasGroup("bar"));
2833 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("bar"));
2834
2835 // Cancel request 1 and then complete request 2. With the requests finished,
2836 // the backup timer should be cancelled.
2837 handle.Reset();
robpercival214763f2016-07-01 23:27:012838 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]3f00be82010-09-27 19:50:022839 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]26b9973962012-01-28 00:57:002840 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2841 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
fdoray5eeb7642016-06-22 16:11:282842 base::RunLoop().RunUntilIdle();
[email protected]3f00be82010-09-27 19:50:022843}
2844
[email protected]eb5a99382010-07-11 03:18:262845// Test delayed socket binding for the case where we have two connects,
2846// and while one is waiting on a connect, the other frees up.
2847// The socket waiting on a connect should switch immediately to the freed
2848// up socket.
2849TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
2850 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2851 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2852
2853 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522854 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132855 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542856 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152857 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202858 callback.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:012859 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:262860
2861 // No idle sockets, no pending jobs.
2862 EXPECT_EQ(0, pool_->IdleSocketCount());
2863 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2864
2865 // Create a second socket to the same host, but this one will wait.
2866 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2867 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132868 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542869 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152870 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202871 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:262872 // No idle sockets, and one connecting job.
2873 EXPECT_EQ(0, pool_->IdleSocketCount());
2874 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2875
2876 // Return the first handle to the pool. This will initiate the delayed
2877 // binding.
2878 handle1.Reset();
2879
fdoray5eeb7642016-06-22 16:11:282880 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262881
2882 // Still no idle sockets, still one pending connect job.
2883 EXPECT_EQ(0, pool_->IdleSocketCount());
2884 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2885
2886 // The second socket connected, even though it was a Waiting Job.
robpercival214763f2016-07-01 23:27:012887 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:262888
2889 // And we can see there is still one job waiting.
2890 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2891
2892 // Finally, signal the waiting Connect.
2893 client_socket_factory_.SignalJobs();
2894 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2895
fdoray5eeb7642016-06-22 16:11:282896 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262897}
2898
2899// Test delayed socket binding when a group is at capacity and one
2900// of the group's sockets frees up.
2901TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
2902 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2903 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2904
2905 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522906 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132907 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542908 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152909 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202910 callback.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:012911 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:262912
2913 // No idle sockets, no pending jobs.
2914 EXPECT_EQ(0, pool_->IdleSocketCount());
2915 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2916
2917 // Create a second socket to the same host, but this one will wait.
2918 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2919 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132920 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542921 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152922 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202923 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:262924 // No idle sockets, and one connecting job.
2925 EXPECT_EQ(0, pool_->IdleSocketCount());
2926 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2927
2928 // Return the first handle to the pool. This will initiate the delayed
2929 // binding.
2930 handle1.Reset();
2931
fdoray5eeb7642016-06-22 16:11:282932 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262933
2934 // Still no idle sockets, still one pending connect job.
2935 EXPECT_EQ(0, pool_->IdleSocketCount());
2936 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2937
2938 // The second socket connected, even though it was a Waiting Job.
robpercival214763f2016-07-01 23:27:012939 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:262940
2941 // And we can see there is still one job waiting.
2942 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2943
2944 // Finally, signal the waiting Connect.
2945 client_socket_factory_.SignalJobs();
2946 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2947
fdoray5eeb7642016-06-22 16:11:282948 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262949}
2950
2951// Test out the case where we have one socket connected, one
2952// connecting, when the first socket finishes and goes idle.
[email protected]2abfe90a2010-08-25 17:49:512953// Although the second connection is pending, the second request
[email protected]eb5a99382010-07-11 03:18:262954// should complete, by taking the first socket's idle socket.
2955TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
2956 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2957 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2958
2959 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522960 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132961 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542962 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152963 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202964 callback.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:012965 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:262966
2967 // No idle sockets, no pending jobs.
2968 EXPECT_EQ(0, pool_->IdleSocketCount());
2969 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2970
2971 // Create a second socket to the same host, but this one will wait.
2972 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2973 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132974 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542975 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152976 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202977 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:262978 // No idle sockets, and one connecting job.
2979 EXPECT_EQ(0, pool_->IdleSocketCount());
2980 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2981
2982 // Return the first handle to the pool. This will initiate the delayed
2983 // binding.
2984 handle1.Reset();
2985
fdoray5eeb7642016-06-22 16:11:282986 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262987
2988 // Still no idle sockets, still one pending connect job.
2989 EXPECT_EQ(0, pool_->IdleSocketCount());
2990 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2991
2992 // The second socket connected, even though it was a Waiting Job.
robpercival214763f2016-07-01 23:27:012993 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:262994
2995 // And we can see there is still one job waiting.
2996 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2997
2998 // Finally, signal the waiting Connect.
2999 client_socket_factory_.SignalJobs();
3000 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3001
fdoray5eeb7642016-06-22 16:11:283002 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263003}
3004
[email protected]2abfe90a2010-08-25 17:49:513005// Cover the case where on an available socket slot, we have one pending
3006// request that completes synchronously, thereby making the Group empty.
3007TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
3008 const int kUnlimitedSockets = 100;
3009 const int kOneSocketPerGroup = 1;
3010 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
3011
3012 // Make the first request asynchronous fail.
3013 // This will free up a socket slot later.
3014 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
3015
3016 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523017 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203018 EXPECT_EQ(
3019 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543020 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203021 ClientSocketPool::RespectLimits::ENABLED,
3022 callback1.callback(), pool_.get(), NetLogWithSource()));
[email protected]2abfe90a2010-08-25 17:49:513023 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3024
3025 // Make the second request synchronously fail. This should make the Group
3026 // empty.
3027 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3028 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523029 TestCompletionCallback callback2;
[email protected]2abfe90a2010-08-25 17:49:513030 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
3031 // when created.
tfarina428341112016-09-22 13:38:203032 EXPECT_EQ(
3033 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543034 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203035 ClientSocketPool::RespectLimits::ENABLED,
3036 callback2.callback(), pool_.get(), NetLogWithSource()));
[email protected]2abfe90a2010-08-25 17:49:513037
3038 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3039
robpercival214763f2016-07-01 23:27:013040 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
3041 EXPECT_THAT(callback2.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]2abfe90a2010-08-25 17:49:513042 EXPECT_FALSE(pool_->HasGroup("a"));
3043}
3044
[email protected]e1b54dc2010-10-06 21:27:223045TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
3046 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3047
3048 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3049
3050 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523051 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203052 EXPECT_EQ(
3053 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543054 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203055 ClientSocketPool::RespectLimits::ENABLED,
3056 callback1.callback(), pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223057
3058 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523059 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203060 EXPECT_EQ(
3061 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543062 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203063 ClientSocketPool::RespectLimits::ENABLED,
3064 callback2.callback(), pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223065 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:523066 TestCompletionCallback callback3;
tfarina428341112016-09-22 13:38:203067 EXPECT_EQ(
3068 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543069 handle3.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203070 ClientSocketPool::RespectLimits::ENABLED,
3071 callback3.callback(), pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223072
robpercival214763f2016-07-01 23:27:013073 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3074 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3075 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]e1b54dc2010-10-06 21:27:223076
3077 // Use the socket.
Ramin Halavati0a08cc82018-02-06 07:46:383078 EXPECT_EQ(1, handle1.socket()->Write(NULL, 1, CompletionCallback(),
3079 TRAFFIC_ANNOTATION_FOR_TESTS));
3080 EXPECT_EQ(1, handle3.socket()->Write(NULL, 1, CompletionCallback(),
3081 TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]e1b54dc2010-10-06 21:27:223082
3083 handle1.Reset();
3084 handle2.Reset();
3085 handle3.Reset();
3086
tfarina428341112016-09-22 13:38:203087 EXPECT_EQ(
Paul Jensen8d6f87ec2018-01-13 00:46:543088 OK, handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203089 ClientSocketPool::RespectLimits::ENABLED,
3090 callback1.callback(), pool_.get(), NetLogWithSource()));
3091 EXPECT_EQ(
Paul Jensen8d6f87ec2018-01-13 00:46:543092 OK, handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203093 ClientSocketPool::RespectLimits::ENABLED,
3094 callback2.callback(), pool_.get(), NetLogWithSource()));
3095 EXPECT_EQ(
Paul Jensen8d6f87ec2018-01-13 00:46:543096 OK, handle3.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203097 ClientSocketPool::RespectLimits::ENABLED,
3098 callback3.callback(), pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223099
3100 EXPECT_TRUE(handle1.socket()->WasEverUsed());
3101 EXPECT_TRUE(handle2.socket()->WasEverUsed());
3102 EXPECT_FALSE(handle3.socket()->WasEverUsed());
3103}
3104
[email protected]2c2bef152010-10-13 00:55:033105TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
3106 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3107 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3108
Alexandr Ilin65ec9582017-10-02 14:50:313109 pool_->RequestSockets("a", &params_, 2, NetLogWithSource(),
3110 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033111
3112 ASSERT_TRUE(pool_->HasGroup("a"));
3113 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103114 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033115 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3116
3117 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523118 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203119 EXPECT_EQ(
3120 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543121 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203122 ClientSocketPool::RespectLimits::ENABLED,
3123 callback1.callback(), pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033124
3125 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523126 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203127 EXPECT_EQ(
3128 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543129 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203130 ClientSocketPool::RespectLimits::ENABLED,
3131 callback2.callback(), pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033132
3133 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103134 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033135 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3136
robpercival214763f2016-07-01 23:27:013137 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3138 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033139 handle1.Reset();
3140 handle2.Reset();
3141
3142 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103143 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033144 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3145}
3146
3147TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
3148 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3149 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3150
3151 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523152 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203153 EXPECT_EQ(
3154 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543155 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203156 ClientSocketPool::RespectLimits::ENABLED,
3157 callback1.callback(), pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033158
3159 ASSERT_TRUE(pool_->HasGroup("a"));
3160 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103161 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033162 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3163
Alexandr Ilin65ec9582017-10-02 14:50:313164 pool_->RequestSockets("a", &params_, 2, NetLogWithSource(),
3165 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033166
3167 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103168 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033169 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3170
3171 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523172 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203173 EXPECT_EQ(
3174 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543175 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203176 ClientSocketPool::RespectLimits::ENABLED,
3177 callback2.callback(), pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033178
3179 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103180 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033181 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3182
robpercival214763f2016-07-01 23:27:013183 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3184 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033185 handle1.Reset();
3186 handle2.Reset();
3187
3188 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103189 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033190 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3191}
3192
3193TEST_F(ClientSocketPoolBaseTest,
3194 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
3195 CreatePool(4, 4);
3196 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3197
3198 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523199 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203200 EXPECT_EQ(
3201 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543202 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203203 ClientSocketPool::RespectLimits::ENABLED,
3204 callback1.callback(), pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033205
3206 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523207 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203208 EXPECT_EQ(
3209 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543210 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203211 ClientSocketPool::RespectLimits::ENABLED,
3212 callback2.callback(), pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033213
3214 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:523215 TestCompletionCallback callback3;
tfarina428341112016-09-22 13:38:203216 EXPECT_EQ(
3217 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543218 handle3.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203219 ClientSocketPool::RespectLimits::ENABLED,
3220 callback3.callback(), pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033221
3222 ASSERT_TRUE(pool_->HasGroup("a"));
3223 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103224 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033225 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3226
Alexandr Ilin65ec9582017-10-02 14:50:313227 pool_->RequestSockets("a", &params_, 2, NetLogWithSource(),
3228 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033229
3230 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103231 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033232 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3233
robpercival214763f2016-07-01 23:27:013234 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3235 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3236 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033237 handle1.Reset();
3238 handle2.Reset();
3239 handle3.Reset();
3240
3241 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103242 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033243 EXPECT_EQ(3, pool_->IdleSocketCountInGroup("a"));
3244}
3245
3246TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
3247 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3248 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3249
3250 ASSERT_FALSE(pool_->HasGroup("a"));
3251
Alexandr Ilin65ec9582017-10-02 14:50:313252 pool_->RequestSockets("a", &params_, kDefaultMaxSockets, NetLogWithSource(),
3253 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033254
3255 ASSERT_TRUE(pool_->HasGroup("a"));
3256 EXPECT_EQ(kDefaultMaxSockets, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103257 EXPECT_EQ(kDefaultMaxSockets, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033258
3259 ASSERT_FALSE(pool_->HasGroup("b"));
3260
Alexandr Ilin65ec9582017-10-02 14:50:313261 pool_->RequestSockets("b", &params_, kDefaultMaxSockets, NetLogWithSource(),
3262 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033263
3264 ASSERT_FALSE(pool_->HasGroup("b"));
3265}
3266
3267TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
3268 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3269 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3270
3271 ASSERT_FALSE(pool_->HasGroup("a"));
3272
3273 pool_->RequestSockets("a", &params_, kDefaultMaxSockets - 1,
Alexandr Ilin65ec9582017-10-02 14:50:313274 NetLogWithSource(), HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033275
3276 ASSERT_TRUE(pool_->HasGroup("a"));
3277 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103278 EXPECT_EQ(kDefaultMaxSockets - 1,
3279 pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]51fdc7c2012-04-10 19:19:483280 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033281
3282 ASSERT_FALSE(pool_->HasGroup("b"));
3283
Alexandr Ilin65ec9582017-10-02 14:50:313284 pool_->RequestSockets("b", &params_, kDefaultMaxSockets, NetLogWithSource(),
3285 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033286
3287 ASSERT_TRUE(pool_->HasGroup("b"));
3288 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("b"));
[email protected]51fdc7c2012-04-10 19:19:483289 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033290}
3291
3292TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
3293 CreatePool(4, 4);
3294 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3295
3296 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523297 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203298 EXPECT_EQ(
3299 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543300 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203301 ClientSocketPool::RespectLimits::ENABLED,
3302 callback1.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013303 ASSERT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033304 handle1.Reset();
3305
3306 ASSERT_TRUE(pool_->HasGroup("a"));
3307 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103308 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033309 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3310
Alexandr Ilin65ec9582017-10-02 14:50:313311 pool_->RequestSockets("a", &params_, 2, NetLogWithSource(),
3312 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033313
3314 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103315 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033316 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3317}
3318
3319TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
3320 CreatePool(4, 4);
3321 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3322
3323 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523324 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203325 EXPECT_EQ(
3326 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543327 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203328 ClientSocketPool::RespectLimits::ENABLED,
3329 callback1.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013330 ASSERT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033331
3332 ASSERT_TRUE(pool_->HasGroup("a"));
3333 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103334 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033335 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3336 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3337
Alexandr Ilin65ec9582017-10-02 14:50:313338 pool_->RequestSockets("a", &params_, 2, NetLogWithSource(),
3339 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033340
3341 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103342 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033343 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3344 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3345}
3346
3347TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
3348 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3349 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3350
3351 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
Alexandr Ilin65ec9582017-10-02 14:50:313352 NetLogWithSource(), HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033353
3354 ASSERT_TRUE(pool_->HasGroup("a"));
3355 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103356 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033357 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("a"));
3358
3359 pool_->RequestSockets("b", &params_, kDefaultMaxSocketsPerGroup,
Alexandr Ilin65ec9582017-10-02 14:50:313360 NetLogWithSource(), HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033361
3362 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103363 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]2c2bef152010-10-13 00:55:033364 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("b"));
3365}
3366
[email protected]3c819f522010-12-02 02:03:123367TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
3368 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3369 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3370
3371 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
Alexandr Ilin65ec9582017-10-02 14:50:313372 NetLogWithSource(), HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]3c819f522010-12-02 02:03:123373
3374 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]fd2e53e2011-01-14 20:40:523375
3376 connect_job_factory_->set_job_type(
3377 TestConnectJob::kMockAdditionalErrorStateJob);
3378 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
Alexandr Ilin65ec9582017-10-02 14:50:313379 NetLogWithSource(), HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]fd2e53e2011-01-14 20:40:523380
3381 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]3c819f522010-12-02 02:03:123382}
3383
[email protected]8159a1c2012-06-07 00:00:103384TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
[email protected]2c2bef152010-10-13 00:55:033385 CreatePool(4, 4);
3386 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3387
Alexandr Ilin65ec9582017-10-02 14:50:313388 pool_->RequestSockets("a", &params_, 2, NetLogWithSource(),
3389 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033390
3391 ASSERT_TRUE(pool_->HasGroup("a"));
3392 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103393 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033394 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3395
Alexandr Ilin65ec9582017-10-02 14:50:313396 pool_->RequestSockets("a", &params_, 2, NetLogWithSource(),
3397 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033398 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103399 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033400 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3401
3402 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523403 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203404 EXPECT_EQ(
3405 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543406 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203407 ClientSocketPool::RespectLimits::ENABLED,
3408 callback1.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013409 ASSERT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033410
3411 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523412 TestCompletionCallback callback2;
Paul Jensen8d6f87ec2018-01-13 00:46:543413 int rv = handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:153414 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:203415 callback2.callback(), pool_.get(), NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033416 if (rv != OK) {
robpercival214763f2016-07-01 23:27:013417 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3418 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033419 }
3420
[email protected]8159a1c2012-06-07 00:00:103421 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3422 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3423 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("a"));
3424 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3425
[email protected]2c2bef152010-10-13 00:55:033426 handle1.Reset();
3427 handle2.Reset();
3428
[email protected]8159a1c2012-06-07 00:00:103429 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3430 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033431 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3432
Alexandr Ilin65ec9582017-10-02 14:50:313433 pool_->RequestSockets("a", &params_, 2, NetLogWithSource(),
3434 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033435 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103436 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033437 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3438}
3439
3440TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
3441 CreatePool(4, 4);
3442 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3443
Alexandr Ilin65ec9582017-10-02 14:50:313444 pool_->RequestSockets("a", &params_, 1, NetLogWithSource(),
3445 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033446
3447 ASSERT_TRUE(pool_->HasGroup("a"));
3448 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103449 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033450 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3451
Alexandr Ilin65ec9582017-10-02 14:50:313452 pool_->RequestSockets("a", &params_, 2, NetLogWithSource(),
3453 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033454 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103455 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033456 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3457
Alexandr Ilin65ec9582017-10-02 14:50:313458 pool_->RequestSockets("a", &params_, 3, NetLogWithSource(),
3459 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033460 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103461 EXPECT_EQ(3, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033462 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3463
Alexandr Ilin65ec9582017-10-02 14:50:313464 pool_->RequestSockets("a", &params_, 1, NetLogWithSource(),
3465 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033466 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103467 EXPECT_EQ(3, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033468 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3469}
3470
3471TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
3472 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3473 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3474
Alexandr Ilin65ec9582017-10-02 14:50:313475 pool_->RequestSockets("a", &params_, 1, NetLogWithSource(),
3476 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033477
3478 ASSERT_TRUE(pool_->HasGroup("a"));
3479 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103480 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033481 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3482
3483 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523484 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203485 EXPECT_EQ(
3486 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543487 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203488 ClientSocketPool::RespectLimits::ENABLED,
3489 callback1.callback(), pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033490
3491 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103492 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033493 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3494
robpercival214763f2016-07-01 23:27:013495 ASSERT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033496
[email protected]0dc88b32014-03-26 20:12:283497 // Make sure if a preconnected socket is not fully connected when a request
[email protected]034df0f32013-01-07 23:17:483498 // starts, it has a connect start time.
3499 TestLoadTimingInfoConnectedNotReused(handle1);
[email protected]2c2bef152010-10-13 00:55:033500 handle1.Reset();
3501
3502 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3503}
3504
[email protected]034df0f32013-01-07 23:17:483505// Checks that fully connected preconnect jobs have no connect times, and are
3506// marked as reused.
3507TEST_F(ClientSocketPoolBaseTest, ConnectedPreconnectJobsHaveNoConnectTimes) {
3508 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3509 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
Alexandr Ilin65ec9582017-10-02 14:50:313510 pool_->RequestSockets("a", &params_, 1, NetLogWithSource(),
3511 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]034df0f32013-01-07 23:17:483512
3513 ASSERT_TRUE(pool_->HasGroup("a"));
3514 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3515 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3516 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3517
3518 ClientSocketHandle handle;
3519 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:203520 EXPECT_EQ(OK,
Paul Jensen8d6f87ec2018-01-13 00:46:543521 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203522 ClientSocketPool::RespectLimits::ENABLED,
3523 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]034df0f32013-01-07 23:17:483524
3525 // Make sure the idle socket was used.
3526 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3527
3528 TestLoadTimingInfoConnectedReused(handle);
3529 handle.Reset();
3530 TestLoadTimingInfoNotConnected(handle);
3531}
3532
[email protected]dcbe168a2010-12-02 03:14:463533// http://crbug.com/64940 regression test.
3534TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
3535 const int kMaxTotalSockets = 3;
3536 const int kMaxSocketsPerGroup = 2;
3537 CreatePool(kMaxTotalSockets, kMaxSocketsPerGroup);
3538 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3539
3540 // Note that group name ordering matters here. "a" comes before "b", so
3541 // CloseOneIdleSocket() will try to close "a"'s idle socket.
3542
3543 // Set up one idle socket in "a".
3544 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523545 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203546 EXPECT_EQ(
3547 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543548 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203549 ClientSocketPool::RespectLimits::ENABLED,
3550 callback1.callback(), pool_.get(), NetLogWithSource()));
[email protected]dcbe168a2010-12-02 03:14:463551
robpercival214763f2016-07-01 23:27:013552 ASSERT_THAT(callback1.WaitForResult(), IsOk());
[email protected]dcbe168a2010-12-02 03:14:463553 handle1.Reset();
3554 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3555
3556 // Set up two active sockets in "b".
3557 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523558 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203559 EXPECT_EQ(
3560 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543561 handle1.Init("b", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203562 ClientSocketPool::RespectLimits::ENABLED,
3563 callback1.callback(), pool_.get(), NetLogWithSource()));
3564 EXPECT_EQ(
3565 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543566 handle2.Init("b", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203567 ClientSocketPool::RespectLimits::ENABLED,
3568 callback2.callback(), pool_.get(), NetLogWithSource()));
[email protected]dcbe168a2010-12-02 03:14:463569
robpercival214763f2016-07-01 23:27:013570 ASSERT_THAT(callback1.WaitForResult(), IsOk());
3571 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]dcbe168a2010-12-02 03:14:463572 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103573 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463574 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3575
3576 // Now we have 1 idle socket in "a" and 2 active sockets in "b". This means
3577 // we've maxed out on sockets, since we set |kMaxTotalSockets| to 3.
3578 // Requesting 2 preconnected sockets for "a" should fail to allocate any more
3579 // sockets for "a", and "b" should still have 2 active sockets.
3580
Alexandr Ilin65ec9582017-10-02 14:50:313581 pool_->RequestSockets("a", &params_, 2, NetLogWithSource(),
3582 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]dcbe168a2010-12-02 03:14:463583 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103584 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]dcbe168a2010-12-02 03:14:463585 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3586 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3587 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103588 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463589 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3590 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3591
3592 // Now release the 2 active sockets for "b". This will give us 1 idle socket
3593 // in "a" and 2 idle sockets in "b". Requesting 2 preconnected sockets for
3594 // "a" should result in closing 1 for "b".
3595 handle1.Reset();
3596 handle2.Reset();
3597 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("b"));
3598 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3599
Alexandr Ilin65ec9582017-10-02 14:50:313600 pool_->RequestSockets("a", &params_, 2, NetLogWithSource(),
3601 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]dcbe168a2010-12-02 03:14:463602 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103603 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]dcbe168a2010-12-02 03:14:463604 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3605 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3606 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103607 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463608 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("b"));
3609 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3610}
3611
[email protected]b7b8be42011-07-12 12:46:413612TEST_F(ClientSocketPoolBaseTest, PreconnectWithoutBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073613 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3614 pool_->EnableConnectBackupJobs();
3615
3616 // Make the ConnectJob hang until it times out, shorten the timeout.
3617 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3618 connect_job_factory_->set_timeout_duration(
3619 base::TimeDelta::FromMilliseconds(500));
Alexandr Ilin65ec9582017-10-02 14:50:313620 pool_->RequestSockets("a", &params_, 1, NetLogWithSource(),
3621 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]a9fc8fc2011-05-10 02:41:073622 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103623 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073624 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073625
[email protected]b7b8be42011-07-12 12:46:413626 // Verify the backup timer doesn't create a backup job, by making
3627 // the backup job a pending job instead of a waiting job, so it
3628 // *would* complete if it were created.
[email protected]a9fc8fc2011-05-10 02:41:073629 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
skyostil4891b25b2015-06-11 11:43:453630 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
ki.stfu375812e2015-10-09 20:23:173631 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
[email protected]2da659e2013-05-23 20:51:343632 base::TimeDelta::FromSeconds(1));
fdoray5eeb7642016-06-22 16:11:283633 base::RunLoop().Run();
[email protected]a9fc8fc2011-05-10 02:41:073634 EXPECT_FALSE(pool_->HasGroup("a"));
3635}
3636
[email protected]b7b8be42011-07-12 12:46:413637TEST_F(ClientSocketPoolBaseTest, PreconnectWithBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073638 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3639 pool_->EnableConnectBackupJobs();
3640
3641 // Make the ConnectJob hang forever.
3642 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
Alexandr Ilin65ec9582017-10-02 14:50:313643 pool_->RequestSockets("a", &params_, 1, NetLogWithSource(),
3644 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]a9fc8fc2011-05-10 02:41:073645 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103646 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073647 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
fdoray5eeb7642016-06-22 16:11:283648 base::RunLoop().RunUntilIdle();
[email protected]a9fc8fc2011-05-10 02:41:073649
3650 // Make the backup job be a pending job, so it completes normally.
3651 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3652 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:523653 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:153654 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543655 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:153656 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:203657 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]b7b8be42011-07-12 12:46:413658 // Timer has started, but the backup connect job shouldn't be created yet.
[email protected]a9fc8fc2011-05-10 02:41:073659 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103660 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073661 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3662 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
robpercival214763f2016-07-01 23:27:013663 ASSERT_THAT(callback.WaitForResult(), IsOk());
[email protected]a9fc8fc2011-05-10 02:41:073664
3665 // The hung connect job should still be there, but everything else should be
3666 // complete.
3667 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103668 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073669 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3670 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3671}
3672
[email protected]0dc88b32014-03-26 20:12:283673// Tests that a preconnect that starts out with unread data can still be used.
3674// http://crbug.com/334467
3675TEST_F(ClientSocketPoolBaseTest, PreconnectWithUnreadData) {
3676 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3677 connect_job_factory_->set_job_type(TestConnectJob::kMockUnreadDataJob);
3678
Alexandr Ilin65ec9582017-10-02 14:50:313679 pool_->RequestSockets("a", &params_, 1, NetLogWithSource(),
3680 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]0dc88b32014-03-26 20:12:283681
3682 ASSERT_TRUE(pool_->HasGroup("a"));
3683 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3684 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3685 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3686
3687 // Fail future jobs to be sure that handle receives the preconnected socket
3688 // rather than closing it and making a new one.
3689 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3690 ClientSocketHandle handle;
3691 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:203692 EXPECT_EQ(OK,
Paul Jensen8d6f87ec2018-01-13 00:46:543693 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203694 ClientSocketPool::RespectLimits::ENABLED,
3695 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]0dc88b32014-03-26 20:12:283696
3697 ASSERT_TRUE(pool_->HasGroup("a"));
3698 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3699 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3700 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3701
3702 // Drain the pending read.
3703 EXPECT_EQ(1, handle.socket()->Read(NULL, 1, CompletionCallback()));
3704
3705 TestLoadTimingInfoConnectedReused(handle);
3706 handle.Reset();
3707
3708 // The socket should be usable now that it's idle again.
3709 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3710}
3711
[email protected]043b68c82013-08-22 23:41:523712class MockLayeredPool : public HigherLayeredPool {
[email protected]58e562f2013-04-22 17:32:203713 public:
3714 MockLayeredPool(TestClientSocketPool* pool,
3715 const std::string& group_name)
3716 : pool_(pool),
[email protected]58e562f2013-04-22 17:32:203717 group_name_(group_name),
3718 can_release_connection_(true) {
[email protected]043b68c82013-08-22 23:41:523719 pool_->AddHigherLayeredPool(this);
[email protected]58e562f2013-04-22 17:32:203720 }
3721
Daniel Cheng4496d0822018-04-26 21:52:153722 ~MockLayeredPool() override { pool_->RemoveHigherLayeredPool(this); }
[email protected]58e562f2013-04-22 17:32:203723
3724 int RequestSocket(TestClientSocketPool* pool) {
mmenked3641e12016-01-28 16:06:153725 scoped_refptr<TestSocketParams> params(new TestSocketParams());
Paul Jensen8d6f87ec2018-01-13 00:46:543726 return handle_.Init(group_name_, params, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:153727 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:203728 callback_.callback(), pool, NetLogWithSource());
[email protected]58e562f2013-04-22 17:32:203729 }
3730
3731 int RequestSocketWithoutLimits(TestClientSocketPool* pool) {
mmenked3641e12016-01-28 16:06:153732 scoped_refptr<TestSocketParams> params(new TestSocketParams());
Paul Jensen8d6f87ec2018-01-13 00:46:543733 return handle_.Init(group_name_, params, MAXIMUM_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:153734 ClientSocketPool::RespectLimits::DISABLED,
tfarina428341112016-09-22 13:38:203735 callback_.callback(), pool, NetLogWithSource());
[email protected]58e562f2013-04-22 17:32:203736 }
3737
3738 bool ReleaseOneConnection() {
3739 if (!handle_.is_initialized() || !can_release_connection_) {
3740 return false;
3741 }
3742 handle_.socket()->Disconnect();
3743 handle_.Reset();
3744 return true;
3745 }
3746
3747 void set_can_release_connection(bool can_release_connection) {
3748 can_release_connection_ = can_release_connection;
3749 }
3750
3751 MOCK_METHOD0(CloseOneIdleConnection, bool());
3752
3753 private:
3754 TestClientSocketPool* const pool_;
[email protected]58e562f2013-04-22 17:32:203755 ClientSocketHandle handle_;
3756 TestCompletionCallback callback_;
3757 const std::string group_name_;
3758 bool can_release_connection_;
3759};
3760
3761TEST_F(ClientSocketPoolBaseTest, FailToCloseIdleSocketsNotHeldByLayeredPool) {
3762 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3763 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3764
3765 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
robpercival214763f2016-07-01 23:27:013766 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:203767 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3768 .WillOnce(Return(false));
[email protected]043b68c82013-08-22 23:41:523769 EXPECT_FALSE(pool_->CloseOneIdleConnectionInHigherLayeredPool());
[email protected]58e562f2013-04-22 17:32:203770}
3771
3772TEST_F(ClientSocketPoolBaseTest, ForciblyCloseIdleSocketsHeldByLayeredPool) {
3773 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3774 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3775
3776 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
robpercival214763f2016-07-01 23:27:013777 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:203778 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3779 .WillOnce(Invoke(&mock_layered_pool,
3780 &MockLayeredPool::ReleaseOneConnection));
[email protected]043b68c82013-08-22 23:41:523781 EXPECT_TRUE(pool_->CloseOneIdleConnectionInHigherLayeredPool());
[email protected]58e562f2013-04-22 17:32:203782}
3783
3784// Tests the basic case of closing an idle socket in a higher layered pool when
3785// a new request is issued and the lower layer pool is stalled.
3786TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsHeldByLayeredPoolWhenNeeded) {
3787 CreatePool(1, 1);
3788 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3789
3790 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
robpercival214763f2016-07-01 23:27:013791 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:203792 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3793 .WillOnce(Invoke(&mock_layered_pool,
3794 &MockLayeredPool::ReleaseOneConnection));
3795 ClientSocketHandle handle;
3796 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:153797 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543798 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:153799 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:203800 callback.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013801 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:203802}
3803
3804// Same as above, but the idle socket is in the same group as the stalled
3805// socket, and closes the only other request in its group when closing requests
3806// in higher layered pools. This generally shouldn't happen, but it may be
3807// possible if a higher level pool issues a request and the request is
3808// subsequently cancelled. Even if it's not possible, best not to crash.
3809TEST_F(ClientSocketPoolBaseTest,
3810 CloseIdleSocketsHeldByLayeredPoolWhenNeededSameGroup) {
3811 CreatePool(2, 2);
3812 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3813
3814 // Need a socket in another group for the pool to be stalled (If a group
3815 // has the maximum number of connections already, it's not stalled).
3816 ClientSocketHandle handle1;
3817 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203818 EXPECT_EQ(
Paul Jensen8d6f87ec2018-01-13 00:46:543819 OK, handle1.Init("group1", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203820 ClientSocketPool::RespectLimits::ENABLED,
3821 callback1.callback(), pool_.get(), NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:203822
3823 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
robpercival214763f2016-07-01 23:27:013824 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:203825 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3826 .WillOnce(Invoke(&mock_layered_pool,
3827 &MockLayeredPool::ReleaseOneConnection));
3828 ClientSocketHandle handle;
3829 TestCompletionCallback callback2;
mmenked3641e12016-01-28 16:06:153830 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543831 handle.Init("group2", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:153832 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:203833 callback2.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013834 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:203835}
3836
3837// Tests the case when an idle socket can be closed when a new request is
3838// issued, and the new request belongs to a group that was previously stalled.
3839TEST_F(ClientSocketPoolBaseTest,
3840 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded) {
3841 CreatePool(2, 2);
3842 std::list<TestConnectJob::JobType> job_types;
3843 job_types.push_back(TestConnectJob::kMockJob);
3844 job_types.push_back(TestConnectJob::kMockJob);
3845 job_types.push_back(TestConnectJob::kMockJob);
3846 job_types.push_back(TestConnectJob::kMockJob);
3847 connect_job_factory_->set_job_types(&job_types);
3848
3849 ClientSocketHandle handle1;
3850 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203851 EXPECT_EQ(
Paul Jensen8d6f87ec2018-01-13 00:46:543852 OK, handle1.Init("group1", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203853 ClientSocketPool::RespectLimits::ENABLED,
3854 callback1.callback(), pool_.get(), NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:203855
3856 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
robpercival214763f2016-07-01 23:27:013857 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:203858 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3859 .WillRepeatedly(Invoke(&mock_layered_pool,
3860 &MockLayeredPool::ReleaseOneConnection));
3861 mock_layered_pool.set_can_release_connection(false);
3862
3863 // The third request is made when the socket pool is in a stalled state.
3864 ClientSocketHandle handle3;
3865 TestCompletionCallback callback3;
tfarina428341112016-09-22 13:38:203866 EXPECT_EQ(
3867 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543868 handle3.Init("group3", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203869 ClientSocketPool::RespectLimits::ENABLED,
3870 callback3.callback(), pool_.get(), NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:203871
3872 base::RunLoop().RunUntilIdle();
3873 EXPECT_FALSE(callback3.have_result());
3874
3875 // The fourth request is made when the pool is no longer stalled. The third
3876 // request should be serviced first, since it was issued first and has the
3877 // same priority.
3878 mock_layered_pool.set_can_release_connection(true);
3879 ClientSocketHandle handle4;
3880 TestCompletionCallback callback4;
tfarina428341112016-09-22 13:38:203881 EXPECT_EQ(
3882 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543883 handle4.Init("group3", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203884 ClientSocketPool::RespectLimits::ENABLED,
3885 callback4.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013886 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:203887 EXPECT_FALSE(callback4.have_result());
3888
3889 // Closing a handle should free up another socket slot.
3890 handle1.Reset();
robpercival214763f2016-07-01 23:27:013891 EXPECT_THAT(callback4.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:203892}
3893
3894// Tests the case when an idle socket can be closed when a new request is
3895// issued, and the new request belongs to a group that was previously stalled.
3896//
3897// The two differences from the above test are that the stalled requests are not
3898// in the same group as the layered pool's request, and the the fourth request
3899// has a higher priority than the third one, so gets a socket first.
3900TEST_F(ClientSocketPoolBaseTest,
3901 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded2) {
3902 CreatePool(2, 2);
3903 std::list<TestConnectJob::JobType> job_types;
3904 job_types.push_back(TestConnectJob::kMockJob);
3905 job_types.push_back(TestConnectJob::kMockJob);
3906 job_types.push_back(TestConnectJob::kMockJob);
3907 job_types.push_back(TestConnectJob::kMockJob);
3908 connect_job_factory_->set_job_types(&job_types);
3909
3910 ClientSocketHandle handle1;
3911 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203912 EXPECT_EQ(
Paul Jensen8d6f87ec2018-01-13 00:46:543913 OK, handle1.Init("group1", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203914 ClientSocketPool::RespectLimits::ENABLED,
3915 callback1.callback(), pool_.get(), NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:203916
3917 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
robpercival214763f2016-07-01 23:27:013918 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:203919 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3920 .WillRepeatedly(Invoke(&mock_layered_pool,
3921 &MockLayeredPool::ReleaseOneConnection));
3922 mock_layered_pool.set_can_release_connection(false);
3923
3924 // The third request is made when the socket pool is in a stalled state.
3925 ClientSocketHandle handle3;
3926 TestCompletionCallback callback3;
tfarina428341112016-09-22 13:38:203927 EXPECT_EQ(
3928 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543929 handle3.Init("group3", params_, MEDIUM, SocketTag(),
tfarina428341112016-09-22 13:38:203930 ClientSocketPool::RespectLimits::ENABLED,
3931 callback3.callback(), pool_.get(), NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:203932
3933 base::RunLoop().RunUntilIdle();
3934 EXPECT_FALSE(callback3.have_result());
3935
3936 // The fourth request is made when the pool is no longer stalled. This
3937 // request has a higher priority than the third request, so is serviced first.
3938 mock_layered_pool.set_can_release_connection(true);
3939 ClientSocketHandle handle4;
3940 TestCompletionCallback callback4;
tfarina428341112016-09-22 13:38:203941 EXPECT_EQ(
3942 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543943 handle4.Init("group3", params_, HIGHEST, SocketTag(),
tfarina428341112016-09-22 13:38:203944 ClientSocketPool::RespectLimits::ENABLED,
3945 callback4.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013946 EXPECT_THAT(callback4.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:203947 EXPECT_FALSE(callback3.have_result());
3948
3949 // Closing a handle should free up another socket slot.
3950 handle1.Reset();
robpercival214763f2016-07-01 23:27:013951 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:203952}
3953
3954TEST_F(ClientSocketPoolBaseTest,
3955 CloseMultipleIdleSocketsHeldByLayeredPoolWhenNeeded) {
3956 CreatePool(1, 1);
3957 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3958
3959 MockLayeredPool mock_layered_pool1(pool_.get(), "foo");
robpercival214763f2016-07-01 23:27:013960 EXPECT_THAT(mock_layered_pool1.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:203961 EXPECT_CALL(mock_layered_pool1, CloseOneIdleConnection())
3962 .WillRepeatedly(Invoke(&mock_layered_pool1,
3963 &MockLayeredPool::ReleaseOneConnection));
3964 MockLayeredPool mock_layered_pool2(pool_.get(), "bar");
robpercival214763f2016-07-01 23:27:013965 EXPECT_THAT(mock_layered_pool2.RequestSocketWithoutLimits(pool_.get()),
3966 IsOk());
[email protected]58e562f2013-04-22 17:32:203967 EXPECT_CALL(mock_layered_pool2, CloseOneIdleConnection())
3968 .WillRepeatedly(Invoke(&mock_layered_pool2,
3969 &MockLayeredPool::ReleaseOneConnection));
3970 ClientSocketHandle handle;
3971 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:153972 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543973 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:153974 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:203975 callback.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013976 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:203977}
3978
[email protected]b021ece62013-06-11 11:06:333979// Test that when a socket pool and group are at their limits, a request
mmenked3641e12016-01-28 16:06:153980// with RespectLimits::DISABLED triggers creation of a new socket, and gets the
3981// socket instead of a request with the same priority that was issued earlier,
3982// but has RespectLimits::ENABLED.
[email protected]b021ece62013-06-11 11:06:333983TEST_F(ClientSocketPoolBaseTest, IgnoreLimits) {
[email protected]b021ece62013-06-11 11:06:333984 CreatePool(1, 1);
3985
3986 // Issue a request to reach the socket pool limit.
mmenked3641e12016-01-28 16:06:153987 EXPECT_EQ(
3988 OK, StartRequestWithIgnoreLimits(
3989 "a", MAXIMUM_PRIORITY, ClientSocketPool::RespectLimits::ENABLED));
[email protected]b021ece62013-06-11 11:06:333990 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3991
3992 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3993
mmenked3641e12016-01-28 16:06:153994 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
3995 "a", MAXIMUM_PRIORITY,
3996 ClientSocketPool::RespectLimits::ENABLED));
[email protected]b021ece62013-06-11 11:06:333997 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3998
mmenked3641e12016-01-28 16:06:153999 // Issue a request that ignores the limits, so a new ConnectJob is
4000 // created.
4001 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
4002 "a", MAXIMUM_PRIORITY,
4003 ClientSocketPool::RespectLimits::DISABLED));
[email protected]b021ece62013-06-11 11:06:334004 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4005
robpercival214763f2016-07-01 23:27:014006 EXPECT_THAT(request(2)->WaitForResult(), IsOk());
[email protected]b021ece62013-06-11 11:06:334007 EXPECT_FALSE(request(1)->have_result());
4008}
4009
[email protected]c55fabd2013-11-04 23:26:564010// Test that when a socket pool and group are at their limits, a ConnectJob
mmenked3641e12016-01-28 16:06:154011// issued for a request with RespectLimits::DISABLED is not cancelled when a
4012// request with RespectLimits::ENABLED issued to the same group is cancelled.
[email protected]c55fabd2013-11-04 23:26:564013TEST_F(ClientSocketPoolBaseTest, IgnoreLimitsCancelOtherJob) {
[email protected]c55fabd2013-11-04 23:26:564014 CreatePool(1, 1);
4015
4016 // Issue a request to reach the socket pool limit.
mmenked3641e12016-01-28 16:06:154017 EXPECT_EQ(
4018 OK, StartRequestWithIgnoreLimits(
4019 "a", MAXIMUM_PRIORITY, ClientSocketPool::RespectLimits::ENABLED));
[email protected]c55fabd2013-11-04 23:26:564020 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4021
4022 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4023
mmenked3641e12016-01-28 16:06:154024 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
4025 "a", MAXIMUM_PRIORITY,
4026 ClientSocketPool::RespectLimits::ENABLED));
[email protected]c55fabd2013-11-04 23:26:564027 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4028
mmenked3641e12016-01-28 16:06:154029 // Issue a request with RespectLimits::DISABLED, so a new ConnectJob is
4030 // created.
4031 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
4032 "a", MAXIMUM_PRIORITY,
4033 ClientSocketPool::RespectLimits::DISABLED));
[email protected]b021ece62013-06-11 11:06:334034 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4035
mmenked3641e12016-01-28 16:06:154036 // Cancel the pending request with RespectLimits::ENABLED. The ConnectJob
[email protected]b021ece62013-06-11 11:06:334037 // should not be cancelled.
4038 request(1)->handle()->Reset();
4039 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4040
robpercival214763f2016-07-01 23:27:014041 EXPECT_THAT(request(2)->WaitForResult(), IsOk());
[email protected]b021ece62013-06-11 11:06:334042 EXPECT_FALSE(request(1)->have_result());
4043}
4044
[email protected]f6d1d6eb2009-06-24 20:16:094045} // namespace
4046
4047} // namespace net