blob: 858942e1a3c3981600223d7edb6c738e15dfcb5a [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"
Alexander Timin4f9c35c2018-11-01 20:15:2019#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
Lily Chen02ef29a2018-11-30 16:31:43425 void ChangePriorityInternal(RequestPriority priority) override {}
426
[email protected]e772db3f2010-07-12 18:11:13427 int DoConnect(bool succeed, bool was_async, bool recoverable) {
428 int result = OK;
[email protected]ab838892009-06-30 18:49:05429 if (succeed) {
Bence Békybdbb0e72018-08-07 21:42:59430 socket()->Connect(CompletionOnceCallback());
[email protected]e772db3f2010-07-12 18:11:13431 } else if (recoverable) {
432 result = ERR_PROXY_AUTH_REQUESTED;
[email protected]6e713f02009-08-06 02:56:40433 } else {
[email protected]e772db3f2010-07-12 18:11:13434 result = ERR_CONNECTION_FAILED;
danakj655b66c2016-04-16 00:51:38435 SetSocket(std::unique_ptr<StreamSocket>());
[email protected]ab838892009-06-30 18:49:05436 }
[email protected]2ab05b52009-07-01 23:57:58437
438 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30439 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05440 return result;
441 }
442
[email protected]5fc08e32009-07-15 17:09:57443 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05444 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57445 MockClientSocketFactory* const client_socket_factory_;
[email protected]46451352009-09-01 14:54:21446 LoadState load_state_;
[email protected]e60e47a2010-07-14 03:37:18447 bool store_additional_error_state_;
[email protected]ab838892009-06-30 18:49:05448
[email protected]d5492c52013-11-10 20:44:39449 base::WeakPtrFactory<TestConnectJob> weak_factory_;
450
[email protected]ab838892009-06-30 18:49:05451 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
452};
453
[email protected]d80a4322009-08-14 07:07:49454class TestConnectJobFactory
455 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05456 public:
[email protected]034df0f32013-01-07 23:17:48457 TestConnectJobFactory(MockClientSocketFactory* client_socket_factory,
458 NetLog* net_log)
[email protected]ab838892009-06-30 18:49:05459 : job_type_(TestConnectJob::kMockJob),
[email protected]51fdc7c2012-04-10 19:19:48460 job_types_(NULL),
[email protected]034df0f32013-01-07 23:17:48461 client_socket_factory_(client_socket_factory),
462 net_log_(net_log) {
[email protected]b021ece62013-06-11 11:06:33463 }
[email protected]ab838892009-06-30 18:49:05464
Chris Watkins7a41d3552017-12-01 02:13:27465 ~TestConnectJobFactory() override = default;
[email protected]ab838892009-06-30 18:49:05466
467 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
468
[email protected]51fdc7c2012-04-10 19:19:48469 void set_job_types(std::list<TestConnectJob::JobType>* job_types) {
470 job_types_ = job_types;
471 CHECK(!job_types_->empty());
472 }
473
[email protected]974ebd62009-08-03 23:14:34474 void set_timeout_duration(base::TimeDelta timeout_duration) {
475 timeout_duration_ = timeout_duration;
476 }
477
[email protected]3f55aa12011-12-07 02:03:33478 // ConnectJobFactory implementation.
[email protected]83039bb2011-12-09 18:43:55479
danakj655b66c2016-04-16 00:51:38480 std::unique_ptr<ConnectJob> NewConnectJob(
[email protected]ab838892009-06-30 18:49:05481 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49482 const TestClientSocketPoolBase::Request& request,
mostynbba063d6032014-10-09 11:01:13483 ConnectJob::Delegate* delegate) const override {
[email protected]51fdc7c2012-04-10 19:19:48484 EXPECT_TRUE(!job_types_ || !job_types_->empty());
485 TestConnectJob::JobType job_type = job_type_;
486 if (job_types_ && !job_types_->empty()) {
487 job_type = job_types_->front();
488 job_types_->pop_front();
489 }
danakj655b66c2016-04-16 00:51:38490 return std::unique_ptr<ConnectJob>(
491 new TestConnectJob(job_type, group_name, request, timeout_duration_,
492 delegate, client_socket_factory_, net_log_));
[email protected]ab838892009-06-30 18:49:05493 }
494
dchengb03027d2014-10-21 12:00:20495 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26496 return timeout_duration_;
497 }
498
[email protected]ab838892009-06-30 18:49:05499 private:
500 TestConnectJob::JobType job_type_;
[email protected]51fdc7c2012-04-10 19:19:48501 std::list<TestConnectJob::JobType>* job_types_;
[email protected]974ebd62009-08-03 23:14:34502 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57503 MockClientSocketFactory* const client_socket_factory_;
[email protected]034df0f32013-01-07 23:17:48504 NetLog* net_log_;
[email protected]ab838892009-06-30 18:49:05505
506 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
507};
508
509class TestClientSocketPool : public ClientSocketPool {
510 public:
[email protected]12322e7e2013-08-15 17:49:26511 typedef TestSocketParams SocketParams;
512
[email protected]ab838892009-06-30 18:49:05513 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53514 int max_sockets,
[email protected]ab838892009-06-30 18:49:05515 int max_sockets_per_group,
[email protected]9bf28db2009-08-29 01:35:16516 base::TimeDelta unused_idle_socket_timeout,
517 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49518 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
rkaplowd90695c2015-03-25 22:12:41519 : base_(NULL,
520 max_sockets,
521 max_sockets_per_group,
522 unused_idle_socket_timeout,
523 used_idle_socket_timeout,
[email protected]66761b952010-06-25 21:30:38524 connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05525
Chris Watkins7a41d3552017-12-01 02:13:27526 ~TestClientSocketPool() override = default;
[email protected]2431756e2010-09-29 20:26:13527
dchengb03027d2014-10-21 12:00:20528 int RequestSocket(const std::string& group_name,
529 const void* params,
ttuttle859dc7a2015-04-23 19:42:29530 RequestPriority priority,
Paul Jensen8d6f87ec2018-01-13 00:46:54531 const SocketTag& socket_tag,
mmenked3641e12016-01-28 16:06:15532 RespectLimits respect_limits,
dchengb03027d2014-10-21 12:00:20533 ClientSocketHandle* handle,
Bence Béky5a8662b2018-07-03 13:04:03534 CompletionOnceCallback callback,
tfarina428341112016-09-22 13:38:20535 const NetLogWithSource& net_log) override {
[email protected]df4b4ef2010-07-12 18:25:21536 const scoped_refptr<TestSocketParams>* casted_socket_params =
537 static_cast<const scoped_refptr<TestSocketParams>*>(params);
538 return base_.RequestSocket(group_name, *casted_socket_params, priority,
Bence Béky5a8662b2018-07-03 13:04:03539 socket_tag, respect_limits, handle,
540 std::move(callback), net_log);
[email protected]ab838892009-06-30 18:49:05541 }
542
dchengb03027d2014-10-21 12:00:20543 void RequestSockets(const std::string& group_name,
544 const void* params,
545 int num_sockets,
Charlie Harrison55ce6082018-05-14 02:25:57546 const NetLogWithSource& net_log) override {
[email protected]2c2bef152010-10-13 00:55:03547 const scoped_refptr<TestSocketParams>* casted_params =
548 static_cast<const scoped_refptr<TestSocketParams>*>(params);
549
Charlie Harrison55ce6082018-05-14 02:25:57550 base_.RequestSockets(group_name, *casted_params, num_sockets, net_log);
[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
Lily Chenecebf932018-11-02 17:15:43612 int NumNeverAssignedConnectJobsInGroup(const std::string& group_name) const {
613 return base_.NumNeverAssignedConnectJobsInGroup(group_name);
614 }
615
[email protected]8159a1c2012-06-07 00:00:10616 int NumUnassignedConnectJobsInGroup(const std::string& group_name) const {
617 return base_.NumUnassignedConnectJobsInGroup(group_name);
618 }
619
[email protected]974ebd62009-08-03 23:14:34620 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49621 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34622 }
623
[email protected]2c2bef152010-10-13 00:55:03624 int NumActiveSocketsInGroup(const std::string& group_name) const {
625 return base_.NumActiveSocketsInGroup(group_name);
626 }
627
Lily Chenecebf932018-11-02 17:15:43628 bool RequestInGroupWithHandleHasJobForTesting(
629 const std::string& group_name,
630 const ClientSocketHandle* handle) const {
631 return base_.RequestInGroupWithHandleHasJobForTesting(group_name, handle);
632 }
633
[email protected]2abfe90a2010-08-25 17:49:51634 bool HasGroup(const std::string& group_name) const {
635 return base_.HasGroup(group_name);
636 }
637
[email protected]9bf28db2009-08-29 01:35:16638 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
639
[email protected]06d94042010-08-25 01:45:22640 void EnableConnectBackupJobs() { base_.EnableConnectBackupJobs(); }
[email protected]43a21b82010-06-10 21:30:54641
[email protected]043b68c82013-08-22 23:41:52642 bool CloseOneIdleConnectionInHigherLayeredPool() {
643 return base_.CloseOneIdleConnectionInHigherLayeredPool();
[email protected]51fdc7c2012-04-10 19:19:48644 }
645
[email protected]ab838892009-06-30 18:49:05646 private:
[email protected]d80a4322009-08-14 07:07:49647 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05648
649 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
650};
651
[email protected]a937a06d2009-08-19 21:19:24652} // namespace
653
[email protected]a937a06d2009-08-19 21:19:24654namespace {
655
[email protected]5fc08e32009-07-15 17:09:57656void MockClientSocketFactory::SignalJobs() {
jdoerrie22a91d8b92018-10-05 08:43:26657 for (auto it = waiting_jobs_.begin(); it != waiting_jobs_.end(); ++it) {
[email protected]5fc08e32009-07-15 17:09:57658 (*it)->Signal();
659 }
660 waiting_jobs_.clear();
661}
662
[email protected]03b7c8c2013-07-20 04:38:55663void MockClientSocketFactory::SignalJob(size_t job) {
664 ASSERT_LT(job, waiting_jobs_.size());
665 waiting_jobs_[job]->Signal();
666 waiting_jobs_.erase(waiting_jobs_.begin() + job);
667}
668
669void MockClientSocketFactory::SetJobLoadState(size_t job,
670 LoadState load_state) {
671 ASSERT_LT(job, waiting_jobs_.size());
672 waiting_jobs_[job]->set_load_state(load_state);
673}
674
[email protected]974ebd62009-08-03 23:14:34675class TestConnectJobDelegate : public ConnectJob::Delegate {
676 public:
Weza03bae02018-07-13 17:17:33677 TestConnectJobDelegate() : have_result_(false), result_(OK) {}
Chris Watkins7a41d3552017-12-01 02:13:27678 ~TestConnectJobDelegate() override = default;
[email protected]974ebd62009-08-03 23:14:34679
dchengb03027d2014-10-21 12:00:20680 void OnConnectJobComplete(int result, ConnectJob* job) override {
[email protected]974ebd62009-08-03 23:14:34681 result_ = result;
danakj655b66c2016-04-16 00:51:38682 std::unique_ptr<ConnectJob> owned_job(job);
683 std::unique_ptr<StreamSocket> socket = owned_job->PassSocket();
[email protected]9b6fee12009-09-29 18:13:07684 // socket.get() should be NULL iff result != OK
[email protected]18ccfdb2013-08-15 00:13:44685 EXPECT_EQ(socket == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34686 have_result_ = true;
Weza03bae02018-07-13 17:17:33687 if (quit_wait_on_result_)
688 std::move(quit_wait_on_result_).Run();
[email protected]974ebd62009-08-03 23:14:34689 }
690
691 int WaitForResult() {
Weza03bae02018-07-13 17:17:33692 DCHECK(!quit_wait_on_result_);
[email protected]974ebd62009-08-03 23:14:34693 while (!have_result_) {
Weza03bae02018-07-13 17:17:33694 base::RunLoop run_loop;
695 quit_wait_on_result_ = run_loop.QuitClosure();
696 run_loop.Run();
[email protected]974ebd62009-08-03 23:14:34697 }
698 have_result_ = false; // auto-reset for next callback
699 return result_;
700 }
701
702 private:
703 bool have_result_;
Weza03bae02018-07-13 17:17:33704 base::OnceClosure quit_wait_on_result_;
[email protected]974ebd62009-08-03 23:14:34705 int result_;
706};
707
Bence Béky98447b12018-05-08 03:14:01708class ClientSocketPoolBaseTest : public TestWithScopedTaskEnvironment {
[email protected]f6d1d6eb2009-06-24 20:16:09709 protected:
Alex Clarke0def2092018-12-10 12:01:45710 ClientSocketPoolBaseTest()
711 : TestWithScopedTaskEnvironment(
712 base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME),
713 params_(new TestSocketParams()) {
[email protected]636b8252011-04-08 19:56:54714 connect_backup_jobs_enabled_ =
715 internal::ClientSocketPoolBaseHelper::connect_backup_jobs_enabled();
716 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(true);
717 }
[email protected]2431756e2010-09-29 20:26:13718
dcheng67be2b1f2014-10-27 21:47:29719 ~ClientSocketPoolBaseTest() override {
[email protected]636b8252011-04-08 19:56:54720 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
721 connect_backup_jobs_enabled_);
722 }
[email protected]c9d6a1d2009-07-14 16:15:20723
[email protected]211d21722009-07-22 15:48:53724 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16725 CreatePoolWithIdleTimeouts(
726 max_sockets,
727 max_sockets_per_group,
[email protected]82b8c962011-10-12 09:17:30728 ClientSocketPool::unused_idle_socket_timeout(),
729 ClientSocketPool::used_idle_socket_timeout());
[email protected]9bf28db2009-08-29 01:35:16730 }
731
732 void CreatePoolWithIdleTimeouts(
733 int max_sockets, int max_sockets_per_group,
734 base::TimeDelta unused_idle_socket_timeout,
735 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20736 DCHECK(!pool_.get());
[email protected]034df0f32013-01-07 23:17:48737 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_,
738 &net_log_);
[email protected]2431756e2010-09-29 20:26:13739 pool_.reset(new TestClientSocketPool(max_sockets,
740 max_sockets_per_group,
[email protected]2431756e2010-09-29 20:26:13741 unused_idle_socket_timeout,
742 used_idle_socket_timeout,
743 connect_job_factory_));
[email protected]c9d6a1d2009-07-14 16:15:20744 }
[email protected]f6d1d6eb2009-06-24 20:16:09745
mmenked3641e12016-01-28 16:06:15746 int StartRequestWithIgnoreLimits(
[email protected]b021ece62013-06-11 11:06:33747 const std::string& group_name,
748 RequestPriority priority,
mmenked3641e12016-01-28 16:06:15749 ClientSocketPool::RespectLimits respect_limits) {
750 return test_base_.StartRequestUsingPool(pool_.get(), group_name, priority,
751 respect_limits, params_);
[email protected]b021ece62013-06-11 11:06:33752 }
753
754 int StartRequest(const std::string& group_name, RequestPriority priority) {
mmenked3641e12016-01-28 16:06:15755 return StartRequestWithIgnoreLimits(
756 group_name, priority, ClientSocketPool::RespectLimits::ENABLED);
[email protected]f6d1d6eb2009-06-24 20:16:09757 }
758
[email protected]2431756e2010-09-29 20:26:13759 int GetOrderOfRequest(size_t index) const {
760 return test_base_.GetOrderOfRequest(index);
[email protected]f6d1d6eb2009-06-24 20:16:09761 }
762
[email protected]2431756e2010-09-29 20:26:13763 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
764 return test_base_.ReleaseOneConnection(keep_alive);
765 }
766
767 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
768 test_base_.ReleaseAllConnections(keep_alive);
769 }
770
771 TestSocketRequest* request(int i) { return test_base_.request(i); }
772 size_t requests_size() const { return test_base_.requests_size(); }
danakj655b66c2016-04-16 00:51:38773 std::vector<std::unique_ptr<TestSocketRequest>>* requests() {
olli.raula9d66b7d2015-11-23 08:30:42774 return test_base_.requests();
775 }
rdsmith29dbad12017-02-17 02:22:18776 // Only counts the requests that get sockets asynchronously;
777 // synchronous completions are not registered by this count.
[email protected]2431756e2010-09-29 20:26:13778 size_t completion_count() const { return test_base_.completion_count(); }
779
vishal.b62985ca92015-04-17 08:45:51780 TestNetLog net_log_;
[email protected]636b8252011-04-08 19:56:54781 bool connect_backup_jobs_enabled_;
[email protected]f6d1d6eb2009-06-24 20:16:09782 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04783 TestConnectJobFactory* connect_job_factory_;
[email protected]df4b4ef2010-07-12 18:25:21784 scoped_refptr<TestSocketParams> params_;
danakj655b66c2016-04-16 00:51:38785 std::unique_ptr<TestClientSocketPool> pool_;
[email protected]2431756e2010-09-29 20:26:13786 ClientSocketPoolTest test_base_;
[email protected]f6d1d6eb2009-06-24 20:16:09787};
788
[email protected]974ebd62009-08-03 23:14:34789// Even though a timeout is specified, it doesn't time out on a synchronous
790// completion.
791TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
792 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06793 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49794 TestClientSocketPoolBase::Request request(
Bence Békybdbb0e72018-08-07 21:42:59795 &ignored, CompletionOnceCallback(), DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:15796 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:20797 internal::ClientSocketPoolBaseHelper::NORMAL, params_,
798 NetLogWithSource());
danakj655b66c2016-04-16 00:51:38799 std::unique_ptr<TestConnectJob> job(
800 new TestConnectJob(TestConnectJob::kMockJob, "a", request,
801 base::TimeDelta::FromMicroseconds(1), &delegate,
802 &client_socket_factory_, NULL));
robpercival214763f2016-07-01 23:27:01803 EXPECT_THAT(job->Connect(), IsOk());
[email protected]974ebd62009-08-03 23:14:34804}
805
806TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
807 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06808 ClientSocketHandle ignored;
vishal.b62985ca92015-04-17 08:45:51809 TestNetLog log;
[email protected]9e743cd2010-03-16 07:03:53810
[email protected]d80a4322009-08-14 07:07:49811 TestClientSocketPoolBase::Request request(
Bence Békybdbb0e72018-08-07 21:42:59812 &ignored, CompletionOnceCallback(), DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:15813 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:20814 internal::ClientSocketPoolBaseHelper::NORMAL, params_,
815 NetLogWithSource());
[email protected]974ebd62009-08-03 23:14:34816 // Deleted by TestConnectJobDelegate.
817 TestConnectJob* job =
818 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12819 "a",
[email protected]974ebd62009-08-03 23:14:34820 request,
821 base::TimeDelta::FromMicroseconds(1),
822 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30823 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17824 &log);
robpercival214763f2016-07-01 23:27:01825 ASSERT_THAT(job->Connect(), IsError(ERR_IO_PENDING));
Alex Clarke0def2092018-12-10 12:01:45826 FastForwardBy(base::TimeDelta::FromMilliseconds(1));
robpercival214763f2016-07-01 23:27:01827 EXPECT_THAT(delegate.WaitForResult(), IsError(ERR_TIMED_OUT));
[email protected]fd7b7c92009-08-20 19:38:30828
mmenke43758e62015-05-04 21:09:46829 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40830 log.GetEntries(&entries);
831
832 EXPECT_EQ(6u, entries.size());
mikecirone8b85c432016-09-08 19:11:00833 EXPECT_TRUE(LogContainsBeginEvent(entries, 0,
834 NetLogEventType::SOCKET_POOL_CONNECT_JOB));
[email protected]e9002a92010-01-29 07:10:46835 EXPECT_TRUE(LogContainsBeginEvent(
mikecirone8b85c432016-09-08 19:11:00836 entries, 1, NetLogEventType::SOCKET_POOL_CONNECT_JOB_CONNECT));
837 EXPECT_TRUE(LogContainsEvent(entries, 2,
838 NetLogEventType::CONNECT_JOB_SET_SOCKET,
839 NetLogEventPhase::NONE));
[email protected]e9002a92010-01-29 07:10:46840 EXPECT_TRUE(LogContainsEvent(
mikecirone8b85c432016-09-08 19:11:00841 entries, 3, NetLogEventType::SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
842 NetLogEventPhase::NONE));
[email protected]e9002a92010-01-29 07:10:46843 EXPECT_TRUE(LogContainsEndEvent(
mikecirone8b85c432016-09-08 19:11:00844 entries, 4, NetLogEventType::SOCKET_POOL_CONNECT_JOB_CONNECT));
845 EXPECT_TRUE(LogContainsEndEvent(entries, 5,
846 NetLogEventType::SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34847}
848
[email protected]5fc08e32009-07-15 17:09:57849TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53850 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20851
[email protected]6ecf2b92011-12-15 01:14:52852 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06853 ClientSocketHandle handle;
vishal.b62985ca92015-04-17 08:45:51854 BoundTestNetLog log;
[email protected]034df0f32013-01-07 23:17:48855 TestLoadTimingInfoNotConnected(handle);
[email protected]9e743cd2010-03-16 07:03:53856
Paul Jensen8d6f87ec2018-01-13 00:46:54857 EXPECT_EQ(OK, handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:15858 ClientSocketPool::RespectLimits::ENABLED,
859 callback.callback(), pool_.get(), log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09860 EXPECT_TRUE(handle.is_initialized());
861 EXPECT_TRUE(handle.socket());
[email protected]034df0f32013-01-07 23:17:48862 TestLoadTimingInfoConnectedNotReused(handle);
863
[email protected]f6d1d6eb2009-06-24 20:16:09864 handle.Reset();
[email protected]034df0f32013-01-07 23:17:48865 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:30866
mmenke43758e62015-05-04 21:09:46867 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40868 log.GetEntries(&entries);
869
870 EXPECT_EQ(4u, entries.size());
mikecirone8b85c432016-09-08 19:11:00871 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKET_POOL));
[email protected]9e743cd2010-03-16 07:03:53872 EXPECT_TRUE(LogContainsEvent(
mikecirone8b85c432016-09-08 19:11:00873 entries, 1, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
874 NetLogEventPhase::NONE));
875 EXPECT_TRUE(LogContainsEvent(entries, 2,
876 NetLogEventType::SOCKET_POOL_BOUND_TO_SOCKET,
877 NetLogEventPhase::NONE));
878 EXPECT_TRUE(LogContainsEndEvent(entries, 3, NetLogEventType::SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09879}
880
[email protected]ab838892009-06-30 18:49:05881TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53882 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20883
[email protected]ab838892009-06-30 18:49:05884 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
vishal.b62985ca92015-04-17 08:45:51885 BoundTestNetLog log;
[email protected]9e743cd2010-03-16 07:03:53886
[email protected]2431756e2010-09-29 20:26:13887 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:52888 TestCompletionCallback callback;
[email protected]e60e47a2010-07-14 03:37:18889 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:13890 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43891 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:45892 info.headers = new HttpResponseHeaders(std::string());
[email protected]2431756e2010-09-29 20:26:13893 handle.set_ssl_error_response_info(info);
894 EXPECT_EQ(ERR_CONNECTION_FAILED,
Paul Jensen8d6f87ec2018-01-13 00:46:54895 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:15896 ClientSocketPool::RespectLimits::ENABLED,
897 callback.callback(), pool_.get(), log.bound()));
[email protected]2431756e2010-09-29 20:26:13898 EXPECT_FALSE(handle.socket());
899 EXPECT_FALSE(handle.is_ssl_error());
900 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]034df0f32013-01-07 23:17:48901 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:30902
mmenke43758e62015-05-04 21:09:46903 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40904 log.GetEntries(&entries);
905
906 EXPECT_EQ(3u, entries.size());
mikecirone8b85c432016-09-08 19:11:00907 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:17908 EXPECT_TRUE(LogContainsEvent(
mikecirone8b85c432016-09-08 19:11:00909 entries, 1, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
910 NetLogEventPhase::NONE));
911 EXPECT_TRUE(LogContainsEndEvent(entries, 2, NetLogEventType::SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09912}
913
[email protected]211d21722009-07-22 15:48:53914TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
915 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
916
[email protected]9e743cd2010-03-16 07:03:53917 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30918
robpercival214763f2016-07-01 23:27:01919 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
920 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
921 EXPECT_THAT(StartRequest("c", DEFAULT_PRIORITY), IsOk());
922 EXPECT_THAT(StartRequest("d", DEFAULT_PRIORITY), IsOk());
[email protected]211d21722009-07-22 15:48:53923
[email protected]2431756e2010-09-29 20:26:13924 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53925 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13926 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53927
robpercival214763f2016-07-01 23:27:01928 EXPECT_THAT(StartRequest("e", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
929 EXPECT_THAT(StartRequest("f", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
930 EXPECT_THAT(StartRequest("g", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:53931
[email protected]2431756e2010-09-29 20:26:13932 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53933
[email protected]2431756e2010-09-29 20:26:13934 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53935 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13936 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53937
938 EXPECT_EQ(1, GetOrderOfRequest(1));
939 EXPECT_EQ(2, GetOrderOfRequest(2));
940 EXPECT_EQ(3, GetOrderOfRequest(3));
941 EXPECT_EQ(4, GetOrderOfRequest(4));
942 EXPECT_EQ(5, GetOrderOfRequest(5));
943 EXPECT_EQ(6, GetOrderOfRequest(6));
944 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17945
946 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13947 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53948}
949
950TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
951 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
952
[email protected]9e743cd2010-03-16 07:03:53953 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30954
[email protected]211d21722009-07-22 15:48:53955 // Reach all limits: max total sockets, and max sockets per group.
robpercival214763f2016-07-01 23:27:01956 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
957 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
958 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
959 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
[email protected]211d21722009-07-22 15:48:53960
[email protected]2431756e2010-09-29 20:26:13961 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53962 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13963 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53964
965 // Now create a new group and verify that we don't starve it.
robpercival214763f2016-07-01 23:27:01966 EXPECT_THAT(StartRequest("c", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:53967
[email protected]2431756e2010-09-29 20:26:13968 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53969
[email protected]2431756e2010-09-29 20:26:13970 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53971 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13972 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53973
974 EXPECT_EQ(1, GetOrderOfRequest(1));
975 EXPECT_EQ(2, GetOrderOfRequest(2));
976 EXPECT_EQ(3, GetOrderOfRequest(3));
977 EXPECT_EQ(4, GetOrderOfRequest(4));
978 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17979
980 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13981 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53982}
983
984TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
985 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
986
robpercival214763f2016-07-01 23:27:01987 EXPECT_THAT(StartRequest("b", LOWEST), IsOk());
988 EXPECT_THAT(StartRequest("a", MEDIUM), IsOk());
989 EXPECT_THAT(StartRequest("b", HIGHEST), IsOk());
990 EXPECT_THAT(StartRequest("a", LOWEST), IsOk());
[email protected]211d21722009-07-22 15:48:53991
[email protected]2431756e2010-09-29 20:26:13992 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53993 client_socket_factory_.allocation_count());
994
robpercival214763f2016-07-01 23:27:01995 EXPECT_THAT(StartRequest("c", LOWEST), IsError(ERR_IO_PENDING));
996 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
997 EXPECT_THAT(StartRequest("b", HIGHEST), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:53998
[email protected]2431756e2010-09-29 20:26:13999 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531000
[email protected]2431756e2010-09-29 20:26:131001 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:531002
1003 // First 4 requests don't have to wait, and finish in order.
1004 EXPECT_EQ(1, GetOrderOfRequest(1));
1005 EXPECT_EQ(2, GetOrderOfRequest(2));
1006 EXPECT_EQ(3, GetOrderOfRequest(3));
1007 EXPECT_EQ(4, GetOrderOfRequest(4));
1008
[email protected]ac790b42009-12-02 04:31:311009 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
1010 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:531011 EXPECT_EQ(7, GetOrderOfRequest(5));
1012 EXPECT_EQ(6, GetOrderOfRequest(6));
1013 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171014
1015 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131016 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]211d21722009-07-22 15:48:531017}
1018
rdsmith29dbad12017-02-17 02:22:181019// Test reprioritizing a request before completion doesn't interfere with
1020// its completion.
1021TEST_F(ClientSocketPoolBaseTest, ReprioritizeOne) {
1022 CreatePool(kDefaultMaxSockets, 1);
1023
1024 EXPECT_THAT(StartRequest("a", LOWEST), IsError(OK));
1025 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1026 EXPECT_TRUE(request(0)->handle()->socket());
1027 EXPECT_FALSE(request(1)->handle()->socket());
1028
Lily Chenecebf932018-11-02 17:15:431029 request(1)->handle()->SetPriority(HIGHEST);
rdsmith29dbad12017-02-17 02:22:181030
1031 ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE);
1032
1033 EXPECT_TRUE(request(1)->handle()->socket());
1034}
1035
1036// Reprioritize a request up past another one and make sure that changes the
1037// completion order.
1038TEST_F(ClientSocketPoolBaseTest, ReprioritizeUpReorder) {
1039 CreatePool(kDefaultMaxSockets, 1);
1040
1041 EXPECT_THAT(StartRequest("a", LOWEST), IsError(OK));
1042 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1043 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
1044 EXPECT_TRUE(request(0)->handle()->socket());
1045 EXPECT_FALSE(request(1)->handle()->socket());
1046 EXPECT_FALSE(request(2)->handle()->socket());
1047
1048 request(2)->handle()->SetPriority(HIGHEST);
1049
1050 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1051
1052 EXPECT_EQ(1, GetOrderOfRequest(1));
1053 EXPECT_EQ(3, GetOrderOfRequest(2));
1054 EXPECT_EQ(2, GetOrderOfRequest(3));
1055}
1056
1057// Reprioritize a request without changing relative priorities and check
1058// that the order doesn't change.
1059TEST_F(ClientSocketPoolBaseTest, ReprioritizeUpNoReorder) {
1060 CreatePool(kDefaultMaxSockets, 1);
1061
1062 EXPECT_THAT(StartRequest("a", LOWEST), IsError(OK));
1063 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1064 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1065 EXPECT_TRUE(request(0)->handle()->socket());
1066 EXPECT_FALSE(request(1)->handle()->socket());
1067 EXPECT_FALSE(request(2)->handle()->socket());
1068
1069 request(2)->handle()->SetPriority(MEDIUM);
1070
1071 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1072
1073 EXPECT_EQ(1, GetOrderOfRequest(1));
1074 EXPECT_EQ(2, GetOrderOfRequest(2));
1075 EXPECT_EQ(3, GetOrderOfRequest(3));
1076}
1077
1078// Reprioritize a request past down another one and make sure that changes the
1079// completion order.
1080TEST_F(ClientSocketPoolBaseTest, ReprioritizeDownReorder) {
1081 CreatePool(kDefaultMaxSockets, 1);
1082
1083 EXPECT_THAT(StartRequest("a", LOWEST), IsError(OK));
1084 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
1085 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1086 EXPECT_TRUE(request(0)->handle()->socket());
1087 EXPECT_FALSE(request(1)->handle()->socket());
1088 EXPECT_FALSE(request(2)->handle()->socket());
1089
1090 request(1)->handle()->SetPriority(LOW);
1091
1092 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1093
1094 EXPECT_EQ(1, GetOrderOfRequest(1));
1095 EXPECT_EQ(3, GetOrderOfRequest(2));
1096 EXPECT_EQ(2, GetOrderOfRequest(3));
1097}
1098
1099// Reprioritize a request to the same level as another and confirm it is
1100// put after the old request.
1101TEST_F(ClientSocketPoolBaseTest, ReprioritizeResetFIFO) {
1102 CreatePool(kDefaultMaxSockets, 1);
1103
1104 EXPECT_THAT(StartRequest("a", LOWEST), IsError(OK));
1105 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
1106 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1107 EXPECT_TRUE(request(0)->handle()->socket());
1108 EXPECT_FALSE(request(1)->handle()->socket());
1109 EXPECT_FALSE(request(2)->handle()->socket());
1110
1111 request(1)->handle()->SetPriority(MEDIUM);
1112
1113 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1114
1115 EXPECT_EQ(1, GetOrderOfRequest(1));
1116 EXPECT_EQ(3, GetOrderOfRequest(2));
1117 EXPECT_EQ(2, GetOrderOfRequest(3));
1118}
1119
[email protected]211d21722009-07-22 15:48:531120TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
1121 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1122
robpercival214763f2016-07-01 23:27:011123 EXPECT_THAT(StartRequest("a", LOWEST), IsOk());
1124 EXPECT_THAT(StartRequest("a", LOW), IsOk());
1125 EXPECT_THAT(StartRequest("b", HIGHEST), IsOk());
1126 EXPECT_THAT(StartRequest("b", MEDIUM), IsOk());
[email protected]211d21722009-07-22 15:48:531127
[email protected]2431756e2010-09-29 20:26:131128 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531129 client_socket_factory_.allocation_count());
1130
robpercival214763f2016-07-01 23:27:011131 EXPECT_THAT(StartRequest("c", MEDIUM), IsError(ERR_IO_PENDING));
1132 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1133 EXPECT_THAT(StartRequest("b", HIGHEST), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531134
[email protected]2431756e2010-09-29 20:26:131135 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531136
[email protected]2431756e2010-09-29 20:26:131137 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531138 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131139 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:531140
1141 // First 4 requests don't have to wait, and finish in order.
1142 EXPECT_EQ(1, GetOrderOfRequest(1));
1143 EXPECT_EQ(2, GetOrderOfRequest(2));
1144 EXPECT_EQ(3, GetOrderOfRequest(3));
1145 EXPECT_EQ(4, GetOrderOfRequest(4));
1146
1147 // Request ("b", 7) has the highest priority, but we can't make new socket for
1148 // group "b", because it has reached the per-group limit. Then we make
1149 // socket for ("c", 6), because it has higher priority than ("a", 4),
1150 // and we still can't make a socket for group "b".
1151 EXPECT_EQ(5, GetOrderOfRequest(5));
1152 EXPECT_EQ(6, GetOrderOfRequest(6));
1153 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171154
1155 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131156 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:531157}
1158
1159// Make sure that we count connecting sockets against the total limit.
1160TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
1161 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1162
robpercival214763f2016-07-01 23:27:011163 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1164 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
1165 EXPECT_THAT(StartRequest("c", DEFAULT_PRIORITY), IsOk());
[email protected]211d21722009-07-22 15:48:531166
1167 // Create one asynchronous request.
1168 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
robpercival214763f2016-07-01 23:27:011169 EXPECT_THAT(StartRequest("d", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531170
[email protected]6b175382009-10-13 06:47:471171 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1172 // actually become pending until 2ms after they have been created. In order
1173 // to flush all tasks, we need to wait so that we know there are no
1174 // soon-to-be-pending tasks waiting.
Alex Clarke0def2092018-12-10 12:01:451175 FastForwardBy(base::TimeDelta::FromMilliseconds(10));
[email protected]6b175382009-10-13 06:47:471176
[email protected]211d21722009-07-22 15:48:531177 // The next synchronous request should wait for its turn.
1178 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
robpercival214763f2016-07-01 23:27:011179 EXPECT_THAT(StartRequest("e", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531180
[email protected]2431756e2010-09-29 20:26:131181 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531182
[email protected]2431756e2010-09-29 20:26:131183 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531184 client_socket_factory_.allocation_count());
1185
1186 EXPECT_EQ(1, GetOrderOfRequest(1));
1187 EXPECT_EQ(2, GetOrderOfRequest(2));
1188 EXPECT_EQ(3, GetOrderOfRequest(3));
1189 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:171190 EXPECT_EQ(5, GetOrderOfRequest(5));
1191
1192 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131193 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:531194}
1195
[email protected]6427fe22010-04-16 22:27:411196TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
1197 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1198 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1199
robpercival214763f2016-07-01 23:27:011200 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1201 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1202 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1203 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
[email protected]6427fe22010-04-16 22:27:411204
1205 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1206
1207 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1208
robpercival214763f2016-07-01 23:27:011209 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1210 EXPECT_THAT(StartRequest("c", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]6427fe22010-04-16 22:27:411211
1212 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1213
[email protected]2431756e2010-09-29 20:26:131214 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411215 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131216 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411217 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131218 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1219 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411220 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
1221}
1222
[email protected]d7027bb2010-05-10 18:58:541223TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
1224 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1225 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1226
1227 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521228 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131229 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541230 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151231 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201232 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:541233
1234 ClientSocketHandle handles[4];
1235 for (size_t i = 0; i < arraysize(handles); ++i) {
[email protected]6ecf2b92011-12-15 01:14:521236 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201237 EXPECT_EQ(
1238 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541239 handles[i].Init("b", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:201240 ClientSocketPool::RespectLimits::ENABLED,
1241 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:541242 }
1243
1244 // One will be stalled, cancel all the handles now.
1245 // This should hit the OnAvailableSocketSlot() code where we previously had
1246 // stalled groups, but no longer have any.
1247 for (size_t i = 0; i < arraysize(handles); ++i)
1248 handles[i].Reset();
1249}
1250
[email protected]eb5a99382010-07-11 03:18:261251TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:541252 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1253 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1254
[email protected]eb5a99382010-07-11 03:18:261255 {
1256 ClientSocketHandle handles[kDefaultMaxSockets];
[email protected]6ecf2b92011-12-15 01:14:521257 TestCompletionCallback callbacks[kDefaultMaxSockets];
[email protected]eb5a99382010-07-11 03:18:261258 for (int i = 0; i < kDefaultMaxSockets; ++i) {
Paul Jensen8d6f87ec2018-01-13 00:46:541259 EXPECT_EQ(OK, handles[i].Init(base::IntToString(i), params_,
1260 DEFAULT_PRIORITY, SocketTag(),
1261 ClientSocketPool::RespectLimits::ENABLED,
1262 callbacks[i].callback(), pool_.get(),
1263 NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261264 }
1265
1266 // Force a stalled group.
1267 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521268 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201269 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541270 stalled_handle.Init("foo", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:201271 ClientSocketPool::RespectLimits::ENABLED,
1272 callback.callback(), pool_.get(),
1273 NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261274
1275 // Cancel the stalled request.
1276 stalled_handle.Reset();
1277
1278 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1279 EXPECT_EQ(0, pool_->IdleSocketCount());
1280
1281 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541282 }
1283
[email protected]43a21b82010-06-10 21:30:541284 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1285 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:261286}
[email protected]43a21b82010-06-10 21:30:541287
[email protected]eb5a99382010-07-11 03:18:261288TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
1289 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1290 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1291
1292 {
1293 ClientSocketHandle handles[kDefaultMaxSockets];
1294 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521295 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201296 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541297 handles[i].Init(
1298 base::IntToString(i), params_, DEFAULT_PRIORITY,
1299 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1300 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261301 }
1302
1303 // Force a stalled group.
1304 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1305 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521306 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201307 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541308 stalled_handle.Init("foo", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:201309 ClientSocketPool::RespectLimits::ENABLED,
1310 callback.callback(), pool_.get(),
1311 NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261312
1313 // Since it is stalled, it should have no connect jobs.
1314 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
Lily Chenecebf932018-11-02 17:15:431315 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101316 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261317
1318 // Cancel the stalled request.
1319 handles[0].Reset();
1320
[email protected]eb5a99382010-07-11 03:18:261321 // Now we should have a connect job.
1322 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("foo"));
Lily Chenecebf932018-11-02 17:15:431323 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101324 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261325
1326 // The stalled socket should connect.
robpercival214763f2016-07-01 23:27:011327 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:261328
1329 EXPECT_EQ(kDefaultMaxSockets + 1,
1330 client_socket_factory_.allocation_count());
1331 EXPECT_EQ(0, pool_->IdleSocketCount());
1332 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
Lily Chenecebf932018-11-02 17:15:431333 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101334 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261335
1336 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541337 }
1338
[email protected]eb5a99382010-07-11 03:18:261339 EXPECT_EQ(1, pool_->IdleSocketCount());
1340}
[email protected]43a21b82010-06-10 21:30:541341
[email protected]eb5a99382010-07-11 03:18:261342TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1343 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1344 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:541345
[email protected]eb5a99382010-07-11 03:18:261346 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521347 TestCompletionCallback callback;
[email protected]eb5a99382010-07-11 03:18:261348 {
[email protected]51fdc7c2012-04-10 19:19:481349 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261350 ClientSocketHandle handles[kDefaultMaxSockets];
1351 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521352 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201353 EXPECT_EQ(OK, handles[i].Init(base::StringPrintf("Take 2: %d", i),
Paul Jensen8d6f87ec2018-01-13 00:46:541354 params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:201355 ClientSocketPool::RespectLimits::ENABLED,
1356 callback.callback(), pool_.get(),
1357 NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261358 }
1359
1360 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1361 EXPECT_EQ(0, pool_->IdleSocketCount());
[email protected]51fdc7c2012-04-10 19:19:481362 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261363
1364 // Now we will hit the socket limit.
tfarina428341112016-09-22 13:38:201365 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541366 stalled_handle.Init("foo", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:201367 ClientSocketPool::RespectLimits::ENABLED,
1368 callback.callback(), pool_.get(),
1369 NetLogWithSource()));
[email protected]51fdc7c2012-04-10 19:19:481370 EXPECT_TRUE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261371
1372 // Dropping out of scope will close all handles and return them to idle.
1373 }
[email protected]43a21b82010-06-10 21:30:541374
1375 // But if we wait for it, the released idle sockets will be closed in
1376 // preference of the waiting request.
robpercival214763f2016-07-01 23:27:011377 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:261378
1379 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1380 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:541381}
1382
1383// Regression test for http://crbug.com/40952.
1384TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1385 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]06d94042010-08-25 01:45:221386 pool_->EnableConnectBackupJobs();
[email protected]43a21b82010-06-10 21:30:541387 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1388
1389 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1390 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521391 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201392 EXPECT_EQ(
1393 OK, handle.Init(base::IntToString(i), params_, DEFAULT_PRIORITY,
Paul Jensen8d6f87ec2018-01-13 00:46:541394 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201395 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]43a21b82010-06-10 21:30:541396 }
1397
1398 // Flush all the DoReleaseSocket tasks.
fdoray5eeb7642016-06-22 16:11:281399 base::RunLoop().RunUntilIdle();
[email protected]43a21b82010-06-10 21:30:541400
1401 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1402 // reuse a socket.
1403 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1404 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521405 TestCompletionCallback callback;
[email protected]43a21b82010-06-10 21:30:541406
1407 // "0" is special here, since it should be the first entry in the sorted map,
1408 // which is the one which we would close an idle socket for. We shouldn't
1409 // close an idle socket though, since we should reuse the idle socket.
tfarina428341112016-09-22 13:38:201410 EXPECT_EQ(OK,
Paul Jensen8d6f87ec2018-01-13 00:46:541411 handle.Init("0", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:201412 ClientSocketPool::RespectLimits::ENABLED,
1413 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]43a21b82010-06-10 21:30:541414
1415 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1416 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1417}
1418
[email protected]ab838892009-06-30 18:49:051419TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531420 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091421
robpercival214763f2016-07-01 23:27:011422 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1423 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1424 EXPECT_THAT(StartRequest("a", IDLE), IsError(ERR_IO_PENDING));
1425 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
1426 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1427 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
1428 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1429 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091430
[email protected]2431756e2010-09-29 20:26:131431 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]c9d6a1d2009-07-14 16:15:201432 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1433 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131434 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1435 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091436
[email protected]c9d6a1d2009-07-14 16:15:201437 EXPECT_EQ(1, GetOrderOfRequest(1));
1438 EXPECT_EQ(2, GetOrderOfRequest(2));
[email protected]c9c6f5c2010-07-31 01:30:031439 EXPECT_EQ(8, GetOrderOfRequest(3));
1440 EXPECT_EQ(6, GetOrderOfRequest(4));
1441 EXPECT_EQ(4, GetOrderOfRequest(5));
1442 EXPECT_EQ(3, GetOrderOfRequest(6));
1443 EXPECT_EQ(5, GetOrderOfRequest(7));
1444 EXPECT_EQ(7, GetOrderOfRequest(8));
[email protected]75439d3b2009-07-23 22:11:171445
1446 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131447 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]f6d1d6eb2009-06-24 20:16:091448}
1449
[email protected]ab838892009-06-30 18:49:051450TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531451 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091452
robpercival214763f2016-07-01 23:27:011453 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1454 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1455 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
1456 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1457 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
1458 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1459 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091460
[email protected]2431756e2010-09-29 20:26:131461 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091462
[email protected]2431756e2010-09-29 20:26:131463 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
robpercival214763f2016-07-01 23:27:011464 EXPECT_THAT(request(i)->WaitForResult(), IsOk());
[email protected]c9d6a1d2009-07-14 16:15:201465
[email protected]2431756e2010-09-29 20:26:131466 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]c9d6a1d2009-07-14 16:15:201467 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131468 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1469 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091470}
1471
1472// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:051473// The pending connect job will be cancelled and should not call back into
1474// ClientSocketPoolBase.
1475TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[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]2431756e2010-09-29 20:26:131479 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521480 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:151481 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541482 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151483 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201484 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:131485 handle.Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091486}
1487
[email protected]ab838892009-06-30 18:49:051488TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531489 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201490
[email protected]ab838892009-06-30 18:49:051491 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061492 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521493 TestCompletionCallback callback;
[email protected]f6d1d6eb2009-06-24 20:16:091494
mmenked3641e12016-01-28 16:06:151495 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541496 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151497 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201498 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]f6d1d6eb2009-06-24 20:16:091499
1500 handle.Reset();
1501
[email protected]6ecf2b92011-12-15 01:14:521502 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:131503 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541504 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151505 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201506 callback2.callback(), pool_.get(), NetLogWithSource()));
[email protected]f6d1d6eb2009-06-24 20:16:091507
robpercival214763f2016-07-01 23:27:011508 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]f6d1d6eb2009-06-24 20:16:091509 EXPECT_FALSE(callback.have_result());
1510
1511 handle.Reset();
1512}
1513
[email protected]ab838892009-06-30 18:49:051514TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531515 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091516
robpercival214763f2016-07-01 23:27:011517 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1518 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1519 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
1520 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1521 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
1522 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1523 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091524
1525 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201526 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]2431756e2010-09-29 20:26:131527 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1528 (*requests())[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091529
[email protected]2431756e2010-09-29 20:26:131530 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091531
[email protected]c9d6a1d2009-07-14 16:15:201532 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1533 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131534 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1535 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091536
[email protected]c9d6a1d2009-07-14 16:15:201537 EXPECT_EQ(1, GetOrderOfRequest(1));
1538 EXPECT_EQ(2, GetOrderOfRequest(2));
1539 EXPECT_EQ(5, GetOrderOfRequest(3));
1540 EXPECT_EQ(3, GetOrderOfRequest(4));
[email protected]2431756e2010-09-29 20:26:131541 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1542 GetOrderOfRequest(5)); // Canceled request.
[email protected]c9d6a1d2009-07-14 16:15:201543 EXPECT_EQ(4, GetOrderOfRequest(6));
1544 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171545
1546 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131547 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091548}
1549
mmenke33d24423d2015-05-19 19:41:091550// Function to be used as a callback on socket request completion. It first
1551// disconnects the successfully connected socket from the first request, and
1552// then reuses the ClientSocketHandle to request another socket.
1553//
1554// |nested_callback| is called with the result of the second socket request.
1555void RequestSocketOnComplete(ClientSocketHandle* handle,
1556 TestClientSocketPool* pool,
1557 TestConnectJobFactory* test_connect_job_factory,
1558 TestConnectJob::JobType next_job_type,
Bence Békya4a50932018-08-10 13:39:411559 TestCompletionCallback* nested_callback,
mmenke33d24423d2015-05-19 19:41:091560 int first_request_result) {
robpercival214763f2016-07-01 23:27:011561 EXPECT_THAT(first_request_result, IsOk());
mmenke33d24423d2015-05-19 19:41:091562
1563 test_connect_job_factory->set_job_type(next_job_type);
1564
1565 // Don't allow reuse of the socket. Disconnect it and then release it.
1566 if (handle->socket())
1567 handle->socket()->Disconnect();
1568 handle->Reset();
1569
mmenked3641e12016-01-28 16:06:151570 scoped_refptr<TestSocketParams> params(new TestSocketParams());
mmenke33d24423d2015-05-19 19:41:091571 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:541572 int rv = handle->Init("a", params, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:151573 ClientSocketPool::RespectLimits::ENABLED,
Bence Békya4a50932018-08-10 13:39:411574 nested_callback->callback(), pool, NetLogWithSource());
mmenke33d24423d2015-05-19 19:41:091575 if (rv != ERR_IO_PENDING) {
1576 DCHECK_EQ(TestConnectJob::kMockJob, next_job_type);
Bence Békya4a50932018-08-10 13:39:411577 nested_callback->callback().Run(rv);
mmenke33d24423d2015-05-19 19:41:091578 } else {
1579 DCHECK_EQ(TestConnectJob::kMockPendingJob, next_job_type);
[email protected]6ecf2b92011-12-15 01:14:521580 }
mmenke33d24423d2015-05-19 19:41:091581}
[email protected]f6d1d6eb2009-06-24 20:16:091582
mmenke33d24423d2015-05-19 19:41:091583// Tests the case where a second socket is requested in a completion callback,
1584// and the second socket connects asynchronously. Reuses the same
1585// ClientSocketHandle for the second socket, after disconnecting the first.
[email protected]2ab05b52009-07-01 23:57:581586TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531587 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201588
[email protected]0b7648c2009-07-06 20:14:011589 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061590 ClientSocketHandle handle;
mmenke33d24423d2015-05-19 19:41:091591 TestCompletionCallback second_result_callback;
1592 int rv = handle.Init(
Paul Jensen8d6f87ec2018-01-13 00:46:541593 "a", params_, DEFAULT_PRIORITY, SocketTag(),
1594 ClientSocketPool::RespectLimits::ENABLED,
mmenke33d24423d2015-05-19 19:41:091595 base::Bind(&RequestSocketOnComplete, &handle, pool_.get(),
1596 connect_job_factory_, TestConnectJob::kMockPendingJob,
Bence Békya4a50932018-08-10 13:39:411597 &second_result_callback),
tfarina428341112016-09-22 13:38:201598 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011599 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091600
robpercival214763f2016-07-01 23:27:011601 EXPECT_THAT(second_result_callback.WaitForResult(), IsOk());
[email protected]2ab05b52009-07-01 23:57:581602}
[email protected]f6d1d6eb2009-06-24 20:16:091603
mmenke33d24423d2015-05-19 19:41:091604// Tests the case where a second socket is requested in a completion callback,
1605// and the second socket connects synchronously. Reuses the same
1606// ClientSocketHandle for the second socket, after disconnecting the first.
[email protected]2ab05b52009-07-01 23:57:581607TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531608 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201609
[email protected]0b7648c2009-07-06 20:14:011610 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061611 ClientSocketHandle handle;
mmenke33d24423d2015-05-19 19:41:091612 TestCompletionCallback second_result_callback;
1613 int rv = handle.Init(
Paul Jensen8d6f87ec2018-01-13 00:46:541614 "a", params_, DEFAULT_PRIORITY, SocketTag(),
1615 ClientSocketPool::RespectLimits::ENABLED,
mmenke33d24423d2015-05-19 19:41:091616 base::Bind(&RequestSocketOnComplete, &handle, pool_.get(),
1617 connect_job_factory_, TestConnectJob::kMockPendingJob,
Bence Békya4a50932018-08-10 13:39:411618 &second_result_callback),
tfarina428341112016-09-22 13:38:201619 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011620 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2ab05b52009-07-01 23:57:581621
robpercival214763f2016-07-01 23:27:011622 EXPECT_THAT(second_result_callback.WaitForResult(), IsOk());
[email protected]f6d1d6eb2009-06-24 20:16:091623}
1624
1625// Make sure that pending requests get serviced after active requests get
1626// cancelled.
[email protected]ab838892009-06-30 18:49:051627TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531628 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201629
[email protected]0b7648c2009-07-06 20:14:011630 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091631
robpercival214763f2016-07-01 23:27:011632 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1633 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1634 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1635 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1636 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1637 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1638 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091639
[email protected]c9d6a1d2009-07-14 16:15:201640 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1641 // Let's cancel them.
1642 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]2431756e2010-09-29 20:26:131643 ASSERT_FALSE(request(i)->handle()->is_initialized());
1644 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091645 }
1646
[email protected]f6d1d6eb2009-06-24 20:16:091647 // Let's wait for the rest to complete now.
[email protected]2431756e2010-09-29 20:26:131648 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
robpercival214763f2016-07-01 23:27:011649 EXPECT_THAT(request(i)->WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:131650 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091651 }
1652
[email protected]2431756e2010-09-29 20:26:131653 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1654 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091655}
1656
1657// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051658TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531659 const size_t kMaxSockets = 5;
1660 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201661
[email protected]0b7648c2009-07-06 20:14:011662 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091663
[email protected]211d21722009-07-22 15:48:531664 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1665 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091666
1667 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531668 for (size_t i = 0; i < kNumberOfRequests; ++i)
robpercival214763f2016-07-01 23:27:011669 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091670
[email protected]211d21722009-07-22 15:48:531671 for (size_t i = 0; i < kNumberOfRequests; ++i)
robpercival214763f2016-07-01 23:27:011672 EXPECT_THAT(request(i)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]f6d1d6eb2009-06-24 20:16:091673}
1674
mmenke9d72fe42017-05-18 22:36:071675// Make sure that pending requests that complete synchronously get serviced
1676// after active requests fail. See https://crbug.com/723748
1677TEST_F(ClientSocketPoolBaseTest, HandleMultipleSyncFailuresAfterAsyncFailure) {
1678 const size_t kNumberOfRequests = 10;
1679 const size_t kMaxSockets = 1;
1680 CreatePool(kMaxSockets, kMaxSockets);
1681
1682 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1683
1684 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1685
1686 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
1687
1688 // Queue up all the other requests
1689 for (size_t i = 1; i < kNumberOfRequests; ++i)
1690 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1691
1692 // Make sure all requests fail, instead of hanging.
1693 for (size_t i = 0; i < kNumberOfRequests; ++i)
1694 EXPECT_THAT(request(i)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
1695}
1696
[email protected]5fc08e32009-07-15 17:09:571697TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531698 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571699
1700 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1701
[email protected]2431756e2010-09-29 20:26:131702 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521703 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:541704 int rv = handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151705 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201706 callback.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011707 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:571708
1709 // Cancel the active request.
[email protected]2431756e2010-09-29 20:26:131710 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571711
Paul Jensen8d6f87ec2018-01-13 00:46:541712 rv = handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151713 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201714 callback.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011715 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1716 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]5fc08e32009-07-15 17:09:571717
[email protected]2431756e2010-09-29 20:26:131718 EXPECT_FALSE(handle.is_reused());
[email protected]034df0f32013-01-07 23:17:481719 TestLoadTimingInfoConnectedNotReused(handle);
[email protected]5fc08e32009-07-15 17:09:571720 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1721}
1722
xunjieli26619e72016-11-23 19:39:551723TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsForced) {
xunjieli26619e72016-11-23 19:39:551724 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1725 ClientSocketHandle handle;
1726 TestCompletionCallback callback;
1727 BoundTestNetLog log;
Paul Jensen8d6f87ec2018-01-13 00:46:541728 int rv = handle.Init("a", params_, LOWEST, SocketTag(),
xunjieli26619e72016-11-23 19:39:551729 ClientSocketPool::RespectLimits::ENABLED,
1730 callback.callback(), pool_.get(), log.bound());
1731 EXPECT_THAT(rv, IsOk());
1732 handle.Reset();
1733 EXPECT_EQ(1, pool_->IdleSocketCount());
1734 pool_->CloseIdleSockets();
xunjieli26619e72016-11-23 19:39:551735}
1736
xunjieli92feb332017-03-03 17:19:231737TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsInGroupForced) {
xunjieli92feb332017-03-03 17:19:231738 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1739 TestCompletionCallback callback;
1740 BoundTestNetLog log;
1741 ClientSocketHandle handle1;
Paul Jensen8d6f87ec2018-01-13 00:46:541742 int rv = handle1.Init("a", params_, LOWEST, SocketTag(),
xunjieli92feb332017-03-03 17:19:231743 ClientSocketPool::RespectLimits::ENABLED,
1744 callback.callback(), pool_.get(), log.bound());
1745 EXPECT_THAT(rv, IsOk());
1746 ClientSocketHandle handle2;
Paul Jensen8d6f87ec2018-01-13 00:46:541747 rv = handle2.Init("a", params_, LOWEST, SocketTag(),
xunjieli92feb332017-03-03 17:19:231748 ClientSocketPool::RespectLimits::ENABLED,
1749 callback.callback(), pool_.get(), log.bound());
1750 ClientSocketHandle handle3;
Paul Jensen8d6f87ec2018-01-13 00:46:541751 rv = handle3.Init("b", params_, LOWEST, SocketTag(),
xunjieli92feb332017-03-03 17:19:231752 ClientSocketPool::RespectLimits::ENABLED,
1753 callback.callback(), pool_.get(), log.bound());
1754 EXPECT_THAT(rv, IsOk());
1755 handle1.Reset();
1756 handle2.Reset();
1757 handle3.Reset();
1758 EXPECT_EQ(3, pool_->IdleSocketCount());
1759 pool_->CloseIdleSocketsInGroup("a");
1760 EXPECT_EQ(1, pool_->IdleSocketCount());
xunjieli92feb332017-03-03 17:19:231761}
1762
xunjieli26619e72016-11-23 19:39:551763TEST_F(ClientSocketPoolBaseTest, CleanUpUnusableIdleSockets) {
xunjieli26619e72016-11-23 19:39:551764 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1765 ClientSocketHandle handle;
1766 TestCompletionCallback callback;
1767 BoundTestNetLog log;
Paul Jensen8d6f87ec2018-01-13 00:46:541768 int rv = handle.Init("a", params_, LOWEST, SocketTag(),
xunjieli26619e72016-11-23 19:39:551769 ClientSocketPool::RespectLimits::ENABLED,
1770 callback.callback(), pool_.get(), log.bound());
1771 EXPECT_THAT(rv, IsOk());
1772 StreamSocket* socket = handle.socket();
1773 handle.Reset();
1774 EXPECT_EQ(1, pool_->IdleSocketCount());
1775
1776 // Disconnect socket now to make the socket unusable.
1777 socket->Disconnect();
1778 ClientSocketHandle handle2;
Paul Jensen8d6f87ec2018-01-13 00:46:541779 rv = handle2.Init("a", params_, LOWEST, SocketTag(),
xunjieli26619e72016-11-23 19:39:551780 ClientSocketPool::RespectLimits::ENABLED,
1781 callback.callback(), pool_.get(), log.bound());
1782 EXPECT_THAT(rv, IsOk());
1783 EXPECT_FALSE(handle2.is_reused());
xunjieli26619e72016-11-23 19:39:551784}
1785
[email protected]2b7523d2009-07-29 20:29:231786// Regression test for http://crbug.com/17985.
1787TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1788 const int kMaxSockets = 3;
1789 const int kMaxSocketsPerGroup = 2;
1790 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1791
[email protected]ac790b42009-12-02 04:31:311792 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231793
robpercival214763f2016-07-01 23:27:011794 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1795 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
[email protected]2b7523d2009-07-29 20:29:231796
1797 // This is going to be a pending request in an otherwise empty group.
robpercival214763f2016-07-01 23:27:011798 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]2b7523d2009-07-29 20:29:231799
1800 // Reach the maximum socket limit.
robpercival214763f2016-07-01 23:27:011801 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
[email protected]2b7523d2009-07-29 20:29:231802
1803 // Create a stalled group with high priorities.
robpercival214763f2016-07-01 23:27:011804 EXPECT_THAT(StartRequest("c", kHighPriority), IsError(ERR_IO_PENDING));
1805 EXPECT_THAT(StartRequest("c", kHighPriority), IsError(ERR_IO_PENDING));
[email protected]2b7523d2009-07-29 20:29:231806
[email protected]eb5a99382010-07-11 03:18:261807 // Release the first two sockets from "a". Because this is a keepalive,
1808 // the first release will unblock the pending request for "a". The
1809 // second release will unblock a request for "c", becaue it is the next
1810 // high priority socket.
[email protected]2431756e2010-09-29 20:26:131811 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1812 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]2b7523d2009-07-29 20:29:231813
1814 // Closing idle sockets should not get us into trouble, but in the bug
1815 // we were hitting a CHECK here.
[email protected]93054cc12010-06-08 06:12:411816 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]43a21b82010-06-10 21:30:541817 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261818
[email protected]2da659e2013-05-23 20:51:341819 // Run the released socket wakeups.
fdoray5eeb7642016-06-22 16:11:281820 base::RunLoop().RunUntilIdle();
[email protected]2b7523d2009-07-29 20:29:231821}
1822
[email protected]4d3b05d2010-01-27 21:27:291823TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531824 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571825
1826 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131827 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521828 TestCompletionCallback callback;
vishal.b62985ca92015-04-17 08:45:511829 BoundTestNetLog log;
Paul Jensen8d6f87ec2018-01-13 00:46:541830 int rv = handle.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:151831 ClientSocketPool::RespectLimits::ENABLED,
1832 callback.callback(), pool_.get(), log.bound());
robpercival214763f2016-07-01 23:27:011833 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2431756e2010-09-29 20:26:131834 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
[email protected]034df0f32013-01-07 23:17:481835 TestLoadTimingInfoNotConnected(handle);
1836
robpercival214763f2016-07-01 23:27:011837 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:131838 EXPECT_TRUE(handle.is_initialized());
1839 EXPECT_TRUE(handle.socket());
[email protected]034df0f32013-01-07 23:17:481840 TestLoadTimingInfoConnectedNotReused(handle);
1841
[email protected]2431756e2010-09-29 20:26:131842 handle.Reset();
[email protected]034df0f32013-01-07 23:17:481843 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:301844
mmenke43758e62015-05-04 21:09:461845 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:401846 log.GetEntries(&entries);
1847
1848 EXPECT_EQ(4u, entries.size());
mikecirone8b85c432016-09-08 19:11:001849 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171850 EXPECT_TRUE(LogContainsEvent(
mikecirone8b85c432016-09-08 19:11:001851 entries, 1, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1852 NetLogEventPhase::NONE));
1853 EXPECT_TRUE(LogContainsEvent(entries, 2,
1854 NetLogEventType::SOCKET_POOL_BOUND_TO_SOCKET,
1855 NetLogEventPhase::NONE));
1856 EXPECT_TRUE(LogContainsEndEvent(entries, 3, NetLogEventType::SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571857}
1858
[email protected]4d3b05d2010-01-27 21:27:291859TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571860 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531861 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571862
1863 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2431756e2010-09-29 20:26:131864 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521865 TestCompletionCallback callback;
vishal.b62985ca92015-04-17 08:45:511866 BoundTestNetLog log;
[email protected]e60e47a2010-07-14 03:37:181867 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:131868 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:431869 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:451870 info.headers = new HttpResponseHeaders(std::string());
[email protected]2431756e2010-09-29 20:26:131871 handle.set_ssl_error_response_info(info);
mmenked3641e12016-01-28 16:06:151872 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541873 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151874 ClientSocketPool::RespectLimits::ENABLED,
1875 callback.callback(), pool_.get(), log.bound()));
[email protected]2431756e2010-09-29 20:26:131876 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
robpercival214763f2016-07-01 23:27:011877 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]2431756e2010-09-29 20:26:131878 EXPECT_FALSE(handle.is_ssl_error());
1879 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:301880
mmenke43758e62015-05-04 21:09:461881 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:401882 log.GetEntries(&entries);
1883
1884 EXPECT_EQ(3u, entries.size());
mikecirone8b85c432016-09-08 19:11:001885 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171886 EXPECT_TRUE(LogContainsEvent(
mikecirone8b85c432016-09-08 19:11:001887 entries, 1, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1888 NetLogEventPhase::NONE));
1889 EXPECT_TRUE(LogContainsEndEvent(entries, 2, NetLogEventType::SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571890}
1891
mmenke6be122f2015-03-09 22:22:471892// Check that an async ConnectJob failure does not result in creation of a new
1893// ConnectJob when there's another pending request also waiting on its own
1894// ConnectJob. See http://crbug.com/463960.
1895TEST_F(ClientSocketPoolBaseTest, AsyncFailureWithPendingRequestWithJob) {
1896 CreatePool(2, 2);
1897 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1898
robpercival214763f2016-07-01 23:27:011899 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1900 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
mmenke6be122f2015-03-09 22:22:471901
robpercival214763f2016-07-01 23:27:011902 EXPECT_THAT(request(0)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
1903 EXPECT_THAT(request(1)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
mmenke6be122f2015-03-09 22:22:471904
1905 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1906}
1907
[email protected]4d3b05d2010-01-27 21:27:291908TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101909 // TODO(eroman): Add back the log expectations! Removed them because the
1910 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531911 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571912
1913 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131914 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521915 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131916 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:521917 TestCompletionCallback callback2;
[email protected]5fc08e32009-07-15 17:09:571918
[email protected]2431756e2010-09-29 20:26:131919 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541920 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151921 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201922 callback.callback(), pool_.get(), NetLogWithSource()));
vishal.b62985ca92015-04-17 08:45:511923 BoundTestNetLog log2;
tfarina428341112016-09-22 13:38:201924 EXPECT_EQ(
1925 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541926 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:201927 ClientSocketPool::RespectLimits::ENABLED,
1928 callback2.callback(), pool_.get(), NetLogWithSource()));
[email protected]5fc08e32009-07-15 17:09:571929
[email protected]2431756e2010-09-29 20:26:131930 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571931
[email protected]fd7b7c92009-08-20 19:38:301932
1933 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301934
robpercival214763f2016-07-01 23:27:011935 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:131936 handle2.Reset();
[email protected]fd7b7c92009-08-20 19:38:301937
1938 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531939 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571940}
1941
[email protected]4d3b05d2010-01-27 21:27:291942TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341943 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1944
[email protected]17a0c6c2009-08-04 00:07:041945 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1946
robpercival214763f2016-07-01 23:27:011947 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
1948 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1949 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1950 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
[email protected]974ebd62009-08-03 23:14:341951
1952 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]2431756e2010-09-29 20:26:131953 (*requests())[2]->handle()->Reset();
1954 (*requests())[3]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341955 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1956
[email protected]2431756e2010-09-29 20:26:131957 (*requests())[1]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341958 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1959
[email protected]2431756e2010-09-29 20:26:131960 (*requests())[0]->handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261961 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]974ebd62009-08-03 23:14:341962}
1963
[email protected]5fc08e32009-07-15 17:09:571964// When requests and ConnectJobs are not coupled, the request will get serviced
1965// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291966TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531967 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571968
1969 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321970 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571971
[email protected]2431756e2010-09-29 20:26:131972 std::vector<TestSocketRequest*> request_order;
1973 size_t completion_count; // unused
1974 TestSocketRequest req1(&request_order, &completion_count);
Paul Jensen8d6f87ec2018-01-13 00:46:541975 int rv =
1976 req1.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
1977 ClientSocketPool::RespectLimits::ENABLED,
1978 req1.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011979 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1980 EXPECT_THAT(req1.WaitForResult(), IsOk());
[email protected]5fc08e32009-07-15 17:09:571981
1982 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1983 // without a job.
1984 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1985
[email protected]2431756e2010-09-29 20:26:131986 TestSocketRequest req2(&request_order, &completion_count);
Paul Jensen8d6f87ec2018-01-13 00:46:541987 rv = req2.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151988 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201989 req2.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011990 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2431756e2010-09-29 20:26:131991 TestSocketRequest req3(&request_order, &completion_count);
Paul Jensen8d6f87ec2018-01-13 00:46:541992 rv = req3.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151993 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201994 req3.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011995 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:571996
1997 // Both Requests 2 and 3 are pending. We release socket 1 which should
1998 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331999 req1.handle()->Reset();
[email protected]2da659e2013-05-23 20:51:342000 // Run the released socket wakeups.
fdoray5eeb7642016-06-22 16:11:282001 base::RunLoop().RunUntilIdle();
[email protected]a6c59f62009-07-29 16:33:332002 ASSERT_TRUE(req2.handle()->socket());
robpercival214763f2016-07-01 23:27:012003 EXPECT_THAT(req2.WaitForResult(), IsOk());
[email protected]a6c59f62009-07-29 16:33:332004 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:572005
2006 // Signal job 2, which should service request 3.
2007
2008 client_socket_factory_.SignalJobs();
robpercival214763f2016-07-01 23:27:012009 EXPECT_THAT(req3.WaitForResult(), IsOk());
[email protected]5fc08e32009-07-15 17:09:572010
[email protected]2431756e2010-09-29 20:26:132011 ASSERT_EQ(3U, request_order.size());
2012 EXPECT_EQ(&req1, request_order[0]);
2013 EXPECT_EQ(&req2, request_order[1]);
2014 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:572015 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2016}
2017
2018// The requests are not coupled to the jobs. So, the requests should finish in
2019// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:292020TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:532021 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:572022 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:322023 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:572024
[email protected]2431756e2010-09-29 20:26:132025 std::vector<TestSocketRequest*> request_order;
2026 size_t completion_count; // unused
2027 TestSocketRequest req1(&request_order, &completion_count);
Paul Jensen8d6f87ec2018-01-13 00:46:542028 int rv =
2029 req1.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2030 ClientSocketPool::RespectLimits::ENABLED,
2031 req1.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012032 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572033
[email protected]2431756e2010-09-29 20:26:132034 TestSocketRequest req2(&request_order, &completion_count);
Paul Jensen8d6f87ec2018-01-13 00:46:542035 rv = req2.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152036 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202037 req2.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012038 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572039
2040 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:322041 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:572042
[email protected]2431756e2010-09-29 20:26:132043 TestSocketRequest req3(&request_order, &completion_count);
Paul Jensen8d6f87ec2018-01-13 00:46:542044 rv = req3.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152045 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202046 req3.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012047 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572048
robpercival214763f2016-07-01 23:27:012049 EXPECT_THAT(req1.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
2050 EXPECT_THAT(req2.WaitForResult(), IsOk());
2051 EXPECT_THAT(req3.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]5fc08e32009-07-15 17:09:572052
[email protected]2431756e2010-09-29 20:26:132053 ASSERT_EQ(3U, request_order.size());
2054 EXPECT_EQ(&req1, request_order[0]);
2055 EXPECT_EQ(&req2, request_order[1]);
2056 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:572057}
2058
[email protected]03b7c8c2013-07-20 04:38:552059// Test GetLoadState in the case there's only one socket request.
2060TEST_F(ClientSocketPoolBaseTest, LoadStateOneRequest) {
[email protected]211d21722009-07-22 15:48:532061 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]03b7c8c2013-07-20 04:38:552062 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]5fc08e32009-07-15 17:09:572063
[email protected]2431756e2010-09-29 20:26:132064 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522065 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:542066 int rv = handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152067 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202068 callback.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012069 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552070 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:572071
[email protected]03b7c8c2013-07-20 04:38:552072 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2073 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
2074
2075 // No point in completing the connection, since ClientSocketHandles only
2076 // expect the LoadState to be checked while connecting.
2077}
2078
2079// Test GetLoadState in the case there are two socket requests.
haavardm835c1d62015-04-22 08:18:002080// Only the first connection in the pool should affect the pool's load status.
[email protected]03b7c8c2013-07-20 04:38:552081TEST_F(ClientSocketPoolBaseTest, LoadStateTwoRequests) {
2082 CreatePool(2, 2);
2083 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2084
2085 ClientSocketHandle handle;
2086 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:542087 int rv = handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152088 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202089 callback.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012090 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
haavardm835c1d62015-04-22 08:18:002091 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
2092
2093 ClientSocketHandle handle2;
2094 TestCompletionCallback callback2;
Paul Jensen8d6f87ec2018-01-13 00:46:542095 rv = handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152096 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202097 callback2.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012098 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
haavardm835c1d62015-04-22 08:18:002099 client_socket_factory_.SetJobLoadState(1, LOAD_STATE_RESOLVING_HOST);
2100
2101 // Check that both handles report the state of the first job.
2102 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle.GetLoadState());
2103 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle2.GetLoadState());
2104
2105 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_CONNECTING);
2106
2107 // Check that both handles change to LOAD_STATE_CONNECTING.
2108 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2109 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
2110}
2111
2112// Test that the second connection request does not affect the pool's load
2113// status.
2114TEST_F(ClientSocketPoolBaseTest, LoadStateTwoRequestsChangeSecondRequestState) {
2115 CreatePool(2, 2);
2116 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2117
2118 ClientSocketHandle handle;
2119 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:542120 int rv = handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152121 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202122 callback.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012123 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572124
[email protected]2431756e2010-09-29 20:26:132125 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522126 TestCompletionCallback callback2;
Paul Jensen8d6f87ec2018-01-13 00:46:542127 rv = handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152128 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202129 callback2.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012130 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
haavardm835c1d62015-04-22 08:18:002131 client_socket_factory_.SetJobLoadState(1, LOAD_STATE_RESOLVING_HOST);
[email protected]03b7c8c2013-07-20 04:38:552132
[email protected]03b7c8c2013-07-20 04:38:552133 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2134 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
2135
haavardm835c1d62015-04-22 08:18:002136 // First job connects and the first request gets the socket. The
[email protected]03b7c8c2013-07-20 04:38:552137 // second handle switches to the state of the remaining ConnectJob.
2138 client_socket_factory_.SignalJob(0);
robpercival214763f2016-07-01 23:27:012139 EXPECT_THAT(callback.WaitForResult(), IsOk());
haavardm835c1d62015-04-22 08:18:002140 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle2.GetLoadState());
[email protected]03b7c8c2013-07-20 04:38:552141}
2142
2143// Test GetLoadState in the case the per-group limit is reached.
2144TEST_F(ClientSocketPoolBaseTest, LoadStateGroupLimit) {
2145 CreatePool(2, 1);
2146 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2147
2148 ClientSocketHandle handle;
2149 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:542150 int rv = handle.Init("a", params_, MEDIUM, SocketTag(),
mmenked3641e12016-01-28 16:06:152151 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202152 callback.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012153 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552154 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2155
2156 // Request another socket from the same pool, buth with a higher priority.
2157 // The first request should now be stalled at the socket group limit.
2158 ClientSocketHandle handle2;
2159 TestCompletionCallback callback2;
Paul Jensen8d6f87ec2018-01-13 00:46:542160 rv = handle2.Init("a", params_, HIGHEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152161 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202162 callback2.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012163 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552164 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2165 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
2166
2167 // The first handle should remain stalled as the other socket goes through
2168 // the connect process.
2169
2170 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2171 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2172 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle2.GetLoadState());
2173
2174 client_socket_factory_.SignalJob(0);
robpercival214763f2016-07-01 23:27:012175 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]03b7c8c2013-07-20 04:38:552176 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2177
2178 // Closing the second socket should cause the stalled handle to finally get a
2179 // ConnectJob.
2180 handle2.socket()->Disconnect();
2181 handle2.Reset();
2182 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2183}
2184
2185// Test GetLoadState in the case the per-pool limit is reached.
2186TEST_F(ClientSocketPoolBaseTest, LoadStatePoolLimit) {
2187 CreatePool(2, 2);
2188 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2189
2190 ClientSocketHandle handle;
2191 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:542192 int rv = handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152193 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202194 callback.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012195 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552196
2197 // Request for socket from another pool.
2198 ClientSocketHandle handle2;
2199 TestCompletionCallback callback2;
Paul Jensen8d6f87ec2018-01-13 00:46:542200 rv = handle2.Init("b", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152201 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202202 callback2.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012203 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552204
2205 // Request another socket from the first pool. Request should stall at the
2206 // socket pool limit.
2207 ClientSocketHandle handle3;
2208 TestCompletionCallback callback3;
Paul Jensen8d6f87ec2018-01-13 00:46:542209 rv = handle3.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152210 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202211 callback2.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012212 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552213
2214 // The third handle should remain stalled as the other sockets in its group
2215 // goes through the connect process.
2216
2217 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2218 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2219
2220 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2221 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
2222 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2223
2224 client_socket_factory_.SignalJob(0);
robpercival214763f2016-07-01 23:27:012225 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]03b7c8c2013-07-20 04:38:552226 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2227
2228 // Closing a socket should allow the stalled handle to finally get a new
2229 // ConnectJob.
2230 handle.socket()->Disconnect();
2231 handle.Reset();
2232 EXPECT_EQ(LOAD_STATE_CONNECTING, handle3.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:572233}
2234
[email protected]e772db3f2010-07-12 18:11:132235TEST_F(ClientSocketPoolBaseTest, Recoverable) {
2236 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2237 connect_job_factory_->set_job_type(TestConnectJob::kMockRecoverableJob);
2238
[email protected]2431756e2010-09-29 20:26:132239 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522240 TestCompletionCallback callback;
2241 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED,
Paul Jensen8d6f87ec2018-01-13 00:46:542242 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152243 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202244 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:132245 EXPECT_TRUE(handle.is_initialized());
2246 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:132247}
2248
2249TEST_F(ClientSocketPoolBaseTest, AsyncRecoverable) {
2250 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2251
2252 connect_job_factory_->set_job_type(
2253 TestConnectJob::kMockPendingRecoverableJob);
[email protected]2431756e2010-09-29 20:26:132254 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522255 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132256 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542257 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152258 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202259 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:132260 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
robpercival214763f2016-07-01 23:27:012261 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_PROXY_AUTH_REQUESTED));
[email protected]2431756e2010-09-29 20:26:132262 EXPECT_TRUE(handle.is_initialized());
2263 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:132264}
2265
[email protected]e60e47a2010-07-14 03:37:182266TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
2267 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2268 connect_job_factory_->set_job_type(
2269 TestConnectJob::kMockAdditionalErrorStateJob);
2270
[email protected]2431756e2010-09-29 20:26:132271 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522272 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132273 EXPECT_EQ(ERR_CONNECTION_FAILED,
Paul Jensen8d6f87ec2018-01-13 00:46:542274 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152275 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202276 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:132277 EXPECT_FALSE(handle.is_initialized());
2278 EXPECT_FALSE(handle.socket());
2279 EXPECT_TRUE(handle.is_ssl_error());
2280 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182281}
2282
2283TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
2284 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2285
2286 connect_job_factory_->set_job_type(
2287 TestConnectJob::kMockPendingAdditionalErrorStateJob);
[email protected]2431756e2010-09-29 20:26:132288 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522289 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132290 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542291 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152292 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202293 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:132294 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
robpercival214763f2016-07-01 23:27:012295 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]2431756e2010-09-29 20:26:132296 EXPECT_FALSE(handle.is_initialized());
2297 EXPECT_FALSE(handle.socket());
2298 EXPECT_TRUE(handle.is_ssl_error());
2299 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182300}
2301
martijn003cd612016-05-19 22:24:382302// Make sure we can reuse sockets.
2303TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSocketsReuse) {
[email protected]64770b7d2011-11-16 04:30:412304 CreatePoolWithIdleTimeouts(
2305 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
[email protected]e7b1c6d2c2012-05-05 00:54:032306 base::TimeDelta(), // Time out unused sockets immediately.
2307 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2308
2309 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2310
2311 ClientSocketHandle handle;
2312 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:542313 int rv = handle.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152314 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202315 callback.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012316 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e7b1c6d2c2012-05-05 00:54:032317 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
robpercival214763f2016-07-01 23:27:012318 ASSERT_THAT(callback.WaitForResult(), IsOk());
[email protected]e7b1c6d2c2012-05-05 00:54:032319
2320 // Use and release the socket.
Bence Békybdbb0e72018-08-07 21:42:592321 EXPECT_EQ(1, handle.socket()->Write(NULL, 1, CompletionOnceCallback(),
Ramin Halavati0a08cc82018-02-06 07:46:382322 TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]034df0f32013-01-07 23:17:482323 TestLoadTimingInfoConnectedNotReused(handle);
[email protected]e7b1c6d2c2012-05-05 00:54:032324 handle.Reset();
2325
2326 // Should now have one idle socket.
2327 ASSERT_EQ(1, pool_->IdleSocketCount());
2328
2329 // Request a new socket. This should reuse the old socket and complete
2330 // synchronously.
vishal.b62985ca92015-04-17 08:45:512331 BoundTestNetLog log;
Paul Jensen8d6f87ec2018-01-13 00:46:542332 rv = handle.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152333 ClientSocketPool::RespectLimits::ENABLED,
Bence Békybdbb0e72018-08-07 21:42:592334 CompletionOnceCallback(), pool_.get(), log.bound());
robpercival214763f2016-07-01 23:27:012335 ASSERT_THAT(rv, IsOk());
[email protected]e7b1c6d2c2012-05-05 00:54:032336 EXPECT_TRUE(handle.is_reused());
[email protected]034df0f32013-01-07 23:17:482337 TestLoadTimingInfoConnectedReused(handle);
[email protected]e7b1c6d2c2012-05-05 00:54:032338
2339 ASSERT_TRUE(pool_->HasGroup("a"));
2340 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2341 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2342
mmenke43758e62015-05-04 21:09:462343 TestNetLogEntry::List entries;
[email protected]e7b1c6d2c2012-05-05 00:54:032344 log.GetEntries(&entries);
2345 EXPECT_TRUE(LogContainsEntryWithType(
mikecirone8b85c432016-09-08 19:11:002346 entries, 1, NetLogEventType::SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]e7b1c6d2c2012-05-05 00:54:032347}
2348
martijn003cd612016-05-19 22:24:382349// Make sure we cleanup old unused sockets.
Eric Romanb49715e2018-04-24 22:41:172350TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSocketsNoReuse) {
[email protected]e7b1c6d2c2012-05-05 00:54:032351 CreatePoolWithIdleTimeouts(
2352 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2353 base::TimeDelta(), // Time out unused sockets immediately
2354 base::TimeDelta()); // Time out used sockets immediately
[email protected]64770b7d2011-11-16 04:30:412355
2356 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2357
2358 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2359
2360 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522361 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:542362 int rv = handle.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152363 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202364 callback.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012365 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]64770b7d2011-11-16 04:30:412366 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2367
2368 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522369 TestCompletionCallback callback2;
Paul Jensen8d6f87ec2018-01-13 00:46:542370 rv = handle2.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152371 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202372 callback2.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012373 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]64770b7d2011-11-16 04:30:412374 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
2375
2376 // Cancel one of the requests. Wait for the other, which will get the first
2377 // job. Release the socket. Run the loop again to make sure the second
2378 // socket is sitting idle and the first one is released (since ReleaseSocket()
2379 // just posts a DoReleaseSocket() task).
2380
2381 handle.Reset();
robpercival214763f2016-07-01 23:27:012382 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]64770b7d2011-11-16 04:30:412383 // Use the socket.
Bence Békybdbb0e72018-08-07 21:42:592384 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, CompletionOnceCallback(),
Ramin Halavati0a08cc82018-02-06 07:46:382385 TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]64770b7d2011-11-16 04:30:412386 handle2.Reset();
2387
[email protected]e7b1c6d2c2012-05-05 00:54:032388 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2389 // actually become pending until 2ms after they have been created. In order
2390 // to flush all tasks, we need to wait so that we know there are no
2391 // soon-to-be-pending tasks waiting.
Alex Clarke0def2092018-12-10 12:01:452392 FastForwardBy(base::TimeDelta::FromMilliseconds(10));
[email protected]64770b7d2011-11-16 04:30:412393
[email protected]e7b1c6d2c2012-05-05 00:54:032394 // Both sockets should now be idle.
[email protected]64770b7d2011-11-16 04:30:412395 ASSERT_EQ(2, pool_->IdleSocketCount());
2396
2397 // Request a new socket. This should cleanup the unused and timed out ones.
2398 // A new socket will be created rather than reusing the idle one.
vishal.b62985ca92015-04-17 08:45:512399 BoundTestNetLog log;
[email protected]6ecf2b92011-12-15 01:14:522400 TestCompletionCallback callback3;
Paul Jensen8d6f87ec2018-01-13 00:46:542401 rv = handle.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152402 ClientSocketPool::RespectLimits::ENABLED,
2403 callback3.callback(), pool_.get(), log.bound());
robpercival214763f2016-07-01 23:27:012404 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
2405 ASSERT_THAT(callback3.WaitForResult(), IsOk());
[email protected]64770b7d2011-11-16 04:30:412406 EXPECT_FALSE(handle.is_reused());
2407
[email protected]e7b1c6d2c2012-05-05 00:54:032408 // Make sure the idle socket is closed.
[email protected]64770b7d2011-11-16 04:30:412409 ASSERT_TRUE(pool_->HasGroup("a"));
2410 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2411 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2412
mmenke43758e62015-05-04 21:09:462413 TestNetLogEntry::List entries;
[email protected]64770b7d2011-11-16 04:30:412414 log.GetEntries(&entries);
2415 EXPECT_FALSE(LogContainsEntryWithType(
mikecirone8b85c432016-09-08 19:11:002416 entries, 1, NetLogEventType::SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]64770b7d2011-11-16 04:30:412417}
2418
[email protected]2041cf342010-02-19 03:15:592419// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:162420// because of multiple releasing disconnected sockets.
2421TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
2422 CreatePoolWithIdleTimeouts(
2423 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2424 base::TimeDelta(), // Time out unused sockets immediately.
2425 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2426
2427 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2428
2429 // Startup 4 connect jobs. Two of them will be pending.
2430
[email protected]2431756e2010-09-29 20:26:132431 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522432 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:542433 int rv = handle.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152434 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202435 callback.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012436 EXPECT_THAT(rv, IsOk());
[email protected]4f2abec2010-02-03 18:10:162437
[email protected]2431756e2010-09-29 20:26:132438 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522439 TestCompletionCallback callback2;
Paul Jensen8d6f87ec2018-01-13 00:46:542440 rv = handle2.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152441 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202442 callback2.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012443 EXPECT_THAT(rv, IsOk());
[email protected]4f2abec2010-02-03 18:10:162444
[email protected]2431756e2010-09-29 20:26:132445 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:522446 TestCompletionCallback callback3;
Paul Jensen8d6f87ec2018-01-13 00:46:542447 rv = handle3.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152448 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202449 callback3.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012450 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4f2abec2010-02-03 18:10:162451
[email protected]2431756e2010-09-29 20:26:132452 ClientSocketHandle handle4;
[email protected]6ecf2b92011-12-15 01:14:522453 TestCompletionCallback callback4;
Paul Jensen8d6f87ec2018-01-13 00:46:542454 rv = handle4.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152455 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202456 callback4.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012457 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4f2abec2010-02-03 18:10:162458
2459 // Release two disconnected sockets.
2460
[email protected]2431756e2010-09-29 20:26:132461 handle.socket()->Disconnect();
2462 handle.Reset();
2463 handle2.socket()->Disconnect();
2464 handle2.Reset();
[email protected]4f2abec2010-02-03 18:10:162465
robpercival214763f2016-07-01 23:27:012466 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132467 EXPECT_FALSE(handle3.is_reused());
robpercival214763f2016-07-01 23:27:012468 EXPECT_THAT(callback4.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132469 EXPECT_FALSE(handle4.is_reused());
[email protected]4f2abec2010-02-03 18:10:162470}
2471
[email protected]d7027bb2010-05-10 18:58:542472// Regression test for http://crbug.com/42267.
2473// When DoReleaseSocket() is processed for one socket, it is blocked because the
2474// other stalled groups all have releasing sockets, so no progress can be made.
2475TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
2476 CreatePoolWithIdleTimeouts(
2477 4 /* socket limit */, 4 /* socket limit per group */,
2478 base::TimeDelta(), // Time out unused sockets immediately.
2479 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2480
2481 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2482
2483 // Max out the socket limit with 2 per group.
2484
[email protected]2431756e2010-09-29 20:26:132485 ClientSocketHandle handle_a[4];
[email protected]6ecf2b92011-12-15 01:14:522486 TestCompletionCallback callback_a[4];
[email protected]2431756e2010-09-29 20:26:132487 ClientSocketHandle handle_b[4];
[email protected]6ecf2b92011-12-15 01:14:522488 TestCompletionCallback callback_b[4];
[email protected]d7027bb2010-05-10 18:58:542489
2490 for (int i = 0; i < 2; ++i) {
Paul Jensen8d6f87ec2018-01-13 00:46:542491 EXPECT_EQ(OK, handle_a[i].Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152492 ClientSocketPool::RespectLimits::ENABLED,
2493 callback_a[i].callback(), pool_.get(),
tfarina428341112016-09-22 13:38:202494 NetLogWithSource()));
Paul Jensen8d6f87ec2018-01-13 00:46:542495 EXPECT_EQ(OK, handle_b[i].Init("b", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152496 ClientSocketPool::RespectLimits::ENABLED,
2497 callback_b[i].callback(), pool_.get(),
tfarina428341112016-09-22 13:38:202498 NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:542499 }
[email protected]b89f7e42010-05-20 20:37:002500
[email protected]d7027bb2010-05-10 18:58:542501 // Make 4 pending requests, 2 per group.
2502
2503 for (int i = 2; i < 4; ++i) {
tfarina428341112016-09-22 13:38:202504 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542505 handle_a[i].Init("a", params_, LOWEST, SocketTag(),
tfarina428341112016-09-22 13:38:202506 ClientSocketPool::RespectLimits::ENABLED,
2507 callback_a[i].callback(), pool_.get(),
2508 NetLogWithSource()));
2509 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542510 handle_b[i].Init("b", params_, LOWEST, SocketTag(),
tfarina428341112016-09-22 13:38:202511 ClientSocketPool::RespectLimits::ENABLED,
2512 callback_b[i].callback(), pool_.get(),
2513 NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:542514 }
2515
2516 // Release b's socket first. The order is important, because in
2517 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2518 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2519 // first, which has a releasing socket, so it refuses to start up another
2520 // ConnectJob. So, we used to infinite loop on this.
[email protected]2431756e2010-09-29 20:26:132521 handle_b[0].socket()->Disconnect();
2522 handle_b[0].Reset();
2523 handle_a[0].socket()->Disconnect();
2524 handle_a[0].Reset();
[email protected]d7027bb2010-05-10 18:58:542525
2526 // Used to get stuck here.
fdoray5eeb7642016-06-22 16:11:282527 base::RunLoop().RunUntilIdle();
[email protected]d7027bb2010-05-10 18:58:542528
[email protected]2431756e2010-09-29 20:26:132529 handle_b[1].socket()->Disconnect();
2530 handle_b[1].Reset();
2531 handle_a[1].socket()->Disconnect();
2532 handle_a[1].Reset();
[email protected]d7027bb2010-05-10 18:58:542533
2534 for (int i = 2; i < 4; ++i) {
robpercival214763f2016-07-01 23:27:012535 EXPECT_THAT(callback_b[i].WaitForResult(), IsOk());
2536 EXPECT_THAT(callback_a[i].WaitForResult(), IsOk());
[email protected]d7027bb2010-05-10 18:58:542537 }
2538}
2539
[email protected]fd4fe0b2010-02-08 23:02:152540TEST_F(ClientSocketPoolBaseTest,
2541 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2542 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2543
2544 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2545
robpercival214763f2016-07-01 23:27:012546 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
2547 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
2548 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
2549 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]fd4fe0b2010-02-08 23:02:152550
robpercival214763f2016-07-01 23:27:012551 EXPECT_THAT((*requests())[0]->WaitForResult(), IsOk());
2552 EXPECT_THAT((*requests())[1]->WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132553 EXPECT_EQ(2u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152554
2555 // Releases one connection.
[email protected]2431756e2010-09-29 20:26:132556 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
robpercival214763f2016-07-01 23:27:012557 EXPECT_THAT((*requests())[2]->WaitForResult(), IsOk());
[email protected]fd4fe0b2010-02-08 23:02:152558
[email protected]2431756e2010-09-29 20:26:132559 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
robpercival214763f2016-07-01 23:27:012560 EXPECT_THAT((*requests())[3]->WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132561 EXPECT_EQ(4u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152562
2563 EXPECT_EQ(1, GetOrderOfRequest(1));
2564 EXPECT_EQ(2, GetOrderOfRequest(2));
2565 EXPECT_EQ(3, GetOrderOfRequest(3));
2566 EXPECT_EQ(4, GetOrderOfRequest(4));
2567
2568 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:132569 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
[email protected]fd4fe0b2010-02-08 23:02:152570}
2571
[email protected]6ecf2b92011-12-15 01:14:522572class TestReleasingSocketRequest : public TestCompletionCallbackBase {
[email protected]4f1e4982010-03-02 18:31:042573 public:
[email protected]2431756e2010-09-29 20:26:132574 TestReleasingSocketRequest(TestClientSocketPool* pool,
2575 int expected_result,
[email protected]e60e47a2010-07-14 03:37:182576 bool reset_releasing_handle)
2577 : pool_(pool),
2578 expected_result_(expected_result),
Bence Béky8ddc2492018-06-13 01:02:042579 reset_releasing_handle_(reset_releasing_handle) {}
[email protected]6ecf2b92011-12-15 01:14:522580
Chris Watkins7a41d3552017-12-01 02:13:272581 ~TestReleasingSocketRequest() override = default;
[email protected]4f1e4982010-03-02 18:31:042582
2583 ClientSocketHandle* handle() { return &handle_; }
2584
Bence Béky8ddc2492018-06-13 01:02:042585 CompletionOnceCallback callback() {
2586 return base::BindOnce(&TestReleasingSocketRequest::OnComplete,
2587 base::Unretained(this));
2588 }
[email protected]4f1e4982010-03-02 18:31:042589
2590 private:
[email protected]6ecf2b92011-12-15 01:14:522591 void OnComplete(int result) {
2592 SetResult(result);
2593 if (reset_releasing_handle_)
2594 handle_.Reset();
2595
mmenked3641e12016-01-28 16:06:152596 scoped_refptr<TestSocketParams> con_params(new TestSocketParams());
Bence Béky8ddc2492018-06-13 01:02:042597 EXPECT_EQ(
2598 expected_result_,
2599 handle2_.Init("a", con_params, DEFAULT_PRIORITY, SocketTag(),
2600 ClientSocketPool::RespectLimits::ENABLED,
2601 CompletionOnceCallback(), pool_, NetLogWithSource()));
[email protected]6ecf2b92011-12-15 01:14:522602 }
2603
[email protected]2431756e2010-09-29 20:26:132604 TestClientSocketPool* const pool_;
[email protected]e60e47a2010-07-14 03:37:182605 int expected_result_;
2606 bool reset_releasing_handle_;
[email protected]4f1e4982010-03-02 18:31:042607 ClientSocketHandle handle_;
2608 ClientSocketHandle handle2_;
[email protected]4f1e4982010-03-02 18:31:042609};
2610
[email protected]e60e47a2010-07-14 03:37:182611
2612TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2613 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2614
robpercival214763f2016-07-01 23:27:012615 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
2616 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
2617 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
[email protected]e60e47a2010-07-14 03:37:182618
[email protected]2431756e2010-09-29 20:26:132619 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]e60e47a2010-07-14 03:37:182620 client_socket_factory_.allocation_count());
2621
2622 connect_job_factory_->set_job_type(
2623 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2624 TestReleasingSocketRequest req(pool_.get(), OK, false);
tfarina428341112016-09-22 13:38:202625 EXPECT_EQ(
2626 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542627 req.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:202628 ClientSocketPool::RespectLimits::ENABLED,
2629 req.callback(), pool_.get(), NetLogWithSource()));
[email protected]e60e47a2010-07-14 03:37:182630 // The next job should complete synchronously
2631 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2632
robpercival214763f2016-07-01 23:27:012633 EXPECT_THAT(req.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:182634 EXPECT_FALSE(req.handle()->is_initialized());
2635 EXPECT_FALSE(req.handle()->socket());
2636 EXPECT_TRUE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:432637 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182638}
2639
[email protected]b6501d3d2010-06-03 23:53:342640// http://crbug.com/44724 regression test.
2641// We start releasing the pool when we flush on network change. When that
2642// happens, the only active references are in the ClientSocketHandles. When a
2643// ConnectJob completes and calls back into the last ClientSocketHandle, that
2644// callback can release the last reference and delete the pool. After the
2645// callback finishes, we go back to the stack frame within the now-deleted pool.
2646// Executing any code that refers to members of the now-deleted pool can cause
2647// crashes.
2648TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2649 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2650 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2651
2652 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522653 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:152654 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542655 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152656 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202657 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]b6501d3d2010-06-03 23:53:342658
[email protected]7af985a2012-12-14 22:40:422659 pool_->FlushWithError(ERR_NETWORK_CHANGED);
[email protected]b6501d3d2010-06-03 23:53:342660
2661 // We'll call back into this now.
2662 callback.WaitForResult();
2663}
2664
[email protected]a7e38572010-06-07 18:22:242665TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2666 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2667 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2668
2669 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522670 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:152671 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542672 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152673 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202674 callback.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:012675 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]a7e38572010-06-07 18:22:242676 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2677
[email protected]7af985a2012-12-14 22:40:422678 pool_->FlushWithError(ERR_NETWORK_CHANGED);
[email protected]a7e38572010-06-07 18:22:242679
2680 handle.Reset();
fdoray5eeb7642016-06-22 16:11:282681 base::RunLoop().RunUntilIdle();
[email protected]a7e38572010-06-07 18:22:242682
mmenked3641e12016-01-28 16:06:152683 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542684 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152685 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202686 callback.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:012687 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]a7e38572010-06-07 18:22:242688 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2689}
2690
[email protected]6ecf2b92011-12-15 01:14:522691class ConnectWithinCallback : public TestCompletionCallbackBase {
[email protected]06f92462010-08-31 19:24:142692 public:
Bence Béky8ddc2492018-06-13 01:02:042693 ConnectWithinCallback(const std::string& group_name,
2694 const scoped_refptr<TestSocketParams>& params,
2695 TestClientSocketPool* pool)
2696 : group_name_(group_name), params_(params), pool_(pool) {}
[email protected]06f92462010-08-31 19:24:142697
Chris Watkins7a41d3552017-12-01 02:13:272698 ~ConnectWithinCallback() override = default;
[email protected]06f92462010-08-31 19:24:142699
2700 int WaitForNestedResult() {
2701 return nested_callback_.WaitForResult();
2702 }
2703
Bence Béky8ddc2492018-06-13 01:02:042704 CompletionOnceCallback callback() {
2705 return base::BindOnce(&ConnectWithinCallback::OnComplete,
2706 base::Unretained(this));
2707 }
[email protected]6ecf2b92011-12-15 01:14:522708
[email protected]06f92462010-08-31 19:24:142709 private:
[email protected]6ecf2b92011-12-15 01:14:522710 void OnComplete(int result) {
2711 SetResult(result);
tfarina428341112016-09-22 13:38:202712 EXPECT_EQ(
2713 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542714 handle_.Init(group_name_, params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:202715 ClientSocketPool::RespectLimits::ENABLED,
2716 nested_callback_.callback(), pool_, NetLogWithSource()));
[email protected]6ecf2b92011-12-15 01:14:522717 }
2718
[email protected]06f92462010-08-31 19:24:142719 const std::string group_name_;
2720 const scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:132721 TestClientSocketPool* const pool_;
[email protected]06f92462010-08-31 19:24:142722 ClientSocketHandle handle_;
[email protected]6ecf2b92011-12-15 01:14:522723 TestCompletionCallback nested_callback_;
2724
2725 DISALLOW_COPY_AND_ASSIGN(ConnectWithinCallback);
[email protected]06f92462010-08-31 19:24:142726};
2727
2728TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
2729 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2730
2731 // First job will be waiting until it gets aborted.
2732 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2733
2734 ClientSocketHandle handle;
[email protected]2431756e2010-09-29 20:26:132735 ConnectWithinCallback callback("a", params_, pool_.get());
mmenked3641e12016-01-28 16:06:152736 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542737 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152738 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202739 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]06f92462010-08-31 19:24:142740
2741 // Second job will be started during the first callback, and will
2742 // asynchronously complete with OK.
2743 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]7af985a2012-12-14 22:40:422744 pool_->FlushWithError(ERR_NETWORK_CHANGED);
robpercival214763f2016-07-01 23:27:012745 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NETWORK_CHANGED));
2746 EXPECT_THAT(callback.WaitForNestedResult(), IsOk());
[email protected]06f92462010-08-31 19:24:142747}
2748
[email protected]25eea382010-07-10 23:55:262749// Cancel a pending socket request while we're at max sockets,
2750// and verify that the backup socket firing doesn't cause a crash.
2751TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
2752 // Max 4 sockets globally, max 4 sockets per group.
2753 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
[email protected]06d94042010-08-25 01:45:222754 pool_->EnableConnectBackupJobs();
[email protected]25eea382010-07-10 23:55:262755
[email protected]4baaf9d2010-08-31 15:15:442756 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2757 // timer.
[email protected]25eea382010-07-10 23:55:262758 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2759 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522760 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:152761 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542762 handle.Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152763 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202764 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]25eea382010-07-10 23:55:262765
2766 // Start (MaxSockets - 1) connected sockets to reach max sockets.
2767 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2768 ClientSocketHandle handles[kDefaultMaxSockets];
2769 for (int i = 1; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:522770 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:542771 EXPECT_EQ(OK, handles[i].Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:202772 ClientSocketPool::RespectLimits::ENABLED,
2773 callback.callback(), pool_.get(),
2774 NetLogWithSource()));
[email protected]25eea382010-07-10 23:55:262775 }
2776
fdoray5eeb7642016-06-22 16:11:282777 base::RunLoop().RunUntilIdle();
[email protected]25eea382010-07-10 23:55:262778
2779 // Cancel the pending request.
2780 handle.Reset();
2781
2782 // Wait for the backup timer to fire (add some slop to ensure it fires)
Alex Clarke0def2092018-12-10 12:01:452783 FastForwardBy(base::TimeDelta::FromMilliseconds(
[email protected]26b9973962012-01-28 00:57:002784 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]25eea382010-07-10 23:55:262785
[email protected]25eea382010-07-10 23:55:262786 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
2787}
2788
[email protected]3f00be82010-09-27 19:50:022789TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
[email protected]4baaf9d2010-08-31 15:15:442790 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2791 pool_->EnableConnectBackupJobs();
2792
2793 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2794 // timer.
2795 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2796 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522797 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:152798 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542799 handle.Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152800 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202801 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]4baaf9d2010-08-31 15:15:442802 ASSERT_TRUE(pool_->HasGroup("bar"));
2803 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
Lily Chenecebf932018-11-02 17:15:432804 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("bar"));
[email protected]8159a1c2012-06-07 00:00:102805 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("bar"));
[email protected]4baaf9d2010-08-31 15:15:442806
2807 // Cancel the socket request. This should cancel the backup timer. Wait for
2808 // the backup time to see if it indeed got canceled.
2809 handle.Reset();
2810 // Wait for the backup timer to fire (add some slop to ensure it fires)
Alex Clarke0def2092018-12-10 12:01:452811 FastForwardBy(base::TimeDelta::FromMilliseconds(
[email protected]26b9973962012-01-28 00:57:002812 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]4baaf9d2010-08-31 15:15:442813 ASSERT_TRUE(pool_->HasGroup("bar"));
2814 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2815}
2816
[email protected]3f00be82010-09-27 19:50:022817TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
2818 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2819 pool_->EnableConnectBackupJobs();
2820
2821 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2822 // timer.
2823 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2824 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522825 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:152826 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542827 handle.Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152828 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202829 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]3f00be82010-09-27 19:50:022830 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2831 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522832 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:202833 EXPECT_EQ(
2834 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542835 handle2.Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:202836 ClientSocketPool::RespectLimits::ENABLED,
2837 callback2.callback(), pool_.get(), NetLogWithSource()));
[email protected]3f00be82010-09-27 19:50:022838 ASSERT_TRUE(pool_->HasGroup("bar"));
2839 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("bar"));
2840
2841 // Cancel request 1 and then complete request 2. With the requests finished,
2842 // the backup timer should be cancelled.
2843 handle.Reset();
robpercival214763f2016-07-01 23:27:012844 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]3f00be82010-09-27 19:50:022845 // Wait for the backup timer to fire (add some slop to ensure it fires)
Alex Clarke0def2092018-12-10 12:01:452846 FastForwardBy(base::TimeDelta::FromMilliseconds(
[email protected]26b9973962012-01-28 00:57:002847 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]3f00be82010-09-27 19:50:022848}
2849
[email protected]eb5a99382010-07-11 03:18:262850// Test delayed socket binding for the case where we have two connects,
2851// and while one is waiting on a connect, the other frees up.
2852// The socket waiting on a connect should switch immediately to the freed
2853// up socket.
2854TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
2855 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2856 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2857
2858 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522859 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132860 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542861 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152862 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202863 callback.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:012864 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:262865
2866 // No idle sockets, no pending jobs.
2867 EXPECT_EQ(0, pool_->IdleSocketCount());
2868 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2869
2870 // Create a second socket to the same host, but this one will wait.
2871 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2872 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132873 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542874 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152875 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202876 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:262877 // No idle sockets, and one connecting job.
2878 EXPECT_EQ(0, pool_->IdleSocketCount());
2879 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2880
2881 // Return the first handle to the pool. This will initiate the delayed
2882 // binding.
2883 handle1.Reset();
2884
fdoray5eeb7642016-06-22 16:11:282885 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262886
2887 // Still no idle sockets, still one pending connect job.
2888 EXPECT_EQ(0, pool_->IdleSocketCount());
2889 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2890
2891 // The second socket connected, even though it was a Waiting Job.
robpercival214763f2016-07-01 23:27:012892 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:262893
2894 // And we can see there is still one job waiting.
2895 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2896
2897 // Finally, signal the waiting Connect.
2898 client_socket_factory_.SignalJobs();
2899 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2900
fdoray5eeb7642016-06-22 16:11:282901 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262902}
2903
2904// Test delayed socket binding when a group is at capacity and one
2905// of the group's sockets frees up.
2906TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
2907 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2908 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2909
2910 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522911 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132912 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542913 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152914 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202915 callback.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:012916 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:262917
2918 // No idle sockets, no pending jobs.
2919 EXPECT_EQ(0, pool_->IdleSocketCount());
2920 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2921
2922 // Create a second socket to the same host, but this one will wait.
2923 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2924 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132925 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542926 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152927 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202928 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:262929 // No idle sockets, and one connecting job.
2930 EXPECT_EQ(0, pool_->IdleSocketCount());
2931 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2932
2933 // Return the first handle to the pool. This will initiate the delayed
2934 // binding.
2935 handle1.Reset();
2936
fdoray5eeb7642016-06-22 16:11:282937 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262938
2939 // Still no idle sockets, still one pending connect job.
2940 EXPECT_EQ(0, pool_->IdleSocketCount());
2941 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2942
2943 // The second socket connected, even though it was a Waiting Job.
robpercival214763f2016-07-01 23:27:012944 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:262945
2946 // And we can see there is still one job waiting.
2947 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2948
2949 // Finally, signal the waiting Connect.
2950 client_socket_factory_.SignalJobs();
2951 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2952
fdoray5eeb7642016-06-22 16:11:282953 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262954}
2955
2956// Test out the case where we have one socket connected, one
2957// connecting, when the first socket finishes and goes idle.
[email protected]2abfe90a2010-08-25 17:49:512958// Although the second connection is pending, the second request
[email protected]eb5a99382010-07-11 03:18:262959// should complete, by taking the first socket's idle socket.
2960TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
2961 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2962 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2963
2964 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522965 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132966 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542967 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152968 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202969 callback.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:012970 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:262971
2972 // No idle sockets, no pending jobs.
2973 EXPECT_EQ(0, pool_->IdleSocketCount());
2974 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2975
2976 // Create a second socket to the same host, but this one will wait.
2977 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2978 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132979 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542980 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152981 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202982 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:262983 // No idle sockets, and one connecting job.
2984 EXPECT_EQ(0, pool_->IdleSocketCount());
2985 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2986
2987 // Return the first handle to the pool. This will initiate the delayed
2988 // binding.
2989 handle1.Reset();
2990
fdoray5eeb7642016-06-22 16:11:282991 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262992
2993 // Still no idle sockets, still one pending connect job.
2994 EXPECT_EQ(0, pool_->IdleSocketCount());
2995 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2996
2997 // The second socket connected, even though it was a Waiting Job.
robpercival214763f2016-07-01 23:27:012998 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:262999
3000 // And we can see there is still one job waiting.
3001 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3002
3003 // Finally, signal the waiting Connect.
3004 client_socket_factory_.SignalJobs();
3005 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3006
fdoray5eeb7642016-06-22 16:11:283007 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263008}
3009
[email protected]2abfe90a2010-08-25 17:49:513010// Cover the case where on an available socket slot, we have one pending
3011// request that completes synchronously, thereby making the Group empty.
3012TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
3013 const int kUnlimitedSockets = 100;
3014 const int kOneSocketPerGroup = 1;
3015 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
3016
3017 // Make the first request asynchronous fail.
3018 // This will free up a socket slot later.
3019 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
3020
3021 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523022 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203023 EXPECT_EQ(
3024 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543025 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203026 ClientSocketPool::RespectLimits::ENABLED,
3027 callback1.callback(), pool_.get(), NetLogWithSource()));
[email protected]2abfe90a2010-08-25 17:49:513028 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3029
3030 // Make the second request synchronously fail. This should make the Group
3031 // empty.
3032 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3033 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523034 TestCompletionCallback callback2;
[email protected]2abfe90a2010-08-25 17:49:513035 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
3036 // when created.
tfarina428341112016-09-22 13:38:203037 EXPECT_EQ(
3038 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543039 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203040 ClientSocketPool::RespectLimits::ENABLED,
3041 callback2.callback(), pool_.get(), NetLogWithSource()));
[email protected]2abfe90a2010-08-25 17:49:513042
3043 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3044
robpercival214763f2016-07-01 23:27:013045 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
3046 EXPECT_THAT(callback2.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]2abfe90a2010-08-25 17:49:513047 EXPECT_FALSE(pool_->HasGroup("a"));
3048}
3049
[email protected]e1b54dc2010-10-06 21:27:223050TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
3051 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3052
3053 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3054
3055 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523056 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203057 EXPECT_EQ(
3058 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543059 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203060 ClientSocketPool::RespectLimits::ENABLED,
3061 callback1.callback(), pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223062
3063 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523064 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203065 EXPECT_EQ(
3066 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543067 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203068 ClientSocketPool::RespectLimits::ENABLED,
3069 callback2.callback(), pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223070 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:523071 TestCompletionCallback callback3;
tfarina428341112016-09-22 13:38:203072 EXPECT_EQ(
3073 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543074 handle3.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203075 ClientSocketPool::RespectLimits::ENABLED,
3076 callback3.callback(), pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223077
robpercival214763f2016-07-01 23:27:013078 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3079 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3080 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]e1b54dc2010-10-06 21:27:223081
3082 // Use the socket.
Bence Békybdbb0e72018-08-07 21:42:593083 EXPECT_EQ(1, handle1.socket()->Write(NULL, 1, CompletionOnceCallback(),
Ramin Halavati0a08cc82018-02-06 07:46:383084 TRAFFIC_ANNOTATION_FOR_TESTS));
Bence Békybdbb0e72018-08-07 21:42:593085 EXPECT_EQ(1, handle3.socket()->Write(NULL, 1, CompletionOnceCallback(),
Ramin Halavati0a08cc82018-02-06 07:46:383086 TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]e1b54dc2010-10-06 21:27:223087
3088 handle1.Reset();
3089 handle2.Reset();
3090 handle3.Reset();
3091
tfarina428341112016-09-22 13:38:203092 EXPECT_EQ(
Paul Jensen8d6f87ec2018-01-13 00:46:543093 OK, handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203094 ClientSocketPool::RespectLimits::ENABLED,
3095 callback1.callback(), pool_.get(), NetLogWithSource()));
3096 EXPECT_EQ(
Paul Jensen8d6f87ec2018-01-13 00:46:543097 OK, handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203098 ClientSocketPool::RespectLimits::ENABLED,
3099 callback2.callback(), pool_.get(), NetLogWithSource()));
3100 EXPECT_EQ(
Paul Jensen8d6f87ec2018-01-13 00:46:543101 OK, handle3.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203102 ClientSocketPool::RespectLimits::ENABLED,
3103 callback3.callback(), pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223104
3105 EXPECT_TRUE(handle1.socket()->WasEverUsed());
3106 EXPECT_TRUE(handle2.socket()->WasEverUsed());
3107 EXPECT_FALSE(handle3.socket()->WasEverUsed());
3108}
3109
[email protected]2c2bef152010-10-13 00:55:033110TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
3111 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3112 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3113
Charlie Harrison55ce6082018-05-14 02:25:573114 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033115
3116 ASSERT_TRUE(pool_->HasGroup("a"));
3117 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433118 EXPECT_EQ(2, pool_->NumNeverAssignedConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103119 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033120 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3121
3122 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523123 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203124 EXPECT_EQ(
3125 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543126 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203127 ClientSocketPool::RespectLimits::ENABLED,
3128 callback1.callback(), pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033129
3130 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523131 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203132 EXPECT_EQ(
3133 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543134 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203135 ClientSocketPool::RespectLimits::ENABLED,
3136 callback2.callback(), pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033137
3138 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433139 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103140 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033141 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3142
robpercival214763f2016-07-01 23:27:013143 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3144 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033145 handle1.Reset();
3146 handle2.Reset();
3147
3148 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433149 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103150 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033151 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3152}
3153
3154TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
3155 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3156 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3157
3158 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523159 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203160 EXPECT_EQ(
3161 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543162 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203163 ClientSocketPool::RespectLimits::ENABLED,
3164 callback1.callback(), pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033165
3166 ASSERT_TRUE(pool_->HasGroup("a"));
3167 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433168 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103169 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033170 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3171
Charlie Harrison55ce6082018-05-14 02:25:573172 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033173
3174 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433175 EXPECT_EQ(1, pool_->NumNeverAssignedConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103176 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033177 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3178
3179 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523180 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203181 EXPECT_EQ(
3182 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543183 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203184 ClientSocketPool::RespectLimits::ENABLED,
3185 callback2.callback(), pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033186
3187 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433188 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("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(0, pool_->IdleSocketCountInGroup("a"));
3191
robpercival214763f2016-07-01 23:27:013192 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3193 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033194 handle1.Reset();
3195 handle2.Reset();
3196
3197 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433198 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103199 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033200 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3201}
3202
3203TEST_F(ClientSocketPoolBaseTest,
3204 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
3205 CreatePool(4, 4);
3206 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3207
3208 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523209 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203210 EXPECT_EQ(
3211 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543212 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203213 ClientSocketPool::RespectLimits::ENABLED,
3214 callback1.callback(), pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033215
3216 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523217 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203218 EXPECT_EQ(
3219 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543220 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203221 ClientSocketPool::RespectLimits::ENABLED,
3222 callback2.callback(), pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033223
3224 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:523225 TestCompletionCallback callback3;
tfarina428341112016-09-22 13:38:203226 EXPECT_EQ(
3227 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543228 handle3.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203229 ClientSocketPool::RespectLimits::ENABLED,
3230 callback3.callback(), pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033231
3232 ASSERT_TRUE(pool_->HasGroup("a"));
3233 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433234 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103235 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033236 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3237
Charlie Harrison55ce6082018-05-14 02:25:573238 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033239
3240 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433241 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("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(0, pool_->IdleSocketCountInGroup("a"));
3244
robpercival214763f2016-07-01 23:27:013245 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3246 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3247 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033248 handle1.Reset();
3249 handle2.Reset();
3250 handle3.Reset();
3251
3252 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433253 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103254 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033255 EXPECT_EQ(3, pool_->IdleSocketCountInGroup("a"));
3256}
3257
3258TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
3259 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3260 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3261
3262 ASSERT_FALSE(pool_->HasGroup("a"));
3263
Charlie Harrison55ce6082018-05-14 02:25:573264 pool_->RequestSockets("a", &params_, kDefaultMaxSockets, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033265
3266 ASSERT_TRUE(pool_->HasGroup("a"));
3267 EXPECT_EQ(kDefaultMaxSockets, pool_->NumConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433268 EXPECT_EQ(kDefaultMaxSockets, pool_->NumNeverAssignedConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103269 EXPECT_EQ(kDefaultMaxSockets, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033270
3271 ASSERT_FALSE(pool_->HasGroup("b"));
3272
Charlie Harrison55ce6082018-05-14 02:25:573273 pool_->RequestSockets("b", &params_, kDefaultMaxSockets, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033274
3275 ASSERT_FALSE(pool_->HasGroup("b"));
3276}
3277
3278TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
3279 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3280 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3281
3282 ASSERT_FALSE(pool_->HasGroup("a"));
3283
3284 pool_->RequestSockets("a", &params_, kDefaultMaxSockets - 1,
Charlie Harrison55ce6082018-05-14 02:25:573285 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033286
3287 ASSERT_TRUE(pool_->HasGroup("a"));
3288 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103289 EXPECT_EQ(kDefaultMaxSockets - 1,
Lily Chenecebf932018-11-02 17:15:433290 pool_->NumNeverAssignedConnectJobsInGroup("a"));
3291 EXPECT_EQ(kDefaultMaxSockets - 1,
[email protected]8159a1c2012-06-07 00:00:103292 pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]51fdc7c2012-04-10 19:19:483293 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033294
3295 ASSERT_FALSE(pool_->HasGroup("b"));
3296
Charlie Harrison55ce6082018-05-14 02:25:573297 pool_->RequestSockets("b", &params_, kDefaultMaxSockets, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033298
3299 ASSERT_TRUE(pool_->HasGroup("b"));
3300 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("b"));
[email protected]51fdc7c2012-04-10 19:19:483301 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033302}
3303
3304TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
3305 CreatePool(4, 4);
3306 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3307
3308 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523309 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203310 EXPECT_EQ(
3311 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543312 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203313 ClientSocketPool::RespectLimits::ENABLED,
3314 callback1.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013315 ASSERT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033316 handle1.Reset();
3317
3318 ASSERT_TRUE(pool_->HasGroup("a"));
3319 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433320 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103321 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033322 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3323
Charlie Harrison55ce6082018-05-14 02:25:573324 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033325
3326 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433327 EXPECT_EQ(1, pool_->NumNeverAssignedConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103328 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033329 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3330}
3331
3332TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
3333 CreatePool(4, 4);
3334 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3335
3336 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523337 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203338 EXPECT_EQ(
3339 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543340 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203341 ClientSocketPool::RespectLimits::ENABLED,
3342 callback1.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013343 ASSERT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033344
3345 ASSERT_TRUE(pool_->HasGroup("a"));
3346 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433347 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103348 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033349 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3350 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3351
Charlie Harrison55ce6082018-05-14 02:25:573352 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033353
3354 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433355 EXPECT_EQ(1, pool_->NumNeverAssignedConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103356 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033357 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3358 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3359}
3360
3361TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
3362 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3363 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3364
3365 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
Charlie Harrison55ce6082018-05-14 02:25:573366 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033367
3368 ASSERT_TRUE(pool_->HasGroup("a"));
3369 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433370 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103371 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033372 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("a"));
3373
3374 pool_->RequestSockets("b", &params_, kDefaultMaxSocketsPerGroup,
Charlie Harrison55ce6082018-05-14 02:25:573375 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033376
3377 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
Lily Chenecebf932018-11-02 17:15:433378 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103379 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]2c2bef152010-10-13 00:55:033380 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("b"));
3381}
3382
[email protected]3c819f522010-12-02 02:03:123383TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
3384 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3385 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3386
3387 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
Charlie Harrison55ce6082018-05-14 02:25:573388 NetLogWithSource());
[email protected]3c819f522010-12-02 02:03:123389
3390 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]fd2e53e2011-01-14 20:40:523391
3392 connect_job_factory_->set_job_type(
3393 TestConnectJob::kMockAdditionalErrorStateJob);
3394 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
Charlie Harrison55ce6082018-05-14 02:25:573395 NetLogWithSource());
[email protected]fd2e53e2011-01-14 20:40:523396
3397 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]3c819f522010-12-02 02:03:123398}
3399
[email protected]8159a1c2012-06-07 00:00:103400TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
[email protected]2c2bef152010-10-13 00:55:033401 CreatePool(4, 4);
Lily Chenecebf932018-11-02 17:15:433402 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]2c2bef152010-10-13 00:55:033403
Charlie Harrison55ce6082018-05-14 02:25:573404 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033405
3406 ASSERT_TRUE(pool_->HasGroup("a"));
3407 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433408 EXPECT_EQ(2, pool_->NumNeverAssignedConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103409 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433410 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033411 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3412
Charlie Harrison55ce6082018-05-14 02:25:573413 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033414 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433415 EXPECT_EQ(2, pool_->NumNeverAssignedConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103416 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433417 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033418 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3419
3420 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523421 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203422 EXPECT_EQ(
3423 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543424 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203425 ClientSocketPool::RespectLimits::ENABLED,
3426 callback1.callback(), pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:433427
3428 client_socket_factory_.SignalJob(0);
3429 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3430
3431 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3432 EXPECT_EQ(1, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3433 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
3434 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3435 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033436
3437 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523438 TestCompletionCallback callback2;
Lily Chenecebf932018-11-02 17:15:433439 EXPECT_EQ(
3440 ERR_IO_PENDING,
3441 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3442 ClientSocketPool::RespectLimits::ENABLED,
3443 callback2.callback(), pool_.get(), NetLogWithSource()));
3444 client_socket_factory_.SignalJob(0);
3445 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033446
[email protected]8159a1c2012-06-07 00:00:103447 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433448 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103449 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3450 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("a"));
3451 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3452
[email protected]2c2bef152010-10-13 00:55:033453 handle1.Reset();
3454 handle2.Reset();
3455
[email protected]8159a1c2012-06-07 00:00:103456 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433457 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103458 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433459 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033460 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3461
Charlie Harrison55ce6082018-05-14 02:25:573462 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033463 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433464 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103465 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433466 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033467 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3468}
3469
3470TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
3471 CreatePool(4, 4);
3472 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3473
Charlie Harrison55ce6082018-05-14 02:25:573474 pool_->RequestSockets("a", &params_, 1, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033475
3476 ASSERT_TRUE(pool_->HasGroup("a"));
3477 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433478 EXPECT_EQ(1, pool_->NumNeverAssignedConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103479 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033480 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3481
Charlie Harrison55ce6082018-05-14 02:25:573482 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033483 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433484 EXPECT_EQ(2, pool_->NumNeverAssignedConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103485 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033486 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3487
Charlie Harrison55ce6082018-05-14 02:25:573488 pool_->RequestSockets("a", &params_, 3, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033489 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433490 EXPECT_EQ(3, pool_->NumNeverAssignedConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103491 EXPECT_EQ(3, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033492 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3493
Charlie Harrison55ce6082018-05-14 02:25:573494 pool_->RequestSockets("a", &params_, 1, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033495 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433496 EXPECT_EQ(3, pool_->NumNeverAssignedConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103497 EXPECT_EQ(3, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033498 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3499}
3500
3501TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
3502 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
Lily Chenecebf932018-11-02 17:15:433503 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]2c2bef152010-10-13 00:55:033504
Charlie Harrison55ce6082018-05-14 02:25:573505 pool_->RequestSockets("a", &params_, 1, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033506
3507 ASSERT_TRUE(pool_->HasGroup("a"));
3508 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433509 EXPECT_EQ(1, pool_->NumNeverAssignedConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103510 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033511 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3512
3513 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523514 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203515 EXPECT_EQ(
3516 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543517 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203518 ClientSocketPool::RespectLimits::ENABLED,
3519 callback1.callback(), pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033520
3521 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433522 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103523 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033524 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3525
Lily Chenecebf932018-11-02 17:15:433526 client_socket_factory_.SignalJobs();
3527 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3528
3529 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3530 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3531 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3532 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3533 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033534
[email protected]0dc88b32014-03-26 20:12:283535 // Make sure if a preconnected socket is not fully connected when a request
[email protected]034df0f32013-01-07 23:17:483536 // starts, it has a connect start time.
3537 TestLoadTimingInfoConnectedNotReused(handle1);
[email protected]2c2bef152010-10-13 00:55:033538 handle1.Reset();
3539
3540 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3541}
3542
[email protected]034df0f32013-01-07 23:17:483543// Checks that fully connected preconnect jobs have no connect times, and are
3544// marked as reused.
3545TEST_F(ClientSocketPoolBaseTest, ConnectedPreconnectJobsHaveNoConnectTimes) {
3546 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3547 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
Charlie Harrison55ce6082018-05-14 02:25:573548 pool_->RequestSockets("a", &params_, 1, NetLogWithSource());
[email protected]034df0f32013-01-07 23:17:483549
3550 ASSERT_TRUE(pool_->HasGroup("a"));
3551 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433552 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
[email protected]034df0f32013-01-07 23:17:483553 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3554 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3555
3556 ClientSocketHandle handle;
3557 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:203558 EXPECT_EQ(OK,
Paul Jensen8d6f87ec2018-01-13 00:46:543559 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203560 ClientSocketPool::RespectLimits::ENABLED,
3561 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]034df0f32013-01-07 23:17:483562
3563 // Make sure the idle socket was used.
3564 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3565
3566 TestLoadTimingInfoConnectedReused(handle);
3567 handle.Reset();
3568 TestLoadTimingInfoNotConnected(handle);
3569}
3570
[email protected]dcbe168a2010-12-02 03:14:463571// http://crbug.com/64940 regression test.
3572TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
3573 const int kMaxTotalSockets = 3;
3574 const int kMaxSocketsPerGroup = 2;
3575 CreatePool(kMaxTotalSockets, kMaxSocketsPerGroup);
Lily Chenecebf932018-11-02 17:15:433576 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]dcbe168a2010-12-02 03:14:463577
3578 // Note that group name ordering matters here. "a" comes before "b", so
3579 // CloseOneIdleSocket() will try to close "a"'s idle socket.
3580
3581 // Set up one idle socket in "a".
3582 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523583 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203584 EXPECT_EQ(
3585 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543586 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203587 ClientSocketPool::RespectLimits::ENABLED,
3588 callback1.callback(), pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:433589 ASSERT_TRUE(pool_->HasGroup("a"));
3590 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3591 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3592 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3593 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]dcbe168a2010-12-02 03:14:463594
Lily Chenecebf932018-11-02 17:15:433595 client_socket_factory_.SignalJobs();
robpercival214763f2016-07-01 23:27:013596 ASSERT_THAT(callback1.WaitForResult(), IsOk());
Lily Chenecebf932018-11-02 17:15:433597 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3598 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3599 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3600 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3601
[email protected]dcbe168a2010-12-02 03:14:463602 handle1.Reset();
3603 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3604
3605 // Set up two active sockets in "b".
3606 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523607 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203608 EXPECT_EQ(
3609 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543610 handle1.Init("b", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203611 ClientSocketPool::RespectLimits::ENABLED,
3612 callback1.callback(), pool_.get(), NetLogWithSource()));
3613 EXPECT_EQ(
3614 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543615 handle2.Init("b", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203616 ClientSocketPool::RespectLimits::ENABLED,
3617 callback2.callback(), pool_.get(), NetLogWithSource()));
[email protected]dcbe168a2010-12-02 03:14:463618
Lily Chenecebf932018-11-02 17:15:433619 ASSERT_TRUE(pool_->HasGroup("b"));
3620 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("b"));
3621 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("b"));
3622 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
3623 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3624
3625 client_socket_factory_.SignalJobs();
robpercival214763f2016-07-01 23:27:013626 ASSERT_THAT(callback1.WaitForResult(), IsOk());
3627 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]dcbe168a2010-12-02 03:14:463628 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
Lily Chenecebf932018-11-02 17:15:433629 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103630 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463631 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3632
3633 // Now we have 1 idle socket in "a" and 2 active sockets in "b". This means
3634 // we've maxed out on sockets, since we set |kMaxTotalSockets| to 3.
3635 // Requesting 2 preconnected sockets for "a" should fail to allocate any more
3636 // sockets for "a", and "b" should still have 2 active sockets.
3637
Charlie Harrison55ce6082018-05-14 02:25:573638 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
[email protected]dcbe168a2010-12-02 03:14:463639 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433640 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103641 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]dcbe168a2010-12-02 03:14:463642 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3643 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3644 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
Lily Chenecebf932018-11-02 17:15:433645 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103646 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463647 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3648 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3649
3650 // Now release the 2 active sockets for "b". This will give us 1 idle socket
3651 // in "a" and 2 idle sockets in "b". Requesting 2 preconnected sockets for
3652 // "a" should result in closing 1 for "b".
3653 handle1.Reset();
3654 handle2.Reset();
3655 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("b"));
3656 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3657
Charlie Harrison55ce6082018-05-14 02:25:573658 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
[email protected]dcbe168a2010-12-02 03:14:463659 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433660 EXPECT_EQ(1, pool_->NumNeverAssignedConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103661 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]dcbe168a2010-12-02 03:14:463662 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3663 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3664 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
Lily Chenecebf932018-11-02 17:15:433665 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103666 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463667 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("b"));
3668 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3669}
3670
[email protected]b7b8be42011-07-12 12:46:413671TEST_F(ClientSocketPoolBaseTest, PreconnectWithoutBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073672 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3673 pool_->EnableConnectBackupJobs();
3674
3675 // Make the ConnectJob hang until it times out, shorten the timeout.
3676 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3677 connect_job_factory_->set_timeout_duration(
3678 base::TimeDelta::FromMilliseconds(500));
Charlie Harrison55ce6082018-05-14 02:25:573679 pool_->RequestSockets("a", &params_, 1, NetLogWithSource());
[email protected]a9fc8fc2011-05-10 02:41:073680 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433681 EXPECT_EQ(1, pool_->NumNeverAssignedConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103682 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073683 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073684
[email protected]b7b8be42011-07-12 12:46:413685 // Verify the backup timer doesn't create a backup job, by making
3686 // the backup job a pending job instead of a waiting job, so it
3687 // *would* complete if it were created.
[email protected]a9fc8fc2011-05-10 02:41:073688 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
skyostil4891b25b2015-06-11 11:43:453689 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
Gabriel Charetteea918012018-05-16 11:53:443690 FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated(),
[email protected]2da659e2013-05-23 20:51:343691 base::TimeDelta::FromSeconds(1));
fdoray5eeb7642016-06-22 16:11:283692 base::RunLoop().Run();
[email protected]a9fc8fc2011-05-10 02:41:073693 EXPECT_FALSE(pool_->HasGroup("a"));
3694}
3695
[email protected]b7b8be42011-07-12 12:46:413696TEST_F(ClientSocketPoolBaseTest, PreconnectWithBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073697 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3698 pool_->EnableConnectBackupJobs();
3699
3700 // Make the ConnectJob hang forever.
3701 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
Charlie Harrison55ce6082018-05-14 02:25:573702 pool_->RequestSockets("a", &params_, 1, NetLogWithSource());
[email protected]a9fc8fc2011-05-10 02:41:073703 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433704 EXPECT_EQ(1, pool_->NumNeverAssignedConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103705 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073706 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
fdoray5eeb7642016-06-22 16:11:283707 base::RunLoop().RunUntilIdle();
[email protected]a9fc8fc2011-05-10 02:41:073708
3709 // Make the backup job be a pending job, so it completes normally.
3710 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3711 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:523712 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:153713 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543714 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:153715 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:203716 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]b7b8be42011-07-12 12:46:413717 // Timer has started, but the backup connect job shouldn't be created yet.
[email protected]a9fc8fc2011-05-10 02:41:073718 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433719 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103720 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073721 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3722 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
robpercival214763f2016-07-01 23:27:013723 ASSERT_THAT(callback.WaitForResult(), IsOk());
[email protected]a9fc8fc2011-05-10 02:41:073724
3725 // The hung connect job should still be there, but everything else should be
3726 // complete.
3727 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433728 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3729 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073730 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3731 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3732}
3733
[email protected]0dc88b32014-03-26 20:12:283734// Tests that a preconnect that starts out with unread data can still be used.
3735// http://crbug.com/334467
3736TEST_F(ClientSocketPoolBaseTest, PreconnectWithUnreadData) {
3737 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3738 connect_job_factory_->set_job_type(TestConnectJob::kMockUnreadDataJob);
3739
Charlie Harrison55ce6082018-05-14 02:25:573740 pool_->RequestSockets("a", &params_, 1, NetLogWithSource());
[email protected]0dc88b32014-03-26 20:12:283741
3742 ASSERT_TRUE(pool_->HasGroup("a"));
3743 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433744 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
[email protected]0dc88b32014-03-26 20:12:283745 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3746 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3747
3748 // Fail future jobs to be sure that handle receives the preconnected socket
3749 // rather than closing it and making a new one.
3750 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3751 ClientSocketHandle handle;
3752 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:203753 EXPECT_EQ(OK,
Paul Jensen8d6f87ec2018-01-13 00:46:543754 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203755 ClientSocketPool::RespectLimits::ENABLED,
3756 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]0dc88b32014-03-26 20:12:283757
3758 ASSERT_TRUE(pool_->HasGroup("a"));
3759 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433760 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
[email protected]0dc88b32014-03-26 20:12:283761 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3762 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433763 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
[email protected]0dc88b32014-03-26 20:12:283764
3765 // Drain the pending read.
Bence Békybdbb0e72018-08-07 21:42:593766 EXPECT_EQ(1, handle.socket()->Read(NULL, 1, CompletionOnceCallback()));
[email protected]0dc88b32014-03-26 20:12:283767
3768 TestLoadTimingInfoConnectedReused(handle);
3769 handle.Reset();
3770
3771 // The socket should be usable now that it's idle again.
3772 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3773}
3774
Lily Chenecebf932018-11-02 17:15:433775TEST_F(ClientSocketPoolBaseTest, RequestGetsAssignedJob) {
3776 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3777 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3778
3779 ClientSocketHandle handle1;
3780 TestCompletionCallback callback1;
3781 EXPECT_EQ(
3782 ERR_IO_PENDING,
3783 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3784 ClientSocketPool::RespectLimits::ENABLED,
3785 callback1.callback(), pool_.get(), NetLogWithSource()));
3786
3787 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3788 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3789 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3790 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3791
3792 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle1));
3793}
3794
3795TEST_F(ClientSocketPoolBaseTest, MultipleRequestsGetAssignedJobs) {
3796 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3797 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3798
3799 ClientSocketHandle handle1;
3800 TestCompletionCallback callback1;
3801 EXPECT_EQ(
3802 ERR_IO_PENDING,
3803 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3804 ClientSocketPool::RespectLimits::ENABLED,
3805 callback1.callback(), pool_.get(), NetLogWithSource()));
3806
3807 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3808 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3809 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3810 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3811
3812 ClientSocketHandle handle2;
3813 TestCompletionCallback callback2;
3814 EXPECT_EQ(
3815 ERR_IO_PENDING,
3816 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3817 ClientSocketPool::RespectLimits::ENABLED,
3818 callback2.callback(), pool_.get(), NetLogWithSource()));
3819
3820 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3821 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3822 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3823 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3824
3825 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle1));
3826 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle2));
3827
3828 // One job completes. The other request should still have its job.
3829 client_socket_factory_.SignalJob(0);
3830 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3831
3832 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3833 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3834 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3835 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3836 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3837
3838 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle2));
3839}
3840
3841TEST_F(ClientSocketPoolBaseTest, PreconnectJobGetsAssignedToRequest) {
3842 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3843 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3844
3845 pool_->RequestSockets("a", &params_, 1, NetLogWithSource());
3846
3847 ASSERT_TRUE(pool_->HasGroup("a"));
3848 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3849 EXPECT_EQ(1, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3850 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
3851 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3852
3853 ClientSocketHandle handle1;
3854 TestCompletionCallback callback1;
3855 EXPECT_EQ(
3856 ERR_IO_PENDING,
3857 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3858 ClientSocketPool::RespectLimits::ENABLED,
3859 callback1.callback(), pool_.get(), NetLogWithSource()));
3860
3861 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3862 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3863 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3864 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3865
3866 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle1));
3867}
3868
3869TEST_F(ClientSocketPoolBaseTest, HigherPriorityRequestStealsJob) {
3870 CreatePool(kDefaultMaxSockets, 1);
3871 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3872
3873 ClientSocketHandle handle1;
3874 TestCompletionCallback callback1;
3875 EXPECT_EQ(
3876 ERR_IO_PENDING,
3877 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3878 ClientSocketPool::RespectLimits::ENABLED,
3879 callback1.callback(), pool_.get(), NetLogWithSource()));
3880
3881 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3882 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3883 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3884 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3885
3886 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle1));
3887
3888 // Insert a higher priority request
3889 ClientSocketHandle handle2;
3890 TestCompletionCallback callback2;
3891 EXPECT_EQ(
3892 ERR_IO_PENDING,
3893 handle2.Init("a", params_, HIGHEST, SocketTag(),
3894 ClientSocketPool::RespectLimits::ENABLED,
3895 callback2.callback(), pool_.get(), NetLogWithSource()));
3896
3897 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3898 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3899 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3900 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3901
3902 // The highest priority request should steal the job from the default priority
3903 // request.
3904 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle2));
3905 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle1));
3906}
3907
3908TEST_F(ClientSocketPoolBaseTest, RequestStealsJobFromLowestRequestWithJob) {
3909 CreatePool(3, 3);
3910 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3911
3912 ClientSocketHandle handle_lowest;
3913 TestCompletionCallback callback_lowest;
3914 EXPECT_EQ(ERR_IO_PENDING,
3915 handle_lowest.Init("a", params_, LOWEST, SocketTag(),
3916 ClientSocketPool::RespectLimits::ENABLED,
3917 callback_lowest.callback(), pool_.get(),
3918 NetLogWithSource()));
3919
3920 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3921 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3922 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3923 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3924
3925 ClientSocketHandle handle_highest;
3926 TestCompletionCallback callback_highest;
3927 EXPECT_EQ(ERR_IO_PENDING,
3928 handle_highest.Init("a", params_, HIGHEST, SocketTag(),
3929 ClientSocketPool::RespectLimits::ENABLED,
3930 callback_highest.callback(), pool_.get(),
3931 NetLogWithSource()));
3932
3933 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3934 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3935 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3936 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3937
3938 ClientSocketHandle handle_low;
3939 TestCompletionCallback callback_low;
3940 EXPECT_EQ(ERR_IO_PENDING,
3941 handle_low.Init("a", params_, LOW, SocketTag(),
3942 ClientSocketPool::RespectLimits::ENABLED,
3943 callback_low.callback(), pool_.get(),
3944 NetLogWithSource()));
3945
3946 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
3947 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3948 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3949 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3950
3951 ClientSocketHandle handle_lowest2;
3952 TestCompletionCallback callback_lowest2;
3953 EXPECT_EQ(ERR_IO_PENDING,
3954 handle_lowest2.Init("a", params_, LOWEST, SocketTag(),
3955 ClientSocketPool::RespectLimits::ENABLED,
3956 callback_lowest2.callback(), pool_.get(),
3957 NetLogWithSource()));
3958
3959 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
3960 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3961 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3962 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3963
3964 // The top three requests in the queue should have jobs.
3965 EXPECT_TRUE(
3966 pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle_highest));
3967 EXPECT_TRUE(
3968 pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle_low));
3969 EXPECT_TRUE(
3970 pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle_lowest));
3971 EXPECT_FALSE(
3972 pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle_lowest2));
3973
3974 // Add another request with medium priority. It should steal the job from the
3975 // lowest priority request with a job.
3976 ClientSocketHandle handle_medium;
3977 TestCompletionCallback callback_medium;
3978 EXPECT_EQ(ERR_IO_PENDING,
3979 handle_medium.Init("a", params_, MEDIUM, SocketTag(),
3980 ClientSocketPool::RespectLimits::ENABLED,
3981 callback_medium.callback(), pool_.get(),
3982 NetLogWithSource()));
3983
3984 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
3985 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3986 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3987 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3988 EXPECT_TRUE(
3989 pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle_highest));
3990 EXPECT_TRUE(
3991 pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle_medium));
3992 EXPECT_TRUE(
3993 pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle_low));
3994 EXPECT_FALSE(
3995 pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle_lowest));
3996 EXPECT_FALSE(
3997 pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle_lowest2));
3998}
3999
4000TEST_F(ClientSocketPoolBaseTest, ReprioritizeRequestStealsJob) {
4001 CreatePool(kDefaultMaxSockets, 1);
4002 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4003
4004 ClientSocketHandle handle1;
4005 TestCompletionCallback callback1;
4006 EXPECT_EQ(
4007 ERR_IO_PENDING,
4008 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
4009 ClientSocketPool::RespectLimits::ENABLED,
4010 callback1.callback(), pool_.get(), NetLogWithSource()));
4011
4012 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4013 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4014 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
4015 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
4016
4017 ClientSocketHandle handle2;
4018 TestCompletionCallback callback2;
4019 EXPECT_EQ(
4020 ERR_IO_PENDING,
4021 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
4022 ClientSocketPool::RespectLimits::ENABLED,
4023 callback2.callback(), pool_.get(), NetLogWithSource()));
4024
4025 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4026 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4027 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
4028 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
4029
4030 // The second request doesn't get a job because we are at the limit.
4031 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle1));
4032 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle2));
4033
4034 // Reprioritizing the second request places it above the first, and it steals
4035 // the job from the first request.
4036 pool_->SetPriority("a", &handle2, HIGHEST);
4037 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle2));
4038 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle1));
4039}
4040
4041TEST_F(ClientSocketPoolBaseTest, CancelRequestReassignsJob) {
4042 CreatePool(kDefaultMaxSockets, 1);
4043 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4044
4045 ClientSocketHandle handle1;
4046 TestCompletionCallback callback1;
4047 EXPECT_EQ(
4048 ERR_IO_PENDING,
4049 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
4050 ClientSocketPool::RespectLimits::ENABLED,
4051 callback1.callback(), pool_.get(), NetLogWithSource()));
4052
4053 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4054 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4055 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
4056 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
4057
4058 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle1));
4059
4060 ClientSocketHandle handle2;
4061 TestCompletionCallback callback2;
4062 EXPECT_EQ(
4063 ERR_IO_PENDING,
4064 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
4065 ClientSocketPool::RespectLimits::ENABLED,
4066 callback2.callback(), pool_.get(), NetLogWithSource()));
4067
4068 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4069 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4070 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
4071 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
4072
4073 // The second request doesn't get a job because we are the limit.
4074 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle1));
4075 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle2));
4076
4077 // The second request should get a job upon cancelling the first request.
4078 handle1.Reset();
4079 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4080 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4081 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
4082 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
4083
4084 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle2));
4085}
4086
4087TEST_F(ClientSocketPoolBaseTest, JobCompletionReassignsJob) {
4088 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4089 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4090
4091 ClientSocketHandle handle1;
4092 TestCompletionCallback callback1;
4093 EXPECT_EQ(
4094 ERR_IO_PENDING,
4095 handle1.Init("a", params_, HIGHEST, SocketTag(),
4096 ClientSocketPool::RespectLimits::ENABLED,
4097 callback1.callback(), pool_.get(), NetLogWithSource()));
4098
4099 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4100 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4101 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
4102 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
4103
4104 ClientSocketHandle handle2;
4105 TestCompletionCallback callback2;
4106 EXPECT_EQ(
4107 ERR_IO_PENDING,
4108 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
4109 ClientSocketPool::RespectLimits::ENABLED,
4110 callback2.callback(), pool_.get(), NetLogWithSource()));
4111
4112 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
4113 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4114 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
4115 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
4116
4117 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle1));
4118 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle2));
4119
4120 // The lower-priority job completes first. The higher-priority request should
4121 // get the socket, and the lower-priority request should get the remaining
4122 // job.
4123 client_socket_factory_.SignalJob(1);
4124 EXPECT_THAT(callback1.WaitForResult(), IsOk());
4125 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4126 EXPECT_EQ(0, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4127 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
4128 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
4129 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
4130 EXPECT_TRUE(handle1.socket());
4131 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle2));
4132}
4133
[email protected]043b68c82013-08-22 23:41:524134class MockLayeredPool : public HigherLayeredPool {
[email protected]58e562f2013-04-22 17:32:204135 public:
4136 MockLayeredPool(TestClientSocketPool* pool,
4137 const std::string& group_name)
4138 : pool_(pool),
[email protected]58e562f2013-04-22 17:32:204139 group_name_(group_name),
4140 can_release_connection_(true) {
[email protected]043b68c82013-08-22 23:41:524141 pool_->AddHigherLayeredPool(this);
[email protected]58e562f2013-04-22 17:32:204142 }
4143
Daniel Cheng4496d0822018-04-26 21:52:154144 ~MockLayeredPool() override { pool_->RemoveHigherLayeredPool(this); }
[email protected]58e562f2013-04-22 17:32:204145
4146 int RequestSocket(TestClientSocketPool* pool) {
mmenked3641e12016-01-28 16:06:154147 scoped_refptr<TestSocketParams> params(new TestSocketParams());
Paul Jensen8d6f87ec2018-01-13 00:46:544148 return handle_.Init(group_name_, params, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:154149 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:204150 callback_.callback(), pool, NetLogWithSource());
[email protected]58e562f2013-04-22 17:32:204151 }
4152
4153 int RequestSocketWithoutLimits(TestClientSocketPool* pool) {
mmenked3641e12016-01-28 16:06:154154 scoped_refptr<TestSocketParams> params(new TestSocketParams());
Paul Jensen8d6f87ec2018-01-13 00:46:544155 return handle_.Init(group_name_, params, MAXIMUM_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:154156 ClientSocketPool::RespectLimits::DISABLED,
tfarina428341112016-09-22 13:38:204157 callback_.callback(), pool, NetLogWithSource());
[email protected]58e562f2013-04-22 17:32:204158 }
4159
4160 bool ReleaseOneConnection() {
4161 if (!handle_.is_initialized() || !can_release_connection_) {
4162 return false;
4163 }
4164 handle_.socket()->Disconnect();
4165 handle_.Reset();
4166 return true;
4167 }
4168
4169 void set_can_release_connection(bool can_release_connection) {
4170 can_release_connection_ = can_release_connection;
4171 }
4172
4173 MOCK_METHOD0(CloseOneIdleConnection, bool());
4174
4175 private:
4176 TestClientSocketPool* const pool_;
[email protected]58e562f2013-04-22 17:32:204177 ClientSocketHandle handle_;
4178 TestCompletionCallback callback_;
4179 const std::string group_name_;
4180 bool can_release_connection_;
4181};
4182
4183TEST_F(ClientSocketPoolBaseTest, FailToCloseIdleSocketsNotHeldByLayeredPool) {
4184 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4185 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4186
4187 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
robpercival214763f2016-07-01 23:27:014188 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204189 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4190 .WillOnce(Return(false));
[email protected]043b68c82013-08-22 23:41:524191 EXPECT_FALSE(pool_->CloseOneIdleConnectionInHigherLayeredPool());
[email protected]58e562f2013-04-22 17:32:204192}
4193
4194TEST_F(ClientSocketPoolBaseTest, ForciblyCloseIdleSocketsHeldByLayeredPool) {
4195 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4196 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4197
4198 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
robpercival214763f2016-07-01 23:27:014199 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204200 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4201 .WillOnce(Invoke(&mock_layered_pool,
4202 &MockLayeredPool::ReleaseOneConnection));
[email protected]043b68c82013-08-22 23:41:524203 EXPECT_TRUE(pool_->CloseOneIdleConnectionInHigherLayeredPool());
[email protected]58e562f2013-04-22 17:32:204204}
4205
4206// Tests the basic case of closing an idle socket in a higher layered pool when
4207// a new request is issued and the lower layer pool is stalled.
4208TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsHeldByLayeredPoolWhenNeeded) {
4209 CreatePool(1, 1);
4210 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4211
4212 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
robpercival214763f2016-07-01 23:27:014213 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204214 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4215 .WillOnce(Invoke(&mock_layered_pool,
4216 &MockLayeredPool::ReleaseOneConnection));
4217 ClientSocketHandle handle;
4218 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:154219 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:544220 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:154221 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:204222 callback.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:014223 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204224}
4225
4226// Same as above, but the idle socket is in the same group as the stalled
4227// socket, and closes the only other request in its group when closing requests
4228// in higher layered pools. This generally shouldn't happen, but it may be
4229// possible if a higher level pool issues a request and the request is
4230// subsequently cancelled. Even if it's not possible, best not to crash.
4231TEST_F(ClientSocketPoolBaseTest,
4232 CloseIdleSocketsHeldByLayeredPoolWhenNeededSameGroup) {
4233 CreatePool(2, 2);
4234 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4235
4236 // Need a socket in another group for the pool to be stalled (If a group
4237 // has the maximum number of connections already, it's not stalled).
4238 ClientSocketHandle handle1;
4239 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:204240 EXPECT_EQ(
Paul Jensen8d6f87ec2018-01-13 00:46:544241 OK, handle1.Init("group1", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:204242 ClientSocketPool::RespectLimits::ENABLED,
4243 callback1.callback(), pool_.get(), NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204244
4245 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
robpercival214763f2016-07-01 23:27:014246 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204247 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4248 .WillOnce(Invoke(&mock_layered_pool,
4249 &MockLayeredPool::ReleaseOneConnection));
4250 ClientSocketHandle handle;
4251 TestCompletionCallback callback2;
mmenked3641e12016-01-28 16:06:154252 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:544253 handle.Init("group2", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:154254 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:204255 callback2.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:014256 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204257}
4258
4259// Tests the case when an idle socket can be closed when a new request is
4260// issued, and the new request belongs to a group that was previously stalled.
4261TEST_F(ClientSocketPoolBaseTest,
4262 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded) {
4263 CreatePool(2, 2);
4264 std::list<TestConnectJob::JobType> job_types;
4265 job_types.push_back(TestConnectJob::kMockJob);
4266 job_types.push_back(TestConnectJob::kMockJob);
4267 job_types.push_back(TestConnectJob::kMockJob);
4268 job_types.push_back(TestConnectJob::kMockJob);
4269 connect_job_factory_->set_job_types(&job_types);
4270
4271 ClientSocketHandle handle1;
4272 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:204273 EXPECT_EQ(
Paul Jensen8d6f87ec2018-01-13 00:46:544274 OK, handle1.Init("group1", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:204275 ClientSocketPool::RespectLimits::ENABLED,
4276 callback1.callback(), pool_.get(), NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204277
4278 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
robpercival214763f2016-07-01 23:27:014279 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204280 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4281 .WillRepeatedly(Invoke(&mock_layered_pool,
4282 &MockLayeredPool::ReleaseOneConnection));
4283 mock_layered_pool.set_can_release_connection(false);
4284
4285 // The third request is made when the socket pool is in a stalled state.
4286 ClientSocketHandle handle3;
4287 TestCompletionCallback callback3;
tfarina428341112016-09-22 13:38:204288 EXPECT_EQ(
4289 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:544290 handle3.Init("group3", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:204291 ClientSocketPool::RespectLimits::ENABLED,
4292 callback3.callback(), pool_.get(), NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204293
4294 base::RunLoop().RunUntilIdle();
4295 EXPECT_FALSE(callback3.have_result());
4296
4297 // The fourth request is made when the pool is no longer stalled. The third
4298 // request should be serviced first, since it was issued first and has the
4299 // same priority.
4300 mock_layered_pool.set_can_release_connection(true);
4301 ClientSocketHandle handle4;
4302 TestCompletionCallback callback4;
tfarina428341112016-09-22 13:38:204303 EXPECT_EQ(
4304 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:544305 handle4.Init("group3", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:204306 ClientSocketPool::RespectLimits::ENABLED,
4307 callback4.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:014308 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204309 EXPECT_FALSE(callback4.have_result());
4310
4311 // Closing a handle should free up another socket slot.
4312 handle1.Reset();
robpercival214763f2016-07-01 23:27:014313 EXPECT_THAT(callback4.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204314}
4315
4316// Tests the case when an idle socket can be closed when a new request is
4317// issued, and the new request belongs to a group that was previously stalled.
4318//
4319// The two differences from the above test are that the stalled requests are not
4320// in the same group as the layered pool's request, and the the fourth request
4321// has a higher priority than the third one, so gets a socket first.
4322TEST_F(ClientSocketPoolBaseTest,
4323 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded2) {
4324 CreatePool(2, 2);
4325 std::list<TestConnectJob::JobType> job_types;
4326 job_types.push_back(TestConnectJob::kMockJob);
4327 job_types.push_back(TestConnectJob::kMockJob);
4328 job_types.push_back(TestConnectJob::kMockJob);
4329 job_types.push_back(TestConnectJob::kMockJob);
4330 connect_job_factory_->set_job_types(&job_types);
4331
4332 ClientSocketHandle handle1;
4333 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:204334 EXPECT_EQ(
Paul Jensen8d6f87ec2018-01-13 00:46:544335 OK, handle1.Init("group1", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:204336 ClientSocketPool::RespectLimits::ENABLED,
4337 callback1.callback(), pool_.get(), NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204338
4339 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
robpercival214763f2016-07-01 23:27:014340 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204341 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4342 .WillRepeatedly(Invoke(&mock_layered_pool,
4343 &MockLayeredPool::ReleaseOneConnection));
4344 mock_layered_pool.set_can_release_connection(false);
4345
4346 // The third request is made when the socket pool is in a stalled state.
4347 ClientSocketHandle handle3;
4348 TestCompletionCallback callback3;
tfarina428341112016-09-22 13:38:204349 EXPECT_EQ(
4350 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:544351 handle3.Init("group3", params_, MEDIUM, SocketTag(),
tfarina428341112016-09-22 13:38:204352 ClientSocketPool::RespectLimits::ENABLED,
4353 callback3.callback(), pool_.get(), NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204354
4355 base::RunLoop().RunUntilIdle();
4356 EXPECT_FALSE(callback3.have_result());
4357
4358 // The fourth request is made when the pool is no longer stalled. This
4359 // request has a higher priority than the third request, so is serviced first.
4360 mock_layered_pool.set_can_release_connection(true);
4361 ClientSocketHandle handle4;
4362 TestCompletionCallback callback4;
tfarina428341112016-09-22 13:38:204363 EXPECT_EQ(
4364 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:544365 handle4.Init("group3", params_, HIGHEST, SocketTag(),
tfarina428341112016-09-22 13:38:204366 ClientSocketPool::RespectLimits::ENABLED,
4367 callback4.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:014368 EXPECT_THAT(callback4.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204369 EXPECT_FALSE(callback3.have_result());
4370
4371 // Closing a handle should free up another socket slot.
4372 handle1.Reset();
robpercival214763f2016-07-01 23:27:014373 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204374}
4375
4376TEST_F(ClientSocketPoolBaseTest,
4377 CloseMultipleIdleSocketsHeldByLayeredPoolWhenNeeded) {
4378 CreatePool(1, 1);
4379 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4380
4381 MockLayeredPool mock_layered_pool1(pool_.get(), "foo");
robpercival214763f2016-07-01 23:27:014382 EXPECT_THAT(mock_layered_pool1.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204383 EXPECT_CALL(mock_layered_pool1, CloseOneIdleConnection())
4384 .WillRepeatedly(Invoke(&mock_layered_pool1,
4385 &MockLayeredPool::ReleaseOneConnection));
4386 MockLayeredPool mock_layered_pool2(pool_.get(), "bar");
robpercival214763f2016-07-01 23:27:014387 EXPECT_THAT(mock_layered_pool2.RequestSocketWithoutLimits(pool_.get()),
4388 IsOk());
[email protected]58e562f2013-04-22 17:32:204389 EXPECT_CALL(mock_layered_pool2, CloseOneIdleConnection())
4390 .WillRepeatedly(Invoke(&mock_layered_pool2,
4391 &MockLayeredPool::ReleaseOneConnection));
4392 ClientSocketHandle handle;
4393 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:154394 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:544395 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:154396 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:204397 callback.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:014398 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204399}
4400
[email protected]b021ece62013-06-11 11:06:334401// Test that when a socket pool and group are at their limits, a request
mmenked3641e12016-01-28 16:06:154402// with RespectLimits::DISABLED triggers creation of a new socket, and gets the
4403// socket instead of a request with the same priority that was issued earlier,
4404// but has RespectLimits::ENABLED.
[email protected]b021ece62013-06-11 11:06:334405TEST_F(ClientSocketPoolBaseTest, IgnoreLimits) {
[email protected]b021ece62013-06-11 11:06:334406 CreatePool(1, 1);
4407
4408 // Issue a request to reach the socket pool limit.
mmenked3641e12016-01-28 16:06:154409 EXPECT_EQ(
4410 OK, StartRequestWithIgnoreLimits(
4411 "a", MAXIMUM_PRIORITY, ClientSocketPool::RespectLimits::ENABLED));
[email protected]b021ece62013-06-11 11:06:334412 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4413
4414 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4415
mmenked3641e12016-01-28 16:06:154416 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
4417 "a", MAXIMUM_PRIORITY,
4418 ClientSocketPool::RespectLimits::ENABLED));
[email protected]b021ece62013-06-11 11:06:334419 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4420
mmenked3641e12016-01-28 16:06:154421 // Issue a request that ignores the limits, so a new ConnectJob is
4422 // created.
4423 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
4424 "a", MAXIMUM_PRIORITY,
4425 ClientSocketPool::RespectLimits::DISABLED));
[email protected]b021ece62013-06-11 11:06:334426 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4427
robpercival214763f2016-07-01 23:27:014428 EXPECT_THAT(request(2)->WaitForResult(), IsOk());
[email protected]b021ece62013-06-11 11:06:334429 EXPECT_FALSE(request(1)->have_result());
4430}
4431
[email protected]c55fabd2013-11-04 23:26:564432// Test that when a socket pool and group are at their limits, a ConnectJob
mmenked3641e12016-01-28 16:06:154433// issued for a request with RespectLimits::DISABLED is not cancelled when a
4434// request with RespectLimits::ENABLED issued to the same group is cancelled.
[email protected]c55fabd2013-11-04 23:26:564435TEST_F(ClientSocketPoolBaseTest, IgnoreLimitsCancelOtherJob) {
[email protected]c55fabd2013-11-04 23:26:564436 CreatePool(1, 1);
4437
4438 // Issue a request to reach the socket pool limit.
mmenked3641e12016-01-28 16:06:154439 EXPECT_EQ(
4440 OK, StartRequestWithIgnoreLimits(
4441 "a", MAXIMUM_PRIORITY, ClientSocketPool::RespectLimits::ENABLED));
[email protected]c55fabd2013-11-04 23:26:564442 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4443
4444 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4445
mmenked3641e12016-01-28 16:06:154446 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
4447 "a", MAXIMUM_PRIORITY,
4448 ClientSocketPool::RespectLimits::ENABLED));
[email protected]c55fabd2013-11-04 23:26:564449 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4450
mmenked3641e12016-01-28 16:06:154451 // Issue a request with RespectLimits::DISABLED, so a new ConnectJob is
4452 // created.
4453 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
4454 "a", MAXIMUM_PRIORITY,
4455 ClientSocketPool::RespectLimits::DISABLED));
[email protected]b021ece62013-06-11 11:06:334456 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4457
mmenked3641e12016-01-28 16:06:154458 // Cancel the pending request with RespectLimits::ENABLED. The ConnectJob
[email protected]b021ece62013-06-11 11:06:334459 // should not be cancelled.
4460 request(1)->handle()->Reset();
4461 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4462
robpercival214763f2016-07-01 23:27:014463 EXPECT_THAT(request(2)->WaitForResult(), IsOk());
[email protected]b021ece62013-06-11 11:06:334464 EXPECT_FALSE(request(1)->have_result());
4465}
4466
[email protected]f6d1d6eb2009-06-24 20:16:094467} // namespace
4468
4469} // namespace net