blob: 4fb6b997ac9c33606976478c350e75cc15e4d707 [file] [log] [blame]
[email protected]e34400c32012-01-24 02:49:331// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]f6d1d6eb2009-06-24 20:16:092// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]ab838892009-06-30 18:49:055#include "net/socket/client_socket_pool_base.h"
[email protected]f6d1d6eb2009-06-24 20:16:096
tbansalf82cc8e2015-10-14 20:05:497#include <stdint.h>
dchengc7eeda422015-12-26 03:56:488#include <utility>
[email protected]51fdc7c2012-04-10 19:19:489#include <vector>
10
[email protected]6ecf2b92011-12-15 01:14:5211#include "base/bind.h"
12#include "base/bind_helpers.h"
[email protected]2041cf342010-02-19 03:15:5913#include "base/callback.h"
skyostil4891b25b2015-06-11 11:43:4514#include "base/location.h"
mmenke33d24423d2015-05-19 19:41:0915#include "base/logging.h"
Avi Drissman13fc8932015-12-20 04:40:4616#include "base/macros.h"
[email protected]3b63f8f42011-03-28 01:54:1517#include "base/memory/ref_counted.h"
[email protected]6ea7b152011-12-21 21:21:1318#include "base/memory/weak_ptr.h"
[email protected]18b577412013-07-18 04:19:1519#include "base/message_loop/message_loop.h"
[email protected]034df0f32013-01-07 23:17:4820#include "base/run_loop.h"
skyostil4891b25b2015-06-11 11:43:4521#include "base/single_thread_task_runner.h"
[email protected]fc9be5802013-06-11 10:56:5122#include "base/strings/string_number_conversions.h"
[email protected]18b577412013-07-18 04:19:1523#include "base/strings/stringprintf.h"
[email protected]f214f8792011-01-01 02:17:0824#include "base/threading/platform_thread.h"
gabf767595f2016-05-11 18:50:3525#include "base/threading/thread_task_runner_handle.h"
[email protected]f3a1c642011-07-12 19:15:0326#include "base/values.h"
[email protected]034df0f32013-01-07 23:17:4827#include "net/base/load_timing_info.h"
[email protected]b258e0792013-01-12 07:11:5928#include "net/base/load_timing_info_test_util.h"
[email protected]d8eb84242010-09-25 02:25:0629#include "net/base/net_errors.h"
[email protected]ac790b42009-12-02 04:31:3130#include "net/base/request_priority.h"
[email protected]f6d1d6eb2009-06-24 20:16:0931#include "net/base/test_completion_callback.h"
[email protected]277d5942010-08-11 21:02:3532#include "net/http/http_response_headers.h"
eroman87c53d62015-04-02 06:51:0733#include "net/log/net_log.h"
mikecirone8b85c432016-09-08 19:11:0034#include "net/log/net_log_event_type.h"
mikecironef22f9812016-10-04 03:40:1935#include "net/log/net_log_source.h"
mikecirone8b85c432016-09-08 19:11:0036#include "net/log/net_log_source_type.h"
mmenke16a7cbdd2015-04-24 23:00:5637#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4638#include "net/log/test_net_log_entry.h"
39#include "net/log/test_net_log_util.h"
[email protected]f6d1d6eb2009-06-24 20:16:0940#include "net/socket/client_socket_factory.h"
41#include "net/socket/client_socket_handle.h"
tfarina5dd13c22016-11-16 12:08:2642#include "net/socket/datagram_client_socket.h"
tbansalca83c002016-04-28 20:56:2843#include "net/socket/socket_performance_watcher.h"
Paul Jensen8d6f87ec2018-01-13 00:46:5444#include "net/socket/socket_tag.h"
[email protected]75439d3b2009-07-23 22:11:1745#include "net/socket/socket_test_util.h"
[email protected]18ccfdb2013-08-15 00:13:4446#include "net/socket/ssl_client_socket.h"
[email protected]3268023f2011-05-05 00:08:1047#include "net/socket/stream_socket.h"
robpercival214763f2016-07-01 23:27:0148#include "net/test/gtest_util.h"
Bence Béky98447b12018-05-08 03:14:0149#include "net/test/test_with_scoped_task_environment.h"
Ramin Halavati0a08cc82018-02-06 07:46:3850#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
[email protected]51fdc7c2012-04-10 19:19:4851#include "testing/gmock/include/gmock/gmock.h"
[email protected]f6d1d6eb2009-06-24 20:16:0952#include "testing/gtest/include/gtest/gtest.h"
53
robpercival214763f2016-07-01 23:27:0154using net::test::IsError;
55using net::test::IsOk;
56
[email protected]51fdc7c2012-04-10 19:19:4857using ::testing::Invoke;
58using ::testing::Return;
59
[email protected]f6d1d6eb2009-06-24 20:16:0960namespace net {
61
62namespace {
63
[email protected]211d21722009-07-22 15:48:5364const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2065const int kDefaultMaxSocketsPerGroup = 2;
[email protected]0b7648c2009-07-06 20:14:0166
[email protected]034df0f32013-01-07 23:17:4867// Make sure |handle| sets load times correctly when it has been assigned a
68// reused socket.
69void TestLoadTimingInfoConnectedReused(const ClientSocketHandle& handle) {
70 LoadTimingInfo load_timing_info;
71 // Only pass true in as |is_reused|, as in general, HttpStream types should
72 // have stricter concepts of reuse than socket pools.
73 EXPECT_TRUE(handle.GetLoadTimingInfo(true, &load_timing_info));
74
75 EXPECT_EQ(true, load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:1976 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]034df0f32013-01-07 23:17:4877
[email protected]b258e0792013-01-12 07:11:5978 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
79 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:4880}
81
82// Make sure |handle| sets load times correctly when it has been assigned a
[email protected]b021ece62013-06-11 11:06:3383// fresh socket. Also runs TestLoadTimingInfoConnectedReused, since the owner
[email protected]034df0f32013-01-07 23:17:4884// of a connection where |is_reused| is false may consider the connection
85// reused.
86void TestLoadTimingInfoConnectedNotReused(const ClientSocketHandle& handle) {
87 EXPECT_FALSE(handle.is_reused());
88
89 LoadTimingInfo load_timing_info;
90 EXPECT_TRUE(handle.GetLoadTimingInfo(false, &load_timing_info));
91
92 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:1993 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]034df0f32013-01-07 23:17:4894
[email protected]b258e0792013-01-12 07:11:5995 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
96 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
97 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:4898
99 TestLoadTimingInfoConnectedReused(handle);
100}
101
102// Make sure |handle| sets load times correctly, in the case that it does not
103// currently have a socket.
104void TestLoadTimingInfoNotConnected(const ClientSocketHandle& handle) {
105 // Should only be set to true once a socket is assigned, if at all.
106 EXPECT_FALSE(handle.is_reused());
107
108 LoadTimingInfo load_timing_info;
109 EXPECT_FALSE(handle.GetLoadTimingInfo(false, &load_timing_info));
110
111 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19112 EXPECT_EQ(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]034df0f32013-01-07 23:17:48113
[email protected]b258e0792013-01-12 07:11:59114 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
115 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:48116}
117
[email protected]df4b4ef2010-07-12 18:25:21118class TestSocketParams : public base::RefCounted<TestSocketParams> {
[email protected]5acdce12011-03-30 13:00:20119 public:
Chris Watkins7a41d3552017-12-01 02:13:27120 explicit TestSocketParams() = default;
[email protected]51fdc7c2012-04-10 19:19:48121
[email protected]df4b4ef2010-07-12 18:25:21122 private:
123 friend class base::RefCounted<TestSocketParams>;
Chris Watkins7a41d3552017-12-01 02:13:27124 ~TestSocketParams() = default;
[email protected]df4b4ef2010-07-12 18:25:21125};
[email protected]7fc5b09a2010-02-27 00:07:38126typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
[email protected]d80a4322009-08-14 07:07:49127
[email protected]3268023f2011-05-05 00:08:10128class MockClientSocket : public StreamSocket {
[email protected]f6d1d6eb2009-06-24 20:16:09129 public:
[email protected]034df0f32013-01-07 23:17:48130 explicit MockClientSocket(net::NetLog* net_log)
131 : connected_(false),
[email protected]0dc88b32014-03-26 20:12:28132 has_unread_data_(false),
tfarina428341112016-09-22 13:38:20133 net_log_(NetLogWithSource::Make(net_log, NetLogSourceType::SOCKET)),
Alexandr Ilin65ec9582017-10-02 14:50:31134 was_used_to_convey_data_(false),
135 motivation_(HttpRequestInfo::NORMAL_MOTIVATION) {}
[email protected]f6d1d6eb2009-06-24 20:16:09136
[email protected]0dc88b32014-03-26 20:12:28137 // Sets whether the socket has unread data. If true, the next call to Read()
138 // will return 1 byte and IsConnectedAndIdle() will return false.
139 void set_has_unread_data(bool has_unread_data) {
140 has_unread_data_ = has_unread_data;
141 }
142
Alexandr Ilin65ec9582017-10-02 14:50:31143 HttpRequestInfo::RequestMotivation motivation() const { return motivation_; }
144
[email protected]3f55aa12011-12-07 02:03:33145 // Socket implementation.
dchengb03027d2014-10-21 12:00:20146 int Read(IOBuffer* /* buf */,
147 int len,
Brad Lassey3a814172018-04-26 03:30:21148 CompletionOnceCallback /* callback */) override {
[email protected]0dc88b32014-03-26 20:12:28149 if (has_unread_data_ && len > 0) {
150 has_unread_data_ = false;
151 was_used_to_convey_data_ = true;
152 return 1;
153 }
[email protected]e86df8dc2013-03-30 13:18:28154 return ERR_UNEXPECTED;
[email protected]3f55aa12011-12-07 02:03:33155 }
[email protected]ab838892009-06-30 18:49:05156
[email protected]a2b2cfc2017-12-06 09:06:08157 int Write(
158 IOBuffer* /* buf */,
159 int len,
Brad Lassey3a814172018-04-26 03:30:21160 CompletionOnceCallback /* callback */,
[email protected]a2b2cfc2017-12-06 09:06:08161 const NetworkTrafficAnnotationTag& /*traffic_annotation*/) override {
[email protected]0f873e82010-09-02 16:09:01162 was_used_to_convey_data_ = true;
163 return len;
[email protected]ab838892009-06-30 18:49:05164 }
Avi Drissman13fc8932015-12-20 04:40:46165 int SetReceiveBufferSize(int32_t size) override { return OK; }
166 int SetSendBufferSize(int32_t size) override { return OK; }
[email protected]ab838892009-06-30 18:49:05167
[email protected]dbf036f2011-12-06 23:33:24168 // StreamSocket implementation.
Brad Lassey3a814172018-04-26 03:30:21169 int Connect(CompletionOnceCallback callback) override {
[email protected]dbf036f2011-12-06 23:33:24170 connected_ = true;
171 return OK;
172 }
[email protected]f6d1d6eb2009-06-24 20:16:09173
dchengb03027d2014-10-21 12:00:20174 void Disconnect() override { connected_ = false; }
175 bool IsConnected() const override { return connected_; }
176 bool IsConnectedAndIdle() const override {
[email protected]0dc88b32014-03-26 20:12:28177 return connected_ && !has_unread_data_;
178 }
[email protected]0b7648c2009-07-06 20:14:01179
dchengb03027d2014-10-21 12:00:20180 int GetPeerAddress(IPEndPoint* /* address */) const override {
[email protected]9f864b32010-01-20 15:01:16181 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:09182 }
[email protected]f6d1d6eb2009-06-24 20:16:09183
dchengb03027d2014-10-21 12:00:20184 int GetLocalAddress(IPEndPoint* /* address */) const override {
[email protected]e7f74da2011-04-19 23:49:35185 return ERR_UNEXPECTED;
186 }
187
tfarina428341112016-09-22 13:38:20188 const NetLogWithSource& NetLog() const override { return net_log_; }
[email protected]a2006ece2010-04-23 16:44:02189
Alexandr Ilin65ec9582017-10-02 14:50:31190 void SetSubresourceSpeculation() override {
191 motivation_ = HttpRequestInfo::PRECONNECT_MOTIVATED;
192 }
193 void SetOmniboxSpeculation() override {
194 motivation_ = HttpRequestInfo::OMNIBOX_MOTIVATED;
195 }
dchengb03027d2014-10-21 12:00:20196 bool WasEverUsed() const override { return was_used_to_convey_data_; }
tfarina2846404c2016-12-25 14:31:37197 bool WasAlpnNegotiated() const override { return false; }
dchengb03027d2014-10-21 12:00:20198 NextProto GetNegotiatedProtocol() const override { return kProtoUnknown; }
199 bool GetSSLInfo(SSLInfo* ssl_info) override { return false; }
ttuttle23fdb7b2015-05-15 01:28:03200 void GetConnectionAttempts(ConnectionAttempts* out) const override {
201 out->clear();
202 }
203 void ClearConnectionAttempts() override {}
204 void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
tbansalf82cc8e2015-10-14 20:05:49205 int64_t GetTotalReceivedBytes() const override {
206 NOTIMPLEMENTED();
207 return 0;
208 }
Paul Jensen0f49dec2017-12-12 23:39:58209 void ApplySocketTag(const SocketTag& tag) override {}
[email protected]9b5614a2010-08-25 20:29:45210
[email protected]f6d1d6eb2009-06-24 20:16:09211 private:
212 bool connected_;
[email protected]0dc88b32014-03-26 20:12:28213 bool has_unread_data_;
tfarina428341112016-09-22 13:38:20214 NetLogWithSource net_log_;
[email protected]0f873e82010-09-02 16:09:01215 bool was_used_to_convey_data_;
Alexandr Ilin65ec9582017-10-02 14:50:31216 HttpRequestInfo::RequestMotivation motivation_;
[email protected]f6d1d6eb2009-06-24 20:16:09217
[email protected]ab838892009-06-30 18:49:05218 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:09219};
220
[email protected]5fc08e32009-07-15 17:09:57221class TestConnectJob;
222
[email protected]f6d1d6eb2009-06-24 20:16:09223class MockClientSocketFactory : public ClientSocketFactory {
224 public:
[email protected]ab838892009-06-30 18:49:05225 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:09226
danakj655b66c2016-04-16 00:51:38227 std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
[email protected]5370c012011-06-29 03:47:04228 DatagramSocket::BindType bind_type,
[email protected]98b0e582011-06-22 14:31:41229 NetLog* net_log,
mikecironef22f9812016-10-04 03:40:19230 const NetLogSource& source) override {
[email protected]98b0e582011-06-22 14:31:41231 NOTREACHED();
danakj655b66c2016-04-16 00:51:38232 return std::unique_ptr<DatagramClientSocket>();
[email protected]98b0e582011-06-22 14:31:41233 }
234
Helen Lid5bb9222018-04-12 15:33:09235 std::unique_ptr<TransportClientSocket> CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07236 const AddressList& addresses,
danakj655b66c2016-04-16 00:51:38237 std::unique_ptr<
238 SocketPerformanceWatcher> /* socket_performance_watcher */,
[email protected]0a0b7682010-08-25 17:08:07239 NetLog* /* net_log */,
mikecironef22f9812016-10-04 03:40:19240 const NetLogSource& /*source*/) override {
[email protected]f6d1d6eb2009-06-24 20:16:09241 allocation_count_++;
Helen Lid5bb9222018-04-12 15:33:09242 return nullptr;
[email protected]f6d1d6eb2009-06-24 20:16:09243 }
244
danakj655b66c2016-04-16 00:51:38245 std::unique_ptr<SSLClientSocket> CreateSSLClientSocket(
246 std::unique_ptr<ClientSocketHandle> transport_socket,
[email protected]4f4de7e62010-11-12 19:55:27247 const HostPortPair& host_and_port,
[email protected]7ab5bbd12010-10-19 13:33:21248 const SSLConfig& ssl_config,
mostynbba063d6032014-10-09 11:01:13249 const SSLClientSocketContext& context) override {
[email protected]f6d1d6eb2009-06-24 20:16:09250 NOTIMPLEMENTED();
danakj655b66c2016-04-16 00:51:38251 return std::unique_ptr<SSLClientSocket>();
[email protected]f6d1d6eb2009-06-24 20:16:09252 }
Helen Liac3c51e2018-04-24 00:02:13253 std::unique_ptr<ProxyClientSocket> CreateProxyClientSocket(
254 std::unique_ptr<ClientSocketHandle> transport_socket,
255 const std::string& user_agent,
256 const HostPortPair& endpoint,
257 HttpAuthController* http_auth_controller,
258 bool tunnel,
259 bool using_spdy,
260 NextProto negotiated_protocol,
261 bool is_https_proxy,
262 const NetworkTrafficAnnotationTag& traffic_annotation) override {
263 NOTIMPLEMENTED();
264 return nullptr;
265 }
[email protected]f6d1d6eb2009-06-24 20:16:09266
dchengb03027d2014-10-21 12:00:20267 void ClearSSLSessionCache() override { NOTIMPLEMENTED(); }
[email protected]25f47352011-02-25 16:31:59268
[email protected]5fc08e32009-07-15 17:09:57269 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
[email protected]03b7c8c2013-07-20 04:38:55270
[email protected]5fc08e32009-07-15 17:09:57271 void SignalJobs();
272
[email protected]03b7c8c2013-07-20 04:38:55273 void SignalJob(size_t job);
274
275 void SetJobLoadState(size_t job, LoadState load_state);
276
[email protected]f6d1d6eb2009-06-24 20:16:09277 int allocation_count() const { return allocation_count_; }
278
[email protected]f6d1d6eb2009-06-24 20:16:09279 private:
280 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:57281 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09282};
283
[email protected]ab838892009-06-30 18:49:05284class TestConnectJob : public ConnectJob {
285 public:
286 enum JobType {
287 kMockJob,
288 kMockFailingJob,
289 kMockPendingJob,
290 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57291 kMockWaitingJob,
[email protected]e772db3f2010-07-12 18:11:13292 kMockRecoverableJob,
293 kMockPendingRecoverableJob,
[email protected]e60e47a2010-07-14 03:37:18294 kMockAdditionalErrorStateJob,
295 kMockPendingAdditionalErrorStateJob,
[email protected]0dc88b32014-03-26 20:12:28296 kMockUnreadDataJob,
[email protected]ab838892009-06-30 18:49:05297 };
298
[email protected]994d4932010-07-12 17:55:13299 // The kMockPendingJob uses a slight delay before allowing the connect
300 // to complete.
301 static const int kPendingConnectDelay = 2;
302
[email protected]ab838892009-06-30 18:49:05303 TestConnectJob(JobType job_type,
304 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49305 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34306 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05307 ConnectJob::Delegate* delegate,
[email protected]fd7b7c92009-08-20 19:38:30308 MockClientSocketFactory* client_socket_factory,
[email protected]06650c52010-06-03 00:49:17309 NetLog* net_log)
tfarina428341112016-09-22 13:38:20310 : ConnectJob(
311 group_name,
312 timeout_duration,
313 request.priority(),
Paul Jensen8d6f87ec2018-01-13 00:46:54314 request.socket_tag(),
tfarina428341112016-09-22 13:38:20315 request.respect_limits(),
316 delegate,
davidbenb7048f092016-11-30 21:20:26317 NetLogWithSource::Make(net_log,
318 NetLogSourceType::TRANSPORT_CONNECT_JOB)),
[email protected]2ab05b52009-07-01 23:57:58319 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05320 client_socket_factory_(client_socket_factory),
[email protected]e60e47a2010-07-14 03:37:18321 load_state_(LOAD_STATE_IDLE),
[email protected]d5492c52013-11-10 20:44:39322 store_additional_error_state_(false),
mmenked3641e12016-01-28 16:06:15323 weak_factory_(this) {}
[email protected]ab838892009-06-30 18:49:05324
[email protected]974ebd62009-08-03 23:14:34325 void Signal() {
[email protected]e772db3f2010-07-12 18:11:13326 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
[email protected]974ebd62009-08-03 23:14:34327 }
328
[email protected]03b7c8c2013-07-20 04:38:55329 void set_load_state(LoadState load_state) { load_state_ = load_state; }
330
331 // From ConnectJob:
332
dchengb03027d2014-10-21 12:00:20333 LoadState GetLoadState() const override { return load_state_; }
[email protected]46451352009-09-01 14:54:21334
dchengb03027d2014-10-21 12:00:20335 void GetAdditionalErrorState(ClientSocketHandle* handle) override {
[email protected]e60e47a2010-07-14 03:37:18336 if (store_additional_error_state_) {
337 // Set all of the additional error state fields in some way.
338 handle->set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43339 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:45340 info.headers = new HttpResponseHeaders(std::string());
[email protected]8b498692010-07-16 17:11:43341 handle->set_ssl_error_response_info(info);
[email protected]e60e47a2010-07-14 03:37:18342 }
343 }
344
[email protected]974ebd62009-08-03 23:14:34345 private:
[email protected]03b7c8c2013-07-20 04:38:55346 // From ConnectJob:
[email protected]ab838892009-06-30 18:49:05347
dchengb03027d2014-10-21 12:00:20348 int ConnectInternal() override {
[email protected]ab838892009-06-30 18:49:05349 AddressList ignored;
tbansal7b403bcc2016-04-13 22:33:21350 client_socket_factory_->CreateTransportClientSocket(ignored, NULL, NULL,
mikecironef22f9812016-10-04 03:40:19351 NetLogSource());
danakj655b66c2016-04-16 00:51:38352 SetSocket(std::unique_ptr<StreamSocket>(
353 new MockClientSocket(net_log().net_log())));
[email protected]ab838892009-06-30 18:49:05354 switch (job_type_) {
355 case kMockJob:
[email protected]e772db3f2010-07-12 18:11:13356 return DoConnect(true /* successful */, false /* sync */,
357 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05358 case kMockFailingJob:
[email protected]e772db3f2010-07-12 18:11:13359 return DoConnect(false /* error */, false /* sync */,
360 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05361 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57362 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47363
364 // Depending on execution timings, posting a delayed task can result
365 // in the task getting executed the at the earliest possible
366 // opportunity or only after returning once from the message loop and
367 // then a second call into the message loop. In order to make behavior
368 // more deterministic, we change the default delay to 2ms. This should
369 // always require us to wait for the second call into the message loop.
370 //
371 // N.B. The correct fix for this and similar timing problems is to
372 // abstract time for the purpose of unittests. Unfortunately, we have
373 // a lot of third-party components that directly call the various
374 // time functions, so this change would be rather invasive.
skyostil4891b25b2015-06-11 11:43:45375 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05376 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13377 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
skyostil4891b25b2015-06-11 11:43:45378 weak_factory_.GetWeakPtr(), true /* successful */,
379 true /* async */, false /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53380 base::TimeDelta::FromMilliseconds(kPendingConnectDelay));
[email protected]ab838892009-06-30 18:49:05381 return ERR_IO_PENDING;
382 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57383 set_load_state(LOAD_STATE_CONNECTING);
skyostil4891b25b2015-06-11 11:43:45384 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05385 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13386 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
skyostil4891b25b2015-06-11 11:43:45387 weak_factory_.GetWeakPtr(), false /* error */,
388 true /* async */, false /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53389 base::TimeDelta::FromMilliseconds(2));
[email protected]ab838892009-06-30 18:49:05390 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57391 case kMockWaitingJob:
[email protected]03b7c8c2013-07-20 04:38:55392 set_load_state(LOAD_STATE_CONNECTING);
[email protected]5fc08e32009-07-15 17:09:57393 client_socket_factory_->WaitForSignal(this);
394 waiting_success_ = true;
395 return ERR_IO_PENDING;
[email protected]e772db3f2010-07-12 18:11:13396 case kMockRecoverableJob:
397 return DoConnect(false /* error */, false /* sync */,
398 true /* recoverable */);
399 case kMockPendingRecoverableJob:
400 set_load_state(LOAD_STATE_CONNECTING);
skyostil4891b25b2015-06-11 11:43:45401 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]e772db3f2010-07-12 18:11:13402 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 */, true /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53406 base::TimeDelta::FromMilliseconds(2));
[email protected]e772db3f2010-07-12 18:11:13407 return ERR_IO_PENDING;
[email protected]e60e47a2010-07-14 03:37:18408 case kMockAdditionalErrorStateJob:
409 store_additional_error_state_ = true;
410 return DoConnect(false /* error */, false /* sync */,
411 false /* recoverable */);
412 case kMockPendingAdditionalErrorStateJob:
413 set_load_state(LOAD_STATE_CONNECTING);
414 store_additional_error_state_ = true;
skyostil4891b25b2015-06-11 11:43:45415 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]e60e47a2010-07-14 03:37:18416 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13417 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
skyostil4891b25b2015-06-11 11:43:45418 weak_factory_.GetWeakPtr(), false /* error */,
419 true /* async */, false /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53420 base::TimeDelta::FromMilliseconds(2));
[email protected]e60e47a2010-07-14 03:37:18421 return ERR_IO_PENDING;
[email protected]0dc88b32014-03-26 20:12:28422 case kMockUnreadDataJob: {
423 int ret = DoConnect(true /* successful */, false /* sync */,
424 false /* recoverable */);
425 static_cast<MockClientSocket*>(socket())->set_has_unread_data(true);
426 return ret;
427 }
[email protected]ab838892009-06-30 18:49:05428 default:
429 NOTREACHED();
danakj655b66c2016-04-16 00:51:38430 SetSocket(std::unique_ptr<StreamSocket>());
[email protected]ab838892009-06-30 18:49:05431 return ERR_FAILED;
432 }
433 }
434
[email protected]e772db3f2010-07-12 18:11:13435 int DoConnect(bool succeed, bool was_async, bool recoverable) {
436 int result = OK;
[email protected]ab838892009-06-30 18:49:05437 if (succeed) {
[email protected]83039bb2011-12-09 18:43:55438 socket()->Connect(CompletionCallback());
[email protected]e772db3f2010-07-12 18:11:13439 } else if (recoverable) {
440 result = ERR_PROXY_AUTH_REQUESTED;
[email protected]6e713f02009-08-06 02:56:40441 } else {
[email protected]e772db3f2010-07-12 18:11:13442 result = ERR_CONNECTION_FAILED;
danakj655b66c2016-04-16 00:51:38443 SetSocket(std::unique_ptr<StreamSocket>());
[email protected]ab838892009-06-30 18:49:05444 }
[email protected]2ab05b52009-07-01 23:57:58445
446 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30447 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05448 return result;
449 }
450
[email protected]5fc08e32009-07-15 17:09:57451 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05452 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57453 MockClientSocketFactory* const client_socket_factory_;
[email protected]46451352009-09-01 14:54:21454 LoadState load_state_;
[email protected]e60e47a2010-07-14 03:37:18455 bool store_additional_error_state_;
[email protected]ab838892009-06-30 18:49:05456
[email protected]d5492c52013-11-10 20:44:39457 base::WeakPtrFactory<TestConnectJob> weak_factory_;
458
[email protected]ab838892009-06-30 18:49:05459 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
460};
461
[email protected]d80a4322009-08-14 07:07:49462class TestConnectJobFactory
463 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05464 public:
[email protected]034df0f32013-01-07 23:17:48465 TestConnectJobFactory(MockClientSocketFactory* client_socket_factory,
466 NetLog* net_log)
[email protected]ab838892009-06-30 18:49:05467 : job_type_(TestConnectJob::kMockJob),
[email protected]51fdc7c2012-04-10 19:19:48468 job_types_(NULL),
[email protected]034df0f32013-01-07 23:17:48469 client_socket_factory_(client_socket_factory),
470 net_log_(net_log) {
[email protected]b021ece62013-06-11 11:06:33471 }
[email protected]ab838892009-06-30 18:49:05472
Chris Watkins7a41d3552017-12-01 02:13:27473 ~TestConnectJobFactory() override = default;
[email protected]ab838892009-06-30 18:49:05474
475 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
476
[email protected]51fdc7c2012-04-10 19:19:48477 void set_job_types(std::list<TestConnectJob::JobType>* job_types) {
478 job_types_ = job_types;
479 CHECK(!job_types_->empty());
480 }
481
[email protected]974ebd62009-08-03 23:14:34482 void set_timeout_duration(base::TimeDelta timeout_duration) {
483 timeout_duration_ = timeout_duration;
484 }
485
[email protected]3f55aa12011-12-07 02:03:33486 // ConnectJobFactory implementation.
[email protected]83039bb2011-12-09 18:43:55487
danakj655b66c2016-04-16 00:51:38488 std::unique_ptr<ConnectJob> NewConnectJob(
[email protected]ab838892009-06-30 18:49:05489 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49490 const TestClientSocketPoolBase::Request& request,
mostynbba063d6032014-10-09 11:01:13491 ConnectJob::Delegate* delegate) const override {
[email protected]51fdc7c2012-04-10 19:19:48492 EXPECT_TRUE(!job_types_ || !job_types_->empty());
493 TestConnectJob::JobType job_type = job_type_;
494 if (job_types_ && !job_types_->empty()) {
495 job_type = job_types_->front();
496 job_types_->pop_front();
497 }
danakj655b66c2016-04-16 00:51:38498 return std::unique_ptr<ConnectJob>(
499 new TestConnectJob(job_type, group_name, request, timeout_duration_,
500 delegate, client_socket_factory_, net_log_));
[email protected]ab838892009-06-30 18:49:05501 }
502
dchengb03027d2014-10-21 12:00:20503 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26504 return timeout_duration_;
505 }
506
[email protected]ab838892009-06-30 18:49:05507 private:
508 TestConnectJob::JobType job_type_;
[email protected]51fdc7c2012-04-10 19:19:48509 std::list<TestConnectJob::JobType>* job_types_;
[email protected]974ebd62009-08-03 23:14:34510 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57511 MockClientSocketFactory* const client_socket_factory_;
[email protected]034df0f32013-01-07 23:17:48512 NetLog* net_log_;
[email protected]ab838892009-06-30 18:49:05513
514 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
515};
516
517class TestClientSocketPool : public ClientSocketPool {
518 public:
[email protected]12322e7e2013-08-15 17:49:26519 typedef TestSocketParams SocketParams;
520
[email protected]ab838892009-06-30 18:49:05521 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53522 int max_sockets,
[email protected]ab838892009-06-30 18:49:05523 int max_sockets_per_group,
[email protected]9bf28db2009-08-29 01:35:16524 base::TimeDelta unused_idle_socket_timeout,
525 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49526 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
rkaplowd90695c2015-03-25 22:12:41527 : base_(NULL,
528 max_sockets,
529 max_sockets_per_group,
530 unused_idle_socket_timeout,
531 used_idle_socket_timeout,
[email protected]66761b952010-06-25 21:30:38532 connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05533
Chris Watkins7a41d3552017-12-01 02:13:27534 ~TestClientSocketPool() override = default;
[email protected]2431756e2010-09-29 20:26:13535
dchengb03027d2014-10-21 12:00:20536 int RequestSocket(const std::string& group_name,
537 const void* params,
ttuttle859dc7a2015-04-23 19:42:29538 RequestPriority priority,
Paul Jensen8d6f87ec2018-01-13 00:46:54539 const SocketTag& socket_tag,
mmenked3641e12016-01-28 16:06:15540 RespectLimits respect_limits,
dchengb03027d2014-10-21 12:00:20541 ClientSocketHandle* handle,
542 const CompletionCallback& callback,
tfarina428341112016-09-22 13:38:20543 const NetLogWithSource& net_log) override {
[email protected]df4b4ef2010-07-12 18:25:21544 const scoped_refptr<TestSocketParams>* casted_socket_params =
545 static_cast<const scoped_refptr<TestSocketParams>*>(params);
546 return base_.RequestSocket(group_name, *casted_socket_params, priority,
Paul Jensen8d6f87ec2018-01-13 00:46:54547 socket_tag, respect_limits, handle, callback,
548 net_log);
[email protected]ab838892009-06-30 18:49:05549 }
550
dchengb03027d2014-10-21 12:00:20551 void RequestSockets(const std::string& group_name,
552 const void* params,
553 int num_sockets,
Alexandr Ilin65ec9582017-10-02 14:50:31554 const NetLogWithSource& net_log,
555 HttpRequestInfo::RequestMotivation motivation) override {
[email protected]2c2bef152010-10-13 00:55:03556 const scoped_refptr<TestSocketParams>* casted_params =
557 static_cast<const scoped_refptr<TestSocketParams>*>(params);
558
Alexandr Ilin65ec9582017-10-02 14:50:31559 base_.RequestSockets(group_name, *casted_params, num_sockets, net_log,
560 motivation);
[email protected]2c2bef152010-10-13 00:55:03561 }
562
rdsmith29dbad12017-02-17 02:22:18563 void SetPriority(const std::string& group_name,
564 ClientSocketHandle* handle,
565 RequestPriority priority) override {
566 base_.SetPriority(group_name, handle, priority);
567 }
568
dchengb03027d2014-10-21 12:00:20569 void CancelRequest(const std::string& group_name,
570 ClientSocketHandle* handle) override {
[email protected]d80a4322009-08-14 07:07:49571 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05572 }
573
dchengb03027d2014-10-21 12:00:20574 void ReleaseSocket(const std::string& group_name,
danakj655b66c2016-04-16 00:51:38575 std::unique_ptr<StreamSocket> socket,
dchengb03027d2014-10-21 12:00:20576 int id) override {
dchengc7eeda422015-12-26 03:56:48577 base_.ReleaseSocket(group_name, std::move(socket), id);
[email protected]a7e38572010-06-07 18:22:24578 }
579
dchengb03027d2014-10-21 12:00:20580 void FlushWithError(int error) override { base_.FlushWithError(error); }
[email protected]ab838892009-06-30 18:49:05581
dchengb03027d2014-10-21 12:00:20582 bool IsStalled() const override { return base_.IsStalled(); }
[email protected]51fdc7c2012-04-10 19:19:48583
dchengb03027d2014-10-21 12:00:20584 void CloseIdleSockets() override { base_.CloseIdleSockets(); }
[email protected]ab838892009-06-30 18:49:05585
xunjieli92feb332017-03-03 17:19:23586 void CloseIdleSocketsInGroup(const std::string& group_name) override {
587 base_.CloseIdleSocketsInGroup(group_name);
588 }
589
dchengb03027d2014-10-21 12:00:20590 int IdleSocketCount() const override { return base_.idle_socket_count(); }
[email protected]ab838892009-06-30 18:49:05591
dchengb03027d2014-10-21 12:00:20592 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]d80a4322009-08-14 07:07:49593 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05594 }
595
dchengb03027d2014-10-21 12:00:20596 LoadState GetLoadState(const std::string& group_name,
597 const ClientSocketHandle* handle) const override {
[email protected]d80a4322009-08-14 07:07:49598 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05599 }
600
dchengb03027d2014-10-21 12:00:20601 void AddHigherLayeredPool(HigherLayeredPool* higher_pool) override {
[email protected]043b68c82013-08-22 23:41:52602 base_.AddHigherLayeredPool(higher_pool);
[email protected]51fdc7c2012-04-10 19:19:48603 }
604
dchengb03027d2014-10-21 12:00:20605 void RemoveHigherLayeredPool(HigherLayeredPool* higher_pool) override {
[email protected]043b68c82013-08-22 23:41:52606 base_.RemoveHigherLayeredPool(higher_pool);
[email protected]51fdc7c2012-04-10 19:19:48607 }
608
danakj655b66c2016-04-16 00:51:38609 std::unique_ptr<base::DictionaryValue> GetInfoAsValue(
[email protected]d4dfdab2011-12-07 16:56:59610 const std::string& name,
611 const std::string& type,
mostynbba063d6032014-10-09 11:01:13612 bool include_nested_pools) const override {
[email protected]59d7a5a2010-08-30 16:44:27613 return base_.GetInfoAsValue(name, type);
614 }
615
dchengb03027d2014-10-21 12:00:20616 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26617 return base_.ConnectionTimeout();
618 }
619
[email protected]d80a4322009-08-14 07:07:49620 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20621
[email protected]8159a1c2012-06-07 00:00:10622 int NumUnassignedConnectJobsInGroup(const std::string& group_name) const {
623 return base_.NumUnassignedConnectJobsInGroup(group_name);
624 }
625
[email protected]974ebd62009-08-03 23:14:34626 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49627 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34628 }
629
[email protected]2c2bef152010-10-13 00:55:03630 int NumActiveSocketsInGroup(const std::string& group_name) const {
631 return base_.NumActiveSocketsInGroup(group_name);
632 }
633
[email protected]2abfe90a2010-08-25 17:49:51634 bool HasGroup(const std::string& group_name) const {
635 return base_.HasGroup(group_name);
636 }
637
[email protected]9bf28db2009-08-29 01:35:16638 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
639
[email protected]06d94042010-08-25 01:45:22640 void EnableConnectBackupJobs() { base_.EnableConnectBackupJobs(); }
[email protected]43a21b82010-06-10 21:30:54641
[email protected]043b68c82013-08-22 23:41:52642 bool CloseOneIdleConnectionInHigherLayeredPool() {
643 return base_.CloseOneIdleConnectionInHigherLayeredPool();
[email protected]51fdc7c2012-04-10 19:19:48644 }
645
[email protected]ab838892009-06-30 18:49:05646 private:
[email protected]d80a4322009-08-14 07:07:49647 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05648
649 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
650};
651
[email protected]a937a06d2009-08-19 21:19:24652} // namespace
653
[email protected]a937a06d2009-08-19 21:19:24654namespace {
655
[email protected]5fc08e32009-07-15 17:09:57656void MockClientSocketFactory::SignalJobs() {
657 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
658 it != waiting_jobs_.end(); ++it) {
659 (*it)->Signal();
660 }
661 waiting_jobs_.clear();
662}
663
[email protected]03b7c8c2013-07-20 04:38:55664void MockClientSocketFactory::SignalJob(size_t job) {
665 ASSERT_LT(job, waiting_jobs_.size());
666 waiting_jobs_[job]->Signal();
667 waiting_jobs_.erase(waiting_jobs_.begin() + job);
668}
669
670void MockClientSocketFactory::SetJobLoadState(size_t job,
671 LoadState load_state) {
672 ASSERT_LT(job, waiting_jobs_.size());
673 waiting_jobs_[job]->set_load_state(load_state);
674}
675
[email protected]974ebd62009-08-03 23:14:34676class TestConnectJobDelegate : public ConnectJob::Delegate {
677 public:
678 TestConnectJobDelegate()
679 : have_result_(false), waiting_for_result_(false), result_(OK) {}
Chris Watkins7a41d3552017-12-01 02:13:27680 ~TestConnectJobDelegate() override = default;
[email protected]974ebd62009-08-03 23:14:34681
dchengb03027d2014-10-21 12:00:20682 void OnConnectJobComplete(int result, ConnectJob* job) override {
[email protected]974ebd62009-08-03 23:14:34683 result_ = result;
danakj655b66c2016-04-16 00:51:38684 std::unique_ptr<ConnectJob> owned_job(job);
685 std::unique_ptr<StreamSocket> socket = owned_job->PassSocket();
[email protected]9b6fee12009-09-29 18:13:07686 // socket.get() should be NULL iff result != OK
[email protected]18ccfdb2013-08-15 00:13:44687 EXPECT_EQ(socket == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34688 have_result_ = true;
689 if (waiting_for_result_)
Gabriel Charette53a9ef812017-07-26 12:36:23690 base::RunLoop::QuitCurrentWhenIdleDeprecated();
[email protected]974ebd62009-08-03 23:14:34691 }
692
693 int WaitForResult() {
694 DCHECK(!waiting_for_result_);
695 while (!have_result_) {
696 waiting_for_result_ = true;
fdoray5eeb7642016-06-22 16:11:28697 base::RunLoop().Run();
[email protected]974ebd62009-08-03 23:14:34698 waiting_for_result_ = false;
699 }
700 have_result_ = false; // auto-reset for next callback
701 return result_;
702 }
703
704 private:
705 bool have_result_;
706 bool waiting_for_result_;
707 int result_;
708};
709
Bence Béky98447b12018-05-08 03:14:01710class ClientSocketPoolBaseTest : public TestWithScopedTaskEnvironment {
[email protected]f6d1d6eb2009-06-24 20:16:09711 protected:
mmenked3641e12016-01-28 16:06:15712 ClientSocketPoolBaseTest() : params_(new TestSocketParams()) {
[email protected]636b8252011-04-08 19:56:54713 connect_backup_jobs_enabled_ =
714 internal::ClientSocketPoolBaseHelper::connect_backup_jobs_enabled();
715 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(true);
716 }
[email protected]2431756e2010-09-29 20:26:13717
dcheng67be2b1f2014-10-27 21:47:29718 ~ClientSocketPoolBaseTest() override {
[email protected]636b8252011-04-08 19:56:54719 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
720 connect_backup_jobs_enabled_);
721 }
[email protected]c9d6a1d2009-07-14 16:15:20722
[email protected]211d21722009-07-22 15:48:53723 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16724 CreatePoolWithIdleTimeouts(
725 max_sockets,
726 max_sockets_per_group,
[email protected]82b8c962011-10-12 09:17:30727 ClientSocketPool::unused_idle_socket_timeout(),
728 ClientSocketPool::used_idle_socket_timeout());
[email protected]9bf28db2009-08-29 01:35:16729 }
730
731 void CreatePoolWithIdleTimeouts(
732 int max_sockets, int max_sockets_per_group,
733 base::TimeDelta unused_idle_socket_timeout,
734 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20735 DCHECK(!pool_.get());
[email protected]034df0f32013-01-07 23:17:48736 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_,
737 &net_log_);
[email protected]2431756e2010-09-29 20:26:13738 pool_.reset(new TestClientSocketPool(max_sockets,
739 max_sockets_per_group,
[email protected]2431756e2010-09-29 20:26:13740 unused_idle_socket_timeout,
741 used_idle_socket_timeout,
742 connect_job_factory_));
[email protected]c9d6a1d2009-07-14 16:15:20743 }
[email protected]f6d1d6eb2009-06-24 20:16:09744
mmenked3641e12016-01-28 16:06:15745 int StartRequestWithIgnoreLimits(
[email protected]b021ece62013-06-11 11:06:33746 const std::string& group_name,
747 RequestPriority priority,
mmenked3641e12016-01-28 16:06:15748 ClientSocketPool::RespectLimits respect_limits) {
749 return test_base_.StartRequestUsingPool(pool_.get(), group_name, priority,
750 respect_limits, params_);
[email protected]b021ece62013-06-11 11:06:33751 }
752
753 int StartRequest(const std::string& group_name, RequestPriority priority) {
mmenked3641e12016-01-28 16:06:15754 return StartRequestWithIgnoreLimits(
755 group_name, priority, ClientSocketPool::RespectLimits::ENABLED);
[email protected]f6d1d6eb2009-06-24 20:16:09756 }
757
[email protected]2431756e2010-09-29 20:26:13758 int GetOrderOfRequest(size_t index) const {
759 return test_base_.GetOrderOfRequest(index);
[email protected]f6d1d6eb2009-06-24 20:16:09760 }
761
[email protected]2431756e2010-09-29 20:26:13762 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
763 return test_base_.ReleaseOneConnection(keep_alive);
764 }
765
766 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
767 test_base_.ReleaseAllConnections(keep_alive);
768 }
769
770 TestSocketRequest* request(int i) { return test_base_.request(i); }
771 size_t requests_size() const { return test_base_.requests_size(); }
danakj655b66c2016-04-16 00:51:38772 std::vector<std::unique_ptr<TestSocketRequest>>* requests() {
olli.raula9d66b7d2015-11-23 08:30:42773 return test_base_.requests();
774 }
rdsmith29dbad12017-02-17 02:22:18775 // Only counts the requests that get sockets asynchronously;
776 // synchronous completions are not registered by this count.
[email protected]2431756e2010-09-29 20:26:13777 size_t completion_count() const { return test_base_.completion_count(); }
778
vishal.b62985ca92015-04-17 08:45:51779 TestNetLog net_log_;
[email protected]636b8252011-04-08 19:56:54780 bool connect_backup_jobs_enabled_;
[email protected]f6d1d6eb2009-06-24 20:16:09781 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04782 TestConnectJobFactory* connect_job_factory_;
[email protected]df4b4ef2010-07-12 18:25:21783 scoped_refptr<TestSocketParams> params_;
danakj655b66c2016-04-16 00:51:38784 std::unique_ptr<TestClientSocketPool> pool_;
[email protected]2431756e2010-09-29 20:26:13785 ClientSocketPoolTest test_base_;
[email protected]f6d1d6eb2009-06-24 20:16:09786};
787
[email protected]974ebd62009-08-03 23:14:34788// Even though a timeout is specified, it doesn't time out on a synchronous
789// completion.
790TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
791 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06792 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49793 TestClientSocketPoolBase::Request request(
Paul Jensen8d6f87ec2018-01-13 00:46:54794 &ignored, CompletionCallback(), DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:15795 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:20796 internal::ClientSocketPoolBaseHelper::NORMAL, params_,
797 NetLogWithSource());
danakj655b66c2016-04-16 00:51:38798 std::unique_ptr<TestConnectJob> job(
799 new TestConnectJob(TestConnectJob::kMockJob, "a", request,
800 base::TimeDelta::FromMicroseconds(1), &delegate,
801 &client_socket_factory_, NULL));
robpercival214763f2016-07-01 23:27:01802 EXPECT_THAT(job->Connect(), IsOk());
[email protected]974ebd62009-08-03 23:14:34803}
804
805TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
806 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06807 ClientSocketHandle ignored;
vishal.b62985ca92015-04-17 08:45:51808 TestNetLog log;
[email protected]9e743cd2010-03-16 07:03:53809
[email protected]d80a4322009-08-14 07:07:49810 TestClientSocketPoolBase::Request request(
Paul Jensen8d6f87ec2018-01-13 00:46:54811 &ignored, CompletionCallback(), DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:15812 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:20813 internal::ClientSocketPoolBaseHelper::NORMAL, params_,
814 NetLogWithSource());
[email protected]974ebd62009-08-03 23:14:34815 // Deleted by TestConnectJobDelegate.
816 TestConnectJob* job =
817 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12818 "a",
[email protected]974ebd62009-08-03 23:14:34819 request,
820 base::TimeDelta::FromMicroseconds(1),
821 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30822 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17823 &log);
robpercival214763f2016-07-01 23:27:01824 ASSERT_THAT(job->Connect(), IsError(ERR_IO_PENDING));
[email protected]26b9973962012-01-28 00:57:00825 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
robpercival214763f2016-07-01 23:27:01826 EXPECT_THAT(delegate.WaitForResult(), IsError(ERR_TIMED_OUT));
[email protected]fd7b7c92009-08-20 19:38:30827
mmenke43758e62015-05-04 21:09:46828 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40829 log.GetEntries(&entries);
830
831 EXPECT_EQ(6u, entries.size());
mikecirone8b85c432016-09-08 19:11:00832 EXPECT_TRUE(LogContainsBeginEvent(entries, 0,
833 NetLogEventType::SOCKET_POOL_CONNECT_JOB));
[email protected]e9002a92010-01-29 07:10:46834 EXPECT_TRUE(LogContainsBeginEvent(
mikecirone8b85c432016-09-08 19:11:00835 entries, 1, NetLogEventType::SOCKET_POOL_CONNECT_JOB_CONNECT));
836 EXPECT_TRUE(LogContainsEvent(entries, 2,
837 NetLogEventType::CONNECT_JOB_SET_SOCKET,
838 NetLogEventPhase::NONE));
[email protected]e9002a92010-01-29 07:10:46839 EXPECT_TRUE(LogContainsEvent(
mikecirone8b85c432016-09-08 19:11:00840 entries, 3, NetLogEventType::SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
841 NetLogEventPhase::NONE));
[email protected]e9002a92010-01-29 07:10:46842 EXPECT_TRUE(LogContainsEndEvent(
mikecirone8b85c432016-09-08 19:11:00843 entries, 4, NetLogEventType::SOCKET_POOL_CONNECT_JOB_CONNECT));
844 EXPECT_TRUE(LogContainsEndEvent(entries, 5,
845 NetLogEventType::SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34846}
847
[email protected]5fc08e32009-07-15 17:09:57848TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53849 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20850
[email protected]6ecf2b92011-12-15 01:14:52851 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06852 ClientSocketHandle handle;
vishal.b62985ca92015-04-17 08:45:51853 BoundTestNetLog log;
[email protected]034df0f32013-01-07 23:17:48854 TestLoadTimingInfoNotConnected(handle);
[email protected]9e743cd2010-03-16 07:03:53855
Paul Jensen8d6f87ec2018-01-13 00:46:54856 EXPECT_EQ(OK, handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:15857 ClientSocketPool::RespectLimits::ENABLED,
858 callback.callback(), pool_.get(), log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09859 EXPECT_TRUE(handle.is_initialized());
860 EXPECT_TRUE(handle.socket());
[email protected]034df0f32013-01-07 23:17:48861 TestLoadTimingInfoConnectedNotReused(handle);
862
[email protected]f6d1d6eb2009-06-24 20:16:09863 handle.Reset();
[email protected]034df0f32013-01-07 23:17:48864 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:30865
mmenke43758e62015-05-04 21:09:46866 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40867 log.GetEntries(&entries);
868
869 EXPECT_EQ(4u, entries.size());
mikecirone8b85c432016-09-08 19:11:00870 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKET_POOL));
[email protected]9e743cd2010-03-16 07:03:53871 EXPECT_TRUE(LogContainsEvent(
mikecirone8b85c432016-09-08 19:11:00872 entries, 1, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
873 NetLogEventPhase::NONE));
874 EXPECT_TRUE(LogContainsEvent(entries, 2,
875 NetLogEventType::SOCKET_POOL_BOUND_TO_SOCKET,
876 NetLogEventPhase::NONE));
877 EXPECT_TRUE(LogContainsEndEvent(entries, 3, NetLogEventType::SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09878}
879
[email protected]ab838892009-06-30 18:49:05880TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53881 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20882
[email protected]ab838892009-06-30 18:49:05883 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
vishal.b62985ca92015-04-17 08:45:51884 BoundTestNetLog log;
[email protected]9e743cd2010-03-16 07:03:53885
[email protected]2431756e2010-09-29 20:26:13886 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:52887 TestCompletionCallback callback;
[email protected]e60e47a2010-07-14 03:37:18888 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:13889 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43890 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:45891 info.headers = new HttpResponseHeaders(std::string());
[email protected]2431756e2010-09-29 20:26:13892 handle.set_ssl_error_response_info(info);
893 EXPECT_EQ(ERR_CONNECTION_FAILED,
Paul Jensen8d6f87ec2018-01-13 00:46:54894 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:15895 ClientSocketPool::RespectLimits::ENABLED,
896 callback.callback(), pool_.get(), log.bound()));
[email protected]2431756e2010-09-29 20:26:13897 EXPECT_FALSE(handle.socket());
898 EXPECT_FALSE(handle.is_ssl_error());
899 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]034df0f32013-01-07 23:17:48900 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:30901
mmenke43758e62015-05-04 21:09:46902 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40903 log.GetEntries(&entries);
904
905 EXPECT_EQ(3u, entries.size());
mikecirone8b85c432016-09-08 19:11:00906 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:17907 EXPECT_TRUE(LogContainsEvent(
mikecirone8b85c432016-09-08 19:11:00908 entries, 1, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
909 NetLogEventPhase::NONE));
910 EXPECT_TRUE(LogContainsEndEvent(entries, 2, NetLogEventType::SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09911}
912
[email protected]211d21722009-07-22 15:48:53913TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
914 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
915
[email protected]9e743cd2010-03-16 07:03:53916 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30917
robpercival214763f2016-07-01 23:27:01918 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
919 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
920 EXPECT_THAT(StartRequest("c", DEFAULT_PRIORITY), IsOk());
921 EXPECT_THAT(StartRequest("d", DEFAULT_PRIORITY), IsOk());
[email protected]211d21722009-07-22 15:48:53922
[email protected]2431756e2010-09-29 20:26:13923 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53924 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13925 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53926
robpercival214763f2016-07-01 23:27:01927 EXPECT_THAT(StartRequest("e", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
928 EXPECT_THAT(StartRequest("f", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
929 EXPECT_THAT(StartRequest("g", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:53930
[email protected]2431756e2010-09-29 20:26:13931 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53932
[email protected]2431756e2010-09-29 20:26:13933 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53934 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13935 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53936
937 EXPECT_EQ(1, GetOrderOfRequest(1));
938 EXPECT_EQ(2, GetOrderOfRequest(2));
939 EXPECT_EQ(3, GetOrderOfRequest(3));
940 EXPECT_EQ(4, GetOrderOfRequest(4));
941 EXPECT_EQ(5, GetOrderOfRequest(5));
942 EXPECT_EQ(6, GetOrderOfRequest(6));
943 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17944
945 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13946 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53947}
948
949TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
950 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
951
[email protected]9e743cd2010-03-16 07:03:53952 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30953
[email protected]211d21722009-07-22 15:48:53954 // Reach all limits: max total sockets, and max sockets per group.
robpercival214763f2016-07-01 23:27:01955 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
956 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
957 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
958 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
[email protected]211d21722009-07-22 15:48:53959
[email protected]2431756e2010-09-29 20:26:13960 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53961 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13962 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53963
964 // Now create a new group and verify that we don't starve it.
robpercival214763f2016-07-01 23:27:01965 EXPECT_THAT(StartRequest("c", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:53966
[email protected]2431756e2010-09-29 20:26:13967 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53968
[email protected]2431756e2010-09-29 20:26:13969 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53970 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13971 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53972
973 EXPECT_EQ(1, GetOrderOfRequest(1));
974 EXPECT_EQ(2, GetOrderOfRequest(2));
975 EXPECT_EQ(3, GetOrderOfRequest(3));
976 EXPECT_EQ(4, GetOrderOfRequest(4));
977 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17978
979 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13980 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53981}
982
983TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
984 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
985
robpercival214763f2016-07-01 23:27:01986 EXPECT_THAT(StartRequest("b", LOWEST), IsOk());
987 EXPECT_THAT(StartRequest("a", MEDIUM), IsOk());
988 EXPECT_THAT(StartRequest("b", HIGHEST), IsOk());
989 EXPECT_THAT(StartRequest("a", LOWEST), IsOk());
[email protected]211d21722009-07-22 15:48:53990
[email protected]2431756e2010-09-29 20:26:13991 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53992 client_socket_factory_.allocation_count());
993
robpercival214763f2016-07-01 23:27:01994 EXPECT_THAT(StartRequest("c", LOWEST), IsError(ERR_IO_PENDING));
995 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
996 EXPECT_THAT(StartRequest("b", HIGHEST), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:53997
[email protected]2431756e2010-09-29 20:26:13998 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53999
[email protected]2431756e2010-09-29 20:26:131000 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:531001
1002 // First 4 requests don't have to wait, and finish in order.
1003 EXPECT_EQ(1, GetOrderOfRequest(1));
1004 EXPECT_EQ(2, GetOrderOfRequest(2));
1005 EXPECT_EQ(3, GetOrderOfRequest(3));
1006 EXPECT_EQ(4, GetOrderOfRequest(4));
1007
[email protected]ac790b42009-12-02 04:31:311008 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
1009 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:531010 EXPECT_EQ(7, GetOrderOfRequest(5));
1011 EXPECT_EQ(6, GetOrderOfRequest(6));
1012 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171013
1014 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131015 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]211d21722009-07-22 15:48:531016}
1017
rdsmith29dbad12017-02-17 02:22:181018// Test reprioritizing a request before completion doesn't interfere with
1019// its completion.
1020TEST_F(ClientSocketPoolBaseTest, ReprioritizeOne) {
1021 CreatePool(kDefaultMaxSockets, 1);
1022
1023 EXPECT_THAT(StartRequest("a", LOWEST), IsError(OK));
1024 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1025 EXPECT_TRUE(request(0)->handle()->socket());
1026 EXPECT_FALSE(request(1)->handle()->socket());
1027
1028 request(1)->handle()->SetPriority(MEDIUM);
1029
1030 ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE);
1031
1032 EXPECT_TRUE(request(1)->handle()->socket());
1033}
1034
1035// Reprioritize a request up past another one and make sure that changes the
1036// completion order.
1037TEST_F(ClientSocketPoolBaseTest, ReprioritizeUpReorder) {
1038 CreatePool(kDefaultMaxSockets, 1);
1039
1040 EXPECT_THAT(StartRequest("a", LOWEST), IsError(OK));
1041 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1042 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
1043 EXPECT_TRUE(request(0)->handle()->socket());
1044 EXPECT_FALSE(request(1)->handle()->socket());
1045 EXPECT_FALSE(request(2)->handle()->socket());
1046
1047 request(2)->handle()->SetPriority(HIGHEST);
1048
1049 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1050
1051 EXPECT_EQ(1, GetOrderOfRequest(1));
1052 EXPECT_EQ(3, GetOrderOfRequest(2));
1053 EXPECT_EQ(2, GetOrderOfRequest(3));
1054}
1055
1056// Reprioritize a request without changing relative priorities and check
1057// that the order doesn't change.
1058TEST_F(ClientSocketPoolBaseTest, ReprioritizeUpNoReorder) {
1059 CreatePool(kDefaultMaxSockets, 1);
1060
1061 EXPECT_THAT(StartRequest("a", LOWEST), IsError(OK));
1062 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1063 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1064 EXPECT_TRUE(request(0)->handle()->socket());
1065 EXPECT_FALSE(request(1)->handle()->socket());
1066 EXPECT_FALSE(request(2)->handle()->socket());
1067
1068 request(2)->handle()->SetPriority(MEDIUM);
1069
1070 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1071
1072 EXPECT_EQ(1, GetOrderOfRequest(1));
1073 EXPECT_EQ(2, GetOrderOfRequest(2));
1074 EXPECT_EQ(3, GetOrderOfRequest(3));
1075}
1076
1077// Reprioritize a request past down another one and make sure that changes the
1078// completion order.
1079TEST_F(ClientSocketPoolBaseTest, ReprioritizeDownReorder) {
1080 CreatePool(kDefaultMaxSockets, 1);
1081
1082 EXPECT_THAT(StartRequest("a", LOWEST), IsError(OK));
1083 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
1084 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1085 EXPECT_TRUE(request(0)->handle()->socket());
1086 EXPECT_FALSE(request(1)->handle()->socket());
1087 EXPECT_FALSE(request(2)->handle()->socket());
1088
1089 request(1)->handle()->SetPriority(LOW);
1090
1091 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1092
1093 EXPECT_EQ(1, GetOrderOfRequest(1));
1094 EXPECT_EQ(3, GetOrderOfRequest(2));
1095 EXPECT_EQ(2, GetOrderOfRequest(3));
1096}
1097
1098// Reprioritize a request to the same level as another and confirm it is
1099// put after the old request.
1100TEST_F(ClientSocketPoolBaseTest, ReprioritizeResetFIFO) {
1101 CreatePool(kDefaultMaxSockets, 1);
1102
1103 EXPECT_THAT(StartRequest("a", LOWEST), IsError(OK));
1104 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
1105 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1106 EXPECT_TRUE(request(0)->handle()->socket());
1107 EXPECT_FALSE(request(1)->handle()->socket());
1108 EXPECT_FALSE(request(2)->handle()->socket());
1109
1110 request(1)->handle()->SetPriority(MEDIUM);
1111
1112 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1113
1114 EXPECT_EQ(1, GetOrderOfRequest(1));
1115 EXPECT_EQ(3, GetOrderOfRequest(2));
1116 EXPECT_EQ(2, GetOrderOfRequest(3));
1117}
1118
[email protected]211d21722009-07-22 15:48:531119TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
1120 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1121
robpercival214763f2016-07-01 23:27:011122 EXPECT_THAT(StartRequest("a", LOWEST), IsOk());
1123 EXPECT_THAT(StartRequest("a", LOW), IsOk());
1124 EXPECT_THAT(StartRequest("b", HIGHEST), IsOk());
1125 EXPECT_THAT(StartRequest("b", MEDIUM), IsOk());
[email protected]211d21722009-07-22 15:48:531126
[email protected]2431756e2010-09-29 20:26:131127 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531128 client_socket_factory_.allocation_count());
1129
robpercival214763f2016-07-01 23:27:011130 EXPECT_THAT(StartRequest("c", MEDIUM), IsError(ERR_IO_PENDING));
1131 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1132 EXPECT_THAT(StartRequest("b", HIGHEST), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531133
[email protected]2431756e2010-09-29 20:26:131134 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531135
[email protected]2431756e2010-09-29 20:26:131136 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531137 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131138 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:531139
1140 // First 4 requests don't have to wait, and finish in order.
1141 EXPECT_EQ(1, GetOrderOfRequest(1));
1142 EXPECT_EQ(2, GetOrderOfRequest(2));
1143 EXPECT_EQ(3, GetOrderOfRequest(3));
1144 EXPECT_EQ(4, GetOrderOfRequest(4));
1145
1146 // Request ("b", 7) has the highest priority, but we can't make new socket for
1147 // group "b", because it has reached the per-group limit. Then we make
1148 // socket for ("c", 6), because it has higher priority than ("a", 4),
1149 // and we still can't make a socket for group "b".
1150 EXPECT_EQ(5, GetOrderOfRequest(5));
1151 EXPECT_EQ(6, GetOrderOfRequest(6));
1152 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171153
1154 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131155 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:531156}
1157
1158// Make sure that we count connecting sockets against the total limit.
1159TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
1160 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1161
robpercival214763f2016-07-01 23:27:011162 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1163 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
1164 EXPECT_THAT(StartRequest("c", DEFAULT_PRIORITY), IsOk());
[email protected]211d21722009-07-22 15:48:531165
1166 // Create one asynchronous request.
1167 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
robpercival214763f2016-07-01 23:27:011168 EXPECT_THAT(StartRequest("d", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531169
[email protected]6b175382009-10-13 06:47:471170 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1171 // actually become pending until 2ms after they have been created. In order
1172 // to flush all tasks, we need to wait so that we know there are no
1173 // soon-to-be-pending tasks waiting.
[email protected]26b9973962012-01-28 00:57:001174 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
fdoray5eeb7642016-06-22 16:11:281175 base::RunLoop().RunUntilIdle();
[email protected]6b175382009-10-13 06:47:471176
[email protected]211d21722009-07-22 15:48:531177 // The next synchronous request should wait for its turn.
1178 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
robpercival214763f2016-07-01 23:27:011179 EXPECT_THAT(StartRequest("e", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531180
[email protected]2431756e2010-09-29 20:26:131181 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531182
[email protected]2431756e2010-09-29 20:26:131183 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531184 client_socket_factory_.allocation_count());
1185
1186 EXPECT_EQ(1, GetOrderOfRequest(1));
1187 EXPECT_EQ(2, GetOrderOfRequest(2));
1188 EXPECT_EQ(3, GetOrderOfRequest(3));
1189 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:171190 EXPECT_EQ(5, GetOrderOfRequest(5));
1191
1192 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131193 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:531194}
1195
[email protected]6427fe22010-04-16 22:27:411196TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
1197 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1198 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1199
robpercival214763f2016-07-01 23:27:011200 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1201 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1202 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1203 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
[email protected]6427fe22010-04-16 22:27:411204
1205 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1206
1207 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1208
robpercival214763f2016-07-01 23:27:011209 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1210 EXPECT_THAT(StartRequest("c", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]6427fe22010-04-16 22:27:411211
1212 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1213
[email protected]2431756e2010-09-29 20:26:131214 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411215 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131216 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411217 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131218 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1219 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411220 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
1221}
1222
[email protected]d7027bb2010-05-10 18:58:541223TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
1224 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1225 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1226
1227 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521228 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131229 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541230 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151231 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201232 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:541233
1234 ClientSocketHandle handles[4];
1235 for (size_t i = 0; i < arraysize(handles); ++i) {
[email protected]6ecf2b92011-12-15 01:14:521236 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201237 EXPECT_EQ(
1238 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541239 handles[i].Init("b", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:201240 ClientSocketPool::RespectLimits::ENABLED,
1241 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:541242 }
1243
1244 // One will be stalled, cancel all the handles now.
1245 // This should hit the OnAvailableSocketSlot() code where we previously had
1246 // stalled groups, but no longer have any.
1247 for (size_t i = 0; i < arraysize(handles); ++i)
1248 handles[i].Reset();
1249}
1250
[email protected]eb5a99382010-07-11 03:18:261251TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:541252 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1253 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1254
[email protected]eb5a99382010-07-11 03:18:261255 {
1256 ClientSocketHandle handles[kDefaultMaxSockets];
[email protected]6ecf2b92011-12-15 01:14:521257 TestCompletionCallback callbacks[kDefaultMaxSockets];
[email protected]eb5a99382010-07-11 03:18:261258 for (int i = 0; i < kDefaultMaxSockets; ++i) {
Paul Jensen8d6f87ec2018-01-13 00:46:541259 EXPECT_EQ(OK, handles[i].Init(base::IntToString(i), params_,
1260 DEFAULT_PRIORITY, SocketTag(),
1261 ClientSocketPool::RespectLimits::ENABLED,
1262 callbacks[i].callback(), pool_.get(),
1263 NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261264 }
1265
1266 // Force a stalled group.
1267 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521268 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201269 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541270 stalled_handle.Init("foo", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:201271 ClientSocketPool::RespectLimits::ENABLED,
1272 callback.callback(), pool_.get(),
1273 NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261274
1275 // Cancel the stalled request.
1276 stalled_handle.Reset();
1277
1278 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1279 EXPECT_EQ(0, pool_->IdleSocketCount());
1280
1281 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541282 }
1283
[email protected]43a21b82010-06-10 21:30:541284 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1285 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:261286}
[email protected]43a21b82010-06-10 21:30:541287
[email protected]eb5a99382010-07-11 03:18:261288TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
1289 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1290 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1291
1292 {
1293 ClientSocketHandle handles[kDefaultMaxSockets];
1294 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521295 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201296 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541297 handles[i].Init(
1298 base::IntToString(i), params_, DEFAULT_PRIORITY,
1299 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1300 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261301 }
1302
1303 // Force a stalled group.
1304 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1305 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521306 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201307 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541308 stalled_handle.Init("foo", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:201309 ClientSocketPool::RespectLimits::ENABLED,
1310 callback.callback(), pool_.get(),
1311 NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261312
1313 // Since it is stalled, it should have no connect jobs.
1314 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101315 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261316
1317 // Cancel the stalled request.
1318 handles[0].Reset();
1319
[email protected]eb5a99382010-07-11 03:18:261320 // Now we should have a connect job.
1321 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101322 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261323
1324 // The stalled socket should connect.
robpercival214763f2016-07-01 23:27:011325 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:261326
1327 EXPECT_EQ(kDefaultMaxSockets + 1,
1328 client_socket_factory_.allocation_count());
1329 EXPECT_EQ(0, pool_->IdleSocketCount());
1330 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101331 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261332
1333 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541334 }
1335
[email protected]eb5a99382010-07-11 03:18:261336 EXPECT_EQ(1, pool_->IdleSocketCount());
1337}
[email protected]43a21b82010-06-10 21:30:541338
[email protected]eb5a99382010-07-11 03:18:261339TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1340 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1341 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:541342
[email protected]eb5a99382010-07-11 03:18:261343 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521344 TestCompletionCallback callback;
[email protected]eb5a99382010-07-11 03:18:261345 {
[email protected]51fdc7c2012-04-10 19:19:481346 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261347 ClientSocketHandle handles[kDefaultMaxSockets];
1348 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521349 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201350 EXPECT_EQ(OK, handles[i].Init(base::StringPrintf("Take 2: %d", i),
Paul Jensen8d6f87ec2018-01-13 00:46:541351 params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:201352 ClientSocketPool::RespectLimits::ENABLED,
1353 callback.callback(), pool_.get(),
1354 NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261355 }
1356
1357 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1358 EXPECT_EQ(0, pool_->IdleSocketCount());
[email protected]51fdc7c2012-04-10 19:19:481359 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261360
1361 // Now we will hit the socket limit.
tfarina428341112016-09-22 13:38:201362 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541363 stalled_handle.Init("foo", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:201364 ClientSocketPool::RespectLimits::ENABLED,
1365 callback.callback(), pool_.get(),
1366 NetLogWithSource()));
[email protected]51fdc7c2012-04-10 19:19:481367 EXPECT_TRUE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261368
1369 // Dropping out of scope will close all handles and return them to idle.
1370 }
[email protected]43a21b82010-06-10 21:30:541371
1372 // But if we wait for it, the released idle sockets will be closed in
1373 // preference of the waiting request.
robpercival214763f2016-07-01 23:27:011374 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:261375
1376 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1377 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:541378}
1379
1380// Regression test for http://crbug.com/40952.
1381TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1382 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]06d94042010-08-25 01:45:221383 pool_->EnableConnectBackupJobs();
[email protected]43a21b82010-06-10 21:30:541384 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1385
1386 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1387 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521388 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201389 EXPECT_EQ(
1390 OK, handle.Init(base::IntToString(i), params_, DEFAULT_PRIORITY,
Paul Jensen8d6f87ec2018-01-13 00:46:541391 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201392 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]43a21b82010-06-10 21:30:541393 }
1394
1395 // Flush all the DoReleaseSocket tasks.
fdoray5eeb7642016-06-22 16:11:281396 base::RunLoop().RunUntilIdle();
[email protected]43a21b82010-06-10 21:30:541397
1398 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1399 // reuse a socket.
1400 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1401 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521402 TestCompletionCallback callback;
[email protected]43a21b82010-06-10 21:30:541403
1404 // "0" is special here, since it should be the first entry in the sorted map,
1405 // which is the one which we would close an idle socket for. We shouldn't
1406 // close an idle socket though, since we should reuse the idle socket.
tfarina428341112016-09-22 13:38:201407 EXPECT_EQ(OK,
Paul Jensen8d6f87ec2018-01-13 00:46:541408 handle.Init("0", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:201409 ClientSocketPool::RespectLimits::ENABLED,
1410 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]43a21b82010-06-10 21:30:541411
1412 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1413 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1414}
1415
[email protected]ab838892009-06-30 18:49:051416TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531417 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091418
robpercival214763f2016-07-01 23:27:011419 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1420 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1421 EXPECT_THAT(StartRequest("a", IDLE), IsError(ERR_IO_PENDING));
1422 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
1423 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1424 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
1425 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1426 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091427
[email protected]2431756e2010-09-29 20:26:131428 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]c9d6a1d2009-07-14 16:15:201429 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1430 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131431 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1432 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091433
[email protected]c9d6a1d2009-07-14 16:15:201434 EXPECT_EQ(1, GetOrderOfRequest(1));
1435 EXPECT_EQ(2, GetOrderOfRequest(2));
[email protected]c9c6f5c2010-07-31 01:30:031436 EXPECT_EQ(8, GetOrderOfRequest(3));
1437 EXPECT_EQ(6, GetOrderOfRequest(4));
1438 EXPECT_EQ(4, GetOrderOfRequest(5));
1439 EXPECT_EQ(3, GetOrderOfRequest(6));
1440 EXPECT_EQ(5, GetOrderOfRequest(7));
1441 EXPECT_EQ(7, GetOrderOfRequest(8));
[email protected]75439d3b2009-07-23 22:11:171442
1443 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131444 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]f6d1d6eb2009-06-24 20:16:091445}
1446
[email protected]ab838892009-06-30 18:49:051447TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531448 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091449
robpercival214763f2016-07-01 23:27:011450 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1451 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1452 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
1453 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1454 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
1455 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1456 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091457
[email protected]2431756e2010-09-29 20:26:131458 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091459
[email protected]2431756e2010-09-29 20:26:131460 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
robpercival214763f2016-07-01 23:27:011461 EXPECT_THAT(request(i)->WaitForResult(), IsOk());
[email protected]c9d6a1d2009-07-14 16:15:201462
[email protected]2431756e2010-09-29 20:26:131463 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]c9d6a1d2009-07-14 16:15:201464 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131465 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1466 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091467}
1468
1469// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:051470// The pending connect job will be cancelled and should not call back into
1471// ClientSocketPoolBase.
1472TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531473 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201474
[email protected]ab838892009-06-30 18:49:051475 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131476 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521477 TestCompletionCallback callback;
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]2431756e2010-09-29 20:26:131482 handle.Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091483}
1484
[email protected]ab838892009-06-30 18:49:051485TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531486 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201487
[email protected]ab838892009-06-30 18:49:051488 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061489 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521490 TestCompletionCallback callback;
[email protected]f6d1d6eb2009-06-24 20:16:091491
mmenked3641e12016-01-28 16:06:151492 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541493 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151494 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201495 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]f6d1d6eb2009-06-24 20:16:091496
1497 handle.Reset();
1498
[email protected]6ecf2b92011-12-15 01:14:521499 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:131500 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541501 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151502 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201503 callback2.callback(), pool_.get(), NetLogWithSource()));
[email protected]f6d1d6eb2009-06-24 20:16:091504
robpercival214763f2016-07-01 23:27:011505 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]f6d1d6eb2009-06-24 20:16:091506 EXPECT_FALSE(callback.have_result());
1507
1508 handle.Reset();
1509}
1510
[email protected]ab838892009-06-30 18:49:051511TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531512 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091513
robpercival214763f2016-07-01 23:27:011514 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1515 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1516 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
1517 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1518 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
1519 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1520 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091521
1522 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201523 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]2431756e2010-09-29 20:26:131524 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1525 (*requests())[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091526
[email protected]2431756e2010-09-29 20:26:131527 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091528
[email protected]c9d6a1d2009-07-14 16:15:201529 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1530 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131531 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1532 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091533
[email protected]c9d6a1d2009-07-14 16:15:201534 EXPECT_EQ(1, GetOrderOfRequest(1));
1535 EXPECT_EQ(2, GetOrderOfRequest(2));
1536 EXPECT_EQ(5, GetOrderOfRequest(3));
1537 EXPECT_EQ(3, GetOrderOfRequest(4));
[email protected]2431756e2010-09-29 20:26:131538 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1539 GetOrderOfRequest(5)); // Canceled request.
[email protected]c9d6a1d2009-07-14 16:15:201540 EXPECT_EQ(4, GetOrderOfRequest(6));
1541 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171542
1543 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131544 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091545}
1546
mmenke33d24423d2015-05-19 19:41:091547// Function to be used as a callback on socket request completion. It first
1548// disconnects the successfully connected socket from the first request, and
1549// then reuses the ClientSocketHandle to request another socket.
1550//
1551// |nested_callback| is called with the result of the second socket request.
1552void RequestSocketOnComplete(ClientSocketHandle* handle,
1553 TestClientSocketPool* pool,
1554 TestConnectJobFactory* test_connect_job_factory,
1555 TestConnectJob::JobType next_job_type,
1556 const CompletionCallback& nested_callback,
1557 int first_request_result) {
robpercival214763f2016-07-01 23:27:011558 EXPECT_THAT(first_request_result, IsOk());
mmenke33d24423d2015-05-19 19:41:091559
1560 test_connect_job_factory->set_job_type(next_job_type);
1561
1562 // Don't allow reuse of the socket. Disconnect it and then release it.
1563 if (handle->socket())
1564 handle->socket()->Disconnect();
1565 handle->Reset();
1566
mmenked3641e12016-01-28 16:06:151567 scoped_refptr<TestSocketParams> params(new TestSocketParams());
mmenke33d24423d2015-05-19 19:41:091568 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:541569 int rv = handle->Init("a", params, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:151570 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201571 nested_callback, pool, NetLogWithSource());
mmenke33d24423d2015-05-19 19:41:091572 if (rv != ERR_IO_PENDING) {
1573 DCHECK_EQ(TestConnectJob::kMockJob, next_job_type);
1574 nested_callback.Run(rv);
1575 } else {
1576 DCHECK_EQ(TestConnectJob::kMockPendingJob, next_job_type);
[email protected]6ecf2b92011-12-15 01:14:521577 }
mmenke33d24423d2015-05-19 19:41:091578}
[email protected]f6d1d6eb2009-06-24 20:16:091579
mmenke33d24423d2015-05-19 19:41:091580// Tests the case where a second socket is requested in a completion callback,
1581// and the second socket connects asynchronously. Reuses the same
1582// ClientSocketHandle for the second socket, after disconnecting the first.
[email protected]2ab05b52009-07-01 23:57:581583TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531584 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201585
[email protected]0b7648c2009-07-06 20:14:011586 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061587 ClientSocketHandle handle;
mmenke33d24423d2015-05-19 19:41:091588 TestCompletionCallback second_result_callback;
1589 int rv = handle.Init(
Paul Jensen8d6f87ec2018-01-13 00:46:541590 "a", params_, DEFAULT_PRIORITY, SocketTag(),
1591 ClientSocketPool::RespectLimits::ENABLED,
mmenke33d24423d2015-05-19 19:41:091592 base::Bind(&RequestSocketOnComplete, &handle, pool_.get(),
1593 connect_job_factory_, TestConnectJob::kMockPendingJob,
1594 second_result_callback.callback()),
tfarina428341112016-09-22 13:38:201595 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011596 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091597
robpercival214763f2016-07-01 23:27:011598 EXPECT_THAT(second_result_callback.WaitForResult(), IsOk());
[email protected]2ab05b52009-07-01 23:57:581599}
[email protected]f6d1d6eb2009-06-24 20:16:091600
mmenke33d24423d2015-05-19 19:41:091601// Tests the case where a second socket is requested in a completion callback,
1602// and the second socket connects synchronously. Reuses the same
1603// ClientSocketHandle for the second socket, after disconnecting the first.
[email protected]2ab05b52009-07-01 23:57:581604TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531605 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201606
[email protected]0b7648c2009-07-06 20:14:011607 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061608 ClientSocketHandle handle;
mmenke33d24423d2015-05-19 19:41:091609 TestCompletionCallback second_result_callback;
1610 int rv = handle.Init(
Paul Jensen8d6f87ec2018-01-13 00:46:541611 "a", params_, DEFAULT_PRIORITY, SocketTag(),
1612 ClientSocketPool::RespectLimits::ENABLED,
mmenke33d24423d2015-05-19 19:41:091613 base::Bind(&RequestSocketOnComplete, &handle, pool_.get(),
1614 connect_job_factory_, TestConnectJob::kMockPendingJob,
1615 second_result_callback.callback()),
tfarina428341112016-09-22 13:38:201616 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011617 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2ab05b52009-07-01 23:57:581618
robpercival214763f2016-07-01 23:27:011619 EXPECT_THAT(second_result_callback.WaitForResult(), IsOk());
[email protected]f6d1d6eb2009-06-24 20:16:091620}
1621
1622// Make sure that pending requests get serviced after active requests get
1623// cancelled.
[email protected]ab838892009-06-30 18:49:051624TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531625 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201626
[email protected]0b7648c2009-07-06 20:14:011627 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091628
robpercival214763f2016-07-01 23:27:011629 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1630 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1631 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1632 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1633 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1634 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1635 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091636
[email protected]c9d6a1d2009-07-14 16:15:201637 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1638 // Let's cancel them.
1639 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]2431756e2010-09-29 20:26:131640 ASSERT_FALSE(request(i)->handle()->is_initialized());
1641 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091642 }
1643
[email protected]f6d1d6eb2009-06-24 20:16:091644 // Let's wait for the rest to complete now.
[email protected]2431756e2010-09-29 20:26:131645 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
robpercival214763f2016-07-01 23:27:011646 EXPECT_THAT(request(i)->WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:131647 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091648 }
1649
[email protected]2431756e2010-09-29 20:26:131650 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1651 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091652}
1653
1654// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051655TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531656 const size_t kMaxSockets = 5;
1657 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201658
[email protected]0b7648c2009-07-06 20:14:011659 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091660
[email protected]211d21722009-07-22 15:48:531661 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1662 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091663
1664 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531665 for (size_t i = 0; i < kNumberOfRequests; ++i)
robpercival214763f2016-07-01 23:27:011666 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091667
[email protected]211d21722009-07-22 15:48:531668 for (size_t i = 0; i < kNumberOfRequests; ++i)
robpercival214763f2016-07-01 23:27:011669 EXPECT_THAT(request(i)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]f6d1d6eb2009-06-24 20:16:091670}
1671
mmenke9d72fe42017-05-18 22:36:071672// Make sure that pending requests that complete synchronously get serviced
1673// after active requests fail. See https://crbug.com/723748
1674TEST_F(ClientSocketPoolBaseTest, HandleMultipleSyncFailuresAfterAsyncFailure) {
1675 const size_t kNumberOfRequests = 10;
1676 const size_t kMaxSockets = 1;
1677 CreatePool(kMaxSockets, kMaxSockets);
1678
1679 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1680
1681 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1682
1683 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
1684
1685 // Queue up all the other requests
1686 for (size_t i = 1; i < kNumberOfRequests; ++i)
1687 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1688
1689 // Make sure all requests fail, instead of hanging.
1690 for (size_t i = 0; i < kNumberOfRequests; ++i)
1691 EXPECT_THAT(request(i)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
1692}
1693
[email protected]5fc08e32009-07-15 17:09:571694TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531695 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571696
1697 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1698
[email protected]2431756e2010-09-29 20:26:131699 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521700 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:541701 int rv = handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151702 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201703 callback.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011704 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:571705
1706 // Cancel the active request.
[email protected]2431756e2010-09-29 20:26:131707 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571708
Paul Jensen8d6f87ec2018-01-13 00:46:541709 rv = handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151710 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201711 callback.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011712 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1713 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]5fc08e32009-07-15 17:09:571714
[email protected]2431756e2010-09-29 20:26:131715 EXPECT_FALSE(handle.is_reused());
[email protected]034df0f32013-01-07 23:17:481716 TestLoadTimingInfoConnectedNotReused(handle);
[email protected]5fc08e32009-07-15 17:09:571717 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1718}
1719
xunjieli26619e72016-11-23 19:39:551720TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsForced) {
xunjieli26619e72016-11-23 19:39:551721 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1722 ClientSocketHandle handle;
1723 TestCompletionCallback callback;
1724 BoundTestNetLog log;
Paul Jensen8d6f87ec2018-01-13 00:46:541725 int rv = handle.Init("a", params_, LOWEST, SocketTag(),
xunjieli26619e72016-11-23 19:39:551726 ClientSocketPool::RespectLimits::ENABLED,
1727 callback.callback(), pool_.get(), log.bound());
1728 EXPECT_THAT(rv, IsOk());
1729 handle.Reset();
1730 EXPECT_EQ(1, pool_->IdleSocketCount());
1731 pool_->CloseIdleSockets();
xunjieli26619e72016-11-23 19:39:551732}
1733
xunjieli92feb332017-03-03 17:19:231734TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsInGroupForced) {
xunjieli92feb332017-03-03 17:19:231735 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1736 TestCompletionCallback callback;
1737 BoundTestNetLog log;
1738 ClientSocketHandle handle1;
Paul Jensen8d6f87ec2018-01-13 00:46:541739 int rv = handle1.Init("a", params_, LOWEST, SocketTag(),
xunjieli92feb332017-03-03 17:19:231740 ClientSocketPool::RespectLimits::ENABLED,
1741 callback.callback(), pool_.get(), log.bound());
1742 EXPECT_THAT(rv, IsOk());
1743 ClientSocketHandle handle2;
Paul Jensen8d6f87ec2018-01-13 00:46:541744 rv = handle2.Init("a", params_, LOWEST, SocketTag(),
xunjieli92feb332017-03-03 17:19:231745 ClientSocketPool::RespectLimits::ENABLED,
1746 callback.callback(), pool_.get(), log.bound());
1747 ClientSocketHandle handle3;
Paul Jensen8d6f87ec2018-01-13 00:46:541748 rv = handle3.Init("b", params_, LOWEST, SocketTag(),
xunjieli92feb332017-03-03 17:19:231749 ClientSocketPool::RespectLimits::ENABLED,
1750 callback.callback(), pool_.get(), log.bound());
1751 EXPECT_THAT(rv, IsOk());
1752 handle1.Reset();
1753 handle2.Reset();
1754 handle3.Reset();
1755 EXPECT_EQ(3, pool_->IdleSocketCount());
1756 pool_->CloseIdleSocketsInGroup("a");
1757 EXPECT_EQ(1, pool_->IdleSocketCount());
xunjieli92feb332017-03-03 17:19:231758}
1759
xunjieli26619e72016-11-23 19:39:551760TEST_F(ClientSocketPoolBaseTest, CleanUpUnusableIdleSockets) {
xunjieli26619e72016-11-23 19:39:551761 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1762 ClientSocketHandle handle;
1763 TestCompletionCallback callback;
1764 BoundTestNetLog log;
Paul Jensen8d6f87ec2018-01-13 00:46:541765 int rv = handle.Init("a", params_, LOWEST, SocketTag(),
xunjieli26619e72016-11-23 19:39:551766 ClientSocketPool::RespectLimits::ENABLED,
1767 callback.callback(), pool_.get(), log.bound());
1768 EXPECT_THAT(rv, IsOk());
1769 StreamSocket* socket = handle.socket();
1770 handle.Reset();
1771 EXPECT_EQ(1, pool_->IdleSocketCount());
1772
1773 // Disconnect socket now to make the socket unusable.
1774 socket->Disconnect();
1775 ClientSocketHandle handle2;
Paul Jensen8d6f87ec2018-01-13 00:46:541776 rv = handle2.Init("a", params_, LOWEST, SocketTag(),
xunjieli26619e72016-11-23 19:39:551777 ClientSocketPool::RespectLimits::ENABLED,
1778 callback.callback(), pool_.get(), log.bound());
1779 EXPECT_THAT(rv, IsOk());
1780 EXPECT_FALSE(handle2.is_reused());
xunjieli26619e72016-11-23 19:39:551781}
1782
[email protected]2b7523d2009-07-29 20:29:231783// Regression test for http://crbug.com/17985.
1784TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1785 const int kMaxSockets = 3;
1786 const int kMaxSocketsPerGroup = 2;
1787 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1788
[email protected]ac790b42009-12-02 04:31:311789 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231790
robpercival214763f2016-07-01 23:27:011791 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1792 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
[email protected]2b7523d2009-07-29 20:29:231793
1794 // This is going to be a pending request in an otherwise empty group.
robpercival214763f2016-07-01 23:27:011795 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]2b7523d2009-07-29 20:29:231796
1797 // Reach the maximum socket limit.
robpercival214763f2016-07-01 23:27:011798 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
[email protected]2b7523d2009-07-29 20:29:231799
1800 // Create a stalled group with high priorities.
robpercival214763f2016-07-01 23:27:011801 EXPECT_THAT(StartRequest("c", kHighPriority), IsError(ERR_IO_PENDING));
1802 EXPECT_THAT(StartRequest("c", kHighPriority), IsError(ERR_IO_PENDING));
[email protected]2b7523d2009-07-29 20:29:231803
[email protected]eb5a99382010-07-11 03:18:261804 // Release the first two sockets from "a". Because this is a keepalive,
1805 // the first release will unblock the pending request for "a". The
1806 // second release will unblock a request for "c", becaue it is the next
1807 // high priority socket.
[email protected]2431756e2010-09-29 20:26:131808 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1809 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]2b7523d2009-07-29 20:29:231810
1811 // Closing idle sockets should not get us into trouble, but in the bug
1812 // we were hitting a CHECK here.
[email protected]93054cc12010-06-08 06:12:411813 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]43a21b82010-06-10 21:30:541814 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261815
[email protected]2da659e2013-05-23 20:51:341816 // Run the released socket wakeups.
fdoray5eeb7642016-06-22 16:11:281817 base::RunLoop().RunUntilIdle();
[email protected]2b7523d2009-07-29 20:29:231818}
1819
[email protected]4d3b05d2010-01-27 21:27:291820TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531821 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571822
1823 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131824 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521825 TestCompletionCallback callback;
vishal.b62985ca92015-04-17 08:45:511826 BoundTestNetLog log;
Paul Jensen8d6f87ec2018-01-13 00:46:541827 int rv = handle.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:151828 ClientSocketPool::RespectLimits::ENABLED,
1829 callback.callback(), pool_.get(), log.bound());
robpercival214763f2016-07-01 23:27:011830 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2431756e2010-09-29 20:26:131831 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
[email protected]034df0f32013-01-07 23:17:481832 TestLoadTimingInfoNotConnected(handle);
1833
robpercival214763f2016-07-01 23:27:011834 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:131835 EXPECT_TRUE(handle.is_initialized());
1836 EXPECT_TRUE(handle.socket());
[email protected]034df0f32013-01-07 23:17:481837 TestLoadTimingInfoConnectedNotReused(handle);
1838
[email protected]2431756e2010-09-29 20:26:131839 handle.Reset();
[email protected]034df0f32013-01-07 23:17:481840 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:301841
mmenke43758e62015-05-04 21:09:461842 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:401843 log.GetEntries(&entries);
1844
1845 EXPECT_EQ(4u, entries.size());
mikecirone8b85c432016-09-08 19:11:001846 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171847 EXPECT_TRUE(LogContainsEvent(
mikecirone8b85c432016-09-08 19:11:001848 entries, 1, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1849 NetLogEventPhase::NONE));
1850 EXPECT_TRUE(LogContainsEvent(entries, 2,
1851 NetLogEventType::SOCKET_POOL_BOUND_TO_SOCKET,
1852 NetLogEventPhase::NONE));
1853 EXPECT_TRUE(LogContainsEndEvent(entries, 3, NetLogEventType::SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571854}
1855
[email protected]4d3b05d2010-01-27 21:27:291856TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571857 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531858 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571859
1860 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2431756e2010-09-29 20:26:131861 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521862 TestCompletionCallback callback;
vishal.b62985ca92015-04-17 08:45:511863 BoundTestNetLog log;
[email protected]e60e47a2010-07-14 03:37:181864 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:131865 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:431866 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:451867 info.headers = new HttpResponseHeaders(std::string());
[email protected]2431756e2010-09-29 20:26:131868 handle.set_ssl_error_response_info(info);
mmenked3641e12016-01-28 16:06:151869 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541870 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151871 ClientSocketPool::RespectLimits::ENABLED,
1872 callback.callback(), pool_.get(), log.bound()));
[email protected]2431756e2010-09-29 20:26:131873 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
robpercival214763f2016-07-01 23:27:011874 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]2431756e2010-09-29 20:26:131875 EXPECT_FALSE(handle.is_ssl_error());
1876 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:301877
mmenke43758e62015-05-04 21:09:461878 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:401879 log.GetEntries(&entries);
1880
1881 EXPECT_EQ(3u, entries.size());
mikecirone8b85c432016-09-08 19:11:001882 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171883 EXPECT_TRUE(LogContainsEvent(
mikecirone8b85c432016-09-08 19:11:001884 entries, 1, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1885 NetLogEventPhase::NONE));
1886 EXPECT_TRUE(LogContainsEndEvent(entries, 2, NetLogEventType::SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571887}
1888
mmenke6be122f2015-03-09 22:22:471889// Check that an async ConnectJob failure does not result in creation of a new
1890// ConnectJob when there's another pending request also waiting on its own
1891// ConnectJob. See http://crbug.com/463960.
1892TEST_F(ClientSocketPoolBaseTest, AsyncFailureWithPendingRequestWithJob) {
1893 CreatePool(2, 2);
1894 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1895
robpercival214763f2016-07-01 23:27:011896 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1897 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
mmenke6be122f2015-03-09 22:22:471898
robpercival214763f2016-07-01 23:27:011899 EXPECT_THAT(request(0)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
1900 EXPECT_THAT(request(1)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
mmenke6be122f2015-03-09 22:22:471901
1902 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1903}
1904
[email protected]4d3b05d2010-01-27 21:27:291905TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101906 // TODO(eroman): Add back the log expectations! Removed them because the
1907 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531908 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571909
1910 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131911 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521912 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131913 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:521914 TestCompletionCallback callback2;
[email protected]5fc08e32009-07-15 17:09:571915
[email protected]2431756e2010-09-29 20:26:131916 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541917 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151918 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201919 callback.callback(), pool_.get(), NetLogWithSource()));
vishal.b62985ca92015-04-17 08:45:511920 BoundTestNetLog log2;
tfarina428341112016-09-22 13:38:201921 EXPECT_EQ(
1922 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541923 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:201924 ClientSocketPool::RespectLimits::ENABLED,
1925 callback2.callback(), pool_.get(), NetLogWithSource()));
[email protected]5fc08e32009-07-15 17:09:571926
[email protected]2431756e2010-09-29 20:26:131927 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571928
[email protected]fd7b7c92009-08-20 19:38:301929
1930 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301931
robpercival214763f2016-07-01 23:27:011932 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:131933 handle2.Reset();
[email protected]fd7b7c92009-08-20 19:38:301934
1935 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531936 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571937}
1938
[email protected]4d3b05d2010-01-27 21:27:291939TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341940 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1941
[email protected]17a0c6c2009-08-04 00:07:041942 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1943
robpercival214763f2016-07-01 23:27:011944 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
1945 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1946 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1947 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
[email protected]974ebd62009-08-03 23:14:341948
1949 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]2431756e2010-09-29 20:26:131950 (*requests())[2]->handle()->Reset();
1951 (*requests())[3]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341952 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1953
[email protected]2431756e2010-09-29 20:26:131954 (*requests())[1]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341955 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1956
[email protected]2431756e2010-09-29 20:26:131957 (*requests())[0]->handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261958 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]974ebd62009-08-03 23:14:341959}
1960
[email protected]5fc08e32009-07-15 17:09:571961// When requests and ConnectJobs are not coupled, the request will get serviced
1962// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291963TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531964 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571965
1966 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321967 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571968
[email protected]2431756e2010-09-29 20:26:131969 std::vector<TestSocketRequest*> request_order;
1970 size_t completion_count; // unused
1971 TestSocketRequest req1(&request_order, &completion_count);
Paul Jensen8d6f87ec2018-01-13 00:46:541972 int rv =
1973 req1.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
1974 ClientSocketPool::RespectLimits::ENABLED,
1975 req1.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011976 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1977 EXPECT_THAT(req1.WaitForResult(), IsOk());
[email protected]5fc08e32009-07-15 17:09:571978
1979 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1980 // without a job.
1981 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1982
[email protected]2431756e2010-09-29 20:26:131983 TestSocketRequest req2(&request_order, &completion_count);
Paul Jensen8d6f87ec2018-01-13 00:46:541984 rv = req2.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151985 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201986 req2.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011987 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2431756e2010-09-29 20:26:131988 TestSocketRequest req3(&request_order, &completion_count);
Paul Jensen8d6f87ec2018-01-13 00:46:541989 rv = req3.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151990 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:201991 req3.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011992 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:571993
1994 // Both Requests 2 and 3 are pending. We release socket 1 which should
1995 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331996 req1.handle()->Reset();
[email protected]2da659e2013-05-23 20:51:341997 // Run the released socket wakeups.
fdoray5eeb7642016-06-22 16:11:281998 base::RunLoop().RunUntilIdle();
[email protected]a6c59f62009-07-29 16:33:331999 ASSERT_TRUE(req2.handle()->socket());
robpercival214763f2016-07-01 23:27:012000 EXPECT_THAT(req2.WaitForResult(), IsOk());
[email protected]a6c59f62009-07-29 16:33:332001 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:572002
2003 // Signal job 2, which should service request 3.
2004
2005 client_socket_factory_.SignalJobs();
robpercival214763f2016-07-01 23:27:012006 EXPECT_THAT(req3.WaitForResult(), IsOk());
[email protected]5fc08e32009-07-15 17:09:572007
[email protected]2431756e2010-09-29 20:26:132008 ASSERT_EQ(3U, request_order.size());
2009 EXPECT_EQ(&req1, request_order[0]);
2010 EXPECT_EQ(&req2, request_order[1]);
2011 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:572012 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2013}
2014
2015// The requests are not coupled to the jobs. So, the requests should finish in
2016// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:292017TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:532018 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:572019 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:322020 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:572021
[email protected]2431756e2010-09-29 20:26:132022 std::vector<TestSocketRequest*> request_order;
2023 size_t completion_count; // unused
2024 TestSocketRequest req1(&request_order, &completion_count);
Paul Jensen8d6f87ec2018-01-13 00:46:542025 int rv =
2026 req1.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2027 ClientSocketPool::RespectLimits::ENABLED,
2028 req1.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012029 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572030
[email protected]2431756e2010-09-29 20:26:132031 TestSocketRequest req2(&request_order, &completion_count);
Paul Jensen8d6f87ec2018-01-13 00:46:542032 rv = req2.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152033 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202034 req2.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012035 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572036
2037 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:322038 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:572039
[email protected]2431756e2010-09-29 20:26:132040 TestSocketRequest req3(&request_order, &completion_count);
Paul Jensen8d6f87ec2018-01-13 00:46:542041 rv = req3.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152042 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202043 req3.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012044 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572045
robpercival214763f2016-07-01 23:27:012046 EXPECT_THAT(req1.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
2047 EXPECT_THAT(req2.WaitForResult(), IsOk());
2048 EXPECT_THAT(req3.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]5fc08e32009-07-15 17:09:572049
[email protected]2431756e2010-09-29 20:26:132050 ASSERT_EQ(3U, request_order.size());
2051 EXPECT_EQ(&req1, request_order[0]);
2052 EXPECT_EQ(&req2, request_order[1]);
2053 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:572054}
2055
[email protected]03b7c8c2013-07-20 04:38:552056// Test GetLoadState in the case there's only one socket request.
2057TEST_F(ClientSocketPoolBaseTest, LoadStateOneRequest) {
[email protected]211d21722009-07-22 15:48:532058 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]03b7c8c2013-07-20 04:38:552059 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]5fc08e32009-07-15 17:09:572060
[email protected]2431756e2010-09-29 20:26:132061 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522062 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:542063 int rv = handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152064 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202065 callback.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012066 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552067 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:572068
[email protected]03b7c8c2013-07-20 04:38:552069 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2070 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
2071
2072 // No point in completing the connection, since ClientSocketHandles only
2073 // expect the LoadState to be checked while connecting.
2074}
2075
2076// Test GetLoadState in the case there are two socket requests.
haavardm835c1d62015-04-22 08:18:002077// Only the first connection in the pool should affect the pool's load status.
[email protected]03b7c8c2013-07-20 04:38:552078TEST_F(ClientSocketPoolBaseTest, LoadStateTwoRequests) {
2079 CreatePool(2, 2);
2080 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2081
2082 ClientSocketHandle handle;
2083 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:542084 int rv = handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152085 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202086 callback.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012087 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
haavardm835c1d62015-04-22 08:18:002088 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
2089
2090 ClientSocketHandle handle2;
2091 TestCompletionCallback callback2;
Paul Jensen8d6f87ec2018-01-13 00:46:542092 rv = handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152093 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202094 callback2.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012095 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
haavardm835c1d62015-04-22 08:18:002096 client_socket_factory_.SetJobLoadState(1, LOAD_STATE_RESOLVING_HOST);
2097
2098 // Check that both handles report the state of the first job.
2099 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle.GetLoadState());
2100 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle2.GetLoadState());
2101
2102 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_CONNECTING);
2103
2104 // Check that both handles change to LOAD_STATE_CONNECTING.
2105 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2106 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
2107}
2108
2109// Test that the second connection request does not affect the pool's load
2110// status.
2111TEST_F(ClientSocketPoolBaseTest, LoadStateTwoRequestsChangeSecondRequestState) {
2112 CreatePool(2, 2);
2113 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2114
2115 ClientSocketHandle handle;
2116 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:542117 int rv = handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152118 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202119 callback.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012120 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572121
[email protected]2431756e2010-09-29 20:26:132122 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522123 TestCompletionCallback callback2;
Paul Jensen8d6f87ec2018-01-13 00:46:542124 rv = handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152125 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202126 callback2.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012127 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
haavardm835c1d62015-04-22 08:18:002128 client_socket_factory_.SetJobLoadState(1, LOAD_STATE_RESOLVING_HOST);
[email protected]03b7c8c2013-07-20 04:38:552129
[email protected]03b7c8c2013-07-20 04:38:552130 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2131 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
2132
haavardm835c1d62015-04-22 08:18:002133 // First job connects and the first request gets the socket. The
[email protected]03b7c8c2013-07-20 04:38:552134 // second handle switches to the state of the remaining ConnectJob.
2135 client_socket_factory_.SignalJob(0);
robpercival214763f2016-07-01 23:27:012136 EXPECT_THAT(callback.WaitForResult(), IsOk());
haavardm835c1d62015-04-22 08:18:002137 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle2.GetLoadState());
[email protected]03b7c8c2013-07-20 04:38:552138}
2139
2140// Test GetLoadState in the case the per-group limit is reached.
2141TEST_F(ClientSocketPoolBaseTest, LoadStateGroupLimit) {
2142 CreatePool(2, 1);
2143 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2144
2145 ClientSocketHandle handle;
2146 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:542147 int rv = handle.Init("a", params_, MEDIUM, SocketTag(),
mmenked3641e12016-01-28 16:06:152148 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202149 callback.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012150 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552151 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2152
2153 // Request another socket from the same pool, buth with a higher priority.
2154 // The first request should now be stalled at the socket group limit.
2155 ClientSocketHandle handle2;
2156 TestCompletionCallback callback2;
Paul Jensen8d6f87ec2018-01-13 00:46:542157 rv = handle2.Init("a", params_, HIGHEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152158 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202159 callback2.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012160 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552161 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2162 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
2163
2164 // The first handle should remain stalled as the other socket goes through
2165 // the connect process.
2166
2167 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2168 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2169 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle2.GetLoadState());
2170
2171 client_socket_factory_.SignalJob(0);
robpercival214763f2016-07-01 23:27:012172 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]03b7c8c2013-07-20 04:38:552173 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2174
2175 // Closing the second socket should cause the stalled handle to finally get a
2176 // ConnectJob.
2177 handle2.socket()->Disconnect();
2178 handle2.Reset();
2179 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2180}
2181
2182// Test GetLoadState in the case the per-pool limit is reached.
2183TEST_F(ClientSocketPoolBaseTest, LoadStatePoolLimit) {
2184 CreatePool(2, 2);
2185 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2186
2187 ClientSocketHandle handle;
2188 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:542189 int rv = handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152190 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202191 callback.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012192 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552193
2194 // Request for socket from another pool.
2195 ClientSocketHandle handle2;
2196 TestCompletionCallback callback2;
Paul Jensen8d6f87ec2018-01-13 00:46:542197 rv = handle2.Init("b", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152198 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202199 callback2.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012200 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552201
2202 // Request another socket from the first pool. Request should stall at the
2203 // socket pool limit.
2204 ClientSocketHandle handle3;
2205 TestCompletionCallback callback3;
Paul Jensen8d6f87ec2018-01-13 00:46:542206 rv = handle3.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152207 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202208 callback2.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012209 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552210
2211 // The third handle should remain stalled as the other sockets in its group
2212 // goes through the connect process.
2213
2214 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2215 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2216
2217 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2218 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
2219 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2220
2221 client_socket_factory_.SignalJob(0);
robpercival214763f2016-07-01 23:27:012222 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]03b7c8c2013-07-20 04:38:552223 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2224
2225 // Closing a socket should allow the stalled handle to finally get a new
2226 // ConnectJob.
2227 handle.socket()->Disconnect();
2228 handle.Reset();
2229 EXPECT_EQ(LOAD_STATE_CONNECTING, handle3.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:572230}
2231
[email protected]e772db3f2010-07-12 18:11:132232TEST_F(ClientSocketPoolBaseTest, Recoverable) {
2233 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2234 connect_job_factory_->set_job_type(TestConnectJob::kMockRecoverableJob);
2235
[email protected]2431756e2010-09-29 20:26:132236 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522237 TestCompletionCallback callback;
2238 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED,
Paul Jensen8d6f87ec2018-01-13 00:46:542239 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152240 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202241 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:132242 EXPECT_TRUE(handle.is_initialized());
2243 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:132244}
2245
2246TEST_F(ClientSocketPoolBaseTest, AsyncRecoverable) {
2247 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2248
2249 connect_job_factory_->set_job_type(
2250 TestConnectJob::kMockPendingRecoverableJob);
[email protected]2431756e2010-09-29 20:26:132251 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522252 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132253 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542254 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152255 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202256 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:132257 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
robpercival214763f2016-07-01 23:27:012258 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_PROXY_AUTH_REQUESTED));
[email protected]2431756e2010-09-29 20:26:132259 EXPECT_TRUE(handle.is_initialized());
2260 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:132261}
2262
[email protected]e60e47a2010-07-14 03:37:182263TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
2264 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2265 connect_job_factory_->set_job_type(
2266 TestConnectJob::kMockAdditionalErrorStateJob);
2267
[email protected]2431756e2010-09-29 20:26:132268 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522269 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132270 EXPECT_EQ(ERR_CONNECTION_FAILED,
Paul Jensen8d6f87ec2018-01-13 00:46:542271 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152272 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202273 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:132274 EXPECT_FALSE(handle.is_initialized());
2275 EXPECT_FALSE(handle.socket());
2276 EXPECT_TRUE(handle.is_ssl_error());
2277 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182278}
2279
2280TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
2281 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2282
2283 connect_job_factory_->set_job_type(
2284 TestConnectJob::kMockPendingAdditionalErrorStateJob);
[email protected]2431756e2010-09-29 20:26:132285 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522286 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132287 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542288 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152289 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202290 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:132291 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
robpercival214763f2016-07-01 23:27:012292 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]2431756e2010-09-29 20:26:132293 EXPECT_FALSE(handle.is_initialized());
2294 EXPECT_FALSE(handle.socket());
2295 EXPECT_TRUE(handle.is_ssl_error());
2296 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182297}
2298
martijn003cd612016-05-19 22:24:382299// Make sure we can reuse sockets.
2300TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSocketsReuse) {
[email protected]64770b7d2011-11-16 04:30:412301 CreatePoolWithIdleTimeouts(
2302 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
[email protected]e7b1c6d2c2012-05-05 00:54:032303 base::TimeDelta(), // Time out unused sockets immediately.
2304 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2305
2306 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2307
2308 ClientSocketHandle handle;
2309 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:542310 int rv = handle.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152311 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202312 callback.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012313 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e7b1c6d2c2012-05-05 00:54:032314 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
robpercival214763f2016-07-01 23:27:012315 ASSERT_THAT(callback.WaitForResult(), IsOk());
[email protected]e7b1c6d2c2012-05-05 00:54:032316
2317 // Use and release the socket.
Ramin Halavati0a08cc82018-02-06 07:46:382318 EXPECT_EQ(1, handle.socket()->Write(NULL, 1, CompletionCallback(),
2319 TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]034df0f32013-01-07 23:17:482320 TestLoadTimingInfoConnectedNotReused(handle);
[email protected]e7b1c6d2c2012-05-05 00:54:032321 handle.Reset();
2322
2323 // Should now have one idle socket.
2324 ASSERT_EQ(1, pool_->IdleSocketCount());
2325
2326 // Request a new socket. This should reuse the old socket and complete
2327 // synchronously.
vishal.b62985ca92015-04-17 08:45:512328 BoundTestNetLog log;
Paul Jensen8d6f87ec2018-01-13 00:46:542329 rv = handle.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152330 ClientSocketPool::RespectLimits::ENABLED,
2331 CompletionCallback(), pool_.get(), log.bound());
robpercival214763f2016-07-01 23:27:012332 ASSERT_THAT(rv, IsOk());
[email protected]e7b1c6d2c2012-05-05 00:54:032333 EXPECT_TRUE(handle.is_reused());
[email protected]034df0f32013-01-07 23:17:482334 TestLoadTimingInfoConnectedReused(handle);
[email protected]e7b1c6d2c2012-05-05 00:54:032335
2336 ASSERT_TRUE(pool_->HasGroup("a"));
2337 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2338 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2339
mmenke43758e62015-05-04 21:09:462340 TestNetLogEntry::List entries;
[email protected]e7b1c6d2c2012-05-05 00:54:032341 log.GetEntries(&entries);
2342 EXPECT_TRUE(LogContainsEntryWithType(
mikecirone8b85c432016-09-08 19:11:002343 entries, 1, NetLogEventType::SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]e7b1c6d2c2012-05-05 00:54:032344}
2345
martijn003cd612016-05-19 22:24:382346// Make sure we cleanup old unused sockets.
Eric Romanb49715e2018-04-24 22:41:172347TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSocketsNoReuse) {
[email protected]e7b1c6d2c2012-05-05 00:54:032348 CreatePoolWithIdleTimeouts(
2349 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2350 base::TimeDelta(), // Time out unused sockets immediately
2351 base::TimeDelta()); // Time out used sockets immediately
[email protected]64770b7d2011-11-16 04:30:412352
2353 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2354
2355 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2356
2357 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522358 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:542359 int rv = handle.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152360 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202361 callback.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012362 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]64770b7d2011-11-16 04:30:412363 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2364
2365 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522366 TestCompletionCallback callback2;
Paul Jensen8d6f87ec2018-01-13 00:46:542367 rv = handle2.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152368 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202369 callback2.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012370 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]64770b7d2011-11-16 04:30:412371 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
2372
2373 // Cancel one of the requests. Wait for the other, which will get the first
2374 // job. Release the socket. Run the loop again to make sure the second
2375 // socket is sitting idle and the first one is released (since ReleaseSocket()
2376 // just posts a DoReleaseSocket() task).
2377
2378 handle.Reset();
robpercival214763f2016-07-01 23:27:012379 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]64770b7d2011-11-16 04:30:412380 // Use the socket.
Ramin Halavati0a08cc82018-02-06 07:46:382381 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, CompletionCallback(),
2382 TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]64770b7d2011-11-16 04:30:412383 handle2.Reset();
2384
[email protected]e7b1c6d2c2012-05-05 00:54:032385 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2386 // actually become pending until 2ms after they have been created. In order
2387 // to flush all tasks, we need to wait so that we know there are no
2388 // soon-to-be-pending tasks waiting.
2389 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
fdoray5eeb7642016-06-22 16:11:282390 base::RunLoop().RunUntilIdle();
[email protected]64770b7d2011-11-16 04:30:412391
[email protected]e7b1c6d2c2012-05-05 00:54:032392 // Both sockets should now be idle.
[email protected]64770b7d2011-11-16 04:30:412393 ASSERT_EQ(2, pool_->IdleSocketCount());
2394
2395 // Request a new socket. This should cleanup the unused and timed out ones.
2396 // A new socket will be created rather than reusing the idle one.
vishal.b62985ca92015-04-17 08:45:512397 BoundTestNetLog log;
[email protected]6ecf2b92011-12-15 01:14:522398 TestCompletionCallback callback3;
Paul Jensen8d6f87ec2018-01-13 00:46:542399 rv = handle.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152400 ClientSocketPool::RespectLimits::ENABLED,
2401 callback3.callback(), pool_.get(), log.bound());
robpercival214763f2016-07-01 23:27:012402 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
2403 ASSERT_THAT(callback3.WaitForResult(), IsOk());
[email protected]64770b7d2011-11-16 04:30:412404 EXPECT_FALSE(handle.is_reused());
2405
[email protected]e7b1c6d2c2012-05-05 00:54:032406 // Make sure the idle socket is closed.
[email protected]64770b7d2011-11-16 04:30:412407 ASSERT_TRUE(pool_->HasGroup("a"));
2408 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2409 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2410
mmenke43758e62015-05-04 21:09:462411 TestNetLogEntry::List entries;
[email protected]64770b7d2011-11-16 04:30:412412 log.GetEntries(&entries);
2413 EXPECT_FALSE(LogContainsEntryWithType(
mikecirone8b85c432016-09-08 19:11:002414 entries, 1, NetLogEventType::SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]64770b7d2011-11-16 04:30:412415}
2416
[email protected]2041cf342010-02-19 03:15:592417// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:162418// because of multiple releasing disconnected sockets.
2419TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
2420 CreatePoolWithIdleTimeouts(
2421 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2422 base::TimeDelta(), // Time out unused sockets immediately.
2423 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2424
2425 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2426
2427 // Startup 4 connect jobs. Two of them will be pending.
2428
[email protected]2431756e2010-09-29 20:26:132429 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522430 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:542431 int rv = handle.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152432 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202433 callback.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012434 EXPECT_THAT(rv, IsOk());
[email protected]4f2abec2010-02-03 18:10:162435
[email protected]2431756e2010-09-29 20:26:132436 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522437 TestCompletionCallback callback2;
Paul Jensen8d6f87ec2018-01-13 00:46:542438 rv = handle2.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152439 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202440 callback2.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012441 EXPECT_THAT(rv, IsOk());
[email protected]4f2abec2010-02-03 18:10:162442
[email protected]2431756e2010-09-29 20:26:132443 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:522444 TestCompletionCallback callback3;
Paul Jensen8d6f87ec2018-01-13 00:46:542445 rv = handle3.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152446 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202447 callback3.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012448 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4f2abec2010-02-03 18:10:162449
[email protected]2431756e2010-09-29 20:26:132450 ClientSocketHandle handle4;
[email protected]6ecf2b92011-12-15 01:14:522451 TestCompletionCallback callback4;
Paul Jensen8d6f87ec2018-01-13 00:46:542452 rv = handle4.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152453 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202454 callback4.callback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012455 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4f2abec2010-02-03 18:10:162456
2457 // Release two disconnected sockets.
2458
[email protected]2431756e2010-09-29 20:26:132459 handle.socket()->Disconnect();
2460 handle.Reset();
2461 handle2.socket()->Disconnect();
2462 handle2.Reset();
[email protected]4f2abec2010-02-03 18:10:162463
robpercival214763f2016-07-01 23:27:012464 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132465 EXPECT_FALSE(handle3.is_reused());
robpercival214763f2016-07-01 23:27:012466 EXPECT_THAT(callback4.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132467 EXPECT_FALSE(handle4.is_reused());
[email protected]4f2abec2010-02-03 18:10:162468}
2469
[email protected]d7027bb2010-05-10 18:58:542470// Regression test for http://crbug.com/42267.
2471// When DoReleaseSocket() is processed for one socket, it is blocked because the
2472// other stalled groups all have releasing sockets, so no progress can be made.
2473TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
2474 CreatePoolWithIdleTimeouts(
2475 4 /* socket limit */, 4 /* socket limit per group */,
2476 base::TimeDelta(), // Time out unused sockets immediately.
2477 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2478
2479 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2480
2481 // Max out the socket limit with 2 per group.
2482
[email protected]2431756e2010-09-29 20:26:132483 ClientSocketHandle handle_a[4];
[email protected]6ecf2b92011-12-15 01:14:522484 TestCompletionCallback callback_a[4];
[email protected]2431756e2010-09-29 20:26:132485 ClientSocketHandle handle_b[4];
[email protected]6ecf2b92011-12-15 01:14:522486 TestCompletionCallback callback_b[4];
[email protected]d7027bb2010-05-10 18:58:542487
2488 for (int i = 0; i < 2; ++i) {
Paul Jensen8d6f87ec2018-01-13 00:46:542489 EXPECT_EQ(OK, handle_a[i].Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152490 ClientSocketPool::RespectLimits::ENABLED,
2491 callback_a[i].callback(), pool_.get(),
tfarina428341112016-09-22 13:38:202492 NetLogWithSource()));
Paul Jensen8d6f87ec2018-01-13 00:46:542493 EXPECT_EQ(OK, handle_b[i].Init("b", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152494 ClientSocketPool::RespectLimits::ENABLED,
2495 callback_b[i].callback(), pool_.get(),
tfarina428341112016-09-22 13:38:202496 NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:542497 }
[email protected]b89f7e42010-05-20 20:37:002498
[email protected]d7027bb2010-05-10 18:58:542499 // Make 4 pending requests, 2 per group.
2500
2501 for (int i = 2; i < 4; ++i) {
tfarina428341112016-09-22 13:38:202502 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542503 handle_a[i].Init("a", params_, LOWEST, SocketTag(),
tfarina428341112016-09-22 13:38:202504 ClientSocketPool::RespectLimits::ENABLED,
2505 callback_a[i].callback(), pool_.get(),
2506 NetLogWithSource()));
2507 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542508 handle_b[i].Init("b", params_, LOWEST, SocketTag(),
tfarina428341112016-09-22 13:38:202509 ClientSocketPool::RespectLimits::ENABLED,
2510 callback_b[i].callback(), pool_.get(),
2511 NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:542512 }
2513
2514 // Release b's socket first. The order is important, because in
2515 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2516 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2517 // first, which has a releasing socket, so it refuses to start up another
2518 // ConnectJob. So, we used to infinite loop on this.
[email protected]2431756e2010-09-29 20:26:132519 handle_b[0].socket()->Disconnect();
2520 handle_b[0].Reset();
2521 handle_a[0].socket()->Disconnect();
2522 handle_a[0].Reset();
[email protected]d7027bb2010-05-10 18:58:542523
2524 // Used to get stuck here.
fdoray5eeb7642016-06-22 16:11:282525 base::RunLoop().RunUntilIdle();
[email protected]d7027bb2010-05-10 18:58:542526
[email protected]2431756e2010-09-29 20:26:132527 handle_b[1].socket()->Disconnect();
2528 handle_b[1].Reset();
2529 handle_a[1].socket()->Disconnect();
2530 handle_a[1].Reset();
[email protected]d7027bb2010-05-10 18:58:542531
2532 for (int i = 2; i < 4; ++i) {
robpercival214763f2016-07-01 23:27:012533 EXPECT_THAT(callback_b[i].WaitForResult(), IsOk());
2534 EXPECT_THAT(callback_a[i].WaitForResult(), IsOk());
[email protected]d7027bb2010-05-10 18:58:542535 }
2536}
2537
[email protected]fd4fe0b2010-02-08 23:02:152538TEST_F(ClientSocketPoolBaseTest,
2539 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2540 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2541
2542 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2543
robpercival214763f2016-07-01 23:27:012544 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
2545 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
2546 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
2547 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]fd4fe0b2010-02-08 23:02:152548
robpercival214763f2016-07-01 23:27:012549 EXPECT_THAT((*requests())[0]->WaitForResult(), IsOk());
2550 EXPECT_THAT((*requests())[1]->WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132551 EXPECT_EQ(2u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152552
2553 // Releases one connection.
[email protected]2431756e2010-09-29 20:26:132554 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
robpercival214763f2016-07-01 23:27:012555 EXPECT_THAT((*requests())[2]->WaitForResult(), IsOk());
[email protected]fd4fe0b2010-02-08 23:02:152556
[email protected]2431756e2010-09-29 20:26:132557 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
robpercival214763f2016-07-01 23:27:012558 EXPECT_THAT((*requests())[3]->WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132559 EXPECT_EQ(4u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152560
2561 EXPECT_EQ(1, GetOrderOfRequest(1));
2562 EXPECT_EQ(2, GetOrderOfRequest(2));
2563 EXPECT_EQ(3, GetOrderOfRequest(3));
2564 EXPECT_EQ(4, GetOrderOfRequest(4));
2565
2566 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:132567 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
[email protected]fd4fe0b2010-02-08 23:02:152568}
2569
[email protected]6ecf2b92011-12-15 01:14:522570class TestReleasingSocketRequest : public TestCompletionCallbackBase {
[email protected]4f1e4982010-03-02 18:31:042571 public:
[email protected]2431756e2010-09-29 20:26:132572 TestReleasingSocketRequest(TestClientSocketPool* pool,
2573 int expected_result,
[email protected]e60e47a2010-07-14 03:37:182574 bool reset_releasing_handle)
2575 : pool_(pool),
2576 expected_result_(expected_result),
[email protected]6ecf2b92011-12-15 01:14:522577 reset_releasing_handle_(reset_releasing_handle),
[email protected]aa249b52013-04-30 01:04:322578 callback_(base::Bind(&TestReleasingSocketRequest::OnComplete,
2579 base::Unretained(this))) {
[email protected]6ecf2b92011-12-15 01:14:522580 }
2581
Chris Watkins7a41d3552017-12-01 02:13:272582 ~TestReleasingSocketRequest() override = default;
[email protected]4f1e4982010-03-02 18:31:042583
2584 ClientSocketHandle* handle() { return &handle_; }
2585
[email protected]6ecf2b92011-12-15 01:14:522586 const CompletionCallback& callback() const { return callback_; }
[email protected]4f1e4982010-03-02 18:31:042587
2588 private:
[email protected]6ecf2b92011-12-15 01:14:522589 void OnComplete(int result) {
2590 SetResult(result);
2591 if (reset_releasing_handle_)
2592 handle_.Reset();
2593
mmenked3641e12016-01-28 16:06:152594 scoped_refptr<TestSocketParams> con_params(new TestSocketParams());
[email protected]6ecf2b92011-12-15 01:14:522595 EXPECT_EQ(expected_result_,
Paul Jensen8d6f87ec2018-01-13 00:46:542596 handle2_.Init("a", con_params, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152597 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202598 callback2_.callback(), pool_, NetLogWithSource()));
[email protected]6ecf2b92011-12-15 01:14:522599 }
2600
[email protected]2431756e2010-09-29 20:26:132601 TestClientSocketPool* const pool_;
[email protected]e60e47a2010-07-14 03:37:182602 int expected_result_;
2603 bool reset_releasing_handle_;
[email protected]4f1e4982010-03-02 18:31:042604 ClientSocketHandle handle_;
2605 ClientSocketHandle handle2_;
[email protected]6ecf2b92011-12-15 01:14:522606 CompletionCallback callback_;
2607 TestCompletionCallback callback2_;
[email protected]4f1e4982010-03-02 18:31:042608};
2609
[email protected]e60e47a2010-07-14 03:37:182610
2611TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2612 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2613
robpercival214763f2016-07-01 23:27:012614 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
2615 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
2616 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
[email protected]e60e47a2010-07-14 03:37:182617
[email protected]2431756e2010-09-29 20:26:132618 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]e60e47a2010-07-14 03:37:182619 client_socket_factory_.allocation_count());
2620
2621 connect_job_factory_->set_job_type(
2622 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2623 TestReleasingSocketRequest req(pool_.get(), OK, false);
tfarina428341112016-09-22 13:38:202624 EXPECT_EQ(
2625 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542626 req.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:202627 ClientSocketPool::RespectLimits::ENABLED,
2628 req.callback(), pool_.get(), NetLogWithSource()));
[email protected]e60e47a2010-07-14 03:37:182629 // The next job should complete synchronously
2630 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2631
robpercival214763f2016-07-01 23:27:012632 EXPECT_THAT(req.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:182633 EXPECT_FALSE(req.handle()->is_initialized());
2634 EXPECT_FALSE(req.handle()->socket());
2635 EXPECT_TRUE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:432636 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182637}
2638
[email protected]b6501d3d2010-06-03 23:53:342639// http://crbug.com/44724 regression test.
2640// We start releasing the pool when we flush on network change. When that
2641// happens, the only active references are in the ClientSocketHandles. When a
2642// ConnectJob completes and calls back into the last ClientSocketHandle, that
2643// callback can release the last reference and delete the pool. After the
2644// callback finishes, we go back to the stack frame within the now-deleted pool.
2645// Executing any code that refers to members of the now-deleted pool can cause
2646// crashes.
2647TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2648 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2649 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2650
2651 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522652 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:152653 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542654 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152655 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202656 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]b6501d3d2010-06-03 23:53:342657
[email protected]7af985a2012-12-14 22:40:422658 pool_->FlushWithError(ERR_NETWORK_CHANGED);
[email protected]b6501d3d2010-06-03 23:53:342659
2660 // We'll call back into this now.
2661 callback.WaitForResult();
2662}
2663
[email protected]a7e38572010-06-07 18:22:242664TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2665 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2666 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2667
2668 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522669 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:152670 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542671 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152672 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202673 callback.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:012674 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]a7e38572010-06-07 18:22:242675 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2676
[email protected]7af985a2012-12-14 22:40:422677 pool_->FlushWithError(ERR_NETWORK_CHANGED);
[email protected]a7e38572010-06-07 18:22:242678
2679 handle.Reset();
fdoray5eeb7642016-06-22 16:11:282680 base::RunLoop().RunUntilIdle();
[email protected]a7e38572010-06-07 18:22:242681
mmenked3641e12016-01-28 16:06:152682 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542683 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152684 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202685 callback.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:012686 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]a7e38572010-06-07 18:22:242687 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2688}
2689
[email protected]6ecf2b92011-12-15 01:14:522690class ConnectWithinCallback : public TestCompletionCallbackBase {
[email protected]06f92462010-08-31 19:24:142691 public:
2692 ConnectWithinCallback(
2693 const std::string& group_name,
2694 const scoped_refptr<TestSocketParams>& params,
[email protected]2431756e2010-09-29 20:26:132695 TestClientSocketPool* pool)
[email protected]6ecf2b92011-12-15 01:14:522696 : group_name_(group_name),
2697 params_(params),
2698 pool_(pool),
[email protected]aa249b52013-04-30 01:04:322699 callback_(base::Bind(&ConnectWithinCallback::OnComplete,
2700 base::Unretained(this))) {
[email protected]06f92462010-08-31 19:24:142701 }
2702
Chris Watkins7a41d3552017-12-01 02:13:272703 ~ConnectWithinCallback() override = default;
[email protected]06f92462010-08-31 19:24:142704
2705 int WaitForNestedResult() {
2706 return nested_callback_.WaitForResult();
2707 }
2708
[email protected]6ecf2b92011-12-15 01:14:522709 const CompletionCallback& callback() const { return callback_; }
2710
[email protected]06f92462010-08-31 19:24:142711 private:
[email protected]6ecf2b92011-12-15 01:14:522712 void OnComplete(int result) {
2713 SetResult(result);
tfarina428341112016-09-22 13:38:202714 EXPECT_EQ(
2715 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542716 handle_.Init(group_name_, params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:202717 ClientSocketPool::RespectLimits::ENABLED,
2718 nested_callback_.callback(), pool_, NetLogWithSource()));
[email protected]6ecf2b92011-12-15 01:14:522719 }
2720
[email protected]06f92462010-08-31 19:24:142721 const std::string group_name_;
2722 const scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:132723 TestClientSocketPool* const pool_;
[email protected]06f92462010-08-31 19:24:142724 ClientSocketHandle handle_;
[email protected]6ecf2b92011-12-15 01:14:522725 CompletionCallback callback_;
2726 TestCompletionCallback nested_callback_;
2727
2728 DISALLOW_COPY_AND_ASSIGN(ConnectWithinCallback);
[email protected]06f92462010-08-31 19:24:142729};
2730
2731TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
2732 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2733
2734 // First job will be waiting until it gets aborted.
2735 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2736
2737 ClientSocketHandle handle;
[email protected]2431756e2010-09-29 20:26:132738 ConnectWithinCallback callback("a", params_, pool_.get());
mmenked3641e12016-01-28 16:06:152739 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542740 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152741 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202742 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]06f92462010-08-31 19:24:142743
2744 // Second job will be started during the first callback, and will
2745 // asynchronously complete with OK.
2746 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]7af985a2012-12-14 22:40:422747 pool_->FlushWithError(ERR_NETWORK_CHANGED);
robpercival214763f2016-07-01 23:27:012748 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NETWORK_CHANGED));
2749 EXPECT_THAT(callback.WaitForNestedResult(), IsOk());
[email protected]06f92462010-08-31 19:24:142750}
2751
[email protected]25eea382010-07-10 23:55:262752// Cancel a pending socket request while we're at max sockets,
2753// and verify that the backup socket firing doesn't cause a crash.
2754TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
2755 // Max 4 sockets globally, max 4 sockets per group.
2756 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
[email protected]06d94042010-08-25 01:45:222757 pool_->EnableConnectBackupJobs();
[email protected]25eea382010-07-10 23:55:262758
[email protected]4baaf9d2010-08-31 15:15:442759 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2760 // timer.
[email protected]25eea382010-07-10 23:55:262761 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2762 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522763 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:152764 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542765 handle.Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152766 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202767 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]25eea382010-07-10 23:55:262768
2769 // Start (MaxSockets - 1) connected sockets to reach max sockets.
2770 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2771 ClientSocketHandle handles[kDefaultMaxSockets];
2772 for (int i = 1; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:522773 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:542774 EXPECT_EQ(OK, handles[i].Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:202775 ClientSocketPool::RespectLimits::ENABLED,
2776 callback.callback(), pool_.get(),
2777 NetLogWithSource()));
[email protected]25eea382010-07-10 23:55:262778 }
2779
fdoray5eeb7642016-06-22 16:11:282780 base::RunLoop().RunUntilIdle();
[email protected]25eea382010-07-10 23:55:262781
2782 // Cancel the pending request.
2783 handle.Reset();
2784
2785 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]26b9973962012-01-28 00:57:002786 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2787 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]25eea382010-07-10 23:55:262788
fdoray5eeb7642016-06-22 16:11:282789 base::RunLoop().RunUntilIdle();
[email protected]25eea382010-07-10 23:55:262790 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
2791}
2792
[email protected]3f00be82010-09-27 19:50:022793TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
[email protected]4baaf9d2010-08-31 15:15:442794 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2795 pool_->EnableConnectBackupJobs();
2796
2797 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2798 // timer.
2799 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2800 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522801 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:152802 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542803 handle.Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152804 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202805 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]4baaf9d2010-08-31 15:15:442806 ASSERT_TRUE(pool_->HasGroup("bar"));
2807 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
[email protected]8159a1c2012-06-07 00:00:102808 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("bar"));
[email protected]4baaf9d2010-08-31 15:15:442809
2810 // Cancel the socket request. This should cancel the backup timer. Wait for
2811 // the backup time to see if it indeed got canceled.
2812 handle.Reset();
2813 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]26b9973962012-01-28 00:57:002814 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2815 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
fdoray5eeb7642016-06-22 16:11:282816 base::RunLoop().RunUntilIdle();
[email protected]4baaf9d2010-08-31 15:15:442817 ASSERT_TRUE(pool_->HasGroup("bar"));
2818 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2819}
2820
[email protected]3f00be82010-09-27 19:50:022821TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
2822 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2823 pool_->EnableConnectBackupJobs();
2824
2825 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2826 // timer.
2827 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2828 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522829 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:152830 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542831 handle.Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152832 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202833 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]3f00be82010-09-27 19:50:022834 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2835 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522836 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:202837 EXPECT_EQ(
2838 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542839 handle2.Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:202840 ClientSocketPool::RespectLimits::ENABLED,
2841 callback2.callback(), pool_.get(), NetLogWithSource()));
[email protected]3f00be82010-09-27 19:50:022842 ASSERT_TRUE(pool_->HasGroup("bar"));
2843 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("bar"));
2844
2845 // Cancel request 1 and then complete request 2. With the requests finished,
2846 // the backup timer should be cancelled.
2847 handle.Reset();
robpercival214763f2016-07-01 23:27:012848 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]3f00be82010-09-27 19:50:022849 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]26b9973962012-01-28 00:57:002850 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2851 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
fdoray5eeb7642016-06-22 16:11:282852 base::RunLoop().RunUntilIdle();
[email protected]3f00be82010-09-27 19:50:022853}
2854
[email protected]eb5a99382010-07-11 03:18:262855// Test delayed socket binding for the case where we have two connects,
2856// and while one is waiting on a connect, the other frees up.
2857// The socket waiting on a connect should switch immediately to the freed
2858// up socket.
2859TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
2860 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2861 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2862
2863 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522864 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132865 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542866 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152867 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202868 callback.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:012869 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:262870
2871 // No idle sockets, no pending jobs.
2872 EXPECT_EQ(0, pool_->IdleSocketCount());
2873 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2874
2875 // Create a second socket to the same host, but this one will wait.
2876 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2877 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132878 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542879 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152880 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202881 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:262882 // No idle sockets, and one connecting job.
2883 EXPECT_EQ(0, pool_->IdleSocketCount());
2884 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2885
2886 // Return the first handle to the pool. This will initiate the delayed
2887 // binding.
2888 handle1.Reset();
2889
fdoray5eeb7642016-06-22 16:11:282890 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262891
2892 // Still no idle sockets, still one pending connect job.
2893 EXPECT_EQ(0, pool_->IdleSocketCount());
2894 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2895
2896 // The second socket connected, even though it was a Waiting Job.
robpercival214763f2016-07-01 23:27:012897 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:262898
2899 // And we can see there is still one job waiting.
2900 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2901
2902 // Finally, signal the waiting Connect.
2903 client_socket_factory_.SignalJobs();
2904 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2905
fdoray5eeb7642016-06-22 16:11:282906 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262907}
2908
2909// Test delayed socket binding when a group is at capacity and one
2910// of the group's sockets frees up.
2911TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
2912 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2913 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2914
2915 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522916 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132917 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542918 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152919 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202920 callback.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:012921 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:262922
2923 // No idle sockets, no pending jobs.
2924 EXPECT_EQ(0, pool_->IdleSocketCount());
2925 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2926
2927 // Create a second socket to the same host, but this one will wait.
2928 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2929 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132930 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542931 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152932 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202933 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:262934 // No idle sockets, and one connecting job.
2935 EXPECT_EQ(0, pool_->IdleSocketCount());
2936 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2937
2938 // Return the first handle to the pool. This will initiate the delayed
2939 // binding.
2940 handle1.Reset();
2941
fdoray5eeb7642016-06-22 16:11:282942 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262943
2944 // Still no idle sockets, still one pending connect job.
2945 EXPECT_EQ(0, pool_->IdleSocketCount());
2946 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2947
2948 // The second socket connected, even though it was a Waiting Job.
robpercival214763f2016-07-01 23:27:012949 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:262950
2951 // And we can see there is still one job waiting.
2952 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2953
2954 // Finally, signal the waiting Connect.
2955 client_socket_factory_.SignalJobs();
2956 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2957
fdoray5eeb7642016-06-22 16:11:282958 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262959}
2960
2961// Test out the case where we have one socket connected, one
2962// connecting, when the first socket finishes and goes idle.
[email protected]2abfe90a2010-08-25 17:49:512963// Although the second connection is pending, the second request
[email protected]eb5a99382010-07-11 03:18:262964// should complete, by taking the first socket's idle socket.
2965TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
2966 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2967 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2968
2969 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522970 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132971 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542972 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152973 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202974 callback.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:012975 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:262976
2977 // No idle sockets, no pending jobs.
2978 EXPECT_EQ(0, pool_->IdleSocketCount());
2979 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2980
2981 // Create a second socket to the same host, but this one will wait.
2982 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2983 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132984 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542985 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152986 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:202987 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:262988 // No idle sockets, and one connecting job.
2989 EXPECT_EQ(0, pool_->IdleSocketCount());
2990 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2991
2992 // Return the first handle to the pool. This will initiate the delayed
2993 // binding.
2994 handle1.Reset();
2995
fdoray5eeb7642016-06-22 16:11:282996 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262997
2998 // Still no idle sockets, still one pending connect job.
2999 EXPECT_EQ(0, pool_->IdleSocketCount());
3000 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3001
3002 // The second socket connected, even though it was a Waiting Job.
robpercival214763f2016-07-01 23:27:013003 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263004
3005 // And we can see there is still one job waiting.
3006 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3007
3008 // Finally, signal the waiting Connect.
3009 client_socket_factory_.SignalJobs();
3010 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3011
fdoray5eeb7642016-06-22 16:11:283012 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263013}
3014
[email protected]2abfe90a2010-08-25 17:49:513015// Cover the case where on an available socket slot, we have one pending
3016// request that completes synchronously, thereby making the Group empty.
3017TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
3018 const int kUnlimitedSockets = 100;
3019 const int kOneSocketPerGroup = 1;
3020 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
3021
3022 // Make the first request asynchronous fail.
3023 // This will free up a socket slot later.
3024 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
3025
3026 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523027 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203028 EXPECT_EQ(
3029 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543030 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203031 ClientSocketPool::RespectLimits::ENABLED,
3032 callback1.callback(), pool_.get(), NetLogWithSource()));
[email protected]2abfe90a2010-08-25 17:49:513033 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3034
3035 // Make the second request synchronously fail. This should make the Group
3036 // empty.
3037 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3038 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523039 TestCompletionCallback callback2;
[email protected]2abfe90a2010-08-25 17:49:513040 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
3041 // when created.
tfarina428341112016-09-22 13:38:203042 EXPECT_EQ(
3043 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543044 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203045 ClientSocketPool::RespectLimits::ENABLED,
3046 callback2.callback(), pool_.get(), NetLogWithSource()));
[email protected]2abfe90a2010-08-25 17:49:513047
3048 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3049
robpercival214763f2016-07-01 23:27:013050 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
3051 EXPECT_THAT(callback2.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]2abfe90a2010-08-25 17:49:513052 EXPECT_FALSE(pool_->HasGroup("a"));
3053}
3054
[email protected]e1b54dc2010-10-06 21:27:223055TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
3056 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3057
3058 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3059
3060 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523061 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203062 EXPECT_EQ(
3063 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543064 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203065 ClientSocketPool::RespectLimits::ENABLED,
3066 callback1.callback(), pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223067
3068 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523069 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203070 EXPECT_EQ(
3071 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543072 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203073 ClientSocketPool::RespectLimits::ENABLED,
3074 callback2.callback(), pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223075 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:523076 TestCompletionCallback callback3;
tfarina428341112016-09-22 13:38:203077 EXPECT_EQ(
3078 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543079 handle3.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203080 ClientSocketPool::RespectLimits::ENABLED,
3081 callback3.callback(), pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223082
robpercival214763f2016-07-01 23:27:013083 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3084 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3085 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]e1b54dc2010-10-06 21:27:223086
3087 // Use the socket.
Ramin Halavati0a08cc82018-02-06 07:46:383088 EXPECT_EQ(1, handle1.socket()->Write(NULL, 1, CompletionCallback(),
3089 TRAFFIC_ANNOTATION_FOR_TESTS));
3090 EXPECT_EQ(1, handle3.socket()->Write(NULL, 1, CompletionCallback(),
3091 TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]e1b54dc2010-10-06 21:27:223092
3093 handle1.Reset();
3094 handle2.Reset();
3095 handle3.Reset();
3096
tfarina428341112016-09-22 13:38:203097 EXPECT_EQ(
Paul Jensen8d6f87ec2018-01-13 00:46:543098 OK, handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203099 ClientSocketPool::RespectLimits::ENABLED,
3100 callback1.callback(), pool_.get(), NetLogWithSource()));
3101 EXPECT_EQ(
Paul Jensen8d6f87ec2018-01-13 00:46:543102 OK, handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203103 ClientSocketPool::RespectLimits::ENABLED,
3104 callback2.callback(), pool_.get(), NetLogWithSource()));
3105 EXPECT_EQ(
Paul Jensen8d6f87ec2018-01-13 00:46:543106 OK, handle3.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203107 ClientSocketPool::RespectLimits::ENABLED,
3108 callback3.callback(), pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223109
3110 EXPECT_TRUE(handle1.socket()->WasEverUsed());
3111 EXPECT_TRUE(handle2.socket()->WasEverUsed());
3112 EXPECT_FALSE(handle3.socket()->WasEverUsed());
3113}
3114
[email protected]2c2bef152010-10-13 00:55:033115TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
3116 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3117 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3118
Alexandr Ilin65ec9582017-10-02 14:50:313119 pool_->RequestSockets("a", &params_, 2, NetLogWithSource(),
3120 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033121
3122 ASSERT_TRUE(pool_->HasGroup("a"));
3123 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103124 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033125 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3126
3127 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523128 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203129 EXPECT_EQ(
3130 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543131 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203132 ClientSocketPool::RespectLimits::ENABLED,
3133 callback1.callback(), pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033134
3135 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523136 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203137 EXPECT_EQ(
3138 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543139 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203140 ClientSocketPool::RespectLimits::ENABLED,
3141 callback2.callback(), pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033142
3143 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103144 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033145 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3146
robpercival214763f2016-07-01 23:27:013147 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3148 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033149 handle1.Reset();
3150 handle2.Reset();
3151
3152 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103153 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033154 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3155}
3156
3157TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
3158 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3159 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3160
3161 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523162 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203163 EXPECT_EQ(
3164 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543165 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203166 ClientSocketPool::RespectLimits::ENABLED,
3167 callback1.callback(), pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033168
3169 ASSERT_TRUE(pool_->HasGroup("a"));
3170 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103171 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033172 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3173
Alexandr Ilin65ec9582017-10-02 14:50:313174 pool_->RequestSockets("a", &params_, 2, NetLogWithSource(),
3175 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033176
3177 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103178 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033179 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3180
3181 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523182 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203183 EXPECT_EQ(
3184 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543185 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203186 ClientSocketPool::RespectLimits::ENABLED,
3187 callback2.callback(), pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033188
3189 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103190 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033191 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3192
robpercival214763f2016-07-01 23:27:013193 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3194 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033195 handle1.Reset();
3196 handle2.Reset();
3197
3198 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103199 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033200 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3201}
3202
3203TEST_F(ClientSocketPoolBaseTest,
3204 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
3205 CreatePool(4, 4);
3206 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3207
3208 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523209 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203210 EXPECT_EQ(
3211 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543212 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203213 ClientSocketPool::RespectLimits::ENABLED,
3214 callback1.callback(), pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033215
3216 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523217 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203218 EXPECT_EQ(
3219 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543220 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203221 ClientSocketPool::RespectLimits::ENABLED,
3222 callback2.callback(), pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033223
3224 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:523225 TestCompletionCallback callback3;
tfarina428341112016-09-22 13:38:203226 EXPECT_EQ(
3227 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543228 handle3.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203229 ClientSocketPool::RespectLimits::ENABLED,
3230 callback3.callback(), pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033231
3232 ASSERT_TRUE(pool_->HasGroup("a"));
3233 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103234 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033235 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3236
Alexandr Ilin65ec9582017-10-02 14:50:313237 pool_->RequestSockets("a", &params_, 2, NetLogWithSource(),
3238 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033239
3240 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103241 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033242 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3243
robpercival214763f2016-07-01 23:27:013244 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3245 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3246 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033247 handle1.Reset();
3248 handle2.Reset();
3249 handle3.Reset();
3250
3251 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103252 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033253 EXPECT_EQ(3, pool_->IdleSocketCountInGroup("a"));
3254}
3255
3256TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
3257 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3258 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3259
3260 ASSERT_FALSE(pool_->HasGroup("a"));
3261
Alexandr Ilin65ec9582017-10-02 14:50:313262 pool_->RequestSockets("a", &params_, kDefaultMaxSockets, NetLogWithSource(),
3263 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033264
3265 ASSERT_TRUE(pool_->HasGroup("a"));
3266 EXPECT_EQ(kDefaultMaxSockets, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103267 EXPECT_EQ(kDefaultMaxSockets, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033268
3269 ASSERT_FALSE(pool_->HasGroup("b"));
3270
Alexandr Ilin65ec9582017-10-02 14:50:313271 pool_->RequestSockets("b", &params_, kDefaultMaxSockets, NetLogWithSource(),
3272 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033273
3274 ASSERT_FALSE(pool_->HasGroup("b"));
3275}
3276
3277TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
3278 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3279 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3280
3281 ASSERT_FALSE(pool_->HasGroup("a"));
3282
3283 pool_->RequestSockets("a", &params_, kDefaultMaxSockets - 1,
Alexandr Ilin65ec9582017-10-02 14:50:313284 NetLogWithSource(), HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033285
3286 ASSERT_TRUE(pool_->HasGroup("a"));
3287 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103288 EXPECT_EQ(kDefaultMaxSockets - 1,
3289 pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]51fdc7c2012-04-10 19:19:483290 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033291
3292 ASSERT_FALSE(pool_->HasGroup("b"));
3293
Alexandr Ilin65ec9582017-10-02 14:50:313294 pool_->RequestSockets("b", &params_, kDefaultMaxSockets, NetLogWithSource(),
3295 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033296
3297 ASSERT_TRUE(pool_->HasGroup("b"));
3298 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("b"));
[email protected]51fdc7c2012-04-10 19:19:483299 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033300}
3301
3302TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
3303 CreatePool(4, 4);
3304 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3305
3306 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523307 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203308 EXPECT_EQ(
3309 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543310 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203311 ClientSocketPool::RespectLimits::ENABLED,
3312 callback1.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013313 ASSERT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033314 handle1.Reset();
3315
3316 ASSERT_TRUE(pool_->HasGroup("a"));
3317 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103318 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033319 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3320
Alexandr Ilin65ec9582017-10-02 14:50:313321 pool_->RequestSockets("a", &params_, 2, NetLogWithSource(),
3322 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033323
3324 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103325 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033326 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3327}
3328
3329TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
3330 CreatePool(4, 4);
3331 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3332
3333 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523334 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203335 EXPECT_EQ(
3336 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543337 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203338 ClientSocketPool::RespectLimits::ENABLED,
3339 callback1.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013340 ASSERT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033341
3342 ASSERT_TRUE(pool_->HasGroup("a"));
3343 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103344 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033345 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3346 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3347
Alexandr Ilin65ec9582017-10-02 14:50:313348 pool_->RequestSockets("a", &params_, 2, NetLogWithSource(),
3349 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033350
3351 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103352 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033353 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3354 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3355}
3356
3357TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
3358 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3359 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3360
3361 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
Alexandr Ilin65ec9582017-10-02 14:50:313362 NetLogWithSource(), HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033363
3364 ASSERT_TRUE(pool_->HasGroup("a"));
3365 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103366 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033367 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("a"));
3368
3369 pool_->RequestSockets("b", &params_, kDefaultMaxSocketsPerGroup,
Alexandr Ilin65ec9582017-10-02 14:50:313370 NetLogWithSource(), HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033371
3372 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103373 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]2c2bef152010-10-13 00:55:033374 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("b"));
3375}
3376
[email protected]3c819f522010-12-02 02:03:123377TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
3378 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3379 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3380
3381 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
Alexandr Ilin65ec9582017-10-02 14:50:313382 NetLogWithSource(), HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]3c819f522010-12-02 02:03:123383
3384 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]fd2e53e2011-01-14 20:40:523385
3386 connect_job_factory_->set_job_type(
3387 TestConnectJob::kMockAdditionalErrorStateJob);
3388 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
Alexandr Ilin65ec9582017-10-02 14:50:313389 NetLogWithSource(), HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]fd2e53e2011-01-14 20:40:523390
3391 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]3c819f522010-12-02 02:03:123392}
3393
[email protected]8159a1c2012-06-07 00:00:103394TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
[email protected]2c2bef152010-10-13 00:55:033395 CreatePool(4, 4);
3396 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3397
Alexandr Ilin65ec9582017-10-02 14:50:313398 pool_->RequestSockets("a", &params_, 2, NetLogWithSource(),
3399 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033400
3401 ASSERT_TRUE(pool_->HasGroup("a"));
3402 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
Alexandr Ilin65ec9582017-10-02 14:50:313406 pool_->RequestSockets("a", &params_, 2, NetLogWithSource(),
3407 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033408 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103409 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033410 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3411
3412 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523413 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203414 EXPECT_EQ(
3415 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543416 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203417 ClientSocketPool::RespectLimits::ENABLED,
3418 callback1.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013419 ASSERT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033420
3421 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523422 TestCompletionCallback callback2;
Paul Jensen8d6f87ec2018-01-13 00:46:543423 int rv = handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:153424 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:203425 callback2.callback(), pool_.get(), NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033426 if (rv != OK) {
robpercival214763f2016-07-01 23:27:013427 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3428 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033429 }
3430
[email protected]8159a1c2012-06-07 00:00:103431 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3432 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3433 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("a"));
3434 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3435
[email protected]2c2bef152010-10-13 00:55:033436 handle1.Reset();
3437 handle2.Reset();
3438
[email protected]8159a1c2012-06-07 00:00:103439 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3440 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033441 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3442
Alexandr Ilin65ec9582017-10-02 14:50:313443 pool_->RequestSockets("a", &params_, 2, NetLogWithSource(),
3444 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033445 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103446 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033447 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3448}
3449
3450TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
3451 CreatePool(4, 4);
3452 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3453
Alexandr Ilin65ec9582017-10-02 14:50:313454 pool_->RequestSockets("a", &params_, 1, NetLogWithSource(),
3455 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033456
3457 ASSERT_TRUE(pool_->HasGroup("a"));
3458 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103459 EXPECT_EQ(1, 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_, 2, NetLogWithSource(),
3463 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033464 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103465 EXPECT_EQ(2, 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_, 3, 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
Alexandr Ilin65ec9582017-10-02 14:50:313474 pool_->RequestSockets("a", &params_, 1, NetLogWithSource(),
3475 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033476 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103477 EXPECT_EQ(3, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033478 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3479}
3480
3481TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
3482 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3483 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3484
Alexandr Ilin65ec9582017-10-02 14:50:313485 pool_->RequestSockets("a", &params_, 1, NetLogWithSource(),
3486 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]2c2bef152010-10-13 00:55:033487
3488 ASSERT_TRUE(pool_->HasGroup("a"));
3489 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103490 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033491 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3492
3493 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523494 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203495 EXPECT_EQ(
3496 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543497 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203498 ClientSocketPool::RespectLimits::ENABLED,
3499 callback1.callback(), pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033500
3501 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103502 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033503 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3504
robpercival214763f2016-07-01 23:27:013505 ASSERT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033506
[email protected]0dc88b32014-03-26 20:12:283507 // Make sure if a preconnected socket is not fully connected when a request
[email protected]034df0f32013-01-07 23:17:483508 // starts, it has a connect start time.
3509 TestLoadTimingInfoConnectedNotReused(handle1);
[email protected]2c2bef152010-10-13 00:55:033510 handle1.Reset();
3511
3512 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3513}
3514
[email protected]034df0f32013-01-07 23:17:483515// Checks that fully connected preconnect jobs have no connect times, and are
3516// marked as reused.
3517TEST_F(ClientSocketPoolBaseTest, ConnectedPreconnectJobsHaveNoConnectTimes) {
3518 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3519 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
Alexandr Ilin65ec9582017-10-02 14:50:313520 pool_->RequestSockets("a", &params_, 1, NetLogWithSource(),
3521 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]034df0f32013-01-07 23:17:483522
3523 ASSERT_TRUE(pool_->HasGroup("a"));
3524 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3525 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3526 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3527
3528 ClientSocketHandle handle;
3529 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:203530 EXPECT_EQ(OK,
Paul Jensen8d6f87ec2018-01-13 00:46:543531 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203532 ClientSocketPool::RespectLimits::ENABLED,
3533 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]034df0f32013-01-07 23:17:483534
3535 // Make sure the idle socket was used.
3536 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3537
3538 TestLoadTimingInfoConnectedReused(handle);
3539 handle.Reset();
3540 TestLoadTimingInfoNotConnected(handle);
3541}
3542
[email protected]dcbe168a2010-12-02 03:14:463543// http://crbug.com/64940 regression test.
3544TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
3545 const int kMaxTotalSockets = 3;
3546 const int kMaxSocketsPerGroup = 2;
3547 CreatePool(kMaxTotalSockets, kMaxSocketsPerGroup);
3548 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3549
3550 // Note that group name ordering matters here. "a" comes before "b", so
3551 // CloseOneIdleSocket() will try to close "a"'s idle socket.
3552
3553 // Set up one idle socket in "a".
3554 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523555 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203556 EXPECT_EQ(
3557 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543558 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203559 ClientSocketPool::RespectLimits::ENABLED,
3560 callback1.callback(), pool_.get(), NetLogWithSource()));
[email protected]dcbe168a2010-12-02 03:14:463561
robpercival214763f2016-07-01 23:27:013562 ASSERT_THAT(callback1.WaitForResult(), IsOk());
[email protected]dcbe168a2010-12-02 03:14:463563 handle1.Reset();
3564 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3565
3566 // Set up two active sockets in "b".
3567 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523568 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203569 EXPECT_EQ(
3570 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543571 handle1.Init("b", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203572 ClientSocketPool::RespectLimits::ENABLED,
3573 callback1.callback(), pool_.get(), NetLogWithSource()));
3574 EXPECT_EQ(
3575 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543576 handle2.Init("b", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203577 ClientSocketPool::RespectLimits::ENABLED,
3578 callback2.callback(), pool_.get(), NetLogWithSource()));
[email protected]dcbe168a2010-12-02 03:14:463579
robpercival214763f2016-07-01 23:27:013580 ASSERT_THAT(callback1.WaitForResult(), IsOk());
3581 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]dcbe168a2010-12-02 03:14:463582 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103583 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463584 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3585
3586 // Now we have 1 idle socket in "a" and 2 active sockets in "b". This means
3587 // we've maxed out on sockets, since we set |kMaxTotalSockets| to 3.
3588 // Requesting 2 preconnected sockets for "a" should fail to allocate any more
3589 // sockets for "a", and "b" should still have 2 active sockets.
3590
Alexandr Ilin65ec9582017-10-02 14:50:313591 pool_->RequestSockets("a", &params_, 2, NetLogWithSource(),
3592 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]dcbe168a2010-12-02 03:14:463593 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103594 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]dcbe168a2010-12-02 03:14:463595 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3596 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3597 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103598 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463599 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3600 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3601
3602 // Now release the 2 active sockets for "b". This will give us 1 idle socket
3603 // in "a" and 2 idle sockets in "b". Requesting 2 preconnected sockets for
3604 // "a" should result in closing 1 for "b".
3605 handle1.Reset();
3606 handle2.Reset();
3607 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("b"));
3608 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3609
Alexandr Ilin65ec9582017-10-02 14:50:313610 pool_->RequestSockets("a", &params_, 2, NetLogWithSource(),
3611 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]dcbe168a2010-12-02 03:14:463612 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103613 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]dcbe168a2010-12-02 03:14:463614 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3615 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3616 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103617 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463618 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("b"));
3619 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3620}
3621
[email protected]b7b8be42011-07-12 12:46:413622TEST_F(ClientSocketPoolBaseTest, PreconnectWithoutBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073623 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3624 pool_->EnableConnectBackupJobs();
3625
3626 // Make the ConnectJob hang until it times out, shorten the timeout.
3627 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3628 connect_job_factory_->set_timeout_duration(
3629 base::TimeDelta::FromMilliseconds(500));
Alexandr Ilin65ec9582017-10-02 14:50:313630 pool_->RequestSockets("a", &params_, 1, NetLogWithSource(),
3631 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]a9fc8fc2011-05-10 02:41:073632 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103633 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073634 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073635
[email protected]b7b8be42011-07-12 12:46:413636 // Verify the backup timer doesn't create a backup job, by making
3637 // the backup job a pending job instead of a waiting job, so it
3638 // *would* complete if it were created.
[email protected]a9fc8fc2011-05-10 02:41:073639 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
skyostil4891b25b2015-06-11 11:43:453640 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
ki.stfu375812e2015-10-09 20:23:173641 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
[email protected]2da659e2013-05-23 20:51:343642 base::TimeDelta::FromSeconds(1));
fdoray5eeb7642016-06-22 16:11:283643 base::RunLoop().Run();
[email protected]a9fc8fc2011-05-10 02:41:073644 EXPECT_FALSE(pool_->HasGroup("a"));
3645}
3646
[email protected]b7b8be42011-07-12 12:46:413647TEST_F(ClientSocketPoolBaseTest, PreconnectWithBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073648 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3649 pool_->EnableConnectBackupJobs();
3650
3651 // Make the ConnectJob hang forever.
3652 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
Alexandr Ilin65ec9582017-10-02 14:50:313653 pool_->RequestSockets("a", &params_, 1, NetLogWithSource(),
3654 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]a9fc8fc2011-05-10 02:41:073655 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103656 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073657 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
fdoray5eeb7642016-06-22 16:11:283658 base::RunLoop().RunUntilIdle();
[email protected]a9fc8fc2011-05-10 02:41:073659
3660 // Make the backup job be a pending job, so it completes normally.
3661 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3662 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:523663 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:153664 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543665 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:153666 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:203667 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]b7b8be42011-07-12 12:46:413668 // Timer has started, but the backup connect job shouldn't be created yet.
[email protected]a9fc8fc2011-05-10 02:41:073669 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103670 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073671 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3672 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
robpercival214763f2016-07-01 23:27:013673 ASSERT_THAT(callback.WaitForResult(), IsOk());
[email protected]a9fc8fc2011-05-10 02:41:073674
3675 // The hung connect job should still be there, but everything else should be
3676 // complete.
3677 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103678 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073679 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3680 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3681}
3682
[email protected]0dc88b32014-03-26 20:12:283683// Tests that a preconnect that starts out with unread data can still be used.
3684// http://crbug.com/334467
3685TEST_F(ClientSocketPoolBaseTest, PreconnectWithUnreadData) {
3686 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3687 connect_job_factory_->set_job_type(TestConnectJob::kMockUnreadDataJob);
3688
Alexandr Ilin65ec9582017-10-02 14:50:313689 pool_->RequestSockets("a", &params_, 1, NetLogWithSource(),
3690 HttpRequestInfo::NORMAL_MOTIVATION);
[email protected]0dc88b32014-03-26 20:12:283691
3692 ASSERT_TRUE(pool_->HasGroup("a"));
3693 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3694 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3695 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3696
3697 // Fail future jobs to be sure that handle receives the preconnected socket
3698 // rather than closing it and making a new one.
3699 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3700 ClientSocketHandle handle;
3701 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:203702 EXPECT_EQ(OK,
Paul Jensen8d6f87ec2018-01-13 00:46:543703 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203704 ClientSocketPool::RespectLimits::ENABLED,
3705 callback.callback(), pool_.get(), NetLogWithSource()));
[email protected]0dc88b32014-03-26 20:12:283706
3707 ASSERT_TRUE(pool_->HasGroup("a"));
3708 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3709 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3710 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3711
3712 // Drain the pending read.
3713 EXPECT_EQ(1, handle.socket()->Read(NULL, 1, CompletionCallback()));
3714
3715 TestLoadTimingInfoConnectedReused(handle);
3716 handle.Reset();
3717
3718 // The socket should be usable now that it's idle again.
3719 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3720}
3721
Alexandr Ilin65ec9582017-10-02 14:50:313722// Tests that a socket pool correctly sets a motivation for a preconnected
3723// socket.
3724TEST_F(ClientSocketPoolBaseTest, PreconnectSetsMotivation) {
3725 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3726 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3727
3728 for (auto motivation : {HttpRequestInfo::NORMAL_MOTIVATION,
3729 HttpRequestInfo::PRECONNECT_MOTIVATED,
3730 HttpRequestInfo::OMNIBOX_MOTIVATED}) {
3731 SCOPED_TRACE(::testing::Message() << "motivation: " << motivation);
3732 pool_->RequestSockets("a", &params_, 1, NetLogWithSource(), motivation);
3733
3734 ClientSocketHandle handle;
3735 TestCompletionCallback callback;
3736 EXPECT_EQ(
3737 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543738 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
Alexandr Ilin65ec9582017-10-02 14:50:313739 ClientSocketPool::RespectLimits::ENABLED,
3740 callback.callback(), pool_.get(), NetLogWithSource()));
3741
3742 EXPECT_THAT(callback.WaitForResult(), IsOk());
3743 EXPECT_TRUE(handle.is_initialized());
3744 ASSERT_TRUE(handle.socket());
3745 EXPECT_EQ(motivation,
3746 static_cast<MockClientSocket*>(handle.socket())->motivation());
3747 handle.socket()->Disconnect();
3748 handle.Reset();
3749 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3750 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3751 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3752 }
3753}
3754
3755// Tests that a socket pool doesn't change motivation on existing sockets.
3756TEST_F(ClientSocketPoolBaseTest, PreconnectPreservesExistingMotivation) {
3757 CreatePool(3, 3);
3758 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3759
3760 // We should get one socket of each motivation.
3761 pool_->RequestSockets("a", &params_, 1, NetLogWithSource(),
3762 HttpRequestInfo::NORMAL_MOTIVATION);
3763 pool_->RequestSockets("a", &params_, 2, NetLogWithSource(),
3764 HttpRequestInfo::PRECONNECT_MOTIVATED);
3765 pool_->RequestSockets("a", &params_, 3, NetLogWithSource(),
3766 HttpRequestInfo::OMNIBOX_MOTIVATED);
3767
3768 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
3769 EXPECT_EQ(3, pool_->NumUnassignedConnectJobsInGroup("a"));
3770 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3771
3772 std::vector<ClientSocketHandle> handles(3);
3773 std::vector<TestCompletionCallback> callbacks(3);
3774
3775 for (size_t i = 0; i < 3; ++i) {
3776 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543777 handles[i].Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
Alexandr Ilin65ec9582017-10-02 14:50:313778 ClientSocketPool::RespectLimits::ENABLED,
3779 callbacks[i].callback(), pool_.get(),
3780 NetLogWithSource()));
3781 }
3782
3783 for (size_t i = 0; i < 3; ++i) {
3784 EXPECT_THAT(callbacks[i].WaitForResult(), IsOk());
3785 EXPECT_TRUE(handles[i].is_initialized());
3786 EXPECT_TRUE(handles[i].socket());
3787 }
3788
3789 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3790 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3791 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3792 EXPECT_EQ(3, pool_->NumActiveSocketsInGroup("a"));
3793
3794 EXPECT_EQ(HttpRequestInfo::NORMAL_MOTIVATION,
3795 static_cast<MockClientSocket*>(handles[0].socket())->motivation());
3796 EXPECT_EQ(HttpRequestInfo::PRECONNECT_MOTIVATED,
3797 static_cast<MockClientSocket*>(handles[1].socket())->motivation());
3798 EXPECT_EQ(HttpRequestInfo::OMNIBOX_MOTIVATED,
3799 static_cast<MockClientSocket*>(handles[2].socket())->motivation());
3800}
3801
[email protected]043b68c82013-08-22 23:41:523802class MockLayeredPool : public HigherLayeredPool {
[email protected]58e562f2013-04-22 17:32:203803 public:
3804 MockLayeredPool(TestClientSocketPool* pool,
3805 const std::string& group_name)
3806 : pool_(pool),
[email protected]58e562f2013-04-22 17:32:203807 group_name_(group_name),
3808 can_release_connection_(true) {
[email protected]043b68c82013-08-22 23:41:523809 pool_->AddHigherLayeredPool(this);
[email protected]58e562f2013-04-22 17:32:203810 }
3811
Daniel Cheng4496d0822018-04-26 21:52:153812 ~MockLayeredPool() override { pool_->RemoveHigherLayeredPool(this); }
[email protected]58e562f2013-04-22 17:32:203813
3814 int RequestSocket(TestClientSocketPool* pool) {
mmenked3641e12016-01-28 16:06:153815 scoped_refptr<TestSocketParams> params(new TestSocketParams());
Paul Jensen8d6f87ec2018-01-13 00:46:543816 return handle_.Init(group_name_, params, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:153817 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:203818 callback_.callback(), pool, NetLogWithSource());
[email protected]58e562f2013-04-22 17:32:203819 }
3820
3821 int RequestSocketWithoutLimits(TestClientSocketPool* pool) {
mmenked3641e12016-01-28 16:06:153822 scoped_refptr<TestSocketParams> params(new TestSocketParams());
Paul Jensen8d6f87ec2018-01-13 00:46:543823 return handle_.Init(group_name_, params, MAXIMUM_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:153824 ClientSocketPool::RespectLimits::DISABLED,
tfarina428341112016-09-22 13:38:203825 callback_.callback(), pool, NetLogWithSource());
[email protected]58e562f2013-04-22 17:32:203826 }
3827
3828 bool ReleaseOneConnection() {
3829 if (!handle_.is_initialized() || !can_release_connection_) {
3830 return false;
3831 }
3832 handle_.socket()->Disconnect();
3833 handle_.Reset();
3834 return true;
3835 }
3836
3837 void set_can_release_connection(bool can_release_connection) {
3838 can_release_connection_ = can_release_connection;
3839 }
3840
3841 MOCK_METHOD0(CloseOneIdleConnection, bool());
3842
3843 private:
3844 TestClientSocketPool* const pool_;
[email protected]58e562f2013-04-22 17:32:203845 ClientSocketHandle handle_;
3846 TestCompletionCallback callback_;
3847 const std::string group_name_;
3848 bool can_release_connection_;
3849};
3850
3851TEST_F(ClientSocketPoolBaseTest, FailToCloseIdleSocketsNotHeldByLayeredPool) {
3852 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3853 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3854
3855 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
robpercival214763f2016-07-01 23:27:013856 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:203857 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3858 .WillOnce(Return(false));
[email protected]043b68c82013-08-22 23:41:523859 EXPECT_FALSE(pool_->CloseOneIdleConnectionInHigherLayeredPool());
[email protected]58e562f2013-04-22 17:32:203860}
3861
3862TEST_F(ClientSocketPoolBaseTest, ForciblyCloseIdleSocketsHeldByLayeredPool) {
3863 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3864 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3865
3866 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
robpercival214763f2016-07-01 23:27:013867 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:203868 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3869 .WillOnce(Invoke(&mock_layered_pool,
3870 &MockLayeredPool::ReleaseOneConnection));
[email protected]043b68c82013-08-22 23:41:523871 EXPECT_TRUE(pool_->CloseOneIdleConnectionInHigherLayeredPool());
[email protected]58e562f2013-04-22 17:32:203872}
3873
3874// Tests the basic case of closing an idle socket in a higher layered pool when
3875// a new request is issued and the lower layer pool is stalled.
3876TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsHeldByLayeredPoolWhenNeeded) {
3877 CreatePool(1, 1);
3878 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3879
3880 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
robpercival214763f2016-07-01 23:27:013881 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:203882 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3883 .WillOnce(Invoke(&mock_layered_pool,
3884 &MockLayeredPool::ReleaseOneConnection));
3885 ClientSocketHandle handle;
3886 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:153887 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543888 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:153889 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:203890 callback.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013891 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:203892}
3893
3894// Same as above, but the idle socket is in the same group as the stalled
3895// socket, and closes the only other request in its group when closing requests
3896// in higher layered pools. This generally shouldn't happen, but it may be
3897// possible if a higher level pool issues a request and the request is
3898// subsequently cancelled. Even if it's not possible, best not to crash.
3899TEST_F(ClientSocketPoolBaseTest,
3900 CloseIdleSocketsHeldByLayeredPoolWhenNeededSameGroup) {
3901 CreatePool(2, 2);
3902 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3903
3904 // Need a socket in another group for the pool to be stalled (If a group
3905 // has the maximum number of connections already, it's not stalled).
3906 ClientSocketHandle handle1;
3907 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203908 EXPECT_EQ(
Paul Jensen8d6f87ec2018-01-13 00:46:543909 OK, handle1.Init("group1", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203910 ClientSocketPool::RespectLimits::ENABLED,
3911 callback1.callback(), pool_.get(), NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:203912
3913 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
robpercival214763f2016-07-01 23:27:013914 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:203915 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3916 .WillOnce(Invoke(&mock_layered_pool,
3917 &MockLayeredPool::ReleaseOneConnection));
3918 ClientSocketHandle handle;
3919 TestCompletionCallback callback2;
mmenked3641e12016-01-28 16:06:153920 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543921 handle.Init("group2", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:153922 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:203923 callback2.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013924 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:203925}
3926
3927// Tests the case when an idle socket can be closed when a new request is
3928// issued, and the new request belongs to a group that was previously stalled.
3929TEST_F(ClientSocketPoolBaseTest,
3930 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded) {
3931 CreatePool(2, 2);
3932 std::list<TestConnectJob::JobType> job_types;
3933 job_types.push_back(TestConnectJob::kMockJob);
3934 job_types.push_back(TestConnectJob::kMockJob);
3935 job_types.push_back(TestConnectJob::kMockJob);
3936 job_types.push_back(TestConnectJob::kMockJob);
3937 connect_job_factory_->set_job_types(&job_types);
3938
3939 ClientSocketHandle handle1;
3940 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203941 EXPECT_EQ(
Paul Jensen8d6f87ec2018-01-13 00:46:543942 OK, handle1.Init("group1", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203943 ClientSocketPool::RespectLimits::ENABLED,
3944 callback1.callback(), pool_.get(), NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:203945
3946 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
robpercival214763f2016-07-01 23:27:013947 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:203948 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3949 .WillRepeatedly(Invoke(&mock_layered_pool,
3950 &MockLayeredPool::ReleaseOneConnection));
3951 mock_layered_pool.set_can_release_connection(false);
3952
3953 // The third request is made when the socket pool is in a stalled state.
3954 ClientSocketHandle handle3;
3955 TestCompletionCallback callback3;
tfarina428341112016-09-22 13:38:203956 EXPECT_EQ(
3957 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543958 handle3.Init("group3", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203959 ClientSocketPool::RespectLimits::ENABLED,
3960 callback3.callback(), pool_.get(), NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:203961
3962 base::RunLoop().RunUntilIdle();
3963 EXPECT_FALSE(callback3.have_result());
3964
3965 // The fourth request is made when the pool is no longer stalled. The third
3966 // request should be serviced first, since it was issued first and has the
3967 // same priority.
3968 mock_layered_pool.set_can_release_connection(true);
3969 ClientSocketHandle handle4;
3970 TestCompletionCallback callback4;
tfarina428341112016-09-22 13:38:203971 EXPECT_EQ(
3972 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543973 handle4.Init("group3", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203974 ClientSocketPool::RespectLimits::ENABLED,
3975 callback4.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013976 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:203977 EXPECT_FALSE(callback4.have_result());
3978
3979 // Closing a handle should free up another socket slot.
3980 handle1.Reset();
robpercival214763f2016-07-01 23:27:013981 EXPECT_THAT(callback4.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:203982}
3983
3984// Tests the case when an idle socket can be closed when a new request is
3985// issued, and the new request belongs to a group that was previously stalled.
3986//
3987// The two differences from the above test are that the stalled requests are not
3988// in the same group as the layered pool's request, and the the fourth request
3989// has a higher priority than the third one, so gets a socket first.
3990TEST_F(ClientSocketPoolBaseTest,
3991 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded2) {
3992 CreatePool(2, 2);
3993 std::list<TestConnectJob::JobType> job_types;
3994 job_types.push_back(TestConnectJob::kMockJob);
3995 job_types.push_back(TestConnectJob::kMockJob);
3996 job_types.push_back(TestConnectJob::kMockJob);
3997 job_types.push_back(TestConnectJob::kMockJob);
3998 connect_job_factory_->set_job_types(&job_types);
3999
4000 ClientSocketHandle handle1;
4001 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:204002 EXPECT_EQ(
Paul Jensen8d6f87ec2018-01-13 00:46:544003 OK, handle1.Init("group1", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:204004 ClientSocketPool::RespectLimits::ENABLED,
4005 callback1.callback(), pool_.get(), NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204006
4007 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
robpercival214763f2016-07-01 23:27:014008 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204009 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4010 .WillRepeatedly(Invoke(&mock_layered_pool,
4011 &MockLayeredPool::ReleaseOneConnection));
4012 mock_layered_pool.set_can_release_connection(false);
4013
4014 // The third request is made when the socket pool is in a stalled state.
4015 ClientSocketHandle handle3;
4016 TestCompletionCallback callback3;
tfarina428341112016-09-22 13:38:204017 EXPECT_EQ(
4018 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:544019 handle3.Init("group3", params_, MEDIUM, SocketTag(),
tfarina428341112016-09-22 13:38:204020 ClientSocketPool::RespectLimits::ENABLED,
4021 callback3.callback(), pool_.get(), NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204022
4023 base::RunLoop().RunUntilIdle();
4024 EXPECT_FALSE(callback3.have_result());
4025
4026 // The fourth request is made when the pool is no longer stalled. This
4027 // request has a higher priority than the third request, so is serviced first.
4028 mock_layered_pool.set_can_release_connection(true);
4029 ClientSocketHandle handle4;
4030 TestCompletionCallback callback4;
tfarina428341112016-09-22 13:38:204031 EXPECT_EQ(
4032 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:544033 handle4.Init("group3", params_, HIGHEST, SocketTag(),
tfarina428341112016-09-22 13:38:204034 ClientSocketPool::RespectLimits::ENABLED,
4035 callback4.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:014036 EXPECT_THAT(callback4.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204037 EXPECT_FALSE(callback3.have_result());
4038
4039 // Closing a handle should free up another socket slot.
4040 handle1.Reset();
robpercival214763f2016-07-01 23:27:014041 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204042}
4043
4044TEST_F(ClientSocketPoolBaseTest,
4045 CloseMultipleIdleSocketsHeldByLayeredPoolWhenNeeded) {
4046 CreatePool(1, 1);
4047 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4048
4049 MockLayeredPool mock_layered_pool1(pool_.get(), "foo");
robpercival214763f2016-07-01 23:27:014050 EXPECT_THAT(mock_layered_pool1.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204051 EXPECT_CALL(mock_layered_pool1, CloseOneIdleConnection())
4052 .WillRepeatedly(Invoke(&mock_layered_pool1,
4053 &MockLayeredPool::ReleaseOneConnection));
4054 MockLayeredPool mock_layered_pool2(pool_.get(), "bar");
robpercival214763f2016-07-01 23:27:014055 EXPECT_THAT(mock_layered_pool2.RequestSocketWithoutLimits(pool_.get()),
4056 IsOk());
[email protected]58e562f2013-04-22 17:32:204057 EXPECT_CALL(mock_layered_pool2, CloseOneIdleConnection())
4058 .WillRepeatedly(Invoke(&mock_layered_pool2,
4059 &MockLayeredPool::ReleaseOneConnection));
4060 ClientSocketHandle handle;
4061 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:154062 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:544063 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:154064 ClientSocketPool::RespectLimits::ENABLED,
tfarina428341112016-09-22 13:38:204065 callback.callback(), pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:014066 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204067}
4068
[email protected]b021ece62013-06-11 11:06:334069// Test that when a socket pool and group are at their limits, a request
mmenked3641e12016-01-28 16:06:154070// with RespectLimits::DISABLED triggers creation of a new socket, and gets the
4071// socket instead of a request with the same priority that was issued earlier,
4072// but has RespectLimits::ENABLED.
[email protected]b021ece62013-06-11 11:06:334073TEST_F(ClientSocketPoolBaseTest, IgnoreLimits) {
[email protected]b021ece62013-06-11 11:06:334074 CreatePool(1, 1);
4075
4076 // Issue a request to reach the socket pool limit.
mmenked3641e12016-01-28 16:06:154077 EXPECT_EQ(
4078 OK, StartRequestWithIgnoreLimits(
4079 "a", MAXIMUM_PRIORITY, ClientSocketPool::RespectLimits::ENABLED));
[email protected]b021ece62013-06-11 11:06:334080 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4081
4082 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4083
mmenked3641e12016-01-28 16:06:154084 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
4085 "a", MAXIMUM_PRIORITY,
4086 ClientSocketPool::RespectLimits::ENABLED));
[email protected]b021ece62013-06-11 11:06:334087 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4088
mmenked3641e12016-01-28 16:06:154089 // Issue a request that ignores the limits, so a new ConnectJob is
4090 // created.
4091 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
4092 "a", MAXIMUM_PRIORITY,
4093 ClientSocketPool::RespectLimits::DISABLED));
[email protected]b021ece62013-06-11 11:06:334094 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4095
robpercival214763f2016-07-01 23:27:014096 EXPECT_THAT(request(2)->WaitForResult(), IsOk());
[email protected]b021ece62013-06-11 11:06:334097 EXPECT_FALSE(request(1)->have_result());
4098}
4099
[email protected]c55fabd2013-11-04 23:26:564100// Test that when a socket pool and group are at their limits, a ConnectJob
mmenked3641e12016-01-28 16:06:154101// issued for a request with RespectLimits::DISABLED is not cancelled when a
4102// request with RespectLimits::ENABLED issued to the same group is cancelled.
[email protected]c55fabd2013-11-04 23:26:564103TEST_F(ClientSocketPoolBaseTest, IgnoreLimitsCancelOtherJob) {
[email protected]c55fabd2013-11-04 23:26:564104 CreatePool(1, 1);
4105
4106 // Issue a request to reach the socket pool limit.
mmenked3641e12016-01-28 16:06:154107 EXPECT_EQ(
4108 OK, StartRequestWithIgnoreLimits(
4109 "a", MAXIMUM_PRIORITY, ClientSocketPool::RespectLimits::ENABLED));
[email protected]c55fabd2013-11-04 23:26:564110 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4111
4112 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4113
mmenked3641e12016-01-28 16:06:154114 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
4115 "a", MAXIMUM_PRIORITY,
4116 ClientSocketPool::RespectLimits::ENABLED));
[email protected]c55fabd2013-11-04 23:26:564117 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4118
mmenked3641e12016-01-28 16:06:154119 // Issue a request with RespectLimits::DISABLED, so a new ConnectJob is
4120 // created.
4121 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
4122 "a", MAXIMUM_PRIORITY,
4123 ClientSocketPool::RespectLimits::DISABLED));
[email protected]b021ece62013-06-11 11:06:334124 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4125
mmenked3641e12016-01-28 16:06:154126 // Cancel the pending request with RespectLimits::ENABLED. The ConnectJob
[email protected]b021ece62013-06-11 11:06:334127 // should not be cancelled.
4128 request(1)->handle()->Reset();
4129 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4130
robpercival214763f2016-07-01 23:27:014131 EXPECT_THAT(request(2)->WaitForResult(), IsOk());
[email protected]b021ece62013-06-11 11:06:334132 EXPECT_FALSE(request(1)->have_result());
4133}
4134
[email protected]f6d1d6eb2009-06-24 20:16:094135} // namespace
4136
4137} // namespace net