blob: 54f1e4e5de3022067d1a2984c17f814b428b4c3f [file] [log] [blame]
[email protected]e34400c32012-01-24 02:49:331// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]f6d1d6eb2009-06-24 20:16:092// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]ab838892009-06-30 18:49:055#include "net/socket/client_socket_pool_base.h"
[email protected]f6d1d6eb2009-06-24 20:16:096
tbansalf82cc8e2015-10-14 20:05:497#include <stdint.h>
dchengc7eeda422015-12-26 03:56:488#include <utility>
[email protected]51fdc7c2012-04-10 19:19:489#include <vector>
10
[email protected]6ecf2b92011-12-15 01:14:5211#include "base/bind.h"
12#include "base/bind_helpers.h"
[email protected]2041cf342010-02-19 03:15:5913#include "base/callback.h"
skyostil4891b25b2015-06-11 11:43:4514#include "base/location.h"
mmenke33d24423d2015-05-19 19:41:0915#include "base/logging.h"
Avi Drissman13fc8932015-12-20 04:40:4616#include "base/macros.h"
[email protected]3b63f8f42011-03-28 01:54:1517#include "base/memory/ref_counted.h"
[email protected]6ea7b152011-12-21 21:21:1318#include "base/memory/weak_ptr.h"
[email protected]18b577412013-07-18 04:19:1519#include "base/message_loop/message_loop.h"
[email protected]034df0f32013-01-07 23:17:4820#include "base/run_loop.h"
skyostil4891b25b2015-06-11 11:43:4521#include "base/single_thread_task_runner.h"
[email protected]fc9be5802013-06-11 10:56:5122#include "base/strings/string_number_conversions.h"
[email protected]18b577412013-07-18 04:19:1523#include "base/strings/stringprintf.h"
[email protected]f214f8792011-01-01 02:17:0824#include "base/threading/platform_thread.h"
gabf767595f2016-05-11 18:50:3525#include "base/threading/thread_task_runner_handle.h"
[email protected]f3a1c642011-07-12 19:15:0326#include "base/values.h"
[email protected]034df0f32013-01-07 23:17:4827#include "net/base/load_timing_info.h"
[email protected]b258e0792013-01-12 07:11:5928#include "net/base/load_timing_info_test_util.h"
[email protected]d8eb84242010-09-25 02:25:0629#include "net/base/net_errors.h"
[email protected]ac790b42009-12-02 04:31:3130#include "net/base/request_priority.h"
[email protected]f6d1d6eb2009-06-24 20:16:0931#include "net/base/test_completion_callback.h"
[email protected]277d5942010-08-11 21:02:3532#include "net/http/http_response_headers.h"
eroman87c53d62015-04-02 06:51:0733#include "net/log/net_log.h"
mikecirone8b85c432016-09-08 19:11:0034#include "net/log/net_log_event_type.h"
mikecironef22f9812016-10-04 03:40:1935#include "net/log/net_log_source.h"
mikecirone8b85c432016-09-08 19:11:0036#include "net/log/net_log_source_type.h"
mmenke16a7cbdd2015-04-24 23:00:5637#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4638#include "net/log/test_net_log_entry.h"
39#include "net/log/test_net_log_util.h"
[email protected]f6d1d6eb2009-06-24 20:16:0940#include "net/socket/client_socket_factory.h"
41#include "net/socket/client_socket_handle.h"
tfarina5dd13c22016-11-16 12:08:2642#include "net/socket/datagram_client_socket.h"
tbansalca83c002016-04-28 20:56:2843#include "net/socket/socket_performance_watcher.h"
Paul Jensen8d6f87ec2018-01-13 00:46:5444#include "net/socket/socket_tag.h"
[email protected]75439d3b2009-07-23 22:11:1745#include "net/socket/socket_test_util.h"
[email protected]18ccfdb2013-08-15 00:13:4446#include "net/socket/ssl_client_socket.h"
[email protected]3268023f2011-05-05 00:08:1047#include "net/socket/stream_socket.h"
robpercival214763f2016-07-01 23:27:0148#include "net/test/gtest_util.h"
Ramin Halavati0a08cc82018-02-06 07:46:3849#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
[email protected]51fdc7c2012-04-10 19:19:4850#include "testing/gmock/include/gmock/gmock.h"
[email protected]f6d1d6eb2009-06-24 20:16:0951#include "testing/gtest/include/gtest/gtest.h"
52
robpercival214763f2016-07-01 23:27:0153using net::test::IsError;
54using net::test::IsOk;
55
[email protected]51fdc7c2012-04-10 19:19:4856using ::testing::Invoke;
57using ::testing::Return;
58
[email protected]f6d1d6eb2009-06-24 20:16:0959namespace net {
60
61namespace {
62
[email protected]211d21722009-07-22 15:48:5363const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2064const int kDefaultMaxSocketsPerGroup = 2;
[email protected]0b7648c2009-07-06 20:14:0165
[email protected]034df0f32013-01-07 23:17:4866// Make sure |handle| sets load times correctly when it has been assigned a
67// reused socket.
68void TestLoadTimingInfoConnectedReused(const ClientSocketHandle& handle) {
69 LoadTimingInfo load_timing_info;
70 // Only pass true in as |is_reused|, as in general, HttpStream types should
71 // have stricter concepts of reuse than socket pools.
72 EXPECT_TRUE(handle.GetLoadTimingInfo(true, &load_timing_info));
73
74 EXPECT_EQ(true, load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:1975 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]034df0f32013-01-07 23:17:4876
[email protected]b258e0792013-01-12 07:11:5977 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
78 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:4879}
80
81// Make sure |handle| sets load times correctly when it has been assigned a
[email protected]b021ece62013-06-11 11:06:3382// fresh socket. Also runs TestLoadTimingInfoConnectedReused, since the owner
[email protected]034df0f32013-01-07 23:17:4883// of a connection where |is_reused| is false may consider the connection
84// reused.
85void TestLoadTimingInfoConnectedNotReused(const ClientSocketHandle& handle) {
86 EXPECT_FALSE(handle.is_reused());
87
88 LoadTimingInfo load_timing_info;
89 EXPECT_TRUE(handle.GetLoadTimingInfo(false, &load_timing_info));
90
91 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:1992 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]034df0f32013-01-07 23:17:4893
[email protected]b258e0792013-01-12 07:11:5994 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
95 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
96 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:4897
98 TestLoadTimingInfoConnectedReused(handle);
99}
100
101// Make sure |handle| sets load times correctly, in the case that it does not
102// currently have a socket.
103void TestLoadTimingInfoNotConnected(const ClientSocketHandle& handle) {
104 // Should only be set to true once a socket is assigned, if at all.
105 EXPECT_FALSE(handle.is_reused());
106
107 LoadTimingInfo load_timing_info;
108 EXPECT_FALSE(handle.GetLoadTimingInfo(false, &load_timing_info));
109
110 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19111 EXPECT_EQ(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]034df0f32013-01-07 23:17:48112
[email protected]b258e0792013-01-12 07:11:59113 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
114 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:48115}
116
[email protected]df4b4ef2010-07-12 18:25:21117class TestSocketParams : public base::RefCounted<TestSocketParams> {
[email protected]5acdce12011-03-30 13:00:20118 public:
Chris Watkins7a41d3552017-12-01 02:13:27119 explicit TestSocketParams() = default;
[email protected]51fdc7c2012-04-10 19:19:48120
[email protected]df4b4ef2010-07-12 18:25:21121 private:
122 friend class base::RefCounted<TestSocketParams>;
Chris Watkins7a41d3552017-12-01 02:13:27123 ~TestSocketParams() = default;
[email protected]df4b4ef2010-07-12 18:25:21124};
[email protected]7fc5b09a2010-02-27 00:07:38125typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
[email protected]d80a4322009-08-14 07:07:49126
[email protected]3268023f2011-05-05 00:08:10127class MockClientSocket : public StreamSocket {
[email protected]f6d1d6eb2009-06-24 20:16:09128 public:
[email protected]034df0f32013-01-07 23:17:48129 explicit MockClientSocket(net::NetLog* net_log)
130 : connected_(false),
[email protected]0dc88b32014-03-26 20:12:28131 has_unread_data_(false),
tfarina428341112016-09-22 13:38:20132 net_log_(NetLogWithSource::Make(net_log, NetLogSourceType::SOCKET)),
Alexandr Ilin65ec9582017-10-02 14:50:31133 was_used_to_convey_data_(false),
134 motivation_(HttpRequestInfo::NORMAL_MOTIVATION) {}
[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
Alexandr Ilin65ec9582017-10-02 14:50:31142 HttpRequestInfo::RequestMotivation motivation() const { return motivation_; }
143
[email protected]3f55aa12011-12-07 02:03:33144 // Socket implementation.
dchengb03027d2014-10-21 12:00:20145 int Read(IOBuffer* /* buf */,
146 int len,
147 const CompletionCallback& /* callback */) override {
[email protected]0dc88b32014-03-26 20:12:28148 if (has_unread_data_ && len > 0) {
149 has_unread_data_ = false;
150 was_used_to_convey_data_ = true;
151 return 1;
152 }
[email protected]e86df8dc2013-03-30 13:18:28153 return ERR_UNEXPECTED;
[email protected]3f55aa12011-12-07 02:03:33154 }
[email protected]ab838892009-06-30 18:49:05155
[email protected]a2b2cfc2017-12-06 09:06:08156 int Write(
157 IOBuffer* /* buf */,
158 int len,
159 const CompletionCallback& /* callback */,
160 const NetworkTrafficAnnotationTag& /*traffic_annotation*/) override {
[email protected]0f873e82010-09-02 16:09:01161 was_used_to_convey_data_ = true;
162 return len;
[email protected]ab838892009-06-30 18:49:05163 }
Avi Drissman13fc8932015-12-20 04:40:46164 int SetReceiveBufferSize(int32_t size) override { return OK; }
165 int SetSendBufferSize(int32_t size) override { return OK; }
[email protected]ab838892009-06-30 18:49:05166
[email protected]dbf036f2011-12-06 23:33:24167 // StreamSocket implementation.
dchengb03027d2014-10-21 12:00:20168 int Connect(const CompletionCallback& callback) override {
[email protected]dbf036f2011-12-06 23:33:24169 connected_ = true;
170 return OK;
171 }
[email protected]f6d1d6eb2009-06-24 20:16:09172
dchengb03027d2014-10-21 12:00:20173 void Disconnect() override { connected_ = false; }
174 bool IsConnected() const override { return connected_; }
175 bool IsConnectedAndIdle() const override {
[email protected]0dc88b32014-03-26 20:12:28176 return connected_ && !has_unread_data_;
177 }
[email protected]0b7648c2009-07-06 20:14:01178
dchengb03027d2014-10-21 12:00:20179 int GetPeerAddress(IPEndPoint* /* address */) const override {
[email protected]9f864b32010-01-20 15:01:16180 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:09181 }
[email protected]f6d1d6eb2009-06-24 20:16:09182
dchengb03027d2014-10-21 12:00:20183 int GetLocalAddress(IPEndPoint* /* address */) const override {
[email protected]e7f74da2011-04-19 23:49:35184 return ERR_UNEXPECTED;
185 }
186
tfarina428341112016-09-22 13:38:20187 const NetLogWithSource& NetLog() const override { return net_log_; }
[email protected]a2006ece2010-04-23 16:44:02188
Alexandr Ilin65ec9582017-10-02 14:50:31189 void SetSubresourceSpeculation() override {
190 motivation_ = HttpRequestInfo::PRECONNECT_MOTIVATED;
191 }
192 void SetOmniboxSpeculation() override {
193 motivation_ = HttpRequestInfo::OMNIBOX_MOTIVATED;
194 }
dchengb03027d2014-10-21 12:00:20195 bool WasEverUsed() const override { return was_used_to_convey_data_; }
tfarina2846404c2016-12-25 14:31:37196 bool WasAlpnNegotiated() const override { return false; }
dchengb03027d2014-10-21 12:00:20197 NextProto GetNegotiatedProtocol() const override { return kProtoUnknown; }
198 bool GetSSLInfo(SSLInfo* ssl_info) override { return false; }
ttuttle23fdb7b2015-05-15 01:28:03199 void GetConnectionAttempts(ConnectionAttempts* out) const override {
200 out->clear();
201 }
202 void ClearConnectionAttempts() override {}
203 void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
tbansalf82cc8e2015-10-14 20:05:49204 int64_t GetTotalReceivedBytes() const override {
205 NOTIMPLEMENTED();
206 return 0;
207 }
Paul Jensen0f49dec2017-12-12 23:39:58208 void ApplySocketTag(const SocketTag& tag) override {}
[email protected]9b5614a2010-08-25 20:29:45209
[email protected]f6d1d6eb2009-06-24 20:16:09210 private:
211 bool connected_;
[email protected]0dc88b32014-03-26 20:12:28212 bool has_unread_data_;
tfarina428341112016-09-22 13:38:20213 NetLogWithSource net_log_;
[email protected]0f873e82010-09-02 16:09:01214 bool was_used_to_convey_data_;
Alexandr Ilin65ec9582017-10-02 14:50:31215 HttpRequestInfo::RequestMotivation motivation_;
[email protected]f6d1d6eb2009-06-24 20:16:09216
[email protected]ab838892009-06-30 18:49:05217 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:09218};
219
[email protected]5fc08e32009-07-15 17:09:57220class TestConnectJob;
221
[email protected]f6d1d6eb2009-06-24 20:16:09222class MockClientSocketFactory : public ClientSocketFactory {
223 public:
[email protected]ab838892009-06-30 18:49:05224 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:09225
danakj655b66c2016-04-16 00:51:38226 std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
[email protected]5370c012011-06-29 03:47:04227 DatagramSocket::BindType bind_type,
[email protected]98b0e582011-06-22 14:31:41228 NetLog* net_log,
mikecironef22f9812016-10-04 03:40:19229 const NetLogSource& source) override {
[email protected]98b0e582011-06-22 14:31:41230 NOTREACHED();
danakj655b66c2016-04-16 00:51:38231 return std::unique_ptr<DatagramClientSocket>();
[email protected]98b0e582011-06-22 14:31:41232 }
233
Helen Lid5bb9222018-04-12 15:33:09234 std::unique_ptr<TransportClientSocket> CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07235 const AddressList& addresses,
danakj655b66c2016-04-16 00:51:38236 std::unique_ptr<
237 SocketPerformanceWatcher> /* socket_performance_watcher */,
[email protected]0a0b7682010-08-25 17:08:07238 NetLog* /* net_log */,
mikecironef22f9812016-10-04 03:40:19239 const NetLogSource& /*source*/) override {
[email protected]f6d1d6eb2009-06-24 20:16:09240 allocation_count_++;
Helen Lid5bb9222018-04-12 15:33:09241 return nullptr;
[email protected]f6d1d6eb2009-06-24 20:16:09242 }
243
danakj655b66c2016-04-16 00:51:38244 std::unique_ptr<SSLClientSocket> CreateSSLClientSocket(
245 std::unique_ptr<ClientSocketHandle> transport_socket,
[email protected]4f4de7e62010-11-12 19:55:27246 const HostPortPair& host_and_port,
[email protected]7ab5bbd12010-10-19 13:33:21247 const SSLConfig& ssl_config,
mostynbba063d6032014-10-09 11:01:13248 const SSLClientSocketContext& context) override {
[email protected]f6d1d6eb2009-06-24 20:16:09249 NOTIMPLEMENTED();
danakj655b66c2016-04-16 00:51:38250 return std::unique_ptr<SSLClientSocket>();
[email protected]f6d1d6eb2009-06-24 20:16:09251 }
252
dchengb03027d2014-10-21 12:00:20253 void ClearSSLSessionCache() override { NOTIMPLEMENTED(); }
[email protected]25f47352011-02-25 16:31:59254
[email protected]5fc08e32009-07-15 17:09:57255 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
[email protected]03b7c8c2013-07-20 04:38:55256
[email protected]5fc08e32009-07-15 17:09:57257 void SignalJobs();
258
[email protected]03b7c8c2013-07-20 04:38:55259 void SignalJob(size_t job);
260
261 void SetJobLoadState(size_t job, LoadState load_state);
262
[email protected]f6d1d6eb2009-06-24 20:16:09263 int allocation_count() const { return allocation_count_; }
264
[email protected]f6d1d6eb2009-06-24 20:16:09265 private:
266 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:57267 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09268};
269
[email protected]ab838892009-06-30 18:49:05270class TestConnectJob : public ConnectJob {
271 public:
272 enum JobType {
273 kMockJob,
274 kMockFailingJob,
275 kMockPendingJob,
276 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57277 kMockWaitingJob,
[email protected]e772db3f2010-07-12 18:11:13278 kMockRecoverableJob,
279 kMockPendingRecoverableJob,
[email protected]e60e47a2010-07-14 03:37:18280 kMockAdditionalErrorStateJob,
281 kMockPendingAdditionalErrorStateJob,
[email protected]0dc88b32014-03-26 20:12:28282 kMockUnreadDataJob,
[email protected]ab838892009-06-30 18:49:05283 };
284
[email protected]994d4932010-07-12 17:55:13285 // The kMockPendingJob uses a slight delay before allowing the connect
286 // to complete.
287 static const int kPendingConnectDelay = 2;
288
[email protected]ab838892009-06-30 18:49:05289 TestConnectJob(JobType job_type,
290 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49291 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34292 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05293 ConnectJob::Delegate* delegate,
[email protected]fd7b7c92009-08-20 19:38:30294 MockClientSocketFactory* client_socket_factory,
[email protected]06650c52010-06-03 00:49:17295 NetLog* net_log)
tfarina428341112016-09-22 13:38:20296 : ConnectJob(
297 group_name,
298 timeout_duration,
299 request.priority(),
Paul Jensen8d6f87ec2018-01-13 00:46:54300 request.socket_tag(),
tfarina428341112016-09-22 13:38:20301 request.respect_limits(),
302 delegate,
davidbenb7048f092016-11-30 21:20:26303 NetLogWithSource::Make(net_log,
304 NetLogSourceType::TRANSPORT_CONNECT_JOB)),
[email protected]2ab05b52009-07-01 23:57:58305 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05306 client_socket_factory_(client_socket_factory),
[email protected]e60e47a2010-07-14 03:37:18307 load_state_(LOAD_STATE_IDLE),
[email protected]d5492c52013-11-10 20:44:39308 store_additional_error_state_(false),
mmenked3641e12016-01-28 16:06:15309 weak_factory_(this) {}
[email protected]ab838892009-06-30 18:49:05310
[email protected]974ebd62009-08-03 23:14:34311 void Signal() {
[email protected]e772db3f2010-07-12 18:11:13312 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
[email protected]974ebd62009-08-03 23:14:34313 }
314
[email protected]03b7c8c2013-07-20 04:38:55315 void set_load_state(LoadState load_state) { load_state_ = load_state; }
316
317 // From ConnectJob:
318
dchengb03027d2014-10-21 12:00:20319 LoadState GetLoadState() const override { return load_state_; }
[email protected]46451352009-09-01 14:54:21320
dchengb03027d2014-10-21 12:00:20321 void GetAdditionalErrorState(ClientSocketHandle* handle) override {
[email protected]e60e47a2010-07-14 03:37:18322 if (store_additional_error_state_) {
323 // Set all of the additional error state fields in some way.
324 handle->set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43325 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:45326 info.headers = new HttpResponseHeaders(std::string());
[email protected]8b498692010-07-16 17:11:43327 handle->set_ssl_error_response_info(info);
[email protected]e60e47a2010-07-14 03:37:18328 }
329 }
330
[email protected]974ebd62009-08-03 23:14:34331 private:
[email protected]03b7c8c2013-07-20 04:38:55332 // From ConnectJob:
[email protected]ab838892009-06-30 18:49:05333
dchengb03027d2014-10-21 12:00:20334 int ConnectInternal() override {
[email protected]ab838892009-06-30 18:49:05335 AddressList ignored;
tbansal7b403bcc2016-04-13 22:33:21336 client_socket_factory_->CreateTransportClientSocket(ignored, NULL, NULL,
mikecironef22f9812016-10-04 03:40:19337 NetLogSource());
danakj655b66c2016-04-16 00:51:38338 SetSocket(std::unique_ptr<StreamSocket>(
339 new MockClientSocket(net_log().net_log())));
[email protected]ab838892009-06-30 18:49:05340 switch (job_type_) {
341 case kMockJob:
[email protected]e772db3f2010-07-12 18:11:13342 return DoConnect(true /* successful */, false /* sync */,
343 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05344 case kMockFailingJob:
[email protected]e772db3f2010-07-12 18:11:13345 return DoConnect(false /* error */, false /* sync */,
346 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05347 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57348 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47349
350 // Depending on execution timings, posting a delayed task can result
351 // in the task getting executed the at the earliest possible
352 // opportunity or only after returning once from the message loop and
353 // then a second call into the message loop. In order to make behavior
354 // more deterministic, we change the default delay to 2ms. This should
355 // always require us to wait for the second call into the message loop.
356 //
357 // N.B. The correct fix for this and similar timing problems is to
358 // abstract time for the purpose of unittests. Unfortunately, we have
359 // a lot of third-party components that directly call the various
360 // time functions, so this change would be rather invasive.
skyostil4891b25b2015-06-11 11:43:45361 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05362 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13363 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
skyostil4891b25b2015-06-11 11:43:45364 weak_factory_.GetWeakPtr(), true /* successful */,
365 true /* async */, false /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53366 base::TimeDelta::FromMilliseconds(kPendingConnectDelay));
[email protected]ab838892009-06-30 18:49:05367 return ERR_IO_PENDING;
368 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57369 set_load_state(LOAD_STATE_CONNECTING);
skyostil4891b25b2015-06-11 11:43:45370 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05371 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13372 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
skyostil4891b25b2015-06-11 11:43:45373 weak_factory_.GetWeakPtr(), false /* error */,
374 true /* async */, false /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53375 base::TimeDelta::FromMilliseconds(2));
[email protected]ab838892009-06-30 18:49:05376 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57377 case kMockWaitingJob:
[email protected]03b7c8c2013-07-20 04:38:55378 set_load_state(LOAD_STATE_CONNECTING);
[email protected]5fc08e32009-07-15 17:09:57379 client_socket_factory_->WaitForSignal(this);
380 waiting_success_ = true;
381 return ERR_IO_PENDING;
[email protected]e772db3f2010-07-12 18:11:13382 case kMockRecoverableJob:
383 return DoConnect(false /* error */, false /* sync */,
384 true /* recoverable */);
385 case kMockPendingRecoverableJob:
386 set_load_state(LOAD_STATE_CONNECTING);
skyostil4891b25b2015-06-11 11:43:45387 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]e772db3f2010-07-12 18:11:13388 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13389 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
skyostil4891b25b2015-06-11 11:43:45390 weak_factory_.GetWeakPtr(), false /* error */,
391 true /* async */, true /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53392 base::TimeDelta::FromMilliseconds(2));
[email protected]e772db3f2010-07-12 18:11:13393 return ERR_IO_PENDING;
[email protected]e60e47a2010-07-14 03:37:18394 case kMockAdditionalErrorStateJob:
395 store_additional_error_state_ = true;
396 return DoConnect(false /* error */, false /* sync */,
397 false /* recoverable */);
398 case kMockPendingAdditionalErrorStateJob:
399 set_load_state(LOAD_STATE_CONNECTING);
400 store_additional_error_state_ = true;
skyostil4891b25b2015-06-11 11:43:45401 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]e60e47a2010-07-14 03:37:18402 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13403 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
skyostil4891b25b2015-06-11 11:43:45404 weak_factory_.GetWeakPtr(), false /* error */,
405 true /* async */, false /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53406 base::TimeDelta::FromMilliseconds(2));
[email protected]e60e47a2010-07-14 03:37:18407 return ERR_IO_PENDING;
[email protected]0dc88b32014-03-26 20:12:28408 case kMockUnreadDataJob: {
409 int ret = DoConnect(true /* successful */, false /* sync */,
410 false /* recoverable */);
411 static_cast<MockClientSocket*>(socket())->set_has_unread_data(true);
412 return ret;
413 }
[email protected]ab838892009-06-30 18:49:05414 default:
415 NOTREACHED();
danakj655b66c2016-04-16 00:51:38416 SetSocket(std::unique_ptr<StreamSocket>());
[email protected]ab838892009-06-30 18:49:05417 return ERR_FAILED;
418 }
419 }
420
[email protected]e772db3f2010-07-12 18:11:13421 int DoConnect(bool succeed, bool was_async, bool recoverable) {
422 int result = OK;
[email protected]ab838892009-06-30 18:49:05423 if (succeed) {
[email protected]83039bb2011-12-09 18:43:55424 socket()->Connect(CompletionCallback());
[email protected]e772db3f2010-07-12 18:11:13425 } else if (recoverable) {
426 result = ERR_PROXY_AUTH_REQUESTED;
[email protected]6e713f02009-08-06 02:56:40427 } else {
[email protected]e772db3f2010-07-12 18:11:13428 result = ERR_CONNECTION_FAILED;
danakj655b66c2016-04-16 00:51:38429 SetSocket(std::unique_ptr<StreamSocket>());
[email protected]ab838892009-06-30 18:49:05430 }
[email protected]2ab05b52009-07-01 23:57:58431
432 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30433 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05434 return result;
435 }
436
[email protected]5fc08e32009-07-15 17:09:57437 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05438 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57439 MockClientSocketFactory* const client_socket_factory_;
[email protected]46451352009-09-01 14:54:21440 LoadState load_state_;
[email protected]e60e47a2010-07-14 03:37:18441 bool store_additional_error_state_;
[email protected]ab838892009-06-30 18:49:05442
[email protected]d5492c52013-11-10 20:44:39443 base::WeakPtrFactory<TestConnectJob> weak_factory_;
444
[email protected]ab838892009-06-30 18:49:05445 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
446};
447
[email protected]d80a4322009-08-14 07:07:49448class TestConnectJobFactory
449 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05450 public:
[email protected]034df0f32013-01-07 23:17:48451 TestConnectJobFactory(MockClientSocketFactory* client_socket_factory,
452 NetLog* net_log)
[email protected]ab838892009-06-30 18:49:05453 : job_type_(TestConnectJob::kMockJob),
[email protected]51fdc7c2012-04-10 19:19:48454 job_types_(NULL),
[email protected]034df0f32013-01-07 23:17:48455 client_socket_factory_(client_socket_factory),
456 net_log_(net_log) {
[email protected]b021ece62013-06-11 11:06:33457 }
[email protected]ab838892009-06-30 18:49:05458
Chris Watkins7a41d3552017-12-01 02:13:27459 ~TestConnectJobFactory() override = default;
[email protected]ab838892009-06-30 18:49:05460
461 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
462
[email protected]51fdc7c2012-04-10 19:19:48463 void set_job_types(std::list<TestConnectJob::JobType>* job_types) {
464 job_types_ = job_types;
465 CHECK(!job_types_->empty());
466 }
467
[email protected]974ebd62009-08-03 23:14:34468 void set_timeout_duration(base::TimeDelta timeout_duration) {
469 timeout_duration_ = timeout_duration;
470 }
471
[email protected]3f55aa12011-12-07 02:03:33472 // ConnectJobFactory implementation.
[email protected]83039bb2011-12-09 18:43:55473
danakj655b66c2016-04-16 00:51:38474 std::unique_ptr<ConnectJob> NewConnectJob(
[email protected]ab838892009-06-30 18:49:05475 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49476 const TestClientSocketPoolBase::Request& request,
mostynbba063d6032014-10-09 11:01:13477 ConnectJob::Delegate* delegate) const override {
[email protected]51fdc7c2012-04-10 19:19:48478 EXPECT_TRUE(!job_types_ || !job_types_->empty());
479 TestConnectJob::JobType job_type = job_type_;
480 if (job_types_ && !job_types_->empty()) {
481 job_type = job_types_->front();
482 job_types_->pop_front();
483 }
danakj655b66c2016-04-16 00:51:38484 return std::unique_ptr<ConnectJob>(
485 new TestConnectJob(job_type, group_name, request, timeout_duration_,
486 delegate, client_socket_factory_, net_log_));
[email protected]ab838892009-06-30 18:49:05487 }
488
dchengb03027d2014-10-21 12:00:20489 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26490 return timeout_duration_;
491 }
492
[email protected]ab838892009-06-30 18:49:05493 private:
494 TestConnectJob::JobType job_type_;
[email protected]51fdc7c2012-04-10 19:19:48495 std::list<TestConnectJob::JobType>* job_types_;
[email protected]974ebd62009-08-03 23:14:34496 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57497 MockClientSocketFactory* const client_socket_factory_;
[email protected]034df0f32013-01-07 23:17:48498 NetLog* net_log_;
[email protected]ab838892009-06-30 18:49:05499
500 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
501};
502
503class TestClientSocketPool : public ClientSocketPool {
504 public:
[email protected]12322e7e2013-08-15 17:49:26505 typedef TestSocketParams SocketParams;
506
[email protected]ab838892009-06-30 18:49:05507 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53508 int max_sockets,
[email protected]ab838892009-06-30 18:49:05509 int max_sockets_per_group,
[email protected]9bf28db2009-08-29 01:35:16510 base::TimeDelta unused_idle_socket_timeout,
511 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49512 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
rkaplowd90695c2015-03-25 22:12:41513 : base_(NULL,
514 max_sockets,
515 max_sockets_per_group,
516 unused_idle_socket_timeout,
517 used_idle_socket_timeout,
[email protected]66761b952010-06-25 21:30:38518 connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05519
Chris Watkins7a41d3552017-12-01 02:13:27520 ~TestClientSocketPool() override = default;
[email protected]2431756e2010-09-29 20:26:13521
dchengb03027d2014-10-21 12:00:20522 int RequestSocket(const std::string& group_name,
523 const void* params,
ttuttle859dc7a2015-04-23 19:42:29524 RequestPriority priority,
Paul Jensen8d6f87ec2018-01-13 00:46:54525 const SocketTag& socket_tag,
mmenked3641e12016-01-28 16:06:15526 RespectLimits respect_limits,
dchengb03027d2014-10-21 12:00:20527 ClientSocketHandle* handle,
528 const CompletionCallback& callback,
tfarina428341112016-09-22 13:38:20529 const NetLogWithSource& net_log) override {
[email protected]df4b4ef2010-07-12 18:25:21530 const scoped_refptr<TestSocketParams>* casted_socket_params =
531 static_cast<const scoped_refptr<TestSocketParams>*>(params);
532 return base_.RequestSocket(group_name, *casted_socket_params, priority,
Paul Jensen8d6f87ec2018-01-13 00:46:54533 socket_tag, respect_limits, handle, callback,
534 net_log);
[email protected]ab838892009-06-30 18:49:05535 }
536
dchengb03027d2014-10-21 12:00:20537 void RequestSockets(const std::string& group_name,
538 const void* params,
539 int num_sockets,
Alexandr Ilin65ec9582017-10-02 14:50:31540 const NetLogWithSource& net_log,
541 HttpRequestInfo::RequestMotivation motivation) override {
[email protected]2c2bef152010-10-13 00:55:03542 const scoped_refptr<TestSocketParams>* casted_params =
543 static_cast<const scoped_refptr<TestSocketParams>*>(params);
544
Alexandr Ilin65ec9582017-10-02 14:50:31545 base_.RequestSockets(group_name, *casted_params, num_sockets, net_log,
546 motivation);
[email protected]2c2bef152010-10-13 00:55:03547 }
548
rdsmith29dbad12017-02-17 02:22:18549 void SetPriority(const std::string& group_name,
550 ClientSocketHandle* handle,
551 RequestPriority priority) override {
552 base_.SetPriority(group_name, handle, priority);
553 }
554
dchengb03027d2014-10-21 12:00:20555 void CancelRequest(const std::string& group_name,
556 ClientSocketHandle* handle) override {
[email protected]d80a4322009-08-14 07:07:49557 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05558 }
559
dchengb03027d2014-10-21 12:00:20560 void ReleaseSocket(const std::string& group_name,
danakj655b66c2016-04-16 00:51:38561 std::unique_ptr<StreamSocket> socket,
dchengb03027d2014-10-21 12:00:20562 int id) override {
dchengc7eeda422015-12-26 03:56:48563 base_.ReleaseSocket(group_name, std::move(socket), id);
[email protected]a7e38572010-06-07 18:22:24564 }
565
dchengb03027d2014-10-21 12:00:20566 void FlushWithError(int error) override { base_.FlushWithError(error); }
[email protected]ab838892009-06-30 18:49:05567
dchengb03027d2014-10-21 12:00:20568 bool IsStalled() const override { return base_.IsStalled(); }
[email protected]51fdc7c2012-04-10 19:19:48569
dchengb03027d2014-10-21 12:00:20570 void CloseIdleSockets() override { base_.CloseIdleSockets(); }
[email protected]ab838892009-06-30 18:49:05571
xunjieli92feb332017-03-03 17:19:23572 void CloseIdleSocketsInGroup(const std::string& group_name) override {
573 base_.CloseIdleSocketsInGroup(group_name);
574 }
575
dchengb03027d2014-10-21 12:00:20576 int IdleSocketCount() const override { return base_.idle_socket_count(); }
[email protected]ab838892009-06-30 18:49:05577
dchengb03027d2014-10-21 12:00:20578 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]d80a4322009-08-14 07:07:49579 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05580 }
581
dchengb03027d2014-10-21 12:00:20582 LoadState GetLoadState(const std::string& group_name,
583 const ClientSocketHandle* handle) const override {
[email protected]d80a4322009-08-14 07:07:49584 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05585 }
586
dchengb03027d2014-10-21 12:00:20587 void AddHigherLayeredPool(HigherLayeredPool* higher_pool) override {
[email protected]043b68c82013-08-22 23:41:52588 base_.AddHigherLayeredPool(higher_pool);
[email protected]51fdc7c2012-04-10 19:19:48589 }
590
dchengb03027d2014-10-21 12:00:20591 void RemoveHigherLayeredPool(HigherLayeredPool* higher_pool) override {
[email protected]043b68c82013-08-22 23:41:52592 base_.RemoveHigherLayeredPool(higher_pool);
[email protected]51fdc7c2012-04-10 19:19:48593 }
594
danakj655b66c2016-04-16 00:51:38595 std::unique_ptr<base::DictionaryValue> GetInfoAsValue(
[email protected]d4dfdab2011-12-07 16:56:59596 const std::string& name,
597 const std::string& type,
mostynbba063d6032014-10-09 11:01:13598 bool include_nested_pools) const override {
[email protected]59d7a5a2010-08-30 16:44:27599 return base_.GetInfoAsValue(name, type);
600 }
601
dchengb03027d2014-10-21 12:00:20602 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26603 return base_.ConnectionTimeout();
604 }
605
[email protected]d80a4322009-08-14 07:07:49606 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20607
[email protected]8159a1c2012-06-07 00:00:10608 int NumUnassignedConnectJobsInGroup(const std::string& group_name) const {
609 return base_.NumUnassignedConnectJobsInGroup(group_name);
610 }
611
[email protected]974ebd62009-08-03 23:14:34612 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49613 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34614 }
615
[email protected]2c2bef152010-10-13 00:55:03616 int NumActiveSocketsInGroup(const std::string& group_name) const {
617 return base_.NumActiveSocketsInGroup(group_name);
618 }
619
[email protected]2abfe90a2010-08-25 17:49:51620 bool HasGroup(const std::string& group_name) const {
621 return base_.HasGroup(group_name);
622 }
623
[email protected]9bf28db2009-08-29 01:35:16624 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
625
[email protected]06d94042010-08-25 01:45:22626 void EnableConnectBackupJobs() { base_.EnableConnectBackupJobs(); }
[email protected]43a21b82010-06-10 21:30:54627
[email protected]043b68c82013-08-22 23:41:52628 bool CloseOneIdleConnectionInHigherLayeredPool() {
629 return base_.CloseOneIdleConnectionInHigherLayeredPool();
[email protected]51fdc7c2012-04-10 19:19:48630 }
631
[email protected]ab838892009-06-30 18:49:05632 private:
[email protected]d80a4322009-08-14 07:07:49633 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05634
635 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
636};
637
[email protected]a937a06d2009-08-19 21:19:24638} // namespace
639
[email protected]a937a06d2009-08-19 21:19:24640namespace {
641
[email protected]5fc08e32009-07-15 17:09:57642void MockClientSocketFactory::SignalJobs() {
643 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
644 it != waiting_jobs_.end(); ++it) {
645 (*it)->Signal();
646 }
647 waiting_jobs_.clear();
648}
649
[email protected]03b7c8c2013-07-20 04:38:55650void MockClientSocketFactory::SignalJob(size_t job) {
651 ASSERT_LT(job, waiting_jobs_.size());
652 waiting_jobs_[job]->Signal();
653 waiting_jobs_.erase(waiting_jobs_.begin() + job);
654}
655
656void MockClientSocketFactory::SetJobLoadState(size_t job,
657 LoadState load_state) {
658 ASSERT_LT(job, waiting_jobs_.size());
659 waiting_jobs_[job]->set_load_state(load_state);
660}
661
[email protected]974ebd62009-08-03 23:14:34662class TestConnectJobDelegate : public ConnectJob::Delegate {
663 public:
664 TestConnectJobDelegate()
665 : have_result_(false), waiting_for_result_(false), result_(OK) {}
Chris Watkins7a41d3552017-12-01 02:13:27666 ~TestConnectJobDelegate() override = default;
[email protected]974ebd62009-08-03 23:14:34667
dchengb03027d2014-10-21 12:00:20668 void OnConnectJobComplete(int result, ConnectJob* job) override {
[email protected]974ebd62009-08-03 23:14:34669 result_ = result;
danakj655b66c2016-04-16 00:51:38670 std::unique_ptr<ConnectJob> owned_job(job);
671 std::unique_ptr<StreamSocket> socket = owned_job->PassSocket();
[email protected]9b6fee12009-09-29 18:13:07672 // socket.get() should be NULL iff result != OK
[email protected]18ccfdb2013-08-15 00:13:44673 EXPECT_EQ(socket == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34674 have_result_ = true;
675 if (waiting_for_result_)
Gabriel Charette53a9ef812017-07-26 12:36:23676 base::RunLoop::QuitCurrentWhenIdleDeprecated();
[email protected]974ebd62009-08-03 23:14:34677 }
678
679 int WaitForResult() {
680 DCHECK(!waiting_for_result_);
681 while (!have_result_) {
682 waiting_for_result_ = true;
fdoray5eeb7642016-06-22 16:11:28683 base::RunLoop().Run();
[email protected]974ebd62009-08-03 23:14:34684 waiting_for_result_ = false;
685 }
686 have_result_ = false; // auto-reset for next callback
687 return result_;
688 }
689
690 private:
691 bool have_result_;
692 bool waiting_for_result_;
693 int result_;
694};
695
[email protected]2431756e2010-09-29 20:26:13696class ClientSocketPoolBaseTest : public testing::Test {
[email protected]f6d1d6eb2009-06-24 20:16:09697 protected:
mmenked3641e12016-01-28 16:06:15698 ClientSocketPoolBaseTest() : params_(new TestSocketParams()) {
[email protected]636b8252011-04-08 19:56:54699 connect_backup_jobs_enabled_ =
700 internal::ClientSocketPoolBaseHelper::connect_backup_jobs_enabled();
701 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(true);
702 }
[email protected]2431756e2010-09-29 20:26:13703
dcheng67be2b1f2014-10-27 21:47:29704 ~ClientSocketPoolBaseTest() override {
[email protected]636b8252011-04-08 19:56:54705 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
706 connect_backup_jobs_enabled_);
707 }
[email protected]c9d6a1d2009-07-14 16:15:20708
[email protected]211d21722009-07-22 15:48:53709 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16710 CreatePoolWithIdleTimeouts(
711 max_sockets,
712 max_sockets_per_group,
[email protected]82b8c962011-10-12 09:17:30713 ClientSocketPool::unused_idle_socket_timeout(),
714 ClientSocketPool::used_idle_socket_timeout());
[email protected]9bf28db2009-08-29 01:35:16715 }
716
717 void CreatePoolWithIdleTimeouts(
718 int max_sockets, int max_sockets_per_group,
719 base::TimeDelta unused_idle_socket_timeout,
720 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20721 DCHECK(!pool_.get());
[email protected]034df0f32013-01-07 23:17:48722 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_,
723 &net_log_);
[email protected]2431756e2010-09-29 20:26:13724 pool_.reset(new TestClientSocketPool(max_sockets,
725 max_sockets_per_group,
[email protected]2431756e2010-09-29 20:26:13726 unused_idle_socket_timeout,
727 used_idle_socket_timeout,
728 connect_job_factory_));
[email protected]c9d6a1d2009-07-14 16:15:20729 }
[email protected]f6d1d6eb2009-06-24 20:16:09730
mmenked3641e12016-01-28 16:06:15731 int StartRequestWithIgnoreLimits(
[email protected]b021ece62013-06-11 11:06:33732 const std::string& group_name,
733 RequestPriority priority,
mmenked3641e12016-01-28 16:06:15734 ClientSocketPool::RespectLimits respect_limits) {
735 return test_base_.StartRequestUsingPool(pool_.get(), group_name, priority,
736 respect_limits, params_);
[email protected]b021ece62013-06-11 11:06:33737 }
738
739 int StartRequest(const std::string& group_name, RequestPriority priority) {
mmenked3641e12016-01-28 16:06:15740 return StartRequestWithIgnoreLimits(
741 group_name, priority, ClientSocketPool::RespectLimits::ENABLED);
[email protected]f6d1d6eb2009-06-24 20:16:09742 }
743
[email protected]2431756e2010-09-29 20:26:13744 int GetOrderOfRequest(size_t index) const {
745 return test_base_.GetOrderOfRequest(index);
[email protected]f6d1d6eb2009-06-24 20:16:09746 }
747
[email protected]2431756e2010-09-29 20:26:13748 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
749 return test_base_.ReleaseOneConnection(keep_alive);
750 }
751
752 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
753 test_base_.ReleaseAllConnections(keep_alive);
754 }
755
756 TestSocketRequest* request(int i) { return test_base_.request(i); }
757 size_t requests_size() const { return test_base_.requests_size(); }
danakj655b66c2016-04-16 00:51:38758 std::vector<std::unique_ptr<TestSocketRequest>>* requests() {
olli.raula9d66b7d2015-11-23 08:30:42759 return test_base_.requests();
760 }
rdsmith29dbad12017-02-17 02:22:18761 // Only counts the requests that get sockets asynchronously;
762 // synchronous completions are not registered by this count.
[email protected]2431756e2010-09-29 20:26:13763 size_t completion_count() const { return test_base_.completion_count(); }
764
vishal.b62985ca92015-04-17 08:45:51765 TestNetLog net_log_;
[email protected]636b8252011-04-08 19:56:54766 bool connect_backup_jobs_enabled_;
[email protected]f6d1d6eb2009-06-24 20:16:09767 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04768 TestConnectJobFactory* connect_job_factory_;
[email protected]df4b4ef2010-07-12 18:25:21769 scoped_refptr<TestSocketParams> params_;
danakj655b66c2016-04-16 00:51:38770 std::unique_ptr<TestClientSocketPool> pool_;
[email protected]2431756e2010-09-29 20:26:13771 ClientSocketPoolTest test_base_;
[email protected]f6d1d6eb2009-06-24 20:16:09772};
773
[email protected]974ebd62009-08-03 23:14:34774// Even though a timeout is specified, it doesn't time out on a synchronous
775// completion.
776TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
777 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06778 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49779 TestClientSocketPoolBase::Request request(
Paul Jensen8d6f87ec2018-01-13 00:46:54780 &ignored, CompletionCallback(), DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:15781 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:20782 internal::ClientSocketPoolBaseHelper::NORMAL, params_,
783 NetLogWithSource());
danakj655b66c2016-04-16 00:51:38784 std::unique_ptr<TestConnectJob> job(
785 new TestConnectJob(TestConnectJob::kMockJob, "a", request,
786 base::TimeDelta::FromMicroseconds(1), &delegate,
787 &client_socket_factory_, NULL));
robpercival214763f2016-07-01 23:27:01788 EXPECT_THAT(job->Connect(), IsOk());
[email protected]974ebd62009-08-03 23:14:34789}
790
791TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
792 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06793 ClientSocketHandle ignored;
vishal.b62985ca92015-04-17 08:45:51794 TestNetLog log;
[email protected]9e743cd2010-03-16 07:03:53795
[email protected]d80a4322009-08-14 07:07:49796 TestClientSocketPoolBase::Request request(
Paul Jensen8d6f87ec2018-01-13 00:46:54797 &ignored, CompletionCallback(), DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:15798 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:20799 internal::ClientSocketPoolBaseHelper::NORMAL, params_,
800 NetLogWithSource());
[email protected]974ebd62009-08-03 23:14:34801 // Deleted by TestConnectJobDelegate.
802 TestConnectJob* job =
803 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12804 "a",
[email protected]974ebd62009-08-03 23:14:34805 request,
806 base::TimeDelta::FromMicroseconds(1),
807 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30808 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17809 &log);
robpercival214763f2016-07-01 23:27:01810 ASSERT_THAT(job->Connect(), IsError(ERR_IO_PENDING));
[email protected]26b9973962012-01-28 00:57:00811 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
robpercival214763f2016-07-01 23:27:01812 EXPECT_THAT(delegate.WaitForResult(), IsError(ERR_TIMED_OUT));
[email protected]fd7b7c92009-08-20 19:38:30813
mmenke43758e62015-05-04 21:09:46814 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40815 log.GetEntries(&entries);
816
817 EXPECT_EQ(6u, entries.size());
mikecirone8b85c432016-09-08 19:11:00818 EXPECT_TRUE(LogContainsBeginEvent(entries, 0,
819 NetLogEventType::SOCKET_POOL_CONNECT_JOB));
[email protected]e9002a92010-01-29 07:10:46820 EXPECT_TRUE(LogContainsBeginEvent(
mikecirone8b85c432016-09-08 19:11:00821 entries, 1, NetLogEventType::SOCKET_POOL_CONNECT_JOB_CONNECT));
822 EXPECT_TRUE(LogContainsEvent(entries, 2,
823 NetLogEventType::CONNECT_JOB_SET_SOCKET,
824 NetLogEventPhase::NONE));
[email protected]e9002a92010-01-29 07:10:46825 EXPECT_TRUE(LogContainsEvent(
mikecirone8b85c432016-09-08 19:11:00826 entries, 3, NetLogEventType::SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
827 NetLogEventPhase::NONE));
[email protected]e9002a92010-01-29 07:10:46828 EXPECT_TRUE(LogContainsEndEvent(
mikecirone8b85c432016-09-08 19:11:00829 entries, 4, NetLogEventType::SOCKET_POOL_CONNECT_JOB_CONNECT));
830 EXPECT_TRUE(LogContainsEndEvent(entries, 5,
831 NetLogEventType::SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34832}
833
[email protected]5fc08e32009-07-15 17:09:57834TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53835 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20836
[email protected]6ecf2b92011-12-15 01:14:52837 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06838 ClientSocketHandle handle;
vishal.b62985ca92015-04-17 08:45:51839 BoundTestNetLog log;
[email protected]034df0f32013-01-07 23:17:48840 TestLoadTimingInfoNotConnected(handle);
[email protected]9e743cd2010-03-16 07:03:53841
Paul Jensen8d6f87ec2018-01-13 00:46:54842 EXPECT_EQ(OK, handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:15843 ClientSocketPool::RespectLimits::ENABLED,
844 callback.callback(), pool_.get(), log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09845 EXPECT_TRUE(handle.is_initialized());
846 EXPECT_TRUE(handle.socket());
[email protected]034df0f32013-01-07 23:17:48847 TestLoadTimingInfoConnectedNotReused(handle);
848
[email protected]f6d1d6eb2009-06-24 20:16:09849 handle.Reset();
[email protected]034df0f32013-01-07 23:17:48850 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:30851
mmenke43758e62015-05-04 21:09:46852 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40853 log.GetEntries(&entries);
854
855 EXPECT_EQ(4u, entries.size());
mikecirone8b85c432016-09-08 19:11:00856 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKET_POOL));
[email protected]9e743cd2010-03-16 07:03:53857 EXPECT_TRUE(LogContainsEvent(
mikecirone8b85c432016-09-08 19:11:00858 entries, 1, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
859 NetLogEventPhase::NONE));
860 EXPECT_TRUE(LogContainsEvent(entries, 2,
861 NetLogEventType::SOCKET_POOL_BOUND_TO_SOCKET,
862 NetLogEventPhase::NONE));
863 EXPECT_TRUE(LogContainsEndEvent(entries, 3, NetLogEventType::SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09864}
865
[email protected]ab838892009-06-30 18:49:05866TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53867 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20868
[email protected]ab838892009-06-30 18:49:05869 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
vishal.b62985ca92015-04-17 08:45:51870 BoundTestNetLog log;
[email protected]9e743cd2010-03-16 07:03:53871
[email protected]2431756e2010-09-29 20:26:13872 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:52873 TestCompletionCallback callback;
[email protected]e60e47a2010-07-14 03:37:18874 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:13875 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43876 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:45877 info.headers = new HttpResponseHeaders(std::string());
[email protected]2431756e2010-09-29 20:26:13878 handle.set_ssl_error_response_info(info);
879 EXPECT_EQ(ERR_CONNECTION_FAILED,
Paul Jensen8d6f87ec2018-01-13 00:46:54880 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:15881 ClientSocketPool::RespectLimits::ENABLED,
882 callback.callback(), pool_.get(), log.bound()));
[email protected]2431756e2010-09-29 20:26:13883 EXPECT_FALSE(handle.socket());
884 EXPECT_FALSE(handle.is_ssl_error());
885 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]034df0f32013-01-07 23:17:48886 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:30887
mmenke43758e62015-05-04 21:09:46888 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40889 log.GetEntries(&entries);
890
891 EXPECT_EQ(3u, entries.size());
mikecirone8b85c432016-09-08 19:11:00892 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:17893 EXPECT_TRUE(LogContainsEvent(
mikecirone8b85c432016-09-08 19:11:00894 entries, 1, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
895 NetLogEventPhase::NONE));
896 EXPECT_TRUE(LogContainsEndEvent(entries, 2, NetLogEventType::SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09897}
898
[email protected]211d21722009-07-22 15:48:53899TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
900 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
901
[email protected]9e743cd2010-03-16 07:03:53902 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30903
robpercival214763f2016-07-01 23:27:01904 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
905 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
906 EXPECT_THAT(StartRequest("c", DEFAULT_PRIORITY), IsOk());
907 EXPECT_THAT(StartRequest("d", DEFAULT_PRIORITY), IsOk());
[email protected]211d21722009-07-22 15:48:53908
[email protected]2431756e2010-09-29 20:26:13909 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53910 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13911 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53912
robpercival214763f2016-07-01 23:27:01913 EXPECT_THAT(StartRequest("e", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
914 EXPECT_THAT(StartRequest("f", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
915 EXPECT_THAT(StartRequest("g", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:53916
[email protected]2431756e2010-09-29 20:26:13917 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53918
[email protected]2431756e2010-09-29 20:26:13919 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53920 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13921 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53922
923 EXPECT_EQ(1, GetOrderOfRequest(1));
924 EXPECT_EQ(2, GetOrderOfRequest(2));
925 EXPECT_EQ(3, GetOrderOfRequest(3));
926 EXPECT_EQ(4, GetOrderOfRequest(4));
927 EXPECT_EQ(5, GetOrderOfRequest(5));
928 EXPECT_EQ(6, GetOrderOfRequest(6));
929 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17930
931 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13932 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53933}
934
935TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
936 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
937
[email protected]9e743cd2010-03-16 07:03:53938 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30939
[email protected]211d21722009-07-22 15:48:53940 // Reach all limits: max total sockets, and max sockets per group.
robpercival214763f2016-07-01 23:27:01941 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
942 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
943 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
944 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
[email protected]211d21722009-07-22 15:48:53945
[email protected]2431756e2010-09-29 20:26:13946 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53947 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13948 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53949
950 // Now create a new group and verify that we don't starve it.
robpercival214763f2016-07-01 23:27:01951 EXPECT_THAT(StartRequest("c", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:53952
[email protected]2431756e2010-09-29 20:26:13953 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53954
[email protected]2431756e2010-09-29 20:26:13955 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53956 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13957 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53958
959 EXPECT_EQ(1, GetOrderOfRequest(1));
960 EXPECT_EQ(2, GetOrderOfRequest(2));
961 EXPECT_EQ(3, GetOrderOfRequest(3));
962 EXPECT_EQ(4, GetOrderOfRequest(4));
963 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17964
965 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13966 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53967}
968
969TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
970 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
971
robpercival214763f2016-07-01 23:27:01972 EXPECT_THAT(StartRequest("b", LOWEST), IsOk());
973 EXPECT_THAT(StartRequest("a", MEDIUM), IsOk());
974 EXPECT_THAT(StartRequest("b", HIGHEST), IsOk());
975 EXPECT_THAT(StartRequest("a", LOWEST), IsOk());
[email protected]211d21722009-07-22 15:48:53976
[email protected]2431756e2010-09-29 20:26:13977 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53978 client_socket_factory_.allocation_count());
979
robpercival214763f2016-07-01 23:27:01980 EXPECT_THAT(StartRequest("c", LOWEST), IsError(ERR_IO_PENDING));
981 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
982 EXPECT_THAT(StartRequest("b", HIGHEST), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:53983
[email protected]2431756e2010-09-29 20:26:13984 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53985
[email protected]2431756e2010-09-29 20:26:13986 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53987
988 // First 4 requests don't have to wait, and finish in order.
989 EXPECT_EQ(1, GetOrderOfRequest(1));
990 EXPECT_EQ(2, GetOrderOfRequest(2));
991 EXPECT_EQ(3, GetOrderOfRequest(3));
992 EXPECT_EQ(4, GetOrderOfRequest(4));
993
[email protected]ac790b42009-12-02 04:31:31994 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
995 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53996 EXPECT_EQ(7, GetOrderOfRequest(5));
997 EXPECT_EQ(6, GetOrderOfRequest(6));
998 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17999
1000 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131001 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]211d21722009-07-22 15:48:531002}
1003
rdsmith29dbad12017-02-17 02:22:181004// Test reprioritizing a request before completion doesn't interfere with
1005// its completion.
1006TEST_F(ClientSocketPoolBaseTest, ReprioritizeOne) {
1007 CreatePool(kDefaultMaxSockets, 1);
1008
1009 EXPECT_THAT(StartRequest("a", LOWEST), IsError(OK));
1010 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1011 EXPECT_TRUE(request(0)->handle()->socket());
1012 EXPECT_FALSE(request(1)->handle()->socket());
1013
1014 request(1)->handle()->SetPriority(MEDIUM);
1015
1016 ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE);
1017
1018 EXPECT_TRUE(request(1)->handle()->socket());
1019}
1020
1021// Reprioritize a request up past another one and make sure that changes the
1022// completion order.
1023TEST_F(ClientSocketPoolBaseTest, ReprioritizeUpReorder) {
1024 CreatePool(kDefaultMaxSockets, 1);
1025
1026 EXPECT_THAT(StartRequest("a", LOWEST), IsError(OK));
1027 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1028 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
1029 EXPECT_TRUE(request(0)->handle()->socket());
1030 EXPECT_FALSE(request(1)->handle()->socket());
1031 EXPECT_FALSE(request(2)->handle()->socket());
1032
1033 request(2)->handle()->SetPriority(HIGHEST);
1034
1035 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1036
1037 EXPECT_EQ(1, GetOrderOfRequest(1));
1038 EXPECT_EQ(3, GetOrderOfRequest(2));
1039 EXPECT_EQ(2, GetOrderOfRequest(3));
1040}
1041
1042// Reprioritize a request without changing relative priorities and check
1043// that the order doesn't change.
1044TEST_F(ClientSocketPoolBaseTest, ReprioritizeUpNoReorder) {
1045 CreatePool(kDefaultMaxSockets, 1);
1046
1047 EXPECT_THAT(StartRequest("a", LOWEST), IsError(OK));
1048 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1049 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1050 EXPECT_TRUE(request(0)->handle()->socket());
1051 EXPECT_FALSE(request(1)->handle()->socket());
1052 EXPECT_FALSE(request(2)->handle()->socket());
1053
1054 request(2)->handle()->SetPriority(MEDIUM);
1055
1056 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1057
1058 EXPECT_EQ(1, GetOrderOfRequest(1));
1059 EXPECT_EQ(2, GetOrderOfRequest(2));
1060 EXPECT_EQ(3, GetOrderOfRequest(3));
1061}
1062
1063// Reprioritize a request past down another one and make sure that changes the
1064// completion order.
1065TEST_F(ClientSocketPoolBaseTest, ReprioritizeDownReorder) {
1066 CreatePool(kDefaultMaxSockets, 1);
1067
1068 EXPECT_THAT(StartRequest("a", LOWEST), IsError(OK));
1069 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
1070 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1071 EXPECT_TRUE(request(0)->handle()->socket());
1072 EXPECT_FALSE(request(1)->handle()->socket());
1073 EXPECT_FALSE(request(2)->handle()->socket());
1074
1075 request(1)->handle()->SetPriority(LOW);
1076
1077 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1078
1079 EXPECT_EQ(1, GetOrderOfRequest(1));
1080 EXPECT_EQ(3, GetOrderOfRequest(2));
1081 EXPECT_EQ(2, GetOrderOfRequest(3));
1082}
1083
1084// Reprioritize a request to the same level as another and confirm it is
1085// put after the old request.
1086TEST_F(ClientSocketPoolBaseTest, ReprioritizeResetFIFO) {
1087 CreatePool(kDefaultMaxSockets, 1);
1088
1089 EXPECT_THAT(StartRequest("a", LOWEST), IsError(OK));
1090 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
1091 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1092 EXPECT_TRUE(request(0)->handle()->socket());
1093 EXPECT_FALSE(request(1)->handle()->socket());
1094 EXPECT_FALSE(request(2)->handle()->socket());
1095
1096 request(1)->handle()->SetPriority(MEDIUM);
1097
1098 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1099
1100 EXPECT_EQ(1, GetOrderOfRequest(1));
1101 EXPECT_EQ(3, GetOrderOfRequest(2));
1102 EXPECT_EQ(2, GetOrderOfRequest(3));
1103}
1104
[email protected]211d21722009-07-22 15:48:531105TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
1106 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1107
robpercival214763f2016-07-01 23:27:011108 EXPECT_THAT(StartRequest("a", LOWEST), IsOk());
1109 EXPECT_THAT(StartRequest("a", LOW), IsOk());
1110 EXPECT_THAT(StartRequest("b", HIGHEST), IsOk());
1111 EXPECT_THAT(StartRequest("b", MEDIUM), IsOk());
[email protected]211d21722009-07-22 15:48:531112
[email protected]2431756e2010-09-29 20:26:131113 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531114 client_socket_factory_.allocation_count());
1115
robpercival214763f2016-07-01 23:27:011116 EXPECT_THAT(StartRequest("c", MEDIUM), IsError(ERR_IO_PENDING));
1117 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1118 EXPECT_THAT(StartRequest("b", HIGHEST), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531119
[email protected]2431756e2010-09-29 20:26:131120 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531121
[email protected]2431756e2010-09-29 20:26:131122 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531123 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131124 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:531125
1126 // First 4 requests don't have to wait, and finish in order.
1127 EXPECT_EQ(1, GetOrderOfRequest(1));
1128 EXPECT_EQ(2, GetOrderOfRequest(2));
1129 EXPECT_EQ(3, GetOrderOfRequest(3));
1130 EXPECT_EQ(4, GetOrderOfRequest(4));
1131
1132 // Request ("b", 7) has the highest priority, but we can't make new socket for
1133 // group "b", because it has reached the per-group limit. Then we make
1134 // socket for ("c", 6), because it has higher priority than ("a", 4),
1135 // and we still can't make a socket for group "b".
1136 EXPECT_EQ(5, GetOrderOfRequest(5));
1137 EXPECT_EQ(6, GetOrderOfRequest(6));
1138 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171139
1140 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131141 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:531142}
1143
1144// Make sure that we count connecting sockets against the total limit.
1145TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
1146 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1147
robpercival214763f2016-07-01 23:27:011148 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1149 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
1150 EXPECT_THAT(StartRequest("c", DEFAULT_PRIORITY), IsOk());
[email protected]211d21722009-07-22 15:48:531151
1152 // Create one asynchronous request.
1153 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
robpercival214763f2016-07-01 23:27:011154 EXPECT_THAT(StartRequest("d", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531155
[email protected]6b175382009-10-13 06:47:471156 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1157 // actually become pending until 2ms after they have been created. In order
1158 // to flush all tasks, we need to wait so that we know there are no
1159 // soon-to-be-pending tasks waiting.
[email protected]26b9973962012-01-28 00:57:001160 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
fdoray5eeb7642016-06-22 16:11:281161 base::RunLoop().RunUntilIdle();
[email protected]6b175382009-10-13 06:47:471162
[email protected]211d21722009-07-22 15:48:531163 // The next synchronous request should wait for its turn.
1164 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
robpercival214763f2016-07-01 23:27:011165 EXPECT_THAT(StartRequest("e", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531166
[email protected]2431756e2010-09-29 20:26:131167 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531168
[email protected]2431756e2010-09-29 20:26:131169 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531170 client_socket_factory_.allocation_count());
1171
1172 EXPECT_EQ(1, GetOrderOfRequest(1));
1173 EXPECT_EQ(2, GetOrderOfRequest(2));
1174 EXPECT_EQ(3, GetOrderOfRequest(3));
1175 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:171176 EXPECT_EQ(5, GetOrderOfRequest(5));
1177
1178 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131179 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:531180}
1181
[email protected]6427fe22010-04-16 22:27:411182TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
1183 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1184 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1185
robpercival214763f2016-07-01 23:27:011186 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1187 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1188 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1189 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
[email protected]6427fe22010-04-16 22:27:411190
1191 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1192
1193 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1194
robpercival214763f2016-07-01 23:27:011195 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1196 EXPECT_THAT(StartRequest("c", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]6427fe22010-04-16 22:27:411197
1198 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1199
[email protected]2431756e2010-09-29 20:26:131200 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411201 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131202 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411203 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131204 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1205 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411206 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
1207}
1208
[email protected]d7027bb2010-05-10 18:58:541209TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
1210 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1211 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1212
1213 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521214 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131215 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541216 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151217 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201218 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:541219
1220 ClientSocketHandle handles[4];
1221 for (size_t i = 0; i < arraysize(handles); ++i) {
[email protected]6ecf2b92011-12-15 01:14:521222 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201223 EXPECT_EQ(
1224 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541225 handles[i].Init("b", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:201226 ClientSocketPool::RespectLimits::ENABLED,
1227 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:541228 }
1229
1230 // One will be stalled, cancel all the handles now.
1231 // This should hit the OnAvailableSocketSlot() code where we previously had
1232 // stalled groups, but no longer have any.
1233 for (size_t i = 0; i < arraysize(handles); ++i)
1234 handles[i].Reset();
1235}
1236
[email protected]eb5a99382010-07-11 03:18:261237TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:541238 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1239 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1240
[email protected]eb5a99382010-07-11 03:18:261241 {
1242 ClientSocketHandle handles[kDefaultMaxSockets];
[email protected]6ecf2b92011-12-15 01:14:521243 TestCompletionCallback callbacks[kDefaultMaxSockets];
[email protected]eb5a99382010-07-11 03:18:261244 for (int i = 0; i < kDefaultMaxSockets; ++i) {
Paul Jensen8d6f87ec2018-01-13 00:46:541245 EXPECT_EQ(OK, handles[i].Init(base::IntToString(i), params_,
1246 DEFAULT_PRIORITY, SocketTag(),
1247 ClientSocketPool::RespectLimits::ENABLED,
1248 callbacks[i].callback(), pool_.get(),
1249 NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261250 }
1251
1252 // Force a stalled group.
1253 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521254 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201255 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541256 stalled_handle.Init("foo", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:201257 ClientSocketPool::RespectLimits::ENABLED,
1258 callback.callback(), pool_.get(),
1259 NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261260
1261 // Cancel the stalled request.
1262 stalled_handle.Reset();
1263
1264 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1265 EXPECT_EQ(0, pool_->IdleSocketCount());
1266
1267 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541268 }
1269
[email protected]43a21b82010-06-10 21:30:541270 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1271 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:261272}
[email protected]43a21b82010-06-10 21:30:541273
[email protected]eb5a99382010-07-11 03:18:261274TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
1275 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1276 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1277
1278 {
1279 ClientSocketHandle handles[kDefaultMaxSockets];
1280 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521281 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201282 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541283 handles[i].Init(
1284 base::IntToString(i), params_, DEFAULT_PRIORITY,
1285 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1286 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261287 }
1288
1289 // Force a stalled group.
1290 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1291 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521292 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201293 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541294 stalled_handle.Init("foo", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:201295 ClientSocketPool::RespectLimits::ENABLED,
1296 callback.callback(), pool_.get(),
1297 NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261298
1299 // Since it is stalled, it should have no connect jobs.
1300 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101301 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261302
1303 // Cancel the stalled request.
1304 handles[0].Reset();
1305
[email protected]eb5a99382010-07-11 03:18:261306 // Now we should have a connect job.
1307 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101308 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261309
1310 // The stalled socket should connect.
robpercival214763f2016-07-01 23:27:011311 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:261312
1313 EXPECT_EQ(kDefaultMaxSockets + 1,
1314 client_socket_factory_.allocation_count());
1315 EXPECT_EQ(0, pool_->IdleSocketCount());
1316 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101317 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261318
1319 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541320 }
1321
[email protected]eb5a99382010-07-11 03:18:261322 EXPECT_EQ(1, pool_->IdleSocketCount());
1323}
[email protected]43a21b82010-06-10 21:30:541324
[email protected]eb5a99382010-07-11 03:18:261325TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1326 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1327 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:541328
[email protected]eb5a99382010-07-11 03:18:261329 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521330 TestCompletionCallback callback;
[email protected]eb5a99382010-07-11 03:18:261331 {
[email protected]51fdc7c2012-04-10 19:19:481332 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261333 ClientSocketHandle handles[kDefaultMaxSockets];
1334 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521335 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201336 EXPECT_EQ(OK, handles[i].Init(base::StringPrintf("Take 2: %d", i),
Paul Jensen8d6f87ec2018-01-13 00:46:541337 params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:201338 ClientSocketPool::RespectLimits::ENABLED,
1339 callback.callback(), pool_.get(),
1340 NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261341 }
1342
1343 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1344 EXPECT_EQ(0, pool_->IdleSocketCount());
[email protected]51fdc7c2012-04-10 19:19:481345 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261346
1347 // Now we will hit the socket limit.
tfarina428341112016-09-22 13:38:201348 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541349 stalled_handle.Init("foo", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:201350 ClientSocketPool::RespectLimits::ENABLED,
1351 callback.callback(), pool_.get(),
1352 NetLogWithSource()));
[email protected]51fdc7c2012-04-10 19:19:481353 EXPECT_TRUE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261354
1355 // Dropping out of scope will close all handles and return them to idle.
1356 }
[email protected]43a21b82010-06-10 21:30:541357
1358 // But if we wait for it, the released idle sockets will be closed in
1359 // preference of the waiting request.
robpercival214763f2016-07-01 23:27:011360 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:261361
1362 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1363 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:541364}
1365
1366// Regression test for http://crbug.com/40952.
1367TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1368 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]06d94042010-08-25 01:45:221369 pool_->EnableConnectBackupJobs();
[email protected]43a21b82010-06-10 21:30:541370 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1371
1372 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1373 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521374 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201375 EXPECT_EQ(
1376 OK, handle.Init(base::IntToString(i), params_, DEFAULT_PRIORITY,
Paul Jensen8d6f87ec2018-01-13 00:46:541377 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201378 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]43a21b82010-06-10 21:30:541379 }
1380
1381 // Flush all the DoReleaseSocket tasks.
fdoray5eeb7642016-06-22 16:11:281382 base::RunLoop().RunUntilIdle();
[email protected]43a21b82010-06-10 21:30:541383
1384 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1385 // reuse a socket.
1386 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1387 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521388 TestCompletionCallback callback;
[email protected]43a21b82010-06-10 21:30:541389
1390 // "0" is special here, since it should be the first entry in the sorted map,
1391 // which is the one which we would close an idle socket for. We shouldn't
1392 // close an idle socket though, since we should reuse the idle socket.
tfarina428341112016-09-22 13:38:201393 EXPECT_EQ(OK,
Paul Jensen8d6f87ec2018-01-13 00:46:541394 handle.Init("0", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:201395 ClientSocketPool::RespectLimits::ENABLED,
1396 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]43a21b82010-06-10 21:30:541397
1398 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1399 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1400}
1401
[email protected]ab838892009-06-30 18:49:051402TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531403 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091404
robpercival214763f2016-07-01 23:27:011405 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1406 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1407 EXPECT_THAT(StartRequest("a", IDLE), IsError(ERR_IO_PENDING));
1408 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
1409 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1410 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
1411 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1412 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091413
[email protected]2431756e2010-09-29 20:26:131414 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]c9d6a1d2009-07-14 16:15:201415 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1416 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131417 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1418 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091419
[email protected]c9d6a1d2009-07-14 16:15:201420 EXPECT_EQ(1, GetOrderOfRequest(1));
1421 EXPECT_EQ(2, GetOrderOfRequest(2));
[email protected]c9c6f5c2010-07-31 01:30:031422 EXPECT_EQ(8, GetOrderOfRequest(3));
1423 EXPECT_EQ(6, GetOrderOfRequest(4));
1424 EXPECT_EQ(4, GetOrderOfRequest(5));
1425 EXPECT_EQ(3, GetOrderOfRequest(6));
1426 EXPECT_EQ(5, GetOrderOfRequest(7));
1427 EXPECT_EQ(7, GetOrderOfRequest(8));
[email protected]75439d3b2009-07-23 22:11:171428
1429 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131430 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]f6d1d6eb2009-06-24 20:16:091431}
1432
[email protected]ab838892009-06-30 18:49:051433TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531434 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091435
robpercival214763f2016-07-01 23:27:011436 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1437 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1438 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
1439 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1440 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
1441 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1442 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091443
[email protected]2431756e2010-09-29 20:26:131444 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091445
[email protected]2431756e2010-09-29 20:26:131446 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
robpercival214763f2016-07-01 23:27:011447 EXPECT_THAT(request(i)->WaitForResult(), IsOk());
[email protected]c9d6a1d2009-07-14 16:15:201448
[email protected]2431756e2010-09-29 20:26:131449 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]c9d6a1d2009-07-14 16:15:201450 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131451 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1452 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091453}
1454
1455// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:051456// The pending connect job will be cancelled and should not call back into
1457// ClientSocketPoolBase.
1458TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531459 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201460
[email protected]ab838892009-06-30 18:49:051461 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131462 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521463 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:151464 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541465 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151466 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201467 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:131468 handle.Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091469}
1470
[email protected]ab838892009-06-30 18:49:051471TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531472 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201473
[email protected]ab838892009-06-30 18:49:051474 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061475 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521476 TestCompletionCallback callback;
[email protected]f6d1d6eb2009-06-24 20:16:091477
mmenked3641e12016-01-28 16:06:151478 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541479 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151480 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201481 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]f6d1d6eb2009-06-24 20:16:091482
1483 handle.Reset();
1484
[email protected]6ecf2b92011-12-15 01:14:521485 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:131486 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541487 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151488 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201489 callback2.callback(), pool_.get(), NetLogWithSource()));
[email protected]f6d1d6eb2009-06-24 20:16:091490
robpercival214763f2016-07-01 23:27:011491 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]f6d1d6eb2009-06-24 20:16:091492 EXPECT_FALSE(callback.have_result());
1493
1494 handle.Reset();
1495}
1496
[email protected]ab838892009-06-30 18:49:051497TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531498 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091499
robpercival214763f2016-07-01 23:27:011500 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1501 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1502 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
1503 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1504 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
1505 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1506 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091507
1508 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201509 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]2431756e2010-09-29 20:26:131510 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1511 (*requests())[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091512
[email protected]2431756e2010-09-29 20:26:131513 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091514
[email protected]c9d6a1d2009-07-14 16:15:201515 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1516 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131517 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1518 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091519
[email protected]c9d6a1d2009-07-14 16:15:201520 EXPECT_EQ(1, GetOrderOfRequest(1));
1521 EXPECT_EQ(2, GetOrderOfRequest(2));
1522 EXPECT_EQ(5, GetOrderOfRequest(3));
1523 EXPECT_EQ(3, GetOrderOfRequest(4));
[email protected]2431756e2010-09-29 20:26:131524 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1525 GetOrderOfRequest(5)); // Canceled request.
[email protected]c9d6a1d2009-07-14 16:15:201526 EXPECT_EQ(4, GetOrderOfRequest(6));
1527 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171528
1529 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131530 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091531}
1532
mmenke33d24423d2015-05-19 19:41:091533// Function to be used as a callback on socket request completion. It first
1534// disconnects the successfully connected socket from the first request, and
1535// then reuses the ClientSocketHandle to request another socket.
1536//
1537// |nested_callback| is called with the result of the second socket request.
1538void RequestSocketOnComplete(ClientSocketHandle* handle,
1539 TestClientSocketPool* pool,
1540 TestConnectJobFactory* test_connect_job_factory,
1541 TestConnectJob::JobType next_job_type,
1542 const CompletionCallback& nested_callback,
1543 int first_request_result) {
robpercival214763f2016-07-01 23:27:011544 EXPECT_THAT(first_request_result, IsOk());
mmenke33d24423d2015-05-19 19:41:091545
1546 test_connect_job_factory->set_job_type(next_job_type);
1547
1548 // Don't allow reuse of the socket. Disconnect it and then release it.
1549 if (handle->socket())
1550 handle->socket()->Disconnect();
1551 handle->Reset();
1552
mmenked3641e12016-01-28 16:06:151553 scoped_refptr<TestSocketParams> params(new TestSocketParams());
mmenke33d24423d2015-05-19 19:41:091554 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:541555 int rv = handle->Init("a", params, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:151556 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201557 nested_callback, pool, NetLogWithSource());
mmenke33d24423d2015-05-19 19:41:091558 if (rv != ERR_IO_PENDING) {
1559 DCHECK_EQ(TestConnectJob::kMockJob, next_job_type);
1560 nested_callback.Run(rv);
1561 } else {
1562 DCHECK_EQ(TestConnectJob::kMockPendingJob, next_job_type);
[email protected]6ecf2b92011-12-15 01:14:521563 }
mmenke33d24423d2015-05-19 19:41:091564}
[email protected]f6d1d6eb2009-06-24 20:16:091565
mmenke33d24423d2015-05-19 19:41:091566// Tests the case where a second socket is requested in a completion callback,
1567// and the second socket connects asynchronously. Reuses the same
1568// ClientSocketHandle for the second socket, after disconnecting the first.
[email protected]2ab05b52009-07-01 23:57:581569TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531570 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201571
[email protected]0b7648c2009-07-06 20:14:011572 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061573 ClientSocketHandle handle;
mmenke33d24423d2015-05-19 19:41:091574 TestCompletionCallback second_result_callback;
1575 int rv = handle.Init(
Paul Jensen8d6f87ec2018-01-13 00:46:541576 "a", params_, DEFAULT_PRIORITY, SocketTag(),
1577 ClientSocketPool::RespectLimits::ENABLED,
mmenke33d24423d2015-05-19 19:41:091578 base::Bind(&RequestSocketOnComplete, &handle, pool_.get(),
1579 connect_job_factory_, TestConnectJob::kMockPendingJob,
1580 second_result_callback.callback()),
tfarina428341112016-09-22 13:38:201581 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011582 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091583
robpercival214763f2016-07-01 23:27:011584 EXPECT_THAT(second_result_callback.WaitForResult(), IsOk());
[email protected]2ab05b52009-07-01 23:57:581585}
[email protected]f6d1d6eb2009-06-24 20:16:091586
mmenke33d24423d2015-05-19 19:41:091587// Tests the case where a second socket is requested in a completion callback,
1588// and the second socket connects synchronously. Reuses the same
1589// ClientSocketHandle for the second socket, after disconnecting the first.
[email protected]2ab05b52009-07-01 23:57:581590TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531591 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201592
[email protected]0b7648c2009-07-06 20:14:011593 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061594 ClientSocketHandle handle;
mmenke33d24423d2015-05-19 19:41:091595 TestCompletionCallback second_result_callback;
1596 int rv = handle.Init(
Paul Jensen8d6f87ec2018-01-13 00:46:541597 "a", params_, DEFAULT_PRIORITY, SocketTag(),
1598 ClientSocketPool::RespectLimits::ENABLED,
mmenke33d24423d2015-05-19 19:41:091599 base::Bind(&RequestSocketOnComplete, &handle, pool_.get(),
1600 connect_job_factory_, TestConnectJob::kMockPendingJob,
1601 second_result_callback.callback()),
tfarina428341112016-09-22 13:38:201602 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011603 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2ab05b52009-07-01 23:57:581604
robpercival214763f2016-07-01 23:27:011605 EXPECT_THAT(second_result_callback.WaitForResult(), IsOk());
[email protected]f6d1d6eb2009-06-24 20:16:091606}
1607
1608// Make sure that pending requests get serviced after active requests get
1609// cancelled.
[email protected]ab838892009-06-30 18:49:051610TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531611 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201612
[email protected]0b7648c2009-07-06 20:14:011613 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091614
robpercival214763f2016-07-01 23:27:011615 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1616 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1617 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1618 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1619 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1620 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1621 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091622
[email protected]c9d6a1d2009-07-14 16:15:201623 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1624 // Let's cancel them.
1625 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]2431756e2010-09-29 20:26:131626 ASSERT_FALSE(request(i)->handle()->is_initialized());
1627 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091628 }
1629
[email protected]f6d1d6eb2009-06-24 20:16:091630 // Let's wait for the rest to complete now.
[email protected]2431756e2010-09-29 20:26:131631 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
robpercival214763f2016-07-01 23:27:011632 EXPECT_THAT(request(i)->WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:131633 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091634 }
1635
[email protected]2431756e2010-09-29 20:26:131636 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1637 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091638}
1639
1640// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051641TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531642 const size_t kMaxSockets = 5;
1643 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201644
[email protected]0b7648c2009-07-06 20:14:011645 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091646
[email protected]211d21722009-07-22 15:48:531647 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1648 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091649
1650 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531651 for (size_t i = 0; i < kNumberOfRequests; ++i)
robpercival214763f2016-07-01 23:27:011652 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091653
[email protected]211d21722009-07-22 15:48:531654 for (size_t i = 0; i < kNumberOfRequests; ++i)
robpercival214763f2016-07-01 23:27:011655 EXPECT_THAT(request(i)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]f6d1d6eb2009-06-24 20:16:091656}
1657
mmenke9d72fe42017-05-18 22:36:071658// Make sure that pending requests that complete synchronously get serviced
1659// after active requests fail. See https://crbug.com/723748
1660TEST_F(ClientSocketPoolBaseTest, HandleMultipleSyncFailuresAfterAsyncFailure) {
1661 const size_t kNumberOfRequests = 10;
1662 const size_t kMaxSockets = 1;
1663 CreatePool(kMaxSockets, kMaxSockets);
1664
1665 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1666
1667 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1668
1669 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
1670
1671 // Queue up all the other requests
1672 for (size_t i = 1; i < kNumberOfRequests; ++i)
1673 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1674
1675 // Make sure all requests fail, instead of hanging.
1676 for (size_t i = 0; i < kNumberOfRequests; ++i)
1677 EXPECT_THAT(request(i)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
1678}
1679
[email protected]5fc08e32009-07-15 17:09:571680TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531681 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571682
1683 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1684
[email protected]2431756e2010-09-29 20:26:131685 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521686 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:541687 int rv = handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151688 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201689 callback.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011690 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:571691
1692 // Cancel the active request.
[email protected]2431756e2010-09-29 20:26:131693 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571694
Paul Jensen8d6f87ec2018-01-13 00:46:541695 rv = handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151696 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201697 callback.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011698 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1699 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]5fc08e32009-07-15 17:09:571700
[email protected]2431756e2010-09-29 20:26:131701 EXPECT_FALSE(handle.is_reused());
[email protected]034df0f32013-01-07 23:17:481702 TestLoadTimingInfoConnectedNotReused(handle);
[email protected]5fc08e32009-07-15 17:09:571703 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1704}
1705
xunjieli26619e72016-11-23 19:39:551706TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsForced) {
xunjieli26619e72016-11-23 19:39:551707 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1708 ClientSocketHandle handle;
1709 TestCompletionCallback callback;
1710 BoundTestNetLog log;
Paul Jensen8d6f87ec2018-01-13 00:46:541711 int rv = handle.Init("a", params_, LOWEST, SocketTag(),
xunjieli26619e72016-11-23 19:39:551712 ClientSocketPool::RespectLimits::ENABLED,
1713 callback.callback(), pool_.get(), log.bound());
1714 EXPECT_THAT(rv, IsOk());
1715 handle.Reset();
1716 EXPECT_EQ(1, pool_->IdleSocketCount());
1717 pool_->CloseIdleSockets();
xunjieli26619e72016-11-23 19:39:551718}
1719
xunjieli92feb332017-03-03 17:19:231720TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsInGroupForced) {
xunjieli92feb332017-03-03 17:19:231721 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1722 TestCompletionCallback callback;
1723 BoundTestNetLog log;
1724 ClientSocketHandle handle1;
Paul Jensen8d6f87ec2018-01-13 00:46:541725 int rv = handle1.Init("a", params_, LOWEST, SocketTag(),
xunjieli92feb332017-03-03 17:19:231726 ClientSocketPool::RespectLimits::ENABLED,
1727 callback.callback(), pool_.get(), log.bound());
1728 EXPECT_THAT(rv, IsOk());
1729 ClientSocketHandle handle2;
Paul Jensen8d6f87ec2018-01-13 00:46:541730 rv = handle2.Init("a", params_, LOWEST, SocketTag(),
xunjieli92feb332017-03-03 17:19:231731 ClientSocketPool::RespectLimits::ENABLED,
1732 callback.callback(), pool_.get(), log.bound());
1733 ClientSocketHandle handle3;
Paul Jensen8d6f87ec2018-01-13 00:46:541734 rv = handle3.Init("b", params_, LOWEST, SocketTag(),
xunjieli92feb332017-03-03 17:19:231735 ClientSocketPool::RespectLimits::ENABLED,
1736 callback.callback(), pool_.get(), log.bound());
1737 EXPECT_THAT(rv, IsOk());
1738 handle1.Reset();
1739 handle2.Reset();
1740 handle3.Reset();
1741 EXPECT_EQ(3, pool_->IdleSocketCount());
1742 pool_->CloseIdleSocketsInGroup("a");
1743 EXPECT_EQ(1, pool_->IdleSocketCount());
xunjieli92feb332017-03-03 17:19:231744}
1745
xunjieli26619e72016-11-23 19:39:551746TEST_F(ClientSocketPoolBaseTest, CleanUpUnusableIdleSockets) {
xunjieli26619e72016-11-23 19:39:551747 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1748 ClientSocketHandle handle;
1749 TestCompletionCallback callback;
1750 BoundTestNetLog log;
Paul Jensen8d6f87ec2018-01-13 00:46:541751 int rv = handle.Init("a", params_, LOWEST, SocketTag(),
xunjieli26619e72016-11-23 19:39:551752 ClientSocketPool::RespectLimits::ENABLED,
1753 callback.callback(), pool_.get(), log.bound());
1754 EXPECT_THAT(rv, IsOk());
1755 StreamSocket* socket = handle.socket();
1756 handle.Reset();
1757 EXPECT_EQ(1, pool_->IdleSocketCount());
1758
1759 // Disconnect socket now to make the socket unusable.
1760 socket->Disconnect();
1761 ClientSocketHandle handle2;
Paul Jensen8d6f87ec2018-01-13 00:46:541762 rv = handle2.Init("a", params_, LOWEST, SocketTag(),
xunjieli26619e72016-11-23 19:39:551763 ClientSocketPool::RespectLimits::ENABLED,
1764 callback.callback(), pool_.get(), log.bound());
1765 EXPECT_THAT(rv, IsOk());
1766 EXPECT_FALSE(handle2.is_reused());
xunjieli26619e72016-11-23 19:39:551767}
1768
[email protected]2b7523d2009-07-29 20:29:231769// Regression test for http://crbug.com/17985.
1770TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1771 const int kMaxSockets = 3;
1772 const int kMaxSocketsPerGroup = 2;
1773 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1774
[email protected]ac790b42009-12-02 04:31:311775 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231776
robpercival214763f2016-07-01 23:27:011777 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1778 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
[email protected]2b7523d2009-07-29 20:29:231779
1780 // This is going to be a pending request in an otherwise empty group.
robpercival214763f2016-07-01 23:27:011781 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]2b7523d2009-07-29 20:29:231782
1783 // Reach the maximum socket limit.
robpercival214763f2016-07-01 23:27:011784 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
[email protected]2b7523d2009-07-29 20:29:231785
1786 // Create a stalled group with high priorities.
robpercival214763f2016-07-01 23:27:011787 EXPECT_THAT(StartRequest("c", kHighPriority), IsError(ERR_IO_PENDING));
1788 EXPECT_THAT(StartRequest("c", kHighPriority), IsError(ERR_IO_PENDING));
[email protected]2b7523d2009-07-29 20:29:231789
[email protected]eb5a99382010-07-11 03:18:261790 // Release the first two sockets from "a". Because this is a keepalive,
1791 // the first release will unblock the pending request for "a". The
1792 // second release will unblock a request for "c", becaue it is the next
1793 // high priority socket.
[email protected]2431756e2010-09-29 20:26:131794 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1795 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]2b7523d2009-07-29 20:29:231796
1797 // Closing idle sockets should not get us into trouble, but in the bug
1798 // we were hitting a CHECK here.
[email protected]93054cc12010-06-08 06:12:411799 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]43a21b82010-06-10 21:30:541800 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261801
[email protected]2da659e2013-05-23 20:51:341802 // Run the released socket wakeups.
fdoray5eeb7642016-06-22 16:11:281803 base::RunLoop().RunUntilIdle();
[email protected]2b7523d2009-07-29 20:29:231804}
1805
[email protected]4d3b05d2010-01-27 21:27:291806TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531807 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571808
1809 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131810 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521811 TestCompletionCallback callback;
vishal.b62985ca92015-04-17 08:45:511812 BoundTestNetLog log;
Paul Jensen8d6f87ec2018-01-13 00:46:541813 int rv = handle.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:151814 ClientSocketPool::RespectLimits::ENABLED,
1815 callback.callback(), pool_.get(), log.bound());
robpercival214763f2016-07-01 23:27:011816 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2431756e2010-09-29 20:26:131817 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
[email protected]034df0f32013-01-07 23:17:481818 TestLoadTimingInfoNotConnected(handle);
1819
robpercival214763f2016-07-01 23:27:011820 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:131821 EXPECT_TRUE(handle.is_initialized());
1822 EXPECT_TRUE(handle.socket());
[email protected]034df0f32013-01-07 23:17:481823 TestLoadTimingInfoConnectedNotReused(handle);
1824
[email protected]2431756e2010-09-29 20:26:131825 handle.Reset();
[email protected]034df0f32013-01-07 23:17:481826 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:301827
mmenke43758e62015-05-04 21:09:461828 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:401829 log.GetEntries(&entries);
1830
1831 EXPECT_EQ(4u, entries.size());
mikecirone8b85c432016-09-08 19:11:001832 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171833 EXPECT_TRUE(LogContainsEvent(
mikecirone8b85c432016-09-08 19:11:001834 entries, 1, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1835 NetLogEventPhase::NONE));
1836 EXPECT_TRUE(LogContainsEvent(entries, 2,
1837 NetLogEventType::SOCKET_POOL_BOUND_TO_SOCKET,
1838 NetLogEventPhase::NONE));
1839 EXPECT_TRUE(LogContainsEndEvent(entries, 3, NetLogEventType::SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571840}
1841
[email protected]4d3b05d2010-01-27 21:27:291842TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571843 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531844 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571845
1846 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2431756e2010-09-29 20:26:131847 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521848 TestCompletionCallback callback;
vishal.b62985ca92015-04-17 08:45:511849 BoundTestNetLog log;
[email protected]e60e47a2010-07-14 03:37:181850 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:131851 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:431852 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:451853 info.headers = new HttpResponseHeaders(std::string());
[email protected]2431756e2010-09-29 20:26:131854 handle.set_ssl_error_response_info(info);
mmenked3641e12016-01-28 16:06:151855 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541856 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151857 ClientSocketPool::RespectLimits::ENABLED,
1858 callback.callback(), pool_.get(), log.bound()));
[email protected]2431756e2010-09-29 20:26:131859 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
robpercival214763f2016-07-01 23:27:011860 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]2431756e2010-09-29 20:26:131861 EXPECT_FALSE(handle.is_ssl_error());
1862 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:301863
mmenke43758e62015-05-04 21:09:461864 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:401865 log.GetEntries(&entries);
1866
1867 EXPECT_EQ(3u, entries.size());
mikecirone8b85c432016-09-08 19:11:001868 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171869 EXPECT_TRUE(LogContainsEvent(
mikecirone8b85c432016-09-08 19:11:001870 entries, 1, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1871 NetLogEventPhase::NONE));
1872 EXPECT_TRUE(LogContainsEndEvent(entries, 2, NetLogEventType::SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571873}
1874
mmenke6be122f2015-03-09 22:22:471875// Check that an async ConnectJob failure does not result in creation of a new
1876// ConnectJob when there's another pending request also waiting on its own
1877// ConnectJob. See http://crbug.com/463960.
1878TEST_F(ClientSocketPoolBaseTest, AsyncFailureWithPendingRequestWithJob) {
1879 CreatePool(2, 2);
1880 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1881
robpercival214763f2016-07-01 23:27:011882 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1883 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
mmenke6be122f2015-03-09 22:22:471884
robpercival214763f2016-07-01 23:27:011885 EXPECT_THAT(request(0)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
1886 EXPECT_THAT(request(1)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
mmenke6be122f2015-03-09 22:22:471887
1888 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1889}
1890
[email protected]4d3b05d2010-01-27 21:27:291891TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101892 // TODO(eroman): Add back the log expectations! Removed them because the
1893 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531894 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571895
1896 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131897 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521898 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131899 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:521900 TestCompletionCallback callback2;
[email protected]5fc08e32009-07-15 17:09:571901
[email protected]2431756e2010-09-29 20:26:131902 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541903 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151904 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201905 callback.callback(), pool_.get(), NetLogWithSource()));
vishal.b62985ca92015-04-17 08:45:511906 BoundTestNetLog log2;
tfarina428341112016-09-22 13:38:201907 EXPECT_EQ(
1908 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541909 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:201910 ClientSocketPool::RespectLimits::ENABLED,
1911 callback2.callback(), pool_.get(), NetLogWithSource()));
[email protected]5fc08e32009-07-15 17:09:571912
[email protected]2431756e2010-09-29 20:26:131913 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571914
[email protected]fd7b7c92009-08-20 19:38:301915
1916 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301917
robpercival214763f2016-07-01 23:27:011918 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:131919 handle2.Reset();
[email protected]fd7b7c92009-08-20 19:38:301920
1921 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531922 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571923}
1924
[email protected]4d3b05d2010-01-27 21:27:291925TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341926 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1927
[email protected]17a0c6c2009-08-04 00:07:041928 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1929
robpercival214763f2016-07-01 23:27:011930 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
1931 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1932 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1933 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
[email protected]974ebd62009-08-03 23:14:341934
1935 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]2431756e2010-09-29 20:26:131936 (*requests())[2]->handle()->Reset();
1937 (*requests())[3]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341938 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1939
[email protected]2431756e2010-09-29 20:26:131940 (*requests())[1]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341941 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1942
[email protected]2431756e2010-09-29 20:26:131943 (*requests())[0]->handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261944 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]974ebd62009-08-03 23:14:341945}
1946
[email protected]5fc08e32009-07-15 17:09:571947// When requests and ConnectJobs are not coupled, the request will get serviced
1948// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291949TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531950 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571951
1952 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321953 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571954
[email protected]2431756e2010-09-29 20:26:131955 std::vector<TestSocketRequest*> request_order;
1956 size_t completion_count; // unused
1957 TestSocketRequest req1(&request_order, &completion_count);
Paul Jensen8d6f87ec2018-01-13 00:46:541958 int rv =
1959 req1.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
1960 ClientSocketPool::RespectLimits::ENABLED,
1961 req1.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011962 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1963 EXPECT_THAT(req1.WaitForResult(), IsOk());
[email protected]5fc08e32009-07-15 17:09:571964
1965 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1966 // without a job.
1967 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1968
[email protected]2431756e2010-09-29 20:26:131969 TestSocketRequest req2(&request_order, &completion_count);
Paul Jensen8d6f87ec2018-01-13 00:46:541970 rv = req2.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151971 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201972 req2.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011973 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2431756e2010-09-29 20:26:131974 TestSocketRequest req3(&request_order, &completion_count);
Paul Jensen8d6f87ec2018-01-13 00:46:541975 rv = req3.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151976 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201977 req3.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011978 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:571979
1980 // Both Requests 2 and 3 are pending. We release socket 1 which should
1981 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331982 req1.handle()->Reset();
[email protected]2da659e2013-05-23 20:51:341983 // Run the released socket wakeups.
fdoray5eeb7642016-06-22 16:11:281984 base::RunLoop().RunUntilIdle();
[email protected]a6c59f62009-07-29 16:33:331985 ASSERT_TRUE(req2.handle()->socket());
robpercival214763f2016-07-01 23:27:011986 EXPECT_THAT(req2.WaitForResult(), IsOk());
[email protected]a6c59f62009-07-29 16:33:331987 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571988
1989 // Signal job 2, which should service request 3.
1990
1991 client_socket_factory_.SignalJobs();
robpercival214763f2016-07-01 23:27:011992 EXPECT_THAT(req3.WaitForResult(), IsOk());
[email protected]5fc08e32009-07-15 17:09:571993
[email protected]2431756e2010-09-29 20:26:131994 ASSERT_EQ(3U, request_order.size());
1995 EXPECT_EQ(&req1, request_order[0]);
1996 EXPECT_EQ(&req2, request_order[1]);
1997 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571998 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1999}
2000
2001// The requests are not coupled to the jobs. So, the requests should finish in
2002// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:292003TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:532004 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:572005 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:322006 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:572007
[email protected]2431756e2010-09-29 20:26:132008 std::vector<TestSocketRequest*> request_order;
2009 size_t completion_count; // unused
2010 TestSocketRequest req1(&request_order, &completion_count);
Paul Jensen8d6f87ec2018-01-13 00:46:542011 int rv =
2012 req1.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2013 ClientSocketPool::RespectLimits::ENABLED,
2014 req1.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012015 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572016
[email protected]2431756e2010-09-29 20:26:132017 TestSocketRequest req2(&request_order, &completion_count);
Paul Jensen8d6f87ec2018-01-13 00:46:542018 rv = req2.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152019 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202020 req2.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012021 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572022
2023 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:322024 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:572025
[email protected]2431756e2010-09-29 20:26:132026 TestSocketRequest req3(&request_order, &completion_count);
Paul Jensen8d6f87ec2018-01-13 00:46:542027 rv = req3.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152028 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202029 req3.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012030 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572031
robpercival214763f2016-07-01 23:27:012032 EXPECT_THAT(req1.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
2033 EXPECT_THAT(req2.WaitForResult(), IsOk());
2034 EXPECT_THAT(req3.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]5fc08e32009-07-15 17:09:572035
[email protected]2431756e2010-09-29 20:26:132036 ASSERT_EQ(3U, request_order.size());
2037 EXPECT_EQ(&req1, request_order[0]);
2038 EXPECT_EQ(&req2, request_order[1]);
2039 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:572040}
2041
[email protected]03b7c8c2013-07-20 04:38:552042// Test GetLoadState in the case there's only one socket request.
2043TEST_F(ClientSocketPoolBaseTest, LoadStateOneRequest) {
[email protected]211d21722009-07-22 15:48:532044 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]03b7c8c2013-07-20 04:38:552045 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]5fc08e32009-07-15 17:09:572046
[email protected]2431756e2010-09-29 20:26:132047 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522048 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:542049 int rv = handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152050 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202051 callback.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012052 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552053 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:572054
[email protected]03b7c8c2013-07-20 04:38:552055 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2056 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
2057
2058 // No point in completing the connection, since ClientSocketHandles only
2059 // expect the LoadState to be checked while connecting.
2060}
2061
2062// Test GetLoadState in the case there are two socket requests.
haavardm835c1d62015-04-22 08:18:002063// Only the first connection in the pool should affect the pool's load status.
[email protected]03b7c8c2013-07-20 04:38:552064TEST_F(ClientSocketPoolBaseTest, LoadStateTwoRequests) {
2065 CreatePool(2, 2);
2066 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2067
2068 ClientSocketHandle handle;
2069 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:542070 int rv = handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152071 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202072 callback.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012073 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
haavardm835c1d62015-04-22 08:18:002074 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
2075
2076 ClientSocketHandle handle2;
2077 TestCompletionCallback callback2;
Paul Jensen8d6f87ec2018-01-13 00:46:542078 rv = handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152079 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202080 callback2.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012081 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
haavardm835c1d62015-04-22 08:18:002082 client_socket_factory_.SetJobLoadState(1, LOAD_STATE_RESOLVING_HOST);
2083
2084 // Check that both handles report the state of the first job.
2085 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle.GetLoadState());
2086 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle2.GetLoadState());
2087
2088 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_CONNECTING);
2089
2090 // Check that both handles change to LOAD_STATE_CONNECTING.
2091 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2092 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
2093}
2094
2095// Test that the second connection request does not affect the pool's load
2096// status.
2097TEST_F(ClientSocketPoolBaseTest, LoadStateTwoRequestsChangeSecondRequestState) {
2098 CreatePool(2, 2);
2099 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2100
2101 ClientSocketHandle handle;
2102 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:542103 int rv = handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152104 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202105 callback.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012106 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572107
[email protected]2431756e2010-09-29 20:26:132108 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522109 TestCompletionCallback callback2;
Paul Jensen8d6f87ec2018-01-13 00:46:542110 rv = handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152111 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202112 callback2.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012113 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
haavardm835c1d62015-04-22 08:18:002114 client_socket_factory_.SetJobLoadState(1, LOAD_STATE_RESOLVING_HOST);
[email protected]03b7c8c2013-07-20 04:38:552115
[email protected]03b7c8c2013-07-20 04:38:552116 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2117 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
2118
haavardm835c1d62015-04-22 08:18:002119 // First job connects and the first request gets the socket. The
[email protected]03b7c8c2013-07-20 04:38:552120 // second handle switches to the state of the remaining ConnectJob.
2121 client_socket_factory_.SignalJob(0);
robpercival214763f2016-07-01 23:27:012122 EXPECT_THAT(callback.WaitForResult(), IsOk());
haavardm835c1d62015-04-22 08:18:002123 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle2.GetLoadState());
[email protected]03b7c8c2013-07-20 04:38:552124}
2125
2126// Test GetLoadState in the case the per-group limit is reached.
2127TEST_F(ClientSocketPoolBaseTest, LoadStateGroupLimit) {
2128 CreatePool(2, 1);
2129 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2130
2131 ClientSocketHandle handle;
2132 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:542133 int rv = handle.Init("a", params_, MEDIUM, SocketTag(),
mmenked3641e12016-01-28 16:06:152134 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202135 callback.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012136 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552137 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2138
2139 // Request another socket from the same pool, buth with a higher priority.
2140 // The first request should now be stalled at the socket group limit.
2141 ClientSocketHandle handle2;
2142 TestCompletionCallback callback2;
Paul Jensen8d6f87ec2018-01-13 00:46:542143 rv = handle2.Init("a", params_, HIGHEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152144 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202145 callback2.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012146 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552147 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2148 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
2149
2150 // The first handle should remain stalled as the other socket goes through
2151 // the connect process.
2152
2153 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2154 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2155 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle2.GetLoadState());
2156
2157 client_socket_factory_.SignalJob(0);
robpercival214763f2016-07-01 23:27:012158 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]03b7c8c2013-07-20 04:38:552159 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2160
2161 // Closing the second socket should cause the stalled handle to finally get a
2162 // ConnectJob.
2163 handle2.socket()->Disconnect();
2164 handle2.Reset();
2165 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2166}
2167
2168// Test GetLoadState in the case the per-pool limit is reached.
2169TEST_F(ClientSocketPoolBaseTest, LoadStatePoolLimit) {
2170 CreatePool(2, 2);
2171 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2172
2173 ClientSocketHandle handle;
2174 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:542175 int rv = handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152176 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202177 callback.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012178 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552179
2180 // Request for socket from another pool.
2181 ClientSocketHandle handle2;
2182 TestCompletionCallback callback2;
Paul Jensen8d6f87ec2018-01-13 00:46:542183 rv = handle2.Init("b", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152184 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202185 callback2.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012186 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552187
2188 // Request another socket from the first pool. Request should stall at the
2189 // socket pool limit.
2190 ClientSocketHandle handle3;
2191 TestCompletionCallback callback3;
Paul Jensen8d6f87ec2018-01-13 00:46:542192 rv = handle3.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152193 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202194 callback2.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 // The third handle should remain stalled as the other sockets in its group
2198 // goes through the connect process.
2199
2200 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2201 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2202
2203 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2204 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
2205 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2206
2207 client_socket_factory_.SignalJob(0);
robpercival214763f2016-07-01 23:27:012208 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]03b7c8c2013-07-20 04:38:552209 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2210
2211 // Closing a socket should allow the stalled handle to finally get a new
2212 // ConnectJob.
2213 handle.socket()->Disconnect();
2214 handle.Reset();
2215 EXPECT_EQ(LOAD_STATE_CONNECTING, handle3.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:572216}
2217
[email protected]e772db3f2010-07-12 18:11:132218TEST_F(ClientSocketPoolBaseTest, Recoverable) {
2219 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2220 connect_job_factory_->set_job_type(TestConnectJob::kMockRecoverableJob);
2221
[email protected]2431756e2010-09-29 20:26:132222 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522223 TestCompletionCallback callback;
2224 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED,
Paul Jensen8d6f87ec2018-01-13 00:46:542225 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152226 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202227 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:132228 EXPECT_TRUE(handle.is_initialized());
2229 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:132230}
2231
2232TEST_F(ClientSocketPoolBaseTest, AsyncRecoverable) {
2233 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2234
2235 connect_job_factory_->set_job_type(
2236 TestConnectJob::kMockPendingRecoverableJob);
[email protected]2431756e2010-09-29 20:26:132237 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522238 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132239 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542240 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152241 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202242 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:132243 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
robpercival214763f2016-07-01 23:27:012244 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_PROXY_AUTH_REQUESTED));
[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
[email protected]e60e47a2010-07-14 03:37:182249TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
2250 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2251 connect_job_factory_->set_job_type(
2252 TestConnectJob::kMockAdditionalErrorStateJob);
2253
[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_CONNECTION_FAILED,
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_FALSE(handle.is_initialized());
2261 EXPECT_FALSE(handle.socket());
2262 EXPECT_TRUE(handle.is_ssl_error());
2263 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182264}
2265
2266TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
2267 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2268
2269 connect_job_factory_->set_job_type(
2270 TestConnectJob::kMockPendingAdditionalErrorStateJob);
[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_IO_PENDING,
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_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
robpercival214763f2016-07-01 23:27:012278 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]2431756e2010-09-29 20:26:132279 EXPECT_FALSE(handle.is_initialized());
2280 EXPECT_FALSE(handle.socket());
2281 EXPECT_TRUE(handle.is_ssl_error());
2282 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182283}
2284
martijn003cd612016-05-19 22:24:382285// Make sure we can reuse sockets.
2286TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSocketsReuse) {
[email protected]64770b7d2011-11-16 04:30:412287 CreatePoolWithIdleTimeouts(
2288 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
[email protected]e7b1c6d2c2012-05-05 00:54:032289 base::TimeDelta(), // Time out unused sockets immediately.
2290 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2291
2292 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2293
2294 ClientSocketHandle handle;
2295 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:542296 int rv = handle.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152297 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202298 callback.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012299 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e7b1c6d2c2012-05-05 00:54:032300 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
robpercival214763f2016-07-01 23:27:012301 ASSERT_THAT(callback.WaitForResult(), IsOk());
[email protected]e7b1c6d2c2012-05-05 00:54:032302
2303 // Use and release the socket.
Ramin Halavati0a08cc82018-02-06 07:46:382304 EXPECT_EQ(1, handle.socket()->Write(NULL, 1, CompletionCallback(),
2305 TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]034df0f32013-01-07 23:17:482306 TestLoadTimingInfoConnectedNotReused(handle);
[email protected]e7b1c6d2c2012-05-05 00:54:032307 handle.Reset();
2308
2309 // Should now have one idle socket.
2310 ASSERT_EQ(1, pool_->IdleSocketCount());
2311
2312 // Request a new socket. This should reuse the old socket and complete
2313 // synchronously.
vishal.b62985ca92015-04-17 08:45:512314 BoundTestNetLog log;
Paul Jensen8d6f87ec2018-01-13 00:46:542315 rv = handle.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152316 ClientSocketPool::RespectLimits::ENABLED,
2317 CompletionCallback(), pool_.get(), log.bound());
robpercival214763f2016-07-01 23:27:012318 ASSERT_THAT(rv, IsOk());
[email protected]e7b1c6d2c2012-05-05 00:54:032319 EXPECT_TRUE(handle.is_reused());
[email protected]034df0f32013-01-07 23:17:482320 TestLoadTimingInfoConnectedReused(handle);
[email protected]e7b1c6d2c2012-05-05 00:54:032321
2322 ASSERT_TRUE(pool_->HasGroup("a"));
2323 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2324 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2325
mmenke43758e62015-05-04 21:09:462326 TestNetLogEntry::List entries;
[email protected]e7b1c6d2c2012-05-05 00:54:032327 log.GetEntries(&entries);
2328 EXPECT_TRUE(LogContainsEntryWithType(
mikecirone8b85c432016-09-08 19:11:002329 entries, 1, NetLogEventType::SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]e7b1c6d2c2012-05-05 00:54:032330}
2331
blundellb8163592f2015-12-16 14:22:422332#if defined(OS_IOS)
2333// TODO(droger): Enable this test (crbug.com/512595).
martijn003cd612016-05-19 22:24:382334#define MAYBE_CleanupTimedOutIdleSocketsNoReuse \
2335 DISABLED_CleanupTimedOutIdleSocketsNoReuse
blundellb8163592f2015-12-16 14:22:422336#else
martijn003cd612016-05-19 22:24:382337#define MAYBE_CleanupTimedOutIdleSocketsNoReuse \
2338 CleanupTimedOutIdleSocketsNoReuse
blundellb8163592f2015-12-16 14:22:422339#endif
martijn003cd612016-05-19 22:24:382340// Make sure we cleanup old unused sockets.
2341TEST_F(ClientSocketPoolBaseTest, MAYBE_CleanupTimedOutIdleSocketsNoReuse) {
[email protected]e7b1c6d2c2012-05-05 00:54:032342 CreatePoolWithIdleTimeouts(
2343 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2344 base::TimeDelta(), // Time out unused sockets immediately
2345 base::TimeDelta()); // Time out used sockets immediately
[email protected]64770b7d2011-11-16 04:30:412346
2347 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2348
2349 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2350
2351 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522352 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:542353 int rv = handle.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152354 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202355 callback.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012356 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]64770b7d2011-11-16 04:30:412357 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2358
2359 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522360 TestCompletionCallback callback2;
Paul Jensen8d6f87ec2018-01-13 00:46:542361 rv = handle2.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152362 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202363 callback2.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012364 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]64770b7d2011-11-16 04:30:412365 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
2366
2367 // Cancel one of the requests. Wait for the other, which will get the first
2368 // job. Release the socket. Run the loop again to make sure the second
2369 // socket is sitting idle and the first one is released (since ReleaseSocket()
2370 // just posts a DoReleaseSocket() task).
2371
2372 handle.Reset();
robpercival214763f2016-07-01 23:27:012373 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]64770b7d2011-11-16 04:30:412374 // Use the socket.
Ramin Halavati0a08cc82018-02-06 07:46:382375 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, CompletionCallback(),
2376 TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]64770b7d2011-11-16 04:30:412377 handle2.Reset();
2378
[email protected]e7b1c6d2c2012-05-05 00:54:032379 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2380 // actually become pending until 2ms after they have been created. In order
2381 // to flush all tasks, we need to wait so that we know there are no
2382 // soon-to-be-pending tasks waiting.
2383 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
fdoray5eeb7642016-06-22 16:11:282384 base::RunLoop().RunUntilIdle();
[email protected]64770b7d2011-11-16 04:30:412385
[email protected]e7b1c6d2c2012-05-05 00:54:032386 // Both sockets should now be idle.
[email protected]64770b7d2011-11-16 04:30:412387 ASSERT_EQ(2, pool_->IdleSocketCount());
2388
2389 // Request a new socket. This should cleanup the unused and timed out ones.
2390 // A new socket will be created rather than reusing the idle one.
vishal.b62985ca92015-04-17 08:45:512391 BoundTestNetLog log;
[email protected]6ecf2b92011-12-15 01:14:522392 TestCompletionCallback callback3;
Paul Jensen8d6f87ec2018-01-13 00:46:542393 rv = handle.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152394 ClientSocketPool::RespectLimits::ENABLED,
2395 callback3.callback(), pool_.get(), log.bound());
robpercival214763f2016-07-01 23:27:012396 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
2397 ASSERT_THAT(callback3.WaitForResult(), IsOk());
[email protected]64770b7d2011-11-16 04:30:412398 EXPECT_FALSE(handle.is_reused());
2399
[email protected]e7b1c6d2c2012-05-05 00:54:032400 // Make sure the idle socket is closed.
[email protected]64770b7d2011-11-16 04:30:412401 ASSERT_TRUE(pool_->HasGroup("a"));
2402 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2403 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2404
mmenke43758e62015-05-04 21:09:462405 TestNetLogEntry::List entries;
[email protected]64770b7d2011-11-16 04:30:412406 log.GetEntries(&entries);
2407 EXPECT_FALSE(LogContainsEntryWithType(
mikecirone8b85c432016-09-08 19:11:002408 entries, 1, NetLogEventType::SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]64770b7d2011-11-16 04:30:412409}
2410
[email protected]2041cf342010-02-19 03:15:592411// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:162412// because of multiple releasing disconnected sockets.
2413TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
2414 CreatePoolWithIdleTimeouts(
2415 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2416 base::TimeDelta(), // Time out unused sockets immediately.
2417 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2418
2419 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2420
2421 // Startup 4 connect jobs. Two of them will be pending.
2422
[email protected]2431756e2010-09-29 20:26:132423 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522424 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:542425 int rv = handle.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152426 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202427 callback.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012428 EXPECT_THAT(rv, IsOk());
[email protected]4f2abec2010-02-03 18:10:162429
[email protected]2431756e2010-09-29 20:26:132430 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522431 TestCompletionCallback callback2;
Paul Jensen8d6f87ec2018-01-13 00:46:542432 rv = handle2.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152433 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202434 callback2.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012435 EXPECT_THAT(rv, IsOk());
[email protected]4f2abec2010-02-03 18:10:162436
[email protected]2431756e2010-09-29 20:26:132437 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:522438 TestCompletionCallback callback3;
Paul Jensen8d6f87ec2018-01-13 00:46:542439 rv = handle3.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152440 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202441 callback3.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012442 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4f2abec2010-02-03 18:10:162443
[email protected]2431756e2010-09-29 20:26:132444 ClientSocketHandle handle4;
[email protected]6ecf2b92011-12-15 01:14:522445 TestCompletionCallback callback4;
Paul Jensen8d6f87ec2018-01-13 00:46:542446 rv = handle4.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152447 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202448 callback4.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012449 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4f2abec2010-02-03 18:10:162450
2451 // Release two disconnected sockets.
2452
[email protected]2431756e2010-09-29 20:26:132453 handle.socket()->Disconnect();
2454 handle.Reset();
2455 handle2.socket()->Disconnect();
2456 handle2.Reset();
[email protected]4f2abec2010-02-03 18:10:162457
robpercival214763f2016-07-01 23:27:012458 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132459 EXPECT_FALSE(handle3.is_reused());
robpercival214763f2016-07-01 23:27:012460 EXPECT_THAT(callback4.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132461 EXPECT_FALSE(handle4.is_reused());
[email protected]4f2abec2010-02-03 18:10:162462}
2463
[email protected]d7027bb2010-05-10 18:58:542464// Regression test for http://crbug.com/42267.
2465// When DoReleaseSocket() is processed for one socket, it is blocked because the
2466// other stalled groups all have releasing sockets, so no progress can be made.
2467TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
2468 CreatePoolWithIdleTimeouts(
2469 4 /* socket limit */, 4 /* socket limit per group */,
2470 base::TimeDelta(), // Time out unused sockets immediately.
2471 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2472
2473 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2474
2475 // Max out the socket limit with 2 per group.
2476
[email protected]2431756e2010-09-29 20:26:132477 ClientSocketHandle handle_a[4];
[email protected]6ecf2b92011-12-15 01:14:522478 TestCompletionCallback callback_a[4];
[email protected]2431756e2010-09-29 20:26:132479 ClientSocketHandle handle_b[4];
[email protected]6ecf2b92011-12-15 01:14:522480 TestCompletionCallback callback_b[4];
[email protected]d7027bb2010-05-10 18:58:542481
2482 for (int i = 0; i < 2; ++i) {
Paul Jensen8d6f87ec2018-01-13 00:46:542483 EXPECT_EQ(OK, handle_a[i].Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152484 ClientSocketPool::RespectLimits::ENABLED,
2485 callback_a[i].callback(), pool_.get(),
tfarina428341112016-09-22 13:38:202486 NetLogWithSource()));
Paul Jensen8d6f87ec2018-01-13 00:46:542487 EXPECT_EQ(OK, handle_b[i].Init("b", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152488 ClientSocketPool::RespectLimits::ENABLED,
2489 callback_b[i].callback(), pool_.get(),
tfarina428341112016-09-22 13:38:202490 NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:542491 }
[email protected]b89f7e42010-05-20 20:37:002492
[email protected]d7027bb2010-05-10 18:58:542493 // Make 4 pending requests, 2 per group.
2494
2495 for (int i = 2; i < 4; ++i) {
tfarina428341112016-09-22 13:38:202496 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542497 handle_a[i].Init("a", params_, LOWEST, SocketTag(),
tfarina428341112016-09-22 13:38:202498 ClientSocketPool::RespectLimits::ENABLED,
2499 callback_a[i].callback(), pool_.get(),
2500 NetLogWithSource()));
2501 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542502 handle_b[i].Init("b", params_, LOWEST, SocketTag(),
tfarina428341112016-09-22 13:38:202503 ClientSocketPool::RespectLimits::ENABLED,
2504 callback_b[i].callback(), pool_.get(),
2505 NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:542506 }
2507
2508 // Release b's socket first. The order is important, because in
2509 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2510 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2511 // first, which has a releasing socket, so it refuses to start up another
2512 // ConnectJob. So, we used to infinite loop on this.
[email protected]2431756e2010-09-29 20:26:132513 handle_b[0].socket()->Disconnect();
2514 handle_b[0].Reset();
2515 handle_a[0].socket()->Disconnect();
2516 handle_a[0].Reset();
[email protected]d7027bb2010-05-10 18:58:542517
2518 // Used to get stuck here.
fdoray5eeb7642016-06-22 16:11:282519 base::RunLoop().RunUntilIdle();
[email protected]d7027bb2010-05-10 18:58:542520
[email protected]2431756e2010-09-29 20:26:132521 handle_b[1].socket()->Disconnect();
2522 handle_b[1].Reset();
2523 handle_a[1].socket()->Disconnect();
2524 handle_a[1].Reset();
[email protected]d7027bb2010-05-10 18:58:542525
2526 for (int i = 2; i < 4; ++i) {
robpercival214763f2016-07-01 23:27:012527 EXPECT_THAT(callback_b[i].WaitForResult(), IsOk());
2528 EXPECT_THAT(callback_a[i].WaitForResult(), IsOk());
[email protected]d7027bb2010-05-10 18:58:542529 }
2530}
2531
[email protected]fd4fe0b2010-02-08 23:02:152532TEST_F(ClientSocketPoolBaseTest,
2533 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2534 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2535
2536 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2537
robpercival214763f2016-07-01 23:27:012538 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
2539 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
2540 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
2541 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]fd4fe0b2010-02-08 23:02:152542
robpercival214763f2016-07-01 23:27:012543 EXPECT_THAT((*requests())[0]->WaitForResult(), IsOk());
2544 EXPECT_THAT((*requests())[1]->WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132545 EXPECT_EQ(2u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152546
2547 // Releases one connection.
[email protected]2431756e2010-09-29 20:26:132548 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
robpercival214763f2016-07-01 23:27:012549 EXPECT_THAT((*requests())[2]->WaitForResult(), IsOk());
[email protected]fd4fe0b2010-02-08 23:02:152550
[email protected]2431756e2010-09-29 20:26:132551 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
robpercival214763f2016-07-01 23:27:012552 EXPECT_THAT((*requests())[3]->WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132553 EXPECT_EQ(4u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152554
2555 EXPECT_EQ(1, GetOrderOfRequest(1));
2556 EXPECT_EQ(2, GetOrderOfRequest(2));
2557 EXPECT_EQ(3, GetOrderOfRequest(3));
2558 EXPECT_EQ(4, GetOrderOfRequest(4));
2559
2560 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:132561 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
[email protected]fd4fe0b2010-02-08 23:02:152562}
2563
[email protected]6ecf2b92011-12-15 01:14:522564class TestReleasingSocketRequest : public TestCompletionCallbackBase {
[email protected]4f1e4982010-03-02 18:31:042565 public:
[email protected]2431756e2010-09-29 20:26:132566 TestReleasingSocketRequest(TestClientSocketPool* pool,
2567 int expected_result,
[email protected]e60e47a2010-07-14 03:37:182568 bool reset_releasing_handle)
2569 : pool_(pool),
2570 expected_result_(expected_result),
[email protected]6ecf2b92011-12-15 01:14:522571 reset_releasing_handle_(reset_releasing_handle),
[email protected]aa249b52013-04-30 01:04:322572 callback_(base::Bind(&TestReleasingSocketRequest::OnComplete,
2573 base::Unretained(this))) {
[email protected]6ecf2b92011-12-15 01:14:522574 }
2575
Chris Watkins7a41d3552017-12-01 02:13:272576 ~TestReleasingSocketRequest() override = default;
[email protected]4f1e4982010-03-02 18:31:042577
2578 ClientSocketHandle* handle() { return &handle_; }
2579
[email protected]6ecf2b92011-12-15 01:14:522580 const CompletionCallback& callback() const { return callback_; }
[email protected]4f1e4982010-03-02 18:31:042581
2582 private:
[email protected]6ecf2b92011-12-15 01:14:522583 void OnComplete(int result) {
2584 SetResult(result);
2585 if (reset_releasing_handle_)
2586 handle_.Reset();
2587
mmenked3641e12016-01-28 16:06:152588 scoped_refptr<TestSocketParams> con_params(new TestSocketParams());
[email protected]6ecf2b92011-12-15 01:14:522589 EXPECT_EQ(expected_result_,
Paul Jensen8d6f87ec2018-01-13 00:46:542590 handle2_.Init("a", con_params, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152591 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202592 callback2_.callback(), pool_, NetLogWithSource()));
[email protected]6ecf2b92011-12-15 01:14:522593 }
2594
[email protected]2431756e2010-09-29 20:26:132595 TestClientSocketPool* const pool_;
[email protected]e60e47a2010-07-14 03:37:182596 int expected_result_;
2597 bool reset_releasing_handle_;
[email protected]4f1e4982010-03-02 18:31:042598 ClientSocketHandle handle_;
2599 ClientSocketHandle handle2_;
[email protected]6ecf2b92011-12-15 01:14:522600 CompletionCallback callback_;
2601 TestCompletionCallback callback2_;
[email protected]4f1e4982010-03-02 18:31:042602};
2603
[email protected]e60e47a2010-07-14 03:37:182604
2605TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2606 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2607
robpercival214763f2016-07-01 23:27:012608 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
2609 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
2610 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
[email protected]e60e47a2010-07-14 03:37:182611
[email protected]2431756e2010-09-29 20:26:132612 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]e60e47a2010-07-14 03:37:182613 client_socket_factory_.allocation_count());
2614
2615 connect_job_factory_->set_job_type(
2616 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2617 TestReleasingSocketRequest req(pool_.get(), OK, false);
tfarina428341112016-09-22 13:38:202618 EXPECT_EQ(
2619 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542620 req.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:202621 ClientSocketPool::RespectLimits::ENABLED,
2622 req.callback(), pool_.get(), NetLogWithSource()));
[email protected]e60e47a2010-07-14 03:37:182623 // The next job should complete synchronously
2624 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2625
robpercival214763f2016-07-01 23:27:012626 EXPECT_THAT(req.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:182627 EXPECT_FALSE(req.handle()->is_initialized());
2628 EXPECT_FALSE(req.handle()->socket());
2629 EXPECT_TRUE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:432630 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182631}
2632
[email protected]b6501d3d2010-06-03 23:53:342633// http://crbug.com/44724 regression test.
2634// We start releasing the pool when we flush on network change. When that
2635// happens, the only active references are in the ClientSocketHandles. When a
2636// ConnectJob completes and calls back into the last ClientSocketHandle, that
2637// callback can release the last reference and delete the pool. After the
2638// callback finishes, we go back to the stack frame within the now-deleted pool.
2639// Executing any code that refers to members of the now-deleted pool can cause
2640// crashes.
2641TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2642 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2643 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2644
2645 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522646 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:152647 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542648 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152649 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202650 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]b6501d3d2010-06-03 23:53:342651
[email protected]7af985a2012-12-14 22:40:422652 pool_->FlushWithError(ERR_NETWORK_CHANGED);
[email protected]b6501d3d2010-06-03 23:53:342653
2654 // We'll call back into this now.
2655 callback.WaitForResult();
2656}
2657
[email protected]a7e38572010-06-07 18:22:242658TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2659 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2660 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2661
2662 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522663 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:152664 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542665 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152666 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202667 callback.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:012668 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]a7e38572010-06-07 18:22:242669 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2670
[email protected]7af985a2012-12-14 22:40:422671 pool_->FlushWithError(ERR_NETWORK_CHANGED);
[email protected]a7e38572010-06-07 18:22:242672
2673 handle.Reset();
fdoray5eeb7642016-06-22 16:11:282674 base::RunLoop().RunUntilIdle();
[email protected]a7e38572010-06-07 18:22:242675
mmenked3641e12016-01-28 16:06:152676 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542677 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152678 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202679 callback.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:012680 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]a7e38572010-06-07 18:22:242681 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2682}
2683
[email protected]6ecf2b92011-12-15 01:14:522684class ConnectWithinCallback : public TestCompletionCallbackBase {
[email protected]06f92462010-08-31 19:24:142685 public:
2686 ConnectWithinCallback(
2687 const std::string& group_name,
2688 const scoped_refptr<TestSocketParams>& params,
[email protected]2431756e2010-09-29 20:26:132689 TestClientSocketPool* pool)
[email protected]6ecf2b92011-12-15 01:14:522690 : group_name_(group_name),
2691 params_(params),
2692 pool_(pool),
[email protected]aa249b52013-04-30 01:04:322693 callback_(base::Bind(&ConnectWithinCallback::OnComplete,
2694 base::Unretained(this))) {
[email protected]06f92462010-08-31 19:24:142695 }
2696
Chris Watkins7a41d3552017-12-01 02:13:272697 ~ConnectWithinCallback() override = default;
[email protected]06f92462010-08-31 19:24:142698
2699 int WaitForNestedResult() {
2700 return nested_callback_.WaitForResult();
2701 }
2702
[email protected]6ecf2b92011-12-15 01:14:522703 const CompletionCallback& callback() const { return callback_; }
2704
[email protected]06f92462010-08-31 19:24:142705 private:
[email protected]6ecf2b92011-12-15 01:14:522706 void OnComplete(int result) {
2707 SetResult(result);
tfarina428341112016-09-22 13:38:202708 EXPECT_EQ(
2709 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542710 handle_.Init(group_name_, params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:202711 ClientSocketPool::RespectLimits::ENABLED,
2712 nested_callback_.callback(), pool_, NetLogWithSource()));
[email protected]6ecf2b92011-12-15 01:14:522713 }
2714
[email protected]06f92462010-08-31 19:24:142715 const std::string group_name_;
2716 const scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:132717 TestClientSocketPool* const pool_;
[email protected]06f92462010-08-31 19:24:142718 ClientSocketHandle handle_;
[email protected]6ecf2b92011-12-15 01:14:522719 CompletionCallback callback_;
2720 TestCompletionCallback nested_callback_;
2721
2722 DISALLOW_COPY_AND_ASSIGN(ConnectWithinCallback);
[email protected]06f92462010-08-31 19:24:142723};
2724
2725TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
2726 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2727
2728 // First job will be waiting until it gets aborted.
2729 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2730
2731 ClientSocketHandle handle;
[email protected]2431756e2010-09-29 20:26:132732 ConnectWithinCallback callback("a", params_, pool_.get());
mmenked3641e12016-01-28 16:06:152733 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542734 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152735 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202736 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]06f92462010-08-31 19:24:142737
2738 // Second job will be started during the first callback, and will
2739 // asynchronously complete with OK.
2740 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]7af985a2012-12-14 22:40:422741 pool_->FlushWithError(ERR_NETWORK_CHANGED);
robpercival214763f2016-07-01 23:27:012742 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NETWORK_CHANGED));
2743 EXPECT_THAT(callback.WaitForNestedResult(), IsOk());
[email protected]06f92462010-08-31 19:24:142744}
2745
[email protected]25eea382010-07-10 23:55:262746// Cancel a pending socket request while we're at max sockets,
2747// and verify that the backup socket firing doesn't cause a crash.
2748TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
2749 // Max 4 sockets globally, max 4 sockets per group.
2750 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
[email protected]06d94042010-08-25 01:45:222751 pool_->EnableConnectBackupJobs();
[email protected]25eea382010-07-10 23:55:262752
[email protected]4baaf9d2010-08-31 15:15:442753 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2754 // timer.
[email protected]25eea382010-07-10 23:55:262755 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2756 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522757 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:152758 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542759 handle.Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152760 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202761 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]25eea382010-07-10 23:55:262762
2763 // Start (MaxSockets - 1) connected sockets to reach max sockets.
2764 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2765 ClientSocketHandle handles[kDefaultMaxSockets];
2766 for (int i = 1; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:522767 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:542768 EXPECT_EQ(OK, handles[i].Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:202769 ClientSocketPool::RespectLimits::ENABLED,
2770 callback.callback(), pool_.get(),
2771 NetLogWithSource()));
[email protected]25eea382010-07-10 23:55:262772 }
2773
fdoray5eeb7642016-06-22 16:11:282774 base::RunLoop().RunUntilIdle();
[email protected]25eea382010-07-10 23:55:262775
2776 // Cancel the pending request.
2777 handle.Reset();
2778
2779 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]26b9973962012-01-28 00:57:002780 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2781 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]25eea382010-07-10 23:55:262782
fdoray5eeb7642016-06-22 16:11:282783 base::RunLoop().RunUntilIdle();
[email protected]25eea382010-07-10 23:55:262784 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
2785}
2786
[email protected]3f00be82010-09-27 19:50:022787TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
[email protected]4baaf9d2010-08-31 15:15:442788 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2789 pool_->EnableConnectBackupJobs();
2790
2791 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2792 // timer.
2793 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2794 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522795 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:152796 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542797 handle.Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152798 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202799 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]4baaf9d2010-08-31 15:15:442800 ASSERT_TRUE(pool_->HasGroup("bar"));
2801 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
[email protected]8159a1c2012-06-07 00:00:102802 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("bar"));
[email protected]4baaf9d2010-08-31 15:15:442803
2804 // Cancel the socket request. This should cancel the backup timer. Wait for
2805 // the backup time to see if it indeed got canceled.
2806 handle.Reset();
2807 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]26b9973962012-01-28 00:57:002808 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2809 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
fdoray5eeb7642016-06-22 16:11:282810 base::RunLoop().RunUntilIdle();
[email protected]4baaf9d2010-08-31 15:15:442811 ASSERT_TRUE(pool_->HasGroup("bar"));
2812 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2813}
2814
[email protected]3f00be82010-09-27 19:50:022815TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
2816 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2817 pool_->EnableConnectBackupJobs();
2818
2819 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2820 // timer.
2821 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2822 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522823 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:152824 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542825 handle.Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152826 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202827 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]3f00be82010-09-27 19:50:022828 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2829 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522830 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:202831 EXPECT_EQ(
2832 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542833 handle2.Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:202834 ClientSocketPool::RespectLimits::ENABLED,
2835 callback2.callback(), pool_.get(), NetLogWithSource()));
[email protected]3f00be82010-09-27 19:50:022836 ASSERT_TRUE(pool_->HasGroup("bar"));
2837 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("bar"));
2838
2839 // Cancel request 1 and then complete request 2. With the requests finished,
2840 // the backup timer should be cancelled.
2841 handle.Reset();
robpercival214763f2016-07-01 23:27:012842 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]3f00be82010-09-27 19:50:022843 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]26b9973962012-01-28 00:57:002844 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2845 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
fdoray5eeb7642016-06-22 16:11:282846 base::RunLoop().RunUntilIdle();
[email protected]3f00be82010-09-27 19:50:022847}
2848
[email protected]eb5a99382010-07-11 03:18:262849// Test delayed socket binding for the case where we have two connects,
2850// and while one is waiting on a connect, the other frees up.
2851// The socket waiting on a connect should switch immediately to the freed
2852// up socket.
2853TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
2854 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2855 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2856
2857 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522858 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132859 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542860 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152861 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202862 callback.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:012863 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:262864
2865 // No idle sockets, no pending jobs.
2866 EXPECT_EQ(0, pool_->IdleSocketCount());
2867 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2868
2869 // Create a second socket to the same host, but this one will wait.
2870 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2871 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132872 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542873 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152874 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202875 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:262876 // No idle sockets, and one connecting job.
2877 EXPECT_EQ(0, pool_->IdleSocketCount());
2878 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2879
2880 // Return the first handle to the pool. This will initiate the delayed
2881 // binding.
2882 handle1.Reset();
2883
fdoray5eeb7642016-06-22 16:11:282884 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262885
2886 // Still no idle sockets, still one pending connect job.
2887 EXPECT_EQ(0, pool_->IdleSocketCount());
2888 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2889
2890 // The second socket connected, even though it was a Waiting Job.
robpercival214763f2016-07-01 23:27:012891 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:262892
2893 // And we can see there is still one job waiting.
2894 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2895
2896 // Finally, signal the waiting Connect.
2897 client_socket_factory_.SignalJobs();
2898 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2899
fdoray5eeb7642016-06-22 16:11:282900 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262901}
2902
2903// Test delayed socket binding when a group is at capacity and one
2904// of the group's sockets frees up.
2905TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
2906 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2907 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2908
2909 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522910 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132911 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542912 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152913 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202914 callback.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:012915 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:262916
2917 // No idle sockets, no pending jobs.
2918 EXPECT_EQ(0, pool_->IdleSocketCount());
2919 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2920
2921 // Create a second socket to the same host, but this one will wait.
2922 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2923 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132924 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542925 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152926 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202927 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:262928 // No idle sockets, and one connecting job.
2929 EXPECT_EQ(0, pool_->IdleSocketCount());
2930 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2931
2932 // Return the first handle to the pool. This will initiate the delayed
2933 // binding.
2934 handle1.Reset();
2935
fdoray5eeb7642016-06-22 16:11:282936 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262937
2938 // Still no idle sockets, still one pending connect job.
2939 EXPECT_EQ(0, pool_->IdleSocketCount());
2940 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2941
2942 // The second socket connected, even though it was a Waiting Job.
robpercival214763f2016-07-01 23:27:012943 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:262944
2945 // And we can see there is still one job waiting.
2946 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2947
2948 // Finally, signal the waiting Connect.
2949 client_socket_factory_.SignalJobs();
2950 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2951
fdoray5eeb7642016-06-22 16:11:282952 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262953}
2954
2955// Test out the case where we have one socket connected, one
2956// connecting, when the first socket finishes and goes idle.
[email protected]2abfe90a2010-08-25 17:49:512957// Although the second connection is pending, the second request
[email protected]eb5a99382010-07-11 03:18:262958// should complete, by taking the first socket's idle socket.
2959TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
2960 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2961 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2962
2963 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522964 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132965 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542966 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152967 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202968 callback.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:012969 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:262970
2971 // No idle sockets, no pending jobs.
2972 EXPECT_EQ(0, pool_->IdleSocketCount());
2973 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2974
2975 // Create a second socket to the same host, but this one will wait.
2976 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2977 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132978 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542979 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152980 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202981 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:262982 // No idle sockets, and one connecting job.
2983 EXPECT_EQ(0, pool_->IdleSocketCount());
2984 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2985
2986 // Return the first handle to the pool. This will initiate the delayed
2987 // binding.
2988 handle1.Reset();
2989
fdoray5eeb7642016-06-22 16:11:282990 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262991
2992 // Still no idle sockets, still one pending connect job.
2993 EXPECT_EQ(0, pool_->IdleSocketCount());
2994 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2995
2996 // The second socket connected, even though it was a Waiting Job.
robpercival214763f2016-07-01 23:27:012997 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:262998
2999 // And we can see there is still one job waiting.
3000 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3001
3002 // Finally, signal the waiting Connect.
3003 client_socket_factory_.SignalJobs();
3004 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3005
fdoray5eeb7642016-06-22 16:11:283006 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263007}
3008
[email protected]2abfe90a2010-08-25 17:49:513009// Cover the case where on an available socket slot, we have one pending
3010// request that completes synchronously, thereby making the Group empty.
3011TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
3012 const int kUnlimitedSockets = 100;
3013 const int kOneSocketPerGroup = 1;
3014 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
3015
3016 // Make the first request asynchronous fail.
3017 // This will free up a socket slot later.
3018 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
3019
3020 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523021 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203022 EXPECT_EQ(
3023 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543024 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203025 ClientSocketPool::RespectLimits::ENABLED,
3026 callback1.callback(), pool_.get(), NetLogWithSource()));
[email protected]2abfe90a2010-08-25 17:49:513027 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3028
3029 // Make the second request synchronously fail. This should make the Group
3030 // empty.
3031 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3032 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523033 TestCompletionCallback callback2;
[email protected]2abfe90a2010-08-25 17:49:513034 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
3035 // when created.
tfarina428341112016-09-22 13:38:203036 EXPECT_EQ(
3037 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543038 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203039 ClientSocketPool::RespectLimits::ENABLED,
3040 callback2.callback(), pool_.get(), NetLogWithSource()));
[email protected]2abfe90a2010-08-25 17:49:513041
3042 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3043
robpercival214763f2016-07-01 23:27:013044 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
3045 EXPECT_THAT(callback2.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]2abfe90a2010-08-25 17:49:513046 EXPECT_FALSE(pool_->HasGroup("a"));
3047}
3048
[email protected]e1b54dc2010-10-06 21:27:223049TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
3050 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3051
3052 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3053
3054 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523055 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203056 EXPECT_EQ(
3057 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543058 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203059 ClientSocketPool::RespectLimits::ENABLED,
3060 callback1.callback(), pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223061
3062 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523063 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203064 EXPECT_EQ(
3065 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543066 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203067 ClientSocketPool::RespectLimits::ENABLED,
3068 callback2.callback(), pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223069 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:523070 TestCompletionCallback callback3;
tfarina428341112016-09-22 13:38:203071 EXPECT_EQ(
3072 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543073 handle3.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203074 ClientSocketPool::RespectLimits::ENABLED,
3075 callback3.callback(), pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223076
robpercival214763f2016-07-01 23:27:013077 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3078 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3079 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]e1b54dc2010-10-06 21:27:223080
3081 // Use the socket.
Ramin Halavati0a08cc82018-02-06 07:46:383082 EXPECT_EQ(1, handle1.socket()->Write(NULL, 1, CompletionCallback(),
3083 TRAFFIC_ANNOTATION_FOR_TESTS));
3084 EXPECT_EQ(1, handle3.socket()->Write(NULL, 1, CompletionCallback(),
3085 TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]e1b54dc2010-10-06 21:27:223086
3087 handle1.Reset();
3088 handle2.Reset();
3089 handle3.Reset();
3090
tfarina428341112016-09-22 13:38:203091 EXPECT_EQ(
Paul Jensen8d6f87ec2018-01-13 00:46:543092 OK, handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203093 ClientSocketPool::RespectLimits::ENABLED,
3094 callback1.callback(), pool_.get(), NetLogWithSource()));
3095 EXPECT_EQ(
Paul Jensen8d6f87ec2018-01-13 00:46:543096 OK, handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203097 ClientSocketPool::RespectLimits::ENABLED,
3098 callback2.callback(), pool_.get(), NetLogWithSource()));
3099 EXPECT_EQ(
Paul Jensen8d6f87ec2018-01-13 00:46:543100 OK, handle3.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203101 ClientSocketPool::RespectLimits::ENABLED,
3102 callback3.callback(), pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223103
3104 EXPECT_TRUE(handle1.socket()->WasEverUsed());
3105 EXPECT_TRUE(handle2.socket()->WasEverUsed());
3106 EXPECT_FALSE(handle3.socket()->WasEverUsed());
3107}
3108
[email protected]2c2bef152010-10-13 00:55:033109TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
3110 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3111 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3112
Alexandr Ilin65ec9582017-10-02 14:50:313113 pool_->RequestSockets("a", &params_, 2, NetLogWithSource(),
3114 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033115
3116 ASSERT_TRUE(pool_->HasGroup("a"));
3117 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103118 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033119 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3120
3121 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523122 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203123 EXPECT_EQ(
3124 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543125 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203126 ClientSocketPool::RespectLimits::ENABLED,
3127 callback1.callback(), pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033128
3129 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523130 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203131 EXPECT_EQ(
3132 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543133 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203134 ClientSocketPool::RespectLimits::ENABLED,
3135 callback2.callback(), pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033136
3137 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103138 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033139 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3140
robpercival214763f2016-07-01 23:27:013141 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3142 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033143 handle1.Reset();
3144 handle2.Reset();
3145
3146 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103147 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033148 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3149}
3150
3151TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
3152 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3153 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3154
3155 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523156 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203157 EXPECT_EQ(
3158 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543159 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203160 ClientSocketPool::RespectLimits::ENABLED,
3161 callback1.callback(), pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033162
3163 ASSERT_TRUE(pool_->HasGroup("a"));
3164 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103165 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033166 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3167
Alexandr Ilin65ec9582017-10-02 14:50:313168 pool_->RequestSockets("a", &params_, 2, NetLogWithSource(),
3169 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033170
3171 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103172 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033173 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3174
3175 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523176 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203177 EXPECT_EQ(
3178 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543179 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203180 ClientSocketPool::RespectLimits::ENABLED,
3181 callback2.callback(), pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033182
3183 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103184 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033185 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3186
robpercival214763f2016-07-01 23:27:013187 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3188 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033189 handle1.Reset();
3190 handle2.Reset();
3191
3192 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103193 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033194 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3195}
3196
3197TEST_F(ClientSocketPoolBaseTest,
3198 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
3199 CreatePool(4, 4);
3200 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3201
3202 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523203 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203204 EXPECT_EQ(
3205 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543206 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203207 ClientSocketPool::RespectLimits::ENABLED,
3208 callback1.callback(), pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033209
3210 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523211 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203212 EXPECT_EQ(
3213 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543214 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203215 ClientSocketPool::RespectLimits::ENABLED,
3216 callback2.callback(), pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033217
3218 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:523219 TestCompletionCallback callback3;
tfarina428341112016-09-22 13:38:203220 EXPECT_EQ(
3221 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543222 handle3.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203223 ClientSocketPool::RespectLimits::ENABLED,
3224 callback3.callback(), pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033225
3226 ASSERT_TRUE(pool_->HasGroup("a"));
3227 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103228 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033229 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3230
Alexandr Ilin65ec9582017-10-02 14:50:313231 pool_->RequestSockets("a", &params_, 2, NetLogWithSource(),
3232 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033233
3234 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("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
robpercival214763f2016-07-01 23:27:013238 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3239 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3240 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033241 handle1.Reset();
3242 handle2.Reset();
3243 handle3.Reset();
3244
3245 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103246 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033247 EXPECT_EQ(3, pool_->IdleSocketCountInGroup("a"));
3248}
3249
3250TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
3251 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3252 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3253
3254 ASSERT_FALSE(pool_->HasGroup("a"));
3255
Alexandr Ilin65ec9582017-10-02 14:50:313256 pool_->RequestSockets("a", &params_, kDefaultMaxSockets, NetLogWithSource(),
3257 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033258
3259 ASSERT_TRUE(pool_->HasGroup("a"));
3260 EXPECT_EQ(kDefaultMaxSockets, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103261 EXPECT_EQ(kDefaultMaxSockets, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033262
3263 ASSERT_FALSE(pool_->HasGroup("b"));
3264
Alexandr Ilin65ec9582017-10-02 14:50:313265 pool_->RequestSockets("b", &params_, kDefaultMaxSockets, NetLogWithSource(),
3266 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033267
3268 ASSERT_FALSE(pool_->HasGroup("b"));
3269}
3270
3271TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
3272 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3273 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3274
3275 ASSERT_FALSE(pool_->HasGroup("a"));
3276
3277 pool_->RequestSockets("a", &params_, kDefaultMaxSockets - 1,
Alexandr Ilin65ec9582017-10-02 14:50:313278 NetLogWithSource(), HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033279
3280 ASSERT_TRUE(pool_->HasGroup("a"));
3281 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103282 EXPECT_EQ(kDefaultMaxSockets - 1,
3283 pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]51fdc7c2012-04-10 19:19:483284 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033285
3286 ASSERT_FALSE(pool_->HasGroup("b"));
3287
Alexandr Ilin65ec9582017-10-02 14:50:313288 pool_->RequestSockets("b", &params_, kDefaultMaxSockets, NetLogWithSource(),
3289 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033290
3291 ASSERT_TRUE(pool_->HasGroup("b"));
3292 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("b"));
[email protected]51fdc7c2012-04-10 19:19:483293 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033294}
3295
3296TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
3297 CreatePool(4, 4);
3298 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3299
3300 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523301 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203302 EXPECT_EQ(
3303 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543304 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203305 ClientSocketPool::RespectLimits::ENABLED,
3306 callback1.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013307 ASSERT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033308 handle1.Reset();
3309
3310 ASSERT_TRUE(pool_->HasGroup("a"));
3311 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103312 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033313 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3314
Alexandr Ilin65ec9582017-10-02 14:50:313315 pool_->RequestSockets("a", &params_, 2, NetLogWithSource(),
3316 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033317
3318 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103319 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033320 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3321}
3322
3323TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
3324 CreatePool(4, 4);
3325 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3326
3327 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523328 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203329 EXPECT_EQ(
3330 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543331 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203332 ClientSocketPool::RespectLimits::ENABLED,
3333 callback1.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013334 ASSERT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033335
3336 ASSERT_TRUE(pool_->HasGroup("a"));
3337 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103338 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033339 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3340 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3341
Alexandr Ilin65ec9582017-10-02 14:50:313342 pool_->RequestSockets("a", &params_, 2, NetLogWithSource(),
3343 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033344
3345 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103346 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033347 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3348 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3349}
3350
3351TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
3352 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3353 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3354
3355 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
Alexandr Ilin65ec9582017-10-02 14:50:313356 NetLogWithSource(), HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033357
3358 ASSERT_TRUE(pool_->HasGroup("a"));
3359 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103360 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033361 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("a"));
3362
3363 pool_->RequestSockets("b", &params_, kDefaultMaxSocketsPerGroup,
Alexandr Ilin65ec9582017-10-02 14:50:313364 NetLogWithSource(), HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033365
3366 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103367 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]2c2bef152010-10-13 00:55:033368 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("b"));
3369}
3370
[email protected]3c819f522010-12-02 02:03:123371TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
3372 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3373 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3374
3375 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
Alexandr Ilin65ec9582017-10-02 14:50:313376 NetLogWithSource(), HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]3c819f522010-12-02 02:03:123377
3378 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]fd2e53e2011-01-14 20:40:523379
3380 connect_job_factory_->set_job_type(
3381 TestConnectJob::kMockAdditionalErrorStateJob);
3382 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
Alexandr Ilin65ec9582017-10-02 14:50:313383 NetLogWithSource(), HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]fd2e53e2011-01-14 20:40:523384
3385 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]3c819f522010-12-02 02:03:123386}
3387
[email protected]8159a1c2012-06-07 00:00:103388TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
[email protected]2c2bef152010-10-13 00:55:033389 CreatePool(4, 4);
3390 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3391
Alexandr Ilin65ec9582017-10-02 14:50:313392 pool_->RequestSockets("a", &params_, 2, NetLogWithSource(),
3393 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033394
3395 ASSERT_TRUE(pool_->HasGroup("a"));
3396 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103397 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033398 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3399
Alexandr Ilin65ec9582017-10-02 14:50:313400 pool_->RequestSockets("a", &params_, 2, NetLogWithSource(),
3401 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033402 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103403 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033404 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3405
3406 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523407 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203408 EXPECT_EQ(
3409 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543410 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203411 ClientSocketPool::RespectLimits::ENABLED,
3412 callback1.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013413 ASSERT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033414
3415 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523416 TestCompletionCallback callback2;
Paul Jensen8d6f87ec2018-01-13 00:46:543417 int rv = handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:153418 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:203419 callback2.callback(), pool_.get(), NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033420 if (rv != OK) {
robpercival214763f2016-07-01 23:27:013421 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3422 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033423 }
3424
[email protected]8159a1c2012-06-07 00:00:103425 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3426 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3427 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("a"));
3428 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3429
[email protected]2c2bef152010-10-13 00:55:033430 handle1.Reset();
3431 handle2.Reset();
3432
[email protected]8159a1c2012-06-07 00:00:103433 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3434 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033435 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3436
Alexandr Ilin65ec9582017-10-02 14:50:313437 pool_->RequestSockets("a", &params_, 2, NetLogWithSource(),
3438 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033439 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103440 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033441 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3442}
3443
3444TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
3445 CreatePool(4, 4);
3446 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3447
Alexandr Ilin65ec9582017-10-02 14:50:313448 pool_->RequestSockets("a", &params_, 1, NetLogWithSource(),
3449 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033450
3451 ASSERT_TRUE(pool_->HasGroup("a"));
3452 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103453 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033454 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3455
Alexandr Ilin65ec9582017-10-02 14:50:313456 pool_->RequestSockets("a", &params_, 2, NetLogWithSource(),
3457 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033458 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103459 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033460 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3461
Alexandr Ilin65ec9582017-10-02 14:50:313462 pool_->RequestSockets("a", &params_, 3, NetLogWithSource(),
3463 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033464 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103465 EXPECT_EQ(3, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033466 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3467
Alexandr Ilin65ec9582017-10-02 14:50:313468 pool_->RequestSockets("a", &params_, 1, NetLogWithSource(),
3469 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033470 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103471 EXPECT_EQ(3, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033472 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3473}
3474
3475TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
3476 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3477 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3478
Alexandr Ilin65ec9582017-10-02 14:50:313479 pool_->RequestSockets("a", &params_, 1, NetLogWithSource(),
3480 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033481
3482 ASSERT_TRUE(pool_->HasGroup("a"));
3483 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103484 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033485 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3486
3487 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523488 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203489 EXPECT_EQ(
3490 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543491 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203492 ClientSocketPool::RespectLimits::ENABLED,
3493 callback1.callback(), pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033494
3495 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103496 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033497 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3498
robpercival214763f2016-07-01 23:27:013499 ASSERT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033500
[email protected]0dc88b32014-03-26 20:12:283501 // Make sure if a preconnected socket is not fully connected when a request
[email protected]034df0f32013-01-07 23:17:483502 // starts, it has a connect start time.
3503 TestLoadTimingInfoConnectedNotReused(handle1);
[email protected]2c2bef152010-10-13 00:55:033504 handle1.Reset();
3505
3506 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3507}
3508
[email protected]034df0f32013-01-07 23:17:483509// Checks that fully connected preconnect jobs have no connect times, and are
3510// marked as reused.
3511TEST_F(ClientSocketPoolBaseTest, ConnectedPreconnectJobsHaveNoConnectTimes) {
3512 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3513 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
Alexandr Ilin65ec9582017-10-02 14:50:313514 pool_->RequestSockets("a", &params_, 1, NetLogWithSource(),
3515 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]034df0f32013-01-07 23:17:483516
3517 ASSERT_TRUE(pool_->HasGroup("a"));
3518 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3519 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3520 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3521
3522 ClientSocketHandle handle;
3523 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:203524 EXPECT_EQ(OK,
Paul Jensen8d6f87ec2018-01-13 00:46:543525 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203526 ClientSocketPool::RespectLimits::ENABLED,
3527 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]034df0f32013-01-07 23:17:483528
3529 // Make sure the idle socket was used.
3530 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3531
3532 TestLoadTimingInfoConnectedReused(handle);
3533 handle.Reset();
3534 TestLoadTimingInfoNotConnected(handle);
3535}
3536
[email protected]dcbe168a2010-12-02 03:14:463537// http://crbug.com/64940 regression test.
3538TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
3539 const int kMaxTotalSockets = 3;
3540 const int kMaxSocketsPerGroup = 2;
3541 CreatePool(kMaxTotalSockets, kMaxSocketsPerGroup);
3542 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3543
3544 // Note that group name ordering matters here. "a" comes before "b", so
3545 // CloseOneIdleSocket() will try to close "a"'s idle socket.
3546
3547 // Set up one idle socket in "a".
3548 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523549 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203550 EXPECT_EQ(
3551 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543552 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203553 ClientSocketPool::RespectLimits::ENABLED,
3554 callback1.callback(), pool_.get(), NetLogWithSource()));
[email protected]dcbe168a2010-12-02 03:14:463555
robpercival214763f2016-07-01 23:27:013556 ASSERT_THAT(callback1.WaitForResult(), IsOk());
[email protected]dcbe168a2010-12-02 03:14:463557 handle1.Reset();
3558 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3559
3560 // Set up two active sockets in "b".
3561 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523562 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203563 EXPECT_EQ(
3564 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543565 handle1.Init("b", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203566 ClientSocketPool::RespectLimits::ENABLED,
3567 callback1.callback(), pool_.get(), NetLogWithSource()));
3568 EXPECT_EQ(
3569 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543570 handle2.Init("b", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203571 ClientSocketPool::RespectLimits::ENABLED,
3572 callback2.callback(), pool_.get(), NetLogWithSource()));
[email protected]dcbe168a2010-12-02 03:14:463573
robpercival214763f2016-07-01 23:27:013574 ASSERT_THAT(callback1.WaitForResult(), IsOk());
3575 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]dcbe168a2010-12-02 03:14:463576 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103577 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463578 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3579
3580 // Now we have 1 idle socket in "a" and 2 active sockets in "b". This means
3581 // we've maxed out on sockets, since we set |kMaxTotalSockets| to 3.
3582 // Requesting 2 preconnected sockets for "a" should fail to allocate any more
3583 // sockets for "a", and "b" should still have 2 active sockets.
3584
Alexandr Ilin65ec9582017-10-02 14:50:313585 pool_->RequestSockets("a", &params_, 2, NetLogWithSource(),
3586 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]dcbe168a2010-12-02 03:14:463587 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103588 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]dcbe168a2010-12-02 03:14:463589 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3590 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3591 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103592 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463593 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3594 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3595
3596 // Now release the 2 active sockets for "b". This will give us 1 idle socket
3597 // in "a" and 2 idle sockets in "b". Requesting 2 preconnected sockets for
3598 // "a" should result in closing 1 for "b".
3599 handle1.Reset();
3600 handle2.Reset();
3601 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("b"));
3602 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3603
Alexandr Ilin65ec9582017-10-02 14:50:313604 pool_->RequestSockets("a", &params_, 2, NetLogWithSource(),
3605 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]dcbe168a2010-12-02 03:14:463606 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103607 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]dcbe168a2010-12-02 03:14:463608 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3609 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3610 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103611 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463612 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("b"));
3613 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3614}
3615
[email protected]b7b8be42011-07-12 12:46:413616TEST_F(ClientSocketPoolBaseTest, PreconnectWithoutBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073617 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3618 pool_->EnableConnectBackupJobs();
3619
3620 // Make the ConnectJob hang until it times out, shorten the timeout.
3621 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3622 connect_job_factory_->set_timeout_duration(
3623 base::TimeDelta::FromMilliseconds(500));
Alexandr Ilin65ec9582017-10-02 14:50:313624 pool_->RequestSockets("a", &params_, 1, NetLogWithSource(),
3625 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]a9fc8fc2011-05-10 02:41:073626 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103627 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073628 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073629
[email protected]b7b8be42011-07-12 12:46:413630 // Verify the backup timer doesn't create a backup job, by making
3631 // the backup job a pending job instead of a waiting job, so it
3632 // *would* complete if it were created.
[email protected]a9fc8fc2011-05-10 02:41:073633 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
skyostil4891b25b2015-06-11 11:43:453634 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
ki.stfu375812e2015-10-09 20:23:173635 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
[email protected]2da659e2013-05-23 20:51:343636 base::TimeDelta::FromSeconds(1));
fdoray5eeb7642016-06-22 16:11:283637 base::RunLoop().Run();
[email protected]a9fc8fc2011-05-10 02:41:073638 EXPECT_FALSE(pool_->HasGroup("a"));
3639}
3640
[email protected]b7b8be42011-07-12 12:46:413641TEST_F(ClientSocketPoolBaseTest, PreconnectWithBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073642 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3643 pool_->EnableConnectBackupJobs();
3644
3645 // Make the ConnectJob hang forever.
3646 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
Alexandr Ilin65ec9582017-10-02 14:50:313647 pool_->RequestSockets("a", &params_, 1, NetLogWithSource(),
3648 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]a9fc8fc2011-05-10 02:41:073649 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103650 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073651 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
fdoray5eeb7642016-06-22 16:11:283652 base::RunLoop().RunUntilIdle();
[email protected]a9fc8fc2011-05-10 02:41:073653
3654 // Make the backup job be a pending job, so it completes normally.
3655 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3656 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:523657 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:153658 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543659 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:153660 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:203661 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]b7b8be42011-07-12 12:46:413662 // Timer has started, but the backup connect job shouldn't be created yet.
[email protected]a9fc8fc2011-05-10 02:41:073663 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103664 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073665 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3666 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
robpercival214763f2016-07-01 23:27:013667 ASSERT_THAT(callback.WaitForResult(), IsOk());
[email protected]a9fc8fc2011-05-10 02:41:073668
3669 // The hung connect job should still be there, but everything else should be
3670 // complete.
3671 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103672 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073673 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3674 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3675}
3676
[email protected]0dc88b32014-03-26 20:12:283677// Tests that a preconnect that starts out with unread data can still be used.
3678// http://crbug.com/334467
3679TEST_F(ClientSocketPoolBaseTest, PreconnectWithUnreadData) {
3680 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3681 connect_job_factory_->set_job_type(TestConnectJob::kMockUnreadDataJob);
3682
Alexandr Ilin65ec9582017-10-02 14:50:313683 pool_->RequestSockets("a", &params_, 1, NetLogWithSource(),
3684 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]0dc88b32014-03-26 20:12:283685
3686 ASSERT_TRUE(pool_->HasGroup("a"));
3687 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3688 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3689 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3690
3691 // Fail future jobs to be sure that handle receives the preconnected socket
3692 // rather than closing it and making a new one.
3693 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3694 ClientSocketHandle handle;
3695 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:203696 EXPECT_EQ(OK,
Paul Jensen8d6f87ec2018-01-13 00:46:543697 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203698 ClientSocketPool::RespectLimits::ENABLED,
3699 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]0dc88b32014-03-26 20:12:283700
3701 ASSERT_TRUE(pool_->HasGroup("a"));
3702 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3703 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3704 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3705
3706 // Drain the pending read.
3707 EXPECT_EQ(1, handle.socket()->Read(NULL, 1, CompletionCallback()));
3708
3709 TestLoadTimingInfoConnectedReused(handle);
3710 handle.Reset();
3711
3712 // The socket should be usable now that it's idle again.
3713 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3714}
3715
Alexandr Ilin65ec9582017-10-02 14:50:313716// Tests that a socket pool correctly sets a motivation for a preconnected
3717// socket.
3718TEST_F(ClientSocketPoolBaseTest, PreconnectSetsMotivation) {
3719 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3720 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3721
3722 for (auto motivation : {HttpRequestInfo::NORMAL_MOTIVATION,
3723 HttpRequestInfo::PRECONNECT_MOTIVATED,
3724 HttpRequestInfo::OMNIBOX_MOTIVATED}) {
3725 SCOPED_TRACE(::testing::Message() << "motivation: " << motivation);
3726 pool_->RequestSockets("a", &params_, 1, NetLogWithSource(), motivation);
3727
3728 ClientSocketHandle handle;
3729 TestCompletionCallback callback;
3730 EXPECT_EQ(
3731 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543732 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
Alexandr Ilin65ec9582017-10-02 14:50:313733 ClientSocketPool::RespectLimits::ENABLED,
3734 callback.callback(), pool_.get(), NetLogWithSource()));
3735
3736 EXPECT_THAT(callback.WaitForResult(), IsOk());
3737 EXPECT_TRUE(handle.is_initialized());
3738 ASSERT_TRUE(handle.socket());
3739 EXPECT_EQ(motivation,
3740 static_cast<MockClientSocket*>(handle.socket())->motivation());
3741 handle.socket()->Disconnect();
3742 handle.Reset();
3743 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3744 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3745 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3746 }
3747}
3748
3749// Tests that a socket pool doesn't change motivation on existing sockets.
3750TEST_F(ClientSocketPoolBaseTest, PreconnectPreservesExistingMotivation) {
3751 CreatePool(3, 3);
3752 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3753
3754 // We should get one socket of each motivation.
3755 pool_->RequestSockets("a", &params_, 1, NetLogWithSource(),
3756 HttpRequestInfo::NORMAL_MOTIVATION);
3757 pool_->RequestSockets("a", &params_, 2, NetLogWithSource(),
3758 HttpRequestInfo::PRECONNECT_MOTIVATED);
3759 pool_->RequestSockets("a", &params_, 3, NetLogWithSource(),
3760 HttpRequestInfo::OMNIBOX_MOTIVATED);
3761
3762 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
3763 EXPECT_EQ(3, pool_->NumUnassignedConnectJobsInGroup("a"));
3764 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3765
3766 std::vector<ClientSocketHandle> handles(3);
3767 std::vector<TestCompletionCallback> callbacks(3);
3768
3769 for (size_t i = 0; i < 3; ++i) {
3770 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543771 handles[i].Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
Alexandr Ilin65ec9582017-10-02 14:50:313772 ClientSocketPool::RespectLimits::ENABLED,
3773 callbacks[i].callback(), pool_.get(),
3774 NetLogWithSource()));
3775 }
3776
3777 for (size_t i = 0; i < 3; ++i) {
3778 EXPECT_THAT(callbacks[i].WaitForResult(), IsOk());
3779 EXPECT_TRUE(handles[i].is_initialized());
3780 EXPECT_TRUE(handles[i].socket());
3781 }
3782
3783 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3784 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3785 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3786 EXPECT_EQ(3, pool_->NumActiveSocketsInGroup("a"));
3787
3788 EXPECT_EQ(HttpRequestInfo::NORMAL_MOTIVATION,
3789 static_cast<MockClientSocket*>(handles[0].socket())->motivation());
3790 EXPECT_EQ(HttpRequestInfo::PRECONNECT_MOTIVATED,
3791 static_cast<MockClientSocket*>(handles[1].socket())->motivation());
3792 EXPECT_EQ(HttpRequestInfo::OMNIBOX_MOTIVATED,
3793 static_cast<MockClientSocket*>(handles[2].socket())->motivation());
3794}
3795
[email protected]043b68c82013-08-22 23:41:523796class MockLayeredPool : public HigherLayeredPool {
[email protected]58e562f2013-04-22 17:32:203797 public:
3798 MockLayeredPool(TestClientSocketPool* pool,
3799 const std::string& group_name)
3800 : pool_(pool),
[email protected]58e562f2013-04-22 17:32:203801 group_name_(group_name),
3802 can_release_connection_(true) {
[email protected]043b68c82013-08-22 23:41:523803 pool_->AddHigherLayeredPool(this);
[email protected]58e562f2013-04-22 17:32:203804 }
3805
3806 ~MockLayeredPool() {
[email protected]043b68c82013-08-22 23:41:523807 pool_->RemoveHigherLayeredPool(this);
[email protected]58e562f2013-04-22 17:32:203808 }
3809
3810 int RequestSocket(TestClientSocketPool* pool) {
mmenked3641e12016-01-28 16:06:153811 scoped_refptr<TestSocketParams> params(new TestSocketParams());
Paul Jensen8d6f87ec2018-01-13 00:46:543812 return handle_.Init(group_name_, params, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:153813 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:203814 callback_.callback(), pool, NetLogWithSource());
[email protected]58e562f2013-04-22 17:32:203815 }
3816
3817 int RequestSocketWithoutLimits(TestClientSocketPool* pool) {
mmenked3641e12016-01-28 16:06:153818 scoped_refptr<TestSocketParams> params(new TestSocketParams());
Paul Jensen8d6f87ec2018-01-13 00:46:543819 return handle_.Init(group_name_, params, MAXIMUM_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:153820 ClientSocketPool::RespectLimits::DISABLED,
tfarina428341112016-09-22 13:38:203821 callback_.callback(), pool, NetLogWithSource());
[email protected]58e562f2013-04-22 17:32:203822 }
3823
3824 bool ReleaseOneConnection() {
3825 if (!handle_.is_initialized() || !can_release_connection_) {
3826 return false;
3827 }
3828 handle_.socket()->Disconnect();
3829 handle_.Reset();
3830 return true;
3831 }
3832
3833 void set_can_release_connection(bool can_release_connection) {
3834 can_release_connection_ = can_release_connection;
3835 }
3836
3837 MOCK_METHOD0(CloseOneIdleConnection, bool());
3838
3839 private:
3840 TestClientSocketPool* const pool_;
[email protected]58e562f2013-04-22 17:32:203841 ClientSocketHandle handle_;
3842 TestCompletionCallback callback_;
3843 const std::string group_name_;
3844 bool can_release_connection_;
3845};
3846
3847TEST_F(ClientSocketPoolBaseTest, FailToCloseIdleSocketsNotHeldByLayeredPool) {
3848 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3849 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3850
3851 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
robpercival214763f2016-07-01 23:27:013852 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:203853 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3854 .WillOnce(Return(false));
[email protected]043b68c82013-08-22 23:41:523855 EXPECT_FALSE(pool_->CloseOneIdleConnectionInHigherLayeredPool());
[email protected]58e562f2013-04-22 17:32:203856}
3857
3858TEST_F(ClientSocketPoolBaseTest, ForciblyCloseIdleSocketsHeldByLayeredPool) {
3859 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3860 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3861
3862 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
robpercival214763f2016-07-01 23:27:013863 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:203864 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3865 .WillOnce(Invoke(&mock_layered_pool,
3866 &MockLayeredPool::ReleaseOneConnection));
[email protected]043b68c82013-08-22 23:41:523867 EXPECT_TRUE(pool_->CloseOneIdleConnectionInHigherLayeredPool());
[email protected]58e562f2013-04-22 17:32:203868}
3869
3870// Tests the basic case of closing an idle socket in a higher layered pool when
3871// a new request is issued and the lower layer pool is stalled.
3872TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsHeldByLayeredPoolWhenNeeded) {
3873 CreatePool(1, 1);
3874 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3875
3876 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
robpercival214763f2016-07-01 23:27:013877 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:203878 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3879 .WillOnce(Invoke(&mock_layered_pool,
3880 &MockLayeredPool::ReleaseOneConnection));
3881 ClientSocketHandle handle;
3882 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:153883 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543884 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:153885 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:203886 callback.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013887 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:203888}
3889
3890// Same as above, but the idle socket is in the same group as the stalled
3891// socket, and closes the only other request in its group when closing requests
3892// in higher layered pools. This generally shouldn't happen, but it may be
3893// possible if a higher level pool issues a request and the request is
3894// subsequently cancelled. Even if it's not possible, best not to crash.
3895TEST_F(ClientSocketPoolBaseTest,
3896 CloseIdleSocketsHeldByLayeredPoolWhenNeededSameGroup) {
3897 CreatePool(2, 2);
3898 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3899
3900 // Need a socket in another group for the pool to be stalled (If a group
3901 // has the maximum number of connections already, it's not stalled).
3902 ClientSocketHandle handle1;
3903 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203904 EXPECT_EQ(
Paul Jensen8d6f87ec2018-01-13 00:46:543905 OK, handle1.Init("group1", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203906 ClientSocketPool::RespectLimits::ENABLED,
3907 callback1.callback(), pool_.get(), NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:203908
3909 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
robpercival214763f2016-07-01 23:27:013910 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:203911 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3912 .WillOnce(Invoke(&mock_layered_pool,
3913 &MockLayeredPool::ReleaseOneConnection));
3914 ClientSocketHandle handle;
3915 TestCompletionCallback callback2;
mmenked3641e12016-01-28 16:06:153916 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543917 handle.Init("group2", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:153918 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:203919 callback2.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013920 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:203921}
3922
3923// Tests the case when an idle socket can be closed when a new request is
3924// issued, and the new request belongs to a group that was previously stalled.
3925TEST_F(ClientSocketPoolBaseTest,
3926 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded) {
3927 CreatePool(2, 2);
3928 std::list<TestConnectJob::JobType> job_types;
3929 job_types.push_back(TestConnectJob::kMockJob);
3930 job_types.push_back(TestConnectJob::kMockJob);
3931 job_types.push_back(TestConnectJob::kMockJob);
3932 job_types.push_back(TestConnectJob::kMockJob);
3933 connect_job_factory_->set_job_types(&job_types);
3934
3935 ClientSocketHandle handle1;
3936 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203937 EXPECT_EQ(
Paul Jensen8d6f87ec2018-01-13 00:46:543938 OK, handle1.Init("group1", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203939 ClientSocketPool::RespectLimits::ENABLED,
3940 callback1.callback(), pool_.get(), NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:203941
3942 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
robpercival214763f2016-07-01 23:27:013943 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:203944 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3945 .WillRepeatedly(Invoke(&mock_layered_pool,
3946 &MockLayeredPool::ReleaseOneConnection));
3947 mock_layered_pool.set_can_release_connection(false);
3948
3949 // The third request is made when the socket pool is in a stalled state.
3950 ClientSocketHandle handle3;
3951 TestCompletionCallback callback3;
tfarina428341112016-09-22 13:38:203952 EXPECT_EQ(
3953 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543954 handle3.Init("group3", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203955 ClientSocketPool::RespectLimits::ENABLED,
3956 callback3.callback(), pool_.get(), NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:203957
3958 base::RunLoop().RunUntilIdle();
3959 EXPECT_FALSE(callback3.have_result());
3960
3961 // The fourth request is made when the pool is no longer stalled. The third
3962 // request should be serviced first, since it was issued first and has the
3963 // same priority.
3964 mock_layered_pool.set_can_release_connection(true);
3965 ClientSocketHandle handle4;
3966 TestCompletionCallback callback4;
tfarina428341112016-09-22 13:38:203967 EXPECT_EQ(
3968 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543969 handle4.Init("group3", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203970 ClientSocketPool::RespectLimits::ENABLED,
3971 callback4.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013972 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:203973 EXPECT_FALSE(callback4.have_result());
3974
3975 // Closing a handle should free up another socket slot.
3976 handle1.Reset();
robpercival214763f2016-07-01 23:27:013977 EXPECT_THAT(callback4.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:203978}
3979
3980// Tests the case when an idle socket can be closed when a new request is
3981// issued, and the new request belongs to a group that was previously stalled.
3982//
3983// The two differences from the above test are that the stalled requests are not
3984// in the same group as the layered pool's request, and the the fourth request
3985// has a higher priority than the third one, so gets a socket first.
3986TEST_F(ClientSocketPoolBaseTest,
3987 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded2) {
3988 CreatePool(2, 2);
3989 std::list<TestConnectJob::JobType> job_types;
3990 job_types.push_back(TestConnectJob::kMockJob);
3991 job_types.push_back(TestConnectJob::kMockJob);
3992 job_types.push_back(TestConnectJob::kMockJob);
3993 job_types.push_back(TestConnectJob::kMockJob);
3994 connect_job_factory_->set_job_types(&job_types);
3995
3996 ClientSocketHandle handle1;
3997 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203998 EXPECT_EQ(
Paul Jensen8d6f87ec2018-01-13 00:46:543999 OK, handle1.Init("group1", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:204000 ClientSocketPool::RespectLimits::ENABLED,
4001 callback1.callback(), pool_.get(), NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204002
4003 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
robpercival214763f2016-07-01 23:27:014004 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204005 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4006 .WillRepeatedly(Invoke(&mock_layered_pool,
4007 &MockLayeredPool::ReleaseOneConnection));
4008 mock_layered_pool.set_can_release_connection(false);
4009
4010 // The third request is made when the socket pool is in a stalled state.
4011 ClientSocketHandle handle3;
4012 TestCompletionCallback callback3;
tfarina428341112016-09-22 13:38:204013 EXPECT_EQ(
4014 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:544015 handle3.Init("group3", params_, MEDIUM, SocketTag(),
tfarina428341112016-09-22 13:38:204016 ClientSocketPool::RespectLimits::ENABLED,
4017 callback3.callback(), pool_.get(), NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204018
4019 base::RunLoop().RunUntilIdle();
4020 EXPECT_FALSE(callback3.have_result());
4021
4022 // The fourth request is made when the pool is no longer stalled. This
4023 // request has a higher priority than the third request, so is serviced first.
4024 mock_layered_pool.set_can_release_connection(true);
4025 ClientSocketHandle handle4;
4026 TestCompletionCallback callback4;
tfarina428341112016-09-22 13:38:204027 EXPECT_EQ(
4028 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:544029 handle4.Init("group3", params_, HIGHEST, SocketTag(),
tfarina428341112016-09-22 13:38:204030 ClientSocketPool::RespectLimits::ENABLED,
4031 callback4.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:014032 EXPECT_THAT(callback4.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204033 EXPECT_FALSE(callback3.have_result());
4034
4035 // Closing a handle should free up another socket slot.
4036 handle1.Reset();
robpercival214763f2016-07-01 23:27:014037 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204038}
4039
4040TEST_F(ClientSocketPoolBaseTest,
4041 CloseMultipleIdleSocketsHeldByLayeredPoolWhenNeeded) {
4042 CreatePool(1, 1);
4043 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4044
4045 MockLayeredPool mock_layered_pool1(pool_.get(), "foo");
robpercival214763f2016-07-01 23:27:014046 EXPECT_THAT(mock_layered_pool1.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204047 EXPECT_CALL(mock_layered_pool1, CloseOneIdleConnection())
4048 .WillRepeatedly(Invoke(&mock_layered_pool1,
4049 &MockLayeredPool::ReleaseOneConnection));
4050 MockLayeredPool mock_layered_pool2(pool_.get(), "bar");
robpercival214763f2016-07-01 23:27:014051 EXPECT_THAT(mock_layered_pool2.RequestSocketWithoutLimits(pool_.get()),
4052 IsOk());
[email protected]58e562f2013-04-22 17:32:204053 EXPECT_CALL(mock_layered_pool2, CloseOneIdleConnection())
4054 .WillRepeatedly(Invoke(&mock_layered_pool2,
4055 &MockLayeredPool::ReleaseOneConnection));
4056 ClientSocketHandle handle;
4057 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:154058 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:544059 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:154060 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:204061 callback.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:014062 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204063}
4064
[email protected]b021ece62013-06-11 11:06:334065// Test that when a socket pool and group are at their limits, a request
mmenked3641e12016-01-28 16:06:154066// with RespectLimits::DISABLED triggers creation of a new socket, and gets the
4067// socket instead of a request with the same priority that was issued earlier,
4068// but has RespectLimits::ENABLED.
[email protected]b021ece62013-06-11 11:06:334069TEST_F(ClientSocketPoolBaseTest, IgnoreLimits) {
[email protected]b021ece62013-06-11 11:06:334070 CreatePool(1, 1);
4071
4072 // Issue a request to reach the socket pool limit.
mmenked3641e12016-01-28 16:06:154073 EXPECT_EQ(
4074 OK, StartRequestWithIgnoreLimits(
4075 "a", MAXIMUM_PRIORITY, ClientSocketPool::RespectLimits::ENABLED));
[email protected]b021ece62013-06-11 11:06:334076 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4077
4078 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4079
mmenked3641e12016-01-28 16:06:154080 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
4081 "a", MAXIMUM_PRIORITY,
4082 ClientSocketPool::RespectLimits::ENABLED));
[email protected]b021ece62013-06-11 11:06:334083 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4084
mmenked3641e12016-01-28 16:06:154085 // Issue a request that ignores the limits, so a new ConnectJob is
4086 // created.
4087 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
4088 "a", MAXIMUM_PRIORITY,
4089 ClientSocketPool::RespectLimits::DISABLED));
[email protected]b021ece62013-06-11 11:06:334090 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4091
robpercival214763f2016-07-01 23:27:014092 EXPECT_THAT(request(2)->WaitForResult(), IsOk());
[email protected]b021ece62013-06-11 11:06:334093 EXPECT_FALSE(request(1)->have_result());
4094}
4095
[email protected]c55fabd2013-11-04 23:26:564096// Test that when a socket pool and group are at their limits, a ConnectJob
mmenked3641e12016-01-28 16:06:154097// issued for a request with RespectLimits::DISABLED is not cancelled when a
4098// request with RespectLimits::ENABLED issued to the same group is cancelled.
[email protected]c55fabd2013-11-04 23:26:564099TEST_F(ClientSocketPoolBaseTest, IgnoreLimitsCancelOtherJob) {
[email protected]c55fabd2013-11-04 23:26:564100 CreatePool(1, 1);
4101
4102 // Issue a request to reach the socket pool limit.
mmenked3641e12016-01-28 16:06:154103 EXPECT_EQ(
4104 OK, StartRequestWithIgnoreLimits(
4105 "a", MAXIMUM_PRIORITY, ClientSocketPool::RespectLimits::ENABLED));
[email protected]c55fabd2013-11-04 23:26:564106 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4107
4108 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4109
mmenked3641e12016-01-28 16:06:154110 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
4111 "a", MAXIMUM_PRIORITY,
4112 ClientSocketPool::RespectLimits::ENABLED));
[email protected]c55fabd2013-11-04 23:26:564113 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4114
mmenked3641e12016-01-28 16:06:154115 // Issue a request with RespectLimits::DISABLED, so a new ConnectJob is
4116 // created.
4117 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
4118 "a", MAXIMUM_PRIORITY,
4119 ClientSocketPool::RespectLimits::DISABLED));
[email protected]b021ece62013-06-11 11:06:334120 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4121
mmenked3641e12016-01-28 16:06:154122 // Cancel the pending request with RespectLimits::ENABLED. The ConnectJob
[email protected]b021ece62013-06-11 11:06:334123 // should not be cancelled.
4124 request(1)->handle()->Reset();
4125 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4126
robpercival214763f2016-07-01 23:27:014127 EXPECT_THAT(request(2)->WaitForResult(), IsOk());
[email protected]b021ece62013-06-11 11:06:334128 EXPECT_FALSE(request(1)->have_result());
4129}
4130
[email protected]f6d1d6eb2009-06-24 20:16:094131} // namespace
4132
4133} // namespace net