blob: 21269bbc5894831448b541075de0cb37f75e7f99 [file] [log] [blame]
[email protected]e34400c32012-01-24 02:49:331// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]f6d1d6eb2009-06-24 20:16:092// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]ab838892009-06-30 18:49:055#include "net/socket/client_socket_pool_base.h"
[email protected]f6d1d6eb2009-06-24 20:16:096
tbansalf82cc8e2015-10-14 20:05:497#include <stdint.h>
dchengc7eeda422015-12-26 03:56:488#include <utility>
[email protected]51fdc7c2012-04-10 19:19:489#include <vector>
10
[email protected]6ecf2b92011-12-15 01:14:5211#include "base/bind.h"
12#include "base/bind_helpers.h"
[email protected]2041cf342010-02-19 03:15:5913#include "base/callback.h"
skyostil4891b25b2015-06-11 11:43:4514#include "base/location.h"
mmenke33d24423d2015-05-19 19:41:0915#include "base/logging.h"
Avi Drissman13fc8932015-12-20 04:40:4616#include "base/macros.h"
[email protected]3b63f8f42011-03-28 01:54:1517#include "base/memory/ref_counted.h"
18#include "base/memory/scoped_vector.h"
[email protected]6ea7b152011-12-21 21:21:1319#include "base/memory/weak_ptr.h"
[email protected]18b577412013-07-18 04:19:1520#include "base/message_loop/message_loop.h"
[email protected]034df0f32013-01-07 23:17:4821#include "base/run_loop.h"
skyostil4891b25b2015-06-11 11:43:4522#include "base/single_thread_task_runner.h"
[email protected]fc9be5802013-06-11 10:56:5123#include "base/strings/string_number_conversions.h"
[email protected]18b577412013-07-18 04:19:1524#include "base/strings/stringprintf.h"
[email protected]f214f8792011-01-01 02:17:0825#include "base/threading/platform_thread.h"
gabf767595f2016-05-11 18:50:3526#include "base/threading/thread_task_runner_handle.h"
[email protected]f3a1c642011-07-12 19:15:0327#include "base/values.h"
[email protected]034df0f32013-01-07 23:17:4828#include "net/base/load_timing_info.h"
[email protected]b258e0792013-01-12 07:11:5929#include "net/base/load_timing_info_test_util.h"
[email protected]d8eb84242010-09-25 02:25:0630#include "net/base/net_errors.h"
[email protected]ac790b42009-12-02 04:31:3131#include "net/base/request_priority.h"
[email protected]f6d1d6eb2009-06-24 20:16:0932#include "net/base/test_completion_callback.h"
[email protected]277d5942010-08-11 21:02:3533#include "net/http/http_response_headers.h"
eroman87c53d62015-04-02 06:51:0734#include "net/log/net_log.h"
mmenke16a7cbdd2015-04-24 23:00:5635#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4636#include "net/log/test_net_log_entry.h"
37#include "net/log/test_net_log_util.h"
[email protected]f6d1d6eb2009-06-24 20:16:0938#include "net/socket/client_socket_factory.h"
39#include "net/socket/client_socket_handle.h"
tbansalca83c002016-04-28 20:56:2840#include "net/socket/socket_performance_watcher.h"
[email protected]75439d3b2009-07-23 22:11:1741#include "net/socket/socket_test_util.h"
[email protected]18ccfdb2013-08-15 00:13:4442#include "net/socket/ssl_client_socket.h"
[email protected]3268023f2011-05-05 00:08:1043#include "net/socket/stream_socket.h"
[email protected]18ccfdb2013-08-15 00:13:4444#include "net/udp/datagram_client_socket.h"
[email protected]51fdc7c2012-04-10 19:19:4845#include "testing/gmock/include/gmock/gmock.h"
[email protected]f6d1d6eb2009-06-24 20:16:0946#include "testing/gtest/include/gtest/gtest.h"
47
[email protected]51fdc7c2012-04-10 19:19:4848using ::testing::Invoke;
49using ::testing::Return;
50
[email protected]f6d1d6eb2009-06-24 20:16:0951namespace net {
52
53namespace {
54
[email protected]211d21722009-07-22 15:48:5355const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2056const int kDefaultMaxSocketsPerGroup = 2;
[email protected]0b7648c2009-07-06 20:14:0157
[email protected]034df0f32013-01-07 23:17:4858// Make sure |handle| sets load times correctly when it has been assigned a
59// reused socket.
60void TestLoadTimingInfoConnectedReused(const ClientSocketHandle& handle) {
61 LoadTimingInfo load_timing_info;
62 // Only pass true in as |is_reused|, as in general, HttpStream types should
63 // have stricter concepts of reuse than socket pools.
64 EXPECT_TRUE(handle.GetLoadTimingInfo(true, &load_timing_info));
65
66 EXPECT_EQ(true, load_timing_info.socket_reused);
67 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
68
[email protected]b258e0792013-01-12 07:11:5969 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
70 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:4871}
72
73// Make sure |handle| sets load times correctly when it has been assigned a
[email protected]b021ece62013-06-11 11:06:3374// fresh socket. Also runs TestLoadTimingInfoConnectedReused, since the owner
[email protected]034df0f32013-01-07 23:17:4875// of a connection where |is_reused| is false may consider the connection
76// reused.
77void TestLoadTimingInfoConnectedNotReused(const ClientSocketHandle& handle) {
78 EXPECT_FALSE(handle.is_reused());
79
80 LoadTimingInfo load_timing_info;
81 EXPECT_TRUE(handle.GetLoadTimingInfo(false, &load_timing_info));
82
83 EXPECT_FALSE(load_timing_info.socket_reused);
84 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
85
[email protected]b258e0792013-01-12 07:11:5986 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
87 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
88 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:4889
90 TestLoadTimingInfoConnectedReused(handle);
91}
92
93// Make sure |handle| sets load times correctly, in the case that it does not
94// currently have a socket.
95void TestLoadTimingInfoNotConnected(const ClientSocketHandle& handle) {
96 // Should only be set to true once a socket is assigned, if at all.
97 EXPECT_FALSE(handle.is_reused());
98
99 LoadTimingInfo load_timing_info;
100 EXPECT_FALSE(handle.GetLoadTimingInfo(false, &load_timing_info));
101
102 EXPECT_FALSE(load_timing_info.socket_reused);
103 EXPECT_EQ(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
104
[email protected]b258e0792013-01-12 07:11:59105 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
106 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:48107}
108
[email protected]df4b4ef2010-07-12 18:25:21109class TestSocketParams : public base::RefCounted<TestSocketParams> {
[email protected]5acdce12011-03-30 13:00:20110 public:
mmenked3641e12016-01-28 16:06:15111 explicit TestSocketParams() {}
[email protected]51fdc7c2012-04-10 19:19:48112
[email protected]df4b4ef2010-07-12 18:25:21113 private:
114 friend class base::RefCounted<TestSocketParams>;
115 ~TestSocketParams() {}
116};
[email protected]7fc5b09a2010-02-27 00:07:38117typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
[email protected]d80a4322009-08-14 07:07:49118
[email protected]3268023f2011-05-05 00:08:10119class MockClientSocket : public StreamSocket {
[email protected]f6d1d6eb2009-06-24 20:16:09120 public:
[email protected]034df0f32013-01-07 23:17:48121 explicit MockClientSocket(net::NetLog* net_log)
122 : connected_(false),
[email protected]0dc88b32014-03-26 20:12:28123 has_unread_data_(false),
ttuttle859dc7a2015-04-23 19:42:29124 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)),
125 was_used_to_convey_data_(false) {}
[email protected]f6d1d6eb2009-06-24 20:16:09126
[email protected]0dc88b32014-03-26 20:12:28127 // Sets whether the socket has unread data. If true, the next call to Read()
128 // will return 1 byte and IsConnectedAndIdle() will return false.
129 void set_has_unread_data(bool has_unread_data) {
130 has_unread_data_ = has_unread_data;
131 }
132
[email protected]3f55aa12011-12-07 02:03:33133 // Socket implementation.
dchengb03027d2014-10-21 12:00:20134 int Read(IOBuffer* /* buf */,
135 int len,
136 const CompletionCallback& /* callback */) override {
[email protected]0dc88b32014-03-26 20:12:28137 if (has_unread_data_ && len > 0) {
138 has_unread_data_ = false;
139 was_used_to_convey_data_ = true;
140 return 1;
141 }
[email protected]e86df8dc2013-03-30 13:18:28142 return ERR_UNEXPECTED;
[email protected]3f55aa12011-12-07 02:03:33143 }
[email protected]ab838892009-06-30 18:49:05144
dchengb03027d2014-10-21 12:00:20145 int Write(IOBuffer* /* buf */,
146 int len,
147 const CompletionCallback& /* callback */) override {
[email protected]0f873e82010-09-02 16:09:01148 was_used_to_convey_data_ = true;
149 return len;
[email protected]ab838892009-06-30 18:49:05150 }
Avi Drissman13fc8932015-12-20 04:40:46151 int SetReceiveBufferSize(int32_t size) override { return OK; }
152 int SetSendBufferSize(int32_t size) override { return OK; }
[email protected]ab838892009-06-30 18:49:05153
[email protected]dbf036f2011-12-06 23:33:24154 // StreamSocket implementation.
dchengb03027d2014-10-21 12:00:20155 int Connect(const CompletionCallback& callback) override {
[email protected]dbf036f2011-12-06 23:33:24156 connected_ = true;
157 return OK;
158 }
[email protected]f6d1d6eb2009-06-24 20:16:09159
dchengb03027d2014-10-21 12:00:20160 void Disconnect() override { connected_ = false; }
161 bool IsConnected() const override { return connected_; }
162 bool IsConnectedAndIdle() const override {
[email protected]0dc88b32014-03-26 20:12:28163 return connected_ && !has_unread_data_;
164 }
[email protected]0b7648c2009-07-06 20:14:01165
dchengb03027d2014-10-21 12:00:20166 int GetPeerAddress(IPEndPoint* /* address */) const override {
[email protected]9f864b32010-01-20 15:01:16167 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:09168 }
[email protected]f6d1d6eb2009-06-24 20:16:09169
dchengb03027d2014-10-21 12:00:20170 int GetLocalAddress(IPEndPoint* /* address */) const override {
[email protected]e7f74da2011-04-19 23:49:35171 return ERR_UNEXPECTED;
172 }
173
dchengb03027d2014-10-21 12:00:20174 const BoundNetLog& NetLog() const override { return net_log_; }
[email protected]a2006ece2010-04-23 16:44:02175
dchengb03027d2014-10-21 12:00:20176 void SetSubresourceSpeculation() override {}
177 void SetOmniboxSpeculation() override {}
178 bool WasEverUsed() const override { return was_used_to_convey_data_; }
dchengb03027d2014-10-21 12:00:20179 bool WasNpnNegotiated() const override { return false; }
180 NextProto GetNegotiatedProtocol() const override { return kProtoUnknown; }
181 bool GetSSLInfo(SSLInfo* ssl_info) override { return false; }
ttuttle23fdb7b2015-05-15 01:28:03182 void GetConnectionAttempts(ConnectionAttempts* out) const override {
183 out->clear();
184 }
185 void ClearConnectionAttempts() override {}
186 void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
tbansalf82cc8e2015-10-14 20:05:49187 int64_t GetTotalReceivedBytes() const override {
188 NOTIMPLEMENTED();
189 return 0;
190 }
[email protected]9b5614a2010-08-25 20:29:45191
[email protected]f6d1d6eb2009-06-24 20:16:09192 private:
193 bool connected_;
[email protected]0dc88b32014-03-26 20:12:28194 bool has_unread_data_;
[email protected]a2006ece2010-04-23 16:44:02195 BoundNetLog net_log_;
[email protected]0f873e82010-09-02 16:09:01196 bool was_used_to_convey_data_;
[email protected]f6d1d6eb2009-06-24 20:16:09197
[email protected]ab838892009-06-30 18:49:05198 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:09199};
200
[email protected]5fc08e32009-07-15 17:09:57201class TestConnectJob;
202
[email protected]f6d1d6eb2009-06-24 20:16:09203class MockClientSocketFactory : public ClientSocketFactory {
204 public:
[email protected]ab838892009-06-30 18:49:05205 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:09206
danakj655b66c2016-04-16 00:51:38207 std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
[email protected]5370c012011-06-29 03:47:04208 DatagramSocket::BindType bind_type,
209 const RandIntCallback& rand_int_cb,
[email protected]98b0e582011-06-22 14:31:41210 NetLog* net_log,
mostynbba063d6032014-10-09 11:01:13211 const NetLog::Source& source) override {
[email protected]98b0e582011-06-22 14:31:41212 NOTREACHED();
danakj655b66c2016-04-16 00:51:38213 return std::unique_ptr<DatagramClientSocket>();
[email protected]98b0e582011-06-22 14:31:41214 }
215
danakj655b66c2016-04-16 00:51:38216 std::unique_ptr<StreamSocket> CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07217 const AddressList& addresses,
danakj655b66c2016-04-16 00:51:38218 std::unique_ptr<
219 SocketPerformanceWatcher> /* socket_performance_watcher */,
[email protected]0a0b7682010-08-25 17:08:07220 NetLog* /* net_log */,
mostynbba063d6032014-10-09 11:01:13221 const NetLog::Source& /*source*/) override {
[email protected]f6d1d6eb2009-06-24 20:16:09222 allocation_count_++;
danakj655b66c2016-04-16 00:51:38223 return std::unique_ptr<StreamSocket>();
[email protected]f6d1d6eb2009-06-24 20:16:09224 }
225
danakj655b66c2016-04-16 00:51:38226 std::unique_ptr<SSLClientSocket> CreateSSLClientSocket(
227 std::unique_ptr<ClientSocketHandle> transport_socket,
[email protected]4f4de7e62010-11-12 19:55:27228 const HostPortPair& host_and_port,
[email protected]7ab5bbd12010-10-19 13:33:21229 const SSLConfig& ssl_config,
mostynbba063d6032014-10-09 11:01:13230 const SSLClientSocketContext& context) override {
[email protected]f6d1d6eb2009-06-24 20:16:09231 NOTIMPLEMENTED();
danakj655b66c2016-04-16 00:51:38232 return std::unique_ptr<SSLClientSocket>();
[email protected]f6d1d6eb2009-06-24 20:16:09233 }
234
dchengb03027d2014-10-21 12:00:20235 void ClearSSLSessionCache() override { NOTIMPLEMENTED(); }
[email protected]25f47352011-02-25 16:31:59236
[email protected]5fc08e32009-07-15 17:09:57237 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
[email protected]03b7c8c2013-07-20 04:38:55238
[email protected]5fc08e32009-07-15 17:09:57239 void SignalJobs();
240
[email protected]03b7c8c2013-07-20 04:38:55241 void SignalJob(size_t job);
242
243 void SetJobLoadState(size_t job, LoadState load_state);
244
[email protected]f6d1d6eb2009-06-24 20:16:09245 int allocation_count() const { return allocation_count_; }
246
[email protected]f6d1d6eb2009-06-24 20:16:09247 private:
248 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:57249 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09250};
251
[email protected]ab838892009-06-30 18:49:05252class TestConnectJob : public ConnectJob {
253 public:
254 enum JobType {
255 kMockJob,
256 kMockFailingJob,
257 kMockPendingJob,
258 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57259 kMockWaitingJob,
[email protected]e772db3f2010-07-12 18:11:13260 kMockRecoverableJob,
261 kMockPendingRecoverableJob,
[email protected]e60e47a2010-07-14 03:37:18262 kMockAdditionalErrorStateJob,
263 kMockPendingAdditionalErrorStateJob,
[email protected]0dc88b32014-03-26 20:12:28264 kMockUnreadDataJob,
[email protected]ab838892009-06-30 18:49:05265 };
266
[email protected]994d4932010-07-12 17:55:13267 // The kMockPendingJob uses a slight delay before allowing the connect
268 // to complete.
269 static const int kPendingConnectDelay = 2;
270
[email protected]ab838892009-06-30 18:49:05271 TestConnectJob(JobType job_type,
272 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49273 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34274 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05275 ConnectJob::Delegate* delegate,
[email protected]fd7b7c92009-08-20 19:38:30276 MockClientSocketFactory* client_socket_factory,
[email protected]06650c52010-06-03 00:49:17277 NetLog* net_log)
mmenked3641e12016-01-28 16:06:15278 : ConnectJob(group_name,
279 timeout_duration,
280 request.priority(),
281 request.respect_limits(),
282 delegate,
[email protected]06650c52010-06-03 00:49:17283 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
[email protected]2ab05b52009-07-01 23:57:58284 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05285 client_socket_factory_(client_socket_factory),
[email protected]e60e47a2010-07-14 03:37:18286 load_state_(LOAD_STATE_IDLE),
[email protected]d5492c52013-11-10 20:44:39287 store_additional_error_state_(false),
mmenked3641e12016-01-28 16:06:15288 weak_factory_(this) {}
[email protected]ab838892009-06-30 18:49:05289
[email protected]974ebd62009-08-03 23:14:34290 void Signal() {
[email protected]e772db3f2010-07-12 18:11:13291 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
[email protected]974ebd62009-08-03 23:14:34292 }
293
[email protected]03b7c8c2013-07-20 04:38:55294 void set_load_state(LoadState load_state) { load_state_ = load_state; }
295
296 // From ConnectJob:
297
dchengb03027d2014-10-21 12:00:20298 LoadState GetLoadState() const override { return load_state_; }
[email protected]46451352009-09-01 14:54:21299
dchengb03027d2014-10-21 12:00:20300 void GetAdditionalErrorState(ClientSocketHandle* handle) override {
[email protected]e60e47a2010-07-14 03:37:18301 if (store_additional_error_state_) {
302 // Set all of the additional error state fields in some way.
303 handle->set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43304 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:45305 info.headers = new HttpResponseHeaders(std::string());
[email protected]8b498692010-07-16 17:11:43306 handle->set_ssl_error_response_info(info);
[email protected]e60e47a2010-07-14 03:37:18307 }
308 }
309
[email protected]974ebd62009-08-03 23:14:34310 private:
[email protected]03b7c8c2013-07-20 04:38:55311 // From ConnectJob:
[email protected]ab838892009-06-30 18:49:05312
dchengb03027d2014-10-21 12:00:20313 int ConnectInternal() override {
[email protected]ab838892009-06-30 18:49:05314 AddressList ignored;
tbansal7b403bcc2016-04-13 22:33:21315 client_socket_factory_->CreateTransportClientSocket(ignored, NULL, NULL,
ttuttle859dc7a2015-04-23 19:42:29316 NetLog::Source());
danakj655b66c2016-04-16 00:51:38317 SetSocket(std::unique_ptr<StreamSocket>(
318 new MockClientSocket(net_log().net_log())));
[email protected]ab838892009-06-30 18:49:05319 switch (job_type_) {
320 case kMockJob:
[email protected]e772db3f2010-07-12 18:11:13321 return DoConnect(true /* successful */, false /* sync */,
322 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05323 case kMockFailingJob:
[email protected]e772db3f2010-07-12 18:11:13324 return DoConnect(false /* error */, false /* sync */,
325 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05326 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57327 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47328
329 // Depending on execution timings, posting a delayed task can result
330 // in the task getting executed the at the earliest possible
331 // opportunity or only after returning once from the message loop and
332 // then a second call into the message loop. In order to make behavior
333 // more deterministic, we change the default delay to 2ms. This should
334 // always require us to wait for the second call into the message loop.
335 //
336 // N.B. The correct fix for this and similar timing problems is to
337 // abstract time for the purpose of unittests. Unfortunately, we have
338 // a lot of third-party components that directly call the various
339 // time functions, so this change would be rather invasive.
skyostil4891b25b2015-06-11 11:43:45340 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05341 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13342 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
skyostil4891b25b2015-06-11 11:43:45343 weak_factory_.GetWeakPtr(), true /* successful */,
344 true /* async */, false /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53345 base::TimeDelta::FromMilliseconds(kPendingConnectDelay));
[email protected]ab838892009-06-30 18:49:05346 return ERR_IO_PENDING;
347 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57348 set_load_state(LOAD_STATE_CONNECTING);
skyostil4891b25b2015-06-11 11:43:45349 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05350 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13351 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
skyostil4891b25b2015-06-11 11:43:45352 weak_factory_.GetWeakPtr(), false /* error */,
353 true /* async */, false /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53354 base::TimeDelta::FromMilliseconds(2));
[email protected]ab838892009-06-30 18:49:05355 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57356 case kMockWaitingJob:
[email protected]03b7c8c2013-07-20 04:38:55357 set_load_state(LOAD_STATE_CONNECTING);
[email protected]5fc08e32009-07-15 17:09:57358 client_socket_factory_->WaitForSignal(this);
359 waiting_success_ = true;
360 return ERR_IO_PENDING;
[email protected]e772db3f2010-07-12 18:11:13361 case kMockRecoverableJob:
362 return DoConnect(false /* error */, false /* sync */,
363 true /* recoverable */);
364 case kMockPendingRecoverableJob:
365 set_load_state(LOAD_STATE_CONNECTING);
skyostil4891b25b2015-06-11 11:43:45366 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]e772db3f2010-07-12 18:11:13367 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13368 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
skyostil4891b25b2015-06-11 11:43:45369 weak_factory_.GetWeakPtr(), false /* error */,
370 true /* async */, true /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53371 base::TimeDelta::FromMilliseconds(2));
[email protected]e772db3f2010-07-12 18:11:13372 return ERR_IO_PENDING;
[email protected]e60e47a2010-07-14 03:37:18373 case kMockAdditionalErrorStateJob:
374 store_additional_error_state_ = true;
375 return DoConnect(false /* error */, false /* sync */,
376 false /* recoverable */);
377 case kMockPendingAdditionalErrorStateJob:
378 set_load_state(LOAD_STATE_CONNECTING);
379 store_additional_error_state_ = true;
skyostil4891b25b2015-06-11 11:43:45380 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]e60e47a2010-07-14 03:37:18381 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13382 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
skyostil4891b25b2015-06-11 11:43:45383 weak_factory_.GetWeakPtr(), false /* error */,
384 true /* async */, false /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53385 base::TimeDelta::FromMilliseconds(2));
[email protected]e60e47a2010-07-14 03:37:18386 return ERR_IO_PENDING;
[email protected]0dc88b32014-03-26 20:12:28387 case kMockUnreadDataJob: {
388 int ret = DoConnect(true /* successful */, false /* sync */,
389 false /* recoverable */);
390 static_cast<MockClientSocket*>(socket())->set_has_unread_data(true);
391 return ret;
392 }
[email protected]ab838892009-06-30 18:49:05393 default:
394 NOTREACHED();
danakj655b66c2016-04-16 00:51:38395 SetSocket(std::unique_ptr<StreamSocket>());
[email protected]ab838892009-06-30 18:49:05396 return ERR_FAILED;
397 }
398 }
399
[email protected]e772db3f2010-07-12 18:11:13400 int DoConnect(bool succeed, bool was_async, bool recoverable) {
401 int result = OK;
[email protected]ab838892009-06-30 18:49:05402 if (succeed) {
[email protected]83039bb2011-12-09 18:43:55403 socket()->Connect(CompletionCallback());
[email protected]e772db3f2010-07-12 18:11:13404 } else if (recoverable) {
405 result = ERR_PROXY_AUTH_REQUESTED;
[email protected]6e713f02009-08-06 02:56:40406 } else {
[email protected]e772db3f2010-07-12 18:11:13407 result = ERR_CONNECTION_FAILED;
danakj655b66c2016-04-16 00:51:38408 SetSocket(std::unique_ptr<StreamSocket>());
[email protected]ab838892009-06-30 18:49:05409 }
[email protected]2ab05b52009-07-01 23:57:58410
411 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30412 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05413 return result;
414 }
415
[email protected]5fc08e32009-07-15 17:09:57416 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05417 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57418 MockClientSocketFactory* const client_socket_factory_;
[email protected]46451352009-09-01 14:54:21419 LoadState load_state_;
[email protected]e60e47a2010-07-14 03:37:18420 bool store_additional_error_state_;
[email protected]ab838892009-06-30 18:49:05421
[email protected]d5492c52013-11-10 20:44:39422 base::WeakPtrFactory<TestConnectJob> weak_factory_;
423
[email protected]ab838892009-06-30 18:49:05424 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
425};
426
[email protected]d80a4322009-08-14 07:07:49427class TestConnectJobFactory
428 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05429 public:
[email protected]034df0f32013-01-07 23:17:48430 TestConnectJobFactory(MockClientSocketFactory* client_socket_factory,
431 NetLog* net_log)
[email protected]ab838892009-06-30 18:49:05432 : job_type_(TestConnectJob::kMockJob),
[email protected]51fdc7c2012-04-10 19:19:48433 job_types_(NULL),
[email protected]034df0f32013-01-07 23:17:48434 client_socket_factory_(client_socket_factory),
435 net_log_(net_log) {
[email protected]b021ece62013-06-11 11:06:33436 }
[email protected]ab838892009-06-30 18:49:05437
dchengb03027d2014-10-21 12:00:20438 ~TestConnectJobFactory() override {}
[email protected]ab838892009-06-30 18:49:05439
440 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
441
[email protected]51fdc7c2012-04-10 19:19:48442 void set_job_types(std::list<TestConnectJob::JobType>* job_types) {
443 job_types_ = job_types;
444 CHECK(!job_types_->empty());
445 }
446
[email protected]974ebd62009-08-03 23:14:34447 void set_timeout_duration(base::TimeDelta timeout_duration) {
448 timeout_duration_ = timeout_duration;
449 }
450
[email protected]3f55aa12011-12-07 02:03:33451 // ConnectJobFactory implementation.
[email protected]83039bb2011-12-09 18:43:55452
danakj655b66c2016-04-16 00:51:38453 std::unique_ptr<ConnectJob> NewConnectJob(
[email protected]ab838892009-06-30 18:49:05454 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49455 const TestClientSocketPoolBase::Request& request,
mostynbba063d6032014-10-09 11:01:13456 ConnectJob::Delegate* delegate) const override {
[email protected]51fdc7c2012-04-10 19:19:48457 EXPECT_TRUE(!job_types_ || !job_types_->empty());
458 TestConnectJob::JobType job_type = job_type_;
459 if (job_types_ && !job_types_->empty()) {
460 job_type = job_types_->front();
461 job_types_->pop_front();
462 }
danakj655b66c2016-04-16 00:51:38463 return std::unique_ptr<ConnectJob>(
464 new TestConnectJob(job_type, group_name, request, timeout_duration_,
465 delegate, client_socket_factory_, net_log_));
[email protected]ab838892009-06-30 18:49:05466 }
467
dchengb03027d2014-10-21 12:00:20468 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26469 return timeout_duration_;
470 }
471
[email protected]ab838892009-06-30 18:49:05472 private:
473 TestConnectJob::JobType job_type_;
[email protected]51fdc7c2012-04-10 19:19:48474 std::list<TestConnectJob::JobType>* job_types_;
[email protected]974ebd62009-08-03 23:14:34475 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57476 MockClientSocketFactory* const client_socket_factory_;
[email protected]034df0f32013-01-07 23:17:48477 NetLog* net_log_;
[email protected]ab838892009-06-30 18:49:05478
479 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
480};
481
482class TestClientSocketPool : public ClientSocketPool {
483 public:
[email protected]12322e7e2013-08-15 17:49:26484 typedef TestSocketParams SocketParams;
485
[email protected]ab838892009-06-30 18:49:05486 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53487 int max_sockets,
[email protected]ab838892009-06-30 18:49:05488 int max_sockets_per_group,
[email protected]9bf28db2009-08-29 01:35:16489 base::TimeDelta unused_idle_socket_timeout,
490 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49491 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
rkaplowd90695c2015-03-25 22:12:41492 : base_(NULL,
493 max_sockets,
494 max_sockets_per_group,
495 unused_idle_socket_timeout,
496 used_idle_socket_timeout,
[email protected]66761b952010-06-25 21:30:38497 connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05498
dchengb03027d2014-10-21 12:00:20499 ~TestClientSocketPool() override {}
[email protected]2431756e2010-09-29 20:26:13500
dchengb03027d2014-10-21 12:00:20501 int RequestSocket(const std::string& group_name,
502 const void* params,
ttuttle859dc7a2015-04-23 19:42:29503 RequestPriority priority,
mmenked3641e12016-01-28 16:06:15504 RespectLimits respect_limits,
dchengb03027d2014-10-21 12:00:20505 ClientSocketHandle* handle,
506 const CompletionCallback& callback,
507 const BoundNetLog& net_log) override {
[email protected]df4b4ef2010-07-12 18:25:21508 const scoped_refptr<TestSocketParams>* casted_socket_params =
509 static_cast<const scoped_refptr<TestSocketParams>*>(params);
510 return base_.RequestSocket(group_name, *casted_socket_params, priority,
mmenked3641e12016-01-28 16:06:15511 respect_limits, handle, callback, net_log);
[email protected]ab838892009-06-30 18:49:05512 }
513
dchengb03027d2014-10-21 12:00:20514 void RequestSockets(const std::string& group_name,
515 const void* params,
516 int num_sockets,
517 const BoundNetLog& net_log) override {
[email protected]2c2bef152010-10-13 00:55:03518 const scoped_refptr<TestSocketParams>* casted_params =
519 static_cast<const scoped_refptr<TestSocketParams>*>(params);
520
521 base_.RequestSockets(group_name, *casted_params, num_sockets, net_log);
522 }
523
dchengb03027d2014-10-21 12:00:20524 void CancelRequest(const std::string& group_name,
525 ClientSocketHandle* handle) override {
[email protected]d80a4322009-08-14 07:07:49526 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05527 }
528
dchengb03027d2014-10-21 12:00:20529 void ReleaseSocket(const std::string& group_name,
danakj655b66c2016-04-16 00:51:38530 std::unique_ptr<StreamSocket> socket,
dchengb03027d2014-10-21 12:00:20531 int id) override {
dchengc7eeda422015-12-26 03:56:48532 base_.ReleaseSocket(group_name, std::move(socket), id);
[email protected]a7e38572010-06-07 18:22:24533 }
534
dchengb03027d2014-10-21 12:00:20535 void FlushWithError(int error) override { base_.FlushWithError(error); }
[email protected]ab838892009-06-30 18:49:05536
dchengb03027d2014-10-21 12:00:20537 bool IsStalled() const override { return base_.IsStalled(); }
[email protected]51fdc7c2012-04-10 19:19:48538
dchengb03027d2014-10-21 12:00:20539 void CloseIdleSockets() override { base_.CloseIdleSockets(); }
[email protected]ab838892009-06-30 18:49:05540
dchengb03027d2014-10-21 12:00:20541 int IdleSocketCount() const override { return base_.idle_socket_count(); }
[email protected]ab838892009-06-30 18:49:05542
dchengb03027d2014-10-21 12:00:20543 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]d80a4322009-08-14 07:07:49544 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05545 }
546
dchengb03027d2014-10-21 12:00:20547 LoadState GetLoadState(const std::string& group_name,
548 const ClientSocketHandle* handle) const override {
[email protected]d80a4322009-08-14 07:07:49549 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05550 }
551
dchengb03027d2014-10-21 12:00:20552 void AddHigherLayeredPool(HigherLayeredPool* higher_pool) override {
[email protected]043b68c82013-08-22 23:41:52553 base_.AddHigherLayeredPool(higher_pool);
[email protected]51fdc7c2012-04-10 19:19:48554 }
555
dchengb03027d2014-10-21 12:00:20556 void RemoveHigherLayeredPool(HigherLayeredPool* higher_pool) override {
[email protected]043b68c82013-08-22 23:41:52557 base_.RemoveHigherLayeredPool(higher_pool);
[email protected]51fdc7c2012-04-10 19:19:48558 }
559
danakj655b66c2016-04-16 00:51:38560 std::unique_ptr<base::DictionaryValue> GetInfoAsValue(
[email protected]d4dfdab2011-12-07 16:56:59561 const std::string& name,
562 const std::string& type,
mostynbba063d6032014-10-09 11:01:13563 bool include_nested_pools) const override {
[email protected]59d7a5a2010-08-30 16:44:27564 return base_.GetInfoAsValue(name, type);
565 }
566
dchengb03027d2014-10-21 12:00:20567 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26568 return base_.ConnectionTimeout();
569 }
570
[email protected]d80a4322009-08-14 07:07:49571 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20572
[email protected]8159a1c2012-06-07 00:00:10573 int NumUnassignedConnectJobsInGroup(const std::string& group_name) const {
574 return base_.NumUnassignedConnectJobsInGroup(group_name);
575 }
576
[email protected]974ebd62009-08-03 23:14:34577 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49578 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34579 }
580
[email protected]2c2bef152010-10-13 00:55:03581 int NumActiveSocketsInGroup(const std::string& group_name) const {
582 return base_.NumActiveSocketsInGroup(group_name);
583 }
584
[email protected]2abfe90a2010-08-25 17:49:51585 bool HasGroup(const std::string& group_name) const {
586 return base_.HasGroup(group_name);
587 }
588
[email protected]9bf28db2009-08-29 01:35:16589 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
590
[email protected]06d94042010-08-25 01:45:22591 void EnableConnectBackupJobs() { base_.EnableConnectBackupJobs(); }
[email protected]43a21b82010-06-10 21:30:54592
[email protected]043b68c82013-08-22 23:41:52593 bool CloseOneIdleConnectionInHigherLayeredPool() {
594 return base_.CloseOneIdleConnectionInHigherLayeredPool();
[email protected]51fdc7c2012-04-10 19:19:48595 }
596
[email protected]ab838892009-06-30 18:49:05597 private:
[email protected]d80a4322009-08-14 07:07:49598 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05599
600 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
601};
602
[email protected]a937a06d2009-08-19 21:19:24603} // namespace
604
[email protected]a937a06d2009-08-19 21:19:24605namespace {
606
[email protected]5fc08e32009-07-15 17:09:57607void MockClientSocketFactory::SignalJobs() {
608 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
609 it != waiting_jobs_.end(); ++it) {
610 (*it)->Signal();
611 }
612 waiting_jobs_.clear();
613}
614
[email protected]03b7c8c2013-07-20 04:38:55615void MockClientSocketFactory::SignalJob(size_t job) {
616 ASSERT_LT(job, waiting_jobs_.size());
617 waiting_jobs_[job]->Signal();
618 waiting_jobs_.erase(waiting_jobs_.begin() + job);
619}
620
621void MockClientSocketFactory::SetJobLoadState(size_t job,
622 LoadState load_state) {
623 ASSERT_LT(job, waiting_jobs_.size());
624 waiting_jobs_[job]->set_load_state(load_state);
625}
626
[email protected]974ebd62009-08-03 23:14:34627class TestConnectJobDelegate : public ConnectJob::Delegate {
628 public:
629 TestConnectJobDelegate()
630 : have_result_(false), waiting_for_result_(false), result_(OK) {}
dchengb03027d2014-10-21 12:00:20631 ~TestConnectJobDelegate() override {}
[email protected]974ebd62009-08-03 23:14:34632
dchengb03027d2014-10-21 12:00:20633 void OnConnectJobComplete(int result, ConnectJob* job) override {
[email protected]974ebd62009-08-03 23:14:34634 result_ = result;
danakj655b66c2016-04-16 00:51:38635 std::unique_ptr<ConnectJob> owned_job(job);
636 std::unique_ptr<StreamSocket> socket = owned_job->PassSocket();
[email protected]9b6fee12009-09-29 18:13:07637 // socket.get() should be NULL iff result != OK
[email protected]18ccfdb2013-08-15 00:13:44638 EXPECT_EQ(socket == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34639 have_result_ = true;
640 if (waiting_for_result_)
ki.stfu375812e2015-10-09 20:23:17641 base::MessageLoop::current()->QuitWhenIdle();
[email protected]974ebd62009-08-03 23:14:34642 }
643
644 int WaitForResult() {
645 DCHECK(!waiting_for_result_);
646 while (!have_result_) {
647 waiting_for_result_ = true;
fdoray5eeb7642016-06-22 16:11:28648 base::RunLoop().Run();
[email protected]974ebd62009-08-03 23:14:34649 waiting_for_result_ = false;
650 }
651 have_result_ = false; // auto-reset for next callback
652 return result_;
653 }
654
655 private:
656 bool have_result_;
657 bool waiting_for_result_;
658 int result_;
659};
660
[email protected]2431756e2010-09-29 20:26:13661class ClientSocketPoolBaseTest : public testing::Test {
[email protected]f6d1d6eb2009-06-24 20:16:09662 protected:
mmenked3641e12016-01-28 16:06:15663 ClientSocketPoolBaseTest() : params_(new TestSocketParams()) {
[email protected]636b8252011-04-08 19:56:54664 connect_backup_jobs_enabled_ =
665 internal::ClientSocketPoolBaseHelper::connect_backup_jobs_enabled();
666 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(true);
[email protected]636b8252011-04-08 19:56:54667 }
[email protected]2431756e2010-09-29 20:26:13668
dcheng67be2b1f2014-10-27 21:47:29669 ~ClientSocketPoolBaseTest() override {
[email protected]636b8252011-04-08 19:56:54670 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
671 connect_backup_jobs_enabled_);
[email protected]636b8252011-04-08 19:56:54672 }
[email protected]c9d6a1d2009-07-14 16:15:20673
[email protected]211d21722009-07-22 15:48:53674 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16675 CreatePoolWithIdleTimeouts(
676 max_sockets,
677 max_sockets_per_group,
[email protected]82b8c962011-10-12 09:17:30678 ClientSocketPool::unused_idle_socket_timeout(),
679 ClientSocketPool::used_idle_socket_timeout());
[email protected]9bf28db2009-08-29 01:35:16680 }
681
682 void CreatePoolWithIdleTimeouts(
683 int max_sockets, int max_sockets_per_group,
684 base::TimeDelta unused_idle_socket_timeout,
685 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20686 DCHECK(!pool_.get());
[email protected]034df0f32013-01-07 23:17:48687 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_,
688 &net_log_);
[email protected]2431756e2010-09-29 20:26:13689 pool_.reset(new TestClientSocketPool(max_sockets,
690 max_sockets_per_group,
[email protected]2431756e2010-09-29 20:26:13691 unused_idle_socket_timeout,
692 used_idle_socket_timeout,
693 connect_job_factory_));
[email protected]c9d6a1d2009-07-14 16:15:20694 }
[email protected]f6d1d6eb2009-06-24 20:16:09695
mmenked3641e12016-01-28 16:06:15696 int StartRequestWithIgnoreLimits(
[email protected]b021ece62013-06-11 11:06:33697 const std::string& group_name,
698 RequestPriority priority,
mmenked3641e12016-01-28 16:06:15699 ClientSocketPool::RespectLimits respect_limits) {
700 return test_base_.StartRequestUsingPool(pool_.get(), group_name, priority,
701 respect_limits, params_);
[email protected]b021ece62013-06-11 11:06:33702 }
703
704 int StartRequest(const std::string& group_name, RequestPriority priority) {
mmenked3641e12016-01-28 16:06:15705 return StartRequestWithIgnoreLimits(
706 group_name, priority, ClientSocketPool::RespectLimits::ENABLED);
[email protected]f6d1d6eb2009-06-24 20:16:09707 }
708
[email protected]2431756e2010-09-29 20:26:13709 int GetOrderOfRequest(size_t index) const {
710 return test_base_.GetOrderOfRequest(index);
[email protected]f6d1d6eb2009-06-24 20:16:09711 }
712
[email protected]2431756e2010-09-29 20:26:13713 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
714 return test_base_.ReleaseOneConnection(keep_alive);
715 }
716
717 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
718 test_base_.ReleaseAllConnections(keep_alive);
719 }
720
721 TestSocketRequest* request(int i) { return test_base_.request(i); }
722 size_t requests_size() const { return test_base_.requests_size(); }
danakj655b66c2016-04-16 00:51:38723 std::vector<std::unique_ptr<TestSocketRequest>>* requests() {
olli.raula9d66b7d2015-11-23 08:30:42724 return test_base_.requests();
725 }
[email protected]2431756e2010-09-29 20:26:13726 size_t completion_count() const { return test_base_.completion_count(); }
727
vishal.b62985ca92015-04-17 08:45:51728 TestNetLog net_log_;
[email protected]636b8252011-04-08 19:56:54729 bool connect_backup_jobs_enabled_;
[email protected]f6d1d6eb2009-06-24 20:16:09730 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04731 TestConnectJobFactory* connect_job_factory_;
[email protected]df4b4ef2010-07-12 18:25:21732 scoped_refptr<TestSocketParams> params_;
danakj655b66c2016-04-16 00:51:38733 std::unique_ptr<TestClientSocketPool> pool_;
[email protected]2431756e2010-09-29 20:26:13734 ClientSocketPoolTest test_base_;
[email protected]f6d1d6eb2009-06-24 20:16:09735};
736
[email protected]974ebd62009-08-03 23:14:34737// Even though a timeout is specified, it doesn't time out on a synchronous
738// completion.
739TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
740 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06741 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49742 TestClientSocketPoolBase::Request request(
[email protected]bb1c4662013-11-14 00:00:07743 &ignored, CompletionCallback(), DEFAULT_PRIORITY,
mmenked3641e12016-01-28 16:06:15744 ClientSocketPool::RespectLimits::ENABLED,
745 internal::ClientSocketPoolBaseHelper::NORMAL, params_, BoundNetLog());
danakj655b66c2016-04-16 00:51:38746 std::unique_ptr<TestConnectJob> job(
747 new TestConnectJob(TestConnectJob::kMockJob, "a", request,
748 base::TimeDelta::FromMicroseconds(1), &delegate,
749 &client_socket_factory_, NULL));
[email protected]974ebd62009-08-03 23:14:34750 EXPECT_EQ(OK, job->Connect());
751}
752
753TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
754 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06755 ClientSocketHandle ignored;
vishal.b62985ca92015-04-17 08:45:51756 TestNetLog log;
[email protected]9e743cd2010-03-16 07:03:53757
[email protected]d80a4322009-08-14 07:07:49758 TestClientSocketPoolBase::Request request(
[email protected]bb1c4662013-11-14 00:00:07759 &ignored, CompletionCallback(), DEFAULT_PRIORITY,
mmenked3641e12016-01-28 16:06:15760 ClientSocketPool::RespectLimits::ENABLED,
761 internal::ClientSocketPoolBaseHelper::NORMAL, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34762 // Deleted by TestConnectJobDelegate.
763 TestConnectJob* job =
764 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12765 "a",
[email protected]974ebd62009-08-03 23:14:34766 request,
767 base::TimeDelta::FromMicroseconds(1),
768 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30769 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17770 &log);
[email protected]974ebd62009-08-03 23:14:34771 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
[email protected]26b9973962012-01-28 00:57:00772 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
[email protected]974ebd62009-08-03 23:14:34773 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30774
mmenke43758e62015-05-04 21:09:46775 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40776 log.GetEntries(&entries);
777
778 EXPECT_EQ(6u, entries.size());
[email protected]e9002a92010-01-29 07:10:46779 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40780 entries, 0, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]06650c52010-06-03 00:49:17781 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40782 entries, 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]e9002a92010-01-29 07:10:46783 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40784 entries, 2, NetLog::TYPE_CONNECT_JOB_SET_SOCKET,
[email protected]06650c52010-06-03 00:49:17785 NetLog::PHASE_NONE));
786 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40787 entries, 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
[email protected]9e743cd2010-03-16 07:03:53788 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:46789 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40790 entries, 4, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]06650c52010-06-03 00:49:17791 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40792 entries, 5, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34793}
794
[email protected]5fc08e32009-07-15 17:09:57795TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53796 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20797
[email protected]6ecf2b92011-12-15 01:14:52798 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06799 ClientSocketHandle handle;
vishal.b62985ca92015-04-17 08:45:51800 BoundTestNetLog log;
[email protected]034df0f32013-01-07 23:17:48801 TestLoadTimingInfoNotConnected(handle);
[email protected]9e743cd2010-03-16 07:03:53802
mmenked3641e12016-01-28 16:06:15803 EXPECT_EQ(OK, handle.Init("a", params_, DEFAULT_PRIORITY,
804 ClientSocketPool::RespectLimits::ENABLED,
805 callback.callback(), pool_.get(), log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09806 EXPECT_TRUE(handle.is_initialized());
807 EXPECT_TRUE(handle.socket());
[email protected]034df0f32013-01-07 23:17:48808 TestLoadTimingInfoConnectedNotReused(handle);
809
[email protected]f6d1d6eb2009-06-24 20:16:09810 handle.Reset();
[email protected]034df0f32013-01-07 23:17:48811 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:30812
mmenke43758e62015-05-04 21:09:46813 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40814 log.GetEntries(&entries);
815
816 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:46817 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40818 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]9e743cd2010-03-16 07:03:53819 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40820 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:17821 NetLog::PHASE_NONE));
822 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40823 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]9e743cd2010-03-16 07:03:53824 NetLog::PHASE_NONE));
825 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40826 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09827}
828
[email protected]ab838892009-06-30 18:49:05829TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53830 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20831
[email protected]ab838892009-06-30 18:49:05832 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
vishal.b62985ca92015-04-17 08:45:51833 BoundTestNetLog log;
[email protected]9e743cd2010-03-16 07:03:53834
[email protected]2431756e2010-09-29 20:26:13835 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:52836 TestCompletionCallback callback;
[email protected]e60e47a2010-07-14 03:37:18837 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:13838 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43839 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:45840 info.headers = new HttpResponseHeaders(std::string());
[email protected]2431756e2010-09-29 20:26:13841 handle.set_ssl_error_response_info(info);
842 EXPECT_EQ(ERR_CONNECTION_FAILED,
mmenked3641e12016-01-28 16:06:15843 handle.Init("a", params_, DEFAULT_PRIORITY,
844 ClientSocketPool::RespectLimits::ENABLED,
845 callback.callback(), pool_.get(), log.bound()));
[email protected]2431756e2010-09-29 20:26:13846 EXPECT_FALSE(handle.socket());
847 EXPECT_FALSE(handle.is_ssl_error());
848 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]034df0f32013-01-07 23:17:48849 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:30850
mmenke43758e62015-05-04 21:09:46851 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40852 log.GetEntries(&entries);
853
854 EXPECT_EQ(3u, entries.size());
[email protected]5a1d7ca2010-04-28 20:12:27855 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40856 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:17857 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40858 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:17859 NetLog::PHASE_NONE));
[email protected]a2006ece2010-04-23 16:44:02860 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40861 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09862}
863
[email protected]211d21722009-07-22 15:48:53864TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
865 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
866
[email protected]9e743cd2010-03-16 07:03:53867 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30868
[email protected]bb1c4662013-11-14 00:00:07869 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
870 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
871 EXPECT_EQ(OK, StartRequest("c", DEFAULT_PRIORITY));
872 EXPECT_EQ(OK, StartRequest("d", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:53873
[email protected]2431756e2010-09-29 20:26:13874 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53875 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13876 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53877
[email protected]bb1c4662013-11-14 00:00:07878 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", DEFAULT_PRIORITY));
879 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", DEFAULT_PRIORITY));
880 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:53881
[email protected]2431756e2010-09-29 20:26:13882 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53883
[email protected]2431756e2010-09-29 20:26:13884 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53885 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13886 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53887
888 EXPECT_EQ(1, GetOrderOfRequest(1));
889 EXPECT_EQ(2, GetOrderOfRequest(2));
890 EXPECT_EQ(3, GetOrderOfRequest(3));
891 EXPECT_EQ(4, GetOrderOfRequest(4));
892 EXPECT_EQ(5, GetOrderOfRequest(5));
893 EXPECT_EQ(6, GetOrderOfRequest(6));
894 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17895
896 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13897 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53898}
899
900TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
901 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
902
[email protected]9e743cd2010-03-16 07:03:53903 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30904
[email protected]211d21722009-07-22 15:48:53905 // Reach all limits: max total sockets, and max sockets per group.
[email protected]bb1c4662013-11-14 00:00:07906 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
907 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
908 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
909 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:53910
[email protected]2431756e2010-09-29 20:26:13911 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53912 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13913 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53914
915 // Now create a new group and verify that we don't starve it.
[email protected]bb1c4662013-11-14 00:00:07916 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:53917
[email protected]2431756e2010-09-29 20:26:13918 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53919
[email protected]2431756e2010-09-29 20:26:13920 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53921 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13922 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53923
924 EXPECT_EQ(1, GetOrderOfRequest(1));
925 EXPECT_EQ(2, GetOrderOfRequest(2));
926 EXPECT_EQ(3, GetOrderOfRequest(3));
927 EXPECT_EQ(4, GetOrderOfRequest(4));
928 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17929
930 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13931 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53932}
933
934TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
935 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
936
[email protected]ac790b42009-12-02 04:31:31937 EXPECT_EQ(OK, StartRequest("b", LOWEST));
938 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
939 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
940 EXPECT_EQ(OK, StartRequest("a", LOWEST));
[email protected]211d21722009-07-22 15:48:53941
[email protected]2431756e2010-09-29 20:26:13942 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53943 client_socket_factory_.allocation_count());
944
[email protected]ac790b42009-12-02 04:31:31945 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
946 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
947 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53948
[email protected]2431756e2010-09-29 20:26:13949 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53950
[email protected]2431756e2010-09-29 20:26:13951 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53952
953 // First 4 requests don't have to wait, and finish in order.
954 EXPECT_EQ(1, GetOrderOfRequest(1));
955 EXPECT_EQ(2, GetOrderOfRequest(2));
956 EXPECT_EQ(3, GetOrderOfRequest(3));
957 EXPECT_EQ(4, GetOrderOfRequest(4));
958
[email protected]ac790b42009-12-02 04:31:31959 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
960 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53961 EXPECT_EQ(7, GetOrderOfRequest(5));
962 EXPECT_EQ(6, GetOrderOfRequest(6));
963 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17964
965 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13966 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]211d21722009-07-22 15:48:53967}
968
969TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
970 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
971
[email protected]ac790b42009-12-02 04:31:31972 EXPECT_EQ(OK, StartRequest("a", LOWEST));
973 EXPECT_EQ(OK, StartRequest("a", LOW));
974 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
975 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
[email protected]211d21722009-07-22 15:48:53976
[email protected]2431756e2010-09-29 20:26:13977 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53978 client_socket_factory_.allocation_count());
979
[email protected]ac790b42009-12-02 04:31:31980 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
981 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
982 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53983
[email protected]2431756e2010-09-29 20:26:13984 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53985
[email protected]2431756e2010-09-29 20:26:13986 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53987 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13988 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53989
990 // First 4 requests don't have to wait, and finish in order.
991 EXPECT_EQ(1, GetOrderOfRequest(1));
992 EXPECT_EQ(2, GetOrderOfRequest(2));
993 EXPECT_EQ(3, GetOrderOfRequest(3));
994 EXPECT_EQ(4, GetOrderOfRequest(4));
995
996 // Request ("b", 7) has the highest priority, but we can't make new socket for
997 // group "b", because it has reached the per-group limit. Then we make
998 // socket for ("c", 6), because it has higher priority than ("a", 4),
999 // and we still can't make a socket for group "b".
1000 EXPECT_EQ(5, GetOrderOfRequest(5));
1001 EXPECT_EQ(6, GetOrderOfRequest(6));
1002 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171003
1004 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131005 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:531006}
1007
1008// Make sure that we count connecting sockets against the total limit.
1009TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
1010 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1011
[email protected]bb1c4662013-11-14 00:00:071012 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1013 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
1014 EXPECT_EQ(OK, StartRequest("c", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:531015
1016 // Create one asynchronous request.
1017 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]bb1c4662013-11-14 00:00:071018 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:531019
[email protected]6b175382009-10-13 06:47:471020 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1021 // actually become pending until 2ms after they have been created. In order
1022 // to flush all tasks, we need to wait so that we know there are no
1023 // soon-to-be-pending tasks waiting.
[email protected]26b9973962012-01-28 00:57:001024 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
fdoray5eeb7642016-06-22 16:11:281025 base::RunLoop().RunUntilIdle();
[email protected]6b175382009-10-13 06:47:471026
[email protected]211d21722009-07-22 15:48:531027 // The next synchronous request should wait for its turn.
1028 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]bb1c4662013-11-14 00:00:071029 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:531030
[email protected]2431756e2010-09-29 20:26:131031 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531032
[email protected]2431756e2010-09-29 20:26:131033 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531034 client_socket_factory_.allocation_count());
1035
1036 EXPECT_EQ(1, GetOrderOfRequest(1));
1037 EXPECT_EQ(2, GetOrderOfRequest(2));
1038 EXPECT_EQ(3, GetOrderOfRequest(3));
1039 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:171040 EXPECT_EQ(5, GetOrderOfRequest(5));
1041
1042 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131043 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:531044}
1045
[email protected]6427fe22010-04-16 22:27:411046TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
1047 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1048 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1049
[email protected]bb1c4662013-11-14 00:00:071050 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1051 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1052 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1053 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
[email protected]6427fe22010-04-16 22:27:411054
1055 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1056
1057 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1058
[email protected]bb1c4662013-11-14 00:00:071059 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", DEFAULT_PRIORITY));
1060 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", DEFAULT_PRIORITY));
[email protected]6427fe22010-04-16 22:27:411061
1062 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1063
[email protected]2431756e2010-09-29 20:26:131064 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411065 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131066 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411067 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131068 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1069 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411070 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
1071}
1072
[email protected]d7027bb2010-05-10 18:58:541073TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
1074 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1075 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1076
1077 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521078 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131079 EXPECT_EQ(ERR_IO_PENDING,
mmenked3641e12016-01-28 16:06:151080 handle.Init("a", params_, DEFAULT_PRIORITY,
1081 ClientSocketPool::RespectLimits::ENABLED,
1082 callback.callback(), pool_.get(), BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541083
1084 ClientSocketHandle handles[4];
1085 for (size_t i = 0; i < arraysize(handles); ++i) {
[email protected]6ecf2b92011-12-15 01:14:521086 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131087 EXPECT_EQ(ERR_IO_PENDING,
mmenked3641e12016-01-28 16:06:151088 handles[i].Init("b", params_, DEFAULT_PRIORITY,
1089 ClientSocketPool::RespectLimits::ENABLED,
1090 callback.callback(), pool_.get(), BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541091 }
1092
1093 // One will be stalled, cancel all the handles now.
1094 // This should hit the OnAvailableSocketSlot() code where we previously had
1095 // stalled groups, but no longer have any.
1096 for (size_t i = 0; i < arraysize(handles); ++i)
1097 handles[i].Reset();
1098}
1099
[email protected]eb5a99382010-07-11 03:18:261100TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:541101 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1102 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1103
[email protected]eb5a99382010-07-11 03:18:261104 {
1105 ClientSocketHandle handles[kDefaultMaxSockets];
[email protected]6ecf2b92011-12-15 01:14:521106 TestCompletionCallback callbacks[kDefaultMaxSockets];
[email protected]eb5a99382010-07-11 03:18:261107 for (int i = 0; i < kDefaultMaxSockets; ++i) {
mmenked3641e12016-01-28 16:06:151108 EXPECT_EQ(OK, handles[i].Init(
1109 base::IntToString(i), params_, DEFAULT_PRIORITY,
1110 ClientSocketPool::RespectLimits::ENABLED,
1111 callbacks[i].callback(), pool_.get(), BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261112 }
1113
1114 // Force a stalled group.
1115 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521116 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:151117 EXPECT_EQ(
1118 ERR_IO_PENDING,
1119 stalled_handle.Init("foo", params_, DEFAULT_PRIORITY,
1120 ClientSocketPool::RespectLimits::ENABLED,
1121 callback.callback(), pool_.get(), BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261122
1123 // Cancel the stalled request.
1124 stalled_handle.Reset();
1125
1126 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1127 EXPECT_EQ(0, pool_->IdleSocketCount());
1128
1129 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541130 }
1131
[email protected]43a21b82010-06-10 21:30:541132 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1133 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:261134}
[email protected]43a21b82010-06-10 21:30:541135
[email protected]eb5a99382010-07-11 03:18:261136TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
1137 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1138 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1139
1140 {
1141 ClientSocketHandle handles[kDefaultMaxSockets];
1142 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521143 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:151144 EXPECT_EQ(
1145 ERR_IO_PENDING,
1146 handles[i].Init(base::IntToString(i), params_, DEFAULT_PRIORITY,
1147 ClientSocketPool::RespectLimits::ENABLED,
1148 callback.callback(), pool_.get(), BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261149 }
1150
1151 // Force a stalled group.
1152 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1153 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521154 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:151155 EXPECT_EQ(
1156 ERR_IO_PENDING,
1157 stalled_handle.Init("foo", params_, DEFAULT_PRIORITY,
1158 ClientSocketPool::RespectLimits::ENABLED,
1159 callback.callback(), pool_.get(), BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261160
1161 // Since it is stalled, it should have no connect jobs.
1162 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101163 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261164
1165 // Cancel the stalled request.
1166 handles[0].Reset();
1167
[email protected]eb5a99382010-07-11 03:18:261168 // Now we should have a connect job.
1169 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101170 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261171
1172 // The stalled socket should connect.
1173 EXPECT_EQ(OK, callback.WaitForResult());
1174
1175 EXPECT_EQ(kDefaultMaxSockets + 1,
1176 client_socket_factory_.allocation_count());
1177 EXPECT_EQ(0, pool_->IdleSocketCount());
1178 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101179 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261180
1181 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541182 }
1183
[email protected]eb5a99382010-07-11 03:18:261184 EXPECT_EQ(1, pool_->IdleSocketCount());
1185}
[email protected]43a21b82010-06-10 21:30:541186
[email protected]eb5a99382010-07-11 03:18:261187TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1188 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1189 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:541190
[email protected]eb5a99382010-07-11 03:18:261191 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521192 TestCompletionCallback callback;
[email protected]eb5a99382010-07-11 03:18:261193 {
[email protected]51fdc7c2012-04-10 19:19:481194 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261195 ClientSocketHandle handles[kDefaultMaxSockets];
1196 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521197 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:151198 EXPECT_EQ(
1199 OK, handles[i].Init(base::StringPrintf("Take 2: %d", i), params_,
1200 DEFAULT_PRIORITY,
1201 ClientSocketPool::RespectLimits::ENABLED,
1202 callback.callback(), pool_.get(), BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261203 }
1204
1205 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1206 EXPECT_EQ(0, pool_->IdleSocketCount());
[email protected]51fdc7c2012-04-10 19:19:481207 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261208
1209 // Now we will hit the socket limit.
mmenked3641e12016-01-28 16:06:151210 EXPECT_EQ(
1211 ERR_IO_PENDING,
1212 stalled_handle.Init("foo", params_, DEFAULT_PRIORITY,
1213 ClientSocketPool::RespectLimits::ENABLED,
1214 callback.callback(), pool_.get(), BoundNetLog()));
[email protected]51fdc7c2012-04-10 19:19:481215 EXPECT_TRUE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261216
1217 // Dropping out of scope will close all handles and return them to idle.
1218 }
[email protected]43a21b82010-06-10 21:30:541219
1220 // But if we wait for it, the released idle sockets will be closed in
1221 // preference of the waiting request.
[email protected]8ae03f42010-07-07 19:08:101222 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]eb5a99382010-07-11 03:18:261223
1224 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1225 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:541226}
1227
1228// Regression test for http://crbug.com/40952.
1229TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1230 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]06d94042010-08-25 01:45:221231 pool_->EnableConnectBackupJobs();
[email protected]43a21b82010-06-10 21:30:541232 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1233
1234 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1235 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521236 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:151237 EXPECT_EQ(OK, handle.Init(base::IntToString(i), params_, DEFAULT_PRIORITY,
1238 ClientSocketPool::RespectLimits::ENABLED,
1239 callback.callback(), pool_.get(), BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541240 }
1241
1242 // Flush all the DoReleaseSocket tasks.
fdoray5eeb7642016-06-22 16:11:281243 base::RunLoop().RunUntilIdle();
[email protected]43a21b82010-06-10 21:30:541244
1245 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1246 // reuse a socket.
1247 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1248 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521249 TestCompletionCallback callback;
[email protected]43a21b82010-06-10 21:30:541250
1251 // "0" is special here, since it should be the first entry in the sorted map,
1252 // which is the one which we would close an idle socket for. We shouldn't
1253 // close an idle socket though, since we should reuse the idle socket.
mmenked3641e12016-01-28 16:06:151254 EXPECT_EQ(OK, handle.Init("0", params_, DEFAULT_PRIORITY,
1255 ClientSocketPool::RespectLimits::ENABLED,
1256 callback.callback(), pool_.get(), BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541257
1258 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1259 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1260}
1261
[email protected]ab838892009-06-30 18:49:051262TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531263 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091264
[email protected]bb1c4662013-11-14 00:00:071265 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1266 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
[email protected]c9c6f5c2010-07-31 01:30:031267 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", IDLE));
[email protected]ac790b42009-12-02 04:31:311268 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1269 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1270 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1271 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1272 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091273
[email protected]2431756e2010-09-29 20:26:131274 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091275
[email protected]c9d6a1d2009-07-14 16:15:201276 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1277 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131278 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1279 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091280
[email protected]c9d6a1d2009-07-14 16:15:201281 EXPECT_EQ(1, GetOrderOfRequest(1));
1282 EXPECT_EQ(2, GetOrderOfRequest(2));
[email protected]c9c6f5c2010-07-31 01:30:031283 EXPECT_EQ(8, GetOrderOfRequest(3));
1284 EXPECT_EQ(6, GetOrderOfRequest(4));
1285 EXPECT_EQ(4, GetOrderOfRequest(5));
1286 EXPECT_EQ(3, GetOrderOfRequest(6));
1287 EXPECT_EQ(5, GetOrderOfRequest(7));
1288 EXPECT_EQ(7, GetOrderOfRequest(8));
[email protected]75439d3b2009-07-23 22:11:171289
1290 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131291 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]f6d1d6eb2009-06-24 20:16:091292}
1293
[email protected]ab838892009-06-30 18:49:051294TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531295 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091296
[email protected]bb1c4662013-11-14 00:00:071297 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1298 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
[email protected]ac790b42009-12-02 04:31:311299 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1300 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1301 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1302 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1303 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091304
[email protected]2431756e2010-09-29 20:26:131305 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091306
[email protected]2431756e2010-09-29 20:26:131307 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
1308 EXPECT_EQ(OK, request(i)->WaitForResult());
[email protected]c9d6a1d2009-07-14 16:15:201309
[email protected]2431756e2010-09-29 20:26:131310 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]c9d6a1d2009-07-14 16:15:201311 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131312 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1313 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091314}
1315
1316// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:051317// The pending connect job will be cancelled and should not call back into
1318// ClientSocketPoolBase.
1319TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531320 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201321
[email protected]ab838892009-06-30 18:49:051322 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131323 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521324 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:151325 EXPECT_EQ(ERR_IO_PENDING,
1326 handle.Init("a", params_, DEFAULT_PRIORITY,
1327 ClientSocketPool::RespectLimits::ENABLED,
1328 callback.callback(), pool_.get(), BoundNetLog()));
[email protected]2431756e2010-09-29 20:26:131329 handle.Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091330}
1331
[email protected]ab838892009-06-30 18:49:051332TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531333 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201334
[email protected]ab838892009-06-30 18:49:051335 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061336 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521337 TestCompletionCallback callback;
[email protected]f6d1d6eb2009-06-24 20:16:091338
mmenked3641e12016-01-28 16:06:151339 EXPECT_EQ(ERR_IO_PENDING,
1340 handle.Init("a", params_, DEFAULT_PRIORITY,
1341 ClientSocketPool::RespectLimits::ENABLED,
1342 callback.callback(), pool_.get(), BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091343
1344 handle.Reset();
1345
[email protected]6ecf2b92011-12-15 01:14:521346 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:131347 EXPECT_EQ(ERR_IO_PENDING,
mmenked3641e12016-01-28 16:06:151348 handle.Init("a", params_, DEFAULT_PRIORITY,
1349 ClientSocketPool::RespectLimits::ENABLED,
1350 callback2.callback(), pool_.get(), BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091351
1352 EXPECT_EQ(OK, callback2.WaitForResult());
1353 EXPECT_FALSE(callback.have_result());
1354
1355 handle.Reset();
1356}
1357
[email protected]ab838892009-06-30 18:49:051358TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531359 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091360
[email protected]bb1c4662013-11-14 00:00:071361 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1362 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
[email protected]ac790b42009-12-02 04:31:311363 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1364 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1365 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1366 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1367 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091368
1369 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201370 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]2431756e2010-09-29 20:26:131371 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1372 (*requests())[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091373
[email protected]2431756e2010-09-29 20:26:131374 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091375
[email protected]c9d6a1d2009-07-14 16:15:201376 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1377 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131378 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1379 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091380
[email protected]c9d6a1d2009-07-14 16:15:201381 EXPECT_EQ(1, GetOrderOfRequest(1));
1382 EXPECT_EQ(2, GetOrderOfRequest(2));
1383 EXPECT_EQ(5, GetOrderOfRequest(3));
1384 EXPECT_EQ(3, GetOrderOfRequest(4));
[email protected]2431756e2010-09-29 20:26:131385 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1386 GetOrderOfRequest(5)); // Canceled request.
[email protected]c9d6a1d2009-07-14 16:15:201387 EXPECT_EQ(4, GetOrderOfRequest(6));
1388 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171389
1390 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131391 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091392}
1393
mmenke33d24423d2015-05-19 19:41:091394// Function to be used as a callback on socket request completion. It first
1395// disconnects the successfully connected socket from the first request, and
1396// then reuses the ClientSocketHandle to request another socket.
1397//
1398// |nested_callback| is called with the result of the second socket request.
1399void RequestSocketOnComplete(ClientSocketHandle* handle,
1400 TestClientSocketPool* pool,
1401 TestConnectJobFactory* test_connect_job_factory,
1402 TestConnectJob::JobType next_job_type,
1403 const CompletionCallback& nested_callback,
1404 int first_request_result) {
1405 EXPECT_EQ(OK, first_request_result);
1406
1407 test_connect_job_factory->set_job_type(next_job_type);
1408
1409 // Don't allow reuse of the socket. Disconnect it and then release it.
1410 if (handle->socket())
1411 handle->socket()->Disconnect();
1412 handle->Reset();
1413
mmenked3641e12016-01-28 16:06:151414 scoped_refptr<TestSocketParams> params(new TestSocketParams());
mmenke33d24423d2015-05-19 19:41:091415 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:151416 int rv = handle->Init("a", params, LOWEST,
1417 ClientSocketPool::RespectLimits::ENABLED,
1418 nested_callback, pool, BoundNetLog());
mmenke33d24423d2015-05-19 19:41:091419 if (rv != ERR_IO_PENDING) {
1420 DCHECK_EQ(TestConnectJob::kMockJob, next_job_type);
1421 nested_callback.Run(rv);
1422 } else {
1423 DCHECK_EQ(TestConnectJob::kMockPendingJob, next_job_type);
[email protected]6ecf2b92011-12-15 01:14:521424 }
mmenke33d24423d2015-05-19 19:41:091425}
[email protected]f6d1d6eb2009-06-24 20:16:091426
mmenke33d24423d2015-05-19 19:41:091427// Tests the case where a second socket is requested in a completion callback,
1428// and the second socket connects asynchronously. Reuses the same
1429// ClientSocketHandle for the second socket, after disconnecting the first.
[email protected]2ab05b52009-07-01 23:57:581430TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531431 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201432
[email protected]0b7648c2009-07-06 20:14:011433 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061434 ClientSocketHandle handle;
mmenke33d24423d2015-05-19 19:41:091435 TestCompletionCallback second_result_callback;
1436 int rv = handle.Init(
mmenked3641e12016-01-28 16:06:151437 "a", params_, DEFAULT_PRIORITY, ClientSocketPool::RespectLimits::ENABLED,
mmenke33d24423d2015-05-19 19:41:091438 base::Bind(&RequestSocketOnComplete, &handle, pool_.get(),
1439 connect_job_factory_, TestConnectJob::kMockPendingJob,
1440 second_result_callback.callback()),
1441 pool_.get(), BoundNetLog());
[email protected]f6d1d6eb2009-06-24 20:16:091442 ASSERT_EQ(ERR_IO_PENDING, rv);
1443
mmenke33d24423d2015-05-19 19:41:091444 EXPECT_EQ(OK, second_result_callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581445}
[email protected]f6d1d6eb2009-06-24 20:16:091446
mmenke33d24423d2015-05-19 19:41:091447// Tests the case where a second socket is requested in a completion callback,
1448// and the second socket connects synchronously. Reuses the same
1449// ClientSocketHandle for the second socket, after disconnecting the first.
[email protected]2ab05b52009-07-01 23:57:581450TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531451 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201452
[email protected]0b7648c2009-07-06 20:14:011453 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061454 ClientSocketHandle handle;
mmenke33d24423d2015-05-19 19:41:091455 TestCompletionCallback second_result_callback;
1456 int rv = handle.Init(
mmenked3641e12016-01-28 16:06:151457 "a", params_, DEFAULT_PRIORITY, ClientSocketPool::RespectLimits::ENABLED,
mmenke33d24423d2015-05-19 19:41:091458 base::Bind(&RequestSocketOnComplete, &handle, pool_.get(),
1459 connect_job_factory_, TestConnectJob::kMockPendingJob,
1460 second_result_callback.callback()),
1461 pool_.get(), BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581462 ASSERT_EQ(ERR_IO_PENDING, rv);
1463
mmenke33d24423d2015-05-19 19:41:091464 EXPECT_EQ(OK, second_result_callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091465}
1466
1467// Make sure that pending requests get serviced after active requests get
1468// cancelled.
[email protected]ab838892009-06-30 18:49:051469TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531470 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201471
[email protected]0b7648c2009-07-06 20:14:011472 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091473
[email protected]bb1c4662013-11-14 00:00:071474 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1475 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1476 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1477 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1478 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1479 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1480 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
[email protected]f6d1d6eb2009-06-24 20:16:091481
[email protected]c9d6a1d2009-07-14 16:15:201482 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1483 // Let's cancel them.
1484 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]2431756e2010-09-29 20:26:131485 ASSERT_FALSE(request(i)->handle()->is_initialized());
1486 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091487 }
1488
[email protected]f6d1d6eb2009-06-24 20:16:091489 // Let's wait for the rest to complete now.
[email protected]2431756e2010-09-29 20:26:131490 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
1491 EXPECT_EQ(OK, request(i)->WaitForResult());
1492 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091493 }
1494
[email protected]2431756e2010-09-29 20:26:131495 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1496 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091497}
1498
1499// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051500TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531501 const size_t kMaxSockets = 5;
1502 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201503
[email protected]0b7648c2009-07-06 20:14:011504 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091505
[email protected]211d21722009-07-22 15:48:531506 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1507 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091508
1509 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531510 for (size_t i = 0; i < kNumberOfRequests; ++i)
[email protected]bb1c4662013-11-14 00:00:071511 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
[email protected]f6d1d6eb2009-06-24 20:16:091512
[email protected]211d21722009-07-22 15:48:531513 for (size_t i = 0; i < kNumberOfRequests; ++i)
[email protected]2431756e2010-09-29 20:26:131514 EXPECT_EQ(ERR_CONNECTION_FAILED, request(i)->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091515}
1516
[email protected]5fc08e32009-07-15 17:09:571517TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531518 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571519
1520 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1521
[email protected]2431756e2010-09-29 20:26:131522 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521523 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:151524 int rv = handle.Init("a", params_, DEFAULT_PRIORITY,
1525 ClientSocketPool::RespectLimits::ENABLED,
1526 callback.callback(), pool_.get(), BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571527 EXPECT_EQ(ERR_IO_PENDING, rv);
1528
1529 // Cancel the active request.
[email protected]2431756e2010-09-29 20:26:131530 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571531
mmenked3641e12016-01-28 16:06:151532 rv = handle.Init("a", params_, DEFAULT_PRIORITY,
1533 ClientSocketPool::RespectLimits::ENABLED,
1534 callback.callback(), pool_.get(), BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571535 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131536 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]5fc08e32009-07-15 17:09:571537
[email protected]2431756e2010-09-29 20:26:131538 EXPECT_FALSE(handle.is_reused());
[email protected]034df0f32013-01-07 23:17:481539 TestLoadTimingInfoConnectedNotReused(handle);
[email protected]5fc08e32009-07-15 17:09:571540 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1541}
1542
[email protected]2b7523d2009-07-29 20:29:231543// Regression test for http://crbug.com/17985.
1544TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1545 const int kMaxSockets = 3;
1546 const int kMaxSocketsPerGroup = 2;
1547 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1548
[email protected]ac790b42009-12-02 04:31:311549 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231550
[email protected]bb1c4662013-11-14 00:00:071551 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1552 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
[email protected]2b7523d2009-07-29 20:29:231553
1554 // This is going to be a pending request in an otherwise empty group.
[email protected]bb1c4662013-11-14 00:00:071555 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
[email protected]2b7523d2009-07-29 20:29:231556
1557 // Reach the maximum socket limit.
[email protected]bb1c4662013-11-14 00:00:071558 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
[email protected]2b7523d2009-07-29 20:29:231559
1560 // Create a stalled group with high priorities.
1561 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1562 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
[email protected]2b7523d2009-07-29 20:29:231563
[email protected]eb5a99382010-07-11 03:18:261564 // Release the first two sockets from "a". Because this is a keepalive,
1565 // the first release will unblock the pending request for "a". The
1566 // second release will unblock a request for "c", becaue it is the next
1567 // high priority socket.
[email protected]2431756e2010-09-29 20:26:131568 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1569 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]2b7523d2009-07-29 20:29:231570
1571 // Closing idle sockets should not get us into trouble, but in the bug
1572 // we were hitting a CHECK here.
[email protected]93054cc12010-06-08 06:12:411573 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]43a21b82010-06-10 21:30:541574 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261575
[email protected]2da659e2013-05-23 20:51:341576 // Run the released socket wakeups.
fdoray5eeb7642016-06-22 16:11:281577 base::RunLoop().RunUntilIdle();
[email protected]2b7523d2009-07-29 20:29:231578}
1579
[email protected]4d3b05d2010-01-27 21:27:291580TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531581 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571582
1583 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131584 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521585 TestCompletionCallback callback;
vishal.b62985ca92015-04-17 08:45:511586 BoundTestNetLog log;
mmenked3641e12016-01-28 16:06:151587 int rv = handle.Init("a", params_, LOWEST,
1588 ClientSocketPool::RespectLimits::ENABLED,
1589 callback.callback(), pool_.get(), log.bound());
[email protected]5fc08e32009-07-15 17:09:571590 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131591 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
[email protected]034df0f32013-01-07 23:17:481592 TestLoadTimingInfoNotConnected(handle);
1593
[email protected]2431756e2010-09-29 20:26:131594 EXPECT_EQ(OK, callback.WaitForResult());
1595 EXPECT_TRUE(handle.is_initialized());
1596 EXPECT_TRUE(handle.socket());
[email protected]034df0f32013-01-07 23:17:481597 TestLoadTimingInfoConnectedNotReused(handle);
1598
[email protected]2431756e2010-09-29 20:26:131599 handle.Reset();
[email protected]034df0f32013-01-07 23:17:481600 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:301601
mmenke43758e62015-05-04 21:09:461602 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:401603 log.GetEntries(&entries);
1604
1605 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:461606 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401607 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171608 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401609 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171610 NetLog::PHASE_NONE));
1611 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401612 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]06650c52010-06-03 00:49:171613 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:461614 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401615 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571616}
1617
[email protected]4d3b05d2010-01-27 21:27:291618TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571619 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531620 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571621
1622 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2431756e2010-09-29 20:26:131623 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521624 TestCompletionCallback callback;
vishal.b62985ca92015-04-17 08:45:511625 BoundTestNetLog log;
[email protected]e60e47a2010-07-14 03:37:181626 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:131627 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:431628 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:451629 info.headers = new HttpResponseHeaders(std::string());
[email protected]2431756e2010-09-29 20:26:131630 handle.set_ssl_error_response_info(info);
mmenked3641e12016-01-28 16:06:151631 EXPECT_EQ(ERR_IO_PENDING,
1632 handle.Init("a", params_, DEFAULT_PRIORITY,
1633 ClientSocketPool::RespectLimits::ENABLED,
1634 callback.callback(), pool_.get(), log.bound()));
[email protected]2431756e2010-09-29 20:26:131635 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1636 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1637 EXPECT_FALSE(handle.is_ssl_error());
1638 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:301639
mmenke43758e62015-05-04 21:09:461640 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:401641 log.GetEntries(&entries);
1642
1643 EXPECT_EQ(3u, entries.size());
[email protected]e9002a92010-01-29 07:10:461644 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401645 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171646 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401647 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171648 NetLog::PHASE_NONE));
[email protected]6b624c62010-03-14 08:37:321649 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401650 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571651}
1652
mmenke6be122f2015-03-09 22:22:471653// Check that an async ConnectJob failure does not result in creation of a new
1654// ConnectJob when there's another pending request also waiting on its own
1655// ConnectJob. See http://crbug.com/463960.
1656TEST_F(ClientSocketPoolBaseTest, AsyncFailureWithPendingRequestWithJob) {
1657 CreatePool(2, 2);
1658 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1659
1660 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1661 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1662
1663 EXPECT_EQ(ERR_CONNECTION_FAILED, request(0)->WaitForResult());
1664 EXPECT_EQ(ERR_CONNECTION_FAILED, request(1)->WaitForResult());
1665
1666 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1667}
1668
[email protected]4d3b05d2010-01-27 21:27:291669TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101670 // TODO(eroman): Add back the log expectations! Removed them because the
1671 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531672 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571673
1674 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131675 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521676 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131677 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:521678 TestCompletionCallback callback2;
[email protected]5fc08e32009-07-15 17:09:571679
[email protected]2431756e2010-09-29 20:26:131680 EXPECT_EQ(ERR_IO_PENDING,
mmenked3641e12016-01-28 16:06:151681 handle.Init("a", params_, DEFAULT_PRIORITY,
1682 ClientSocketPool::RespectLimits::ENABLED,
1683 callback.callback(), pool_.get(), BoundNetLog()));
vishal.b62985ca92015-04-17 08:45:511684 BoundTestNetLog log2;
[email protected]2431756e2010-09-29 20:26:131685 EXPECT_EQ(ERR_IO_PENDING,
mmenked3641e12016-01-28 16:06:151686 handle2.Init("a", params_, DEFAULT_PRIORITY,
1687 ClientSocketPool::RespectLimits::ENABLED,
1688 callback2.callback(), pool_.get(), BoundNetLog()));
[email protected]5fc08e32009-07-15 17:09:571689
[email protected]2431756e2010-09-29 20:26:131690 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571691
[email protected]fd7b7c92009-08-20 19:38:301692
1693 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301694
[email protected]2431756e2010-09-29 20:26:131695 EXPECT_EQ(OK, callback2.WaitForResult());
1696 handle2.Reset();
[email protected]fd7b7c92009-08-20 19:38:301697
1698 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531699 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571700}
1701
[email protected]4d3b05d2010-01-27 21:27:291702TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341703 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1704
[email protected]17a0c6c2009-08-04 00:07:041705 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1706
[email protected]ac790b42009-12-02 04:31:311707 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1708 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1709 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1710 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341711
1712 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]2431756e2010-09-29 20:26:131713 (*requests())[2]->handle()->Reset();
1714 (*requests())[3]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341715 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1716
[email protected]2431756e2010-09-29 20:26:131717 (*requests())[1]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341718 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1719
[email protected]2431756e2010-09-29 20:26:131720 (*requests())[0]->handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261721 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]974ebd62009-08-03 23:14:341722}
1723
[email protected]5fc08e32009-07-15 17:09:571724// When requests and ConnectJobs are not coupled, the request will get serviced
1725// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291726TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531727 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571728
1729 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321730 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571731
[email protected]2431756e2010-09-29 20:26:131732 std::vector<TestSocketRequest*> request_order;
1733 size_t completion_count; // unused
1734 TestSocketRequest req1(&request_order, &completion_count);
mmenked3641e12016-01-28 16:06:151735 int rv = req1.handle()->Init("a", params_, DEFAULT_PRIORITY,
1736 ClientSocketPool::RespectLimits::ENABLED,
1737 req1.callback(), pool_.get(), BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571738 EXPECT_EQ(ERR_IO_PENDING, rv);
1739 EXPECT_EQ(OK, req1.WaitForResult());
1740
1741 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1742 // without a job.
1743 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1744
[email protected]2431756e2010-09-29 20:26:131745 TestSocketRequest req2(&request_order, &completion_count);
mmenked3641e12016-01-28 16:06:151746 rv = req2.handle()->Init("a", params_, DEFAULT_PRIORITY,
1747 ClientSocketPool::RespectLimits::ENABLED,
1748 req2.callback(), pool_.get(), BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571749 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131750 TestSocketRequest req3(&request_order, &completion_count);
mmenked3641e12016-01-28 16:06:151751 rv = req3.handle()->Init("a", params_, DEFAULT_PRIORITY,
1752 ClientSocketPool::RespectLimits::ENABLED,
1753 req3.callback(), pool_.get(), BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571754 EXPECT_EQ(ERR_IO_PENDING, rv);
1755
1756 // Both Requests 2 and 3 are pending. We release socket 1 which should
1757 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331758 req1.handle()->Reset();
[email protected]2da659e2013-05-23 20:51:341759 // Run the released socket wakeups.
fdoray5eeb7642016-06-22 16:11:281760 base::RunLoop().RunUntilIdle();
[email protected]a6c59f62009-07-29 16:33:331761 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571762 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331763 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571764
1765 // Signal job 2, which should service request 3.
1766
1767 client_socket_factory_.SignalJobs();
1768 EXPECT_EQ(OK, req3.WaitForResult());
1769
[email protected]2431756e2010-09-29 20:26:131770 ASSERT_EQ(3U, request_order.size());
1771 EXPECT_EQ(&req1, request_order[0]);
1772 EXPECT_EQ(&req2, request_order[1]);
1773 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571774 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1775}
1776
1777// The requests are not coupled to the jobs. So, the requests should finish in
1778// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:291779TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531780 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571781 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321782 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571783
[email protected]2431756e2010-09-29 20:26:131784 std::vector<TestSocketRequest*> request_order;
1785 size_t completion_count; // unused
1786 TestSocketRequest req1(&request_order, &completion_count);
mmenked3641e12016-01-28 16:06:151787 int rv = req1.handle()->Init("a", params_, DEFAULT_PRIORITY,
1788 ClientSocketPool::RespectLimits::ENABLED,
1789 req1.callback(), pool_.get(), BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571790 EXPECT_EQ(ERR_IO_PENDING, rv);
1791
[email protected]2431756e2010-09-29 20:26:131792 TestSocketRequest req2(&request_order, &completion_count);
mmenked3641e12016-01-28 16:06:151793 rv = req2.handle()->Init("a", params_, DEFAULT_PRIORITY,
1794 ClientSocketPool::RespectLimits::ENABLED,
1795 req2.callback(), pool_.get(), BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571796 EXPECT_EQ(ERR_IO_PENDING, rv);
1797
1798 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321799 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571800
[email protected]2431756e2010-09-29 20:26:131801 TestSocketRequest req3(&request_order, &completion_count);
mmenked3641e12016-01-28 16:06:151802 rv = req3.handle()->Init("a", params_, DEFAULT_PRIORITY,
1803 ClientSocketPool::RespectLimits::ENABLED,
1804 req3.callback(), pool_.get(), BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571805 EXPECT_EQ(ERR_IO_PENDING, rv);
1806
1807 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1808 EXPECT_EQ(OK, req2.WaitForResult());
1809 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1810
[email protected]2431756e2010-09-29 20:26:131811 ASSERT_EQ(3U, request_order.size());
1812 EXPECT_EQ(&req1, request_order[0]);
1813 EXPECT_EQ(&req2, request_order[1]);
1814 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571815}
1816
[email protected]03b7c8c2013-07-20 04:38:551817// Test GetLoadState in the case there's only one socket request.
1818TEST_F(ClientSocketPoolBaseTest, LoadStateOneRequest) {
[email protected]211d21722009-07-22 15:48:531819 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]03b7c8c2013-07-20 04:38:551820 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]5fc08e32009-07-15 17:09:571821
[email protected]2431756e2010-09-29 20:26:131822 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521823 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:151824 int rv = handle.Init("a", params_, DEFAULT_PRIORITY,
1825 ClientSocketPool::RespectLimits::ENABLED,
1826 callback.callback(), pool_.get(), BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571827 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]03b7c8c2013-07-20 04:38:551828 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571829
[email protected]03b7c8c2013-07-20 04:38:551830 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
1831 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
1832
1833 // No point in completing the connection, since ClientSocketHandles only
1834 // expect the LoadState to be checked while connecting.
1835}
1836
1837// Test GetLoadState in the case there are two socket requests.
haavardm835c1d62015-04-22 08:18:001838// Only the first connection in the pool should affect the pool's load status.
[email protected]03b7c8c2013-07-20 04:38:551839TEST_F(ClientSocketPoolBaseTest, LoadStateTwoRequests) {
1840 CreatePool(2, 2);
1841 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1842
1843 ClientSocketHandle handle;
1844 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:151845 int rv = handle.Init("a", params_, DEFAULT_PRIORITY,
1846 ClientSocketPool::RespectLimits::ENABLED,
1847 callback.callback(), pool_.get(), BoundNetLog());
haavardm835c1d62015-04-22 08:18:001848 EXPECT_EQ(ERR_IO_PENDING, rv);
1849 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
1850
1851 ClientSocketHandle handle2;
1852 TestCompletionCallback callback2;
mmenked3641e12016-01-28 16:06:151853 rv = handle2.Init("a", params_, DEFAULT_PRIORITY,
1854 ClientSocketPool::RespectLimits::ENABLED,
1855 callback2.callback(), pool_.get(), BoundNetLog());
haavardm835c1d62015-04-22 08:18:001856 EXPECT_EQ(ERR_IO_PENDING, rv);
1857 client_socket_factory_.SetJobLoadState(1, LOAD_STATE_RESOLVING_HOST);
1858
1859 // Check that both handles report the state of the first job.
1860 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle.GetLoadState());
1861 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle2.GetLoadState());
1862
1863 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_CONNECTING);
1864
1865 // Check that both handles change to LOAD_STATE_CONNECTING.
1866 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
1867 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
1868}
1869
1870// Test that the second connection request does not affect the pool's load
1871// status.
1872TEST_F(ClientSocketPoolBaseTest, LoadStateTwoRequestsChangeSecondRequestState) {
1873 CreatePool(2, 2);
1874 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1875
1876 ClientSocketHandle handle;
1877 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:151878 int rv = handle.Init("a", params_, DEFAULT_PRIORITY,
1879 ClientSocketPool::RespectLimits::ENABLED,
1880 callback.callback(), pool_.get(), BoundNetLog());
[email protected]03b7c8c2013-07-20 04:38:551881 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]5fc08e32009-07-15 17:09:571882
[email protected]2431756e2010-09-29 20:26:131883 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:521884 TestCompletionCallback callback2;
mmenked3641e12016-01-28 16:06:151885 rv = handle2.Init("a", params_, DEFAULT_PRIORITY,
1886 ClientSocketPool::RespectLimits::ENABLED,
1887 callback2.callback(), pool_.get(), BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571888 EXPECT_EQ(ERR_IO_PENDING, rv);
haavardm835c1d62015-04-22 08:18:001889 client_socket_factory_.SetJobLoadState(1, LOAD_STATE_RESOLVING_HOST);
[email protected]03b7c8c2013-07-20 04:38:551890
[email protected]03b7c8c2013-07-20 04:38:551891 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
1892 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
1893
haavardm835c1d62015-04-22 08:18:001894 // First job connects and the first request gets the socket. The
[email protected]03b7c8c2013-07-20 04:38:551895 // second handle switches to the state of the remaining ConnectJob.
1896 client_socket_factory_.SignalJob(0);
1897 EXPECT_EQ(OK, callback.WaitForResult());
haavardm835c1d62015-04-22 08:18:001898 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle2.GetLoadState());
[email protected]03b7c8c2013-07-20 04:38:551899}
1900
1901// Test GetLoadState in the case the per-group limit is reached.
1902TEST_F(ClientSocketPoolBaseTest, LoadStateGroupLimit) {
1903 CreatePool(2, 1);
1904 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1905
1906 ClientSocketHandle handle;
1907 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:151908 int rv = handle.Init("a", params_, MEDIUM,
1909 ClientSocketPool::RespectLimits::ENABLED,
1910 callback.callback(), pool_.get(), BoundNetLog());
[email protected]03b7c8c2013-07-20 04:38:551911 EXPECT_EQ(ERR_IO_PENDING, rv);
1912 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
1913
1914 // Request another socket from the same pool, buth with a higher priority.
1915 // The first request should now be stalled at the socket group limit.
1916 ClientSocketHandle handle2;
1917 TestCompletionCallback callback2;
mmenked3641e12016-01-28 16:06:151918 rv = handle2.Init("a", params_, HIGHEST,
1919 ClientSocketPool::RespectLimits::ENABLED,
1920 callback2.callback(), pool_.get(), BoundNetLog());
[email protected]03b7c8c2013-07-20 04:38:551921 EXPECT_EQ(ERR_IO_PENDING, rv);
1922 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
1923 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
1924
1925 // The first handle should remain stalled as the other socket goes through
1926 // the connect process.
1927
1928 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
1929 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
1930 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle2.GetLoadState());
1931
1932 client_socket_factory_.SignalJob(0);
1933 EXPECT_EQ(OK, callback2.WaitForResult());
1934 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
1935
1936 // Closing the second socket should cause the stalled handle to finally get a
1937 // ConnectJob.
1938 handle2.socket()->Disconnect();
1939 handle2.Reset();
1940 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
1941}
1942
1943// Test GetLoadState in the case the per-pool limit is reached.
1944TEST_F(ClientSocketPoolBaseTest, LoadStatePoolLimit) {
1945 CreatePool(2, 2);
1946 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1947
1948 ClientSocketHandle handle;
1949 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:151950 int rv = handle.Init("a", params_, DEFAULT_PRIORITY,
1951 ClientSocketPool::RespectLimits::ENABLED,
1952 callback.callback(), pool_.get(), BoundNetLog());
[email protected]03b7c8c2013-07-20 04:38:551953 EXPECT_EQ(ERR_IO_PENDING, rv);
1954
1955 // Request for socket from another pool.
1956 ClientSocketHandle handle2;
1957 TestCompletionCallback callback2;
mmenked3641e12016-01-28 16:06:151958 rv = handle2.Init("b", params_, DEFAULT_PRIORITY,
1959 ClientSocketPool::RespectLimits::ENABLED,
1960 callback2.callback(), pool_.get(), BoundNetLog());
[email protected]03b7c8c2013-07-20 04:38:551961 EXPECT_EQ(ERR_IO_PENDING, rv);
1962
1963 // Request another socket from the first pool. Request should stall at the
1964 // socket pool limit.
1965 ClientSocketHandle handle3;
1966 TestCompletionCallback callback3;
mmenked3641e12016-01-28 16:06:151967 rv = handle3.Init("a", params_, DEFAULT_PRIORITY,
1968 ClientSocketPool::RespectLimits::ENABLED,
1969 callback2.callback(), pool_.get(), BoundNetLog());
[email protected]03b7c8c2013-07-20 04:38:551970 EXPECT_EQ(ERR_IO_PENDING, rv);
1971
1972 // The third handle should remain stalled as the other sockets in its group
1973 // goes through the connect process.
1974
1975 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
1976 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
1977
1978 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
1979 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
1980 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
1981
1982 client_socket_factory_.SignalJob(0);
1983 EXPECT_EQ(OK, callback.WaitForResult());
1984 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
1985
1986 // Closing a socket should allow the stalled handle to finally get a new
1987 // ConnectJob.
1988 handle.socket()->Disconnect();
1989 handle.Reset();
1990 EXPECT_EQ(LOAD_STATE_CONNECTING, handle3.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571991}
1992
[email protected]e772db3f2010-07-12 18:11:131993TEST_F(ClientSocketPoolBaseTest, Recoverable) {
1994 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1995 connect_job_factory_->set_job_type(TestConnectJob::kMockRecoverableJob);
1996
[email protected]2431756e2010-09-29 20:26:131997 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521998 TestCompletionCallback callback;
1999 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED,
mmenked3641e12016-01-28 16:06:152000 handle.Init("a", params_, DEFAULT_PRIORITY,
2001 ClientSocketPool::RespectLimits::ENABLED,
2002 callback.callback(), pool_.get(), BoundNetLog()));
[email protected]2431756e2010-09-29 20:26:132003 EXPECT_TRUE(handle.is_initialized());
2004 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:132005}
2006
2007TEST_F(ClientSocketPoolBaseTest, AsyncRecoverable) {
2008 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2009
2010 connect_job_factory_->set_job_type(
2011 TestConnectJob::kMockPendingRecoverableJob);
[email protected]2431756e2010-09-29 20:26:132012 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522013 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132014 EXPECT_EQ(ERR_IO_PENDING,
mmenked3641e12016-01-28 16:06:152015 handle.Init("a", params_, DEFAULT_PRIORITY,
2016 ClientSocketPool::RespectLimits::ENABLED,
2017 callback.callback(), pool_.get(), BoundNetLog()));
[email protected]2431756e2010-09-29 20:26:132018 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2019 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, callback.WaitForResult());
2020 EXPECT_TRUE(handle.is_initialized());
2021 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:132022}
2023
[email protected]e60e47a2010-07-14 03:37:182024TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
2025 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2026 connect_job_factory_->set_job_type(
2027 TestConnectJob::kMockAdditionalErrorStateJob);
2028
[email protected]2431756e2010-09-29 20:26:132029 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522030 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132031 EXPECT_EQ(ERR_CONNECTION_FAILED,
mmenked3641e12016-01-28 16:06:152032 handle.Init("a", params_, DEFAULT_PRIORITY,
2033 ClientSocketPool::RespectLimits::ENABLED,
2034 callback.callback(), pool_.get(), BoundNetLog()));
[email protected]2431756e2010-09-29 20:26:132035 EXPECT_FALSE(handle.is_initialized());
2036 EXPECT_FALSE(handle.socket());
2037 EXPECT_TRUE(handle.is_ssl_error());
2038 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182039}
2040
2041TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
2042 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2043
2044 connect_job_factory_->set_job_type(
2045 TestConnectJob::kMockPendingAdditionalErrorStateJob);
[email protected]2431756e2010-09-29 20:26:132046 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522047 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132048 EXPECT_EQ(ERR_IO_PENDING,
mmenked3641e12016-01-28 16:06:152049 handle.Init("a", params_, DEFAULT_PRIORITY,
2050 ClientSocketPool::RespectLimits::ENABLED,
2051 callback.callback(), pool_.get(), BoundNetLog()));
[email protected]2431756e2010-09-29 20:26:132052 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2053 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
2054 EXPECT_FALSE(handle.is_initialized());
2055 EXPECT_FALSE(handle.socket());
2056 EXPECT_TRUE(handle.is_ssl_error());
2057 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182058}
2059
martijn003cd612016-05-19 22:24:382060// Make sure we can reuse sockets.
2061TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSocketsReuse) {
[email protected]64770b7d2011-11-16 04:30:412062 CreatePoolWithIdleTimeouts(
2063 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
[email protected]e7b1c6d2c2012-05-05 00:54:032064 base::TimeDelta(), // Time out unused sockets immediately.
2065 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2066
2067 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2068
2069 ClientSocketHandle handle;
2070 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:152071 int rv = handle.Init("a", params_, LOWEST,
2072 ClientSocketPool::RespectLimits::ENABLED,
2073 callback.callback(), pool_.get(), BoundNetLog());
[email protected]e7b1c6d2c2012-05-05 00:54:032074 ASSERT_EQ(ERR_IO_PENDING, rv);
2075 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2076 ASSERT_EQ(OK, callback.WaitForResult());
2077
2078 // Use and release the socket.
2079 EXPECT_EQ(1, handle.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]034df0f32013-01-07 23:17:482080 TestLoadTimingInfoConnectedNotReused(handle);
[email protected]e7b1c6d2c2012-05-05 00:54:032081 handle.Reset();
2082
2083 // Should now have one idle socket.
2084 ASSERT_EQ(1, pool_->IdleSocketCount());
2085
2086 // Request a new socket. This should reuse the old socket and complete
2087 // synchronously.
vishal.b62985ca92015-04-17 08:45:512088 BoundTestNetLog log;
mmenked3641e12016-01-28 16:06:152089 rv = handle.Init("a", params_, LOWEST,
2090 ClientSocketPool::RespectLimits::ENABLED,
2091 CompletionCallback(), pool_.get(), log.bound());
[email protected]e7b1c6d2c2012-05-05 00:54:032092 ASSERT_EQ(OK, rv);
2093 EXPECT_TRUE(handle.is_reused());
[email protected]034df0f32013-01-07 23:17:482094 TestLoadTimingInfoConnectedReused(handle);
[email protected]e7b1c6d2c2012-05-05 00:54:032095
2096 ASSERT_TRUE(pool_->HasGroup("a"));
2097 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2098 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2099
mmenke43758e62015-05-04 21:09:462100 TestNetLogEntry::List entries;
[email protected]e7b1c6d2c2012-05-05 00:54:032101 log.GetEntries(&entries);
2102 EXPECT_TRUE(LogContainsEntryWithType(
2103 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
2104}
2105
blundellb8163592f2015-12-16 14:22:422106#if defined(OS_IOS)
2107// TODO(droger): Enable this test (crbug.com/512595).
martijn003cd612016-05-19 22:24:382108#define MAYBE_CleanupTimedOutIdleSocketsNoReuse \
2109 DISABLED_CleanupTimedOutIdleSocketsNoReuse
blundellb8163592f2015-12-16 14:22:422110#else
martijn003cd612016-05-19 22:24:382111#define MAYBE_CleanupTimedOutIdleSocketsNoReuse \
2112 CleanupTimedOutIdleSocketsNoReuse
blundellb8163592f2015-12-16 14:22:422113#endif
martijn003cd612016-05-19 22:24:382114// Make sure we cleanup old unused sockets.
2115TEST_F(ClientSocketPoolBaseTest, MAYBE_CleanupTimedOutIdleSocketsNoReuse) {
[email protected]e7b1c6d2c2012-05-05 00:54:032116 CreatePoolWithIdleTimeouts(
2117 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2118 base::TimeDelta(), // Time out unused sockets immediately
2119 base::TimeDelta()); // Time out used sockets immediately
[email protected]64770b7d2011-11-16 04:30:412120
2121 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2122
2123 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2124
2125 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522126 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:152127 int rv = handle.Init("a", params_, LOWEST,
2128 ClientSocketPool::RespectLimits::ENABLED,
2129 callback.callback(), pool_.get(), BoundNetLog());
[email protected]e7b1c6d2c2012-05-05 00:54:032130 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]64770b7d2011-11-16 04:30:412131 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2132
2133 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522134 TestCompletionCallback callback2;
mmenked3641e12016-01-28 16:06:152135 rv = handle2.Init("a", params_, LOWEST,
2136 ClientSocketPool::RespectLimits::ENABLED,
2137 callback2.callback(), pool_.get(), BoundNetLog());
[email protected]e7b1c6d2c2012-05-05 00:54:032138 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]64770b7d2011-11-16 04:30:412139 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
2140
2141 // Cancel one of the requests. Wait for the other, which will get the first
2142 // job. Release the socket. Run the loop again to make sure the second
2143 // socket is sitting idle and the first one is released (since ReleaseSocket()
2144 // just posts a DoReleaseSocket() task).
2145
2146 handle.Reset();
[email protected]e7b1c6d2c2012-05-05 00:54:032147 ASSERT_EQ(OK, callback2.WaitForResult());
[email protected]64770b7d2011-11-16 04:30:412148 // Use the socket.
[email protected]83039bb2011-12-09 18:43:552149 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]64770b7d2011-11-16 04:30:412150 handle2.Reset();
2151
[email protected]e7b1c6d2c2012-05-05 00:54:032152 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2153 // actually become pending until 2ms after they have been created. In order
2154 // to flush all tasks, we need to wait so that we know there are no
2155 // soon-to-be-pending tasks waiting.
2156 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
fdoray5eeb7642016-06-22 16:11:282157 base::RunLoop().RunUntilIdle();
[email protected]64770b7d2011-11-16 04:30:412158
[email protected]e7b1c6d2c2012-05-05 00:54:032159 // Both sockets should now be idle.
[email protected]64770b7d2011-11-16 04:30:412160 ASSERT_EQ(2, pool_->IdleSocketCount());
2161
2162 // Request a new socket. This should cleanup the unused and timed out ones.
2163 // A new socket will be created rather than reusing the idle one.
vishal.b62985ca92015-04-17 08:45:512164 BoundTestNetLog log;
[email protected]6ecf2b92011-12-15 01:14:522165 TestCompletionCallback callback3;
mmenked3641e12016-01-28 16:06:152166 rv = handle.Init("a", params_, LOWEST,
2167 ClientSocketPool::RespectLimits::ENABLED,
2168 callback3.callback(), pool_.get(), log.bound());
[email protected]e7b1c6d2c2012-05-05 00:54:032169 ASSERT_EQ(ERR_IO_PENDING, rv);
2170 ASSERT_EQ(OK, callback3.WaitForResult());
[email protected]64770b7d2011-11-16 04:30:412171 EXPECT_FALSE(handle.is_reused());
2172
[email protected]e7b1c6d2c2012-05-05 00:54:032173 // Make sure the idle socket is closed.
[email protected]64770b7d2011-11-16 04:30:412174 ASSERT_TRUE(pool_->HasGroup("a"));
2175 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2176 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2177
mmenke43758e62015-05-04 21:09:462178 TestNetLogEntry::List entries;
[email protected]64770b7d2011-11-16 04:30:412179 log.GetEntries(&entries);
2180 EXPECT_FALSE(LogContainsEntryWithType(
2181 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
2182}
2183
[email protected]2041cf342010-02-19 03:15:592184// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:162185// because of multiple releasing disconnected sockets.
2186TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
2187 CreatePoolWithIdleTimeouts(
2188 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2189 base::TimeDelta(), // Time out unused sockets immediately.
2190 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2191
2192 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2193
2194 // Startup 4 connect jobs. Two of them will be pending.
2195
[email protected]2431756e2010-09-29 20:26:132196 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522197 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:152198 int rv = handle.Init("a", params_, LOWEST,
2199 ClientSocketPool::RespectLimits::ENABLED,
2200 callback.callback(), pool_.get(), BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162201 EXPECT_EQ(OK, rv);
2202
[email protected]2431756e2010-09-29 20:26:132203 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522204 TestCompletionCallback callback2;
mmenked3641e12016-01-28 16:06:152205 rv = handle2.Init("a", params_, LOWEST,
2206 ClientSocketPool::RespectLimits::ENABLED,
2207 callback2.callback(), pool_.get(), BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162208 EXPECT_EQ(OK, rv);
2209
[email protected]2431756e2010-09-29 20:26:132210 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:522211 TestCompletionCallback callback3;
mmenked3641e12016-01-28 16:06:152212 rv = handle3.Init("a", params_, LOWEST,
2213 ClientSocketPool::RespectLimits::ENABLED,
2214 callback3.callback(), pool_.get(), BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162215 EXPECT_EQ(ERR_IO_PENDING, rv);
2216
[email protected]2431756e2010-09-29 20:26:132217 ClientSocketHandle handle4;
[email protected]6ecf2b92011-12-15 01:14:522218 TestCompletionCallback callback4;
mmenked3641e12016-01-28 16:06:152219 rv = handle4.Init("a", params_, LOWEST,
2220 ClientSocketPool::RespectLimits::ENABLED,
2221 callback4.callback(), pool_.get(), BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162222 EXPECT_EQ(ERR_IO_PENDING, rv);
2223
2224 // Release two disconnected sockets.
2225
[email protected]2431756e2010-09-29 20:26:132226 handle.socket()->Disconnect();
2227 handle.Reset();
2228 handle2.socket()->Disconnect();
2229 handle2.Reset();
[email protected]4f2abec2010-02-03 18:10:162230
[email protected]2431756e2010-09-29 20:26:132231 EXPECT_EQ(OK, callback3.WaitForResult());
2232 EXPECT_FALSE(handle3.is_reused());
2233 EXPECT_EQ(OK, callback4.WaitForResult());
2234 EXPECT_FALSE(handle4.is_reused());
[email protected]4f2abec2010-02-03 18:10:162235}
2236
[email protected]d7027bb2010-05-10 18:58:542237// Regression test for http://crbug.com/42267.
2238// When DoReleaseSocket() is processed for one socket, it is blocked because the
2239// other stalled groups all have releasing sockets, so no progress can be made.
2240TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
2241 CreatePoolWithIdleTimeouts(
2242 4 /* socket limit */, 4 /* socket limit per group */,
2243 base::TimeDelta(), // Time out unused sockets immediately.
2244 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2245
2246 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2247
2248 // Max out the socket limit with 2 per group.
2249
[email protected]2431756e2010-09-29 20:26:132250 ClientSocketHandle handle_a[4];
[email protected]6ecf2b92011-12-15 01:14:522251 TestCompletionCallback callback_a[4];
[email protected]2431756e2010-09-29 20:26:132252 ClientSocketHandle handle_b[4];
[email protected]6ecf2b92011-12-15 01:14:522253 TestCompletionCallback callback_b[4];
[email protected]d7027bb2010-05-10 18:58:542254
2255 for (int i = 0; i < 2; ++i) {
mmenked3641e12016-01-28 16:06:152256 EXPECT_EQ(OK, handle_a[i].Init("a", params_, LOWEST,
2257 ClientSocketPool::RespectLimits::ENABLED,
2258 callback_a[i].callback(), pool_.get(),
[email protected]2431756e2010-09-29 20:26:132259 BoundNetLog()));
mmenked3641e12016-01-28 16:06:152260 EXPECT_EQ(OK, handle_b[i].Init("b", params_, LOWEST,
2261 ClientSocketPool::RespectLimits::ENABLED,
2262 callback_b[i].callback(), pool_.get(),
[email protected]2431756e2010-09-29 20:26:132263 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542264 }
[email protected]b89f7e42010-05-20 20:37:002265
[email protected]d7027bb2010-05-10 18:58:542266 // Make 4 pending requests, 2 per group.
2267
2268 for (int i = 2; i < 4; ++i) {
mmenked3641e12016-01-28 16:06:152269 EXPECT_EQ(
2270 ERR_IO_PENDING,
2271 handle_a[i].Init("a", params_, LOWEST,
2272 ClientSocketPool::RespectLimits::ENABLED,
2273 callback_a[i].callback(), pool_.get(), BoundNetLog()));
2274 EXPECT_EQ(
2275 ERR_IO_PENDING,
2276 handle_b[i].Init("b", params_, LOWEST,
2277 ClientSocketPool::RespectLimits::ENABLED,
2278 callback_b[i].callback(), pool_.get(), BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542279 }
2280
2281 // Release b's socket first. The order is important, because in
2282 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2283 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2284 // first, which has a releasing socket, so it refuses to start up another
2285 // ConnectJob. So, we used to infinite loop on this.
[email protected]2431756e2010-09-29 20:26:132286 handle_b[0].socket()->Disconnect();
2287 handle_b[0].Reset();
2288 handle_a[0].socket()->Disconnect();
2289 handle_a[0].Reset();
[email protected]d7027bb2010-05-10 18:58:542290
2291 // Used to get stuck here.
fdoray5eeb7642016-06-22 16:11:282292 base::RunLoop().RunUntilIdle();
[email protected]d7027bb2010-05-10 18:58:542293
[email protected]2431756e2010-09-29 20:26:132294 handle_b[1].socket()->Disconnect();
2295 handle_b[1].Reset();
2296 handle_a[1].socket()->Disconnect();
2297 handle_a[1].Reset();
[email protected]d7027bb2010-05-10 18:58:542298
2299 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132300 EXPECT_EQ(OK, callback_b[i].WaitForResult());
2301 EXPECT_EQ(OK, callback_a[i].WaitForResult());
[email protected]d7027bb2010-05-10 18:58:542302 }
2303}
2304
[email protected]fd4fe0b2010-02-08 23:02:152305TEST_F(ClientSocketPoolBaseTest,
2306 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2307 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2308
2309 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2310
[email protected]bb1c4662013-11-14 00:00:072311 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
2312 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
2313 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
2314 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
[email protected]fd4fe0b2010-02-08 23:02:152315
[email protected]2431756e2010-09-29 20:26:132316 EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
2317 EXPECT_EQ(OK, (*requests())[1]->WaitForResult());
2318 EXPECT_EQ(2u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152319
2320 // Releases one connection.
[email protected]2431756e2010-09-29 20:26:132321 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2322 EXPECT_EQ(OK, (*requests())[2]->WaitForResult());
[email protected]fd4fe0b2010-02-08 23:02:152323
[email protected]2431756e2010-09-29 20:26:132324 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2325 EXPECT_EQ(OK, (*requests())[3]->WaitForResult());
2326 EXPECT_EQ(4u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152327
2328 EXPECT_EQ(1, GetOrderOfRequest(1));
2329 EXPECT_EQ(2, GetOrderOfRequest(2));
2330 EXPECT_EQ(3, GetOrderOfRequest(3));
2331 EXPECT_EQ(4, GetOrderOfRequest(4));
2332
2333 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:132334 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
[email protected]fd4fe0b2010-02-08 23:02:152335}
2336
[email protected]6ecf2b92011-12-15 01:14:522337class TestReleasingSocketRequest : public TestCompletionCallbackBase {
[email protected]4f1e4982010-03-02 18:31:042338 public:
[email protected]2431756e2010-09-29 20:26:132339 TestReleasingSocketRequest(TestClientSocketPool* pool,
2340 int expected_result,
[email protected]e60e47a2010-07-14 03:37:182341 bool reset_releasing_handle)
2342 : pool_(pool),
2343 expected_result_(expected_result),
[email protected]6ecf2b92011-12-15 01:14:522344 reset_releasing_handle_(reset_releasing_handle),
[email protected]aa249b52013-04-30 01:04:322345 callback_(base::Bind(&TestReleasingSocketRequest::OnComplete,
2346 base::Unretained(this))) {
[email protected]6ecf2b92011-12-15 01:14:522347 }
2348
dchengb03027d2014-10-21 12:00:202349 ~TestReleasingSocketRequest() override {}
[email protected]4f1e4982010-03-02 18:31:042350
2351 ClientSocketHandle* handle() { return &handle_; }
2352
[email protected]6ecf2b92011-12-15 01:14:522353 const CompletionCallback& callback() const { return callback_; }
[email protected]4f1e4982010-03-02 18:31:042354
2355 private:
[email protected]6ecf2b92011-12-15 01:14:522356 void OnComplete(int result) {
2357 SetResult(result);
2358 if (reset_releasing_handle_)
2359 handle_.Reset();
2360
mmenked3641e12016-01-28 16:06:152361 scoped_refptr<TestSocketParams> con_params(new TestSocketParams());
[email protected]6ecf2b92011-12-15 01:14:522362 EXPECT_EQ(expected_result_,
[email protected]bb1c4662013-11-14 00:00:072363 handle2_.Init("a", con_params, DEFAULT_PRIORITY,
mmenked3641e12016-01-28 16:06:152364 ClientSocketPool::RespectLimits::ENABLED,
[email protected]6ecf2b92011-12-15 01:14:522365 callback2_.callback(), pool_, BoundNetLog()));
2366 }
2367
[email protected]2431756e2010-09-29 20:26:132368 TestClientSocketPool* const pool_;
[email protected]e60e47a2010-07-14 03:37:182369 int expected_result_;
2370 bool reset_releasing_handle_;
[email protected]4f1e4982010-03-02 18:31:042371 ClientSocketHandle handle_;
2372 ClientSocketHandle handle2_;
[email protected]6ecf2b92011-12-15 01:14:522373 CompletionCallback callback_;
2374 TestCompletionCallback callback2_;
[email protected]4f1e4982010-03-02 18:31:042375};
2376
[email protected]e60e47a2010-07-14 03:37:182377
2378TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2379 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2380
[email protected]bb1c4662013-11-14 00:00:072381 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
2382 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
2383 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
[email protected]e60e47a2010-07-14 03:37:182384
[email protected]2431756e2010-09-29 20:26:132385 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]e60e47a2010-07-14 03:37:182386 client_socket_factory_.allocation_count());
2387
2388 connect_job_factory_->set_job_type(
2389 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2390 TestReleasingSocketRequest req(pool_.get(), OK, false);
[email protected]2431756e2010-09-29 20:26:132391 EXPECT_EQ(ERR_IO_PENDING,
mmenked3641e12016-01-28 16:06:152392 req.handle()->Init("a", params_, DEFAULT_PRIORITY,
2393 ClientSocketPool::RespectLimits::ENABLED,
2394 req.callback(), pool_.get(), BoundNetLog()));
[email protected]e60e47a2010-07-14 03:37:182395 // The next job should complete synchronously
2396 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2397
2398 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
2399 EXPECT_FALSE(req.handle()->is_initialized());
2400 EXPECT_FALSE(req.handle()->socket());
2401 EXPECT_TRUE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:432402 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182403}
2404
[email protected]b6501d3d2010-06-03 23:53:342405// http://crbug.com/44724 regression test.
2406// We start releasing the pool when we flush on network change. When that
2407// happens, the only active references are in the ClientSocketHandles. When a
2408// ConnectJob completes and calls back into the last ClientSocketHandle, that
2409// callback can release the last reference and delete the pool. After the
2410// callback finishes, we go back to the stack frame within the now-deleted pool.
2411// Executing any code that refers to members of the now-deleted pool can cause
2412// crashes.
2413TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2414 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2415 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2416
2417 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522418 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:152419 EXPECT_EQ(ERR_IO_PENDING,
2420 handle.Init("a", params_, DEFAULT_PRIORITY,
2421 ClientSocketPool::RespectLimits::ENABLED,
2422 callback.callback(), pool_.get(), BoundNetLog()));
[email protected]b6501d3d2010-06-03 23:53:342423
[email protected]7af985a2012-12-14 22:40:422424 pool_->FlushWithError(ERR_NETWORK_CHANGED);
[email protected]b6501d3d2010-06-03 23:53:342425
2426 // We'll call back into this now.
2427 callback.WaitForResult();
2428}
2429
[email protected]a7e38572010-06-07 18:22:242430TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2431 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2432 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2433
2434 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522435 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:152436 EXPECT_EQ(ERR_IO_PENDING,
2437 handle.Init("a", params_, DEFAULT_PRIORITY,
2438 ClientSocketPool::RespectLimits::ENABLED,
2439 callback.callback(), pool_.get(), BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242440 EXPECT_EQ(OK, callback.WaitForResult());
2441 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2442
[email protected]7af985a2012-12-14 22:40:422443 pool_->FlushWithError(ERR_NETWORK_CHANGED);
[email protected]a7e38572010-06-07 18:22:242444
2445 handle.Reset();
fdoray5eeb7642016-06-22 16:11:282446 base::RunLoop().RunUntilIdle();
[email protected]a7e38572010-06-07 18:22:242447
mmenked3641e12016-01-28 16:06:152448 EXPECT_EQ(ERR_IO_PENDING,
2449 handle.Init("a", params_, DEFAULT_PRIORITY,
2450 ClientSocketPool::RespectLimits::ENABLED,
2451 callback.callback(), pool_.get(), BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242452 EXPECT_EQ(OK, callback.WaitForResult());
2453 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2454}
2455
[email protected]6ecf2b92011-12-15 01:14:522456class ConnectWithinCallback : public TestCompletionCallbackBase {
[email protected]06f92462010-08-31 19:24:142457 public:
2458 ConnectWithinCallback(
2459 const std::string& group_name,
2460 const scoped_refptr<TestSocketParams>& params,
[email protected]2431756e2010-09-29 20:26:132461 TestClientSocketPool* pool)
[email protected]6ecf2b92011-12-15 01:14:522462 : group_name_(group_name),
2463 params_(params),
2464 pool_(pool),
[email protected]aa249b52013-04-30 01:04:322465 callback_(base::Bind(&ConnectWithinCallback::OnComplete,
2466 base::Unretained(this))) {
[email protected]06f92462010-08-31 19:24:142467 }
2468
dchengb03027d2014-10-21 12:00:202469 ~ConnectWithinCallback() override {}
[email protected]06f92462010-08-31 19:24:142470
2471 int WaitForNestedResult() {
2472 return nested_callback_.WaitForResult();
2473 }
2474
[email protected]6ecf2b92011-12-15 01:14:522475 const CompletionCallback& callback() const { return callback_; }
2476
[email protected]06f92462010-08-31 19:24:142477 private:
[email protected]6ecf2b92011-12-15 01:14:522478 void OnComplete(int result) {
2479 SetResult(result);
2480 EXPECT_EQ(ERR_IO_PENDING,
mmenked3641e12016-01-28 16:06:152481 handle_.Init(group_name_, params_, DEFAULT_PRIORITY,
2482 ClientSocketPool::RespectLimits::ENABLED,
2483 nested_callback_.callback(), pool_, BoundNetLog()));
[email protected]6ecf2b92011-12-15 01:14:522484 }
2485
[email protected]06f92462010-08-31 19:24:142486 const std::string group_name_;
2487 const scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:132488 TestClientSocketPool* const pool_;
[email protected]06f92462010-08-31 19:24:142489 ClientSocketHandle handle_;
[email protected]6ecf2b92011-12-15 01:14:522490 CompletionCallback callback_;
2491 TestCompletionCallback nested_callback_;
2492
2493 DISALLOW_COPY_AND_ASSIGN(ConnectWithinCallback);
[email protected]06f92462010-08-31 19:24:142494};
2495
2496TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
2497 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2498
2499 // First job will be waiting until it gets aborted.
2500 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2501
2502 ClientSocketHandle handle;
[email protected]2431756e2010-09-29 20:26:132503 ConnectWithinCallback callback("a", params_, pool_.get());
mmenked3641e12016-01-28 16:06:152504 EXPECT_EQ(ERR_IO_PENDING,
2505 handle.Init("a", params_, DEFAULT_PRIORITY,
2506 ClientSocketPool::RespectLimits::ENABLED,
2507 callback.callback(), pool_.get(), BoundNetLog()));
[email protected]06f92462010-08-31 19:24:142508
2509 // Second job will be started during the first callback, and will
2510 // asynchronously complete with OK.
2511 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]7af985a2012-12-14 22:40:422512 pool_->FlushWithError(ERR_NETWORK_CHANGED);
2513 EXPECT_EQ(ERR_NETWORK_CHANGED, callback.WaitForResult());
[email protected]06f92462010-08-31 19:24:142514 EXPECT_EQ(OK, callback.WaitForNestedResult());
2515}
2516
[email protected]25eea382010-07-10 23:55:262517// Cancel a pending socket request while we're at max sockets,
2518// and verify that the backup socket firing doesn't cause a crash.
2519TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
2520 // Max 4 sockets globally, max 4 sockets per group.
2521 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
[email protected]06d94042010-08-25 01:45:222522 pool_->EnableConnectBackupJobs();
[email protected]25eea382010-07-10 23:55:262523
[email protected]4baaf9d2010-08-31 15:15:442524 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2525 // timer.
[email protected]25eea382010-07-10 23:55:262526 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2527 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522528 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:152529 EXPECT_EQ(ERR_IO_PENDING,
2530 handle.Init("bar", params_, DEFAULT_PRIORITY,
2531 ClientSocketPool::RespectLimits::ENABLED,
2532 callback.callback(), pool_.get(), BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262533
2534 // Start (MaxSockets - 1) connected sockets to reach max sockets.
2535 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2536 ClientSocketHandle handles[kDefaultMaxSockets];
2537 for (int i = 1; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:522538 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:152539 EXPECT_EQ(OK,
2540 handles[i].Init("bar", params_, DEFAULT_PRIORITY,
2541 ClientSocketPool::RespectLimits::ENABLED,
2542 callback.callback(), pool_.get(), BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262543 }
2544
fdoray5eeb7642016-06-22 16:11:282545 base::RunLoop().RunUntilIdle();
[email protected]25eea382010-07-10 23:55:262546
2547 // Cancel the pending request.
2548 handle.Reset();
2549
2550 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]26b9973962012-01-28 00:57:002551 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2552 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]25eea382010-07-10 23:55:262553
fdoray5eeb7642016-06-22 16:11:282554 base::RunLoop().RunUntilIdle();
[email protected]25eea382010-07-10 23:55:262555 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
2556}
2557
[email protected]3f00be82010-09-27 19:50:022558TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
[email protected]4baaf9d2010-08-31 15:15:442559 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2560 pool_->EnableConnectBackupJobs();
2561
2562 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2563 // timer.
2564 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2565 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522566 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:152567 EXPECT_EQ(ERR_IO_PENDING,
2568 handle.Init("bar", params_, DEFAULT_PRIORITY,
2569 ClientSocketPool::RespectLimits::ENABLED,
2570 callback.callback(), pool_.get(), BoundNetLog()));
[email protected]4baaf9d2010-08-31 15:15:442571 ASSERT_TRUE(pool_->HasGroup("bar"));
2572 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
[email protected]8159a1c2012-06-07 00:00:102573 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("bar"));
[email protected]4baaf9d2010-08-31 15:15:442574
2575 // Cancel the socket request. This should cancel the backup timer. Wait for
2576 // the backup time to see if it indeed got canceled.
2577 handle.Reset();
2578 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]26b9973962012-01-28 00:57:002579 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2580 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
fdoray5eeb7642016-06-22 16:11:282581 base::RunLoop().RunUntilIdle();
[email protected]4baaf9d2010-08-31 15:15:442582 ASSERT_TRUE(pool_->HasGroup("bar"));
2583 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2584}
2585
[email protected]3f00be82010-09-27 19:50:022586TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
2587 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2588 pool_->EnableConnectBackupJobs();
2589
2590 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2591 // timer.
2592 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2593 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522594 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:152595 EXPECT_EQ(ERR_IO_PENDING,
2596 handle.Init("bar", params_, DEFAULT_PRIORITY,
2597 ClientSocketPool::RespectLimits::ENABLED,
2598 callback.callback(), pool_.get(), BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022599 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2600 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522601 TestCompletionCallback callback2;
mmenked3641e12016-01-28 16:06:152602 EXPECT_EQ(ERR_IO_PENDING,
2603 handle2.Init("bar", params_, DEFAULT_PRIORITY,
2604 ClientSocketPool::RespectLimits::ENABLED,
2605 callback2.callback(), pool_.get(), BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022606 ASSERT_TRUE(pool_->HasGroup("bar"));
2607 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("bar"));
2608
2609 // Cancel request 1 and then complete request 2. With the requests finished,
2610 // the backup timer should be cancelled.
2611 handle.Reset();
2612 EXPECT_EQ(OK, callback2.WaitForResult());
2613 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]26b9973962012-01-28 00:57:002614 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2615 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
fdoray5eeb7642016-06-22 16:11:282616 base::RunLoop().RunUntilIdle();
[email protected]3f00be82010-09-27 19:50:022617}
2618
[email protected]eb5a99382010-07-11 03:18:262619// Test delayed socket binding for the case where we have two connects,
2620// and while one is waiting on a connect, the other frees up.
2621// The socket waiting on a connect should switch immediately to the freed
2622// up socket.
2623TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
2624 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2625 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2626
2627 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522628 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132629 EXPECT_EQ(ERR_IO_PENDING,
mmenked3641e12016-01-28 16:06:152630 handle1.Init("a", params_, DEFAULT_PRIORITY,
2631 ClientSocketPool::RespectLimits::ENABLED,
2632 callback.callback(), pool_.get(), BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262633 EXPECT_EQ(OK, callback.WaitForResult());
2634
2635 // No idle sockets, no pending jobs.
2636 EXPECT_EQ(0, pool_->IdleSocketCount());
2637 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2638
2639 // Create a second socket to the same host, but this one will wait.
2640 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2641 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132642 EXPECT_EQ(ERR_IO_PENDING,
mmenked3641e12016-01-28 16:06:152643 handle2.Init("a", params_, DEFAULT_PRIORITY,
2644 ClientSocketPool::RespectLimits::ENABLED,
2645 callback.callback(), pool_.get(), BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262646 // No idle sockets, and one connecting job.
2647 EXPECT_EQ(0, pool_->IdleSocketCount());
2648 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2649
2650 // Return the first handle to the pool. This will initiate the delayed
2651 // binding.
2652 handle1.Reset();
2653
fdoray5eeb7642016-06-22 16:11:282654 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262655
2656 // Still no idle sockets, still one pending connect job.
2657 EXPECT_EQ(0, pool_->IdleSocketCount());
2658 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2659
2660 // The second socket connected, even though it was a Waiting Job.
2661 EXPECT_EQ(OK, callback.WaitForResult());
2662
2663 // And we can see there is still one job waiting.
2664 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2665
2666 // Finally, signal the waiting Connect.
2667 client_socket_factory_.SignalJobs();
2668 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2669
fdoray5eeb7642016-06-22 16:11:282670 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262671}
2672
2673// Test delayed socket binding when a group is at capacity and one
2674// of the group's sockets frees up.
2675TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
2676 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2677 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2678
2679 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522680 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132681 EXPECT_EQ(ERR_IO_PENDING,
mmenked3641e12016-01-28 16:06:152682 handle1.Init("a", params_, DEFAULT_PRIORITY,
2683 ClientSocketPool::RespectLimits::ENABLED,
2684 callback.callback(), pool_.get(), BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262685 EXPECT_EQ(OK, callback.WaitForResult());
2686
2687 // No idle sockets, no pending jobs.
2688 EXPECT_EQ(0, pool_->IdleSocketCount());
2689 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2690
2691 // Create a second socket to the same host, but this one will wait.
2692 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2693 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132694 EXPECT_EQ(ERR_IO_PENDING,
mmenked3641e12016-01-28 16:06:152695 handle2.Init("a", params_, DEFAULT_PRIORITY,
2696 ClientSocketPool::RespectLimits::ENABLED,
2697 callback.callback(), pool_.get(), BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262698 // No idle sockets, and one connecting job.
2699 EXPECT_EQ(0, pool_->IdleSocketCount());
2700 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2701
2702 // Return the first handle to the pool. This will initiate the delayed
2703 // binding.
2704 handle1.Reset();
2705
fdoray5eeb7642016-06-22 16:11:282706 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262707
2708 // Still no idle sockets, still one pending connect job.
2709 EXPECT_EQ(0, pool_->IdleSocketCount());
2710 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2711
2712 // The second socket connected, even though it was a Waiting Job.
2713 EXPECT_EQ(OK, callback.WaitForResult());
2714
2715 // And we can see there is still one job waiting.
2716 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2717
2718 // Finally, signal the waiting Connect.
2719 client_socket_factory_.SignalJobs();
2720 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2721
fdoray5eeb7642016-06-22 16:11:282722 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262723}
2724
2725// Test out the case where we have one socket connected, one
2726// connecting, when the first socket finishes and goes idle.
[email protected]2abfe90a2010-08-25 17:49:512727// Although the second connection is pending, the second request
[email protected]eb5a99382010-07-11 03:18:262728// should complete, by taking the first socket's idle socket.
2729TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
2730 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2731 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2732
2733 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522734 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132735 EXPECT_EQ(ERR_IO_PENDING,
mmenked3641e12016-01-28 16:06:152736 handle1.Init("a", params_, DEFAULT_PRIORITY,
2737 ClientSocketPool::RespectLimits::ENABLED,
2738 callback.callback(), pool_.get(), BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262739 EXPECT_EQ(OK, callback.WaitForResult());
2740
2741 // No idle sockets, no pending jobs.
2742 EXPECT_EQ(0, pool_->IdleSocketCount());
2743 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2744
2745 // Create a second socket to the same host, but this one will wait.
2746 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2747 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132748 EXPECT_EQ(ERR_IO_PENDING,
mmenked3641e12016-01-28 16:06:152749 handle2.Init("a", params_, DEFAULT_PRIORITY,
2750 ClientSocketPool::RespectLimits::ENABLED,
2751 callback.callback(), pool_.get(), BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262752 // No idle sockets, and one connecting job.
2753 EXPECT_EQ(0, pool_->IdleSocketCount());
2754 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2755
2756 // Return the first handle to the pool. This will initiate the delayed
2757 // binding.
2758 handle1.Reset();
2759
fdoray5eeb7642016-06-22 16:11:282760 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262761
2762 // Still no idle sockets, still one pending connect job.
2763 EXPECT_EQ(0, pool_->IdleSocketCount());
2764 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2765
2766 // The second socket connected, even though it was a Waiting Job.
2767 EXPECT_EQ(OK, callback.WaitForResult());
2768
2769 // And we can see there is still one job waiting.
2770 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2771
2772 // Finally, signal the waiting Connect.
2773 client_socket_factory_.SignalJobs();
2774 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2775
fdoray5eeb7642016-06-22 16:11:282776 base::RunLoop().RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262777}
2778
[email protected]2abfe90a2010-08-25 17:49:512779// Cover the case where on an available socket slot, we have one pending
2780// request that completes synchronously, thereby making the Group empty.
2781TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
2782 const int kUnlimitedSockets = 100;
2783 const int kOneSocketPerGroup = 1;
2784 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
2785
2786 // Make the first request asynchronous fail.
2787 // This will free up a socket slot later.
2788 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2789
2790 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522791 TestCompletionCallback callback1;
[email protected]2431756e2010-09-29 20:26:132792 EXPECT_EQ(ERR_IO_PENDING,
mmenked3641e12016-01-28 16:06:152793 handle1.Init("a", params_, DEFAULT_PRIORITY,
2794 ClientSocketPool::RespectLimits::ENABLED,
2795 callback1.callback(), pool_.get(), BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:512796 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2797
2798 // Make the second request synchronously fail. This should make the Group
2799 // empty.
2800 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
2801 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522802 TestCompletionCallback callback2;
[email protected]2abfe90a2010-08-25 17:49:512803 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
2804 // when created.
[email protected]2431756e2010-09-29 20:26:132805 EXPECT_EQ(ERR_IO_PENDING,
mmenked3641e12016-01-28 16:06:152806 handle2.Init("a", params_, DEFAULT_PRIORITY,
2807 ClientSocketPool::RespectLimits::ENABLED,
2808 callback2.callback(), pool_.get(), BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:512809
2810 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2811
2812 EXPECT_EQ(ERR_CONNECTION_FAILED, callback1.WaitForResult());
2813 EXPECT_EQ(ERR_CONNECTION_FAILED, callback2.WaitForResult());
2814 EXPECT_FALSE(pool_->HasGroup("a"));
2815}
2816
[email protected]e1b54dc2010-10-06 21:27:222817TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
2818 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2819
2820 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2821
2822 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522823 TestCompletionCallback callback1;
mmenked3641e12016-01-28 16:06:152824 EXPECT_EQ(ERR_IO_PENDING,
2825 handle1.Init("a", params_, DEFAULT_PRIORITY,
2826 ClientSocketPool::RespectLimits::ENABLED,
2827 callback1.callback(), pool_.get(), BoundNetLog()));
[email protected]e1b54dc2010-10-06 21:27:222828
2829 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522830 TestCompletionCallback callback2;
mmenked3641e12016-01-28 16:06:152831 EXPECT_EQ(ERR_IO_PENDING,
2832 handle2.Init("a", params_, DEFAULT_PRIORITY,
2833 ClientSocketPool::RespectLimits::ENABLED,
2834 callback2.callback(), pool_.get(), BoundNetLog()));
[email protected]e1b54dc2010-10-06 21:27:222835 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:522836 TestCompletionCallback callback3;
mmenked3641e12016-01-28 16:06:152837 EXPECT_EQ(ERR_IO_PENDING,
2838 handle3.Init("a", params_, DEFAULT_PRIORITY,
2839 ClientSocketPool::RespectLimits::ENABLED,
2840 callback3.callback(), pool_.get(), BoundNetLog()));
[email protected]e1b54dc2010-10-06 21:27:222841
2842 EXPECT_EQ(OK, callback1.WaitForResult());
2843 EXPECT_EQ(OK, callback2.WaitForResult());
2844 EXPECT_EQ(OK, callback3.WaitForResult());
2845
2846 // Use the socket.
[email protected]83039bb2011-12-09 18:43:552847 EXPECT_EQ(1, handle1.socket()->Write(NULL, 1, CompletionCallback()));
2848 EXPECT_EQ(1, handle3.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]e1b54dc2010-10-06 21:27:222849
2850 handle1.Reset();
2851 handle2.Reset();
2852 handle3.Reset();
2853
mmenked3641e12016-01-28 16:06:152854 EXPECT_EQ(OK, handle1.Init("a", params_, DEFAULT_PRIORITY,
2855 ClientSocketPool::RespectLimits::ENABLED,
2856 callback1.callback(), pool_.get(), BoundNetLog()));
2857 EXPECT_EQ(OK, handle2.Init("a", params_, DEFAULT_PRIORITY,
2858 ClientSocketPool::RespectLimits::ENABLED,
2859 callback2.callback(), pool_.get(), BoundNetLog()));
2860 EXPECT_EQ(OK, handle3.Init("a", params_, DEFAULT_PRIORITY,
2861 ClientSocketPool::RespectLimits::ENABLED,
2862 callback3.callback(), pool_.get(), BoundNetLog()));
[email protected]e1b54dc2010-10-06 21:27:222863
2864 EXPECT_TRUE(handle1.socket()->WasEverUsed());
2865 EXPECT_TRUE(handle2.socket()->WasEverUsed());
2866 EXPECT_FALSE(handle3.socket()->WasEverUsed());
2867}
2868
[email protected]2c2bef152010-10-13 00:55:032869TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
2870 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2871 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2872
2873 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2874
2875 ASSERT_TRUE(pool_->HasGroup("a"));
2876 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:102877 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:032878 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2879
2880 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522881 TestCompletionCallback callback1;
mmenked3641e12016-01-28 16:06:152882 EXPECT_EQ(ERR_IO_PENDING,
2883 handle1.Init("a", params_, DEFAULT_PRIORITY,
2884 ClientSocketPool::RespectLimits::ENABLED,
2885 callback1.callback(), pool_.get(), BoundNetLog()));
[email protected]2c2bef152010-10-13 00:55:032886
2887 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522888 TestCompletionCallback callback2;
mmenked3641e12016-01-28 16:06:152889 EXPECT_EQ(ERR_IO_PENDING,
2890 handle2.Init("a", params_, DEFAULT_PRIORITY,
2891 ClientSocketPool::RespectLimits::ENABLED,
2892 callback2.callback(), pool_.get(), BoundNetLog()));
[email protected]2c2bef152010-10-13 00:55:032893
2894 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:102895 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:032896 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2897
2898 EXPECT_EQ(OK, callback1.WaitForResult());
2899 EXPECT_EQ(OK, callback2.WaitForResult());
2900 handle1.Reset();
2901 handle2.Reset();
2902
2903 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:102904 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:032905 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2906}
2907
2908TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
2909 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2910 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2911
2912 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522913 TestCompletionCallback callback1;
mmenked3641e12016-01-28 16:06:152914 EXPECT_EQ(ERR_IO_PENDING,
2915 handle1.Init("a", params_, DEFAULT_PRIORITY,
2916 ClientSocketPool::RespectLimits::ENABLED,
2917 callback1.callback(), pool_.get(), BoundNetLog()));
[email protected]2c2bef152010-10-13 00:55:032918
2919 ASSERT_TRUE(pool_->HasGroup("a"));
2920 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:102921 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:032922 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2923
2924 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2925
2926 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:102927 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:032928 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2929
2930 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522931 TestCompletionCallback callback2;
mmenked3641e12016-01-28 16:06:152932 EXPECT_EQ(ERR_IO_PENDING,
2933 handle2.Init("a", params_, DEFAULT_PRIORITY,
2934 ClientSocketPool::RespectLimits::ENABLED,
2935 callback2.callback(), pool_.get(), BoundNetLog()));
[email protected]2c2bef152010-10-13 00:55:032936
2937 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:102938 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:032939 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2940
2941 EXPECT_EQ(OK, callback1.WaitForResult());
2942 EXPECT_EQ(OK, callback2.WaitForResult());
2943 handle1.Reset();
2944 handle2.Reset();
2945
2946 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:102947 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:032948 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2949}
2950
2951TEST_F(ClientSocketPoolBaseTest,
2952 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
2953 CreatePool(4, 4);
2954 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2955
2956 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522957 TestCompletionCallback callback1;
mmenked3641e12016-01-28 16:06:152958 EXPECT_EQ(ERR_IO_PENDING,
2959 handle1.Init("a", params_, DEFAULT_PRIORITY,
2960 ClientSocketPool::RespectLimits::ENABLED,
2961 callback1.callback(), pool_.get(), BoundNetLog()));
[email protected]2c2bef152010-10-13 00:55:032962
2963 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522964 TestCompletionCallback callback2;
mmenked3641e12016-01-28 16:06:152965 EXPECT_EQ(ERR_IO_PENDING,
2966 handle2.Init("a", params_, DEFAULT_PRIORITY,
2967 ClientSocketPool::RespectLimits::ENABLED,
2968 callback2.callback(), pool_.get(), BoundNetLog()));
[email protected]2c2bef152010-10-13 00:55:032969
2970 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:522971 TestCompletionCallback callback3;
mmenked3641e12016-01-28 16:06:152972 EXPECT_EQ(ERR_IO_PENDING,
2973 handle3.Init("a", params_, DEFAULT_PRIORITY,
2974 ClientSocketPool::RespectLimits::ENABLED,
2975 callback3.callback(), pool_.get(), BoundNetLog()));
[email protected]2c2bef152010-10-13 00:55:032976
2977 ASSERT_TRUE(pool_->HasGroup("a"));
2978 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:102979 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:032980 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2981
2982 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2983
2984 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:102985 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:032986 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2987
2988 EXPECT_EQ(OK, callback1.WaitForResult());
2989 EXPECT_EQ(OK, callback2.WaitForResult());
2990 EXPECT_EQ(OK, callback3.WaitForResult());
2991 handle1.Reset();
2992 handle2.Reset();
2993 handle3.Reset();
2994
2995 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:102996 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:032997 EXPECT_EQ(3, pool_->IdleSocketCountInGroup("a"));
2998}
2999
3000TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
3001 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3002 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3003
3004 ASSERT_FALSE(pool_->HasGroup("a"));
3005
3006 pool_->RequestSockets("a", &params_, kDefaultMaxSockets,
3007 BoundNetLog());
3008
3009 ASSERT_TRUE(pool_->HasGroup("a"));
3010 EXPECT_EQ(kDefaultMaxSockets, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103011 EXPECT_EQ(kDefaultMaxSockets, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033012
3013 ASSERT_FALSE(pool_->HasGroup("b"));
3014
3015 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
3016 BoundNetLog());
3017
3018 ASSERT_FALSE(pool_->HasGroup("b"));
3019}
3020
3021TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
3022 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3023 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3024
3025 ASSERT_FALSE(pool_->HasGroup("a"));
3026
3027 pool_->RequestSockets("a", &params_, kDefaultMaxSockets - 1,
3028 BoundNetLog());
3029
3030 ASSERT_TRUE(pool_->HasGroup("a"));
3031 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103032 EXPECT_EQ(kDefaultMaxSockets - 1,
3033 pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]51fdc7c2012-04-10 19:19:483034 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033035
3036 ASSERT_FALSE(pool_->HasGroup("b"));
3037
3038 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
3039 BoundNetLog());
3040
3041 ASSERT_TRUE(pool_->HasGroup("b"));
3042 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("b"));
[email protected]51fdc7c2012-04-10 19:19:483043 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033044}
3045
3046TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
3047 CreatePool(4, 4);
3048 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3049
3050 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523051 TestCompletionCallback callback1;
mmenked3641e12016-01-28 16:06:153052 EXPECT_EQ(ERR_IO_PENDING,
3053 handle1.Init("a", params_, DEFAULT_PRIORITY,
3054 ClientSocketPool::RespectLimits::ENABLED,
3055 callback1.callback(), pool_.get(), BoundNetLog()));
[email protected]2c2bef152010-10-13 00:55:033056 ASSERT_EQ(OK, callback1.WaitForResult());
3057 handle1.Reset();
3058
3059 ASSERT_TRUE(pool_->HasGroup("a"));
3060 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103061 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033062 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3063
3064 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3065
3066 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103067 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033068 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3069}
3070
3071TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
3072 CreatePool(4, 4);
3073 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3074
3075 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523076 TestCompletionCallback callback1;
mmenked3641e12016-01-28 16:06:153077 EXPECT_EQ(ERR_IO_PENDING,
3078 handle1.Init("a", params_, DEFAULT_PRIORITY,
3079 ClientSocketPool::RespectLimits::ENABLED,
3080 callback1.callback(), pool_.get(), BoundNetLog()));
[email protected]2c2bef152010-10-13 00:55:033081 ASSERT_EQ(OK, callback1.WaitForResult());
3082
3083 ASSERT_TRUE(pool_->HasGroup("a"));
3084 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103085 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033086 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3087 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3088
3089 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3090
3091 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103092 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033093 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3094 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3095}
3096
3097TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
3098 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3099 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3100
3101 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3102 BoundNetLog());
3103
3104 ASSERT_TRUE(pool_->HasGroup("a"));
3105 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103106 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033107 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("a"));
3108
3109 pool_->RequestSockets("b", &params_, kDefaultMaxSocketsPerGroup,
3110 BoundNetLog());
3111
3112 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103113 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]2c2bef152010-10-13 00:55:033114 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("b"));
3115}
3116
[email protected]3c819f522010-12-02 02:03:123117TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
3118 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3119 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3120
3121 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3122 BoundNetLog());
3123
3124 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]fd2e53e2011-01-14 20:40:523125
3126 connect_job_factory_->set_job_type(
3127 TestConnectJob::kMockAdditionalErrorStateJob);
3128 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3129 BoundNetLog());
3130
3131 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]3c819f522010-12-02 02:03:123132}
3133
[email protected]8159a1c2012-06-07 00:00:103134TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
[email protected]2c2bef152010-10-13 00:55:033135 CreatePool(4, 4);
3136 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3137
3138 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3139
3140 ASSERT_TRUE(pool_->HasGroup("a"));
3141 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103142 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033143 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3144
3145 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3146 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103147 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033148 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3149
3150 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523151 TestCompletionCallback callback1;
mmenked3641e12016-01-28 16:06:153152 EXPECT_EQ(ERR_IO_PENDING,
3153 handle1.Init("a", params_, DEFAULT_PRIORITY,
3154 ClientSocketPool::RespectLimits::ENABLED,
3155 callback1.callback(), pool_.get(), BoundNetLog()));
[email protected]2c2bef152010-10-13 00:55:033156 ASSERT_EQ(OK, callback1.WaitForResult());
3157
3158 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523159 TestCompletionCallback callback2;
mmenked3641e12016-01-28 16:06:153160 int rv = handle2.Init("a", params_, DEFAULT_PRIORITY,
3161 ClientSocketPool::RespectLimits::ENABLED,
3162 callback2.callback(), pool_.get(), BoundNetLog());
[email protected]2c2bef152010-10-13 00:55:033163 if (rv != OK) {
3164 EXPECT_EQ(ERR_IO_PENDING, rv);
3165 EXPECT_EQ(OK, callback2.WaitForResult());
3166 }
3167
[email protected]8159a1c2012-06-07 00:00:103168 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3169 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3170 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("a"));
3171 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3172
[email protected]2c2bef152010-10-13 00:55:033173 handle1.Reset();
3174 handle2.Reset();
3175
[email protected]8159a1c2012-06-07 00:00:103176 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3177 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033178 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3179
3180 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3181 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103182 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033183 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3184}
3185
3186TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
3187 CreatePool(4, 4);
3188 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3189
3190 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3191
3192 ASSERT_TRUE(pool_->HasGroup("a"));
3193 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103194 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033195 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3196
3197 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3198 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103199 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033200 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3201
3202 pool_->RequestSockets("a", &params_, 3, BoundNetLog());
3203 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103204 EXPECT_EQ(3, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033205 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3206
3207 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3208 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103209 EXPECT_EQ(3, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033210 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3211}
3212
3213TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
3214 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3215 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3216
3217 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3218
3219 ASSERT_TRUE(pool_->HasGroup("a"));
3220 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103221 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033222 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3223
3224 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523225 TestCompletionCallback callback1;
mmenked3641e12016-01-28 16:06:153226 EXPECT_EQ(ERR_IO_PENDING,
3227 handle1.Init("a", params_, DEFAULT_PRIORITY,
3228 ClientSocketPool::RespectLimits::ENABLED,
3229 callback1.callback(), pool_.get(), BoundNetLog()));
[email protected]2c2bef152010-10-13 00:55:033230
3231 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103232 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033233 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3234
3235 ASSERT_EQ(OK, callback1.WaitForResult());
3236
[email protected]0dc88b32014-03-26 20:12:283237 // Make sure if a preconnected socket is not fully connected when a request
[email protected]034df0f32013-01-07 23:17:483238 // starts, it has a connect start time.
3239 TestLoadTimingInfoConnectedNotReused(handle1);
[email protected]2c2bef152010-10-13 00:55:033240 handle1.Reset();
3241
3242 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3243}
3244
[email protected]034df0f32013-01-07 23:17:483245// Checks that fully connected preconnect jobs have no connect times, and are
3246// marked as reused.
3247TEST_F(ClientSocketPoolBaseTest, ConnectedPreconnectJobsHaveNoConnectTimes) {
3248 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3249 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3250 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3251
3252 ASSERT_TRUE(pool_->HasGroup("a"));
3253 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3254 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3255 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3256
3257 ClientSocketHandle handle;
3258 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:153259 EXPECT_EQ(OK, handle.Init("a", params_, DEFAULT_PRIORITY,
3260 ClientSocketPool::RespectLimits::ENABLED,
3261 callback.callback(), pool_.get(), BoundNetLog()));
[email protected]034df0f32013-01-07 23:17:483262
3263 // Make sure the idle socket was used.
3264 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3265
3266 TestLoadTimingInfoConnectedReused(handle);
3267 handle.Reset();
3268 TestLoadTimingInfoNotConnected(handle);
3269}
3270
[email protected]dcbe168a2010-12-02 03:14:463271// http://crbug.com/64940 regression test.
3272TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
3273 const int kMaxTotalSockets = 3;
3274 const int kMaxSocketsPerGroup = 2;
3275 CreatePool(kMaxTotalSockets, kMaxSocketsPerGroup);
3276 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3277
3278 // Note that group name ordering matters here. "a" comes before "b", so
3279 // CloseOneIdleSocket() will try to close "a"'s idle socket.
3280
3281 // Set up one idle socket in "a".
3282 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523283 TestCompletionCallback callback1;
mmenked3641e12016-01-28 16:06:153284 EXPECT_EQ(ERR_IO_PENDING,
3285 handle1.Init("a", params_, DEFAULT_PRIORITY,
3286 ClientSocketPool::RespectLimits::ENABLED,
3287 callback1.callback(), pool_.get(), BoundNetLog()));
[email protected]dcbe168a2010-12-02 03:14:463288
3289 ASSERT_EQ(OK, callback1.WaitForResult());
3290 handle1.Reset();
3291 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3292
3293 // Set up two active sockets in "b".
3294 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523295 TestCompletionCallback callback2;
mmenked3641e12016-01-28 16:06:153296 EXPECT_EQ(ERR_IO_PENDING,
3297 handle1.Init("b", params_, DEFAULT_PRIORITY,
3298 ClientSocketPool::RespectLimits::ENABLED,
3299 callback1.callback(), pool_.get(), BoundNetLog()));
3300 EXPECT_EQ(ERR_IO_PENDING,
3301 handle2.Init("b", params_, DEFAULT_PRIORITY,
3302 ClientSocketPool::RespectLimits::ENABLED,
3303 callback2.callback(), pool_.get(), BoundNetLog()));
[email protected]dcbe168a2010-12-02 03:14:463304
3305 ASSERT_EQ(OK, callback1.WaitForResult());
3306 ASSERT_EQ(OK, callback2.WaitForResult());
3307 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103308 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463309 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3310
3311 // Now we have 1 idle socket in "a" and 2 active sockets in "b". This means
3312 // we've maxed out on sockets, since we set |kMaxTotalSockets| to 3.
3313 // Requesting 2 preconnected sockets for "a" should fail to allocate any more
3314 // sockets for "a", and "b" should still have 2 active sockets.
3315
3316 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3317 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103318 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]dcbe168a2010-12-02 03:14:463319 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3320 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3321 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103322 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463323 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3324 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3325
3326 // Now release the 2 active sockets for "b". This will give us 1 idle socket
3327 // in "a" and 2 idle sockets in "b". Requesting 2 preconnected sockets for
3328 // "a" should result in closing 1 for "b".
3329 handle1.Reset();
3330 handle2.Reset();
3331 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("b"));
3332 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3333
3334 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3335 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103336 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]dcbe168a2010-12-02 03:14:463337 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3338 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3339 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103340 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463341 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("b"));
3342 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3343}
3344
[email protected]b7b8be42011-07-12 12:46:413345TEST_F(ClientSocketPoolBaseTest, PreconnectWithoutBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073346 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3347 pool_->EnableConnectBackupJobs();
3348
3349 // Make the ConnectJob hang until it times out, shorten the timeout.
3350 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3351 connect_job_factory_->set_timeout_duration(
3352 base::TimeDelta::FromMilliseconds(500));
3353 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3354 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103355 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073356 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073357
[email protected]b7b8be42011-07-12 12:46:413358 // Verify the backup timer doesn't create a backup job, by making
3359 // the backup job a pending job instead of a waiting job, so it
3360 // *would* complete if it were created.
[email protected]a9fc8fc2011-05-10 02:41:073361 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
skyostil4891b25b2015-06-11 11:43:453362 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
ki.stfu375812e2015-10-09 20:23:173363 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
[email protected]2da659e2013-05-23 20:51:343364 base::TimeDelta::FromSeconds(1));
fdoray5eeb7642016-06-22 16:11:283365 base::RunLoop().Run();
[email protected]a9fc8fc2011-05-10 02:41:073366 EXPECT_FALSE(pool_->HasGroup("a"));
3367}
3368
[email protected]b7b8be42011-07-12 12:46:413369TEST_F(ClientSocketPoolBaseTest, PreconnectWithBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073370 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3371 pool_->EnableConnectBackupJobs();
3372
3373 // Make the ConnectJob hang forever.
3374 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3375 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3376 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103377 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073378 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
fdoray5eeb7642016-06-22 16:11:283379 base::RunLoop().RunUntilIdle();
[email protected]a9fc8fc2011-05-10 02:41:073380
3381 // Make the backup job be a pending job, so it completes normally.
3382 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3383 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:523384 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:153385 EXPECT_EQ(ERR_IO_PENDING,
3386 handle.Init("a", params_, DEFAULT_PRIORITY,
3387 ClientSocketPool::RespectLimits::ENABLED,
3388 callback.callback(), pool_.get(), BoundNetLog()));
[email protected]b7b8be42011-07-12 12:46:413389 // Timer has started, but the backup connect job shouldn't be created yet.
[email protected]a9fc8fc2011-05-10 02:41:073390 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103391 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073392 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3393 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3394 ASSERT_EQ(OK, callback.WaitForResult());
3395
3396 // The hung connect job should still be there, but everything else should be
3397 // complete.
3398 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103399 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073400 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3401 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3402}
3403
[email protected]0dc88b32014-03-26 20:12:283404// Tests that a preconnect that starts out with unread data can still be used.
3405// http://crbug.com/334467
3406TEST_F(ClientSocketPoolBaseTest, PreconnectWithUnreadData) {
3407 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3408 connect_job_factory_->set_job_type(TestConnectJob::kMockUnreadDataJob);
3409
3410 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3411
3412 ASSERT_TRUE(pool_->HasGroup("a"));
3413 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3414 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3415 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3416
3417 // Fail future jobs to be sure that handle receives the preconnected socket
3418 // rather than closing it and making a new one.
3419 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3420 ClientSocketHandle handle;
3421 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:153422 EXPECT_EQ(OK, handle.Init("a", params_, DEFAULT_PRIORITY,
3423 ClientSocketPool::RespectLimits::ENABLED,
3424 callback.callback(), pool_.get(), BoundNetLog()));
[email protected]0dc88b32014-03-26 20:12:283425
3426 ASSERT_TRUE(pool_->HasGroup("a"));
3427 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3428 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3429 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3430
3431 // Drain the pending read.
3432 EXPECT_EQ(1, handle.socket()->Read(NULL, 1, CompletionCallback()));
3433
3434 TestLoadTimingInfoConnectedReused(handle);
3435 handle.Reset();
3436
3437 // The socket should be usable now that it's idle again.
3438 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3439}
3440
[email protected]043b68c82013-08-22 23:41:523441class MockLayeredPool : public HigherLayeredPool {
[email protected]58e562f2013-04-22 17:32:203442 public:
3443 MockLayeredPool(TestClientSocketPool* pool,
3444 const std::string& group_name)
3445 : pool_(pool),
[email protected]58e562f2013-04-22 17:32:203446 group_name_(group_name),
3447 can_release_connection_(true) {
[email protected]043b68c82013-08-22 23:41:523448 pool_->AddHigherLayeredPool(this);
[email protected]58e562f2013-04-22 17:32:203449 }
3450
3451 ~MockLayeredPool() {
[email protected]043b68c82013-08-22 23:41:523452 pool_->RemoveHigherLayeredPool(this);
[email protected]58e562f2013-04-22 17:32:203453 }
3454
3455 int RequestSocket(TestClientSocketPool* pool) {
mmenked3641e12016-01-28 16:06:153456 scoped_refptr<TestSocketParams> params(new TestSocketParams());
[email protected]bb1c4662013-11-14 00:00:073457 return handle_.Init(group_name_, params, DEFAULT_PRIORITY,
mmenked3641e12016-01-28 16:06:153458 ClientSocketPool::RespectLimits::ENABLED,
[email protected]58e562f2013-04-22 17:32:203459 callback_.callback(), pool, BoundNetLog());
3460 }
3461
3462 int RequestSocketWithoutLimits(TestClientSocketPool* pool) {
mmenked3641e12016-01-28 16:06:153463 scoped_refptr<TestSocketParams> params(new TestSocketParams());
[email protected]bb1c4662013-11-14 00:00:073464 return handle_.Init(group_name_, params, MAXIMUM_PRIORITY,
mmenked3641e12016-01-28 16:06:153465 ClientSocketPool::RespectLimits::DISABLED,
[email protected]58e562f2013-04-22 17:32:203466 callback_.callback(), pool, BoundNetLog());
3467 }
3468
3469 bool ReleaseOneConnection() {
3470 if (!handle_.is_initialized() || !can_release_connection_) {
3471 return false;
3472 }
3473 handle_.socket()->Disconnect();
3474 handle_.Reset();
3475 return true;
3476 }
3477
3478 void set_can_release_connection(bool can_release_connection) {
3479 can_release_connection_ = can_release_connection;
3480 }
3481
3482 MOCK_METHOD0(CloseOneIdleConnection, bool());
3483
3484 private:
3485 TestClientSocketPool* const pool_;
[email protected]58e562f2013-04-22 17:32:203486 ClientSocketHandle handle_;
3487 TestCompletionCallback callback_;
3488 const std::string group_name_;
3489 bool can_release_connection_;
3490};
3491
3492TEST_F(ClientSocketPoolBaseTest, FailToCloseIdleSocketsNotHeldByLayeredPool) {
3493 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3494 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3495
3496 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
3497 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3498 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3499 .WillOnce(Return(false));
[email protected]043b68c82013-08-22 23:41:523500 EXPECT_FALSE(pool_->CloseOneIdleConnectionInHigherLayeredPool());
[email protected]58e562f2013-04-22 17:32:203501}
3502
3503TEST_F(ClientSocketPoolBaseTest, ForciblyCloseIdleSocketsHeldByLayeredPool) {
3504 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3505 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3506
3507 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
3508 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3509 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3510 .WillOnce(Invoke(&mock_layered_pool,
3511 &MockLayeredPool::ReleaseOneConnection));
[email protected]043b68c82013-08-22 23:41:523512 EXPECT_TRUE(pool_->CloseOneIdleConnectionInHigherLayeredPool());
[email protected]58e562f2013-04-22 17:32:203513}
3514
3515// Tests the basic case of closing an idle socket in a higher layered pool when
3516// a new request is issued and the lower layer pool is stalled.
3517TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsHeldByLayeredPoolWhenNeeded) {
3518 CreatePool(1, 1);
3519 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3520
3521 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
3522 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3523 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3524 .WillOnce(Invoke(&mock_layered_pool,
3525 &MockLayeredPool::ReleaseOneConnection));
3526 ClientSocketHandle handle;
3527 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:153528 EXPECT_EQ(ERR_IO_PENDING,
3529 handle.Init("a", params_, DEFAULT_PRIORITY,
3530 ClientSocketPool::RespectLimits::ENABLED,
3531 callback.callback(), pool_.get(), BoundNetLog()));
[email protected]58e562f2013-04-22 17:32:203532 EXPECT_EQ(OK, callback.WaitForResult());
3533}
3534
3535// Same as above, but the idle socket is in the same group as the stalled
3536// socket, and closes the only other request in its group when closing requests
3537// in higher layered pools. This generally shouldn't happen, but it may be
3538// possible if a higher level pool issues a request and the request is
3539// subsequently cancelled. Even if it's not possible, best not to crash.
3540TEST_F(ClientSocketPoolBaseTest,
3541 CloseIdleSocketsHeldByLayeredPoolWhenNeededSameGroup) {
3542 CreatePool(2, 2);
3543 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3544
3545 // Need a socket in another group for the pool to be stalled (If a group
3546 // has the maximum number of connections already, it's not stalled).
3547 ClientSocketHandle handle1;
3548 TestCompletionCallback callback1;
mmenked3641e12016-01-28 16:06:153549 EXPECT_EQ(OK, handle1.Init("group1", params_, DEFAULT_PRIORITY,
3550 ClientSocketPool::RespectLimits::ENABLED,
3551 callback1.callback(), pool_.get(), BoundNetLog()));
[email protected]58e562f2013-04-22 17:32:203552
3553 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
3554 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3555 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3556 .WillOnce(Invoke(&mock_layered_pool,
3557 &MockLayeredPool::ReleaseOneConnection));
3558 ClientSocketHandle handle;
3559 TestCompletionCallback callback2;
mmenked3641e12016-01-28 16:06:153560 EXPECT_EQ(ERR_IO_PENDING,
3561 handle.Init("group2", params_, DEFAULT_PRIORITY,
3562 ClientSocketPool::RespectLimits::ENABLED,
3563 callback2.callback(), pool_.get(), BoundNetLog()));
[email protected]58e562f2013-04-22 17:32:203564 EXPECT_EQ(OK, callback2.WaitForResult());
3565}
3566
3567// Tests the case when an idle socket can be closed when a new request is
3568// issued, and the new request belongs to a group that was previously stalled.
3569TEST_F(ClientSocketPoolBaseTest,
3570 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded) {
3571 CreatePool(2, 2);
3572 std::list<TestConnectJob::JobType> job_types;
3573 job_types.push_back(TestConnectJob::kMockJob);
3574 job_types.push_back(TestConnectJob::kMockJob);
3575 job_types.push_back(TestConnectJob::kMockJob);
3576 job_types.push_back(TestConnectJob::kMockJob);
3577 connect_job_factory_->set_job_types(&job_types);
3578
3579 ClientSocketHandle handle1;
3580 TestCompletionCallback callback1;
mmenked3641e12016-01-28 16:06:153581 EXPECT_EQ(OK, handle1.Init("group1", params_, DEFAULT_PRIORITY,
3582 ClientSocketPool::RespectLimits::ENABLED,
3583 callback1.callback(), pool_.get(), BoundNetLog()));
[email protected]58e562f2013-04-22 17:32:203584
3585 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
3586 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3587 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3588 .WillRepeatedly(Invoke(&mock_layered_pool,
3589 &MockLayeredPool::ReleaseOneConnection));
3590 mock_layered_pool.set_can_release_connection(false);
3591
3592 // The third request is made when the socket pool is in a stalled state.
3593 ClientSocketHandle handle3;
3594 TestCompletionCallback callback3;
mmenked3641e12016-01-28 16:06:153595 EXPECT_EQ(ERR_IO_PENDING,
3596 handle3.Init("group3", params_, DEFAULT_PRIORITY,
3597 ClientSocketPool::RespectLimits::ENABLED,
3598 callback3.callback(), pool_.get(), BoundNetLog()));
[email protected]58e562f2013-04-22 17:32:203599
3600 base::RunLoop().RunUntilIdle();
3601 EXPECT_FALSE(callback3.have_result());
3602
3603 // The fourth request is made when the pool is no longer stalled. The third
3604 // request should be serviced first, since it was issued first and has the
3605 // same priority.
3606 mock_layered_pool.set_can_release_connection(true);
3607 ClientSocketHandle handle4;
3608 TestCompletionCallback callback4;
mmenked3641e12016-01-28 16:06:153609 EXPECT_EQ(ERR_IO_PENDING,
3610 handle4.Init("group3", params_, DEFAULT_PRIORITY,
3611 ClientSocketPool::RespectLimits::ENABLED,
3612 callback4.callback(), pool_.get(), BoundNetLog()));
[email protected]58e562f2013-04-22 17:32:203613 EXPECT_EQ(OK, callback3.WaitForResult());
3614 EXPECT_FALSE(callback4.have_result());
3615
3616 // Closing a handle should free up another socket slot.
3617 handle1.Reset();
3618 EXPECT_EQ(OK, callback4.WaitForResult());
3619}
3620
3621// Tests the case when an idle socket can be closed when a new request is
3622// issued, and the new request belongs to a group that was previously stalled.
3623//
3624// The two differences from the above test are that the stalled requests are not
3625// in the same group as the layered pool's request, and the the fourth request
3626// has a higher priority than the third one, so gets a socket first.
3627TEST_F(ClientSocketPoolBaseTest,
3628 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded2) {
3629 CreatePool(2, 2);
3630 std::list<TestConnectJob::JobType> job_types;
3631 job_types.push_back(TestConnectJob::kMockJob);
3632 job_types.push_back(TestConnectJob::kMockJob);
3633 job_types.push_back(TestConnectJob::kMockJob);
3634 job_types.push_back(TestConnectJob::kMockJob);
3635 connect_job_factory_->set_job_types(&job_types);
3636
3637 ClientSocketHandle handle1;
3638 TestCompletionCallback callback1;
mmenked3641e12016-01-28 16:06:153639 EXPECT_EQ(OK, handle1.Init("group1", params_, DEFAULT_PRIORITY,
3640 ClientSocketPool::RespectLimits::ENABLED,
3641 callback1.callback(), pool_.get(), BoundNetLog()));
[email protected]58e562f2013-04-22 17:32:203642
3643 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
3644 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3645 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3646 .WillRepeatedly(Invoke(&mock_layered_pool,
3647 &MockLayeredPool::ReleaseOneConnection));
3648 mock_layered_pool.set_can_release_connection(false);
3649
3650 // The third request is made when the socket pool is in a stalled state.
3651 ClientSocketHandle handle3;
3652 TestCompletionCallback callback3;
mmenked3641e12016-01-28 16:06:153653 EXPECT_EQ(ERR_IO_PENDING,
3654 handle3.Init("group3", params_, MEDIUM,
3655 ClientSocketPool::RespectLimits::ENABLED,
3656 callback3.callback(), pool_.get(), BoundNetLog()));
[email protected]58e562f2013-04-22 17:32:203657
3658 base::RunLoop().RunUntilIdle();
3659 EXPECT_FALSE(callback3.have_result());
3660
3661 // The fourth request is made when the pool is no longer stalled. This
3662 // request has a higher priority than the third request, so is serviced first.
3663 mock_layered_pool.set_can_release_connection(true);
3664 ClientSocketHandle handle4;
3665 TestCompletionCallback callback4;
mmenked3641e12016-01-28 16:06:153666 EXPECT_EQ(ERR_IO_PENDING,
3667 handle4.Init("group3", params_, HIGHEST,
3668 ClientSocketPool::RespectLimits::ENABLED,
3669 callback4.callback(), pool_.get(), BoundNetLog()));
[email protected]58e562f2013-04-22 17:32:203670 EXPECT_EQ(OK, callback4.WaitForResult());
3671 EXPECT_FALSE(callback3.have_result());
3672
3673 // Closing a handle should free up another socket slot.
3674 handle1.Reset();
3675 EXPECT_EQ(OK, callback3.WaitForResult());
3676}
3677
3678TEST_F(ClientSocketPoolBaseTest,
3679 CloseMultipleIdleSocketsHeldByLayeredPoolWhenNeeded) {
3680 CreatePool(1, 1);
3681 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3682
3683 MockLayeredPool mock_layered_pool1(pool_.get(), "foo");
3684 EXPECT_EQ(OK, mock_layered_pool1.RequestSocket(pool_.get()));
3685 EXPECT_CALL(mock_layered_pool1, CloseOneIdleConnection())
3686 .WillRepeatedly(Invoke(&mock_layered_pool1,
3687 &MockLayeredPool::ReleaseOneConnection));
3688 MockLayeredPool mock_layered_pool2(pool_.get(), "bar");
3689 EXPECT_EQ(OK, mock_layered_pool2.RequestSocketWithoutLimits(pool_.get()));
3690 EXPECT_CALL(mock_layered_pool2, CloseOneIdleConnection())
3691 .WillRepeatedly(Invoke(&mock_layered_pool2,
3692 &MockLayeredPool::ReleaseOneConnection));
3693 ClientSocketHandle handle;
3694 TestCompletionCallback callback;
mmenked3641e12016-01-28 16:06:153695 EXPECT_EQ(ERR_IO_PENDING,
3696 handle.Init("a", params_, DEFAULT_PRIORITY,
3697 ClientSocketPool::RespectLimits::ENABLED,
3698 callback.callback(), pool_.get(), BoundNetLog()));
[email protected]58e562f2013-04-22 17:32:203699 EXPECT_EQ(OK, callback.WaitForResult());
3700}
3701
[email protected]b021ece62013-06-11 11:06:333702// Test that when a socket pool and group are at their limits, a request
mmenked3641e12016-01-28 16:06:153703// with RespectLimits::DISABLED triggers creation of a new socket, and gets the
3704// socket instead of a request with the same priority that was issued earlier,
3705// but has RespectLimits::ENABLED.
[email protected]b021ece62013-06-11 11:06:333706TEST_F(ClientSocketPoolBaseTest, IgnoreLimits) {
[email protected]b021ece62013-06-11 11:06:333707 CreatePool(1, 1);
3708
3709 // Issue a request to reach the socket pool limit.
mmenked3641e12016-01-28 16:06:153710 EXPECT_EQ(
3711 OK, StartRequestWithIgnoreLimits(
3712 "a", MAXIMUM_PRIORITY, ClientSocketPool::RespectLimits::ENABLED));
[email protected]b021ece62013-06-11 11:06:333713 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3714
3715 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3716
mmenked3641e12016-01-28 16:06:153717 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
3718 "a", MAXIMUM_PRIORITY,
3719 ClientSocketPool::RespectLimits::ENABLED));
[email protected]b021ece62013-06-11 11:06:333720 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3721
mmenked3641e12016-01-28 16:06:153722 // Issue a request that ignores the limits, so a new ConnectJob is
3723 // created.
3724 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
3725 "a", MAXIMUM_PRIORITY,
3726 ClientSocketPool::RespectLimits::DISABLED));
[email protected]b021ece62013-06-11 11:06:333727 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3728
3729 EXPECT_EQ(OK, request(2)->WaitForResult());
3730 EXPECT_FALSE(request(1)->have_result());
3731}
3732
[email protected]c55fabd2013-11-04 23:26:563733// Test that when a socket pool and group are at their limits, a ConnectJob
mmenked3641e12016-01-28 16:06:153734// issued for a request with RespectLimits::DISABLED is not cancelled when a
3735// request with RespectLimits::ENABLED issued to the same group is cancelled.
[email protected]c55fabd2013-11-04 23:26:563736TEST_F(ClientSocketPoolBaseTest, IgnoreLimitsCancelOtherJob) {
[email protected]c55fabd2013-11-04 23:26:563737 CreatePool(1, 1);
3738
3739 // Issue a request to reach the socket pool limit.
mmenked3641e12016-01-28 16:06:153740 EXPECT_EQ(
3741 OK, StartRequestWithIgnoreLimits(
3742 "a", MAXIMUM_PRIORITY, ClientSocketPool::RespectLimits::ENABLED));
[email protected]c55fabd2013-11-04 23:26:563743 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3744
3745 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3746
mmenked3641e12016-01-28 16:06:153747 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
3748 "a", MAXIMUM_PRIORITY,
3749 ClientSocketPool::RespectLimits::ENABLED));
[email protected]c55fabd2013-11-04 23:26:563750 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3751
mmenked3641e12016-01-28 16:06:153752 // Issue a request with RespectLimits::DISABLED, so a new ConnectJob is
3753 // created.
3754 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
3755 "a", MAXIMUM_PRIORITY,
3756 ClientSocketPool::RespectLimits::DISABLED));
[email protected]b021ece62013-06-11 11:06:333757 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3758
mmenked3641e12016-01-28 16:06:153759 // Cancel the pending request with RespectLimits::ENABLED. The ConnectJob
[email protected]b021ece62013-06-11 11:06:333760 // should not be cancelled.
3761 request(1)->handle()->Reset();
3762 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3763
3764 EXPECT_EQ(OK, request(2)->WaitForResult());
3765 EXPECT_FALSE(request(1)->have_result());
3766}
3767
[email protected]f6d1d6eb2009-06-24 20:16:093768} // namespace
3769
3770} // namespace net