blob: b753e4cdca06a715371e3810f13d360bad8b0c8d [file] [log] [blame]
[email protected]e34400c32012-01-24 02:49:331// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]f6d1d6eb2009-06-24 20:16:092// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]ab838892009-06-30 18:49:055#include "net/socket/client_socket_pool_base.h"
[email protected]f6d1d6eb2009-06-24 20:16:096
tbansalf82cc8e2015-10-14 20:05:497#include <stdint.h>
dchengc7eeda422015-12-26 03:56:488#include <utility>
[email protected]51fdc7c2012-04-10 19:19:489#include <vector>
10
[email protected]6ecf2b92011-12-15 01:14:5211#include "base/bind.h"
12#include "base/bind_helpers.h"
[email protected]2041cf342010-02-19 03:15:5913#include "base/callback.h"
skyostil4891b25b2015-06-11 11:43:4514#include "base/location.h"
mmenke33d24423d2015-05-19 19:41:0915#include "base/logging.h"
[email protected]3b63f8f42011-03-28 01:54:1516#include "base/memory/ref_counted.h"
[email protected]6ea7b152011-12-21 21:21:1317#include "base/memory/weak_ptr.h"
Alexander Timin4f9c35c2018-11-01 20:15:2018#include "base/message_loop/message_loop.h"
[email protected]034df0f32013-01-07 23:17:4819#include "base/run_loop.h"
skyostil4891b25b2015-06-11 11:43:4520#include "base/single_thread_task_runner.h"
Avi Drissman4365a4782018-12-28 19:26:2421#include "base/stl_util.h"
[email protected]fc9be5802013-06-11 10:56:5122#include "base/strings/string_number_conversions.h"
[email protected]18b577412013-07-18 04:19:1523#include "base/strings/stringprintf.h"
[email protected]f214f8792011-01-01 02:17:0824#include "base/threading/platform_thread.h"
gabf767595f2016-05-11 18:50:3525#include "base/threading/thread_task_runner_handle.h"
[email protected]f3a1c642011-07-12 19:15:0326#include "base/values.h"
[email protected]034df0f32013-01-07 23:17:4827#include "net/base/load_timing_info.h"
[email protected]b258e0792013-01-12 07:11:5928#include "net/base/load_timing_info_test_util.h"
[email protected]d8eb84242010-09-25 02:25:0629#include "net/base/net_errors.h"
[email protected]ac790b42009-12-02 04:31:3130#include "net/base/request_priority.h"
[email protected]f6d1d6eb2009-06-24 20:16:0931#include "net/base/test_completion_callback.h"
[email protected]277d5942010-08-11 21:02:3532#include "net/http/http_response_headers.h"
eroman87c53d62015-04-02 06:51:0733#include "net/log/net_log.h"
mikecirone8b85c432016-09-08 19:11:0034#include "net/log/net_log_event_type.h"
mikecironef22f9812016-10-04 03:40:1935#include "net/log/net_log_source.h"
mikecirone8b85c432016-09-08 19:11:0036#include "net/log/net_log_source_type.h"
mmenke16a7cbdd2015-04-24 23:00:5637#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4638#include "net/log/test_net_log_entry.h"
39#include "net/log/test_net_log_util.h"
[email protected]f6d1d6eb2009-06-24 20:16:0940#include "net/socket/client_socket_factory.h"
41#include "net/socket/client_socket_handle.h"
tfarina5dd13c22016-11-16 12:08:2642#include "net/socket/datagram_client_socket.h"
tbansalca83c002016-04-28 20:56:2843#include "net/socket/socket_performance_watcher.h"
Paul Jensen8d6f87ec2018-01-13 00:46:5444#include "net/socket/socket_tag.h"
[email protected]75439d3b2009-07-23 22:11:1745#include "net/socket/socket_test_util.h"
[email protected]18ccfdb2013-08-15 00:13:4446#include "net/socket/ssl_client_socket.h"
[email protected]3268023f2011-05-05 00:08:1047#include "net/socket/stream_socket.h"
robpercival214763f2016-07-01 23:27:0148#include "net/test/gtest_util.h"
Bence Béky98447b12018-05-08 03:14:0149#include "net/test/test_with_scoped_task_environment.h"
Ramin Halavati0a08cc82018-02-06 07:46:3850#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
[email protected]51fdc7c2012-04-10 19:19:4851#include "testing/gmock/include/gmock/gmock.h"
[email protected]f6d1d6eb2009-06-24 20:16:0952#include "testing/gtest/include/gtest/gtest.h"
53
robpercival214763f2016-07-01 23:27:0154using net::test::IsError;
55using net::test::IsOk;
56
[email protected]51fdc7c2012-04-10 19:19:4857using ::testing::Invoke;
58using ::testing::Return;
59
[email protected]f6d1d6eb2009-06-24 20:16:0960namespace net {
61
62namespace {
63
[email protected]211d21722009-07-22 15:48:5364const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2065const int kDefaultMaxSocketsPerGroup = 2;
Tarun Bansala7635092019-02-20 10:00:5966constexpr base::TimeDelta kUnusedIdleSocketTimeout =
67 base::TimeDelta::FromSeconds(10);
[email protected]0b7648c2009-07-06 20:14:0168
[email protected]034df0f32013-01-07 23:17:4869// Make sure |handle| sets load times correctly when it has been assigned a
70// reused socket.
71void TestLoadTimingInfoConnectedReused(const ClientSocketHandle& handle) {
72 LoadTimingInfo load_timing_info;
73 // Only pass true in as |is_reused|, as in general, HttpStream types should
74 // have stricter concepts of reuse than socket pools.
75 EXPECT_TRUE(handle.GetLoadTimingInfo(true, &load_timing_info));
76
77 EXPECT_EQ(true, load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:1978 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]034df0f32013-01-07 23:17:4879
[email protected]b258e0792013-01-12 07:11:5980 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
81 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:4882}
83
84// Make sure |handle| sets load times correctly when it has been assigned a
[email protected]b021ece62013-06-11 11:06:3385// fresh socket. Also runs TestLoadTimingInfoConnectedReused, since the owner
[email protected]034df0f32013-01-07 23:17:4886// of a connection where |is_reused| is false may consider the connection
87// reused.
88void TestLoadTimingInfoConnectedNotReused(const ClientSocketHandle& handle) {
89 EXPECT_FALSE(handle.is_reused());
90
91 LoadTimingInfo load_timing_info;
92 EXPECT_TRUE(handle.GetLoadTimingInfo(false, &load_timing_info));
93
94 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:1995 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]034df0f32013-01-07 23:17:4896
[email protected]b258e0792013-01-12 07:11:5997 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
98 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
99 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:48100
101 TestLoadTimingInfoConnectedReused(handle);
102}
103
104// Make sure |handle| sets load times correctly, in the case that it does not
105// currently have a socket.
106void TestLoadTimingInfoNotConnected(const ClientSocketHandle& handle) {
107 // Should only be set to true once a socket is assigned, if at all.
108 EXPECT_FALSE(handle.is_reused());
109
110 LoadTimingInfo load_timing_info;
111 EXPECT_FALSE(handle.GetLoadTimingInfo(false, &load_timing_info));
112
113 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19114 EXPECT_EQ(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]034df0f32013-01-07 23:17:48115
[email protected]b258e0792013-01-12 07:11:59116 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
117 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:48118}
119
[email protected]df4b4ef2010-07-12 18:25:21120class TestSocketParams : public base::RefCounted<TestSocketParams> {
[email protected]5acdce12011-03-30 13:00:20121 public:
Chris Watkins7a41d3552017-12-01 02:13:27122 explicit TestSocketParams() = default;
[email protected]51fdc7c2012-04-10 19:19:48123
[email protected]df4b4ef2010-07-12 18:25:21124 private:
125 friend class base::RefCounted<TestSocketParams>;
Chris Watkins7a41d3552017-12-01 02:13:27126 ~TestSocketParams() = default;
[email protected]df4b4ef2010-07-12 18:25:21127};
[email protected]7fc5b09a2010-02-27 00:07:38128typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
[email protected]d80a4322009-08-14 07:07:49129
[email protected]3268023f2011-05-05 00:08:10130class MockClientSocket : public StreamSocket {
[email protected]f6d1d6eb2009-06-24 20:16:09131 public:
[email protected]034df0f32013-01-07 23:17:48132 explicit MockClientSocket(net::NetLog* net_log)
133 : connected_(false),
[email protected]0dc88b32014-03-26 20:12:28134 has_unread_data_(false),
tfarina428341112016-09-22 13:38:20135 net_log_(NetLogWithSource::Make(net_log, NetLogSourceType::SOCKET)),
Charlie Harrison3e4c0622018-05-13 15:44:30136 was_used_to_convey_data_(false) {}
[email protected]f6d1d6eb2009-06-24 20:16:09137
[email protected]0dc88b32014-03-26 20:12:28138 // Sets whether the socket has unread data. If true, the next call to Read()
139 // will return 1 byte and IsConnectedAndIdle() will return false.
140 void set_has_unread_data(bool has_unread_data) {
141 has_unread_data_ = has_unread_data;
142 }
143
[email protected]3f55aa12011-12-07 02:03:33144 // Socket implementation.
dchengb03027d2014-10-21 12:00:20145 int Read(IOBuffer* /* buf */,
146 int len,
Brad Lassey3a814172018-04-26 03:30:21147 CompletionOnceCallback /* callback */) override {
[email protected]0dc88b32014-03-26 20:12:28148 if (has_unread_data_ && len > 0) {
149 has_unread_data_ = false;
150 was_used_to_convey_data_ = true;
151 return 1;
152 }
[email protected]e86df8dc2013-03-30 13:18:28153 return ERR_UNEXPECTED;
[email protected]3f55aa12011-12-07 02:03:33154 }
[email protected]ab838892009-06-30 18:49:05155
[email protected]a2b2cfc2017-12-06 09:06:08156 int Write(
157 IOBuffer* /* buf */,
158 int len,
Brad Lassey3a814172018-04-26 03:30:21159 CompletionOnceCallback /* callback */,
[email protected]a2b2cfc2017-12-06 09:06:08160 const NetworkTrafficAnnotationTag& /*traffic_annotation*/) override {
[email protected]0f873e82010-09-02 16:09:01161 was_used_to_convey_data_ = true;
162 return len;
[email protected]ab838892009-06-30 18:49:05163 }
Avi Drissman13fc8932015-12-20 04:40:46164 int SetReceiveBufferSize(int32_t size) override { return OK; }
165 int SetSendBufferSize(int32_t size) override { return OK; }
[email protected]ab838892009-06-30 18:49:05166
[email protected]dbf036f2011-12-06 23:33:24167 // StreamSocket implementation.
Brad Lassey3a814172018-04-26 03:30:21168 int Connect(CompletionOnceCallback callback) override {
[email protected]dbf036f2011-12-06 23:33:24169 connected_ = true;
170 return OK;
171 }
[email protected]f6d1d6eb2009-06-24 20:16:09172
dchengb03027d2014-10-21 12:00:20173 void Disconnect() override { connected_ = false; }
174 bool IsConnected() const override { return connected_; }
175 bool IsConnectedAndIdle() const override {
[email protected]0dc88b32014-03-26 20:12:28176 return connected_ && !has_unread_data_;
177 }
[email protected]0b7648c2009-07-06 20:14:01178
dchengb03027d2014-10-21 12:00:20179 int GetPeerAddress(IPEndPoint* /* address */) const override {
[email protected]9f864b32010-01-20 15:01:16180 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:09181 }
[email protected]f6d1d6eb2009-06-24 20:16:09182
dchengb03027d2014-10-21 12:00:20183 int GetLocalAddress(IPEndPoint* /* address */) const override {
[email protected]e7f74da2011-04-19 23:49:35184 return ERR_UNEXPECTED;
185 }
186
tfarina428341112016-09-22 13:38:20187 const NetLogWithSource& NetLog() const override { return net_log_; }
[email protected]a2006ece2010-04-23 16:44:02188
dchengb03027d2014-10-21 12:00:20189 bool WasEverUsed() const override { return was_used_to_convey_data_; }
tfarina2846404c2016-12-25 14:31:37190 bool WasAlpnNegotiated() const override { return false; }
dchengb03027d2014-10-21 12:00:20191 NextProto GetNegotiatedProtocol() const override { return kProtoUnknown; }
192 bool GetSSLInfo(SSLInfo* ssl_info) override { return false; }
ttuttle23fdb7b2015-05-15 01:28:03193 void GetConnectionAttempts(ConnectionAttempts* out) const override {
194 out->clear();
195 }
196 void ClearConnectionAttempts() override {}
197 void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
tbansalf82cc8e2015-10-14 20:05:49198 int64_t GetTotalReceivedBytes() const override {
199 NOTIMPLEMENTED();
200 return 0;
201 }
Paul Jensen0f49dec2017-12-12 23:39:58202 void ApplySocketTag(const SocketTag& tag) override {}
[email protected]9b5614a2010-08-25 20:29:45203
[email protected]f6d1d6eb2009-06-24 20:16:09204 private:
205 bool connected_;
[email protected]0dc88b32014-03-26 20:12:28206 bool has_unread_data_;
tfarina428341112016-09-22 13:38:20207 NetLogWithSource net_log_;
[email protected]0f873e82010-09-02 16:09:01208 bool was_used_to_convey_data_;
[email protected]f6d1d6eb2009-06-24 20:16:09209
[email protected]ab838892009-06-30 18:49:05210 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:09211};
212
[email protected]5fc08e32009-07-15 17:09:57213class TestConnectJob;
214
[email protected]f6d1d6eb2009-06-24 20:16:09215class MockClientSocketFactory : public ClientSocketFactory {
216 public:
[email protected]ab838892009-06-30 18:49:05217 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:09218
danakj655b66c2016-04-16 00:51:38219 std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
[email protected]5370c012011-06-29 03:47:04220 DatagramSocket::BindType bind_type,
[email protected]98b0e582011-06-22 14:31:41221 NetLog* net_log,
mikecironef22f9812016-10-04 03:40:19222 const NetLogSource& source) override {
[email protected]98b0e582011-06-22 14:31:41223 NOTREACHED();
danakj655b66c2016-04-16 00:51:38224 return std::unique_ptr<DatagramClientSocket>();
[email protected]98b0e582011-06-22 14:31:41225 }
226
Helen Lid5bb9222018-04-12 15:33:09227 std::unique_ptr<TransportClientSocket> CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07228 const AddressList& addresses,
danakj655b66c2016-04-16 00:51:38229 std::unique_ptr<
230 SocketPerformanceWatcher> /* socket_performance_watcher */,
[email protected]0a0b7682010-08-25 17:08:07231 NetLog* /* net_log */,
mikecironef22f9812016-10-04 03:40:19232 const NetLogSource& /*source*/) override {
[email protected]f6d1d6eb2009-06-24 20:16:09233 allocation_count_++;
Helen Lid5bb9222018-04-12 15:33:09234 return nullptr;
[email protected]f6d1d6eb2009-06-24 20:16:09235 }
236
danakj655b66c2016-04-16 00:51:38237 std::unique_ptr<SSLClientSocket> CreateSSLClientSocket(
Matt Menke841fc412019-03-05 23:20:12238 std::unique_ptr<StreamSocket> stream_socket,
[email protected]4f4de7e62010-11-12 19:55:27239 const HostPortPair& host_and_port,
[email protected]7ab5bbd12010-10-19 13:33:21240 const SSLConfig& ssl_config,
mostynbba063d6032014-10-09 11:01:13241 const SSLClientSocketContext& context) override {
[email protected]f6d1d6eb2009-06-24 20:16:09242 NOTIMPLEMENTED();
danakj655b66c2016-04-16 00:51:38243 return std::unique_ptr<SSLClientSocket>();
[email protected]f6d1d6eb2009-06-24 20:16:09244 }
Matt Menkefd956922019-02-04 23:44:03245
Matt Menke52cd95a2019-02-08 06:16:27246 std::unique_ptr<ProxyClientSocket> CreateProxyClientSocket(
247 std::unique_ptr<StreamSocket> stream_socket,
248 const std::string& user_agent,
249 const HostPortPair& endpoint,
250 const ProxyServer& proxy_server,
251 HttpAuthController* http_auth_controller,
252 bool tunnel,
253 bool using_spdy,
254 NextProto negotiated_protocol,
255 ProxyDelegate* proxy_delegate,
256 bool is_https_proxy,
257 const NetworkTrafficAnnotationTag& traffic_annotation) override {
258 NOTIMPLEMENTED();
259 return nullptr;
260 }
261
[email protected]5fc08e32009-07-15 17:09:57262 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
[email protected]03b7c8c2013-07-20 04:38:55263
[email protected]5fc08e32009-07-15 17:09:57264 void SignalJobs();
265
[email protected]03b7c8c2013-07-20 04:38:55266 void SignalJob(size_t job);
267
268 void SetJobLoadState(size_t job, LoadState load_state);
269
Matt Menke141b87f22019-01-30 02:43:03270 // Sets the HasConnectionEstablished value of the specified job to true,
271 // without invoking the callback.
272 void SetJobHasEstablishedConnection(size_t job);
273
[email protected]f6d1d6eb2009-06-24 20:16:09274 int allocation_count() const { return allocation_count_; }
275
[email protected]f6d1d6eb2009-06-24 20:16:09276 private:
277 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:57278 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09279};
280
[email protected]ab838892009-06-30 18:49:05281class TestConnectJob : public ConnectJob {
282 public:
283 enum JobType {
284 kMockJob,
285 kMockFailingJob,
286 kMockPendingJob,
287 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57288 kMockWaitingJob,
Matt Menkeb57663b32019-03-01 17:17:10289
290 // Certificate errors return a socket in addition to an error code.
291 kMockCertErrorJob,
292 kMockPendingCertErrorJob,
293
[email protected]e60e47a2010-07-14 03:37:18294 kMockAdditionalErrorStateJob,
295 kMockPendingAdditionalErrorStateJob,
[email protected]0dc88b32014-03-26 20:12:28296 kMockUnreadDataJob,
Matt Menkeb57663b32019-03-01 17:17:10297
298 kMockAuthChallengeOnceJob,
299 kMockAuthChallengeTwiceJob,
300 kMockAuthChallengeOnceFailingJob,
301 kMockAuthChallengeTwiceFailingJob,
[email protected]ab838892009-06-30 18:49:05302 };
303
[email protected]994d4932010-07-12 17:55:13304 // The kMockPendingJob uses a slight delay before allowing the connect
305 // to complete.
306 static const int kPendingConnectDelay = 2;
307
[email protected]ab838892009-06-30 18:49:05308 TestConnectJob(JobType job_type,
[email protected]d80a4322009-08-14 07:07:49309 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34310 base::TimeDelta timeout_duration,
Matt Menkea6f99ad2019-03-08 02:26:43311 const CommonConnectJobParams* common_connect_job_params,
[email protected]ab838892009-06-30 18:49:05312 ConnectJob::Delegate* delegate,
Matt Menkea6f99ad2019-03-08 02:26:43313 MockClientSocketFactory* client_socket_factory)
Matt Menke1a6c92d2019-02-23 00:25:38314 : ConnectJob(request.priority(),
Matt Menkea6f99ad2019-03-08 02:26:43315 request.socket_tag(),
Matt Menke1a6c92d2019-02-23 00:25:38316 timeout_duration,
Matt Menkea6f99ad2019-03-08 02:26:43317 common_connect_job_params,
Matt Menke1a6c92d2019-02-23 00:25:38318 delegate,
319 nullptr /* net_log */,
320 NetLogSourceType::TRANSPORT_CONNECT_JOB,
321 NetLogEventType::TRANSPORT_CONNECT_JOB_CONNECT),
[email protected]2ab05b52009-07-01 23:57:58322 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05323 client_socket_factory_(client_socket_factory),
[email protected]e60e47a2010-07-14 03:37:18324 load_state_(LOAD_STATE_IDLE),
Matt Menke141b87f22019-01-30 02:43:03325 has_established_connection_(false),
[email protected]d5492c52013-11-10 20:44:39326 store_additional_error_state_(false),
mmenked3641e12016-01-28 16:06:15327 weak_factory_(this) {}
[email protected]ab838892009-06-30 18:49:05328
[email protected]974ebd62009-08-03 23:14:34329 void Signal() {
[email protected]e772db3f2010-07-12 18:11:13330 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
[email protected]974ebd62009-08-03 23:14:34331 }
332
[email protected]03b7c8c2013-07-20 04:38:55333 void set_load_state(LoadState load_state) { load_state_ = load_state; }
334
Matt Menke141b87f22019-01-30 02:43:03335 void set_has_established_connection() {
336 DCHECK(!has_established_connection_);
337 has_established_connection_ = true;
338 }
339
[email protected]03b7c8c2013-07-20 04:38:55340 // From ConnectJob:
341
dchengb03027d2014-10-21 12:00:20342 LoadState GetLoadState() const override { return load_state_; }
[email protected]46451352009-09-01 14:54:21343
Matt Menke141b87f22019-01-30 02:43:03344 bool HasEstablishedConnection() const override {
345 return has_established_connection_;
346 }
347
dchengb03027d2014-10-21 12:00:20348 void GetAdditionalErrorState(ClientSocketHandle* handle) override {
[email protected]e60e47a2010-07-14 03:37:18349 if (store_additional_error_state_) {
350 // Set all of the additional error state fields in some way.
351 handle->set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43352 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:45353 info.headers = new HttpResponseHeaders(std::string());
[email protected]8b498692010-07-16 17:11:43354 handle->set_ssl_error_response_info(info);
[email protected]e60e47a2010-07-14 03:37:18355 }
356 }
357
[email protected]974ebd62009-08-03 23:14:34358 private:
[email protected]03b7c8c2013-07-20 04:38:55359 // From ConnectJob:
[email protected]ab838892009-06-30 18:49:05360
dchengb03027d2014-10-21 12:00:20361 int ConnectInternal() override {
[email protected]ab838892009-06-30 18:49:05362 AddressList ignored;
tbansal7b403bcc2016-04-13 22:33:21363 client_socket_factory_->CreateTransportClientSocket(ignored, NULL, NULL,
mikecironef22f9812016-10-04 03:40:19364 NetLogSource());
[email protected]ab838892009-06-30 18:49:05365 switch (job_type_) {
366 case kMockJob:
[email protected]e772db3f2010-07-12 18:11:13367 return DoConnect(true /* successful */, false /* sync */,
Matt Menkeb57663b32019-03-01 17:17:10368 false /* cert_error */);
[email protected]ab838892009-06-30 18:49:05369 case kMockFailingJob:
[email protected]e772db3f2010-07-12 18:11:13370 return DoConnect(false /* error */, false /* sync */,
Matt Menkeb57663b32019-03-01 17:17:10371 false /* cert_error */);
[email protected]ab838892009-06-30 18:49:05372 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57373 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47374
375 // Depending on execution timings, posting a delayed task can result
376 // in the task getting executed the at the earliest possible
377 // opportunity or only after returning once from the message loop and
378 // then a second call into the message loop. In order to make behavior
379 // more deterministic, we change the default delay to 2ms. This should
380 // always require us to wait for the second call into the message loop.
381 //
382 // N.B. The correct fix for this and similar timing problems is to
383 // abstract time for the purpose of unittests. Unfortunately, we have
384 // a lot of third-party components that directly call the various
385 // time functions, so this change would be rather invasive.
skyostil4891b25b2015-06-11 11:43:45386 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05387 FROM_HERE,
kylecharf4fe5172019-02-15 18:53:49388 base::BindOnce(base::IgnoreResult(&TestConnectJob::DoConnect),
389 weak_factory_.GetWeakPtr(), true /* successful */,
Matt Menkeb57663b32019-03-01 17:17:10390 true /* async */, false /* cert_error */),
[email protected]5761ab9c2012-02-04 16:44:53391 base::TimeDelta::FromMilliseconds(kPendingConnectDelay));
[email protected]ab838892009-06-30 18:49:05392 return ERR_IO_PENDING;
393 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57394 set_load_state(LOAD_STATE_CONNECTING);
skyostil4891b25b2015-06-11 11:43:45395 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05396 FROM_HERE,
kylecharf4fe5172019-02-15 18:53:49397 base::BindOnce(base::IgnoreResult(&TestConnectJob::DoConnect),
398 weak_factory_.GetWeakPtr(), false /* error */,
Matt Menkeb57663b32019-03-01 17:17:10399 true /* async */, false /* cert_error */),
[email protected]5761ab9c2012-02-04 16:44:53400 base::TimeDelta::FromMilliseconds(2));
[email protected]ab838892009-06-30 18:49:05401 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57402 case kMockWaitingJob:
[email protected]03b7c8c2013-07-20 04:38:55403 set_load_state(LOAD_STATE_CONNECTING);
[email protected]5fc08e32009-07-15 17:09:57404 client_socket_factory_->WaitForSignal(this);
405 waiting_success_ = true;
406 return ERR_IO_PENDING;
Matt Menkeb57663b32019-03-01 17:17:10407 case kMockCertErrorJob:
[email protected]e772db3f2010-07-12 18:11:13408 return DoConnect(false /* error */, false /* sync */,
Matt Menkeb57663b32019-03-01 17:17:10409 true /* cert_error */);
410 case kMockPendingCertErrorJob:
[email protected]e772db3f2010-07-12 18:11:13411 set_load_state(LOAD_STATE_CONNECTING);
skyostil4891b25b2015-06-11 11:43:45412 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]e772db3f2010-07-12 18:11:13413 FROM_HERE,
kylecharf4fe5172019-02-15 18:53:49414 base::BindOnce(base::IgnoreResult(&TestConnectJob::DoConnect),
415 weak_factory_.GetWeakPtr(), false /* error */,
Matt Menkeb57663b32019-03-01 17:17:10416 true /* async */, true /* cert_error */),
[email protected]5761ab9c2012-02-04 16:44:53417 base::TimeDelta::FromMilliseconds(2));
[email protected]e772db3f2010-07-12 18:11:13418 return ERR_IO_PENDING;
[email protected]e60e47a2010-07-14 03:37:18419 case kMockAdditionalErrorStateJob:
420 store_additional_error_state_ = true;
421 return DoConnect(false /* error */, false /* sync */,
Matt Menkeb57663b32019-03-01 17:17:10422 false /* cert_error */);
[email protected]e60e47a2010-07-14 03:37:18423 case kMockPendingAdditionalErrorStateJob:
424 set_load_state(LOAD_STATE_CONNECTING);
425 store_additional_error_state_ = true;
skyostil4891b25b2015-06-11 11:43:45426 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]e60e47a2010-07-14 03:37:18427 FROM_HERE,
kylecharf4fe5172019-02-15 18:53:49428 base::BindOnce(base::IgnoreResult(&TestConnectJob::DoConnect),
429 weak_factory_.GetWeakPtr(), false /* error */,
Matt Menkeb57663b32019-03-01 17:17:10430 true /* async */, false /* cert_error */),
[email protected]5761ab9c2012-02-04 16:44:53431 base::TimeDelta::FromMilliseconds(2));
[email protected]e60e47a2010-07-14 03:37:18432 return ERR_IO_PENDING;
[email protected]0dc88b32014-03-26 20:12:28433 case kMockUnreadDataJob: {
434 int ret = DoConnect(true /* successful */, false /* sync */,
Matt Menkeb57663b32019-03-01 17:17:10435 false /* cert_error */);
[email protected]0dc88b32014-03-26 20:12:28436 static_cast<MockClientSocket*>(socket())->set_has_unread_data(true);
437 return ret;
438 }
Matt Menkeb57663b32019-03-01 17:17:10439 case kMockAuthChallengeOnceJob:
Matt Menke4b69f932019-03-04 16:20:01440 set_load_state(LOAD_STATE_CONNECTING);
Matt Menkeb57663b32019-03-01 17:17:10441 DoAdvanceAuthChallenge(1, true /* succeed_after_last_challenge */);
442 return ERR_IO_PENDING;
443 case kMockAuthChallengeTwiceJob:
Matt Menke4b69f932019-03-04 16:20:01444 set_load_state(LOAD_STATE_CONNECTING);
Matt Menkeb57663b32019-03-01 17:17:10445 DoAdvanceAuthChallenge(2, true /* succeed_after_last_challenge */);
446 return ERR_IO_PENDING;
447 case kMockAuthChallengeOnceFailingJob:
Matt Menke4b69f932019-03-04 16:20:01448 set_load_state(LOAD_STATE_CONNECTING);
Matt Menkeb57663b32019-03-01 17:17:10449 DoAdvanceAuthChallenge(1, false /* succeed_after_last_challenge */);
450 return ERR_IO_PENDING;
451 case kMockAuthChallengeTwiceFailingJob:
Matt Menke4b69f932019-03-04 16:20:01452 set_load_state(LOAD_STATE_CONNECTING);
Matt Menkeb57663b32019-03-01 17:17:10453 DoAdvanceAuthChallenge(2, false /* succeed_after_last_challenge */);
454 return ERR_IO_PENDING;
[email protected]ab838892009-06-30 18:49:05455 default:
456 NOTREACHED();
danakj655b66c2016-04-16 00:51:38457 SetSocket(std::unique_ptr<StreamSocket>());
[email protected]ab838892009-06-30 18:49:05458 return ERR_FAILED;
459 }
460 }
461
Lily Chen02ef29a2018-11-30 16:31:43462 void ChangePriorityInternal(RequestPriority priority) override {}
463
Matt Menkeb57663b32019-03-01 17:17:10464 int DoConnect(bool succeed, bool was_async, bool cert_error) {
[email protected]e772db3f2010-07-12 18:11:13465 int result = OK;
Matt Menke141b87f22019-01-30 02:43:03466 has_established_connection_ = true;
[email protected]ab838892009-06-30 18:49:05467 if (succeed) {
Matt Menkeb57663b32019-03-01 17:17:10468 SetSocket(std::make_unique<MockClientSocket>(net_log().net_log()));
Bence Békybdbb0e72018-08-07 21:42:59469 socket()->Connect(CompletionOnceCallback());
Matt Menkeb57663b32019-03-01 17:17:10470 } else if (cert_error) {
471 SetSocket(std::make_unique<MockClientSocket>(net_log().net_log()));
472 result = ERR_CERT_COMMON_NAME_INVALID;
[email protected]6e713f02009-08-06 02:56:40473 } else {
[email protected]e772db3f2010-07-12 18:11:13474 result = ERR_CONNECTION_FAILED;
danakj655b66c2016-04-16 00:51:38475 SetSocket(std::unique_ptr<StreamSocket>());
[email protected]ab838892009-06-30 18:49:05476 }
[email protected]2ab05b52009-07-01 23:57:58477
478 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30479 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05480 return result;
481 }
482
Matt Menkeb57663b32019-03-01 17:17:10483 void DoAdvanceAuthChallenge(int remaining_challenges,
484 bool succeed_after_last_challenge) {
485 base::ThreadTaskRunnerHandle::Get()->PostTask(
486 FROM_HERE,
487 base::BindOnce(&TestConnectJob::InvokeNextProxyAuthCallback,
488 weak_factory_.GetWeakPtr(), remaining_challenges,
489 succeed_after_last_challenge));
490 }
491
492 void InvokeNextProxyAuthCallback(int remaining_challenges,
493 bool succeed_after_last_challenge) {
Matt Menke4b69f932019-03-04 16:20:01494 set_load_state(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL);
Matt Menkeb57663b32019-03-01 17:17:10495 if (remaining_challenges == 0) {
496 DoConnect(succeed_after_last_challenge, true /* was_async */,
497 false /* cert_error */);
498 return;
499 }
500
501 // Integration tests make sure HttpResponseInfo and HttpAuthController work.
502 // The auth tests here are just focused on ConnectJob bookkeeping.
503 HttpResponseInfo info;
504 NotifyDelegateOfProxyAuth(
505 info, nullptr /* http_auth_controller */,
506 base::BindOnce(&TestConnectJob::DoAdvanceAuthChallenge,
507 weak_factory_.GetWeakPtr(), remaining_challenges - 1,
508 succeed_after_last_challenge));
509 }
510
[email protected]5fc08e32009-07-15 17:09:57511 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05512 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57513 MockClientSocketFactory* const client_socket_factory_;
[email protected]46451352009-09-01 14:54:21514 LoadState load_state_;
Matt Menke141b87f22019-01-30 02:43:03515 bool has_established_connection_;
[email protected]e60e47a2010-07-14 03:37:18516 bool store_additional_error_state_;
[email protected]ab838892009-06-30 18:49:05517
[email protected]d5492c52013-11-10 20:44:39518 base::WeakPtrFactory<TestConnectJob> weak_factory_;
519
[email protected]ab838892009-06-30 18:49:05520 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
521};
522
[email protected]d80a4322009-08-14 07:07:49523class TestConnectJobFactory
524 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05525 public:
[email protected]034df0f32013-01-07 23:17:48526 TestConnectJobFactory(MockClientSocketFactory* client_socket_factory,
527 NetLog* net_log)
Matt Menkea6f99ad2019-03-08 02:26:43528 : common_connect_job_params_(
529 nullptr /* client_socket_factory */,
530 nullptr /* host_resolver */,
531 nullptr /* proxy_delegate */,
532 SSLClientSocketContext(),
533 SSLClientSocketContext(),
534 nullptr /* socket_performance_watcher_factory */,
535 nullptr /* network_quality_estimator */,
536 net_log,
537 nullptr /* websocket_endpoint_lock_manager */),
538 job_type_(TestConnectJob::kMockJob),
[email protected]51fdc7c2012-04-10 19:19:48539 job_types_(NULL),
Matt Menkea6f99ad2019-03-08 02:26:43540 client_socket_factory_(client_socket_factory) {}
[email protected]ab838892009-06-30 18:49:05541
Chris Watkins7a41d3552017-12-01 02:13:27542 ~TestConnectJobFactory() override = default;
[email protected]ab838892009-06-30 18:49:05543
544 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
545
[email protected]51fdc7c2012-04-10 19:19:48546 void set_job_types(std::list<TestConnectJob::JobType>* job_types) {
547 job_types_ = job_types;
548 CHECK(!job_types_->empty());
549 }
550
[email protected]974ebd62009-08-03 23:14:34551 void set_timeout_duration(base::TimeDelta timeout_duration) {
552 timeout_duration_ = timeout_duration;
553 }
554
[email protected]3f55aa12011-12-07 02:03:33555 // ConnectJobFactory implementation.
[email protected]83039bb2011-12-09 18:43:55556
danakj655b66c2016-04-16 00:51:38557 std::unique_ptr<ConnectJob> NewConnectJob(
[email protected]d80a4322009-08-14 07:07:49558 const TestClientSocketPoolBase::Request& request,
mostynbba063d6032014-10-09 11:01:13559 ConnectJob::Delegate* delegate) const override {
[email protected]51fdc7c2012-04-10 19:19:48560 EXPECT_TRUE(!job_types_ || !job_types_->empty());
561 TestConnectJob::JobType job_type = job_type_;
562 if (job_types_ && !job_types_->empty()) {
563 job_type = job_types_->front();
564 job_types_->pop_front();
565 }
Matt Menkea6f99ad2019-03-08 02:26:43566 return std::make_unique<TestConnectJob>(
567 job_type, request, timeout_duration_, &common_connect_job_params_,
568 delegate, client_socket_factory_);
[email protected]ab838892009-06-30 18:49:05569 }
570
571 private:
Matt Menkea6f99ad2019-03-08 02:26:43572 const CommonConnectJobParams common_connect_job_params_;
[email protected]ab838892009-06-30 18:49:05573 TestConnectJob::JobType job_type_;
[email protected]51fdc7c2012-04-10 19:19:48574 std::list<TestConnectJob::JobType>* job_types_;
[email protected]974ebd62009-08-03 23:14:34575 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57576 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05577
578 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
579};
580
581class TestClientSocketPool : public ClientSocketPool {
582 public:
[email protected]12322e7e2013-08-15 17:49:26583 typedef TestSocketParams SocketParams;
584
[email protected]ab838892009-06-30 18:49:05585 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53586 int max_sockets,
[email protected]ab838892009-06-30 18:49:05587 int max_sockets_per_group,
[email protected]9bf28db2009-08-29 01:35:16588 base::TimeDelta unused_idle_socket_timeout,
589 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49590 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
Matt Menke833678642019-03-05 22:05:51591 : base_(max_sockets,
rkaplowd90695c2015-03-25 22:12:41592 max_sockets_per_group,
593 unused_idle_socket_timeout,
594 used_idle_socket_timeout,
[email protected]66761b952010-06-25 21:30:38595 connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05596
Chris Watkins7a41d3552017-12-01 02:13:27597 ~TestClientSocketPool() override = default;
[email protected]2431756e2010-09-29 20:26:13598
dchengb03027d2014-10-21 12:00:20599 int RequestSocket(const std::string& group_name,
600 const void* params,
ttuttle859dc7a2015-04-23 19:42:29601 RequestPriority priority,
Paul Jensen8d6f87ec2018-01-13 00:46:54602 const SocketTag& socket_tag,
mmenked3641e12016-01-28 16:06:15603 RespectLimits respect_limits,
dchengb03027d2014-10-21 12:00:20604 ClientSocketHandle* handle,
Bence Béky5a8662b2018-07-03 13:04:03605 CompletionOnceCallback callback,
Matt Menke28ac03e2019-02-25 22:25:50606 const ProxyAuthCallback& proxy_auth_callback,
tfarina428341112016-09-22 13:38:20607 const NetLogWithSource& net_log) override {
[email protected]df4b4ef2010-07-12 18:25:21608 const scoped_refptr<TestSocketParams>* casted_socket_params =
609 static_cast<const scoped_refptr<TestSocketParams>*>(params);
Matt Menke28ac03e2019-02-25 22:25:50610 return base_.RequestSocket(
611 group_name, *casted_socket_params, priority, socket_tag, respect_limits,
612 handle, std::move(callback), proxy_auth_callback, net_log);
[email protected]ab838892009-06-30 18:49:05613 }
614
dchengb03027d2014-10-21 12:00:20615 void RequestSockets(const std::string& group_name,
616 const void* params,
617 int num_sockets,
Charlie Harrison55ce6082018-05-14 02:25:57618 const NetLogWithSource& net_log) override {
[email protected]2c2bef152010-10-13 00:55:03619 const scoped_refptr<TestSocketParams>* casted_params =
620 static_cast<const scoped_refptr<TestSocketParams>*>(params);
621
Charlie Harrison55ce6082018-05-14 02:25:57622 base_.RequestSockets(group_name, *casted_params, num_sockets, net_log);
[email protected]2c2bef152010-10-13 00:55:03623 }
624
rdsmith29dbad12017-02-17 02:22:18625 void SetPriority(const std::string& group_name,
626 ClientSocketHandle* handle,
627 RequestPriority priority) override {
628 base_.SetPriority(group_name, handle, priority);
629 }
630
dchengb03027d2014-10-21 12:00:20631 void CancelRequest(const std::string& group_name,
632 ClientSocketHandle* handle) override {
[email protected]d80a4322009-08-14 07:07:49633 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05634 }
635
dchengb03027d2014-10-21 12:00:20636 void ReleaseSocket(const std::string& group_name,
danakj655b66c2016-04-16 00:51:38637 std::unique_ptr<StreamSocket> socket,
dchengb03027d2014-10-21 12:00:20638 int id) override {
dchengc7eeda422015-12-26 03:56:48639 base_.ReleaseSocket(group_name, std::move(socket), id);
[email protected]a7e38572010-06-07 18:22:24640 }
641
dchengb03027d2014-10-21 12:00:20642 void FlushWithError(int error) override { base_.FlushWithError(error); }
[email protected]ab838892009-06-30 18:49:05643
dchengb03027d2014-10-21 12:00:20644 bool IsStalled() const override { return base_.IsStalled(); }
[email protected]51fdc7c2012-04-10 19:19:48645
dchengb03027d2014-10-21 12:00:20646 void CloseIdleSockets() override { base_.CloseIdleSockets(); }
[email protected]ab838892009-06-30 18:49:05647
xunjieli92feb332017-03-03 17:19:23648 void CloseIdleSocketsInGroup(const std::string& group_name) override {
649 base_.CloseIdleSocketsInGroup(group_name);
650 }
651
dchengb03027d2014-10-21 12:00:20652 int IdleSocketCount() const override { return base_.idle_socket_count(); }
[email protected]ab838892009-06-30 18:49:05653
Raul Tambre8335a6d2019-02-21 16:57:43654 size_t IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]d80a4322009-08-14 07:07:49655 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05656 }
657
dchengb03027d2014-10-21 12:00:20658 LoadState GetLoadState(const std::string& group_name,
659 const ClientSocketHandle* handle) const override {
[email protected]d80a4322009-08-14 07:07:49660 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05661 }
662
dchengb03027d2014-10-21 12:00:20663 void AddHigherLayeredPool(HigherLayeredPool* higher_pool) override {
[email protected]043b68c82013-08-22 23:41:52664 base_.AddHigherLayeredPool(higher_pool);
[email protected]51fdc7c2012-04-10 19:19:48665 }
666
dchengb03027d2014-10-21 12:00:20667 void RemoveHigherLayeredPool(HigherLayeredPool* higher_pool) override {
[email protected]043b68c82013-08-22 23:41:52668 base_.RemoveHigherLayeredPool(higher_pool);
[email protected]51fdc7c2012-04-10 19:19:48669 }
670
danakj655b66c2016-04-16 00:51:38671 std::unique_ptr<base::DictionaryValue> GetInfoAsValue(
[email protected]d4dfdab2011-12-07 16:56:59672 const std::string& name,
Matt Menke833678642019-03-05 22:05:51673 const std::string& type) const override {
[email protected]59d7a5a2010-08-30 16:44:27674 return base_.GetInfoAsValue(name, type);
675 }
676
[email protected]d80a4322009-08-14 07:07:49677 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20678
Raul Tambre8335a6d2019-02-21 16:57:43679 size_t NumNeverAssignedConnectJobsInGroup(
680 const std::string& group_name) const {
Lily Chenecebf932018-11-02 17:15:43681 return base_.NumNeverAssignedConnectJobsInGroup(group_name);
682 }
683
Raul Tambre8335a6d2019-02-21 16:57:43684 size_t NumUnassignedConnectJobsInGroup(const std::string& group_name) const {
[email protected]8159a1c2012-06-07 00:00:10685 return base_.NumUnassignedConnectJobsInGroup(group_name);
686 }
687
Raul Tambre8335a6d2019-02-21 16:57:43688 size_t NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49689 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34690 }
691
[email protected]2c2bef152010-10-13 00:55:03692 int NumActiveSocketsInGroup(const std::string& group_name) const {
693 return base_.NumActiveSocketsInGroup(group_name);
694 }
695
Lily Chenecebf932018-11-02 17:15:43696 bool RequestInGroupWithHandleHasJobForTesting(
697 const std::string& group_name,
698 const ClientSocketHandle* handle) const {
699 return base_.RequestInGroupWithHandleHasJobForTesting(group_name, handle);
700 }
701
[email protected]2abfe90a2010-08-25 17:49:51702 bool HasGroup(const std::string& group_name) const {
703 return base_.HasGroup(group_name);
704 }
705
[email protected]9bf28db2009-08-29 01:35:16706 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
707
[email protected]06d94042010-08-25 01:45:22708 void EnableConnectBackupJobs() { base_.EnableConnectBackupJobs(); }
[email protected]43a21b82010-06-10 21:30:54709
[email protected]ab838892009-06-30 18:49:05710 private:
[email protected]d80a4322009-08-14 07:07:49711 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05712
713 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
714};
715
[email protected]a937a06d2009-08-19 21:19:24716} // namespace
717
[email protected]a937a06d2009-08-19 21:19:24718namespace {
719
[email protected]5fc08e32009-07-15 17:09:57720void MockClientSocketFactory::SignalJobs() {
jdoerrie22a91d8b92018-10-05 08:43:26721 for (auto it = waiting_jobs_.begin(); it != waiting_jobs_.end(); ++it) {
[email protected]5fc08e32009-07-15 17:09:57722 (*it)->Signal();
723 }
724 waiting_jobs_.clear();
725}
726
[email protected]03b7c8c2013-07-20 04:38:55727void MockClientSocketFactory::SignalJob(size_t job) {
728 ASSERT_LT(job, waiting_jobs_.size());
729 waiting_jobs_[job]->Signal();
730 waiting_jobs_.erase(waiting_jobs_.begin() + job);
731}
732
733void MockClientSocketFactory::SetJobLoadState(size_t job,
734 LoadState load_state) {
735 ASSERT_LT(job, waiting_jobs_.size());
736 waiting_jobs_[job]->set_load_state(load_state);
737}
738
Matt Menke141b87f22019-01-30 02:43:03739void MockClientSocketFactory::SetJobHasEstablishedConnection(size_t job) {
740 ASSERT_LT(job, waiting_jobs_.size());
741 waiting_jobs_[job]->set_has_established_connection();
742}
743
Bence Béky98447b12018-05-08 03:14:01744class ClientSocketPoolBaseTest : public TestWithScopedTaskEnvironment {
[email protected]f6d1d6eb2009-06-24 20:16:09745 protected:
Alex Clarke0def2092018-12-10 12:01:45746 ClientSocketPoolBaseTest()
747 : TestWithScopedTaskEnvironment(
748 base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME),
749 params_(new TestSocketParams()) {
[email protected]636b8252011-04-08 19:56:54750 connect_backup_jobs_enabled_ =
751 internal::ClientSocketPoolBaseHelper::connect_backup_jobs_enabled();
752 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(true);
753 }
[email protected]2431756e2010-09-29 20:26:13754
dcheng67be2b1f2014-10-27 21:47:29755 ~ClientSocketPoolBaseTest() override {
[email protected]636b8252011-04-08 19:56:54756 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
757 connect_backup_jobs_enabled_);
758 }
[email protected]c9d6a1d2009-07-14 16:15:20759
[email protected]211d21722009-07-22 15:48:53760 void CreatePool(int max_sockets, int max_sockets_per_group) {
Tarun Bansala7635092019-02-20 10:00:59761 CreatePoolWithIdleTimeouts(max_sockets, max_sockets_per_group,
762 kUnusedIdleSocketTimeout,
763 ClientSocketPool::used_idle_socket_timeout());
[email protected]9bf28db2009-08-29 01:35:16764 }
765
766 void CreatePoolWithIdleTimeouts(
767 int max_sockets, int max_sockets_per_group,
768 base::TimeDelta unused_idle_socket_timeout,
769 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20770 DCHECK(!pool_.get());
[email protected]034df0f32013-01-07 23:17:48771 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_,
772 &net_log_);
[email protected]2431756e2010-09-29 20:26:13773 pool_.reset(new TestClientSocketPool(max_sockets,
774 max_sockets_per_group,
[email protected]2431756e2010-09-29 20:26:13775 unused_idle_socket_timeout,
776 used_idle_socket_timeout,
777 connect_job_factory_));
[email protected]c9d6a1d2009-07-14 16:15:20778 }
[email protected]f6d1d6eb2009-06-24 20:16:09779
mmenked3641e12016-01-28 16:06:15780 int StartRequestWithIgnoreLimits(
[email protected]b021ece62013-06-11 11:06:33781 const std::string& group_name,
782 RequestPriority priority,
mmenked3641e12016-01-28 16:06:15783 ClientSocketPool::RespectLimits respect_limits) {
784 return test_base_.StartRequestUsingPool(pool_.get(), group_name, priority,
785 respect_limits, params_);
[email protected]b021ece62013-06-11 11:06:33786 }
787
788 int StartRequest(const std::string& group_name, RequestPriority priority) {
mmenked3641e12016-01-28 16:06:15789 return StartRequestWithIgnoreLimits(
790 group_name, priority, ClientSocketPool::RespectLimits::ENABLED);
[email protected]f6d1d6eb2009-06-24 20:16:09791 }
792
[email protected]2431756e2010-09-29 20:26:13793 int GetOrderOfRequest(size_t index) const {
794 return test_base_.GetOrderOfRequest(index);
[email protected]f6d1d6eb2009-06-24 20:16:09795 }
796
[email protected]2431756e2010-09-29 20:26:13797 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
798 return test_base_.ReleaseOneConnection(keep_alive);
799 }
800
801 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
802 test_base_.ReleaseAllConnections(keep_alive);
803 }
804
805 TestSocketRequest* request(int i) { return test_base_.request(i); }
806 size_t requests_size() const { return test_base_.requests_size(); }
danakj655b66c2016-04-16 00:51:38807 std::vector<std::unique_ptr<TestSocketRequest>>* requests() {
olli.raula9d66b7d2015-11-23 08:30:42808 return test_base_.requests();
809 }
rdsmith29dbad12017-02-17 02:22:18810 // Only counts the requests that get sockets asynchronously;
811 // synchronous completions are not registered by this count.
[email protected]2431756e2010-09-29 20:26:13812 size_t completion_count() const { return test_base_.completion_count(); }
813
vishal.b62985ca92015-04-17 08:45:51814 TestNetLog net_log_;
[email protected]636b8252011-04-08 19:56:54815 bool connect_backup_jobs_enabled_;
[email protected]f6d1d6eb2009-06-24 20:16:09816 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04817 TestConnectJobFactory* connect_job_factory_;
[email protected]df4b4ef2010-07-12 18:25:21818 scoped_refptr<TestSocketParams> params_;
danakj655b66c2016-04-16 00:51:38819 std::unique_ptr<TestClientSocketPool> pool_;
[email protected]2431756e2010-09-29 20:26:13820 ClientSocketPoolTest test_base_;
[email protected]f6d1d6eb2009-06-24 20:16:09821};
822
[email protected]5fc08e32009-07-15 17:09:57823TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53824 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20825
[email protected]6ecf2b92011-12-15 01:14:52826 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06827 ClientSocketHandle handle;
vishal.b62985ca92015-04-17 08:45:51828 BoundTestNetLog log;
[email protected]034df0f32013-01-07 23:17:48829 TestLoadTimingInfoNotConnected(handle);
[email protected]9e743cd2010-03-16 07:03:53830
Paul Jensen8d6f87ec2018-01-13 00:46:54831 EXPECT_EQ(OK, handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:15832 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:50833 callback.callback(),
834 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
835 log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09836 EXPECT_TRUE(handle.is_initialized());
837 EXPECT_TRUE(handle.socket());
[email protected]034df0f32013-01-07 23:17:48838 TestLoadTimingInfoConnectedNotReused(handle);
839
[email protected]f6d1d6eb2009-06-24 20:16:09840 handle.Reset();
[email protected]034df0f32013-01-07 23:17:48841 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:30842
mmenke43758e62015-05-04 21:09:46843 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40844 log.GetEntries(&entries);
845
846 EXPECT_EQ(4u, entries.size());
mikecirone8b85c432016-09-08 19:11:00847 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKET_POOL));
[email protected]9e743cd2010-03-16 07:03:53848 EXPECT_TRUE(LogContainsEvent(
mikecirone8b85c432016-09-08 19:11:00849 entries, 1, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
850 NetLogEventPhase::NONE));
851 EXPECT_TRUE(LogContainsEvent(entries, 2,
852 NetLogEventType::SOCKET_POOL_BOUND_TO_SOCKET,
853 NetLogEventPhase::NONE));
854 EXPECT_TRUE(LogContainsEndEvent(entries, 3, NetLogEventType::SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09855}
856
[email protected]ab838892009-06-30 18:49:05857TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53858 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20859
[email protected]ab838892009-06-30 18:49:05860 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
vishal.b62985ca92015-04-17 08:45:51861 BoundTestNetLog log;
[email protected]9e743cd2010-03-16 07:03:53862
[email protected]2431756e2010-09-29 20:26:13863 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:52864 TestCompletionCallback callback;
[email protected]e60e47a2010-07-14 03:37:18865 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:13866 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43867 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:45868 info.headers = new HttpResponseHeaders(std::string());
[email protected]2431756e2010-09-29 20:26:13869 handle.set_ssl_error_response_info(info);
Matt Menke28ac03e2019-02-25 22:25:50870 EXPECT_EQ(
871 ERR_CONNECTION_FAILED,
872 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
873 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
874 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
875 log.bound()));
[email protected]2431756e2010-09-29 20:26:13876 EXPECT_FALSE(handle.socket());
877 EXPECT_FALSE(handle.is_ssl_error());
878 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]034df0f32013-01-07 23:17:48879 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:30880
mmenke43758e62015-05-04 21:09:46881 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40882 log.GetEntries(&entries);
883
884 EXPECT_EQ(3u, entries.size());
mikecirone8b85c432016-09-08 19:11:00885 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:17886 EXPECT_TRUE(LogContainsEvent(
mikecirone8b85c432016-09-08 19:11:00887 entries, 1, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
888 NetLogEventPhase::NONE));
889 EXPECT_TRUE(LogContainsEndEvent(entries, 2, NetLogEventType::SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09890}
891
[email protected]211d21722009-07-22 15:48:53892TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
893 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
894
[email protected]9e743cd2010-03-16 07:03:53895 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30896
robpercival214763f2016-07-01 23:27:01897 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
898 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
899 EXPECT_THAT(StartRequest("c", DEFAULT_PRIORITY), IsOk());
900 EXPECT_THAT(StartRequest("d", DEFAULT_PRIORITY), IsOk());
[email protected]211d21722009-07-22 15:48:53901
[email protected]2431756e2010-09-29 20:26:13902 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53903 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13904 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53905
robpercival214763f2016-07-01 23:27:01906 EXPECT_THAT(StartRequest("e", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
907 EXPECT_THAT(StartRequest("f", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
908 EXPECT_THAT(StartRequest("g", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:53909
[email protected]2431756e2010-09-29 20:26:13910 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53911
[email protected]2431756e2010-09-29 20:26:13912 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53913 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13914 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53915
916 EXPECT_EQ(1, GetOrderOfRequest(1));
917 EXPECT_EQ(2, GetOrderOfRequest(2));
918 EXPECT_EQ(3, GetOrderOfRequest(3));
919 EXPECT_EQ(4, GetOrderOfRequest(4));
920 EXPECT_EQ(5, GetOrderOfRequest(5));
921 EXPECT_EQ(6, GetOrderOfRequest(6));
922 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17923
924 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13925 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53926}
927
928TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
929 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
930
[email protected]9e743cd2010-03-16 07:03:53931 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30932
[email protected]211d21722009-07-22 15:48:53933 // Reach all limits: max total sockets, and max sockets per group.
robpercival214763f2016-07-01 23:27:01934 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
935 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
936 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
937 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
[email protected]211d21722009-07-22 15:48:53938
[email protected]2431756e2010-09-29 20:26:13939 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53940 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13941 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53942
943 // Now create a new group and verify that we don't starve it.
robpercival214763f2016-07-01 23:27:01944 EXPECT_THAT(StartRequest("c", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:53945
[email protected]2431756e2010-09-29 20:26:13946 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53947
[email protected]2431756e2010-09-29 20:26:13948 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53949 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13950 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53951
952 EXPECT_EQ(1, GetOrderOfRequest(1));
953 EXPECT_EQ(2, GetOrderOfRequest(2));
954 EXPECT_EQ(3, GetOrderOfRequest(3));
955 EXPECT_EQ(4, GetOrderOfRequest(4));
956 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17957
958 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13959 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53960}
961
962TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
963 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
964
robpercival214763f2016-07-01 23:27:01965 EXPECT_THAT(StartRequest("b", LOWEST), IsOk());
966 EXPECT_THAT(StartRequest("a", MEDIUM), IsOk());
967 EXPECT_THAT(StartRequest("b", HIGHEST), IsOk());
968 EXPECT_THAT(StartRequest("a", LOWEST), IsOk());
[email protected]211d21722009-07-22 15:48:53969
[email protected]2431756e2010-09-29 20:26:13970 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53971 client_socket_factory_.allocation_count());
972
robpercival214763f2016-07-01 23:27:01973 EXPECT_THAT(StartRequest("c", LOWEST), IsError(ERR_IO_PENDING));
974 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
975 EXPECT_THAT(StartRequest("b", HIGHEST), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:53976
[email protected]2431756e2010-09-29 20:26:13977 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53978
[email protected]2431756e2010-09-29 20:26:13979 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53980
981 // First 4 requests don't have to wait, and finish in order.
982 EXPECT_EQ(1, GetOrderOfRequest(1));
983 EXPECT_EQ(2, GetOrderOfRequest(2));
984 EXPECT_EQ(3, GetOrderOfRequest(3));
985 EXPECT_EQ(4, GetOrderOfRequest(4));
986
[email protected]ac790b42009-12-02 04:31:31987 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
988 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53989 EXPECT_EQ(7, GetOrderOfRequest(5));
990 EXPECT_EQ(6, GetOrderOfRequest(6));
991 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17992
993 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13994 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]211d21722009-07-22 15:48:53995}
996
rdsmith29dbad12017-02-17 02:22:18997// Test reprioritizing a request before completion doesn't interfere with
998// its completion.
999TEST_F(ClientSocketPoolBaseTest, ReprioritizeOne) {
1000 CreatePool(kDefaultMaxSockets, 1);
1001
1002 EXPECT_THAT(StartRequest("a", LOWEST), IsError(OK));
1003 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1004 EXPECT_TRUE(request(0)->handle()->socket());
1005 EXPECT_FALSE(request(1)->handle()->socket());
1006
Lily Chenecebf932018-11-02 17:15:431007 request(1)->handle()->SetPriority(HIGHEST);
rdsmith29dbad12017-02-17 02:22:181008
1009 ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE);
1010
1011 EXPECT_TRUE(request(1)->handle()->socket());
1012}
1013
1014// Reprioritize a request up past another one and make sure that changes the
1015// completion order.
1016TEST_F(ClientSocketPoolBaseTest, ReprioritizeUpReorder) {
1017 CreatePool(kDefaultMaxSockets, 1);
1018
1019 EXPECT_THAT(StartRequest("a", LOWEST), IsError(OK));
1020 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1021 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
1022 EXPECT_TRUE(request(0)->handle()->socket());
1023 EXPECT_FALSE(request(1)->handle()->socket());
1024 EXPECT_FALSE(request(2)->handle()->socket());
1025
1026 request(2)->handle()->SetPriority(HIGHEST);
1027
1028 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1029
1030 EXPECT_EQ(1, GetOrderOfRequest(1));
1031 EXPECT_EQ(3, GetOrderOfRequest(2));
1032 EXPECT_EQ(2, GetOrderOfRequest(3));
1033}
1034
1035// Reprioritize a request without changing relative priorities and check
1036// that the order doesn't change.
1037TEST_F(ClientSocketPoolBaseTest, ReprioritizeUpNoReorder) {
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", LOW), 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(MEDIUM);
1048
1049 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1050
1051 EXPECT_EQ(1, GetOrderOfRequest(1));
1052 EXPECT_EQ(2, GetOrderOfRequest(2));
1053 EXPECT_EQ(3, GetOrderOfRequest(3));
1054}
1055
1056// Reprioritize a request past down another one and make sure that changes the
1057// completion order.
1058TEST_F(ClientSocketPoolBaseTest, ReprioritizeDownReorder) {
1059 CreatePool(kDefaultMaxSockets, 1);
1060
1061 EXPECT_THAT(StartRequest("a", LOWEST), IsError(OK));
1062 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
1063 EXPECT_THAT(StartRequest("a", MEDIUM), 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(1)->handle()->SetPriority(LOW);
1069
1070 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1071
1072 EXPECT_EQ(1, GetOrderOfRequest(1));
1073 EXPECT_EQ(3, GetOrderOfRequest(2));
1074 EXPECT_EQ(2, GetOrderOfRequest(3));
1075}
1076
1077// Reprioritize a request to the same level as another and confirm it is
1078// put after the old request.
1079TEST_F(ClientSocketPoolBaseTest, ReprioritizeResetFIFO) {
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(MEDIUM);
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
[email protected]211d21722009-07-22 15:48:531098TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
1099 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1100
robpercival214763f2016-07-01 23:27:011101 EXPECT_THAT(StartRequest("a", LOWEST), IsOk());
1102 EXPECT_THAT(StartRequest("a", LOW), IsOk());
1103 EXPECT_THAT(StartRequest("b", HIGHEST), IsOk());
1104 EXPECT_THAT(StartRequest("b", MEDIUM), IsOk());
[email protected]211d21722009-07-22 15:48:531105
[email protected]2431756e2010-09-29 20:26:131106 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531107 client_socket_factory_.allocation_count());
1108
robpercival214763f2016-07-01 23:27:011109 EXPECT_THAT(StartRequest("c", MEDIUM), IsError(ERR_IO_PENDING));
1110 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1111 EXPECT_THAT(StartRequest("b", HIGHEST), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531112
[email protected]2431756e2010-09-29 20:26:131113 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531114
[email protected]2431756e2010-09-29 20:26:131115 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531116 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131117 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:531118
1119 // First 4 requests don't have to wait, and finish in order.
1120 EXPECT_EQ(1, GetOrderOfRequest(1));
1121 EXPECT_EQ(2, GetOrderOfRequest(2));
1122 EXPECT_EQ(3, GetOrderOfRequest(3));
1123 EXPECT_EQ(4, GetOrderOfRequest(4));
1124
1125 // Request ("b", 7) has the highest priority, but we can't make new socket for
1126 // group "b", because it has reached the per-group limit. Then we make
1127 // socket for ("c", 6), because it has higher priority than ("a", 4),
1128 // and we still can't make a socket for group "b".
1129 EXPECT_EQ(5, GetOrderOfRequest(5));
1130 EXPECT_EQ(6, GetOrderOfRequest(6));
1131 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171132
1133 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131134 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:531135}
1136
1137// Make sure that we count connecting sockets against the total limit.
1138TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
1139 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1140
robpercival214763f2016-07-01 23:27:011141 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1142 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
1143 EXPECT_THAT(StartRequest("c", DEFAULT_PRIORITY), IsOk());
[email protected]211d21722009-07-22 15:48:531144
1145 // Create one asynchronous request.
1146 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
robpercival214763f2016-07-01 23:27:011147 EXPECT_THAT(StartRequest("d", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531148
[email protected]6b175382009-10-13 06:47:471149 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1150 // actually become pending until 2ms after they have been created. In order
1151 // to flush all tasks, we need to wait so that we know there are no
1152 // soon-to-be-pending tasks waiting.
Alex Clarke0def2092018-12-10 12:01:451153 FastForwardBy(base::TimeDelta::FromMilliseconds(10));
[email protected]6b175382009-10-13 06:47:471154
[email protected]211d21722009-07-22 15:48:531155 // The next synchronous request should wait for its turn.
1156 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
robpercival214763f2016-07-01 23:27:011157 EXPECT_THAT(StartRequest("e", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]211d21722009-07-22 15:48:531158
[email protected]2431756e2010-09-29 20:26:131159 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531160
[email protected]2431756e2010-09-29 20:26:131161 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531162 client_socket_factory_.allocation_count());
1163
1164 EXPECT_EQ(1, GetOrderOfRequest(1));
1165 EXPECT_EQ(2, GetOrderOfRequest(2));
1166 EXPECT_EQ(3, GetOrderOfRequest(3));
1167 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:171168 EXPECT_EQ(5, GetOrderOfRequest(5));
1169
1170 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131171 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:531172}
1173
[email protected]6427fe22010-04-16 22:27:411174TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
1175 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1176 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1177
robpercival214763f2016-07-01 23:27:011178 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1179 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1180 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1181 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
[email protected]6427fe22010-04-16 22:27:411182
1183 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1184
1185 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1186
robpercival214763f2016-07-01 23:27:011187 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1188 EXPECT_THAT(StartRequest("c", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]6427fe22010-04-16 22:27:411189
1190 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1191
[email protected]2431756e2010-09-29 20:26:131192 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411193 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131194 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411195 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131196 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1197 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411198 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
1199}
1200
[email protected]d7027bb2010-05-10 18:58:541201TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
1202 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1203 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1204
1205 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521206 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:501207 EXPECT_EQ(
1208 ERR_IO_PENDING,
1209 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
1210 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1211 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
1212 NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:541213
1214 ClientSocketHandle handles[4];
Avi Drissman4365a4782018-12-28 19:26:241215 for (size_t i = 0; i < base::size(handles); ++i) {
[email protected]6ecf2b92011-12-15 01:14:521216 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:501217 EXPECT_EQ(ERR_IO_PENDING,
1218 handles[i].Init("b", params_, DEFAULT_PRIORITY, SocketTag(),
1219 ClientSocketPool::RespectLimits::ENABLED,
1220 callback.callback(),
1221 ClientSocketPool::ProxyAuthCallback(),
1222 pool_.get(), NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:541223 }
1224
1225 // One will be stalled, cancel all the handles now.
1226 // This should hit the OnAvailableSocketSlot() code where we previously had
1227 // stalled groups, but no longer have any.
Avi Drissman4365a4782018-12-28 19:26:241228 for (size_t i = 0; i < base::size(handles); ++i)
[email protected]d7027bb2010-05-10 18:58:541229 handles[i].Reset();
1230}
1231
[email protected]eb5a99382010-07-11 03:18:261232TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:541233 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1234 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1235
[email protected]eb5a99382010-07-11 03:18:261236 {
1237 ClientSocketHandle handles[kDefaultMaxSockets];
[email protected]6ecf2b92011-12-15 01:14:521238 TestCompletionCallback callbacks[kDefaultMaxSockets];
[email protected]eb5a99382010-07-11 03:18:261239 for (int i = 0; i < kDefaultMaxSockets; ++i) {
Raul Tambre8c1981d2019-02-08 02:22:261240 EXPECT_EQ(OK, handles[i].Init(base::NumberToString(i), params_,
Paul Jensen8d6f87ec2018-01-13 00:46:541241 DEFAULT_PRIORITY, SocketTag(),
1242 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501243 callbacks[i].callback(),
1244 ClientSocketPool::ProxyAuthCallback(),
1245 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261246 }
1247
1248 // Force a stalled group.
1249 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521250 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201251 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541252 stalled_handle.Init("foo", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:201253 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501254 callback.callback(),
1255 ClientSocketPool::ProxyAuthCallback(),
1256 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261257
1258 // Cancel the stalled request.
1259 stalled_handle.Reset();
1260
1261 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1262 EXPECT_EQ(0, pool_->IdleSocketCount());
1263
1264 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541265 }
1266
[email protected]43a21b82010-06-10 21:30:541267 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1268 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:261269}
[email protected]43a21b82010-06-10 21:30:541270
[email protected]eb5a99382010-07-11 03:18:261271TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
1272 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1273 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1274
1275 {
1276 ClientSocketHandle handles[kDefaultMaxSockets];
1277 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521278 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201279 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541280 handles[i].Init(
Raul Tambre8c1981d2019-02-08 02:22:261281 base::NumberToString(i), params_, DEFAULT_PRIORITY,
Paul Jensen8d6f87ec2018-01-13 00:46:541282 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501283 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1284 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261285 }
1286
1287 // Force a stalled group.
1288 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1289 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521290 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201291 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541292 stalled_handle.Init("foo", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:201293 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501294 callback.callback(),
1295 ClientSocketPool::ProxyAuthCallback(),
1296 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261297
1298 // Since it is stalled, it should have no connect jobs.
Raul Tambre8335a6d2019-02-21 16:57:431299 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("foo"));
1300 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("foo"));
1301 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261302
1303 // Cancel the stalled request.
1304 handles[0].Reset();
1305
[email protected]eb5a99382010-07-11 03:18:261306 // Now we should have a connect job.
Raul Tambre8335a6d2019-02-21 16:57:431307 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("foo"));
1308 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("foo"));
1309 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261310
1311 // The stalled socket should connect.
robpercival214763f2016-07-01 23:27:011312 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:261313
1314 EXPECT_EQ(kDefaultMaxSockets + 1,
1315 client_socket_factory_.allocation_count());
1316 EXPECT_EQ(0, pool_->IdleSocketCount());
Raul Tambre8335a6d2019-02-21 16:57:431317 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("foo"));
1318 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("foo"));
1319 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261320
1321 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541322 }
1323
[email protected]eb5a99382010-07-11 03:18:261324 EXPECT_EQ(1, pool_->IdleSocketCount());
1325}
[email protected]43a21b82010-06-10 21:30:541326
[email protected]eb5a99382010-07-11 03:18:261327TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1328 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1329 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:541330
[email protected]eb5a99382010-07-11 03:18:261331 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521332 TestCompletionCallback callback;
[email protected]eb5a99382010-07-11 03:18:261333 {
[email protected]51fdc7c2012-04-10 19:19:481334 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261335 ClientSocketHandle handles[kDefaultMaxSockets];
1336 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521337 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201338 EXPECT_EQ(OK, handles[i].Init(base::StringPrintf("Take 2: %d", i),
Paul Jensen8d6f87ec2018-01-13 00:46:541339 params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:201340 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501341 callback.callback(),
1342 ClientSocketPool::ProxyAuthCallback(),
1343 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:261344 }
1345
1346 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1347 EXPECT_EQ(0, pool_->IdleSocketCount());
[email protected]51fdc7c2012-04-10 19:19:481348 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261349
1350 // Now we will hit the socket limit.
tfarina428341112016-09-22 13:38:201351 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541352 stalled_handle.Init("foo", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:201353 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501354 callback.callback(),
1355 ClientSocketPool::ProxyAuthCallback(),
1356 pool_.get(), NetLogWithSource()));
[email protected]51fdc7c2012-04-10 19:19:481357 EXPECT_TRUE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261358
1359 // Dropping out of scope will close all handles and return them to idle.
1360 }
[email protected]43a21b82010-06-10 21:30:541361
1362 // But if we wait for it, the released idle sockets will be closed in
1363 // preference of the waiting request.
robpercival214763f2016-07-01 23:27:011364 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:261365
1366 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1367 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:541368}
1369
1370// Regression test for http://crbug.com/40952.
1371TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1372 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]06d94042010-08-25 01:45:221373 pool_->EnableConnectBackupJobs();
[email protected]43a21b82010-06-10 21:30:541374 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1375
1376 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1377 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521378 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:201379 EXPECT_EQ(
Matt Menke28ac03e2019-02-25 22:25:501380 OK,
1381 handle.Init(base::NumberToString(i), params_, DEFAULT_PRIORITY,
1382 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1383 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1384 pool_.get(), NetLogWithSource()));
[email protected]43a21b82010-06-10 21:30:541385 }
1386
1387 // Flush all the DoReleaseSocket tasks.
fdoray5eeb7642016-06-22 16:11:281388 base::RunLoop().RunUntilIdle();
[email protected]43a21b82010-06-10 21:30:541389
1390 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1391 // reuse a socket.
1392 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1393 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521394 TestCompletionCallback callback;
[email protected]43a21b82010-06-10 21:30:541395
1396 // "0" is special here, since it should be the first entry in the sorted map,
1397 // which is the one which we would close an idle socket for. We shouldn't
1398 // close an idle socket though, since we should reuse the idle socket.
Matt Menke28ac03e2019-02-25 22:25:501399 EXPECT_EQ(OK, handle.Init("0", params_, DEFAULT_PRIORITY, SocketTag(),
1400 ClientSocketPool::RespectLimits::ENABLED,
1401 callback.callback(),
1402 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
1403 NetLogWithSource()));
[email protected]43a21b82010-06-10 21:30:541404
1405 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1406 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1407}
1408
[email protected]ab838892009-06-30 18:49:051409TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531410 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091411
robpercival214763f2016-07-01 23:27:011412 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1413 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1414 EXPECT_THAT(StartRequest("a", IDLE), IsError(ERR_IO_PENDING));
1415 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
1416 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1417 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
1418 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1419 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091420
[email protected]2431756e2010-09-29 20:26:131421 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]c9d6a1d2009-07-14 16:15:201422 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1423 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131424 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1425 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091426
[email protected]c9d6a1d2009-07-14 16:15:201427 EXPECT_EQ(1, GetOrderOfRequest(1));
1428 EXPECT_EQ(2, GetOrderOfRequest(2));
[email protected]c9c6f5c2010-07-31 01:30:031429 EXPECT_EQ(8, GetOrderOfRequest(3));
1430 EXPECT_EQ(6, GetOrderOfRequest(4));
1431 EXPECT_EQ(4, GetOrderOfRequest(5));
1432 EXPECT_EQ(3, GetOrderOfRequest(6));
1433 EXPECT_EQ(5, GetOrderOfRequest(7));
1434 EXPECT_EQ(7, GetOrderOfRequest(8));
[email protected]75439d3b2009-07-23 22:11:171435
1436 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131437 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]f6d1d6eb2009-06-24 20:16:091438}
1439
[email protected]ab838892009-06-30 18:49:051440TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531441 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091442
robpercival214763f2016-07-01 23:27:011443 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1444 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1445 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
1446 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1447 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
1448 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1449 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091450
[email protected]2431756e2010-09-29 20:26:131451 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091452
[email protected]2431756e2010-09-29 20:26:131453 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
robpercival214763f2016-07-01 23:27:011454 EXPECT_THAT(request(i)->WaitForResult(), IsOk());
[email protected]c9d6a1d2009-07-14 16:15:201455
[email protected]2431756e2010-09-29 20:26:131456 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]c9d6a1d2009-07-14 16:15:201457 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131458 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1459 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091460}
1461
1462// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:051463// The pending connect job will be cancelled and should not call back into
1464// ClientSocketPoolBase.
1465TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531466 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201467
[email protected]ab838892009-06-30 18:49:051468 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131469 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521470 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:501471 EXPECT_EQ(
1472 ERR_IO_PENDING,
1473 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
1474 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1475 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
1476 NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:131477 handle.Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091478}
1479
[email protected]ab838892009-06-30 18:49:051480TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531481 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201482
[email protected]ab838892009-06-30 18:49:051483 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061484 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521485 TestCompletionCallback callback;
[email protected]f6d1d6eb2009-06-24 20:16:091486
Matt Menke28ac03e2019-02-25 22:25:501487 EXPECT_EQ(
1488 ERR_IO_PENDING,
1489 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
1490 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1491 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
1492 NetLogWithSource()));
[email protected]f6d1d6eb2009-06-24 20:16:091493
1494 handle.Reset();
1495
[email protected]6ecf2b92011-12-15 01:14:521496 TestCompletionCallback callback2;
Matt Menke28ac03e2019-02-25 22:25:501497 EXPECT_EQ(
1498 ERR_IO_PENDING,
1499 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
1500 ClientSocketPool::RespectLimits::ENABLED,
1501 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
1502 pool_.get(), NetLogWithSource()));
[email protected]f6d1d6eb2009-06-24 20:16:091503
robpercival214763f2016-07-01 23:27:011504 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]f6d1d6eb2009-06-24 20:16:091505 EXPECT_FALSE(callback.have_result());
1506
1507 handle.Reset();
1508}
1509
[email protected]ab838892009-06-30 18:49:051510TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531511 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091512
robpercival214763f2016-07-01 23:27:011513 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1514 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1515 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
1516 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1517 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
1518 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1519 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
[email protected]f6d1d6eb2009-06-24 20:16:091520
1521 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201522 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]2431756e2010-09-29 20:26:131523 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1524 (*requests())[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091525
[email protected]2431756e2010-09-29 20:26:131526 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091527
[email protected]c9d6a1d2009-07-14 16:15:201528 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1529 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131530 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1531 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091532
[email protected]c9d6a1d2009-07-14 16:15:201533 EXPECT_EQ(1, GetOrderOfRequest(1));
1534 EXPECT_EQ(2, GetOrderOfRequest(2));
1535 EXPECT_EQ(5, GetOrderOfRequest(3));
1536 EXPECT_EQ(3, GetOrderOfRequest(4));
[email protected]2431756e2010-09-29 20:26:131537 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1538 GetOrderOfRequest(5)); // Canceled request.
[email protected]c9d6a1d2009-07-14 16:15:201539 EXPECT_EQ(4, GetOrderOfRequest(6));
1540 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171541
1542 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131543 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091544}
1545
mmenke33d24423d2015-05-19 19:41:091546// Function to be used as a callback on socket request completion. It first
1547// disconnects the successfully connected socket from the first request, and
1548// then reuses the ClientSocketHandle to request another socket.
1549//
1550// |nested_callback| is called with the result of the second socket request.
1551void RequestSocketOnComplete(ClientSocketHandle* handle,
1552 TestClientSocketPool* pool,
1553 TestConnectJobFactory* test_connect_job_factory,
1554 TestConnectJob::JobType next_job_type,
Bence Békya4a50932018-08-10 13:39:411555 TestCompletionCallback* nested_callback,
mmenke33d24423d2015-05-19 19:41:091556 int first_request_result) {
robpercival214763f2016-07-01 23:27:011557 EXPECT_THAT(first_request_result, IsOk());
mmenke33d24423d2015-05-19 19:41:091558
1559 test_connect_job_factory->set_job_type(next_job_type);
1560
1561 // Don't allow reuse of the socket. Disconnect it and then release it.
1562 if (handle->socket())
1563 handle->socket()->Disconnect();
1564 handle->Reset();
1565
mmenked3641e12016-01-28 16:06:151566 scoped_refptr<TestSocketParams> params(new TestSocketParams());
mmenke33d24423d2015-05-19 19:41:091567 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:501568 int rv = handle->Init(
1569 "a", params, LOWEST, SocketTag(),
1570 ClientSocketPool::RespectLimits::ENABLED, nested_callback->callback(),
1571 ClientSocketPool::ProxyAuthCallback(), pool, NetLogWithSource());
mmenke33d24423d2015-05-19 19:41:091572 if (rv != ERR_IO_PENDING) {
1573 DCHECK_EQ(TestConnectJob::kMockJob, next_job_type);
Bence Békya4a50932018-08-10 13:39:411574 nested_callback->callback().Run(rv);
mmenke33d24423d2015-05-19 19:41:091575 } 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,
Matt Menke28ac03e2019-02-25 22:25:501592 base::BindOnce(&RequestSocketOnComplete, &handle, pool_.get(),
1593 connect_job_factory_, TestConnectJob::kMockPendingJob,
1594 &second_result_callback),
1595 ClientSocketPool::ProxyAuthCallback(), 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,
Matt Menke28ac03e2019-02-25 22:25:501613 base::BindOnce(&RequestSocketOnComplete, &handle, pool_.get(),
1614 connect_job_factory_, TestConnectJob::kMockPendingJob,
1615 &second_result_callback),
1616 ClientSocketPool::ProxyAuthCallback(), 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;
Matt Menke28ac03e2019-02-25 22:25:501701 int rv = handle.Init(
1702 "a", params_, DEFAULT_PRIORITY, SocketTag(),
1703 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1704 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011705 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:571706
1707 // Cancel the active request.
[email protected]2431756e2010-09-29 20:26:131708 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571709
Paul Jensen8d6f87ec2018-01-13 00:46:541710 rv = handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:151711 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501712 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1713 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011714 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1715 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]5fc08e32009-07-15 17:09:571716
[email protected]2431756e2010-09-29 20:26:131717 EXPECT_FALSE(handle.is_reused());
[email protected]034df0f32013-01-07 23:17:481718 TestLoadTimingInfoConnectedNotReused(handle);
[email protected]5fc08e32009-07-15 17:09:571719 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1720}
1721
xunjieli26619e72016-11-23 19:39:551722TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsForced) {
xunjieli26619e72016-11-23 19:39:551723 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1724 ClientSocketHandle handle;
1725 TestCompletionCallback callback;
1726 BoundTestNetLog log;
Matt Menke28ac03e2019-02-25 22:25:501727 int rv = handle.Init(
1728 "a", params_, LOWEST, SocketTag(),
1729 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1730 ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound());
xunjieli26619e72016-11-23 19:39:551731 EXPECT_THAT(rv, IsOk());
1732 handle.Reset();
1733 EXPECT_EQ(1, pool_->IdleSocketCount());
1734 pool_->CloseIdleSockets();
xunjieli26619e72016-11-23 19:39:551735}
1736
xunjieli92feb332017-03-03 17:19:231737TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsInGroupForced) {
xunjieli92feb332017-03-03 17:19:231738 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1739 TestCompletionCallback callback;
1740 BoundTestNetLog log;
1741 ClientSocketHandle handle1;
Matt Menke28ac03e2019-02-25 22:25:501742 int rv = handle1.Init(
1743 "a", params_, LOWEST, SocketTag(),
1744 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1745 ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound());
xunjieli92feb332017-03-03 17:19:231746 EXPECT_THAT(rv, IsOk());
1747 ClientSocketHandle handle2;
Paul Jensen8d6f87ec2018-01-13 00:46:541748 rv = handle2.Init("a", params_, LOWEST, SocketTag(),
xunjieli92feb332017-03-03 17:19:231749 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501750 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1751 pool_.get(), log.bound());
xunjieli92feb332017-03-03 17:19:231752 ClientSocketHandle handle3;
Paul Jensen8d6f87ec2018-01-13 00:46:541753 rv = handle3.Init("b", params_, LOWEST, SocketTag(),
xunjieli92feb332017-03-03 17:19:231754 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501755 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1756 pool_.get(), log.bound());
xunjieli92feb332017-03-03 17:19:231757 EXPECT_THAT(rv, IsOk());
1758 handle1.Reset();
1759 handle2.Reset();
1760 handle3.Reset();
1761 EXPECT_EQ(3, pool_->IdleSocketCount());
1762 pool_->CloseIdleSocketsInGroup("a");
1763 EXPECT_EQ(1, pool_->IdleSocketCount());
xunjieli92feb332017-03-03 17:19:231764}
1765
xunjieli26619e72016-11-23 19:39:551766TEST_F(ClientSocketPoolBaseTest, CleanUpUnusableIdleSockets) {
xunjieli26619e72016-11-23 19:39:551767 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1768 ClientSocketHandle handle;
1769 TestCompletionCallback callback;
1770 BoundTestNetLog log;
Matt Menke28ac03e2019-02-25 22:25:501771 int rv = handle.Init(
1772 "a", params_, LOWEST, SocketTag(),
1773 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1774 ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound());
xunjieli26619e72016-11-23 19:39:551775 EXPECT_THAT(rv, IsOk());
1776 StreamSocket* socket = handle.socket();
1777 handle.Reset();
1778 EXPECT_EQ(1, pool_->IdleSocketCount());
1779
1780 // Disconnect socket now to make the socket unusable.
1781 socket->Disconnect();
1782 ClientSocketHandle handle2;
Paul Jensen8d6f87ec2018-01-13 00:46:541783 rv = handle2.Init("a", params_, LOWEST, SocketTag(),
xunjieli26619e72016-11-23 19:39:551784 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501785 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1786 pool_.get(), log.bound());
xunjieli26619e72016-11-23 19:39:551787 EXPECT_THAT(rv, IsOk());
1788 EXPECT_FALSE(handle2.is_reused());
xunjieli26619e72016-11-23 19:39:551789}
1790
[email protected]2b7523d2009-07-29 20:29:231791// Regression test for http://crbug.com/17985.
1792TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1793 const int kMaxSockets = 3;
1794 const int kMaxSocketsPerGroup = 2;
1795 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1796
[email protected]ac790b42009-12-02 04:31:311797 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231798
robpercival214763f2016-07-01 23:27:011799 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1800 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
[email protected]2b7523d2009-07-29 20:29:231801
1802 // This is going to be a pending request in an otherwise empty group.
robpercival214763f2016-07-01 23:27:011803 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]2b7523d2009-07-29 20:29:231804
1805 // Reach the maximum socket limit.
robpercival214763f2016-07-01 23:27:011806 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
[email protected]2b7523d2009-07-29 20:29:231807
1808 // Create a stalled group with high priorities.
robpercival214763f2016-07-01 23:27:011809 EXPECT_THAT(StartRequest("c", kHighPriority), IsError(ERR_IO_PENDING));
1810 EXPECT_THAT(StartRequest("c", kHighPriority), IsError(ERR_IO_PENDING));
[email protected]2b7523d2009-07-29 20:29:231811
[email protected]eb5a99382010-07-11 03:18:261812 // Release the first two sockets from "a". Because this is a keepalive,
1813 // the first release will unblock the pending request for "a". The
1814 // second release will unblock a request for "c", becaue it is the next
1815 // high priority socket.
[email protected]2431756e2010-09-29 20:26:131816 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1817 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]2b7523d2009-07-29 20:29:231818
1819 // Closing idle sockets should not get us into trouble, but in the bug
1820 // we were hitting a CHECK here.
Raul Tambre8335a6d2019-02-21 16:57:431821 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]43a21b82010-06-10 21:30:541822 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261823
[email protected]2da659e2013-05-23 20:51:341824 // Run the released socket wakeups.
fdoray5eeb7642016-06-22 16:11:281825 base::RunLoop().RunUntilIdle();
[email protected]2b7523d2009-07-29 20:29:231826}
1827
[email protected]4d3b05d2010-01-27 21:27:291828TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531829 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571830
1831 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131832 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521833 TestCompletionCallback callback;
vishal.b62985ca92015-04-17 08:45:511834 BoundTestNetLog log;
Matt Menke28ac03e2019-02-25 22:25:501835 int rv = handle.Init(
1836 "a", params_, LOWEST, SocketTag(),
1837 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1838 ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound());
robpercival214763f2016-07-01 23:27:011839 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2431756e2010-09-29 20:26:131840 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
[email protected]034df0f32013-01-07 23:17:481841 TestLoadTimingInfoNotConnected(handle);
1842
robpercival214763f2016-07-01 23:27:011843 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:131844 EXPECT_TRUE(handle.is_initialized());
1845 EXPECT_TRUE(handle.socket());
[email protected]034df0f32013-01-07 23:17:481846 TestLoadTimingInfoConnectedNotReused(handle);
1847
[email protected]2431756e2010-09-29 20:26:131848 handle.Reset();
[email protected]034df0f32013-01-07 23:17:481849 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:301850
mmenke43758e62015-05-04 21:09:461851 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:401852 log.GetEntries(&entries);
1853
1854 EXPECT_EQ(4u, entries.size());
mikecirone8b85c432016-09-08 19:11:001855 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171856 EXPECT_TRUE(LogContainsEvent(
mikecirone8b85c432016-09-08 19:11:001857 entries, 1, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1858 NetLogEventPhase::NONE));
1859 EXPECT_TRUE(LogContainsEvent(entries, 2,
1860 NetLogEventType::SOCKET_POOL_BOUND_TO_SOCKET,
1861 NetLogEventPhase::NONE));
1862 EXPECT_TRUE(LogContainsEndEvent(entries, 3, NetLogEventType::SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571863}
1864
[email protected]4d3b05d2010-01-27 21:27:291865TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571866 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531867 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571868
1869 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2431756e2010-09-29 20:26:131870 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521871 TestCompletionCallback callback;
vishal.b62985ca92015-04-17 08:45:511872 BoundTestNetLog log;
[email protected]e60e47a2010-07-14 03:37:181873 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:131874 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:431875 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:451876 info.headers = new HttpResponseHeaders(std::string());
[email protected]2431756e2010-09-29 20:26:131877 handle.set_ssl_error_response_info(info);
Matt Menke28ac03e2019-02-25 22:25:501878 EXPECT_EQ(
1879 ERR_IO_PENDING,
1880 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
1881 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1882 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
1883 log.bound()));
[email protected]2431756e2010-09-29 20:26:131884 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
robpercival214763f2016-07-01 23:27:011885 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]2431756e2010-09-29 20:26:131886 EXPECT_FALSE(handle.is_ssl_error());
1887 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:301888
mmenke43758e62015-05-04 21:09:461889 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:401890 log.GetEntries(&entries);
1891
1892 EXPECT_EQ(3u, entries.size());
mikecirone8b85c432016-09-08 19:11:001893 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171894 EXPECT_TRUE(LogContainsEvent(
mikecirone8b85c432016-09-08 19:11:001895 entries, 1, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1896 NetLogEventPhase::NONE));
1897 EXPECT_TRUE(LogContainsEndEvent(entries, 2, NetLogEventType::SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571898}
1899
mmenke6be122f2015-03-09 22:22:471900// Check that an async ConnectJob failure does not result in creation of a new
1901// ConnectJob when there's another pending request also waiting on its own
1902// ConnectJob. See http://crbug.com/463960.
1903TEST_F(ClientSocketPoolBaseTest, AsyncFailureWithPendingRequestWithJob) {
1904 CreatePool(2, 2);
1905 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1906
robpercival214763f2016-07-01 23:27:011907 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1908 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
mmenke6be122f2015-03-09 22:22:471909
robpercival214763f2016-07-01 23:27:011910 EXPECT_THAT(request(0)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
1911 EXPECT_THAT(request(1)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
mmenke6be122f2015-03-09 22:22:471912
1913 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1914}
1915
[email protected]4d3b05d2010-01-27 21:27:291916TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101917 // TODO(eroman): Add back the log expectations! Removed them because the
1918 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531919 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571920
1921 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131922 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521923 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131924 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:521925 TestCompletionCallback callback2;
[email protected]5fc08e32009-07-15 17:09:571926
Matt Menke28ac03e2019-02-25 22:25:501927 EXPECT_EQ(
1928 ERR_IO_PENDING,
1929 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
1930 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1931 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
1932 NetLogWithSource()));
vishal.b62985ca92015-04-17 08:45:511933 BoundTestNetLog log2;
tfarina428341112016-09-22 13:38:201934 EXPECT_EQ(
1935 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:541936 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:201937 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:501938 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
1939 pool_.get(), NetLogWithSource()));
[email protected]5fc08e32009-07-15 17:09:571940
[email protected]2431756e2010-09-29 20:26:131941 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571942
[email protected]fd7b7c92009-08-20 19:38:301943
1944 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301945
robpercival214763f2016-07-01 23:27:011946 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:131947 handle2.Reset();
[email protected]fd7b7c92009-08-20 19:38:301948
1949 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531950 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571951}
1952
[email protected]4d3b05d2010-01-27 21:27:291953TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341954 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1955
[email protected]17a0c6c2009-08-04 00:07:041956 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1957
robpercival214763f2016-07-01 23:27:011958 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
1959 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1960 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1961 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
[email protected]974ebd62009-08-03 23:14:341962
Raul Tambre8335a6d2019-02-21 16:57:431963 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1964 static_cast<int>(pool_->NumConnectJobsInGroup("a")));
[email protected]2431756e2010-09-29 20:26:131965 (*requests())[2]->handle()->Reset();
1966 (*requests())[3]->handle()->Reset();
Raul Tambre8335a6d2019-02-21 16:57:431967 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1968 static_cast<int>(pool_->NumConnectJobsInGroup("a")));
[email protected]974ebd62009-08-03 23:14:341969
[email protected]2431756e2010-09-29 20:26:131970 (*requests())[1]->handle()->Reset();
Raul Tambre8335a6d2019-02-21 16:57:431971 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1972 static_cast<int>(pool_->NumConnectJobsInGroup("a")));
[email protected]974ebd62009-08-03 23:14:341973
[email protected]2431756e2010-09-29 20:26:131974 (*requests())[0]->handle()->Reset();
Raul Tambre8335a6d2019-02-21 16:57:431975 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1976 static_cast<int>(pool_->NumConnectJobsInGroup("a")));
[email protected]974ebd62009-08-03 23:14:341977}
1978
[email protected]5fc08e32009-07-15 17:09:571979// When requests and ConnectJobs are not coupled, the request will get serviced
1980// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291981TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531982 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571983
1984 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321985 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571986
[email protected]2431756e2010-09-29 20:26:131987 std::vector<TestSocketRequest*> request_order;
1988 size_t completion_count; // unused
1989 TestSocketRequest req1(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:501990 int rv = req1.handle()->Init(
1991 "a", params_, DEFAULT_PRIORITY, SocketTag(),
1992 ClientSocketPool::RespectLimits::ENABLED, req1.callback(),
1993 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011994 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1995 EXPECT_THAT(req1.WaitForResult(), IsOk());
[email protected]5fc08e32009-07-15 17:09:571996
1997 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1998 // without a job.
1999 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2000
[email protected]2431756e2010-09-29 20:26:132001 TestSocketRequest req2(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502002 rv = req2.handle()->Init(
2003 "a", params_, DEFAULT_PRIORITY, SocketTag(),
2004 ClientSocketPool::RespectLimits::ENABLED, req2.callback(),
2005 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012006 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2431756e2010-09-29 20:26:132007 TestSocketRequest req3(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502008 rv = req3.handle()->Init(
2009 "a", params_, DEFAULT_PRIORITY, SocketTag(),
2010 ClientSocketPool::RespectLimits::ENABLED, req3.callback(),
2011 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012012 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572013
2014 // Both Requests 2 and 3 are pending. We release socket 1 which should
2015 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:332016 req1.handle()->Reset();
[email protected]2da659e2013-05-23 20:51:342017 // Run the released socket wakeups.
fdoray5eeb7642016-06-22 16:11:282018 base::RunLoop().RunUntilIdle();
[email protected]a6c59f62009-07-29 16:33:332019 ASSERT_TRUE(req2.handle()->socket());
robpercival214763f2016-07-01 23:27:012020 EXPECT_THAT(req2.WaitForResult(), IsOk());
[email protected]a6c59f62009-07-29 16:33:332021 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:572022
2023 // Signal job 2, which should service request 3.
2024
2025 client_socket_factory_.SignalJobs();
robpercival214763f2016-07-01 23:27:012026 EXPECT_THAT(req3.WaitForResult(), IsOk());
[email protected]5fc08e32009-07-15 17:09:572027
Raul Tambre8335a6d2019-02-21 16:57:432028 ASSERT_EQ(3u, request_order.size());
[email protected]2431756e2010-09-29 20:26:132029 EXPECT_EQ(&req1, request_order[0]);
2030 EXPECT_EQ(&req2, request_order[1]);
2031 EXPECT_EQ(&req3, request_order[2]);
Raul Tambre8335a6d2019-02-21 16:57:432032 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]5fc08e32009-07-15 17:09:572033}
2034
2035// The requests are not coupled to the jobs. So, the requests should finish in
2036// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:292037TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:532038 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:572039 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:322040 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:572041
[email protected]2431756e2010-09-29 20:26:132042 std::vector<TestSocketRequest*> request_order;
2043 size_t completion_count; // unused
2044 TestSocketRequest req1(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502045 int rv = req1.handle()->Init(
2046 "a", params_, DEFAULT_PRIORITY, SocketTag(),
2047 ClientSocketPool::RespectLimits::ENABLED, req1.callback(),
2048 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012049 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572050
[email protected]2431756e2010-09-29 20:26:132051 TestSocketRequest req2(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502052 rv = req2.handle()->Init(
2053 "a", params_, DEFAULT_PRIORITY, SocketTag(),
2054 ClientSocketPool::RespectLimits::ENABLED, req2.callback(),
2055 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012056 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572057
2058 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:322059 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:572060
[email protected]2431756e2010-09-29 20:26:132061 TestSocketRequest req3(&request_order, &completion_count);
Matt Menke28ac03e2019-02-25 22:25:502062 rv = req3.handle()->Init(
2063 "a", params_, DEFAULT_PRIORITY, SocketTag(),
2064 ClientSocketPool::RespectLimits::ENABLED, req3.callback(),
2065 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012066 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]5fc08e32009-07-15 17:09:572067
robpercival214763f2016-07-01 23:27:012068 EXPECT_THAT(req1.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
2069 EXPECT_THAT(req2.WaitForResult(), IsOk());
2070 EXPECT_THAT(req3.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]5fc08e32009-07-15 17:09:572071
Raul Tambre8335a6d2019-02-21 16:57:432072 ASSERT_EQ(3u, request_order.size());
[email protected]2431756e2010-09-29 20:26:132073 EXPECT_EQ(&req1, request_order[0]);
2074 EXPECT_EQ(&req2, request_order[1]);
2075 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:572076}
2077
[email protected]03b7c8c2013-07-20 04:38:552078// Test GetLoadState in the case there's only one socket request.
2079TEST_F(ClientSocketPoolBaseTest, LoadStateOneRequest) {
[email protected]211d21722009-07-22 15:48:532080 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]03b7c8c2013-07-20 04:38:552081 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]5fc08e32009-07-15 17:09:572082
[email protected]2431756e2010-09-29 20:26:132083 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522084 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502085 int rv = handle.Init(
2086 "a", params_, DEFAULT_PRIORITY, SocketTag(),
2087 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2088 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012089 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552090 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:572091
[email protected]03b7c8c2013-07-20 04:38:552092 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2093 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
2094
2095 // No point in completing the connection, since ClientSocketHandles only
2096 // expect the LoadState to be checked while connecting.
2097}
2098
2099// Test GetLoadState in the case there are two socket requests.
2100TEST_F(ClientSocketPoolBaseTest, LoadStateTwoRequests) {
2101 CreatePool(2, 2);
2102 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2103
2104 ClientSocketHandle handle;
2105 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502106 int rv = handle.Init(
2107 "a", params_, DEFAULT_PRIORITY, SocketTag(),
2108 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2109 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012110 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
haavardm835c1d62015-04-22 08:18:002111 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
2112
2113 ClientSocketHandle handle2;
2114 TestCompletionCallback callback2;
Paul Jensen8d6f87ec2018-01-13 00:46:542115 rv = handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152116 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502117 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2118 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012119 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
haavardm835c1d62015-04-22 08:18:002120 client_socket_factory_.SetJobLoadState(1, LOAD_STATE_RESOLVING_HOST);
2121
Matt Menke4b69f932019-03-04 16:20:012122 // Each handle should reflect the state of its own job.
haavardm835c1d62015-04-22 08:18:002123 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle.GetLoadState());
2124 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle2.GetLoadState());
2125
Matt Menke4b69f932019-03-04 16:20:012126 // Update the state of the first job.
haavardm835c1d62015-04-22 08:18:002127 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_CONNECTING);
2128
Matt Menke4b69f932019-03-04 16:20:012129 // Only the state of the first request should have changed.
haavardm835c1d62015-04-22 08:18:002130 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
haavardm835c1d62015-04-22 08:18:002131 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle2.GetLoadState());
Matt Menke4b69f932019-03-04 16:20:012132
2133 // Update the state of the second job.
2134 client_socket_factory_.SetJobLoadState(1, LOAD_STATE_SSL_HANDSHAKE);
2135
2136 // Only the state of the second request should have changed.
2137 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2138 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle2.GetLoadState());
2139
2140 // Second job connects and the first request gets the socket. The
2141 // second handle switches to the state of the remaining ConnectJob.
2142 client_socket_factory_.SignalJob(1);
2143 EXPECT_THAT(callback.WaitForResult(), IsOk());
2144 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
[email protected]03b7c8c2013-07-20 04:38:552145}
2146
2147// Test GetLoadState in the case the per-group limit is reached.
2148TEST_F(ClientSocketPoolBaseTest, LoadStateGroupLimit) {
2149 CreatePool(2, 1);
2150 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2151
2152 ClientSocketHandle handle;
2153 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502154 int rv = handle.Init(
2155 "a", params_, MEDIUM, SocketTag(),
2156 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2157 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012158 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552159 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2160
2161 // Request another socket from the same pool, buth with a higher priority.
2162 // The first request should now be stalled at the socket group limit.
2163 ClientSocketHandle handle2;
2164 TestCompletionCallback callback2;
Paul Jensen8d6f87ec2018-01-13 00:46:542165 rv = handle2.Init("a", params_, HIGHEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152166 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502167 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2168 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012169 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552170 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2171 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
2172
2173 // The first handle should remain stalled as the other socket goes through
2174 // the connect process.
2175
2176 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2177 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2178 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle2.GetLoadState());
2179
2180 client_socket_factory_.SignalJob(0);
robpercival214763f2016-07-01 23:27:012181 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]03b7c8c2013-07-20 04:38:552182 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2183
2184 // Closing the second socket should cause the stalled handle to finally get a
2185 // ConnectJob.
2186 handle2.socket()->Disconnect();
2187 handle2.Reset();
2188 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2189}
2190
2191// Test GetLoadState in the case the per-pool limit is reached.
2192TEST_F(ClientSocketPoolBaseTest, LoadStatePoolLimit) {
2193 CreatePool(2, 2);
2194 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2195
2196 ClientSocketHandle handle;
2197 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502198 int rv = handle.Init(
2199 "a", params_, DEFAULT_PRIORITY, SocketTag(),
2200 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2201 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012202 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552203
2204 // Request for socket from another pool.
2205 ClientSocketHandle handle2;
2206 TestCompletionCallback callback2;
Paul Jensen8d6f87ec2018-01-13 00:46:542207 rv = handle2.Init("b", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152208 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502209 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2210 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012211 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552212
2213 // Request another socket from the first pool. Request should stall at the
2214 // socket pool limit.
2215 ClientSocketHandle handle3;
2216 TestCompletionCallback callback3;
Paul Jensen8d6f87ec2018-01-13 00:46:542217 rv = handle3.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
mmenked3641e12016-01-28 16:06:152218 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502219 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2220 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012221 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]03b7c8c2013-07-20 04:38:552222
2223 // The third handle should remain stalled as the other sockets in its group
2224 // goes through the connect process.
2225
2226 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2227 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2228
2229 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2230 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
2231 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2232
2233 client_socket_factory_.SignalJob(0);
robpercival214763f2016-07-01 23:27:012234 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]03b7c8c2013-07-20 04:38:552235 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2236
2237 // Closing a socket should allow the stalled handle to finally get a new
2238 // ConnectJob.
2239 handle.socket()->Disconnect();
2240 handle.Reset();
2241 EXPECT_EQ(LOAD_STATE_CONNECTING, handle3.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:572242}
2243
Matt Menkeb57663b32019-03-01 17:17:102244TEST_F(ClientSocketPoolBaseTest, CertError) {
[email protected]e772db3f2010-07-12 18:11:132245 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
Matt Menkeb57663b32019-03-01 17:17:102246 connect_job_factory_->set_job_type(TestConnectJob::kMockCertErrorJob);
[email protected]e772db3f2010-07-12 18:11:132247
[email protected]2431756e2010-09-29 20:26:132248 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522249 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502250 EXPECT_EQ(
Matt Menkeb57663b32019-03-01 17:17:102251 ERR_CERT_COMMON_NAME_INVALID,
Matt Menke28ac03e2019-02-25 22:25:502252 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2253 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2254 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2255 NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:132256 EXPECT_TRUE(handle.is_initialized());
2257 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:132258}
2259
Matt Menkeb57663b32019-03-01 17:17:102260TEST_F(ClientSocketPoolBaseTest, AsyncCertError) {
[email protected]e772db3f2010-07-12 18:11:132261 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2262
Matt Menkeb57663b32019-03-01 17:17:102263 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingCertErrorJob);
[email protected]2431756e2010-09-29 20:26:132264 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522265 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502266 EXPECT_EQ(
2267 ERR_IO_PENDING,
2268 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2269 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2270 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2271 NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:132272 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
Matt Menkeb57663b32019-03-01 17:17:102273 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CERT_COMMON_NAME_INVALID));
[email protected]2431756e2010-09-29 20:26:132274 EXPECT_TRUE(handle.is_initialized());
2275 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:132276}
2277
[email protected]e60e47a2010-07-14 03:37:182278TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
2279 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2280 connect_job_factory_->set_job_type(
2281 TestConnectJob::kMockAdditionalErrorStateJob);
2282
[email protected]2431756e2010-09-29 20:26:132283 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522284 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502285 EXPECT_EQ(
2286 ERR_CONNECTION_FAILED,
2287 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2288 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2289 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2290 NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:132291 EXPECT_FALSE(handle.is_initialized());
2292 EXPECT_FALSE(handle.socket());
2293 EXPECT_TRUE(handle.is_ssl_error());
2294 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182295}
2296
2297TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
2298 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2299
2300 connect_job_factory_->set_job_type(
2301 TestConnectJob::kMockPendingAdditionalErrorStateJob);
[email protected]2431756e2010-09-29 20:26:132302 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522303 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502304 EXPECT_EQ(
2305 ERR_IO_PENDING,
2306 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2307 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2308 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2309 NetLogWithSource()));
[email protected]2431756e2010-09-29 20:26:132310 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
robpercival214763f2016-07-01 23:27:012311 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]2431756e2010-09-29 20:26:132312 EXPECT_FALSE(handle.is_initialized());
2313 EXPECT_FALSE(handle.socket());
2314 EXPECT_TRUE(handle.is_ssl_error());
2315 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182316}
2317
martijn003cd612016-05-19 22:24:382318// Make sure we can reuse sockets.
2319TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSocketsReuse) {
[email protected]64770b7d2011-11-16 04:30:412320 CreatePoolWithIdleTimeouts(
2321 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
[email protected]e7b1c6d2c2012-05-05 00:54:032322 base::TimeDelta(), // Time out unused sockets immediately.
2323 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2324
2325 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2326
2327 ClientSocketHandle handle;
2328 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502329 int rv = handle.Init(
2330 "a", params_, LOWEST, SocketTag(),
2331 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2332 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012333 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e7b1c6d2c2012-05-05 00:54:032334 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
robpercival214763f2016-07-01 23:27:012335 ASSERT_THAT(callback.WaitForResult(), IsOk());
[email protected]e7b1c6d2c2012-05-05 00:54:032336
2337 // Use and release the socket.
Bence Békybdbb0e72018-08-07 21:42:592338 EXPECT_EQ(1, handle.socket()->Write(NULL, 1, CompletionOnceCallback(),
Ramin Halavati0a08cc82018-02-06 07:46:382339 TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]034df0f32013-01-07 23:17:482340 TestLoadTimingInfoConnectedNotReused(handle);
[email protected]e7b1c6d2c2012-05-05 00:54:032341 handle.Reset();
2342
2343 // Should now have one idle socket.
2344 ASSERT_EQ(1, pool_->IdleSocketCount());
2345
2346 // Request a new socket. This should reuse the old socket and complete
2347 // synchronously.
vishal.b62985ca92015-04-17 08:45:512348 BoundTestNetLog log;
Matt Menke28ac03e2019-02-25 22:25:502349 rv = handle.Init(
2350 "a", params_, LOWEST, SocketTag(),
2351 ClientSocketPool::RespectLimits::ENABLED, CompletionOnceCallback(),
2352 ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound());
robpercival214763f2016-07-01 23:27:012353 ASSERT_THAT(rv, IsOk());
[email protected]e7b1c6d2c2012-05-05 00:54:032354 EXPECT_TRUE(handle.is_reused());
[email protected]034df0f32013-01-07 23:17:482355 TestLoadTimingInfoConnectedReused(handle);
[email protected]e7b1c6d2c2012-05-05 00:54:032356
2357 ASSERT_TRUE(pool_->HasGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:432358 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]e7b1c6d2c2012-05-05 00:54:032359 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2360
mmenke43758e62015-05-04 21:09:462361 TestNetLogEntry::List entries;
[email protected]e7b1c6d2c2012-05-05 00:54:032362 log.GetEntries(&entries);
2363 EXPECT_TRUE(LogContainsEntryWithType(
mikecirone8b85c432016-09-08 19:11:002364 entries, 1, NetLogEventType::SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]e7b1c6d2c2012-05-05 00:54:032365}
2366
martijn003cd612016-05-19 22:24:382367// Make sure we cleanup old unused sockets.
Eric Romanb49715e2018-04-24 22:41:172368TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSocketsNoReuse) {
[email protected]e7b1c6d2c2012-05-05 00:54:032369 CreatePoolWithIdleTimeouts(
2370 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2371 base::TimeDelta(), // Time out unused sockets immediately
2372 base::TimeDelta()); // Time out used sockets immediately
[email protected]64770b7d2011-11-16 04:30:412373
2374 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2375
2376 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2377
2378 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522379 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502380 int rv = handle.Init(
2381 "a", params_, LOWEST, SocketTag(),
2382 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2383 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012384 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]64770b7d2011-11-16 04:30:412385 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2386
2387 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522388 TestCompletionCallback callback2;
Paul Jensen8d6f87ec2018-01-13 00:46:542389 rv = handle2.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152390 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502391 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2392 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012393 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]64770b7d2011-11-16 04:30:412394 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
2395
2396 // Cancel one of the requests. Wait for the other, which will get the first
2397 // job. Release the socket. Run the loop again to make sure the second
2398 // socket is sitting idle and the first one is released (since ReleaseSocket()
2399 // just posts a DoReleaseSocket() task).
2400
2401 handle.Reset();
robpercival214763f2016-07-01 23:27:012402 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]64770b7d2011-11-16 04:30:412403 // Use the socket.
Bence Békybdbb0e72018-08-07 21:42:592404 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, CompletionOnceCallback(),
Ramin Halavati0a08cc82018-02-06 07:46:382405 TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]64770b7d2011-11-16 04:30:412406 handle2.Reset();
2407
[email protected]e7b1c6d2c2012-05-05 00:54:032408 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2409 // actually become pending until 2ms after they have been created. In order
2410 // to flush all tasks, we need to wait so that we know there are no
2411 // soon-to-be-pending tasks waiting.
Alex Clarke0def2092018-12-10 12:01:452412 FastForwardBy(base::TimeDelta::FromMilliseconds(10));
[email protected]64770b7d2011-11-16 04:30:412413
[email protected]e7b1c6d2c2012-05-05 00:54:032414 // Both sockets should now be idle.
[email protected]64770b7d2011-11-16 04:30:412415 ASSERT_EQ(2, pool_->IdleSocketCount());
2416
2417 // Request a new socket. This should cleanup the unused and timed out ones.
2418 // A new socket will be created rather than reusing the idle one.
vishal.b62985ca92015-04-17 08:45:512419 BoundTestNetLog log;
[email protected]6ecf2b92011-12-15 01:14:522420 TestCompletionCallback callback3;
Paul Jensen8d6f87ec2018-01-13 00:46:542421 rv = handle.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152422 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502423 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
2424 pool_.get(), log.bound());
robpercival214763f2016-07-01 23:27:012425 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
2426 ASSERT_THAT(callback3.WaitForResult(), IsOk());
[email protected]64770b7d2011-11-16 04:30:412427 EXPECT_FALSE(handle.is_reused());
2428
[email protected]e7b1c6d2c2012-05-05 00:54:032429 // Make sure the idle socket is closed.
[email protected]64770b7d2011-11-16 04:30:412430 ASSERT_TRUE(pool_->HasGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:432431 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]64770b7d2011-11-16 04:30:412432 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2433
mmenke43758e62015-05-04 21:09:462434 TestNetLogEntry::List entries;
[email protected]64770b7d2011-11-16 04:30:412435 log.GetEntries(&entries);
2436 EXPECT_FALSE(LogContainsEntryWithType(
mikecirone8b85c432016-09-08 19:11:002437 entries, 1, NetLogEventType::SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]64770b7d2011-11-16 04:30:412438}
2439
[email protected]2041cf342010-02-19 03:15:592440// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:162441// because of multiple releasing disconnected sockets.
2442TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
2443 CreatePoolWithIdleTimeouts(
2444 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2445 base::TimeDelta(), // Time out unused sockets immediately.
2446 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2447
2448 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2449
2450 // Startup 4 connect jobs. Two of them will be pending.
2451
[email protected]2431756e2010-09-29 20:26:132452 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522453 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502454 int rv = handle.Init(
2455 "a", params_, LOWEST, SocketTag(),
2456 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2457 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012458 EXPECT_THAT(rv, IsOk());
[email protected]4f2abec2010-02-03 18:10:162459
[email protected]2431756e2010-09-29 20:26:132460 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522461 TestCompletionCallback callback2;
Paul Jensen8d6f87ec2018-01-13 00:46:542462 rv = handle2.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152463 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502464 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2465 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012466 EXPECT_THAT(rv, IsOk());
[email protected]4f2abec2010-02-03 18:10:162467
[email protected]2431756e2010-09-29 20:26:132468 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:522469 TestCompletionCallback callback3;
Paul Jensen8d6f87ec2018-01-13 00:46:542470 rv = handle3.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152471 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502472 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
2473 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012474 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4f2abec2010-02-03 18:10:162475
[email protected]2431756e2010-09-29 20:26:132476 ClientSocketHandle handle4;
[email protected]6ecf2b92011-12-15 01:14:522477 TestCompletionCallback callback4;
Paul Jensen8d6f87ec2018-01-13 00:46:542478 rv = handle4.Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152479 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502480 callback4.callback(), ClientSocketPool::ProxyAuthCallback(),
2481 pool_.get(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012482 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4f2abec2010-02-03 18:10:162483
2484 // Release two disconnected sockets.
2485
[email protected]2431756e2010-09-29 20:26:132486 handle.socket()->Disconnect();
2487 handle.Reset();
2488 handle2.socket()->Disconnect();
2489 handle2.Reset();
[email protected]4f2abec2010-02-03 18:10:162490
robpercival214763f2016-07-01 23:27:012491 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132492 EXPECT_FALSE(handle3.is_reused());
robpercival214763f2016-07-01 23:27:012493 EXPECT_THAT(callback4.WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132494 EXPECT_FALSE(handle4.is_reused());
[email protected]4f2abec2010-02-03 18:10:162495}
2496
[email protected]d7027bb2010-05-10 18:58:542497// Regression test for http://crbug.com/42267.
2498// When DoReleaseSocket() is processed for one socket, it is blocked because the
2499// other stalled groups all have releasing sockets, so no progress can be made.
2500TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
2501 CreatePoolWithIdleTimeouts(
2502 4 /* socket limit */, 4 /* socket limit per group */,
2503 base::TimeDelta(), // Time out unused sockets immediately.
2504 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2505
2506 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2507
2508 // Max out the socket limit with 2 per group.
2509
[email protected]2431756e2010-09-29 20:26:132510 ClientSocketHandle handle_a[4];
[email protected]6ecf2b92011-12-15 01:14:522511 TestCompletionCallback callback_a[4];
[email protected]2431756e2010-09-29 20:26:132512 ClientSocketHandle handle_b[4];
[email protected]6ecf2b92011-12-15 01:14:522513 TestCompletionCallback callback_b[4];
[email protected]d7027bb2010-05-10 18:58:542514
2515 for (int i = 0; i < 2; ++i) {
Paul Jensen8d6f87ec2018-01-13 00:46:542516 EXPECT_EQ(OK, handle_a[i].Init("a", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152517 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502518 callback_a[i].callback(),
2519 ClientSocketPool::ProxyAuthCallback(),
2520 pool_.get(), NetLogWithSource()));
Paul Jensen8d6f87ec2018-01-13 00:46:542521 EXPECT_EQ(OK, handle_b[i].Init("b", params_, LOWEST, SocketTag(),
mmenked3641e12016-01-28 16:06:152522 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502523 callback_b[i].callback(),
2524 ClientSocketPool::ProxyAuthCallback(),
2525 pool_.get(), NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:542526 }
[email protected]b89f7e42010-05-20 20:37:002527
[email protected]d7027bb2010-05-10 18:58:542528 // Make 4 pending requests, 2 per group.
2529
2530 for (int i = 2; i < 4; ++i) {
tfarina428341112016-09-22 13:38:202531 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542532 handle_a[i].Init("a", params_, LOWEST, SocketTag(),
tfarina428341112016-09-22 13:38:202533 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502534 callback_a[i].callback(),
2535 ClientSocketPool::ProxyAuthCallback(),
2536 pool_.get(), NetLogWithSource()));
tfarina428341112016-09-22 13:38:202537 EXPECT_EQ(ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542538 handle_b[i].Init("b", params_, LOWEST, SocketTag(),
tfarina428341112016-09-22 13:38:202539 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502540 callback_b[i].callback(),
2541 ClientSocketPool::ProxyAuthCallback(),
2542 pool_.get(), NetLogWithSource()));
[email protected]d7027bb2010-05-10 18:58:542543 }
2544
2545 // Release b's socket first. The order is important, because in
2546 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2547 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2548 // first, which has a releasing socket, so it refuses to start up another
2549 // ConnectJob. So, we used to infinite loop on this.
[email protected]2431756e2010-09-29 20:26:132550 handle_b[0].socket()->Disconnect();
2551 handle_b[0].Reset();
2552 handle_a[0].socket()->Disconnect();
2553 handle_a[0].Reset();
[email protected]d7027bb2010-05-10 18:58:542554
2555 // Used to get stuck here.
fdoray5eeb7642016-06-22 16:11:282556 base::RunLoop().RunUntilIdle();
[email protected]d7027bb2010-05-10 18:58:542557
[email protected]2431756e2010-09-29 20:26:132558 handle_b[1].socket()->Disconnect();
2559 handle_b[1].Reset();
2560 handle_a[1].socket()->Disconnect();
2561 handle_a[1].Reset();
[email protected]d7027bb2010-05-10 18:58:542562
2563 for (int i = 2; i < 4; ++i) {
robpercival214763f2016-07-01 23:27:012564 EXPECT_THAT(callback_b[i].WaitForResult(), IsOk());
2565 EXPECT_THAT(callback_a[i].WaitForResult(), IsOk());
[email protected]d7027bb2010-05-10 18:58:542566 }
2567}
2568
[email protected]fd4fe0b2010-02-08 23:02:152569TEST_F(ClientSocketPoolBaseTest,
2570 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2571 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2572
2573 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2574
robpercival214763f2016-07-01 23:27:012575 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
2576 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
2577 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
2578 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
[email protected]fd4fe0b2010-02-08 23:02:152579
robpercival214763f2016-07-01 23:27:012580 EXPECT_THAT((*requests())[0]->WaitForResult(), IsOk());
2581 EXPECT_THAT((*requests())[1]->WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132582 EXPECT_EQ(2u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152583
2584 // Releases one connection.
[email protected]2431756e2010-09-29 20:26:132585 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
robpercival214763f2016-07-01 23:27:012586 EXPECT_THAT((*requests())[2]->WaitForResult(), IsOk());
[email protected]fd4fe0b2010-02-08 23:02:152587
[email protected]2431756e2010-09-29 20:26:132588 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
robpercival214763f2016-07-01 23:27:012589 EXPECT_THAT((*requests())[3]->WaitForResult(), IsOk());
[email protected]2431756e2010-09-29 20:26:132590 EXPECT_EQ(4u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152591
2592 EXPECT_EQ(1, GetOrderOfRequest(1));
2593 EXPECT_EQ(2, GetOrderOfRequest(2));
2594 EXPECT_EQ(3, GetOrderOfRequest(3));
2595 EXPECT_EQ(4, GetOrderOfRequest(4));
2596
2597 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:132598 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
[email protected]fd4fe0b2010-02-08 23:02:152599}
2600
[email protected]6ecf2b92011-12-15 01:14:522601class TestReleasingSocketRequest : public TestCompletionCallbackBase {
[email protected]4f1e4982010-03-02 18:31:042602 public:
[email protected]2431756e2010-09-29 20:26:132603 TestReleasingSocketRequest(TestClientSocketPool* pool,
2604 int expected_result,
[email protected]e60e47a2010-07-14 03:37:182605 bool reset_releasing_handle)
2606 : pool_(pool),
2607 expected_result_(expected_result),
Bence Béky8ddc2492018-06-13 01:02:042608 reset_releasing_handle_(reset_releasing_handle) {}
[email protected]6ecf2b92011-12-15 01:14:522609
Chris Watkins7a41d3552017-12-01 02:13:272610 ~TestReleasingSocketRequest() override = default;
[email protected]4f1e4982010-03-02 18:31:042611
2612 ClientSocketHandle* handle() { return &handle_; }
2613
Bence Béky8ddc2492018-06-13 01:02:042614 CompletionOnceCallback callback() {
2615 return base::BindOnce(&TestReleasingSocketRequest::OnComplete,
2616 base::Unretained(this));
2617 }
[email protected]4f1e4982010-03-02 18:31:042618
2619 private:
[email protected]6ecf2b92011-12-15 01:14:522620 void OnComplete(int result) {
2621 SetResult(result);
2622 if (reset_releasing_handle_)
2623 handle_.Reset();
2624
mmenked3641e12016-01-28 16:06:152625 scoped_refptr<TestSocketParams> con_params(new TestSocketParams());
Matt Menke28ac03e2019-02-25 22:25:502626 EXPECT_EQ(expected_result_,
2627 handle2_.Init("a", con_params, DEFAULT_PRIORITY, SocketTag(),
2628 ClientSocketPool::RespectLimits::ENABLED,
2629 CompletionOnceCallback(),
2630 ClientSocketPool::ProxyAuthCallback(), pool_,
2631 NetLogWithSource()));
[email protected]6ecf2b92011-12-15 01:14:522632 }
2633
[email protected]2431756e2010-09-29 20:26:132634 TestClientSocketPool* const pool_;
[email protected]e60e47a2010-07-14 03:37:182635 int expected_result_;
2636 bool reset_releasing_handle_;
[email protected]4f1e4982010-03-02 18:31:042637 ClientSocketHandle handle_;
2638 ClientSocketHandle handle2_;
[email protected]4f1e4982010-03-02 18:31:042639};
2640
[email protected]e60e47a2010-07-14 03:37:182641
2642TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2643 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2644
robpercival214763f2016-07-01 23:27:012645 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
2646 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
2647 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
[email protected]e60e47a2010-07-14 03:37:182648
[email protected]2431756e2010-09-29 20:26:132649 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]e60e47a2010-07-14 03:37:182650 client_socket_factory_.allocation_count());
2651
2652 connect_job_factory_->set_job_type(
2653 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2654 TestReleasingSocketRequest req(pool_.get(), OK, false);
tfarina428341112016-09-22 13:38:202655 EXPECT_EQ(
2656 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542657 req.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:202658 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502659 req.callback(), ClientSocketPool::ProxyAuthCallback(),
2660 pool_.get(), NetLogWithSource()));
[email protected]e60e47a2010-07-14 03:37:182661 // The next job should complete synchronously
2662 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2663
robpercival214763f2016-07-01 23:27:012664 EXPECT_THAT(req.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:182665 EXPECT_FALSE(req.handle()->is_initialized());
2666 EXPECT_FALSE(req.handle()->socket());
2667 EXPECT_TRUE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:432668 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182669}
2670
[email protected]b6501d3d2010-06-03 23:53:342671// http://crbug.com/44724 regression test.
2672// We start releasing the pool when we flush on network change. When that
2673// happens, the only active references are in the ClientSocketHandles. When a
2674// ConnectJob completes and calls back into the last ClientSocketHandle, that
2675// callback can release the last reference and delete the pool. After the
2676// callback finishes, we go back to the stack frame within the now-deleted pool.
2677// Executing any code that refers to members of the now-deleted pool can cause
2678// crashes.
2679TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2680 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2681 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2682
2683 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522684 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502685 EXPECT_EQ(
2686 ERR_IO_PENDING,
2687 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2688 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2689 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2690 NetLogWithSource()));
[email protected]b6501d3d2010-06-03 23:53:342691
[email protected]7af985a2012-12-14 22:40:422692 pool_->FlushWithError(ERR_NETWORK_CHANGED);
[email protected]b6501d3d2010-06-03 23:53:342693
2694 // We'll call back into this now.
2695 callback.WaitForResult();
2696}
2697
[email protected]a7e38572010-06-07 18:22:242698TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2699 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2700 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2701
2702 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522703 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502704 EXPECT_EQ(
2705 ERR_IO_PENDING,
2706 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2707 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2708 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2709 NetLogWithSource()));
robpercival214763f2016-07-01 23:27:012710 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]a7e38572010-06-07 18:22:242711 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2712
[email protected]7af985a2012-12-14 22:40:422713 pool_->FlushWithError(ERR_NETWORK_CHANGED);
[email protected]a7e38572010-06-07 18:22:242714
2715 handle.Reset();
fdoray5eeb7642016-06-22 16:11:282716 base::RunLoop().RunUntilIdle();
[email protected]a7e38572010-06-07 18:22:242717
Matt Menke28ac03e2019-02-25 22:25:502718 EXPECT_EQ(
2719 ERR_IO_PENDING,
2720 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2721 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2722 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2723 NetLogWithSource()));
robpercival214763f2016-07-01 23:27:012724 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]a7e38572010-06-07 18:22:242725 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2726}
2727
[email protected]6ecf2b92011-12-15 01:14:522728class ConnectWithinCallback : public TestCompletionCallbackBase {
[email protected]06f92462010-08-31 19:24:142729 public:
Bence Béky8ddc2492018-06-13 01:02:042730 ConnectWithinCallback(const std::string& group_name,
2731 const scoped_refptr<TestSocketParams>& params,
2732 TestClientSocketPool* pool)
2733 : group_name_(group_name), params_(params), pool_(pool) {}
[email protected]06f92462010-08-31 19:24:142734
Chris Watkins7a41d3552017-12-01 02:13:272735 ~ConnectWithinCallback() override = default;
[email protected]06f92462010-08-31 19:24:142736
2737 int WaitForNestedResult() {
2738 return nested_callback_.WaitForResult();
2739 }
2740
Bence Béky8ddc2492018-06-13 01:02:042741 CompletionOnceCallback callback() {
2742 return base::BindOnce(&ConnectWithinCallback::OnComplete,
2743 base::Unretained(this));
2744 }
[email protected]6ecf2b92011-12-15 01:14:522745
[email protected]06f92462010-08-31 19:24:142746 private:
[email protected]6ecf2b92011-12-15 01:14:522747 void OnComplete(int result) {
2748 SetResult(result);
Matt Menke28ac03e2019-02-25 22:25:502749 EXPECT_EQ(ERR_IO_PENDING,
2750 handle_.Init(group_name_, params_, DEFAULT_PRIORITY, SocketTag(),
2751 ClientSocketPool::RespectLimits::ENABLED,
2752 nested_callback_.callback(),
2753 ClientSocketPool::ProxyAuthCallback(), pool_,
2754 NetLogWithSource()));
[email protected]6ecf2b92011-12-15 01:14:522755 }
2756
[email protected]06f92462010-08-31 19:24:142757 const std::string group_name_;
2758 const scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:132759 TestClientSocketPool* const pool_;
[email protected]06f92462010-08-31 19:24:142760 ClientSocketHandle handle_;
[email protected]6ecf2b92011-12-15 01:14:522761 TestCompletionCallback nested_callback_;
2762
2763 DISALLOW_COPY_AND_ASSIGN(ConnectWithinCallback);
[email protected]06f92462010-08-31 19:24:142764};
2765
2766TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
2767 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2768
2769 // First job will be waiting until it gets aborted.
2770 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2771
2772 ClientSocketHandle handle;
[email protected]2431756e2010-09-29 20:26:132773 ConnectWithinCallback callback("a", params_, pool_.get());
Matt Menke28ac03e2019-02-25 22:25:502774 EXPECT_EQ(
2775 ERR_IO_PENDING,
2776 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2777 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2778 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2779 NetLogWithSource()));
[email protected]06f92462010-08-31 19:24:142780
2781 // Second job will be started during the first callback, and will
2782 // asynchronously complete with OK.
2783 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]7af985a2012-12-14 22:40:422784 pool_->FlushWithError(ERR_NETWORK_CHANGED);
robpercival214763f2016-07-01 23:27:012785 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NETWORK_CHANGED));
2786 EXPECT_THAT(callback.WaitForNestedResult(), IsOk());
[email protected]06f92462010-08-31 19:24:142787}
2788
Matt Menke141b87f22019-01-30 02:43:032789TEST_F(ClientSocketPoolBaseTest, BackupSocketWaitsForHostResolution) {
2790 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2791 pool_->EnableConnectBackupJobs();
2792
2793 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2794 ClientSocketHandle handle;
2795 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502796 EXPECT_EQ(
2797 ERR_IO_PENDING,
2798 handle.Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
2799 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2800 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2801 NetLogWithSource()));
Matt Menke141b87f22019-01-30 02:43:032802 // The backup timer fires but doesn't start a new ConnectJob while resolving
2803 // the hostname.
2804 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
2805 FastForwardBy(base::TimeDelta::FromMilliseconds(
2806 ClientSocketPool::kMaxConnectRetryIntervalMs * 100));
2807 EXPECT_EQ(1, client_socket_factory_.allocation_count());
2808
2809 // Once the ConnectJob has finished resolving the hostname, the backup timer
2810 // will create a ConnectJob when it fires.
2811 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_CONNECTING);
2812 FastForwardBy(base::TimeDelta::FromMilliseconds(
2813 ClientSocketPool::kMaxConnectRetryIntervalMs));
2814 EXPECT_EQ(2, client_socket_factory_.allocation_count());
2815}
2816
2817// Test that no backup socket is created when a ConnectJob connects before it
2818// completes.
2819TEST_F(ClientSocketPoolBaseTest, NoBackupSocketWhenConnected) {
2820 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2821 pool_->EnableConnectBackupJobs();
2822
2823 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2824 ClientSocketHandle handle;
2825 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502826 EXPECT_EQ(
2827 ERR_IO_PENDING,
2828 handle.Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
2829 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2830 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2831 NetLogWithSource()));
Matt Menke141b87f22019-01-30 02:43:032832 // The backup timer fires but doesn't start a new ConnectJob while resolving
2833 // the hostname.
2834 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
2835 FastForwardBy(base::TimeDelta::FromMilliseconds(
2836 ClientSocketPool::kMaxConnectRetryIntervalMs * 100));
2837 EXPECT_EQ(1, client_socket_factory_.allocation_count());
2838
2839 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2840 client_socket_factory_.SetJobHasEstablishedConnection(0);
2841 FastForwardBy(base::TimeDelta::FromMilliseconds(
2842 ClientSocketPool::kMaxConnectRetryIntervalMs * 100));
2843 EXPECT_EQ(1, client_socket_factory_.allocation_count());
2844}
2845
[email protected]25eea382010-07-10 23:55:262846// Cancel a pending socket request while we're at max sockets,
2847// and verify that the backup socket firing doesn't cause a crash.
2848TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
2849 // Max 4 sockets globally, max 4 sockets per group.
2850 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
[email protected]06d94042010-08-25 01:45:222851 pool_->EnableConnectBackupJobs();
[email protected]25eea382010-07-10 23:55:262852
[email protected]4baaf9d2010-08-31 15:15:442853 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2854 // timer.
[email protected]25eea382010-07-10 23:55:262855 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2856 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522857 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502858 EXPECT_EQ(
2859 ERR_IO_PENDING,
2860 handle.Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
2861 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2862 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2863 NetLogWithSource()));
[email protected]25eea382010-07-10 23:55:262864
2865 // Start (MaxSockets - 1) connected sockets to reach max sockets.
2866 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2867 ClientSocketHandle handles[kDefaultMaxSockets];
2868 for (int i = 1; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:522869 TestCompletionCallback callback;
Paul Jensen8d6f87ec2018-01-13 00:46:542870 EXPECT_EQ(OK, handles[i].Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:202871 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502872 callback.callback(),
2873 ClientSocketPool::ProxyAuthCallback(),
2874 pool_.get(), NetLogWithSource()));
[email protected]25eea382010-07-10 23:55:262875 }
2876
fdoray5eeb7642016-06-22 16:11:282877 base::RunLoop().RunUntilIdle();
[email protected]25eea382010-07-10 23:55:262878
2879 // Cancel the pending request.
2880 handle.Reset();
2881
2882 // Wait for the backup timer to fire (add some slop to ensure it fires)
Alex Clarke0def2092018-12-10 12:01:452883 FastForwardBy(base::TimeDelta::FromMilliseconds(
[email protected]26b9973962012-01-28 00:57:002884 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]25eea382010-07-10 23:55:262885
[email protected]25eea382010-07-10 23:55:262886 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
2887}
2888
[email protected]3f00be82010-09-27 19:50:022889TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
[email protected]4baaf9d2010-08-31 15:15:442890 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2891 pool_->EnableConnectBackupJobs();
2892
2893 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2894 // timer.
2895 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2896 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522897 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502898 EXPECT_EQ(
2899 ERR_IO_PENDING,
2900 handle.Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
2901 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2902 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2903 NetLogWithSource()));
[email protected]4baaf9d2010-08-31 15:15:442904 ASSERT_TRUE(pool_->HasGroup("bar"));
Raul Tambre8335a6d2019-02-21 16:57:432905 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("bar"));
2906 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("bar"));
2907 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("bar"));
[email protected]4baaf9d2010-08-31 15:15:442908
2909 // Cancel the socket request. This should cancel the backup timer. Wait for
2910 // the backup time to see if it indeed got canceled.
2911 handle.Reset();
2912 // Wait for the backup timer to fire (add some slop to ensure it fires)
Alex Clarke0def2092018-12-10 12:01:452913 FastForwardBy(base::TimeDelta::FromMilliseconds(
[email protected]26b9973962012-01-28 00:57:002914 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]4baaf9d2010-08-31 15:15:442915 ASSERT_TRUE(pool_->HasGroup("bar"));
Raul Tambre8335a6d2019-02-21 16:57:432916 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("bar"));
[email protected]4baaf9d2010-08-31 15:15:442917}
2918
[email protected]3f00be82010-09-27 19:50:022919TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
2920 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2921 pool_->EnableConnectBackupJobs();
2922
2923 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2924 // timer.
2925 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2926 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522927 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502928 EXPECT_EQ(
2929 ERR_IO_PENDING,
2930 handle.Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
2931 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2932 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2933 NetLogWithSource()));
[email protected]3f00be82010-09-27 19:50:022934 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2935 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522936 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:202937 EXPECT_EQ(
2938 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:542939 handle2.Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:202940 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:502941 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2942 pool_.get(), NetLogWithSource()));
[email protected]3f00be82010-09-27 19:50:022943 ASSERT_TRUE(pool_->HasGroup("bar"));
Raul Tambre8335a6d2019-02-21 16:57:432944 EXPECT_EQ(2u, pool_->NumConnectJobsInGroup("bar"));
[email protected]3f00be82010-09-27 19:50:022945
2946 // Cancel request 1 and then complete request 2. With the requests finished,
2947 // the backup timer should be cancelled.
2948 handle.Reset();
robpercival214763f2016-07-01 23:27:012949 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]3f00be82010-09-27 19:50:022950 // Wait for the backup timer to fire (add some slop to ensure it fires)
Alex Clarke0def2092018-12-10 12:01:452951 FastForwardBy(base::TimeDelta::FromMilliseconds(
[email protected]26b9973962012-01-28 00:57:002952 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]3f00be82010-09-27 19:50:022953}
2954
[email protected]eb5a99382010-07-11 03:18:262955// Test delayed socket binding for the case where we have two connects,
2956// and while one is waiting on a connect, the other frees up.
2957// The socket waiting on a connect should switch immediately to the freed
2958// up socket.
2959TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
2960 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2961 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2962
2963 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522964 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:502965 EXPECT_EQ(
2966 ERR_IO_PENDING,
2967 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2968 ClientSocketPool::RespectLimits::ENABLED,
2969 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2970 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:012971 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:262972
2973 // No idle sockets, no pending jobs.
2974 EXPECT_EQ(0, pool_->IdleSocketCount());
Raul Tambre8335a6d2019-02-21 16:57:432975 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
[email protected]eb5a99382010-07-11 03:18:262976
2977 // Create a second socket to the same host, but this one will wait.
2978 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2979 ClientSocketHandle handle2;
Matt Menke28ac03e2019-02-25 22:25:502980 EXPECT_EQ(
2981 ERR_IO_PENDING,
2982 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2983 ClientSocketPool::RespectLimits::ENABLED,
2984 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2985 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:262986 // No idle sockets, and one connecting job.
2987 EXPECT_EQ(0, pool_->IdleSocketCount());
Raul Tambre8335a6d2019-02-21 16:57:432988 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
[email protected]eb5a99382010-07-11 03:18:262989
2990 // Return the first handle to the pool. This will initiate the delayed
2991 // binding.
2992 handle1.Reset();
2993
fdoray5eeb7642016-06-22 16:11:282994 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262995
2996 // Still no idle sockets, still one pending connect job.
2997 EXPECT_EQ(0, pool_->IdleSocketCount());
Raul Tambre8335a6d2019-02-21 16:57:432998 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
[email protected]eb5a99382010-07-11 03:18:262999
3000 // The second socket connected, even though it was a Waiting Job.
robpercival214763f2016-07-01 23:27:013001 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263002
3003 // And we can see there is still one job waiting.
Raul Tambre8335a6d2019-02-21 16:57:433004 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
[email protected]eb5a99382010-07-11 03:18:263005
3006 // Finally, signal the waiting Connect.
3007 client_socket_factory_.SignalJobs();
Raul Tambre8335a6d2019-02-21 16:57:433008 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
[email protected]eb5a99382010-07-11 03:18:263009
fdoray5eeb7642016-06-22 16:11:283010 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263011}
3012
3013// Test delayed socket binding when a group is at capacity and one
3014// of the group's sockets frees up.
3015TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
3016 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3017 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3018
3019 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523020 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503021 EXPECT_EQ(
3022 ERR_IO_PENDING,
3023 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3024 ClientSocketPool::RespectLimits::ENABLED,
3025 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3026 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013027 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263028
3029 // No idle sockets, no pending jobs.
3030 EXPECT_EQ(0, pool_->IdleSocketCount());
Raul Tambre8335a6d2019-02-21 16:57:433031 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
[email protected]eb5a99382010-07-11 03:18:263032
3033 // Create a second socket to the same host, but this one will wait.
3034 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3035 ClientSocketHandle handle2;
Matt Menke28ac03e2019-02-25 22:25:503036 EXPECT_EQ(
3037 ERR_IO_PENDING,
3038 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3039 ClientSocketPool::RespectLimits::ENABLED,
3040 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3041 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:263042 // No idle sockets, and one connecting job.
3043 EXPECT_EQ(0, pool_->IdleSocketCount());
Raul Tambre8335a6d2019-02-21 16:57:433044 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
[email protected]eb5a99382010-07-11 03:18:263045
3046 // Return the first handle to the pool. This will initiate the delayed
3047 // binding.
3048 handle1.Reset();
3049
fdoray5eeb7642016-06-22 16:11:283050 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263051
3052 // Still no idle sockets, still one pending connect job.
3053 EXPECT_EQ(0, pool_->IdleSocketCount());
Raul Tambre8335a6d2019-02-21 16:57:433054 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
[email protected]eb5a99382010-07-11 03:18:263055
3056 // The second socket connected, even though it was a Waiting Job.
robpercival214763f2016-07-01 23:27:013057 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263058
3059 // And we can see there is still one job waiting.
Raul Tambre8335a6d2019-02-21 16:57:433060 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
[email protected]eb5a99382010-07-11 03:18:263061
3062 // Finally, signal the waiting Connect.
3063 client_socket_factory_.SignalJobs();
Raul Tambre8335a6d2019-02-21 16:57:433064 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
[email protected]eb5a99382010-07-11 03:18:263065
fdoray5eeb7642016-06-22 16:11:283066 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263067}
3068
3069// Test out the case where we have one socket connected, one
3070// connecting, when the first socket finishes and goes idle.
[email protected]2abfe90a2010-08-25 17:49:513071// Although the second connection is pending, the second request
[email protected]eb5a99382010-07-11 03:18:263072// should complete, by taking the first socket's idle socket.
3073TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
3074 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3075 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3076
3077 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523078 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503079 EXPECT_EQ(
3080 ERR_IO_PENDING,
3081 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3082 ClientSocketPool::RespectLimits::ENABLED,
3083 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3084 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013085 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263086
3087 // No idle sockets, no pending jobs.
3088 EXPECT_EQ(0, pool_->IdleSocketCount());
Raul Tambre8335a6d2019-02-21 16:57:433089 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
[email protected]eb5a99382010-07-11 03:18:263090
3091 // Create a second socket to the same host, but this one will wait.
3092 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3093 ClientSocketHandle handle2;
Matt Menke28ac03e2019-02-25 22:25:503094 EXPECT_EQ(
3095 ERR_IO_PENDING,
3096 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3097 ClientSocketPool::RespectLimits::ENABLED,
3098 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3099 pool_.get(), NetLogWithSource()));
[email protected]eb5a99382010-07-11 03:18:263100 // No idle sockets, and one connecting job.
3101 EXPECT_EQ(0, pool_->IdleSocketCount());
Raul Tambre8335a6d2019-02-21 16:57:433102 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
[email protected]eb5a99382010-07-11 03:18:263103
3104 // Return the first handle to the pool. This will initiate the delayed
3105 // binding.
3106 handle1.Reset();
3107
fdoray5eeb7642016-06-22 16:11:283108 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263109
3110 // Still no idle sockets, still one pending connect job.
3111 EXPECT_EQ(0, pool_->IdleSocketCount());
Raul Tambre8335a6d2019-02-21 16:57:433112 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
[email protected]eb5a99382010-07-11 03:18:263113
3114 // The second socket connected, even though it was a Waiting Job.
robpercival214763f2016-07-01 23:27:013115 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb5a99382010-07-11 03:18:263116
3117 // And we can see there is still one job waiting.
Raul Tambre8335a6d2019-02-21 16:57:433118 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
[email protected]eb5a99382010-07-11 03:18:263119
3120 // Finally, signal the waiting Connect.
3121 client_socket_factory_.SignalJobs();
Raul Tambre8335a6d2019-02-21 16:57:433122 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
[email protected]eb5a99382010-07-11 03:18:263123
fdoray5eeb7642016-06-22 16:11:283124 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263125}
3126
[email protected]2abfe90a2010-08-25 17:49:513127// Cover the case where on an available socket slot, we have one pending
3128// request that completes synchronously, thereby making the Group empty.
3129TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
3130 const int kUnlimitedSockets = 100;
3131 const int kOneSocketPerGroup = 1;
3132 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
3133
3134 // Make the first request asynchronous fail.
3135 // This will free up a socket slot later.
3136 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
3137
3138 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523139 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203140 EXPECT_EQ(
3141 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543142 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203143 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503144 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3145 pool_.get(), NetLogWithSource()));
Raul Tambre8335a6d2019-02-21 16:57:433146 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
[email protected]2abfe90a2010-08-25 17:49:513147
3148 // Make the second request synchronously fail. This should make the Group
3149 // empty.
3150 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3151 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523152 TestCompletionCallback callback2;
[email protected]2abfe90a2010-08-25 17:49:513153 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
3154 // when created.
tfarina428341112016-09-22 13:38:203155 EXPECT_EQ(
3156 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543157 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203158 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503159 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3160 pool_.get(), NetLogWithSource()));
[email protected]2abfe90a2010-08-25 17:49:513161
Raul Tambre8335a6d2019-02-21 16:57:433162 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
[email protected]2abfe90a2010-08-25 17:49:513163
robpercival214763f2016-07-01 23:27:013164 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
3165 EXPECT_THAT(callback2.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
[email protected]2abfe90a2010-08-25 17:49:513166 EXPECT_FALSE(pool_->HasGroup("a"));
3167}
3168
[email protected]e1b54dc2010-10-06 21:27:223169TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
3170 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3171
3172 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3173
3174 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523175 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203176 EXPECT_EQ(
3177 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543178 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203179 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503180 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3181 pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223182
3183 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523184 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203185 EXPECT_EQ(
3186 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543187 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203188 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503189 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3190 pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223191 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:523192 TestCompletionCallback callback3;
tfarina428341112016-09-22 13:38:203193 EXPECT_EQ(
3194 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543195 handle3.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203196 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503197 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
3198 pool_.get(), NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223199
robpercival214763f2016-07-01 23:27:013200 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3201 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3202 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]e1b54dc2010-10-06 21:27:223203
3204 // Use the socket.
Bence Békybdbb0e72018-08-07 21:42:593205 EXPECT_EQ(1, handle1.socket()->Write(NULL, 1, CompletionOnceCallback(),
Ramin Halavati0a08cc82018-02-06 07:46:383206 TRAFFIC_ANNOTATION_FOR_TESTS));
Bence Békybdbb0e72018-08-07 21:42:593207 EXPECT_EQ(1, handle3.socket()->Write(NULL, 1, CompletionOnceCallback(),
Ramin Halavati0a08cc82018-02-06 07:46:383208 TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]e1b54dc2010-10-06 21:27:223209
3210 handle1.Reset();
3211 handle2.Reset();
3212 handle3.Reset();
3213
Matt Menke28ac03e2019-02-25 22:25:503214 EXPECT_EQ(OK, handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3215 ClientSocketPool::RespectLimits::ENABLED,
3216 callback1.callback(),
3217 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
3218 NetLogWithSource()));
3219 EXPECT_EQ(OK, handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3220 ClientSocketPool::RespectLimits::ENABLED,
3221 callback2.callback(),
3222 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
3223 NetLogWithSource()));
3224 EXPECT_EQ(OK, handle3.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3225 ClientSocketPool::RespectLimits::ENABLED,
3226 callback3.callback(),
3227 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
3228 NetLogWithSource()));
[email protected]e1b54dc2010-10-06 21:27:223229
3230 EXPECT_TRUE(handle1.socket()->WasEverUsed());
3231 EXPECT_TRUE(handle2.socket()->WasEverUsed());
3232 EXPECT_FALSE(handle3.socket()->WasEverUsed());
3233}
3234
[email protected]2c2bef152010-10-13 00:55:033235TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
3236 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3237 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3238
Charlie Harrison55ce6082018-05-14 02:25:573239 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033240
3241 ASSERT_TRUE(pool_->HasGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433242 EXPECT_EQ(2u, pool_->NumConnectJobsInGroup("a"));
3243 EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3244 EXPECT_EQ(2u, pool_->NumUnassignedConnectJobsInGroup("a"));
3245 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033246
3247 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523248 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203249 EXPECT_EQ(
3250 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543251 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203252 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503253 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3254 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033255
3256 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523257 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203258 EXPECT_EQ(
3259 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543260 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203261 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503262 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3263 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033264
Raul Tambre8335a6d2019-02-21 16:57:433265 EXPECT_EQ(2u, pool_->NumConnectJobsInGroup("a"));
3266 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3267 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3268 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033269
robpercival214763f2016-07-01 23:27:013270 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3271 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033272 handle1.Reset();
3273 handle2.Reset();
3274
Raul Tambre8335a6d2019-02-21 16:57:433275 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
3276 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3277 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3278 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033279}
3280
3281TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
3282 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3283 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3284
3285 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523286 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203287 EXPECT_EQ(
3288 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543289 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203290 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503291 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3292 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033293
3294 ASSERT_TRUE(pool_->HasGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433295 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
3296 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3297 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3298 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033299
Charlie Harrison55ce6082018-05-14 02:25:573300 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033301
Raul Tambre8335a6d2019-02-21 16:57:433302 EXPECT_EQ(2u, pool_->NumConnectJobsInGroup("a"));
3303 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3304 EXPECT_EQ(1u, pool_->NumUnassignedConnectJobsInGroup("a"));
3305 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033306
3307 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523308 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203309 EXPECT_EQ(
3310 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543311 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203312 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503313 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3314 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033315
Raul Tambre8335a6d2019-02-21 16:57:433316 EXPECT_EQ(2u, pool_->NumConnectJobsInGroup("a"));
3317 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3318 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3319 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033320
robpercival214763f2016-07-01 23:27:013321 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3322 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033323 handle1.Reset();
3324 handle2.Reset();
3325
Raul Tambre8335a6d2019-02-21 16:57:433326 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
3327 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3328 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3329 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033330}
3331
3332TEST_F(ClientSocketPoolBaseTest,
3333 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
3334 CreatePool(4, 4);
3335 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3336
3337 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523338 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203339 EXPECT_EQ(
3340 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543341 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203342 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503343 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3344 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033345
3346 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523347 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203348 EXPECT_EQ(
3349 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543350 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203351 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503352 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3353 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033354
3355 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:523356 TestCompletionCallback callback3;
tfarina428341112016-09-22 13:38:203357 EXPECT_EQ(
3358 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543359 handle3.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203360 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503361 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
3362 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033363
3364 ASSERT_TRUE(pool_->HasGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433365 EXPECT_EQ(3u, pool_->NumConnectJobsInGroup("a"));
3366 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3367 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3368 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033369
Charlie Harrison55ce6082018-05-14 02:25:573370 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033371
Raul Tambre8335a6d2019-02-21 16:57:433372 EXPECT_EQ(3u, pool_->NumConnectJobsInGroup("a"));
3373 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3374 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3375 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033376
robpercival214763f2016-07-01 23:27:013377 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3378 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3379 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033380 handle1.Reset();
3381 handle2.Reset();
3382 handle3.Reset();
3383
Raul Tambre8335a6d2019-02-21 16:57:433384 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
3385 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3386 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3387 EXPECT_EQ(3u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033388}
3389
3390TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
3391 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3392 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3393
3394 ASSERT_FALSE(pool_->HasGroup("a"));
3395
Charlie Harrison55ce6082018-05-14 02:25:573396 pool_->RequestSockets("a", &params_, kDefaultMaxSockets, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033397
3398 ASSERT_TRUE(pool_->HasGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433399 EXPECT_EQ(kDefaultMaxSockets,
3400 static_cast<int>(pool_->NumConnectJobsInGroup("a")));
3401 EXPECT_EQ(kDefaultMaxSockets,
3402 static_cast<int>(pool_->NumNeverAssignedConnectJobsInGroup("a")));
3403 EXPECT_EQ(kDefaultMaxSockets,
3404 static_cast<int>(pool_->NumUnassignedConnectJobsInGroup("a")));
[email protected]2c2bef152010-10-13 00:55:033405
3406 ASSERT_FALSE(pool_->HasGroup("b"));
3407
Charlie Harrison55ce6082018-05-14 02:25:573408 pool_->RequestSockets("b", &params_, kDefaultMaxSockets, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033409
3410 ASSERT_FALSE(pool_->HasGroup("b"));
3411}
3412
3413TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
3414 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3415 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3416
3417 ASSERT_FALSE(pool_->HasGroup("a"));
3418
3419 pool_->RequestSockets("a", &params_, kDefaultMaxSockets - 1,
Charlie Harrison55ce6082018-05-14 02:25:573420 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033421
3422 ASSERT_TRUE(pool_->HasGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103423 EXPECT_EQ(kDefaultMaxSockets - 1,
Raul Tambre8335a6d2019-02-21 16:57:433424 static_cast<int>(pool_->NumConnectJobsInGroup("a")));
Lily Chenecebf932018-11-02 17:15:433425 EXPECT_EQ(kDefaultMaxSockets - 1,
Raul Tambre8335a6d2019-02-21 16:57:433426 static_cast<int>(pool_->NumNeverAssignedConnectJobsInGroup("a")));
3427 EXPECT_EQ(kDefaultMaxSockets - 1,
3428 static_cast<int>(pool_->NumUnassignedConnectJobsInGroup("a")));
[email protected]51fdc7c2012-04-10 19:19:483429 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033430
3431 ASSERT_FALSE(pool_->HasGroup("b"));
3432
Charlie Harrison55ce6082018-05-14 02:25:573433 pool_->RequestSockets("b", &params_, kDefaultMaxSockets, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033434
3435 ASSERT_TRUE(pool_->HasGroup("b"));
Raul Tambre8335a6d2019-02-21 16:57:433436 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("b"));
[email protected]51fdc7c2012-04-10 19:19:483437 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033438}
3439
3440TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
3441 CreatePool(4, 4);
3442 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3443
3444 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523445 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203446 EXPECT_EQ(
3447 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543448 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203449 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503450 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3451 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013452 ASSERT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033453 handle1.Reset();
3454
3455 ASSERT_TRUE(pool_->HasGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433456 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
3457 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3458 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3459 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033460
Charlie Harrison55ce6082018-05-14 02:25:573461 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033462
Raul Tambre8335a6d2019-02-21 16:57:433463 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
3464 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3465 EXPECT_EQ(1u, pool_->NumUnassignedConnectJobsInGroup("a"));
3466 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033467}
3468
3469TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
3470 CreatePool(4, 4);
3471 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3472
3473 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523474 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203475 EXPECT_EQ(
3476 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543477 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203478 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503479 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3480 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:013481 ASSERT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033482
3483 ASSERT_TRUE(pool_->HasGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433484 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
3485 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3486 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3487 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033488 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3489
Charlie Harrison55ce6082018-05-14 02:25:573490 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033491
Raul Tambre8335a6d2019-02-21 16:57:433492 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
3493 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3494 EXPECT_EQ(1u, pool_->NumUnassignedConnectJobsInGroup("a"));
3495 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033496 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3497}
3498
3499TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
3500 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3501 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3502
3503 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
Charlie Harrison55ce6082018-05-14 02:25:573504 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033505
3506 ASSERT_TRUE(pool_->HasGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433507 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
3508 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3509 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3510 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
3511 static_cast<int>(pool_->IdleSocketCountInGroup("a")));
[email protected]2c2bef152010-10-13 00:55:033512
3513 pool_->RequestSockets("b", &params_, kDefaultMaxSocketsPerGroup,
Charlie Harrison55ce6082018-05-14 02:25:573514 NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033515
Raul Tambre8335a6d2019-02-21 16:57:433516 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("b"));
3517 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("b"));
3518 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("b"));
3519 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
3520 static_cast<int>(pool_->IdleSocketCountInGroup("b")));
[email protected]2c2bef152010-10-13 00:55:033521}
3522
[email protected]3c819f522010-12-02 02:03:123523TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
3524 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3525 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3526
3527 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
Charlie Harrison55ce6082018-05-14 02:25:573528 NetLogWithSource());
[email protected]3c819f522010-12-02 02:03:123529
3530 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]fd2e53e2011-01-14 20:40:523531
3532 connect_job_factory_->set_job_type(
3533 TestConnectJob::kMockAdditionalErrorStateJob);
3534 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
Charlie Harrison55ce6082018-05-14 02:25:573535 NetLogWithSource());
[email protected]fd2e53e2011-01-14 20:40:523536
3537 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]3c819f522010-12-02 02:03:123538}
3539
[email protected]8159a1c2012-06-07 00:00:103540TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
[email protected]2c2bef152010-10-13 00:55:033541 CreatePool(4, 4);
Lily Chenecebf932018-11-02 17:15:433542 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]2c2bef152010-10-13 00:55:033543
Charlie Harrison55ce6082018-05-14 02:25:573544 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033545
3546 ASSERT_TRUE(pool_->HasGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433547 EXPECT_EQ(2u, pool_->NumConnectJobsInGroup("a"));
3548 EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3549 EXPECT_EQ(2u, pool_->NumUnassignedConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433550 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433551 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033552
Charlie Harrison55ce6082018-05-14 02:25:573553 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
Raul Tambre8335a6d2019-02-21 16:57:433554 EXPECT_EQ(2u, pool_->NumConnectJobsInGroup("a"));
3555 EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3556 EXPECT_EQ(2u, pool_->NumUnassignedConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433557 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433558 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033559
3560 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523561 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203562 EXPECT_EQ(
3563 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543564 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203565 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503566 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3567 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:433568
3569 client_socket_factory_.SignalJob(0);
3570 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3571
Raul Tambre8335a6d2019-02-21 16:57:433572 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
3573 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3574 EXPECT_EQ(1u, pool_->NumUnassignedConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433575 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433576 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033577
3578 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523579 TestCompletionCallback callback2;
Lily Chenecebf932018-11-02 17:15:433580 EXPECT_EQ(
3581 ERR_IO_PENDING,
3582 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3583 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503584 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3585 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:433586 client_socket_factory_.SignalJob(0);
3587 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2c2bef152010-10-13 00:55:033588
Raul Tambre8335a6d2019-02-21 16:57:433589 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
3590 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3591 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103592 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433593 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103594
[email protected]2c2bef152010-10-13 00:55:033595 handle1.Reset();
3596 handle2.Reset();
3597
Raul Tambre8335a6d2019-02-21 16:57:433598 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
3599 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3600 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433601 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433602 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033603
Charlie Harrison55ce6082018-05-14 02:25:573604 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
Raul Tambre8335a6d2019-02-21 16:57:433605 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
3606 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3607 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433608 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433609 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033610}
3611
3612TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
3613 CreatePool(4, 4);
3614 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3615
Charlie Harrison55ce6082018-05-14 02:25:573616 pool_->RequestSockets("a", &params_, 1, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033617
3618 ASSERT_TRUE(pool_->HasGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433619 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
3620 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3621 EXPECT_EQ(1u, pool_->NumUnassignedConnectJobsInGroup("a"));
3622 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033623
Charlie Harrison55ce6082018-05-14 02:25:573624 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
Raul Tambre8335a6d2019-02-21 16:57:433625 EXPECT_EQ(2u, pool_->NumConnectJobsInGroup("a"));
3626 EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3627 EXPECT_EQ(2u, pool_->NumUnassignedConnectJobsInGroup("a"));
3628 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033629
Charlie Harrison55ce6082018-05-14 02:25:573630 pool_->RequestSockets("a", &params_, 3, NetLogWithSource());
Raul Tambre8335a6d2019-02-21 16:57:433631 EXPECT_EQ(3u, pool_->NumConnectJobsInGroup("a"));
3632 EXPECT_EQ(3u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3633 EXPECT_EQ(3u, pool_->NumUnassignedConnectJobsInGroup("a"));
3634 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033635
Charlie Harrison55ce6082018-05-14 02:25:573636 pool_->RequestSockets("a", &params_, 1, NetLogWithSource());
Raul Tambre8335a6d2019-02-21 16:57:433637 EXPECT_EQ(3u, pool_->NumConnectJobsInGroup("a"));
3638 EXPECT_EQ(3u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3639 EXPECT_EQ(3u, pool_->NumUnassignedConnectJobsInGroup("a"));
3640 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033641}
3642
3643TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
3644 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
Lily Chenecebf932018-11-02 17:15:433645 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]2c2bef152010-10-13 00:55:033646
Charlie Harrison55ce6082018-05-14 02:25:573647 pool_->RequestSockets("a", &params_, 1, NetLogWithSource());
[email protected]2c2bef152010-10-13 00:55:033648
3649 ASSERT_TRUE(pool_->HasGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433650 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
3651 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3652 EXPECT_EQ(1u, pool_->NumUnassignedConnectJobsInGroup("a"));
3653 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033654
3655 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523656 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203657 EXPECT_EQ(
3658 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543659 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203660 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503661 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3662 pool_.get(), NetLogWithSource()));
[email protected]2c2bef152010-10-13 00:55:033663
Raul Tambre8335a6d2019-02-21 16:57:433664 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
3665 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3666 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3667 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033668
Lily Chenecebf932018-11-02 17:15:433669 client_socket_factory_.SignalJobs();
3670 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3671
Raul Tambre8335a6d2019-02-21 16:57:433672 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
3673 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3674 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3675 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433676 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033677
[email protected]0dc88b32014-03-26 20:12:283678 // Make sure if a preconnected socket is not fully connected when a request
[email protected]034df0f32013-01-07 23:17:483679 // starts, it has a connect start time.
3680 TestLoadTimingInfoConnectedNotReused(handle1);
[email protected]2c2bef152010-10-13 00:55:033681 handle1.Reset();
3682
Raul Tambre8335a6d2019-02-21 16:57:433683 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033684}
3685
[email protected]034df0f32013-01-07 23:17:483686// Checks that fully connected preconnect jobs have no connect times, and are
3687// marked as reused.
3688TEST_F(ClientSocketPoolBaseTest, ConnectedPreconnectJobsHaveNoConnectTimes) {
3689 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3690 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
Charlie Harrison55ce6082018-05-14 02:25:573691 pool_->RequestSockets("a", &params_, 1, NetLogWithSource());
[email protected]034df0f32013-01-07 23:17:483692
3693 ASSERT_TRUE(pool_->HasGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433694 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
3695 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3696 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3697 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup("a"));
[email protected]034df0f32013-01-07 23:17:483698
3699 ClientSocketHandle handle;
3700 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503701 EXPECT_EQ(OK, handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3702 ClientSocketPool::RespectLimits::ENABLED,
3703 callback.callback(),
3704 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
3705 NetLogWithSource()));
[email protected]034df0f32013-01-07 23:17:483706
3707 // Make sure the idle socket was used.
Raul Tambre8335a6d2019-02-21 16:57:433708 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]034df0f32013-01-07 23:17:483709
3710 TestLoadTimingInfoConnectedReused(handle);
3711 handle.Reset();
3712 TestLoadTimingInfoNotConnected(handle);
3713}
3714
[email protected]dcbe168a2010-12-02 03:14:463715// http://crbug.com/64940 regression test.
3716TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
3717 const int kMaxTotalSockets = 3;
3718 const int kMaxSocketsPerGroup = 2;
3719 CreatePool(kMaxTotalSockets, kMaxSocketsPerGroup);
Lily Chenecebf932018-11-02 17:15:433720 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]dcbe168a2010-12-02 03:14:463721
3722 // Note that group name ordering matters here. "a" comes before "b", so
3723 // CloseOneIdleSocket() will try to close "a"'s idle socket.
3724
3725 // Set up one idle socket in "a".
3726 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523727 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:203728 EXPECT_EQ(
3729 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543730 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203731 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503732 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3733 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:433734 ASSERT_TRUE(pool_->HasGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433735 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
3736 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3737 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3738 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]dcbe168a2010-12-02 03:14:463739
Lily Chenecebf932018-11-02 17:15:433740 client_socket_factory_.SignalJobs();
robpercival214763f2016-07-01 23:27:013741 ASSERT_THAT(callback1.WaitForResult(), IsOk());
Raul Tambre8335a6d2019-02-21 16:57:433742 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
3743 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3744 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433745 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3746
[email protected]dcbe168a2010-12-02 03:14:463747 handle1.Reset();
Raul Tambre8335a6d2019-02-21 16:57:433748 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup("a"));
[email protected]dcbe168a2010-12-02 03:14:463749
3750 // Set up two active sockets in "b".
3751 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523752 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:203753 EXPECT_EQ(
3754 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543755 handle1.Init("b", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203756 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503757 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3758 pool_.get(), NetLogWithSource()));
tfarina428341112016-09-22 13:38:203759 EXPECT_EQ(
3760 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:543761 handle2.Init("b", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:203762 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503763 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3764 pool_.get(), NetLogWithSource()));
[email protected]dcbe168a2010-12-02 03:14:463765
Lily Chenecebf932018-11-02 17:15:433766 ASSERT_TRUE(pool_->HasGroup("b"));
Raul Tambre8335a6d2019-02-21 16:57:433767 EXPECT_EQ(2u, pool_->NumConnectJobsInGroup("b"));
3768 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("b"));
3769 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("b"));
3770 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("b"));
Lily Chenecebf932018-11-02 17:15:433771
3772 client_socket_factory_.SignalJobs();
robpercival214763f2016-07-01 23:27:013773 ASSERT_THAT(callback1.WaitForResult(), IsOk());
3774 ASSERT_THAT(callback2.WaitForResult(), IsOk());
Raul Tambre8335a6d2019-02-21 16:57:433775 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("b"));
3776 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("b"));
3777 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463778 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3779
3780 // Now we have 1 idle socket in "a" and 2 active sockets in "b". This means
3781 // we've maxed out on sockets, since we set |kMaxTotalSockets| to 3.
3782 // Requesting 2 preconnected sockets for "a" should fail to allocate any more
3783 // sockets for "a", and "b" should still have 2 active sockets.
3784
Charlie Harrison55ce6082018-05-14 02:25:573785 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
Raul Tambre8335a6d2019-02-21 16:57:433786 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
3787 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3788 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3789 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup("a"));
[email protected]dcbe168a2010-12-02 03:14:463790 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433791 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("b"));
3792 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("b"));
3793 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("b"));
3794 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463795 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3796
3797 // Now release the 2 active sockets for "b". This will give us 1 idle socket
3798 // in "a" and 2 idle sockets in "b". Requesting 2 preconnected sockets for
3799 // "a" should result in closing 1 for "b".
3800 handle1.Reset();
3801 handle2.Reset();
Raul Tambre8335a6d2019-02-21 16:57:433802 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463803 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3804
Charlie Harrison55ce6082018-05-14 02:25:573805 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
Raul Tambre8335a6d2019-02-21 16:57:433806 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
3807 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3808 EXPECT_EQ(1u, pool_->NumUnassignedConnectJobsInGroup("a"));
3809 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup("a"));
[email protected]dcbe168a2010-12-02 03:14:463810 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433811 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("b"));
3812 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("b"));
3813 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("b"));
3814 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463815 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3816}
3817
[email protected]b7b8be42011-07-12 12:46:413818TEST_F(ClientSocketPoolBaseTest, PreconnectWithoutBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073819 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3820 pool_->EnableConnectBackupJobs();
3821
3822 // Make the ConnectJob hang until it times out, shorten the timeout.
3823 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3824 connect_job_factory_->set_timeout_duration(
3825 base::TimeDelta::FromMilliseconds(500));
Charlie Harrison55ce6082018-05-14 02:25:573826 pool_->RequestSockets("a", &params_, 1, NetLogWithSource());
Raul Tambre8335a6d2019-02-21 16:57:433827 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
3828 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3829 EXPECT_EQ(1u, pool_->NumUnassignedConnectJobsInGroup("a"));
3830 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073831
[email protected]b7b8be42011-07-12 12:46:413832 // Verify the backup timer doesn't create a backup job, by making
3833 // the backup job a pending job instead of a waiting job, so it
3834 // *would* complete if it were created.
[email protected]a9fc8fc2011-05-10 02:41:073835 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
skyostil4891b25b2015-06-11 11:43:453836 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
Gabriel Charetteea918012018-05-16 11:53:443837 FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated(),
[email protected]2da659e2013-05-23 20:51:343838 base::TimeDelta::FromSeconds(1));
fdoray5eeb7642016-06-22 16:11:283839 base::RunLoop().Run();
[email protected]a9fc8fc2011-05-10 02:41:073840 EXPECT_FALSE(pool_->HasGroup("a"));
3841}
3842
[email protected]b7b8be42011-07-12 12:46:413843TEST_F(ClientSocketPoolBaseTest, PreconnectWithBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073844 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3845 pool_->EnableConnectBackupJobs();
3846
3847 // Make the ConnectJob hang forever.
3848 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
Charlie Harrison55ce6082018-05-14 02:25:573849 pool_->RequestSockets("a", &params_, 1, NetLogWithSource());
Raul Tambre8335a6d2019-02-21 16:57:433850 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
3851 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3852 EXPECT_EQ(1u, pool_->NumUnassignedConnectJobsInGroup("a"));
3853 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
fdoray5eeb7642016-06-22 16:11:283854 base::RunLoop().RunUntilIdle();
[email protected]a9fc8fc2011-05-10 02:41:073855
3856 // Make the backup job be a pending job, so it completes normally.
3857 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3858 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:523859 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503860 EXPECT_EQ(
3861 ERR_IO_PENDING,
3862 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3863 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
3864 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
3865 NetLogWithSource()));
[email protected]b7b8be42011-07-12 12:46:413866 // Timer has started, but the backup connect job shouldn't be created yet.
Raul Tambre8335a6d2019-02-21 16:57:433867 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
3868 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3869 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3870 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073871 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
robpercival214763f2016-07-01 23:27:013872 ASSERT_THAT(callback.WaitForResult(), IsOk());
[email protected]a9fc8fc2011-05-10 02:41:073873
3874 // The hung connect job should still be there, but everything else should be
3875 // complete.
Raul Tambre8335a6d2019-02-21 16:57:433876 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
3877 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3878 EXPECT_EQ(1u, pool_->NumUnassignedConnectJobsInGroup("a"));
3879 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073880 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3881}
3882
[email protected]0dc88b32014-03-26 20:12:283883// Tests that a preconnect that starts out with unread data can still be used.
3884// http://crbug.com/334467
3885TEST_F(ClientSocketPoolBaseTest, PreconnectWithUnreadData) {
3886 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3887 connect_job_factory_->set_job_type(TestConnectJob::kMockUnreadDataJob);
3888
Charlie Harrison55ce6082018-05-14 02:25:573889 pool_->RequestSockets("a", &params_, 1, NetLogWithSource());
[email protected]0dc88b32014-03-26 20:12:283890
3891 ASSERT_TRUE(pool_->HasGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433892 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
3893 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3894 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3895 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup("a"));
[email protected]0dc88b32014-03-26 20:12:283896
3897 // Fail future jobs to be sure that handle receives the preconnected socket
3898 // rather than closing it and making a new one.
3899 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3900 ClientSocketHandle handle;
3901 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:503902 EXPECT_EQ(OK, handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3903 ClientSocketPool::RespectLimits::ENABLED,
3904 callback.callback(),
3905 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
3906 NetLogWithSource()));
[email protected]0dc88b32014-03-26 20:12:283907
3908 ASSERT_TRUE(pool_->HasGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433909 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
3910 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3911 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3912 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433913 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
[email protected]0dc88b32014-03-26 20:12:283914
3915 // Drain the pending read.
Bence Békybdbb0e72018-08-07 21:42:593916 EXPECT_EQ(1, handle.socket()->Read(NULL, 1, CompletionOnceCallback()));
[email protected]0dc88b32014-03-26 20:12:283917
3918 TestLoadTimingInfoConnectedReused(handle);
3919 handle.Reset();
3920
3921 // The socket should be usable now that it's idle again.
Raul Tambre8335a6d2019-02-21 16:57:433922 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup("a"));
[email protected]0dc88b32014-03-26 20:12:283923}
3924
Lily Chenecebf932018-11-02 17:15:433925TEST_F(ClientSocketPoolBaseTest, RequestGetsAssignedJob) {
3926 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3927 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3928
3929 ClientSocketHandle handle1;
3930 TestCompletionCallback callback1;
3931 EXPECT_EQ(
3932 ERR_IO_PENDING,
3933 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3934 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503935 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3936 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:433937
Raul Tambre8335a6d2019-02-21 16:57:433938 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
3939 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3940 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3941 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433942
3943 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle1));
3944}
3945
3946TEST_F(ClientSocketPoolBaseTest, MultipleRequestsGetAssignedJobs) {
3947 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3948 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3949
3950 ClientSocketHandle handle1;
3951 TestCompletionCallback callback1;
3952 EXPECT_EQ(
3953 ERR_IO_PENDING,
3954 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3955 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503956 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3957 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:433958
Raul Tambre8335a6d2019-02-21 16:57:433959 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
3960 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3961 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3962 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433963
3964 ClientSocketHandle handle2;
3965 TestCompletionCallback callback2;
3966 EXPECT_EQ(
3967 ERR_IO_PENDING,
3968 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3969 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:503970 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3971 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:433972
Raul Tambre8335a6d2019-02-21 16:57:433973 EXPECT_EQ(2u, pool_->NumConnectJobsInGroup("a"));
3974 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3975 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
3976 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433977
3978 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle1));
3979 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle2));
3980
3981 // One job completes. The other request should still have its job.
3982 client_socket_factory_.SignalJob(0);
3983 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3984
Raul Tambre8335a6d2019-02-21 16:57:433985 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
3986 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
3987 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433988 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:433989 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:433990
3991 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle2));
3992}
3993
3994TEST_F(ClientSocketPoolBaseTest, PreconnectJobGetsAssignedToRequest) {
3995 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3996 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3997
3998 pool_->RequestSockets("a", &params_, 1, NetLogWithSource());
3999
4000 ASSERT_TRUE(pool_->HasGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:434001 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4002 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4003 EXPECT_EQ(1u, pool_->NumUnassignedConnectJobsInGroup("a"));
4004 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:434005
4006 ClientSocketHandle handle1;
4007 TestCompletionCallback callback1;
4008 EXPECT_EQ(
4009 ERR_IO_PENDING,
4010 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
4011 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504012 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4013 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434014
Raul Tambre8335a6d2019-02-21 16:57:434015 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4016 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4017 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
4018 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:434019
4020 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle1));
4021}
4022
4023TEST_F(ClientSocketPoolBaseTest, HigherPriorityRequestStealsJob) {
4024 CreatePool(kDefaultMaxSockets, 1);
4025 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4026
4027 ClientSocketHandle handle1;
4028 TestCompletionCallback callback1;
4029 EXPECT_EQ(
4030 ERR_IO_PENDING,
4031 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
4032 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504033 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4034 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434035
Raul Tambre8335a6d2019-02-21 16:57:434036 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4037 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4038 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
4039 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:434040
4041 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle1));
4042
4043 // Insert a higher priority request
4044 ClientSocketHandle handle2;
4045 TestCompletionCallback callback2;
4046 EXPECT_EQ(
4047 ERR_IO_PENDING,
4048 handle2.Init("a", params_, HIGHEST, SocketTag(),
4049 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504050 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4051 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434052
Raul Tambre8335a6d2019-02-21 16:57:434053 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4054 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4055 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
4056 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:434057
4058 // The highest priority request should steal the job from the default priority
4059 // request.
4060 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle2));
4061 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle1));
4062}
4063
4064TEST_F(ClientSocketPoolBaseTest, RequestStealsJobFromLowestRequestWithJob) {
4065 CreatePool(3, 3);
4066 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4067
4068 ClientSocketHandle handle_lowest;
4069 TestCompletionCallback callback_lowest;
4070 EXPECT_EQ(ERR_IO_PENDING,
4071 handle_lowest.Init("a", params_, LOWEST, SocketTag(),
4072 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504073 callback_lowest.callback(),
4074 ClientSocketPool::ProxyAuthCallback(),
4075 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434076
Raul Tambre8335a6d2019-02-21 16:57:434077 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4078 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4079 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
4080 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:434081
4082 ClientSocketHandle handle_highest;
4083 TestCompletionCallback callback_highest;
4084 EXPECT_EQ(ERR_IO_PENDING,
4085 handle_highest.Init("a", params_, HIGHEST, SocketTag(),
4086 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504087 callback_highest.callback(),
4088 ClientSocketPool::ProxyAuthCallback(),
4089 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434090
Raul Tambre8335a6d2019-02-21 16:57:434091 EXPECT_EQ(2u, pool_->NumConnectJobsInGroup("a"));
4092 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4093 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
4094 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:434095
4096 ClientSocketHandle handle_low;
4097 TestCompletionCallback callback_low;
4098 EXPECT_EQ(ERR_IO_PENDING,
4099 handle_low.Init("a", params_, LOW, SocketTag(),
4100 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504101 callback_low.callback(),
4102 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
Lily Chenecebf932018-11-02 17:15:434103 NetLogWithSource()));
4104
Raul Tambre8335a6d2019-02-21 16:57:434105 EXPECT_EQ(3u, pool_->NumConnectJobsInGroup("a"));
4106 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4107 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
4108 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:434109
4110 ClientSocketHandle handle_lowest2;
4111 TestCompletionCallback callback_lowest2;
4112 EXPECT_EQ(ERR_IO_PENDING,
4113 handle_lowest2.Init("a", params_, LOWEST, SocketTag(),
4114 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504115 callback_lowest2.callback(),
4116 ClientSocketPool::ProxyAuthCallback(),
4117 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434118
Raul Tambre8335a6d2019-02-21 16:57:434119 EXPECT_EQ(3u, pool_->NumConnectJobsInGroup("a"));
4120 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4121 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
4122 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:434123
4124 // The top three requests in the queue should have jobs.
4125 EXPECT_TRUE(
4126 pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle_highest));
4127 EXPECT_TRUE(
4128 pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle_low));
4129 EXPECT_TRUE(
4130 pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle_lowest));
4131 EXPECT_FALSE(
4132 pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle_lowest2));
4133
4134 // Add another request with medium priority. It should steal the job from the
4135 // lowest priority request with a job.
4136 ClientSocketHandle handle_medium;
4137 TestCompletionCallback callback_medium;
4138 EXPECT_EQ(ERR_IO_PENDING,
4139 handle_medium.Init("a", params_, MEDIUM, SocketTag(),
4140 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504141 callback_medium.callback(),
4142 ClientSocketPool::ProxyAuthCallback(),
4143 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434144
Raul Tambre8335a6d2019-02-21 16:57:434145 EXPECT_EQ(3u, pool_->NumConnectJobsInGroup("a"));
4146 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4147 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
4148 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:434149 EXPECT_TRUE(
4150 pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle_highest));
4151 EXPECT_TRUE(
4152 pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle_medium));
4153 EXPECT_TRUE(
4154 pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle_low));
4155 EXPECT_FALSE(
4156 pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle_lowest));
4157 EXPECT_FALSE(
4158 pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle_lowest2));
4159}
4160
4161TEST_F(ClientSocketPoolBaseTest, ReprioritizeRequestStealsJob) {
4162 CreatePool(kDefaultMaxSockets, 1);
4163 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4164
4165 ClientSocketHandle handle1;
4166 TestCompletionCallback callback1;
4167 EXPECT_EQ(
4168 ERR_IO_PENDING,
4169 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
4170 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504171 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4172 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434173
Raul Tambre8335a6d2019-02-21 16:57:434174 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4175 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4176 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
4177 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:434178
4179 ClientSocketHandle handle2;
4180 TestCompletionCallback callback2;
4181 EXPECT_EQ(
4182 ERR_IO_PENDING,
4183 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
4184 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504185 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4186 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434187
Raul Tambre8335a6d2019-02-21 16:57:434188 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4189 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4190 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
4191 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:434192
4193 // The second request doesn't get a job because we are at the limit.
4194 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle1));
4195 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle2));
4196
4197 // Reprioritizing the second request places it above the first, and it steals
4198 // the job from the first request.
4199 pool_->SetPriority("a", &handle2, HIGHEST);
4200 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle2));
4201 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle1));
4202}
4203
4204TEST_F(ClientSocketPoolBaseTest, CancelRequestReassignsJob) {
4205 CreatePool(kDefaultMaxSockets, 1);
4206 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4207
4208 ClientSocketHandle handle1;
4209 TestCompletionCallback callback1;
4210 EXPECT_EQ(
4211 ERR_IO_PENDING,
4212 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
4213 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504214 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4215 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434216
Raul Tambre8335a6d2019-02-21 16:57:434217 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4218 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4219 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
4220 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:434221
4222 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle1));
4223
4224 ClientSocketHandle handle2;
4225 TestCompletionCallback callback2;
4226 EXPECT_EQ(
4227 ERR_IO_PENDING,
4228 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
4229 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504230 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4231 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434232
Raul Tambre8335a6d2019-02-21 16:57:434233 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4234 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4235 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
4236 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:434237
4238 // The second request doesn't get a job because we are the limit.
4239 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle1));
4240 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle2));
4241
4242 // The second request should get a job upon cancelling the first request.
4243 handle1.Reset();
Raul Tambre8335a6d2019-02-21 16:57:434244 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4245 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4246 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
4247 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:434248
4249 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle2));
4250}
4251
4252TEST_F(ClientSocketPoolBaseTest, JobCompletionReassignsJob) {
4253 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4254 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4255
4256 ClientSocketHandle handle1;
4257 TestCompletionCallback callback1;
4258 EXPECT_EQ(
4259 ERR_IO_PENDING,
4260 handle1.Init("a", params_, HIGHEST, SocketTag(),
4261 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504262 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4263 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434264
Raul Tambre8335a6d2019-02-21 16:57:434265 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4266 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4267 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
4268 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:434269
4270 ClientSocketHandle handle2;
4271 TestCompletionCallback callback2;
4272 EXPECT_EQ(
4273 ERR_IO_PENDING,
4274 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
4275 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504276 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4277 pool_.get(), NetLogWithSource()));
Lily Chenecebf932018-11-02 17:15:434278
Raul Tambre8335a6d2019-02-21 16:57:434279 EXPECT_EQ(2u, pool_->NumConnectJobsInGroup("a"));
4280 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4281 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
4282 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:434283
4284 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle1));
4285 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle2));
4286
4287 // The lower-priority job completes first. The higher-priority request should
4288 // get the socket, and the lower-priority request should get the remaining
4289 // job.
4290 client_socket_factory_.SignalJob(1);
4291 EXPECT_THAT(callback1.WaitForResult(), IsOk());
Raul Tambre8335a6d2019-02-21 16:57:434292 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4293 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroup("a"));
4294 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroup("a"));
Lily Chenecebf932018-11-02 17:15:434295 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
Raul Tambre8335a6d2019-02-21 16:57:434296 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
Lily Chenecebf932018-11-02 17:15:434297 EXPECT_TRUE(handle1.socket());
4298 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting("a", &handle2));
4299}
4300
[email protected]043b68c82013-08-22 23:41:524301class MockLayeredPool : public HigherLayeredPool {
[email protected]58e562f2013-04-22 17:32:204302 public:
4303 MockLayeredPool(TestClientSocketPool* pool,
4304 const std::string& group_name)
4305 : pool_(pool),
[email protected]58e562f2013-04-22 17:32:204306 group_name_(group_name),
4307 can_release_connection_(true) {
[email protected]043b68c82013-08-22 23:41:524308 pool_->AddHigherLayeredPool(this);
[email protected]58e562f2013-04-22 17:32:204309 }
4310
Daniel Cheng4496d0822018-04-26 21:52:154311 ~MockLayeredPool() override { pool_->RemoveHigherLayeredPool(this); }
[email protected]58e562f2013-04-22 17:32:204312
4313 int RequestSocket(TestClientSocketPool* pool) {
mmenked3641e12016-01-28 16:06:154314 scoped_refptr<TestSocketParams> params(new TestSocketParams());
Matt Menke28ac03e2019-02-25 22:25:504315 return handle_.Init(
4316 group_name_, params, DEFAULT_PRIORITY, SocketTag(),
4317 ClientSocketPool::RespectLimits::ENABLED, callback_.callback(),
4318 ClientSocketPool::ProxyAuthCallback(), pool, NetLogWithSource());
[email protected]58e562f2013-04-22 17:32:204319 }
4320
4321 int RequestSocketWithoutLimits(TestClientSocketPool* pool) {
mmenked3641e12016-01-28 16:06:154322 scoped_refptr<TestSocketParams> params(new TestSocketParams());
Matt Menke28ac03e2019-02-25 22:25:504323 return handle_.Init(
4324 group_name_, params, MAXIMUM_PRIORITY, SocketTag(),
4325 ClientSocketPool::RespectLimits::DISABLED, callback_.callback(),
4326 ClientSocketPool::ProxyAuthCallback(), pool, NetLogWithSource());
[email protected]58e562f2013-04-22 17:32:204327 }
4328
4329 bool ReleaseOneConnection() {
4330 if (!handle_.is_initialized() || !can_release_connection_) {
4331 return false;
4332 }
4333 handle_.socket()->Disconnect();
4334 handle_.Reset();
4335 return true;
4336 }
4337
4338 void set_can_release_connection(bool can_release_connection) {
4339 can_release_connection_ = can_release_connection;
4340 }
4341
4342 MOCK_METHOD0(CloseOneIdleConnection, bool());
4343
4344 private:
4345 TestClientSocketPool* const pool_;
[email protected]58e562f2013-04-22 17:32:204346 ClientSocketHandle handle_;
4347 TestCompletionCallback callback_;
4348 const std::string group_name_;
4349 bool can_release_connection_;
4350};
4351
[email protected]58e562f2013-04-22 17:32:204352// Tests the basic case of closing an idle socket in a higher layered pool when
4353// a new request is issued and the lower layer pool is stalled.
4354TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsHeldByLayeredPoolWhenNeeded) {
4355 CreatePool(1, 1);
4356 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4357
4358 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
robpercival214763f2016-07-01 23:27:014359 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204360 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4361 .WillOnce(Invoke(&mock_layered_pool,
4362 &MockLayeredPool::ReleaseOneConnection));
4363 ClientSocketHandle handle;
4364 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:504365 EXPECT_EQ(
4366 ERR_IO_PENDING,
4367 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
4368 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
4369 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4370 NetLogWithSource()));
robpercival214763f2016-07-01 23:27:014371 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204372}
4373
Matt Menke833678642019-03-05 22:05:514374// Tests the case that trying to close an idle socket in a higher layered pool
4375// fails.
4376TEST_F(ClientSocketPoolBaseTest,
4377 CloseIdleSocketsHeldByLayeredPoolWhenNeededFails) {
4378 CreatePool(1, 1);
4379 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4380
4381 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
4382 mock_layered_pool.set_can_release_connection(false);
4383 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
4384 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4385 .WillOnce(Invoke(&mock_layered_pool,
4386 &MockLayeredPool::ReleaseOneConnection));
4387 ClientSocketHandle handle;
4388 TestCompletionCallback callback;
4389 EXPECT_EQ(
4390 ERR_IO_PENDING,
4391 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
4392 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
4393 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4394 NetLogWithSource()));
4395 base::RunLoop().RunUntilIdle();
4396 EXPECT_FALSE(callback.have_result());
4397}
4398
[email protected]58e562f2013-04-22 17:32:204399// Same as above, but the idle socket is in the same group as the stalled
4400// socket, and closes the only other request in its group when closing requests
4401// in higher layered pools. This generally shouldn't happen, but it may be
4402// possible if a higher level pool issues a request and the request is
4403// subsequently cancelled. Even if it's not possible, best not to crash.
4404TEST_F(ClientSocketPoolBaseTest,
4405 CloseIdleSocketsHeldByLayeredPoolWhenNeededSameGroup) {
4406 CreatePool(2, 2);
4407 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4408
4409 // Need a socket in another group for the pool to be stalled (If a group
4410 // has the maximum number of connections already, it's not stalled).
4411 ClientSocketHandle handle1;
4412 TestCompletionCallback callback1;
Matt Menke28ac03e2019-02-25 22:25:504413 EXPECT_EQ(OK, handle1.Init("group1", params_, DEFAULT_PRIORITY, SocketTag(),
4414 ClientSocketPool::RespectLimits::ENABLED,
4415 callback1.callback(),
4416 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4417 NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204418
4419 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
robpercival214763f2016-07-01 23:27:014420 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204421 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4422 .WillOnce(Invoke(&mock_layered_pool,
4423 &MockLayeredPool::ReleaseOneConnection));
4424 ClientSocketHandle handle;
4425 TestCompletionCallback callback2;
Matt Menke28ac03e2019-02-25 22:25:504426 EXPECT_EQ(
4427 ERR_IO_PENDING,
4428 handle.Init("group2", params_, DEFAULT_PRIORITY, SocketTag(),
4429 ClientSocketPool::RespectLimits::ENABLED,
4430 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4431 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:014432 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204433}
4434
4435// Tests the case when an idle socket can be closed when a new request is
4436// issued, and the new request belongs to a group that was previously stalled.
4437TEST_F(ClientSocketPoolBaseTest,
4438 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded) {
4439 CreatePool(2, 2);
4440 std::list<TestConnectJob::JobType> job_types;
4441 job_types.push_back(TestConnectJob::kMockJob);
4442 job_types.push_back(TestConnectJob::kMockJob);
4443 job_types.push_back(TestConnectJob::kMockJob);
4444 job_types.push_back(TestConnectJob::kMockJob);
4445 connect_job_factory_->set_job_types(&job_types);
4446
4447 ClientSocketHandle handle1;
4448 TestCompletionCallback callback1;
Matt Menke28ac03e2019-02-25 22:25:504449 EXPECT_EQ(OK, handle1.Init("group1", params_, DEFAULT_PRIORITY, SocketTag(),
4450 ClientSocketPool::RespectLimits::ENABLED,
4451 callback1.callback(),
4452 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4453 NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204454
4455 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
robpercival214763f2016-07-01 23:27:014456 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204457 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4458 .WillRepeatedly(Invoke(&mock_layered_pool,
4459 &MockLayeredPool::ReleaseOneConnection));
4460 mock_layered_pool.set_can_release_connection(false);
4461
4462 // The third request is made when the socket pool is in a stalled state.
4463 ClientSocketHandle handle3;
4464 TestCompletionCallback callback3;
tfarina428341112016-09-22 13:38:204465 EXPECT_EQ(
4466 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:544467 handle3.Init("group3", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:204468 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504469 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
4470 pool_.get(), NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204471
4472 base::RunLoop().RunUntilIdle();
4473 EXPECT_FALSE(callback3.have_result());
4474
4475 // The fourth request is made when the pool is no longer stalled. The third
4476 // request should be serviced first, since it was issued first and has the
4477 // same priority.
4478 mock_layered_pool.set_can_release_connection(true);
4479 ClientSocketHandle handle4;
4480 TestCompletionCallback callback4;
tfarina428341112016-09-22 13:38:204481 EXPECT_EQ(
4482 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:544483 handle4.Init("group3", params_, DEFAULT_PRIORITY, SocketTag(),
tfarina428341112016-09-22 13:38:204484 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504485 callback4.callback(), ClientSocketPool::ProxyAuthCallback(),
4486 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:014487 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204488 EXPECT_FALSE(callback4.have_result());
4489
4490 // Closing a handle should free up another socket slot.
4491 handle1.Reset();
robpercival214763f2016-07-01 23:27:014492 EXPECT_THAT(callback4.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204493}
4494
4495// Tests the case when an idle socket can be closed when a new request is
4496// issued, and the new request belongs to a group that was previously stalled.
4497//
4498// The two differences from the above test are that the stalled requests are not
4499// in the same group as the layered pool's request, and the the fourth request
4500// has a higher priority than the third one, so gets a socket first.
4501TEST_F(ClientSocketPoolBaseTest,
4502 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded2) {
4503 CreatePool(2, 2);
4504 std::list<TestConnectJob::JobType> job_types;
4505 job_types.push_back(TestConnectJob::kMockJob);
4506 job_types.push_back(TestConnectJob::kMockJob);
4507 job_types.push_back(TestConnectJob::kMockJob);
4508 job_types.push_back(TestConnectJob::kMockJob);
4509 connect_job_factory_->set_job_types(&job_types);
4510
4511 ClientSocketHandle handle1;
4512 TestCompletionCallback callback1;
Matt Menke28ac03e2019-02-25 22:25:504513 EXPECT_EQ(OK, handle1.Init("group1", params_, DEFAULT_PRIORITY, SocketTag(),
4514 ClientSocketPool::RespectLimits::ENABLED,
4515 callback1.callback(),
4516 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4517 NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204518
4519 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
robpercival214763f2016-07-01 23:27:014520 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204521 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4522 .WillRepeatedly(Invoke(&mock_layered_pool,
4523 &MockLayeredPool::ReleaseOneConnection));
4524 mock_layered_pool.set_can_release_connection(false);
4525
4526 // The third request is made when the socket pool is in a stalled state.
4527 ClientSocketHandle handle3;
4528 TestCompletionCallback callback3;
tfarina428341112016-09-22 13:38:204529 EXPECT_EQ(
4530 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:544531 handle3.Init("group3", params_, MEDIUM, SocketTag(),
tfarina428341112016-09-22 13:38:204532 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504533 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
4534 pool_.get(), NetLogWithSource()));
[email protected]58e562f2013-04-22 17:32:204535
4536 base::RunLoop().RunUntilIdle();
4537 EXPECT_FALSE(callback3.have_result());
4538
4539 // The fourth request is made when the pool is no longer stalled. This
4540 // request has a higher priority than the third request, so is serviced first.
4541 mock_layered_pool.set_can_release_connection(true);
4542 ClientSocketHandle handle4;
4543 TestCompletionCallback callback4;
tfarina428341112016-09-22 13:38:204544 EXPECT_EQ(
4545 ERR_IO_PENDING,
Paul Jensen8d6f87ec2018-01-13 00:46:544546 handle4.Init("group3", params_, HIGHEST, SocketTag(),
tfarina428341112016-09-22 13:38:204547 ClientSocketPool::RespectLimits::ENABLED,
Matt Menke28ac03e2019-02-25 22:25:504548 callback4.callback(), ClientSocketPool::ProxyAuthCallback(),
4549 pool_.get(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:014550 EXPECT_THAT(callback4.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204551 EXPECT_FALSE(callback3.have_result());
4552
4553 // Closing a handle should free up another socket slot.
4554 handle1.Reset();
robpercival214763f2016-07-01 23:27:014555 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204556}
4557
4558TEST_F(ClientSocketPoolBaseTest,
4559 CloseMultipleIdleSocketsHeldByLayeredPoolWhenNeeded) {
4560 CreatePool(1, 1);
4561 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4562
4563 MockLayeredPool mock_layered_pool1(pool_.get(), "foo");
robpercival214763f2016-07-01 23:27:014564 EXPECT_THAT(mock_layered_pool1.RequestSocket(pool_.get()), IsOk());
[email protected]58e562f2013-04-22 17:32:204565 EXPECT_CALL(mock_layered_pool1, CloseOneIdleConnection())
4566 .WillRepeatedly(Invoke(&mock_layered_pool1,
4567 &MockLayeredPool::ReleaseOneConnection));
4568 MockLayeredPool mock_layered_pool2(pool_.get(), "bar");
robpercival214763f2016-07-01 23:27:014569 EXPECT_THAT(mock_layered_pool2.RequestSocketWithoutLimits(pool_.get()),
4570 IsOk());
[email protected]58e562f2013-04-22 17:32:204571 EXPECT_CALL(mock_layered_pool2, CloseOneIdleConnection())
4572 .WillRepeatedly(Invoke(&mock_layered_pool2,
4573 &MockLayeredPool::ReleaseOneConnection));
4574 ClientSocketHandle handle;
4575 TestCompletionCallback callback;
Matt Menke28ac03e2019-02-25 22:25:504576 EXPECT_EQ(
4577 ERR_IO_PENDING,
4578 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
4579 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
4580 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4581 NetLogWithSource()));
robpercival214763f2016-07-01 23:27:014582 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]58e562f2013-04-22 17:32:204583}
4584
[email protected]b021ece62013-06-11 11:06:334585// Test that when a socket pool and group are at their limits, a request
mmenked3641e12016-01-28 16:06:154586// with RespectLimits::DISABLED triggers creation of a new socket, and gets the
4587// socket instead of a request with the same priority that was issued earlier,
4588// but has RespectLimits::ENABLED.
[email protected]b021ece62013-06-11 11:06:334589TEST_F(ClientSocketPoolBaseTest, IgnoreLimits) {
[email protected]b021ece62013-06-11 11:06:334590 CreatePool(1, 1);
4591
4592 // Issue a request to reach the socket pool limit.
mmenked3641e12016-01-28 16:06:154593 EXPECT_EQ(
4594 OK, StartRequestWithIgnoreLimits(
4595 "a", MAXIMUM_PRIORITY, ClientSocketPool::RespectLimits::ENABLED));
Raul Tambre8335a6d2019-02-21 16:57:434596 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
[email protected]b021ece62013-06-11 11:06:334597
4598 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4599
mmenked3641e12016-01-28 16:06:154600 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
4601 "a", MAXIMUM_PRIORITY,
4602 ClientSocketPool::RespectLimits::ENABLED));
Raul Tambre8335a6d2019-02-21 16:57:434603 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
[email protected]b021ece62013-06-11 11:06:334604
mmenked3641e12016-01-28 16:06:154605 // Issue a request that ignores the limits, so a new ConnectJob is
4606 // created.
4607 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
4608 "a", MAXIMUM_PRIORITY,
4609 ClientSocketPool::RespectLimits::DISABLED));
Raul Tambre8335a6d2019-02-21 16:57:434610 ASSERT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
[email protected]b021ece62013-06-11 11:06:334611
robpercival214763f2016-07-01 23:27:014612 EXPECT_THAT(request(2)->WaitForResult(), IsOk());
[email protected]b021ece62013-06-11 11:06:334613 EXPECT_FALSE(request(1)->have_result());
4614}
4615
[email protected]c55fabd2013-11-04 23:26:564616// Test that when a socket pool and group are at their limits, a ConnectJob
mmenked3641e12016-01-28 16:06:154617// issued for a request with RespectLimits::DISABLED is not cancelled when a
4618// request with RespectLimits::ENABLED issued to the same group is cancelled.
[email protected]c55fabd2013-11-04 23:26:564619TEST_F(ClientSocketPoolBaseTest, IgnoreLimitsCancelOtherJob) {
[email protected]c55fabd2013-11-04 23:26:564620 CreatePool(1, 1);
4621
4622 // Issue a request to reach the socket pool limit.
mmenked3641e12016-01-28 16:06:154623 EXPECT_EQ(
4624 OK, StartRequestWithIgnoreLimits(
4625 "a", MAXIMUM_PRIORITY, ClientSocketPool::RespectLimits::ENABLED));
Raul Tambre8335a6d2019-02-21 16:57:434626 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
[email protected]c55fabd2013-11-04 23:26:564627
4628 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4629
mmenked3641e12016-01-28 16:06:154630 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
4631 "a", MAXIMUM_PRIORITY,
4632 ClientSocketPool::RespectLimits::ENABLED));
Raul Tambre8335a6d2019-02-21 16:57:434633 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
[email protected]c55fabd2013-11-04 23:26:564634
mmenked3641e12016-01-28 16:06:154635 // Issue a request with RespectLimits::DISABLED, so a new ConnectJob is
4636 // created.
4637 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
4638 "a", MAXIMUM_PRIORITY,
4639 ClientSocketPool::RespectLimits::DISABLED));
Raul Tambre8335a6d2019-02-21 16:57:434640 ASSERT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
[email protected]b021ece62013-06-11 11:06:334641
mmenked3641e12016-01-28 16:06:154642 // Cancel the pending request with RespectLimits::ENABLED. The ConnectJob
[email protected]b021ece62013-06-11 11:06:334643 // should not be cancelled.
4644 request(1)->handle()->Reset();
Raul Tambre8335a6d2019-02-21 16:57:434645 ASSERT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
[email protected]b021ece62013-06-11 11:06:334646
robpercival214763f2016-07-01 23:27:014647 EXPECT_THAT(request(2)->WaitForResult(), IsOk());
[email protected]b021ece62013-06-11 11:06:334648 EXPECT_FALSE(request(1)->have_result());
4649}
4650
Matt Menkeb57663b32019-03-01 17:17:104651TEST_F(ClientSocketPoolBaseTest, ProxyAuthNoAuthCallback) {
4652 CreatePool(1, 1);
4653
4654 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
4655
4656 ClientSocketHandle handle;
4657 TestCompletionCallback callback;
4658 EXPECT_EQ(
4659 ERR_IO_PENDING,
4660 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
4661 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
4662 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4663 NetLogWithSource()));
4664
4665 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4666
4667 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_PROXY_AUTH_REQUESTED));
4668 EXPECT_FALSE(handle.is_initialized());
4669 EXPECT_FALSE(handle.socket());
4670
4671 // The group should now be empty, and thus be deleted.
4672 EXPECT_FALSE(pool_->HasGroup("a"));
4673}
4674
4675class TestAuthHelper {
4676 public:
4677 TestAuthHelper() = default;
4678 ~TestAuthHelper() = default;
4679
4680 void InitHandle(scoped_refptr<TestSocketParams> params,
4681 TestClientSocketPool* pool,
4682 RequestPriority priority = DEFAULT_PRIORITY,
4683 ClientSocketPool::RespectLimits respect_limits =
4684 ClientSocketPool::RespectLimits::ENABLED,
4685 const char* group_name = "a") {
4686 EXPECT_EQ(ERR_IO_PENDING,
4687 handle_.Init(group_name, params.get(), priority, SocketTag(),
4688 respect_limits, callback_.callback(),
4689 base::BindRepeating(&TestAuthHelper::AuthCallback,
4690 base::Unretained(this)),
4691 pool, NetLogWithSource()));
4692 }
4693
4694 void WaitForAuth() {
4695 run_loop_ = std::make_unique<base::RunLoop>();
4696 run_loop_->Run();
4697 run_loop_.reset();
4698 }
4699
4700 void WaitForAuthAndRestartSync() {
4701 restart_sync_ = true;
4702 WaitForAuth();
4703 restart_sync_ = false;
4704 }
4705
4706 void WaitForAuthAndResetHandleSync() {
4707 reset_handle_sync_ = true;
4708 WaitForAuth();
4709 reset_handle_sync_ = false;
4710 }
4711
4712 void RestartWithAuth() {
4713 DCHECK(restart_with_auth_callback_);
4714 std::move(restart_with_auth_callback_).Run();
4715 }
4716
4717 int WaitForResult() {
4718 int result = callback_.WaitForResult();
4719 // There shouldn't be any callback waiting to be invoked once the request is
4720 // complete.
4721 EXPECT_FALSE(restart_with_auth_callback_);
4722 // The socket should only be initialized on success.
4723 EXPECT_EQ(result == OK, handle_.is_initialized());
4724 EXPECT_EQ(result == OK, handle_.socket() != nullptr);
4725 return result;
4726 }
4727
4728 ClientSocketHandle* handle() { return &handle_; }
4729 int auth_count() const { return auth_count_; }
4730 int have_result() const { return callback_.have_result(); }
4731
4732 private:
4733 void AuthCallback(const HttpResponseInfo& response,
4734 HttpAuthController* auth_controller,
4735 base::OnceClosure restart_with_auth_callback) {
4736 EXPECT_FALSE(restart_with_auth_callback_);
4737 EXPECT_TRUE(restart_with_auth_callback);
4738
4739 // Once there's a result, this method shouldn't be invoked again.
4740 EXPECT_FALSE(callback_.have_result());
4741
4742 ++auth_count_;
4743 run_loop_->Quit();
4744 if (restart_sync_) {
4745 std::move(restart_with_auth_callback).Run();
4746 return;
4747 }
4748
4749 restart_with_auth_callback_ = std::move(restart_with_auth_callback);
4750
4751 if (reset_handle_sync_) {
4752 handle_.Reset();
4753 return;
4754 }
4755 }
4756
4757 std::unique_ptr<base::RunLoop> run_loop_;
4758 base::OnceClosure restart_with_auth_callback_;
4759
4760 bool restart_sync_ = false;
4761 bool reset_handle_sync_ = false;
4762
4763 ClientSocketHandle handle_;
4764 int auth_count_ = 0;
4765 TestCompletionCallback callback_;
4766
4767 DISALLOW_COPY_AND_ASSIGN(TestAuthHelper);
4768};
4769
4770TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnce) {
4771 CreatePool(1, 1);
4772 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
4773
4774 TestAuthHelper auth_helper;
4775 auth_helper.InitHandle(params_, pool_.get());
4776 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
Matt Menke4b69f932019-03-04 16:20:014777 EXPECT_EQ(LOAD_STATE_CONNECTING,
4778 pool_->GetLoadState("a", auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:104779
4780 auth_helper.WaitForAuth();
4781 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
Matt Menke4b69f932019-03-04 16:20:014782 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
4783 pool_->GetLoadState("a", auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:104784
4785 auth_helper.RestartWithAuth();
4786 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
Matt Menke4b69f932019-03-04 16:20:014787 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
4788 pool_->GetLoadState("a", auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:104789
4790 EXPECT_THAT(auth_helper.WaitForResult(), IsOk());
4791 EXPECT_EQ(1, auth_helper.auth_count());
4792 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
4793 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
4794 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
4795 EXPECT_EQ(0, pool_->IdleSocketCount());
4796}
4797
4798TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceSync) {
4799 CreatePool(1, 1);
4800 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
4801
4802 TestAuthHelper auth_helper;
4803 auth_helper.InitHandle(params_, pool_.get());
4804 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
Matt Menke4b69f932019-03-04 16:20:014805 EXPECT_EQ(LOAD_STATE_CONNECTING,
4806 pool_->GetLoadState("a", auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:104807
4808 auth_helper.WaitForAuthAndRestartSync();
4809 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
Matt Menke4b69f932019-03-04 16:20:014810 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
4811 pool_->GetLoadState("a", auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:104812
4813 EXPECT_THAT(auth_helper.WaitForResult(), IsOk());
4814 EXPECT_EQ(1, auth_helper.auth_count());
4815 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
4816 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
4817 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
4818 EXPECT_EQ(0, pool_->IdleSocketCount());
4819}
4820
4821TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceFails) {
4822 CreatePool(1, 1);
4823 connect_job_factory_->set_job_type(
4824 TestConnectJob::kMockAuthChallengeOnceFailingJob);
4825
4826 TestAuthHelper auth_helper;
4827 auth_helper.InitHandle(params_, pool_.get());
4828 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4829
4830 auth_helper.WaitForAuth();
4831 auth_helper.RestartWithAuth();
4832 EXPECT_THAT(auth_helper.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
4833
4834 EXPECT_EQ(1, auth_helper.auth_count());
4835 EXPECT_FALSE(pool_->HasGroup("a"));
4836 EXPECT_EQ(0, pool_->IdleSocketCount());
4837}
4838
4839TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceSyncFails) {
4840 CreatePool(1, 1);
4841 connect_job_factory_->set_job_type(
4842 TestConnectJob::kMockAuthChallengeOnceFailingJob);
4843
4844 TestAuthHelper auth_helper;
4845 auth_helper.InitHandle(params_, pool_.get());
4846 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4847
4848 auth_helper.WaitForAuthAndRestartSync();
4849 EXPECT_THAT(auth_helper.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
4850
4851 EXPECT_EQ(1, auth_helper.auth_count());
4852 EXPECT_FALSE(pool_->HasGroup("a"));
4853 EXPECT_EQ(0, pool_->IdleSocketCount());
4854}
4855
4856TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceDeleteHandle) {
4857 CreatePool(1, 1);
4858 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
4859
4860 TestAuthHelper auth_helper;
4861 auth_helper.InitHandle(params_, pool_.get());
4862 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4863
4864 auth_helper.WaitForAuth();
4865 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4866
4867 auth_helper.handle()->Reset();
4868
4869 EXPECT_EQ(1, auth_helper.auth_count());
4870 EXPECT_FALSE(pool_->HasGroup("a"));
4871 EXPECT_EQ(0, pool_->IdleSocketCount());
4872 EXPECT_FALSE(auth_helper.handle()->is_initialized());
4873 EXPECT_FALSE(auth_helper.handle()->socket());
4874}
4875
4876TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceDeleteHandleSync) {
4877 CreatePool(1, 1);
4878 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
4879
4880 TestAuthHelper auth_helper;
4881 auth_helper.InitHandle(params_, pool_.get());
4882 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4883
4884 auth_helper.WaitForAuthAndResetHandleSync();
4885 EXPECT_EQ(1, auth_helper.auth_count());
4886 EXPECT_FALSE(pool_->HasGroup("a"));
4887 EXPECT_EQ(0, pool_->IdleSocketCount());
4888 EXPECT_FALSE(auth_helper.handle()->is_initialized());
4889 EXPECT_FALSE(auth_helper.handle()->socket());
4890}
4891
4892TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceFlushWithError) {
4893 CreatePool(1, 1);
4894 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
4895
4896 TestAuthHelper auth_helper;
4897 auth_helper.InitHandle(params_, pool_.get());
4898 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4899
4900 auth_helper.WaitForAuth();
4901
4902 pool_->FlushWithError(ERR_FAILED);
4903 base::RunLoop().RunUntilIdle();
4904
4905 // When flushing the socket pool, bound sockets should delay returning the
4906 // error until completion.
4907 EXPECT_FALSE(auth_helper.have_result());
4908 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4909 EXPECT_EQ(0, pool_->IdleSocketCount());
4910
4911 auth_helper.RestartWithAuth();
4912 // The callback should be called asynchronously.
4913 EXPECT_FALSE(auth_helper.have_result());
4914
4915 EXPECT_THAT(auth_helper.WaitForResult(), IsError(ERR_FAILED));
4916 EXPECT_FALSE(pool_->HasGroup("a"));
4917 EXPECT_EQ(0, pool_->IdleSocketCount());
4918}
4919
4920TEST_F(ClientSocketPoolBaseTest, ProxyAuthTwice) {
4921 CreatePool(1, 1);
4922 connect_job_factory_->set_job_type(
4923 TestConnectJob::kMockAuthChallengeTwiceJob);
4924
4925 TestAuthHelper auth_helper;
4926 auth_helper.InitHandle(params_, pool_.get());
4927 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
Matt Menke4b69f932019-03-04 16:20:014928 EXPECT_EQ(LOAD_STATE_CONNECTING,
4929 pool_->GetLoadState("a", auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:104930
4931 auth_helper.WaitForAuth();
4932 auth_helper.RestartWithAuth();
4933 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4934 EXPECT_EQ(1, auth_helper.auth_count());
Matt Menke4b69f932019-03-04 16:20:014935 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
4936 pool_->GetLoadState("a", auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:104937
4938 auth_helper.WaitForAuth();
Matt Menke4b69f932019-03-04 16:20:014939 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4940 EXPECT_EQ(2, auth_helper.auth_count());
4941 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
4942 pool_->GetLoadState("a", auth_helper.handle()));
4943
Matt Menkeb57663b32019-03-01 17:17:104944 auth_helper.RestartWithAuth();
4945 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4946 EXPECT_EQ(2, auth_helper.auth_count());
Matt Menke4b69f932019-03-04 16:20:014947 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
4948 pool_->GetLoadState("a", auth_helper.handle()));
Matt Menkeb57663b32019-03-01 17:17:104949
4950 EXPECT_THAT(auth_helper.WaitForResult(), IsOk());
4951 EXPECT_EQ(2, auth_helper.auth_count());
4952 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
4953 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
4954 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
4955 EXPECT_EQ(0, pool_->IdleSocketCount());
4956}
4957
4958TEST_F(ClientSocketPoolBaseTest, ProxyAuthTwiceFails) {
4959 CreatePool(1, 1);
4960 connect_job_factory_->set_job_type(
4961 TestConnectJob::kMockAuthChallengeTwiceFailingJob);
4962
4963 TestAuthHelper auth_helper;
4964 auth_helper.InitHandle(params_, pool_.get());
4965 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4966
4967 auth_helper.WaitForAuth();
4968 auth_helper.RestartWithAuth();
4969 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4970 EXPECT_EQ(1, auth_helper.auth_count());
4971
4972 auth_helper.WaitForAuth();
4973 auth_helper.RestartWithAuth();
4974 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4975 EXPECT_EQ(2, auth_helper.auth_count());
4976
4977 EXPECT_THAT(auth_helper.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
4978 EXPECT_EQ(2, auth_helper.auth_count());
4979 EXPECT_FALSE(pool_->HasGroup("a"));
4980 EXPECT_EQ(0, pool_->IdleSocketCount());
4981}
4982
4983// Makes sure that when a bound request is destroyed, a new ConnectJob is
4984// created, if needed.
4985TEST_F(ClientSocketPoolBaseTest,
4986 ProxyAuthCreateNewConnectJobOnDestroyBoundRequest) {
4987 CreatePool(1 /* max_sockets */, 1 /* max_sockets_per_group */);
4988 connect_job_factory_->set_job_type(
4989 TestConnectJob::kMockAuthChallengeOnceFailingJob);
4990
4991 // First request creates a ConnectJob.
4992 TestAuthHelper auth_helper1;
4993 auth_helper1.InitHandle(params_, pool_.get());
4994 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
4995
4996 // A second request come in, but no new ConnectJob is needed, since the limit
4997 // has been reached.
4998 TestAuthHelper auth_helper2;
4999 auth_helper2.InitHandle(params_, pool_.get());
5000 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
5001
5002 // Run until the auth callback for the first request is invoked.
5003 auth_helper1.WaitForAuth();
5004 EXPECT_EQ(0, auth_helper2.auth_count());
5005 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
5006 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
5007 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
5008
5009 // Make connect jobs succeed, then cancel the first request, which should
5010 // destroy the bound ConnectJob, and cause a new ConnectJob to start.
5011 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
5012 auth_helper1.handle()->Reset();
5013 EXPECT_EQ(0, auth_helper2.auth_count());
5014 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
5015
5016 // The second ConnectJob should succeed.
5017 EXPECT_THAT(auth_helper2.WaitForResult(), IsOk());
5018 EXPECT_EQ(0, auth_helper2.auth_count());
5019 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("a"));
5020}
5021
5022// Makes sure that when a bound request is destroyed, a new ConnectJob is
5023// created for another group, if needed.
5024TEST_F(ClientSocketPoolBaseTest,
5025 ProxyAuthCreateNewConnectJobOnDestroyBoundRequestDifferentGroups) {
5026 CreatePool(1 /* max_sockets */, 1 /* max_sockets_per_group */);
5027 connect_job_factory_->set_job_type(
5028 TestConnectJob::kMockAuthChallengeOnceFailingJob);
5029
5030 // First request creates a ConnectJob.
5031 TestAuthHelper auth_helper1;
5032 auth_helper1.InitHandle(params_, pool_.get(), DEFAULT_PRIORITY);
5033 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
5034
5035 // A second request come in, but no new ConnectJob is needed, since the limit
5036 // has been reached.
5037 TestAuthHelper auth_helper2;
5038 auth_helper2.InitHandle(params_, pool_.get(), DEFAULT_PRIORITY,
5039 ClientSocketPool::RespectLimits::ENABLED, "b");
5040 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
5041 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("b"));
5042
5043 // Run until the auth callback for the first request is invoked.
5044 auth_helper1.WaitForAuth();
5045 EXPECT_EQ(0, auth_helper2.auth_count());
5046 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
5047 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
5048 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
5049 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("b"));
5050 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
5051 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("b"));
5052
5053 // Make connect jobs succeed, then cancel the first request, which should
5054 // destroy the bound ConnectJob, and cause a new ConnectJob to start for the
5055 // other group.
5056 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
5057 auth_helper1.handle()->Reset();
5058 EXPECT_EQ(0, auth_helper2.auth_count());
5059 EXPECT_FALSE(pool_->HasGroup("a"));
5060 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("b"));
5061
5062 // The second ConnectJob should succeed.
5063 EXPECT_THAT(auth_helper2.WaitForResult(), IsOk());
5064 EXPECT_EQ(0, auth_helper2.auth_count());
5065 EXPECT_FALSE(pool_->HasGroup("a"));
5066 EXPECT_EQ(0u, pool_->NumConnectJobsInGroup("b"));
5067}
5068
5069// Test that once an auth challenge is bound, that's the request that gets all
5070// subsequent calls and the socket itself.
5071TEST_F(ClientSocketPoolBaseTest, ProxyAuthStaysBound) {
5072 CreatePool(1, 1);
5073 connect_job_factory_->set_job_type(
5074 TestConnectJob::kMockAuthChallengeTwiceJob);
5075
5076 // First request creates a ConnectJob.
5077 TestAuthHelper auth_helper1;
5078 auth_helper1.InitHandle(params_, pool_.get(), LOWEST);
5079 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
5080
5081 // A second, higher priority request is made.
5082 TestAuthHelper auth_helper2;
5083 auth_helper2.InitHandle(params_, pool_.get(), LOW);
5084 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
5085
5086 // Run until the auth callback for the second request is invoked.
5087 auth_helper2.WaitForAuth();
5088 EXPECT_EQ(0, auth_helper1.auth_count());
5089 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
5090 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
5091 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup("a"));
5092
5093 // Start a higher priority job. It shouldn't be able to steal |auth_helper2|'s
5094 // ConnectJob.
5095 TestAuthHelper auth_helper3;
5096 auth_helper3.InitHandle(params_, pool_.get(), HIGHEST);
5097 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
5098
5099 // Start a higher job that ignores limits, creating a hanging socket. It
5100 // shouldn't be able to steal |auth_helper2|'s ConnectJob.
5101 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
5102 TestAuthHelper auth_helper4;
5103 auth_helper4.InitHandle(params_, pool_.get(), HIGHEST,
5104 ClientSocketPool::RespectLimits::DISABLED);
5105 EXPECT_EQ(2u, pool_->NumConnectJobsInGroup("a"));
5106
5107 // Restart with auth, and |auth_helper2|'s auth method should be invoked
5108 // again.
5109 auth_helper2.RestartWithAuth();
5110 auth_helper2.WaitForAuth();
5111 EXPECT_EQ(0, auth_helper1.auth_count());
5112 EXPECT_FALSE(auth_helper1.have_result());
5113 EXPECT_EQ(2, auth_helper2.auth_count());
5114 EXPECT_FALSE(auth_helper2.have_result());
5115 EXPECT_EQ(0, auth_helper3.auth_count());
5116 EXPECT_FALSE(auth_helper3.have_result());
5117 EXPECT_EQ(0, auth_helper4.auth_count());
5118 EXPECT_FALSE(auth_helper4.have_result());
5119
5120 // Advance auth again, and |auth_helper2| should get the socket.
5121 auth_helper2.RestartWithAuth();
5122 EXPECT_THAT(auth_helper2.WaitForResult(), IsOk());
5123 // The hung ConnectJob for the RespectLimits::DISABLED request is still in the
5124 // socket pool.
5125 EXPECT_EQ(1u, pool_->NumConnectJobsInGroup("a"));
5126 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
5127 EXPECT_EQ(0, auth_helper1.auth_count());
5128 EXPECT_FALSE(auth_helper1.have_result());
5129 EXPECT_EQ(0, auth_helper3.auth_count());
5130 EXPECT_FALSE(auth_helper3.have_result());
5131 EXPECT_EQ(0, auth_helper4.auth_count());
5132 EXPECT_FALSE(auth_helper4.have_result());
5133
5134 // If the socket is returned to the socket pool, the RespectLimits::DISABLED
5135 // socket request should be able to claim it.
5136 auth_helper2.handle()->Reset();
5137 EXPECT_THAT(auth_helper4.WaitForResult(), IsOk());
5138 EXPECT_EQ(0, auth_helper1.auth_count());
5139 EXPECT_FALSE(auth_helper1.have_result());
5140 EXPECT_EQ(0, auth_helper3.auth_count());
5141 EXPECT_FALSE(auth_helper3.have_result());
5142 EXPECT_EQ(0, auth_helper4.auth_count());
5143}
5144
[email protected]f6d1d6eb2009-06-24 20:16:095145} // namespace
5146
5147} // namespace net