blob: c7cbda1562f00cc2e417cb25b4322e92dfdcf193 [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
[email protected]51fdc7c2012-04-10 19:19:487#include <vector>
8
[email protected]6ecf2b92011-12-15 01:14:529#include "base/bind.h"
10#include "base/bind_helpers.h"
[email protected]2041cf342010-02-19 03:15:5911#include "base/callback.h"
[email protected]3b63f8f42011-03-28 01:54:1512#include "base/memory/ref_counted.h"
13#include "base/memory/scoped_vector.h"
[email protected]6ea7b152011-12-21 21:21:1314#include "base/memory/weak_ptr.h"
[email protected]18b577412013-07-18 04:19:1515#include "base/message_loop/message_loop.h"
[email protected]034df0f32013-01-07 23:17:4816#include "base/run_loop.h"
[email protected]fc9be5802013-06-11 10:56:5117#include "base/strings/string_number_conversions.h"
[email protected]18b577412013-07-18 04:19:1518#include "base/strings/stringprintf.h"
[email protected]f214f8792011-01-01 02:17:0819#include "base/threading/platform_thread.h"
[email protected]f3a1c642011-07-12 19:15:0320#include "base/values.h"
[email protected]034df0f32013-01-07 23:17:4821#include "net/base/load_timing_info.h"
[email protected]b258e0792013-01-12 07:11:5922#include "net/base/load_timing_info_test_util.h"
[email protected]d8eb84242010-09-25 02:25:0623#include "net/base/net_errors.h"
[email protected]9e743cd2010-03-16 07:03:5324#include "net/base/net_log.h"
25#include "net/base/net_log_unittest.h"
[email protected]ac790b42009-12-02 04:31:3126#include "net/base/request_priority.h"
[email protected]f6d1d6eb2009-06-24 20:16:0927#include "net/base/test_completion_callback.h"
[email protected]277d5942010-08-11 21:02:3528#include "net/http/http_response_headers.h"
[email protected]f6d1d6eb2009-06-24 20:16:0929#include "net/socket/client_socket_factory.h"
30#include "net/socket/client_socket_handle.h"
[email protected]b89f7e42010-05-20 20:37:0031#include "net/socket/client_socket_pool_histograms.h"
[email protected]75439d3b2009-07-23 22:11:1732#include "net/socket/socket_test_util.h"
[email protected]18ccfdb2013-08-15 00:13:4433#include "net/socket/ssl_client_socket.h"
[email protected]3268023f2011-05-05 00:08:1034#include "net/socket/stream_socket.h"
[email protected]18ccfdb2013-08-15 00:13:4435#include "net/udp/datagram_client_socket.h"
[email protected]51fdc7c2012-04-10 19:19:4836#include "testing/gmock/include/gmock/gmock.h"
[email protected]f6d1d6eb2009-06-24 20:16:0937#include "testing/gtest/include/gtest/gtest.h"
38
[email protected]51fdc7c2012-04-10 19:19:4839using ::testing::Invoke;
40using ::testing::Return;
41
[email protected]f6d1d6eb2009-06-24 20:16:0942namespace net {
43
44namespace {
45
[email protected]211d21722009-07-22 15:48:5346const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2047const int kDefaultMaxSocketsPerGroup = 2;
[email protected]0b7648c2009-07-06 20:14:0148
[email protected]034df0f32013-01-07 23:17:4849// Make sure |handle| sets load times correctly when it has been assigned a
50// reused socket.
51void TestLoadTimingInfoConnectedReused(const ClientSocketHandle& handle) {
52 LoadTimingInfo load_timing_info;
53 // Only pass true in as |is_reused|, as in general, HttpStream types should
54 // have stricter concepts of reuse than socket pools.
55 EXPECT_TRUE(handle.GetLoadTimingInfo(true, &load_timing_info));
56
57 EXPECT_EQ(true, load_timing_info.socket_reused);
58 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
59
[email protected]b258e0792013-01-12 07:11:5960 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
61 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:4862}
63
64// Make sure |handle| sets load times correctly when it has been assigned a
[email protected]b021ece62013-06-11 11:06:3365// fresh socket. Also runs TestLoadTimingInfoConnectedReused, since the owner
[email protected]034df0f32013-01-07 23:17:4866// of a connection where |is_reused| is false may consider the connection
67// reused.
68void TestLoadTimingInfoConnectedNotReused(const ClientSocketHandle& handle) {
69 EXPECT_FALSE(handle.is_reused());
70
71 LoadTimingInfo load_timing_info;
72 EXPECT_TRUE(handle.GetLoadTimingInfo(false, &load_timing_info));
73
74 EXPECT_FALSE(load_timing_info.socket_reused);
75 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
76
[email protected]b258e0792013-01-12 07:11:5977 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
78 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
79 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:4880
81 TestLoadTimingInfoConnectedReused(handle);
82}
83
84// Make sure |handle| sets load times correctly, in the case that it does not
85// currently have a socket.
86void TestLoadTimingInfoNotConnected(const ClientSocketHandle& handle) {
87 // Should only be set to true once a socket is assigned, if at all.
88 EXPECT_FALSE(handle.is_reused());
89
90 LoadTimingInfo load_timing_info;
91 EXPECT_FALSE(handle.GetLoadTimingInfo(false, &load_timing_info));
92
93 EXPECT_FALSE(load_timing_info.socket_reused);
94 EXPECT_EQ(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
95
[email protected]b258e0792013-01-12 07:11:5996 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
97 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:4898}
99
[email protected]df4b4ef2010-07-12 18:25:21100class TestSocketParams : public base::RefCounted<TestSocketParams> {
[email protected]5acdce12011-03-30 13:00:20101 public:
[email protected]bb1c4662013-11-14 00:00:07102 explicit TestSocketParams(bool ignore_limits)
103 : ignore_limits_(ignore_limits) {}
[email protected]51fdc7c2012-04-10 19:19:48104
[email protected]51fdc7c2012-04-10 19:19:48105 bool ignore_limits() { return ignore_limits_; }
106
[email protected]df4b4ef2010-07-12 18:25:21107 private:
108 friend class base::RefCounted<TestSocketParams>;
109 ~TestSocketParams() {}
[email protected]51fdc7c2012-04-10 19:19:48110
[email protected]bb1c4662013-11-14 00:00:07111 const bool ignore_limits_;
[email protected]df4b4ef2010-07-12 18:25:21112};
[email protected]7fc5b09a2010-02-27 00:07:38113typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
[email protected]d80a4322009-08-14 07:07:49114
[email protected]3268023f2011-05-05 00:08:10115class MockClientSocket : public StreamSocket {
[email protected]f6d1d6eb2009-06-24 20:16:09116 public:
[email protected]034df0f32013-01-07 23:17:48117 explicit MockClientSocket(net::NetLog* net_log)
118 : connected_(false),
[email protected]0dc88b32014-03-26 20:12:28119 has_unread_data_(false),
[email protected]034df0f32013-01-07 23:17:48120 net_log_(BoundNetLog::Make(net_log, net::NetLog::SOURCE_SOCKET)),
[email protected]e86df8dc2013-03-30 13:18:28121 was_used_to_convey_data_(false) {
[email protected]034df0f32013-01-07 23:17:48122 }
[email protected]f6d1d6eb2009-06-24 20:16:09123
[email protected]0dc88b32014-03-26 20:12:28124 // Sets whether the socket has unread data. If true, the next call to Read()
125 // will return 1 byte and IsConnectedAndIdle() will return false.
126 void set_has_unread_data(bool has_unread_data) {
127 has_unread_data_ = has_unread_data;
128 }
129
[email protected]3f55aa12011-12-07 02:03:33130 // Socket implementation.
dchengb03027d2014-10-21 12:00:20131 int Read(IOBuffer* /* buf */,
132 int len,
133 const CompletionCallback& /* callback */) override {
[email protected]0dc88b32014-03-26 20:12:28134 if (has_unread_data_ && len > 0) {
135 has_unread_data_ = false;
136 was_used_to_convey_data_ = true;
137 return 1;
138 }
[email protected]e86df8dc2013-03-30 13:18:28139 return ERR_UNEXPECTED;
[email protected]3f55aa12011-12-07 02:03:33140 }
[email protected]ab838892009-06-30 18:49:05141
dchengb03027d2014-10-21 12:00:20142 int Write(IOBuffer* /* buf */,
143 int len,
144 const CompletionCallback& /* callback */) override {
[email protected]0f873e82010-09-02 16:09:01145 was_used_to_convey_data_ = true;
146 return len;
[email protected]ab838892009-06-30 18:49:05147 }
dchengb03027d2014-10-21 12:00:20148 int SetReceiveBufferSize(int32 size) override { return OK; }
149 int SetSendBufferSize(int32 size) override { return OK; }
[email protected]ab838892009-06-30 18:49:05150
[email protected]dbf036f2011-12-06 23:33:24151 // StreamSocket implementation.
dchengb03027d2014-10-21 12:00:20152 int Connect(const CompletionCallback& callback) override {
[email protected]dbf036f2011-12-06 23:33:24153 connected_ = true;
154 return OK;
155 }
[email protected]f6d1d6eb2009-06-24 20:16:09156
dchengb03027d2014-10-21 12:00:20157 void Disconnect() override { connected_ = false; }
158 bool IsConnected() const override { return connected_; }
159 bool IsConnectedAndIdle() const override {
[email protected]0dc88b32014-03-26 20:12:28160 return connected_ && !has_unread_data_;
161 }
[email protected]0b7648c2009-07-06 20:14:01162
dchengb03027d2014-10-21 12:00:20163 int GetPeerAddress(IPEndPoint* /* address */) const override {
[email protected]9f864b32010-01-20 15:01:16164 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:09165 }
[email protected]f6d1d6eb2009-06-24 20:16:09166
dchengb03027d2014-10-21 12:00:20167 int GetLocalAddress(IPEndPoint* /* address */) const override {
[email protected]e7f74da2011-04-19 23:49:35168 return ERR_UNEXPECTED;
169 }
170
dchengb03027d2014-10-21 12:00:20171 const BoundNetLog& NetLog() const override { return net_log_; }
[email protected]a2006ece2010-04-23 16:44:02172
dchengb03027d2014-10-21 12:00:20173 void SetSubresourceSpeculation() override {}
174 void SetOmniboxSpeculation() override {}
175 bool WasEverUsed() const override { return was_used_to_convey_data_; }
176 bool UsingTCPFastOpen() const override { return false; }
177 bool WasNpnNegotiated() const override { return false; }
178 NextProto GetNegotiatedProtocol() const override { return kProtoUnknown; }
179 bool GetSSLInfo(SSLInfo* ssl_info) override { return false; }
[email protected]9b5614a2010-08-25 20:29:45180
[email protected]f6d1d6eb2009-06-24 20:16:09181 private:
182 bool connected_;
[email protected]0dc88b32014-03-26 20:12:28183 bool has_unread_data_;
[email protected]a2006ece2010-04-23 16:44:02184 BoundNetLog net_log_;
[email protected]0f873e82010-09-02 16:09:01185 bool was_used_to_convey_data_;
[email protected]f6d1d6eb2009-06-24 20:16:09186
[email protected]ab838892009-06-30 18:49:05187 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:09188};
189
[email protected]5fc08e32009-07-15 17:09:57190class TestConnectJob;
191
[email protected]f6d1d6eb2009-06-24 20:16:09192class MockClientSocketFactory : public ClientSocketFactory {
193 public:
[email protected]ab838892009-06-30 18:49:05194 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:09195
dchengb03027d2014-10-21 12:00:20196 scoped_ptr<DatagramClientSocket> CreateDatagramClientSocket(
[email protected]5370c012011-06-29 03:47:04197 DatagramSocket::BindType bind_type,
198 const RandIntCallback& rand_int_cb,
[email protected]98b0e582011-06-22 14:31:41199 NetLog* net_log,
mostynbba063d6032014-10-09 11:01:13200 const NetLog::Source& source) override {
[email protected]98b0e582011-06-22 14:31:41201 NOTREACHED();
[email protected]18ccfdb2013-08-15 00:13:44202 return scoped_ptr<DatagramClientSocket>();
[email protected]98b0e582011-06-22 14:31:41203 }
204
dchengb03027d2014-10-21 12:00:20205 scoped_ptr<StreamSocket> CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07206 const AddressList& addresses,
207 NetLog* /* net_log */,
mostynbba063d6032014-10-09 11:01:13208 const NetLog::Source& /*source*/) override {
[email protected]f6d1d6eb2009-06-24 20:16:09209 allocation_count_++;
[email protected]18ccfdb2013-08-15 00:13:44210 return scoped_ptr<StreamSocket>();
[email protected]f6d1d6eb2009-06-24 20:16:09211 }
212
dchengb03027d2014-10-21 12:00:20213 scoped_ptr<SSLClientSocket> CreateSSLClientSocket(
[email protected]18ccfdb2013-08-15 00:13:44214 scoped_ptr<ClientSocketHandle> transport_socket,
[email protected]4f4de7e62010-11-12 19:55:27215 const HostPortPair& host_and_port,
[email protected]7ab5bbd12010-10-19 13:33:21216 const SSLConfig& ssl_config,
mostynbba063d6032014-10-09 11:01:13217 const SSLClientSocketContext& context) override {
[email protected]f6d1d6eb2009-06-24 20:16:09218 NOTIMPLEMENTED();
[email protected]18ccfdb2013-08-15 00:13:44219 return scoped_ptr<SSLClientSocket>();
[email protected]f6d1d6eb2009-06-24 20:16:09220 }
221
dchengb03027d2014-10-21 12:00:20222 void ClearSSLSessionCache() override { NOTIMPLEMENTED(); }
[email protected]25f47352011-02-25 16:31:59223
[email protected]5fc08e32009-07-15 17:09:57224 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
[email protected]03b7c8c2013-07-20 04:38:55225
[email protected]5fc08e32009-07-15 17:09:57226 void SignalJobs();
227
[email protected]03b7c8c2013-07-20 04:38:55228 void SignalJob(size_t job);
229
230 void SetJobLoadState(size_t job, LoadState load_state);
231
[email protected]f6d1d6eb2009-06-24 20:16:09232 int allocation_count() const { return allocation_count_; }
233
[email protected]f6d1d6eb2009-06-24 20:16:09234 private:
235 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:57236 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09237};
238
[email protected]ab838892009-06-30 18:49:05239class TestConnectJob : public ConnectJob {
240 public:
241 enum JobType {
242 kMockJob,
243 kMockFailingJob,
244 kMockPendingJob,
245 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57246 kMockWaitingJob,
[email protected]e772db3f2010-07-12 18:11:13247 kMockRecoverableJob,
248 kMockPendingRecoverableJob,
[email protected]e60e47a2010-07-14 03:37:18249 kMockAdditionalErrorStateJob,
250 kMockPendingAdditionalErrorStateJob,
[email protected]0dc88b32014-03-26 20:12:28251 kMockUnreadDataJob,
[email protected]ab838892009-06-30 18:49:05252 };
253
[email protected]994d4932010-07-12 17:55:13254 // The kMockPendingJob uses a slight delay before allowing the connect
255 // to complete.
256 static const int kPendingConnectDelay = 2;
257
[email protected]ab838892009-06-30 18:49:05258 TestConnectJob(JobType job_type,
259 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49260 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34261 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05262 ConnectJob::Delegate* delegate,
[email protected]fd7b7c92009-08-20 19:38:30263 MockClientSocketFactory* client_socket_factory,
[email protected]06650c52010-06-03 00:49:17264 NetLog* net_log)
[email protected]3f6007ab2013-08-22 19:45:39265 : ConnectJob(group_name, timeout_duration, request.priority(), delegate,
[email protected]06650c52010-06-03 00:49:17266 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
[email protected]2ab05b52009-07-01 23:57:58267 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05268 client_socket_factory_(client_socket_factory),
[email protected]e60e47a2010-07-14 03:37:18269 load_state_(LOAD_STATE_IDLE),
[email protected]d5492c52013-11-10 20:44:39270 store_additional_error_state_(false),
271 weak_factory_(this) {
272 }
[email protected]ab838892009-06-30 18:49:05273
[email protected]974ebd62009-08-03 23:14:34274 void Signal() {
[email protected]e772db3f2010-07-12 18:11:13275 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
[email protected]974ebd62009-08-03 23:14:34276 }
277
[email protected]03b7c8c2013-07-20 04:38:55278 void set_load_state(LoadState load_state) { load_state_ = load_state; }
279
280 // From ConnectJob:
281
dchengb03027d2014-10-21 12:00:20282 LoadState GetLoadState() const override { return load_state_; }
[email protected]46451352009-09-01 14:54:21283
dchengb03027d2014-10-21 12:00:20284 void GetAdditionalErrorState(ClientSocketHandle* handle) override {
[email protected]e60e47a2010-07-14 03:37:18285 if (store_additional_error_state_) {
286 // Set all of the additional error state fields in some way.
287 handle->set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43288 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:45289 info.headers = new HttpResponseHeaders(std::string());
[email protected]8b498692010-07-16 17:11:43290 handle->set_ssl_error_response_info(info);
[email protected]e60e47a2010-07-14 03:37:18291 }
292 }
293
[email protected]974ebd62009-08-03 23:14:34294 private:
[email protected]03b7c8c2013-07-20 04:38:55295 // From ConnectJob:
[email protected]ab838892009-06-30 18:49:05296
dchengb03027d2014-10-21 12:00:20297 int ConnectInternal() override {
[email protected]ab838892009-06-30 18:49:05298 AddressList ignored;
[email protected]ab739042011-04-07 15:22:28299 client_socket_factory_->CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07300 ignored, NULL, net::NetLog::Source());
[email protected]18ccfdb2013-08-15 00:13:44301 SetSocket(
302 scoped_ptr<StreamSocket>(new MockClientSocket(net_log().net_log())));
[email protected]ab838892009-06-30 18:49:05303 switch (job_type_) {
304 case kMockJob:
[email protected]e772db3f2010-07-12 18:11:13305 return DoConnect(true /* successful */, false /* sync */,
306 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05307 case kMockFailingJob:
[email protected]e772db3f2010-07-12 18:11:13308 return DoConnect(false /* error */, false /* sync */,
309 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05310 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57311 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47312
313 // Depending on execution timings, posting a delayed task can result
314 // in the task getting executed the at the earliest possible
315 // opportunity or only after returning once from the message loop and
316 // then a second call into the message loop. In order to make behavior
317 // more deterministic, we change the default delay to 2ms. This should
318 // always require us to wait for the second call into the message loop.
319 //
320 // N.B. The correct fix for this and similar timing problems is to
321 // abstract time for the purpose of unittests. Unfortunately, we have
322 // a lot of third-party components that directly call the various
323 // time functions, so this change would be rather invasive.
[email protected]2da659e2013-05-23 20:51:34324 base::MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05325 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13326 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
327 weak_factory_.GetWeakPtr(),
328 true /* successful */,
329 true /* async */,
330 false /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53331 base::TimeDelta::FromMilliseconds(kPendingConnectDelay));
[email protected]ab838892009-06-30 18:49:05332 return ERR_IO_PENDING;
333 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57334 set_load_state(LOAD_STATE_CONNECTING);
[email protected]2da659e2013-05-23 20:51:34335 base::MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05336 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13337 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
338 weak_factory_.GetWeakPtr(),
339 false /* error */,
340 true /* async */,
341 false /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53342 base::TimeDelta::FromMilliseconds(2));
[email protected]ab838892009-06-30 18:49:05343 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57344 case kMockWaitingJob:
[email protected]03b7c8c2013-07-20 04:38:55345 set_load_state(LOAD_STATE_CONNECTING);
[email protected]5fc08e32009-07-15 17:09:57346 client_socket_factory_->WaitForSignal(this);
347 waiting_success_ = true;
348 return ERR_IO_PENDING;
[email protected]e772db3f2010-07-12 18:11:13349 case kMockRecoverableJob:
350 return DoConnect(false /* error */, false /* sync */,
351 true /* recoverable */);
352 case kMockPendingRecoverableJob:
353 set_load_state(LOAD_STATE_CONNECTING);
[email protected]2da659e2013-05-23 20:51:34354 base::MessageLoop::current()->PostDelayedTask(
[email protected]e772db3f2010-07-12 18:11:13355 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13356 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
357 weak_factory_.GetWeakPtr(),
358 false /* error */,
359 true /* async */,
360 true /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53361 base::TimeDelta::FromMilliseconds(2));
[email protected]e772db3f2010-07-12 18:11:13362 return ERR_IO_PENDING;
[email protected]e60e47a2010-07-14 03:37:18363 case kMockAdditionalErrorStateJob:
364 store_additional_error_state_ = true;
365 return DoConnect(false /* error */, false /* sync */,
366 false /* recoverable */);
367 case kMockPendingAdditionalErrorStateJob:
368 set_load_state(LOAD_STATE_CONNECTING);
369 store_additional_error_state_ = true;
[email protected]2da659e2013-05-23 20:51:34370 base::MessageLoop::current()->PostDelayedTask(
[email protected]e60e47a2010-07-14 03:37:18371 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13372 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
373 weak_factory_.GetWeakPtr(),
374 false /* error */,
375 true /* async */,
376 false /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53377 base::TimeDelta::FromMilliseconds(2));
[email protected]e60e47a2010-07-14 03:37:18378 return ERR_IO_PENDING;
[email protected]0dc88b32014-03-26 20:12:28379 case kMockUnreadDataJob: {
380 int ret = DoConnect(true /* successful */, false /* sync */,
381 false /* recoverable */);
382 static_cast<MockClientSocket*>(socket())->set_has_unread_data(true);
383 return ret;
384 }
[email protected]ab838892009-06-30 18:49:05385 default:
386 NOTREACHED();
[email protected]18ccfdb2013-08-15 00:13:44387 SetSocket(scoped_ptr<StreamSocket>());
[email protected]ab838892009-06-30 18:49:05388 return ERR_FAILED;
389 }
390 }
391
[email protected]e772db3f2010-07-12 18:11:13392 int DoConnect(bool succeed, bool was_async, bool recoverable) {
393 int result = OK;
[email protected]ab838892009-06-30 18:49:05394 if (succeed) {
[email protected]83039bb2011-12-09 18:43:55395 socket()->Connect(CompletionCallback());
[email protected]e772db3f2010-07-12 18:11:13396 } else if (recoverable) {
397 result = ERR_PROXY_AUTH_REQUESTED;
[email protected]6e713f02009-08-06 02:56:40398 } else {
[email protected]e772db3f2010-07-12 18:11:13399 result = ERR_CONNECTION_FAILED;
[email protected]18ccfdb2013-08-15 00:13:44400 SetSocket(scoped_ptr<StreamSocket>());
[email protected]ab838892009-06-30 18:49:05401 }
[email protected]2ab05b52009-07-01 23:57:58402
403 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30404 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05405 return result;
406 }
407
[email protected]5fc08e32009-07-15 17:09:57408 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05409 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57410 MockClientSocketFactory* const client_socket_factory_;
[email protected]46451352009-09-01 14:54:21411 LoadState load_state_;
[email protected]e60e47a2010-07-14 03:37:18412 bool store_additional_error_state_;
[email protected]ab838892009-06-30 18:49:05413
[email protected]d5492c52013-11-10 20:44:39414 base::WeakPtrFactory<TestConnectJob> weak_factory_;
415
[email protected]ab838892009-06-30 18:49:05416 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
417};
418
[email protected]d80a4322009-08-14 07:07:49419class TestConnectJobFactory
420 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05421 public:
[email protected]034df0f32013-01-07 23:17:48422 TestConnectJobFactory(MockClientSocketFactory* client_socket_factory,
423 NetLog* net_log)
[email protected]ab838892009-06-30 18:49:05424 : job_type_(TestConnectJob::kMockJob),
[email protected]51fdc7c2012-04-10 19:19:48425 job_types_(NULL),
[email protected]034df0f32013-01-07 23:17:48426 client_socket_factory_(client_socket_factory),
427 net_log_(net_log) {
[email protected]b021ece62013-06-11 11:06:33428 }
[email protected]ab838892009-06-30 18:49:05429
dchengb03027d2014-10-21 12:00:20430 ~TestConnectJobFactory() override {}
[email protected]ab838892009-06-30 18:49:05431
432 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
433
[email protected]51fdc7c2012-04-10 19:19:48434 void set_job_types(std::list<TestConnectJob::JobType>* job_types) {
435 job_types_ = job_types;
436 CHECK(!job_types_->empty());
437 }
438
[email protected]974ebd62009-08-03 23:14:34439 void set_timeout_duration(base::TimeDelta timeout_duration) {
440 timeout_duration_ = timeout_duration;
441 }
442
[email protected]3f55aa12011-12-07 02:03:33443 // ConnectJobFactory implementation.
[email protected]83039bb2011-12-09 18:43:55444
dchengb03027d2014-10-21 12:00:20445 scoped_ptr<ConnectJob> NewConnectJob(
[email protected]ab838892009-06-30 18:49:05446 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49447 const TestClientSocketPoolBase::Request& request,
mostynbba063d6032014-10-09 11:01:13448 ConnectJob::Delegate* delegate) const override {
[email protected]51fdc7c2012-04-10 19:19:48449 EXPECT_TRUE(!job_types_ || !job_types_->empty());
450 TestConnectJob::JobType job_type = job_type_;
451 if (job_types_ && !job_types_->empty()) {
452 job_type = job_types_->front();
453 job_types_->pop_front();
454 }
[email protected]18ccfdb2013-08-15 00:13:44455 return scoped_ptr<ConnectJob>(new TestConnectJob(job_type,
456 group_name,
457 request,
458 timeout_duration_,
459 delegate,
460 client_socket_factory_,
461 net_log_));
[email protected]ab838892009-06-30 18:49:05462 }
463
dchengb03027d2014-10-21 12:00:20464 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26465 return timeout_duration_;
466 }
467
[email protected]ab838892009-06-30 18:49:05468 private:
469 TestConnectJob::JobType job_type_;
[email protected]51fdc7c2012-04-10 19:19:48470 std::list<TestConnectJob::JobType>* job_types_;
[email protected]974ebd62009-08-03 23:14:34471 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57472 MockClientSocketFactory* const client_socket_factory_;
[email protected]034df0f32013-01-07 23:17:48473 NetLog* net_log_;
[email protected]ab838892009-06-30 18:49:05474
475 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
476};
477
478class TestClientSocketPool : public ClientSocketPool {
479 public:
[email protected]12322e7e2013-08-15 17:49:26480 typedef TestSocketParams SocketParams;
481
[email protected]ab838892009-06-30 18:49:05482 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53483 int max_sockets,
[email protected]ab838892009-06-30 18:49:05484 int max_sockets_per_group,
[email protected]2431756e2010-09-29 20:26:13485 ClientSocketPoolHistograms* histograms,
[email protected]9bf28db2009-08-29 01:35:16486 base::TimeDelta unused_idle_socket_timeout,
487 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49488 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
[email protected]043b68c82013-08-22 23:41:52489 : base_(NULL, max_sockets, max_sockets_per_group, histograms,
[email protected]9bf28db2009-08-29 01:35:16490 unused_idle_socket_timeout, used_idle_socket_timeout,
[email protected]66761b952010-06-25 21:30:38491 connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05492
dchengb03027d2014-10-21 12:00:20493 ~TestClientSocketPool() override {}
[email protected]2431756e2010-09-29 20:26:13494
dchengb03027d2014-10-21 12:00:20495 int RequestSocket(const std::string& group_name,
496 const void* params,
497 net::RequestPriority priority,
498 ClientSocketHandle* handle,
499 const CompletionCallback& callback,
500 const BoundNetLog& net_log) override {
[email protected]df4b4ef2010-07-12 18:25:21501 const scoped_refptr<TestSocketParams>* casted_socket_params =
502 static_cast<const scoped_refptr<TestSocketParams>*>(params);
503 return base_.RequestSocket(group_name, *casted_socket_params, priority,
504 handle, callback, net_log);
[email protected]ab838892009-06-30 18:49:05505 }
506
dchengb03027d2014-10-21 12:00:20507 void RequestSockets(const std::string& group_name,
508 const void* params,
509 int num_sockets,
510 const BoundNetLog& net_log) override {
[email protected]2c2bef152010-10-13 00:55:03511 const scoped_refptr<TestSocketParams>* casted_params =
512 static_cast<const scoped_refptr<TestSocketParams>*>(params);
513
514 base_.RequestSockets(group_name, *casted_params, num_sockets, net_log);
515 }
516
dchengb03027d2014-10-21 12:00:20517 void CancelRequest(const std::string& group_name,
518 ClientSocketHandle* handle) override {
[email protected]d80a4322009-08-14 07:07:49519 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05520 }
521
dchengb03027d2014-10-21 12:00:20522 void ReleaseSocket(const std::string& group_name,
523 scoped_ptr<StreamSocket> socket,
524 int id) override {
[email protected]18ccfdb2013-08-15 00:13:44525 base_.ReleaseSocket(group_name, socket.Pass(), id);
[email protected]a7e38572010-06-07 18:22:24526 }
527
dchengb03027d2014-10-21 12:00:20528 void FlushWithError(int error) override { base_.FlushWithError(error); }
[email protected]ab838892009-06-30 18:49:05529
dchengb03027d2014-10-21 12:00:20530 bool IsStalled() const override { return base_.IsStalled(); }
[email protected]51fdc7c2012-04-10 19:19:48531
dchengb03027d2014-10-21 12:00:20532 void CloseIdleSockets() override { base_.CloseIdleSockets(); }
[email protected]ab838892009-06-30 18:49:05533
dchengb03027d2014-10-21 12:00:20534 int IdleSocketCount() const override { return base_.idle_socket_count(); }
[email protected]ab838892009-06-30 18:49:05535
dchengb03027d2014-10-21 12:00:20536 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]d80a4322009-08-14 07:07:49537 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05538 }
539
dchengb03027d2014-10-21 12:00:20540 LoadState GetLoadState(const std::string& group_name,
541 const ClientSocketHandle* handle) const override {
[email protected]d80a4322009-08-14 07:07:49542 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05543 }
544
dchengb03027d2014-10-21 12:00:20545 void AddHigherLayeredPool(HigherLayeredPool* higher_pool) override {
[email protected]043b68c82013-08-22 23:41:52546 base_.AddHigherLayeredPool(higher_pool);
[email protected]51fdc7c2012-04-10 19:19:48547 }
548
dchengb03027d2014-10-21 12:00:20549 void RemoveHigherLayeredPool(HigherLayeredPool* higher_pool) override {
[email protected]043b68c82013-08-22 23:41:52550 base_.RemoveHigherLayeredPool(higher_pool);
[email protected]51fdc7c2012-04-10 19:19:48551 }
552
dchengb03027d2014-10-21 12:00:20553 base::DictionaryValue* GetInfoAsValue(
[email protected]d4dfdab2011-12-07 16:56:59554 const std::string& name,
555 const std::string& type,
mostynbba063d6032014-10-09 11:01:13556 bool include_nested_pools) const override {
[email protected]59d7a5a2010-08-30 16:44:27557 return base_.GetInfoAsValue(name, type);
558 }
559
dchengb03027d2014-10-21 12:00:20560 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26561 return base_.ConnectionTimeout();
562 }
563
dchengb03027d2014-10-21 12:00:20564 ClientSocketPoolHistograms* histograms() const override {
[email protected]b89f7e42010-05-20 20:37:00565 return base_.histograms();
566 }
[email protected]a796bcec2010-03-22 17:17:26567
[email protected]d80a4322009-08-14 07:07:49568 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20569
[email protected]8159a1c2012-06-07 00:00:10570 int NumUnassignedConnectJobsInGroup(const std::string& group_name) const {
571 return base_.NumUnassignedConnectJobsInGroup(group_name);
572 }
573
[email protected]974ebd62009-08-03 23:14:34574 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49575 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34576 }
577
[email protected]2c2bef152010-10-13 00:55:03578 int NumActiveSocketsInGroup(const std::string& group_name) const {
579 return base_.NumActiveSocketsInGroup(group_name);
580 }
581
[email protected]2abfe90a2010-08-25 17:49:51582 bool HasGroup(const std::string& group_name) const {
583 return base_.HasGroup(group_name);
584 }
585
[email protected]9bf28db2009-08-29 01:35:16586 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
587
[email protected]06d94042010-08-25 01:45:22588 void EnableConnectBackupJobs() { base_.EnableConnectBackupJobs(); }
[email protected]43a21b82010-06-10 21:30:54589
[email protected]043b68c82013-08-22 23:41:52590 bool CloseOneIdleConnectionInHigherLayeredPool() {
591 return base_.CloseOneIdleConnectionInHigherLayeredPool();
[email protected]51fdc7c2012-04-10 19:19:48592 }
593
[email protected]ab838892009-06-30 18:49:05594 private:
[email protected]d80a4322009-08-14 07:07:49595 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05596
597 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
598};
599
[email protected]a937a06d2009-08-19 21:19:24600} // namespace
601
[email protected]a937a06d2009-08-19 21:19:24602namespace {
603
[email protected]5fc08e32009-07-15 17:09:57604void MockClientSocketFactory::SignalJobs() {
605 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
606 it != waiting_jobs_.end(); ++it) {
607 (*it)->Signal();
608 }
609 waiting_jobs_.clear();
610}
611
[email protected]03b7c8c2013-07-20 04:38:55612void MockClientSocketFactory::SignalJob(size_t job) {
613 ASSERT_LT(job, waiting_jobs_.size());
614 waiting_jobs_[job]->Signal();
615 waiting_jobs_.erase(waiting_jobs_.begin() + job);
616}
617
618void MockClientSocketFactory::SetJobLoadState(size_t job,
619 LoadState load_state) {
620 ASSERT_LT(job, waiting_jobs_.size());
621 waiting_jobs_[job]->set_load_state(load_state);
622}
623
[email protected]974ebd62009-08-03 23:14:34624class TestConnectJobDelegate : public ConnectJob::Delegate {
625 public:
626 TestConnectJobDelegate()
627 : have_result_(false), waiting_for_result_(false), result_(OK) {}
dchengb03027d2014-10-21 12:00:20628 ~TestConnectJobDelegate() override {}
[email protected]974ebd62009-08-03 23:14:34629
dchengb03027d2014-10-21 12:00:20630 void OnConnectJobComplete(int result, ConnectJob* job) override {
[email protected]974ebd62009-08-03 23:14:34631 result_ = result;
[email protected]18ccfdb2013-08-15 00:13:44632 scoped_ptr<ConnectJob> owned_job(job);
633 scoped_ptr<StreamSocket> socket = owned_job->PassSocket();
[email protected]9b6fee12009-09-29 18:13:07634 // socket.get() should be NULL iff result != OK
[email protected]18ccfdb2013-08-15 00:13:44635 EXPECT_EQ(socket == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34636 have_result_ = true;
637 if (waiting_for_result_)
[email protected]2da659e2013-05-23 20:51:34638 base::MessageLoop::current()->Quit();
[email protected]974ebd62009-08-03 23:14:34639 }
640
641 int WaitForResult() {
642 DCHECK(!waiting_for_result_);
643 while (!have_result_) {
644 waiting_for_result_ = true;
[email protected]2da659e2013-05-23 20:51:34645 base::MessageLoop::current()->Run();
[email protected]974ebd62009-08-03 23:14:34646 waiting_for_result_ = false;
647 }
648 have_result_ = false; // auto-reset for next callback
649 return result_;
650 }
651
652 private:
653 bool have_result_;
654 bool waiting_for_result_;
655 int result_;
656};
657
[email protected]2431756e2010-09-29 20:26:13658class ClientSocketPoolBaseTest : public testing::Test {
[email protected]f6d1d6eb2009-06-24 20:16:09659 protected:
[email protected]b89f7e42010-05-20 20:37:00660 ClientSocketPoolBaseTest()
[email protected]bb1c4662013-11-14 00:00:07661 : params_(new TestSocketParams(false /* ignore_limits */)),
[email protected]636b8252011-04-08 19:56:54662 histograms_("ClientSocketPoolTest") {
663 connect_backup_jobs_enabled_ =
664 internal::ClientSocketPoolBaseHelper::connect_backup_jobs_enabled();
665 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(true);
[email protected]64770b7d2011-11-16 04:30:41666 cleanup_timer_enabled_ =
667 internal::ClientSocketPoolBaseHelper::cleanup_timer_enabled();
[email protected]636b8252011-04-08 19:56:54668 }
[email protected]2431756e2010-09-29 20:26:13669
dcheng67be2b1f2014-10-27 21:47:29670 ~ClientSocketPoolBaseTest() override {
[email protected]636b8252011-04-08 19:56:54671 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
672 connect_backup_jobs_enabled_);
[email protected]64770b7d2011-11-16 04:30:41673 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(
674 cleanup_timer_enabled_);
[email protected]636b8252011-04-08 19:56:54675 }
[email protected]c9d6a1d2009-07-14 16:15:20676
[email protected]211d21722009-07-22 15:48:53677 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16678 CreatePoolWithIdleTimeouts(
679 max_sockets,
680 max_sockets_per_group,
[email protected]82b8c962011-10-12 09:17:30681 ClientSocketPool::unused_idle_socket_timeout(),
682 ClientSocketPool::used_idle_socket_timeout());
[email protected]9bf28db2009-08-29 01:35:16683 }
684
685 void CreatePoolWithIdleTimeouts(
686 int max_sockets, int max_sockets_per_group,
687 base::TimeDelta unused_idle_socket_timeout,
688 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20689 DCHECK(!pool_.get());
[email protected]034df0f32013-01-07 23:17:48690 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_,
691 &net_log_);
[email protected]2431756e2010-09-29 20:26:13692 pool_.reset(new TestClientSocketPool(max_sockets,
693 max_sockets_per_group,
694 &histograms_,
695 unused_idle_socket_timeout,
696 used_idle_socket_timeout,
697 connect_job_factory_));
[email protected]c9d6a1d2009-07-14 16:15:20698 }
[email protected]f6d1d6eb2009-06-24 20:16:09699
[email protected]b021ece62013-06-11 11:06:33700 int StartRequestWithParams(
701 const std::string& group_name,
702 RequestPriority priority,
703 const scoped_refptr<TestSocketParams>& params) {
[email protected]12322e7e2013-08-15 17:49:26704 return test_base_.StartRequestUsingPool(
705 pool_.get(), group_name, priority, params);
[email protected]b021ece62013-06-11 11:06:33706 }
707
708 int StartRequest(const std::string& group_name, RequestPriority priority) {
709 return StartRequestWithParams(group_name, priority, params_);
[email protected]f6d1d6eb2009-06-24 20:16:09710 }
711
[email protected]2431756e2010-09-29 20:26:13712 int GetOrderOfRequest(size_t index) const {
713 return test_base_.GetOrderOfRequest(index);
[email protected]f6d1d6eb2009-06-24 20:16:09714 }
715
[email protected]2431756e2010-09-29 20:26:13716 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
717 return test_base_.ReleaseOneConnection(keep_alive);
718 }
719
720 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
721 test_base_.ReleaseAllConnections(keep_alive);
722 }
723
724 TestSocketRequest* request(int i) { return test_base_.request(i); }
725 size_t requests_size() const { return test_base_.requests_size(); }
726 ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); }
727 size_t completion_count() const { return test_base_.completion_count(); }
728
[email protected]034df0f32013-01-07 23:17:48729 CapturingNetLog net_log_;
[email protected]636b8252011-04-08 19:56:54730 bool connect_backup_jobs_enabled_;
[email protected]64770b7d2011-11-16 04:30:41731 bool cleanup_timer_enabled_;
[email protected]f6d1d6eb2009-06-24 20:16:09732 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04733 TestConnectJobFactory* connect_job_factory_;
[email protected]df4b4ef2010-07-12 18:25:21734 scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:13735 ClientSocketPoolHistograms histograms_;
736 scoped_ptr<TestClientSocketPool> pool_;
737 ClientSocketPoolTest test_base_;
[email protected]f6d1d6eb2009-06-24 20:16:09738};
739
[email protected]974ebd62009-08-03 23:14:34740// Even though a timeout is specified, it doesn't time out on a synchronous
741// completion.
742TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
743 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06744 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49745 TestClientSocketPoolBase::Request request(
[email protected]bb1c4662013-11-14 00:00:07746 &ignored, CompletionCallback(), DEFAULT_PRIORITY,
[email protected]2c2bef152010-10-13 00:55:03747 internal::ClientSocketPoolBaseHelper::NORMAL,
[email protected]5acdce12011-03-30 13:00:20748 false, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34749 scoped_ptr<TestConnectJob> job(
750 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:12751 "a",
[email protected]974ebd62009-08-03 23:14:34752 request,
753 base::TimeDelta::FromMicroseconds(1),
754 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30755 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17756 NULL));
[email protected]974ebd62009-08-03 23:14:34757 EXPECT_EQ(OK, job->Connect());
758}
759
760TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
761 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06762 ClientSocketHandle ignored;
[email protected]333bdf62012-06-08 22:57:29763 CapturingNetLog log;
[email protected]9e743cd2010-03-16 07:03:53764
[email protected]d80a4322009-08-14 07:07:49765 TestClientSocketPoolBase::Request request(
[email protected]bb1c4662013-11-14 00:00:07766 &ignored, CompletionCallback(), DEFAULT_PRIORITY,
[email protected]2c2bef152010-10-13 00:55:03767 internal::ClientSocketPoolBaseHelper::NORMAL,
[email protected]5acdce12011-03-30 13:00:20768 false, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34769 // Deleted by TestConnectJobDelegate.
770 TestConnectJob* job =
771 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12772 "a",
[email protected]974ebd62009-08-03 23:14:34773 request,
774 base::TimeDelta::FromMicroseconds(1),
775 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30776 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17777 &log);
[email protected]974ebd62009-08-03 23:14:34778 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
[email protected]26b9973962012-01-28 00:57:00779 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
[email protected]974ebd62009-08-03 23:14:34780 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30781
[email protected]333bdf62012-06-08 22:57:29782 CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:40783 log.GetEntries(&entries);
784
785 EXPECT_EQ(6u, entries.size());
[email protected]e9002a92010-01-29 07:10:46786 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40787 entries, 0, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]06650c52010-06-03 00:49:17788 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40789 entries, 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]e9002a92010-01-29 07:10:46790 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40791 entries, 2, NetLog::TYPE_CONNECT_JOB_SET_SOCKET,
[email protected]06650c52010-06-03 00:49:17792 NetLog::PHASE_NONE));
793 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40794 entries, 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
[email protected]9e743cd2010-03-16 07:03:53795 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:46796 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40797 entries, 4, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]06650c52010-06-03 00:49:17798 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40799 entries, 5, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34800}
801
[email protected]5fc08e32009-07-15 17:09:57802TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53803 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20804
[email protected]6ecf2b92011-12-15 01:14:52805 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06806 ClientSocketHandle handle;
[email protected]333bdf62012-06-08 22:57:29807 CapturingBoundNetLog log;
[email protected]034df0f32013-01-07 23:17:48808 TestLoadTimingInfoNotConnected(handle);
[email protected]9e743cd2010-03-16 07:03:53809
[email protected]2431756e2010-09-29 20:26:13810 EXPECT_EQ(OK,
811 handle.Init("a",
812 params_,
[email protected]bb1c4662013-11-14 00:00:07813 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:52814 callback.callback(),
[email protected]2431756e2010-09-29 20:26:13815 pool_.get(),
816 log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09817 EXPECT_TRUE(handle.is_initialized());
818 EXPECT_TRUE(handle.socket());
[email protected]034df0f32013-01-07 23:17:48819 TestLoadTimingInfoConnectedNotReused(handle);
820
[email protected]f6d1d6eb2009-06-24 20:16:09821 handle.Reset();
[email protected]034df0f32013-01-07 23:17:48822 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:30823
[email protected]333bdf62012-06-08 22:57:29824 CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:40825 log.GetEntries(&entries);
826
827 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:46828 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40829 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]9e743cd2010-03-16 07:03:53830 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40831 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:17832 NetLog::PHASE_NONE));
833 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40834 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]9e743cd2010-03-16 07:03:53835 NetLog::PHASE_NONE));
836 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40837 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09838}
839
[email protected]ab838892009-06-30 18:49:05840TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53841 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20842
[email protected]ab838892009-06-30 18:49:05843 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]333bdf62012-06-08 22:57:29844 CapturingBoundNetLog log;
[email protected]9e743cd2010-03-16 07:03:53845
[email protected]2431756e2010-09-29 20:26:13846 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:52847 TestCompletionCallback callback;
[email protected]e60e47a2010-07-14 03:37:18848 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:13849 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43850 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:45851 info.headers = new HttpResponseHeaders(std::string());
[email protected]2431756e2010-09-29 20:26:13852 handle.set_ssl_error_response_info(info);
853 EXPECT_EQ(ERR_CONNECTION_FAILED,
854 handle.Init("a",
855 params_,
[email protected]bb1c4662013-11-14 00:00:07856 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:52857 callback.callback(),
[email protected]2431756e2010-09-29 20:26:13858 pool_.get(),
859 log.bound()));
860 EXPECT_FALSE(handle.socket());
861 EXPECT_FALSE(handle.is_ssl_error());
862 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]034df0f32013-01-07 23:17:48863 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:30864
[email protected]333bdf62012-06-08 22:57:29865 CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:40866 log.GetEntries(&entries);
867
868 EXPECT_EQ(3u, entries.size());
[email protected]5a1d7ca2010-04-28 20:12:27869 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40870 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:17871 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40872 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:17873 NetLog::PHASE_NONE));
[email protected]a2006ece2010-04-23 16:44:02874 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40875 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09876}
877
[email protected]211d21722009-07-22 15:48:53878TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
879 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
880
[email protected]9e743cd2010-03-16 07:03:53881 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30882
[email protected]bb1c4662013-11-14 00:00:07883 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
884 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
885 EXPECT_EQ(OK, StartRequest("c", DEFAULT_PRIORITY));
886 EXPECT_EQ(OK, StartRequest("d", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:53887
[email protected]2431756e2010-09-29 20:26:13888 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53889 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13890 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53891
[email protected]bb1c4662013-11-14 00:00:07892 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", DEFAULT_PRIORITY));
893 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", DEFAULT_PRIORITY));
894 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:53895
[email protected]2431756e2010-09-29 20:26:13896 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53897
[email protected]2431756e2010-09-29 20:26:13898 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53899 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13900 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53901
902 EXPECT_EQ(1, GetOrderOfRequest(1));
903 EXPECT_EQ(2, GetOrderOfRequest(2));
904 EXPECT_EQ(3, GetOrderOfRequest(3));
905 EXPECT_EQ(4, GetOrderOfRequest(4));
906 EXPECT_EQ(5, GetOrderOfRequest(5));
907 EXPECT_EQ(6, GetOrderOfRequest(6));
908 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17909
910 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13911 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53912}
913
914TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
915 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
916
[email protected]9e743cd2010-03-16 07:03:53917 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30918
[email protected]211d21722009-07-22 15:48:53919 // Reach all limits: max total sockets, and max sockets per group.
[email protected]bb1c4662013-11-14 00:00:07920 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
921 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
922 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
923 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:53924
[email protected]2431756e2010-09-29 20:26:13925 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53926 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13927 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53928
929 // Now create a new group and verify that we don't starve it.
[email protected]bb1c4662013-11-14 00:00:07930 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:53931
[email protected]2431756e2010-09-29 20:26:13932 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53933
[email protected]2431756e2010-09-29 20:26:13934 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53935 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13936 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53937
938 EXPECT_EQ(1, GetOrderOfRequest(1));
939 EXPECT_EQ(2, GetOrderOfRequest(2));
940 EXPECT_EQ(3, GetOrderOfRequest(3));
941 EXPECT_EQ(4, GetOrderOfRequest(4));
942 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17943
944 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13945 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53946}
947
948TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
949 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
950
[email protected]ac790b42009-12-02 04:31:31951 EXPECT_EQ(OK, StartRequest("b", LOWEST));
952 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
953 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
954 EXPECT_EQ(OK, StartRequest("a", LOWEST));
[email protected]211d21722009-07-22 15:48:53955
[email protected]2431756e2010-09-29 20:26:13956 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53957 client_socket_factory_.allocation_count());
958
[email protected]ac790b42009-12-02 04:31:31959 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
960 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
961 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53962
[email protected]2431756e2010-09-29 20:26:13963 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53964
[email protected]2431756e2010-09-29 20:26:13965 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53966
967 // First 4 requests don't have to wait, and finish in order.
968 EXPECT_EQ(1, GetOrderOfRequest(1));
969 EXPECT_EQ(2, GetOrderOfRequest(2));
970 EXPECT_EQ(3, GetOrderOfRequest(3));
971 EXPECT_EQ(4, GetOrderOfRequest(4));
972
[email protected]ac790b42009-12-02 04:31:31973 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
974 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53975 EXPECT_EQ(7, GetOrderOfRequest(5));
976 EXPECT_EQ(6, GetOrderOfRequest(6));
977 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17978
979 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13980 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]211d21722009-07-22 15:48:53981}
982
983TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
984 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
985
[email protected]ac790b42009-12-02 04:31:31986 EXPECT_EQ(OK, StartRequest("a", LOWEST));
987 EXPECT_EQ(OK, StartRequest("a", LOW));
988 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
989 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
[email protected]211d21722009-07-22 15:48:53990
[email protected]2431756e2010-09-29 20:26:13991 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53992 client_socket_factory_.allocation_count());
993
[email protected]ac790b42009-12-02 04:31:31994 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
995 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
996 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53997
[email protected]2431756e2010-09-29 20:26:13998 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53999
[email protected]2431756e2010-09-29 20:26:131000 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531001 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131002 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:531003
1004 // First 4 requests don't have to wait, and finish in order.
1005 EXPECT_EQ(1, GetOrderOfRequest(1));
1006 EXPECT_EQ(2, GetOrderOfRequest(2));
1007 EXPECT_EQ(3, GetOrderOfRequest(3));
1008 EXPECT_EQ(4, GetOrderOfRequest(4));
1009
1010 // Request ("b", 7) has the highest priority, but we can't make new socket for
1011 // group "b", because it has reached the per-group limit. Then we make
1012 // socket for ("c", 6), because it has higher priority than ("a", 4),
1013 // and we still can't make a socket for group "b".
1014 EXPECT_EQ(5, GetOrderOfRequest(5));
1015 EXPECT_EQ(6, GetOrderOfRequest(6));
1016 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171017
1018 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131019 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:531020}
1021
1022// Make sure that we count connecting sockets against the total limit.
1023TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
1024 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1025
[email protected]bb1c4662013-11-14 00:00:071026 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1027 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
1028 EXPECT_EQ(OK, StartRequest("c", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:531029
1030 // Create one asynchronous request.
1031 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]bb1c4662013-11-14 00:00:071032 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:531033
[email protected]6b175382009-10-13 06:47:471034 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1035 // actually become pending until 2ms after they have been created. In order
1036 // to flush all tasks, we need to wait so that we know there are no
1037 // soon-to-be-pending tasks waiting.
[email protected]26b9973962012-01-28 00:57:001038 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
[email protected]2da659e2013-05-23 20:51:341039 base::MessageLoop::current()->RunUntilIdle();
[email protected]6b175382009-10-13 06:47:471040
[email protected]211d21722009-07-22 15:48:531041 // The next synchronous request should wait for its turn.
1042 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]bb1c4662013-11-14 00:00:071043 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:531044
[email protected]2431756e2010-09-29 20:26:131045 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531046
[email protected]2431756e2010-09-29 20:26:131047 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531048 client_socket_factory_.allocation_count());
1049
1050 EXPECT_EQ(1, GetOrderOfRequest(1));
1051 EXPECT_EQ(2, GetOrderOfRequest(2));
1052 EXPECT_EQ(3, GetOrderOfRequest(3));
1053 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:171054 EXPECT_EQ(5, GetOrderOfRequest(5));
1055
1056 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131057 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:531058}
1059
[email protected]6427fe22010-04-16 22:27:411060TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
1061 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1062 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1063
[email protected]bb1c4662013-11-14 00:00:071064 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1065 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1066 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1067 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
[email protected]6427fe22010-04-16 22:27:411068
1069 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1070
1071 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1072
[email protected]bb1c4662013-11-14 00:00:071073 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", DEFAULT_PRIORITY));
1074 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", DEFAULT_PRIORITY));
[email protected]6427fe22010-04-16 22:27:411075
1076 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1077
[email protected]2431756e2010-09-29 20:26:131078 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411079 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131080 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411081 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131082 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1083 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411084 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
1085}
1086
[email protected]d7027bb2010-05-10 18:58:541087TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
1088 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1089 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1090
1091 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521092 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131093 EXPECT_EQ(ERR_IO_PENDING,
1094 handle.Init("a",
1095 params_,
[email protected]bb1c4662013-11-14 00:00:071096 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521097 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131098 pool_.get(),
1099 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541100
1101 ClientSocketHandle handles[4];
1102 for (size_t i = 0; i < arraysize(handles); ++i) {
[email protected]6ecf2b92011-12-15 01:14:521103 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131104 EXPECT_EQ(ERR_IO_PENDING,
1105 handles[i].Init("b",
1106 params_,
[email protected]bb1c4662013-11-14 00:00:071107 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521108 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131109 pool_.get(),
1110 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541111 }
1112
1113 // One will be stalled, cancel all the handles now.
1114 // This should hit the OnAvailableSocketSlot() code where we previously had
1115 // stalled groups, but no longer have any.
1116 for (size_t i = 0; i < arraysize(handles); ++i)
1117 handles[i].Reset();
1118}
1119
[email protected]eb5a99382010-07-11 03:18:261120TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:541121 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1122 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1123
[email protected]eb5a99382010-07-11 03:18:261124 {
1125 ClientSocketHandle handles[kDefaultMaxSockets];
[email protected]6ecf2b92011-12-15 01:14:521126 TestCompletionCallback callbacks[kDefaultMaxSockets];
[email protected]eb5a99382010-07-11 03:18:261127 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]2431756e2010-09-29 20:26:131128 EXPECT_EQ(OK, handles[i].Init(base::IntToString(i),
1129 params_,
[email protected]bb1c4662013-11-14 00:00:071130 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521131 callbacks[i].callback(),
[email protected]2431756e2010-09-29 20:26:131132 pool_.get(),
1133 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261134 }
1135
1136 // Force a stalled group.
1137 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521138 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131139 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1140 params_,
[email protected]bb1c4662013-11-14 00:00:071141 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521142 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131143 pool_.get(),
1144 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261145
1146 // Cancel the stalled request.
1147 stalled_handle.Reset();
1148
1149 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1150 EXPECT_EQ(0, pool_->IdleSocketCount());
1151
1152 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541153 }
1154
[email protected]43a21b82010-06-10 21:30:541155 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1156 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:261157}
[email protected]43a21b82010-06-10 21:30:541158
[email protected]eb5a99382010-07-11 03:18:261159TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
1160 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1161 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1162
1163 {
1164 ClientSocketHandle handles[kDefaultMaxSockets];
1165 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521166 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131167 EXPECT_EQ(ERR_IO_PENDING, handles[i].Init(base::IntToString(i),
1168 params_,
[email protected]bb1c4662013-11-14 00:00:071169 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521170 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131171 pool_.get(),
1172 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261173 }
1174
1175 // Force a stalled group.
1176 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1177 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521178 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131179 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1180 params_,
[email protected]bb1c4662013-11-14 00:00:071181 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521182 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131183 pool_.get(),
1184 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261185
1186 // Since it is stalled, it should have no connect jobs.
1187 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101188 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261189
1190 // Cancel the stalled request.
1191 handles[0].Reset();
1192
[email protected]eb5a99382010-07-11 03:18:261193 // Now we should have a connect job.
1194 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101195 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261196
1197 // The stalled socket should connect.
1198 EXPECT_EQ(OK, callback.WaitForResult());
1199
1200 EXPECT_EQ(kDefaultMaxSockets + 1,
1201 client_socket_factory_.allocation_count());
1202 EXPECT_EQ(0, pool_->IdleSocketCount());
1203 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101204 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261205
1206 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541207 }
1208
[email protected]eb5a99382010-07-11 03:18:261209 EXPECT_EQ(1, pool_->IdleSocketCount());
1210}
[email protected]43a21b82010-06-10 21:30:541211
[email protected]eb5a99382010-07-11 03:18:261212TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1213 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1214 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:541215
[email protected]eb5a99382010-07-11 03:18:261216 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521217 TestCompletionCallback callback;
[email protected]eb5a99382010-07-11 03:18:261218 {
[email protected]51fdc7c2012-04-10 19:19:481219 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261220 ClientSocketHandle handles[kDefaultMaxSockets];
1221 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521222 TestCompletionCallback callback;
[email protected]1870d5cf2011-05-12 01:55:401223 EXPECT_EQ(OK, handles[i].Init(base::StringPrintf(
1224 "Take 2: %d", i),
1225 params_,
[email protected]bb1c4662013-11-14 00:00:071226 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521227 callback.callback(),
[email protected]1870d5cf2011-05-12 01:55:401228 pool_.get(),
1229 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261230 }
1231
1232 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1233 EXPECT_EQ(0, pool_->IdleSocketCount());
[email protected]51fdc7c2012-04-10 19:19:481234 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261235
1236 // Now we will hit the socket limit.
[email protected]2431756e2010-09-29 20:26:131237 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1238 params_,
[email protected]bb1c4662013-11-14 00:00:071239 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521240 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131241 pool_.get(),
1242 BoundNetLog()));
[email protected]51fdc7c2012-04-10 19:19:481243 EXPECT_TRUE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261244
1245 // Dropping out of scope will close all handles and return them to idle.
1246 }
[email protected]43a21b82010-06-10 21:30:541247
1248 // But if we wait for it, the released idle sockets will be closed in
1249 // preference of the waiting request.
[email protected]8ae03f42010-07-07 19:08:101250 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]eb5a99382010-07-11 03:18:261251
1252 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1253 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:541254}
1255
1256// Regression test for http://crbug.com/40952.
1257TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1258 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]06d94042010-08-25 01:45:221259 pool_->EnableConnectBackupJobs();
[email protected]43a21b82010-06-10 21:30:541260 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1261
1262 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1263 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521264 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131265 EXPECT_EQ(OK, handle.Init(base::IntToString(i),
1266 params_,
[email protected]bb1c4662013-11-14 00:00:071267 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521268 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131269 pool_.get(),
1270 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541271 }
1272
1273 // Flush all the DoReleaseSocket tasks.
[email protected]2da659e2013-05-23 20:51:341274 base::MessageLoop::current()->RunUntilIdle();
[email protected]43a21b82010-06-10 21:30:541275
1276 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1277 // reuse a socket.
1278 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1279 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521280 TestCompletionCallback callback;
[email protected]43a21b82010-06-10 21:30:541281
1282 // "0" is special here, since it should be the first entry in the sorted map,
1283 // which is the one which we would close an idle socket for. We shouldn't
1284 // close an idle socket though, since we should reuse the idle socket.
[email protected]2431756e2010-09-29 20:26:131285 EXPECT_EQ(OK, handle.Init("0",
1286 params_,
[email protected]bb1c4662013-11-14 00:00:071287 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521288 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131289 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211290 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541291
1292 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1293 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1294}
1295
[email protected]ab838892009-06-30 18:49:051296TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531297 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091298
[email protected]bb1c4662013-11-14 00:00:071299 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1300 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
[email protected]c9c6f5c2010-07-31 01:30:031301 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", IDLE));
[email protected]ac790b42009-12-02 04:31:311302 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1303 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1304 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1305 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1306 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091307
[email protected]2431756e2010-09-29 20:26:131308 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091309
[email protected]c9d6a1d2009-07-14 16:15:201310 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1311 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
[email protected]c9d6a1d2009-07-14 16:15:201315 EXPECT_EQ(1, GetOrderOfRequest(1));
1316 EXPECT_EQ(2, GetOrderOfRequest(2));
[email protected]c9c6f5c2010-07-31 01:30:031317 EXPECT_EQ(8, GetOrderOfRequest(3));
1318 EXPECT_EQ(6, GetOrderOfRequest(4));
1319 EXPECT_EQ(4, GetOrderOfRequest(5));
1320 EXPECT_EQ(3, GetOrderOfRequest(6));
1321 EXPECT_EQ(5, GetOrderOfRequest(7));
1322 EXPECT_EQ(7, GetOrderOfRequest(8));
[email protected]75439d3b2009-07-23 22:11:171323
1324 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131325 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]f6d1d6eb2009-06-24 20:16:091326}
1327
[email protected]ab838892009-06-30 18:49:051328TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531329 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091330
[email protected]bb1c4662013-11-14 00:00:071331 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1332 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
[email protected]ac790b42009-12-02 04:31:311333 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1334 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1335 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1336 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1337 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091338
[email protected]2431756e2010-09-29 20:26:131339 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091340
[email protected]2431756e2010-09-29 20:26:131341 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
1342 EXPECT_EQ(OK, request(i)->WaitForResult());
[email protected]c9d6a1d2009-07-14 16:15:201343
[email protected]2431756e2010-09-29 20:26:131344 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]c9d6a1d2009-07-14 16:15:201345 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131346 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1347 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091348}
1349
1350// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:051351// The pending connect job will be cancelled and should not call back into
1352// ClientSocketPoolBase.
1353TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531354 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201355
[email protected]ab838892009-06-30 18:49:051356 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131357 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521358 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131359 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1360 params_,
[email protected]bb1c4662013-11-14 00:00:071361 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521362 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131363 pool_.get(),
1364 BoundNetLog()));
1365 handle.Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091366}
1367
[email protected]ab838892009-06-30 18:49:051368TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531369 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201370
[email protected]ab838892009-06-30 18:49:051371 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061372 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521373 TestCompletionCallback callback;
[email protected]f6d1d6eb2009-06-24 20:16:091374
[email protected]2431756e2010-09-29 20:26:131375 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1376 params_,
[email protected]bb1c4662013-11-14 00:00:071377 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521378 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131379 pool_.get(),
1380 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091381
1382 handle.Reset();
1383
[email protected]6ecf2b92011-12-15 01:14:521384 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:131385 EXPECT_EQ(ERR_IO_PENDING,
1386 handle.Init("a",
1387 params_,
[email protected]bb1c4662013-11-14 00:00:071388 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521389 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:131390 pool_.get(),
1391 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091392
1393 EXPECT_EQ(OK, callback2.WaitForResult());
1394 EXPECT_FALSE(callback.have_result());
1395
1396 handle.Reset();
1397}
1398
[email protected]ab838892009-06-30 18:49:051399TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531400 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091401
[email protected]bb1c4662013-11-14 00:00:071402 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1403 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
[email protected]ac790b42009-12-02 04:31:311404 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1405 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1406 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1407 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1408 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091409
1410 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201411 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]2431756e2010-09-29 20:26:131412 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1413 (*requests())[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091414
[email protected]2431756e2010-09-29 20:26:131415 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091416
[email protected]c9d6a1d2009-07-14 16:15:201417 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1418 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131419 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1420 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091421
[email protected]c9d6a1d2009-07-14 16:15:201422 EXPECT_EQ(1, GetOrderOfRequest(1));
1423 EXPECT_EQ(2, GetOrderOfRequest(2));
1424 EXPECT_EQ(5, GetOrderOfRequest(3));
1425 EXPECT_EQ(3, GetOrderOfRequest(4));
[email protected]2431756e2010-09-29 20:26:131426 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1427 GetOrderOfRequest(5)); // Canceled request.
[email protected]c9d6a1d2009-07-14 16:15:201428 EXPECT_EQ(4, GetOrderOfRequest(6));
1429 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171430
1431 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131432 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091433}
1434
[email protected]6ecf2b92011-12-15 01:14:521435class RequestSocketCallback : public TestCompletionCallbackBase {
[email protected]f6d1d6eb2009-06-24 20:16:091436 public:
[email protected]2ab05b52009-07-01 23:57:581437 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:241438 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:581439 TestConnectJobFactory* test_connect_job_factory,
1440 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:091441 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:061442 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:581443 within_callback_(false),
1444 test_connect_job_factory_(test_connect_job_factory),
[email protected]6ecf2b92011-12-15 01:14:521445 next_job_type_(next_job_type),
[email protected]aa249b52013-04-30 01:04:321446 callback_(base::Bind(&RequestSocketCallback::OnComplete,
1447 base::Unretained(this))) {
[email protected]6ecf2b92011-12-15 01:14:521448 }
[email protected]f6d1d6eb2009-06-24 20:16:091449
dchengb03027d2014-10-21 12:00:201450 ~RequestSocketCallback() override {}
[email protected]6ecf2b92011-12-15 01:14:521451
1452 const CompletionCallback& callback() const { return callback_; }
1453
1454 private:
1455 void OnComplete(int result) {
1456 SetResult(result);
1457 ASSERT_EQ(OK, result);
[email protected]f6d1d6eb2009-06-24 20:16:091458
1459 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:581460 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]5edbf8d2010-01-13 18:44:111461
1462 // Don't allow reuse of the socket. Disconnect it and then release it and
1463 // run through the MessageLoop once to get it completely released.
1464 handle_->socket()->Disconnect();
[email protected]f6d1d6eb2009-06-24 20:16:091465 handle_->Reset();
[email protected]5edbf8d2010-01-13 18:44:111466 {
[email protected]b5717a42012-02-14 19:33:521467 // TODO: Resolve conflicting intentions of stopping recursion with the
[email protected]b4c62eb2012-11-14 18:36:511468 // |!within_callback_| test (above) and the call to |RunUntilIdle()|
[email protected]b5717a42012-02-14 19:33:521469 // below. http://crbug.com/114130.
[email protected]2da659e2013-05-23 20:51:341470 base::MessageLoop::ScopedNestableTaskAllower allow(
1471 base::MessageLoop::current());
1472 base::MessageLoop::current()->RunUntilIdle();
[email protected]5edbf8d2010-01-13 18:44:111473 }
[email protected]f6d1d6eb2009-06-24 20:16:091474 within_callback_ = true;
[email protected]6ecf2b92011-12-15 01:14:521475 TestCompletionCallback next_job_callback;
[email protected]bb1c4662013-11-14 00:00:071476 scoped_refptr<TestSocketParams> params(
1477 new TestSocketParams(false /* ignore_limits */));
[email protected]2431756e2010-09-29 20:26:131478 int rv = handle_->Init("a",
1479 params,
[email protected]bb1c4662013-11-14 00:00:071480 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521481 next_job_callback.callback(),
[email protected]2431756e2010-09-29 20:26:131482 pool_,
1483 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581484 switch (next_job_type_) {
1485 case TestConnectJob::kMockJob:
1486 EXPECT_EQ(OK, rv);
1487 break;
1488 case TestConnectJob::kMockPendingJob:
1489 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:471490
1491 // For pending jobs, wait for new socket to be created. This makes
1492 // sure there are no more pending operations nor any unclosed sockets
1493 // when the test finishes.
1494 // We need to give it a little bit of time to run, so that all the
1495 // operations that happen on timers (e.g. cleanup of idle
1496 // connections) can execute.
[email protected]5edbf8d2010-01-13 18:44:111497 {
[email protected]2da659e2013-05-23 20:51:341498 base::MessageLoop::ScopedNestableTaskAllower allow(
1499 base::MessageLoop::current());
[email protected]26b9973962012-01-28 00:57:001500 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
[email protected]5edbf8d2010-01-13 18:44:111501 EXPECT_EQ(OK, next_job_callback.WaitForResult());
1502 }
[email protected]2ab05b52009-07-01 23:57:581503 break;
1504 default:
1505 FAIL() << "Unexpected job type: " << next_job_type_;
1506 break;
1507 }
[email protected]f6d1d6eb2009-06-24 20:16:091508 }
1509 }
1510
[email protected]f6d1d6eb2009-06-24 20:16:091511 ClientSocketHandle* const handle_;
[email protected]2431756e2010-09-29 20:26:131512 TestClientSocketPool* const pool_;
[email protected]f6d1d6eb2009-06-24 20:16:091513 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:581514 TestConnectJobFactory* const test_connect_job_factory_;
1515 TestConnectJob::JobType next_job_type_;
[email protected]6ecf2b92011-12-15 01:14:521516 CompletionCallback callback_;
[email protected]f6d1d6eb2009-06-24 20:16:091517};
1518
[email protected]2ab05b52009-07-01 23:57:581519TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531520 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201521
[email protected]0b7648c2009-07-06 20:14:011522 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061523 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581524 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061525 &handle, pool_.get(), connect_job_factory_,
1526 TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131527 int rv = handle.Init("a",
1528 params_,
[email protected]bb1c4662013-11-14 00:00:071529 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521530 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131531 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211532 BoundNetLog());
[email protected]f6d1d6eb2009-06-24 20:16:091533 ASSERT_EQ(ERR_IO_PENDING, rv);
1534
1535 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581536}
[email protected]f6d1d6eb2009-06-24 20:16:091537
[email protected]2ab05b52009-07-01 23:57:581538TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531539 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201540
[email protected]0b7648c2009-07-06 20:14:011541 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061542 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581543 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061544 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]2431756e2010-09-29 20:26:131545 int rv = handle.Init("a",
1546 params_,
[email protected]bb1c4662013-11-14 00:00:071547 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521548 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131549 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211550 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581551 ASSERT_EQ(ERR_IO_PENDING, rv);
1552
1553 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091554}
1555
1556// Make sure that pending requests get serviced after active requests get
1557// cancelled.
[email protected]ab838892009-06-30 18:49:051558TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531559 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201560
[email protected]0b7648c2009-07-06 20:14:011561 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091562
[email protected]bb1c4662013-11-14 00:00:071563 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1564 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1565 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1566 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1567 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1568 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1569 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
[email protected]f6d1d6eb2009-06-24 20:16:091570
[email protected]c9d6a1d2009-07-14 16:15:201571 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1572 // Let's cancel them.
1573 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]2431756e2010-09-29 20:26:131574 ASSERT_FALSE(request(i)->handle()->is_initialized());
1575 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091576 }
1577
[email protected]f6d1d6eb2009-06-24 20:16:091578 // Let's wait for the rest to complete now.
[email protected]2431756e2010-09-29 20:26:131579 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
1580 EXPECT_EQ(OK, request(i)->WaitForResult());
1581 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091582 }
1583
[email protected]2431756e2010-09-29 20:26:131584 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1585 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091586}
1587
1588// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051589TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531590 const size_t kMaxSockets = 5;
1591 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201592
[email protected]0b7648c2009-07-06 20:14:011593 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091594
[email protected]211d21722009-07-22 15:48:531595 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1596 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091597
1598 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531599 for (size_t i = 0; i < kNumberOfRequests; ++i)
[email protected]bb1c4662013-11-14 00:00:071600 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
[email protected]f6d1d6eb2009-06-24 20:16:091601
[email protected]211d21722009-07-22 15:48:531602 for (size_t i = 0; i < kNumberOfRequests; ++i)
[email protected]2431756e2010-09-29 20:26:131603 EXPECT_EQ(ERR_CONNECTION_FAILED, request(i)->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091604}
1605
[email protected]5fc08e32009-07-15 17:09:571606TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531607 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571608
1609 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1610
[email protected]2431756e2010-09-29 20:26:131611 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521612 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131613 int rv = handle.Init("a",
1614 params_,
[email protected]bb1c4662013-11-14 00:00:071615 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521616 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131617 pool_.get(),
1618 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571619 EXPECT_EQ(ERR_IO_PENDING, rv);
1620
1621 // Cancel the active request.
[email protected]2431756e2010-09-29 20:26:131622 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571623
[email protected]2431756e2010-09-29 20:26:131624 rv = handle.Init("a",
1625 params_,
[email protected]bb1c4662013-11-14 00:00:071626 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521627 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131628 pool_.get(),
1629 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571630 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131631 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]5fc08e32009-07-15 17:09:571632
[email protected]2431756e2010-09-29 20:26:131633 EXPECT_FALSE(handle.is_reused());
[email protected]034df0f32013-01-07 23:17:481634 TestLoadTimingInfoConnectedNotReused(handle);
[email protected]5fc08e32009-07-15 17:09:571635 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1636}
1637
[email protected]2b7523d2009-07-29 20:29:231638// Regression test for http://crbug.com/17985.
1639TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1640 const int kMaxSockets = 3;
1641 const int kMaxSocketsPerGroup = 2;
1642 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1643
[email protected]ac790b42009-12-02 04:31:311644 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231645
[email protected]bb1c4662013-11-14 00:00:071646 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1647 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
[email protected]2b7523d2009-07-29 20:29:231648
1649 // This is going to be a pending request in an otherwise empty group.
[email protected]bb1c4662013-11-14 00:00:071650 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
[email protected]2b7523d2009-07-29 20:29:231651
1652 // Reach the maximum socket limit.
[email protected]bb1c4662013-11-14 00:00:071653 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
[email protected]2b7523d2009-07-29 20:29:231654
1655 // Create a stalled group with high priorities.
1656 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1657 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
[email protected]2b7523d2009-07-29 20:29:231658
[email protected]eb5a99382010-07-11 03:18:261659 // Release the first two sockets from "a". Because this is a keepalive,
1660 // the first release will unblock the pending request for "a". The
1661 // second release will unblock a request for "c", becaue it is the next
1662 // high priority socket.
[email protected]2431756e2010-09-29 20:26:131663 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1664 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]2b7523d2009-07-29 20:29:231665
1666 // Closing idle sockets should not get us into trouble, but in the bug
1667 // we were hitting a CHECK here.
[email protected]93054cc12010-06-08 06:12:411668 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]43a21b82010-06-10 21:30:541669 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261670
[email protected]2da659e2013-05-23 20:51:341671 // Run the released socket wakeups.
1672 base::MessageLoop::current()->RunUntilIdle();
[email protected]2b7523d2009-07-29 20:29:231673}
1674
[email protected]4d3b05d2010-01-27 21:27:291675TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531676 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571677
1678 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131679 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521680 TestCompletionCallback callback;
[email protected]333bdf62012-06-08 22:57:291681 CapturingBoundNetLog log;
[email protected]2431756e2010-09-29 20:26:131682 int rv = handle.Init("a",
1683 params_,
1684 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:521685 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131686 pool_.get(),
1687 log.bound());
[email protected]5fc08e32009-07-15 17:09:571688 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131689 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
[email protected]034df0f32013-01-07 23:17:481690 TestLoadTimingInfoNotConnected(handle);
1691
[email protected]2431756e2010-09-29 20:26:131692 EXPECT_EQ(OK, callback.WaitForResult());
1693 EXPECT_TRUE(handle.is_initialized());
1694 EXPECT_TRUE(handle.socket());
[email protected]034df0f32013-01-07 23:17:481695 TestLoadTimingInfoConnectedNotReused(handle);
1696
[email protected]2431756e2010-09-29 20:26:131697 handle.Reset();
[email protected]034df0f32013-01-07 23:17:481698 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:301699
[email protected]333bdf62012-06-08 22:57:291700 CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:401701 log.GetEntries(&entries);
1702
1703 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:461704 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401705 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171706 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401707 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171708 NetLog::PHASE_NONE));
1709 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401710 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]06650c52010-06-03 00:49:171711 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:461712 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401713 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571714}
1715
[email protected]4d3b05d2010-01-27 21:27:291716TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571717 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531718 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571719
1720 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2431756e2010-09-29 20:26:131721 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521722 TestCompletionCallback callback;
[email protected]333bdf62012-06-08 22:57:291723 CapturingBoundNetLog log;
[email protected]e60e47a2010-07-14 03:37:181724 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:131725 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:431726 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:451727 info.headers = new HttpResponseHeaders(std::string());
[email protected]2431756e2010-09-29 20:26:131728 handle.set_ssl_error_response_info(info);
1729 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1730 params_,
[email protected]bb1c4662013-11-14 00:00:071731 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521732 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131733 pool_.get(),
1734 log.bound()));
1735 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1736 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1737 EXPECT_FALSE(handle.is_ssl_error());
1738 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:301739
[email protected]333bdf62012-06-08 22:57:291740 CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:401741 log.GetEntries(&entries);
1742
1743 EXPECT_EQ(3u, entries.size());
[email protected]e9002a92010-01-29 07:10:461744 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401745 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171746 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401747 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171748 NetLog::PHASE_NONE));
[email protected]6b624c62010-03-14 08:37:321749 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401750 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571751}
1752
mmenke6be122f2015-03-09 22:22:471753// Check that an async ConnectJob failure does not result in creation of a new
1754// ConnectJob when there's another pending request also waiting on its own
1755// ConnectJob. See http://crbug.com/463960.
1756TEST_F(ClientSocketPoolBaseTest, AsyncFailureWithPendingRequestWithJob) {
1757 CreatePool(2, 2);
1758 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1759
1760 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1761 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1762
1763 EXPECT_EQ(ERR_CONNECTION_FAILED, request(0)->WaitForResult());
1764 EXPECT_EQ(ERR_CONNECTION_FAILED, request(1)->WaitForResult());
1765
1766 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1767}
1768
[email protected]4d3b05d2010-01-27 21:27:291769TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101770 // TODO(eroman): Add back the log expectations! Removed them because the
1771 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531772 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571773
1774 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131775 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521776 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131777 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:521778 TestCompletionCallback callback2;
[email protected]5fc08e32009-07-15 17:09:571779
[email protected]2431756e2010-09-29 20:26:131780 EXPECT_EQ(ERR_IO_PENDING,
1781 handle.Init("a",
1782 params_,
[email protected]bb1c4662013-11-14 00:00:071783 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521784 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131785 pool_.get(),
1786 BoundNetLog()));
[email protected]333bdf62012-06-08 22:57:291787 CapturingBoundNetLog log2;
[email protected]2431756e2010-09-29 20:26:131788 EXPECT_EQ(ERR_IO_PENDING,
1789 handle2.Init("a",
1790 params_,
[email protected]bb1c4662013-11-14 00:00:071791 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521792 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:131793 pool_.get(),
1794 BoundNetLog()));
[email protected]5fc08e32009-07-15 17:09:571795
[email protected]2431756e2010-09-29 20:26:131796 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571797
[email protected]fd7b7c92009-08-20 19:38:301798
1799 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301800
[email protected]2431756e2010-09-29 20:26:131801 EXPECT_EQ(OK, callback2.WaitForResult());
1802 handle2.Reset();
[email protected]fd7b7c92009-08-20 19:38:301803
1804 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531805 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571806}
1807
[email protected]4d3b05d2010-01-27 21:27:291808TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341809 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1810
[email protected]17a0c6c2009-08-04 00:07:041811 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1812
[email protected]ac790b42009-12-02 04:31:311813 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1814 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1815 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1816 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341817
1818 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]2431756e2010-09-29 20:26:131819 (*requests())[2]->handle()->Reset();
1820 (*requests())[3]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341821 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1822
[email protected]2431756e2010-09-29 20:26:131823 (*requests())[1]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341824 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1825
[email protected]2431756e2010-09-29 20:26:131826 (*requests())[0]->handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261827 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]974ebd62009-08-03 23:14:341828}
1829
[email protected]5fc08e32009-07-15 17:09:571830// When requests and ConnectJobs are not coupled, the request will get serviced
1831// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291832TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531833 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571834
1835 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321836 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571837
[email protected]2431756e2010-09-29 20:26:131838 std::vector<TestSocketRequest*> request_order;
1839 size_t completion_count; // unused
1840 TestSocketRequest req1(&request_order, &completion_count);
1841 int rv = req1.handle()->Init("a",
1842 params_,
[email protected]bb1c4662013-11-14 00:00:071843 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521844 req1.callback(), pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211845 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571846 EXPECT_EQ(ERR_IO_PENDING, rv);
1847 EXPECT_EQ(OK, req1.WaitForResult());
1848
1849 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1850 // without a job.
1851 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1852
[email protected]2431756e2010-09-29 20:26:131853 TestSocketRequest req2(&request_order, &completion_count);
1854 rv = req2.handle()->Init("a",
1855 params_,
[email protected]bb1c4662013-11-14 00:00:071856 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521857 req2.callback(),
[email protected]2431756e2010-09-29 20:26:131858 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211859 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571860 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131861 TestSocketRequest req3(&request_order, &completion_count);
1862 rv = req3.handle()->Init("a",
1863 params_,
[email protected]bb1c4662013-11-14 00:00:071864 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521865 req3.callback(),
[email protected]2431756e2010-09-29 20:26:131866 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211867 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571868 EXPECT_EQ(ERR_IO_PENDING, rv);
1869
1870 // Both Requests 2 and 3 are pending. We release socket 1 which should
1871 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331872 req1.handle()->Reset();
[email protected]2da659e2013-05-23 20:51:341873 // Run the released socket wakeups.
1874 base::MessageLoop::current()->RunUntilIdle();
[email protected]a6c59f62009-07-29 16:33:331875 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571876 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331877 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571878
1879 // Signal job 2, which should service request 3.
1880
1881 client_socket_factory_.SignalJobs();
1882 EXPECT_EQ(OK, req3.WaitForResult());
1883
[email protected]2431756e2010-09-29 20:26:131884 ASSERT_EQ(3U, request_order.size());
1885 EXPECT_EQ(&req1, request_order[0]);
1886 EXPECT_EQ(&req2, request_order[1]);
1887 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571888 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1889}
1890
1891// The requests are not coupled to the jobs. So, the requests should finish in
1892// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:291893TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531894 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571895 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321896 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571897
[email protected]2431756e2010-09-29 20:26:131898 std::vector<TestSocketRequest*> request_order;
1899 size_t completion_count; // unused
1900 TestSocketRequest req1(&request_order, &completion_count);
1901 int rv = req1.handle()->Init("a",
1902 params_,
[email protected]bb1c4662013-11-14 00:00:071903 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521904 req1.callback(),
[email protected]2431756e2010-09-29 20:26:131905 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211906 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571907 EXPECT_EQ(ERR_IO_PENDING, rv);
1908
[email protected]2431756e2010-09-29 20:26:131909 TestSocketRequest req2(&request_order, &completion_count);
1910 rv = req2.handle()->Init("a",
1911 params_,
[email protected]bb1c4662013-11-14 00:00:071912 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521913 req2.callback(),
[email protected]2431756e2010-09-29 20:26:131914 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211915 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571916 EXPECT_EQ(ERR_IO_PENDING, rv);
1917
1918 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321919 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571920
[email protected]2431756e2010-09-29 20:26:131921 TestSocketRequest req3(&request_order, &completion_count);
1922 rv = req3.handle()->Init("a",
1923 params_,
[email protected]bb1c4662013-11-14 00:00:071924 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521925 req3.callback(),
[email protected]2431756e2010-09-29 20:26:131926 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211927 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571928 EXPECT_EQ(ERR_IO_PENDING, rv);
1929
1930 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1931 EXPECT_EQ(OK, req2.WaitForResult());
1932 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1933
[email protected]2431756e2010-09-29 20:26:131934 ASSERT_EQ(3U, request_order.size());
1935 EXPECT_EQ(&req1, request_order[0]);
1936 EXPECT_EQ(&req2, request_order[1]);
1937 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571938}
1939
[email protected]03b7c8c2013-07-20 04:38:551940// Test GetLoadState in the case there's only one socket request.
1941TEST_F(ClientSocketPoolBaseTest, LoadStateOneRequest) {
[email protected]211d21722009-07-22 15:48:531942 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]03b7c8c2013-07-20 04:38:551943 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]5fc08e32009-07-15 17:09:571944
[email protected]2431756e2010-09-29 20:26:131945 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521946 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131947 int rv = handle.Init("a",
1948 params_,
[email protected]bb1c4662013-11-14 00:00:071949 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521950 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131951 pool_.get(),
1952 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571953 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]03b7c8c2013-07-20 04:38:551954 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571955
[email protected]03b7c8c2013-07-20 04:38:551956 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
1957 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
1958
1959 // No point in completing the connection, since ClientSocketHandles only
1960 // expect the LoadState to be checked while connecting.
1961}
1962
1963// Test GetLoadState in the case there are two socket requests.
1964TEST_F(ClientSocketPoolBaseTest, LoadStateTwoRequests) {
1965 CreatePool(2, 2);
1966 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1967
1968 ClientSocketHandle handle;
1969 TestCompletionCallback callback;
1970 int rv = handle.Init("a",
1971 params_,
[email protected]bb1c4662013-11-14 00:00:071972 DEFAULT_PRIORITY,
[email protected]03b7c8c2013-07-20 04:38:551973 callback.callback(),
1974 pool_.get(),
1975 BoundNetLog());
1976 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]5fc08e32009-07-15 17:09:571977
[email protected]2431756e2010-09-29 20:26:131978 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:521979 TestCompletionCallback callback2;
[email protected]03b7c8c2013-07-20 04:38:551980 rv = handle2.Init("a",
1981 params_,
[email protected]bb1c4662013-11-14 00:00:071982 DEFAULT_PRIORITY,
[email protected]03b7c8c2013-07-20 04:38:551983 callback2.callback(),
1984 pool_.get(),
1985 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571986 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]03b7c8c2013-07-20 04:38:551987
1988 // If the first Job is in an earlier state than the second, the state of
1989 // the second job should be used for both handles.
1990 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
1991 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
1992 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
1993
1994 // If the second Job is in an earlier state than the second, the state of
1995 // the first job should be used for both handles.
1996 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
1997 // One request is farther
1998 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
1999 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle2.GetLoadState());
2000
2001 // Farthest along job connects and the first request gets the socket. The
2002 // second handle switches to the state of the remaining ConnectJob.
2003 client_socket_factory_.SignalJob(0);
2004 EXPECT_EQ(OK, callback.WaitForResult());
2005 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
2006}
2007
2008// Test GetLoadState in the case the per-group limit is reached.
2009TEST_F(ClientSocketPoolBaseTest, LoadStateGroupLimit) {
2010 CreatePool(2, 1);
2011 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2012
2013 ClientSocketHandle handle;
2014 TestCompletionCallback callback;
2015 int rv = handle.Init("a",
2016 params_,
2017 MEDIUM,
2018 callback.callback(),
2019 pool_.get(),
2020 BoundNetLog());
2021 EXPECT_EQ(ERR_IO_PENDING, rv);
2022 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2023
2024 // Request another socket from the same pool, buth with a higher priority.
2025 // The first request should now be stalled at the socket group limit.
2026 ClientSocketHandle handle2;
2027 TestCompletionCallback callback2;
2028 rv = handle2.Init("a",
2029 params_,
2030 HIGHEST,
2031 callback2.callback(),
2032 pool_.get(),
2033 BoundNetLog());
2034 EXPECT_EQ(ERR_IO_PENDING, rv);
2035 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2036 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
2037
2038 // The first handle should remain stalled as the other socket goes through
2039 // the connect process.
2040
2041 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2042 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2043 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle2.GetLoadState());
2044
2045 client_socket_factory_.SignalJob(0);
2046 EXPECT_EQ(OK, callback2.WaitForResult());
2047 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2048
2049 // Closing the second socket should cause the stalled handle to finally get a
2050 // ConnectJob.
2051 handle2.socket()->Disconnect();
2052 handle2.Reset();
2053 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2054}
2055
2056// Test GetLoadState in the case the per-pool limit is reached.
2057TEST_F(ClientSocketPoolBaseTest, LoadStatePoolLimit) {
2058 CreatePool(2, 2);
2059 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2060
2061 ClientSocketHandle handle;
2062 TestCompletionCallback callback;
2063 int rv = handle.Init("a",
2064 params_,
[email protected]bb1c4662013-11-14 00:00:072065 DEFAULT_PRIORITY,
[email protected]03b7c8c2013-07-20 04:38:552066 callback.callback(),
2067 pool_.get(),
2068 BoundNetLog());
2069 EXPECT_EQ(ERR_IO_PENDING, rv);
2070
2071 // Request for socket from another pool.
2072 ClientSocketHandle handle2;
2073 TestCompletionCallback callback2;
2074 rv = handle2.Init("b",
2075 params_,
[email protected]bb1c4662013-11-14 00:00:072076 DEFAULT_PRIORITY,
[email protected]03b7c8c2013-07-20 04:38:552077 callback2.callback(),
2078 pool_.get(),
2079 BoundNetLog());
2080 EXPECT_EQ(ERR_IO_PENDING, rv);
2081
2082 // Request another socket from the first pool. Request should stall at the
2083 // socket pool limit.
2084 ClientSocketHandle handle3;
2085 TestCompletionCallback callback3;
2086 rv = handle3.Init("a",
2087 params_,
[email protected]bb1c4662013-11-14 00:00:072088 DEFAULT_PRIORITY,
[email protected]03b7c8c2013-07-20 04:38:552089 callback2.callback(),
2090 pool_.get(),
2091 BoundNetLog());
2092 EXPECT_EQ(ERR_IO_PENDING, rv);
2093
2094 // The third handle should remain stalled as the other sockets in its group
2095 // goes through the connect process.
2096
2097 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2098 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2099
2100 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2101 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
2102 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2103
2104 client_socket_factory_.SignalJob(0);
2105 EXPECT_EQ(OK, callback.WaitForResult());
2106 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2107
2108 // Closing a socket should allow the stalled handle to finally get a new
2109 // ConnectJob.
2110 handle.socket()->Disconnect();
2111 handle.Reset();
2112 EXPECT_EQ(LOAD_STATE_CONNECTING, handle3.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:572113}
2114
[email protected]e772db3f2010-07-12 18:11:132115TEST_F(ClientSocketPoolBaseTest, Recoverable) {
2116 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2117 connect_job_factory_->set_job_type(TestConnectJob::kMockRecoverableJob);
2118
[email protected]2431756e2010-09-29 20:26:132119 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522120 TestCompletionCallback callback;
2121 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED,
[email protected]bb1c4662013-11-14 00:00:072122 handle.Init("a", params_, DEFAULT_PRIORITY, callback.callback(),
[email protected]6ecf2b92011-12-15 01:14:522123 pool_.get(), BoundNetLog()));
[email protected]2431756e2010-09-29 20:26:132124 EXPECT_TRUE(handle.is_initialized());
2125 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:132126}
2127
2128TEST_F(ClientSocketPoolBaseTest, AsyncRecoverable) {
2129 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2130
2131 connect_job_factory_->set_job_type(
2132 TestConnectJob::kMockPendingRecoverableJob);
[email protected]2431756e2010-09-29 20:26:132133 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522134 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132135 EXPECT_EQ(ERR_IO_PENDING,
2136 handle.Init("a",
2137 params_,
[email protected]bb1c4662013-11-14 00:00:072138 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522139 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132140 pool_.get(),
2141 BoundNetLog()));
2142 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2143 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, callback.WaitForResult());
2144 EXPECT_TRUE(handle.is_initialized());
2145 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:132146}
2147
[email protected]e60e47a2010-07-14 03:37:182148TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
2149 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2150 connect_job_factory_->set_job_type(
2151 TestConnectJob::kMockAdditionalErrorStateJob);
2152
[email protected]2431756e2010-09-29 20:26:132153 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522154 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132155 EXPECT_EQ(ERR_CONNECTION_FAILED,
2156 handle.Init("a",
2157 params_,
[email protected]bb1c4662013-11-14 00:00:072158 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522159 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132160 pool_.get(),
2161 BoundNetLog()));
2162 EXPECT_FALSE(handle.is_initialized());
2163 EXPECT_FALSE(handle.socket());
2164 EXPECT_TRUE(handle.is_ssl_error());
2165 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182166}
2167
2168TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
2169 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2170
2171 connect_job_factory_->set_job_type(
2172 TestConnectJob::kMockPendingAdditionalErrorStateJob);
[email protected]2431756e2010-09-29 20:26:132173 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522174 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132175 EXPECT_EQ(ERR_IO_PENDING,
2176 handle.Init("a",
2177 params_,
[email protected]bb1c4662013-11-14 00:00:072178 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522179 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132180 pool_.get(),
2181 BoundNetLog()));
2182 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2183 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
2184 EXPECT_FALSE(handle.is_initialized());
2185 EXPECT_FALSE(handle.socket());
2186 EXPECT_TRUE(handle.is_ssl_error());
2187 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182188}
2189
[email protected]e7b1c6d2c2012-05-05 00:54:032190// Make sure we can reuse sockets when the cleanup timer is disabled.
2191TEST_F(ClientSocketPoolBaseTest, DisableCleanupTimerReuse) {
[email protected]64770b7d2011-11-16 04:30:412192 // Disable cleanup timer.
2193 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(false);
2194
2195 CreatePoolWithIdleTimeouts(
2196 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
[email protected]e7b1c6d2c2012-05-05 00:54:032197 base::TimeDelta(), // Time out unused sockets immediately.
2198 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2199
2200 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2201
2202 ClientSocketHandle handle;
2203 TestCompletionCallback callback;
2204 int rv = handle.Init("a",
2205 params_,
2206 LOWEST,
2207 callback.callback(),
2208 pool_.get(),
2209 BoundNetLog());
2210 ASSERT_EQ(ERR_IO_PENDING, rv);
2211 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2212 ASSERT_EQ(OK, callback.WaitForResult());
2213
2214 // Use and release the socket.
2215 EXPECT_EQ(1, handle.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]034df0f32013-01-07 23:17:482216 TestLoadTimingInfoConnectedNotReused(handle);
[email protected]e7b1c6d2c2012-05-05 00:54:032217 handle.Reset();
2218
2219 // Should now have one idle socket.
2220 ASSERT_EQ(1, pool_->IdleSocketCount());
2221
2222 // Request a new socket. This should reuse the old socket and complete
2223 // synchronously.
[email protected]333bdf62012-06-08 22:57:292224 CapturingBoundNetLog log;
[email protected]e7b1c6d2c2012-05-05 00:54:032225 rv = handle.Init("a",
2226 params_,
2227 LOWEST,
2228 CompletionCallback(),
2229 pool_.get(),
2230 log.bound());
2231 ASSERT_EQ(OK, rv);
2232 EXPECT_TRUE(handle.is_reused());
[email protected]034df0f32013-01-07 23:17:482233 TestLoadTimingInfoConnectedReused(handle);
[email protected]e7b1c6d2c2012-05-05 00:54:032234
2235 ASSERT_TRUE(pool_->HasGroup("a"));
2236 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2237 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2238
[email protected]333bdf62012-06-08 22:57:292239 CapturingNetLog::CapturedEntryList entries;
[email protected]e7b1c6d2c2012-05-05 00:54:032240 log.GetEntries(&entries);
2241 EXPECT_TRUE(LogContainsEntryWithType(
2242 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
2243}
2244
2245// Make sure we cleanup old unused sockets when the cleanup timer is disabled.
2246TEST_F(ClientSocketPoolBaseTest, DisableCleanupTimerNoReuse) {
2247 // Disable cleanup timer.
2248 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(false);
2249
2250 CreatePoolWithIdleTimeouts(
2251 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2252 base::TimeDelta(), // Time out unused sockets immediately
2253 base::TimeDelta()); // Time out used sockets immediately
[email protected]64770b7d2011-11-16 04:30:412254
2255 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2256
2257 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2258
2259 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522260 TestCompletionCallback callback;
[email protected]64770b7d2011-11-16 04:30:412261 int rv = handle.Init("a",
2262 params_,
2263 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522264 callback.callback(),
[email protected]64770b7d2011-11-16 04:30:412265 pool_.get(),
2266 BoundNetLog());
[email protected]e7b1c6d2c2012-05-05 00:54:032267 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]64770b7d2011-11-16 04:30:412268 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2269
2270 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522271 TestCompletionCallback callback2;
[email protected]64770b7d2011-11-16 04:30:412272 rv = handle2.Init("a",
2273 params_,
2274 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522275 callback2.callback(),
[email protected]64770b7d2011-11-16 04:30:412276 pool_.get(),
2277 BoundNetLog());
[email protected]e7b1c6d2c2012-05-05 00:54:032278 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]64770b7d2011-11-16 04:30:412279 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
2280
2281 // Cancel one of the requests. Wait for the other, which will get the first
2282 // job. Release the socket. Run the loop again to make sure the second
2283 // socket is sitting idle and the first one is released (since ReleaseSocket()
2284 // just posts a DoReleaseSocket() task).
2285
2286 handle.Reset();
[email protected]e7b1c6d2c2012-05-05 00:54:032287 ASSERT_EQ(OK, callback2.WaitForResult());
[email protected]64770b7d2011-11-16 04:30:412288 // Use the socket.
[email protected]83039bb2011-12-09 18:43:552289 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]64770b7d2011-11-16 04:30:412290 handle2.Reset();
2291
[email protected]e7b1c6d2c2012-05-05 00:54:032292 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2293 // actually become pending until 2ms after they have been created. In order
2294 // to flush all tasks, we need to wait so that we know there are no
2295 // soon-to-be-pending tasks waiting.
2296 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
[email protected]2da659e2013-05-23 20:51:342297 base::MessageLoop::current()->RunUntilIdle();
[email protected]64770b7d2011-11-16 04:30:412298
[email protected]e7b1c6d2c2012-05-05 00:54:032299 // Both sockets should now be idle.
[email protected]64770b7d2011-11-16 04:30:412300 ASSERT_EQ(2, pool_->IdleSocketCount());
2301
2302 // Request a new socket. This should cleanup the unused and timed out ones.
2303 // A new socket will be created rather than reusing the idle one.
[email protected]333bdf62012-06-08 22:57:292304 CapturingBoundNetLog log;
[email protected]6ecf2b92011-12-15 01:14:522305 TestCompletionCallback callback3;
[email protected]64770b7d2011-11-16 04:30:412306 rv = handle.Init("a",
2307 params_,
2308 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522309 callback3.callback(),
[email protected]64770b7d2011-11-16 04:30:412310 pool_.get(),
2311 log.bound());
[email protected]e7b1c6d2c2012-05-05 00:54:032312 ASSERT_EQ(ERR_IO_PENDING, rv);
2313 ASSERT_EQ(OK, callback3.WaitForResult());
[email protected]64770b7d2011-11-16 04:30:412314 EXPECT_FALSE(handle.is_reused());
2315
[email protected]e7b1c6d2c2012-05-05 00:54:032316 // Make sure the idle socket is closed.
[email protected]64770b7d2011-11-16 04:30:412317 ASSERT_TRUE(pool_->HasGroup("a"));
2318 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2319 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2320
[email protected]333bdf62012-06-08 22:57:292321 CapturingNetLog::CapturedEntryList entries;
[email protected]64770b7d2011-11-16 04:30:412322 log.GetEntries(&entries);
2323 EXPECT_FALSE(LogContainsEntryWithType(
2324 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
2325}
2326
[email protected]4d3b05d2010-01-27 21:27:292327TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
[email protected]9bf28db2009-08-29 01:35:162328 CreatePoolWithIdleTimeouts(
2329 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2330 base::TimeDelta(), // Time out unused sockets immediately.
2331 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2332
2333 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2334
2335 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2336
[email protected]2431756e2010-09-29 20:26:132337 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522338 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132339 int rv = handle.Init("a",
2340 params_,
2341 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522342 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132343 pool_.get(),
2344 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:162345 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:132346 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
[email protected]9bf28db2009-08-29 01:35:162347
[email protected]2431756e2010-09-29 20:26:132348 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522349 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132350 rv = handle2.Init("a",
2351 params_,
2352 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522353 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132354 pool_.get(),
2355 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:162356 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:132357 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
[email protected]9bf28db2009-08-29 01:35:162358
2359 // Cancel one of the requests. Wait for the other, which will get the first
2360 // job. Release the socket. Run the loop again to make sure the second
2361 // socket is sitting idle and the first one is released (since ReleaseSocket()
2362 // just posts a DoReleaseSocket() task).
2363
[email protected]2431756e2010-09-29 20:26:132364 handle.Reset();
2365 EXPECT_EQ(OK, callback2.WaitForResult());
[email protected]0f873e82010-09-02 16:09:012366 // Use the socket.
[email protected]83039bb2011-12-09 18:43:552367 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]2431756e2010-09-29 20:26:132368 handle2.Reset();
[email protected]6b175382009-10-13 06:47:472369
2370 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2371 // actually become pending until 2ms after they have been created. In order
2372 // to flush all tasks, we need to wait so that we know there are no
2373 // soon-to-be-pending tasks waiting.
[email protected]26b9973962012-01-28 00:57:002374 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
[email protected]2da659e2013-05-23 20:51:342375 base::MessageLoop::current()->RunUntilIdle();
[email protected]9bf28db2009-08-29 01:35:162376
2377 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:042378
[email protected]9bf28db2009-08-29 01:35:162379 // Invoke the idle socket cleanup check. Only one socket should be left, the
2380 // used socket. Request it to make sure that it's used.
2381
2382 pool_->CleanupTimedOutIdleSockets();
[email protected]333bdf62012-06-08 22:57:292383 CapturingBoundNetLog log;
[email protected]2431756e2010-09-29 20:26:132384 rv = handle.Init("a",
2385 params_,
2386 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522387 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132388 pool_.get(),
2389 log.bound());
[email protected]9bf28db2009-08-29 01:35:162390 EXPECT_EQ(OK, rv);
[email protected]2431756e2010-09-29 20:26:132391 EXPECT_TRUE(handle.is_reused());
[email protected]b2fcd0e2010-12-01 15:19:402392
[email protected]333bdf62012-06-08 22:57:292393 CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402394 log.GetEntries(&entries);
[email protected]fd4fe0b2010-02-08 23:02:152395 EXPECT_TRUE(LogContainsEntryWithType(
[email protected]b2fcd0e2010-12-01 15:19:402396 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]9bf28db2009-08-29 01:35:162397}
2398
[email protected]2041cf342010-02-19 03:15:592399// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:162400// because of multiple releasing disconnected sockets.
2401TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
2402 CreatePoolWithIdleTimeouts(
2403 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2404 base::TimeDelta(), // Time out unused sockets immediately.
2405 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2406
2407 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2408
2409 // Startup 4 connect jobs. Two of them will be pending.
2410
[email protected]2431756e2010-09-29 20:26:132411 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522412 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132413 int rv = handle.Init("a",
2414 params_,
2415 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522416 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132417 pool_.get(),
2418 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162419 EXPECT_EQ(OK, rv);
2420
[email protected]2431756e2010-09-29 20:26:132421 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522422 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132423 rv = handle2.Init("a",
2424 params_,
2425 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522426 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132427 pool_.get(),
2428 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162429 EXPECT_EQ(OK, rv);
2430
[email protected]2431756e2010-09-29 20:26:132431 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:522432 TestCompletionCallback callback3;
[email protected]2431756e2010-09-29 20:26:132433 rv = handle3.Init("a",
2434 params_,
2435 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522436 callback3.callback(),
[email protected]2431756e2010-09-29 20:26:132437 pool_.get(),
2438 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162439 EXPECT_EQ(ERR_IO_PENDING, rv);
2440
[email protected]2431756e2010-09-29 20:26:132441 ClientSocketHandle handle4;
[email protected]6ecf2b92011-12-15 01:14:522442 TestCompletionCallback callback4;
[email protected]2431756e2010-09-29 20:26:132443 rv = handle4.Init("a",
2444 params_,
2445 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522446 callback4.callback(),
[email protected]2431756e2010-09-29 20:26:132447 pool_.get(),
2448 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162449 EXPECT_EQ(ERR_IO_PENDING, rv);
2450
2451 // Release two disconnected sockets.
2452
[email protected]2431756e2010-09-29 20:26:132453 handle.socket()->Disconnect();
2454 handle.Reset();
2455 handle2.socket()->Disconnect();
2456 handle2.Reset();
[email protected]4f2abec2010-02-03 18:10:162457
[email protected]2431756e2010-09-29 20:26:132458 EXPECT_EQ(OK, callback3.WaitForResult());
2459 EXPECT_FALSE(handle3.is_reused());
2460 EXPECT_EQ(OK, callback4.WaitForResult());
2461 EXPECT_FALSE(handle4.is_reused());
[email protected]4f2abec2010-02-03 18:10:162462}
2463
[email protected]d7027bb2010-05-10 18:58:542464// Regression test for http://crbug.com/42267.
2465// When DoReleaseSocket() is processed for one socket, it is blocked because the
2466// other stalled groups all have releasing sockets, so no progress can be made.
2467TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
2468 CreatePoolWithIdleTimeouts(
2469 4 /* socket limit */, 4 /* socket limit per group */,
2470 base::TimeDelta(), // Time out unused sockets immediately.
2471 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2472
2473 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2474
2475 // Max out the socket limit with 2 per group.
2476
[email protected]2431756e2010-09-29 20:26:132477 ClientSocketHandle handle_a[4];
[email protected]6ecf2b92011-12-15 01:14:522478 TestCompletionCallback callback_a[4];
[email protected]2431756e2010-09-29 20:26:132479 ClientSocketHandle handle_b[4];
[email protected]6ecf2b92011-12-15 01:14:522480 TestCompletionCallback callback_b[4];
[email protected]d7027bb2010-05-10 18:58:542481
2482 for (int i = 0; i < 2; ++i) {
[email protected]2431756e2010-09-29 20:26:132483 EXPECT_EQ(OK, handle_a[i].Init("a",
2484 params_,
2485 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522486 callback_a[i].callback(),
[email protected]2431756e2010-09-29 20:26:132487 pool_.get(),
2488 BoundNetLog()));
2489 EXPECT_EQ(OK, handle_b[i].Init("b",
2490 params_,
2491 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522492 callback_b[i].callback(),
[email protected]2431756e2010-09-29 20:26:132493 pool_.get(),
2494 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542495 }
[email protected]b89f7e42010-05-20 20:37:002496
[email protected]d7027bb2010-05-10 18:58:542497 // Make 4 pending requests, 2 per group.
2498
2499 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132500 EXPECT_EQ(ERR_IO_PENDING,
2501 handle_a[i].Init("a",
2502 params_,
2503 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522504 callback_a[i].callback(),
[email protected]2431756e2010-09-29 20:26:132505 pool_.get(),
2506 BoundNetLog()));
2507 EXPECT_EQ(ERR_IO_PENDING,
2508 handle_b[i].Init("b",
2509 params_,
2510 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522511 callback_b[i].callback(),
[email protected]2431756e2010-09-29 20:26:132512 pool_.get(),
2513 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542514 }
2515
2516 // Release b's socket first. The order is important, because in
2517 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2518 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2519 // first, which has a releasing socket, so it refuses to start up another
2520 // ConnectJob. So, we used to infinite loop on this.
[email protected]2431756e2010-09-29 20:26:132521 handle_b[0].socket()->Disconnect();
2522 handle_b[0].Reset();
2523 handle_a[0].socket()->Disconnect();
2524 handle_a[0].Reset();
[email protected]d7027bb2010-05-10 18:58:542525
2526 // Used to get stuck here.
[email protected]2da659e2013-05-23 20:51:342527 base::MessageLoop::current()->RunUntilIdle();
[email protected]d7027bb2010-05-10 18:58:542528
[email protected]2431756e2010-09-29 20:26:132529 handle_b[1].socket()->Disconnect();
2530 handle_b[1].Reset();
2531 handle_a[1].socket()->Disconnect();
2532 handle_a[1].Reset();
[email protected]d7027bb2010-05-10 18:58:542533
2534 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132535 EXPECT_EQ(OK, callback_b[i].WaitForResult());
2536 EXPECT_EQ(OK, callback_a[i].WaitForResult());
[email protected]d7027bb2010-05-10 18:58:542537 }
2538}
2539
[email protected]fd4fe0b2010-02-08 23:02:152540TEST_F(ClientSocketPoolBaseTest,
2541 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2542 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2543
2544 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2545
[email protected]bb1c4662013-11-14 00:00:072546 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
2547 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
2548 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
2549 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
[email protected]fd4fe0b2010-02-08 23:02:152550
[email protected]2431756e2010-09-29 20:26:132551 EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
2552 EXPECT_EQ(OK, (*requests())[1]->WaitForResult());
2553 EXPECT_EQ(2u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152554
2555 // Releases one connection.
[email protected]2431756e2010-09-29 20:26:132556 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2557 EXPECT_EQ(OK, (*requests())[2]->WaitForResult());
[email protected]fd4fe0b2010-02-08 23:02:152558
[email protected]2431756e2010-09-29 20:26:132559 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2560 EXPECT_EQ(OK, (*requests())[3]->WaitForResult());
2561 EXPECT_EQ(4u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152562
2563 EXPECT_EQ(1, GetOrderOfRequest(1));
2564 EXPECT_EQ(2, GetOrderOfRequest(2));
2565 EXPECT_EQ(3, GetOrderOfRequest(3));
2566 EXPECT_EQ(4, GetOrderOfRequest(4));
2567
2568 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:132569 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
[email protected]fd4fe0b2010-02-08 23:02:152570}
2571
[email protected]6ecf2b92011-12-15 01:14:522572class TestReleasingSocketRequest : public TestCompletionCallbackBase {
[email protected]4f1e4982010-03-02 18:31:042573 public:
[email protected]2431756e2010-09-29 20:26:132574 TestReleasingSocketRequest(TestClientSocketPool* pool,
2575 int expected_result,
[email protected]e60e47a2010-07-14 03:37:182576 bool reset_releasing_handle)
2577 : pool_(pool),
2578 expected_result_(expected_result),
[email protected]6ecf2b92011-12-15 01:14:522579 reset_releasing_handle_(reset_releasing_handle),
[email protected]aa249b52013-04-30 01:04:322580 callback_(base::Bind(&TestReleasingSocketRequest::OnComplete,
2581 base::Unretained(this))) {
[email protected]6ecf2b92011-12-15 01:14:522582 }
2583
dchengb03027d2014-10-21 12:00:202584 ~TestReleasingSocketRequest() override {}
[email protected]4f1e4982010-03-02 18:31:042585
2586 ClientSocketHandle* handle() { return &handle_; }
2587
[email protected]6ecf2b92011-12-15 01:14:522588 const CompletionCallback& callback() const { return callback_; }
[email protected]4f1e4982010-03-02 18:31:042589
2590 private:
[email protected]6ecf2b92011-12-15 01:14:522591 void OnComplete(int result) {
2592 SetResult(result);
2593 if (reset_releasing_handle_)
2594 handle_.Reset();
2595
[email protected]bb1c4662013-11-14 00:00:072596 scoped_refptr<TestSocketParams> con_params(
2597 new TestSocketParams(false /* ignore_limits */));
[email protected]6ecf2b92011-12-15 01:14:522598 EXPECT_EQ(expected_result_,
[email protected]bb1c4662013-11-14 00:00:072599 handle2_.Init("a", con_params, DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522600 callback2_.callback(), pool_, BoundNetLog()));
2601 }
2602
[email protected]2431756e2010-09-29 20:26:132603 TestClientSocketPool* const pool_;
[email protected]e60e47a2010-07-14 03:37:182604 int expected_result_;
2605 bool reset_releasing_handle_;
[email protected]4f1e4982010-03-02 18:31:042606 ClientSocketHandle handle_;
2607 ClientSocketHandle handle2_;
[email protected]6ecf2b92011-12-15 01:14:522608 CompletionCallback callback_;
2609 TestCompletionCallback callback2_;
[email protected]4f1e4982010-03-02 18:31:042610};
2611
[email protected]e60e47a2010-07-14 03:37:182612
2613TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2614 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2615
[email protected]bb1c4662013-11-14 00:00:072616 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
2617 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
2618 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
[email protected]e60e47a2010-07-14 03:37:182619
[email protected]2431756e2010-09-29 20:26:132620 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]e60e47a2010-07-14 03:37:182621 client_socket_factory_.allocation_count());
2622
2623 connect_job_factory_->set_job_type(
2624 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2625 TestReleasingSocketRequest req(pool_.get(), OK, false);
[email protected]2431756e2010-09-29 20:26:132626 EXPECT_EQ(ERR_IO_PENDING,
[email protected]bb1c4662013-11-14 00:00:072627 req.handle()->Init("a", params_, DEFAULT_PRIORITY, req.callback(),
[email protected]6ecf2b92011-12-15 01:14:522628 pool_.get(), BoundNetLog()));
[email protected]e60e47a2010-07-14 03:37:182629 // The next job should complete synchronously
2630 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2631
2632 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
2633 EXPECT_FALSE(req.handle()->is_initialized());
2634 EXPECT_FALSE(req.handle()->socket());
2635 EXPECT_TRUE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:432636 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182637}
2638
[email protected]b6501d3d2010-06-03 23:53:342639// http://crbug.com/44724 regression test.
2640// We start releasing the pool when we flush on network change. When that
2641// happens, the only active references are in the ClientSocketHandles. When a
2642// ConnectJob completes and calls back into the last ClientSocketHandle, that
2643// callback can release the last reference and delete the pool. After the
2644// callback finishes, we go back to the stack frame within the now-deleted pool.
2645// Executing any code that refers to members of the now-deleted pool can cause
2646// crashes.
2647TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2648 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2649 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2650
2651 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522652 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132653 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2654 params_,
[email protected]bb1c4662013-11-14 00:00:072655 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522656 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132657 pool_.get(),
2658 BoundNetLog()));
[email protected]b6501d3d2010-06-03 23:53:342659
[email protected]7af985a2012-12-14 22:40:422660 pool_->FlushWithError(ERR_NETWORK_CHANGED);
[email protected]b6501d3d2010-06-03 23:53:342661
2662 // We'll call back into this now.
2663 callback.WaitForResult();
2664}
2665
[email protected]a7e38572010-06-07 18:22:242666TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2667 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2668 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2669
2670 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522671 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132672 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2673 params_,
[email protected]bb1c4662013-11-14 00:00:072674 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522675 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132676 pool_.get(),
2677 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242678 EXPECT_EQ(OK, callback.WaitForResult());
2679 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2680
[email protected]7af985a2012-12-14 22:40:422681 pool_->FlushWithError(ERR_NETWORK_CHANGED);
[email protected]a7e38572010-06-07 18:22:242682
2683 handle.Reset();
[email protected]2da659e2013-05-23 20:51:342684 base::MessageLoop::current()->RunUntilIdle();
[email protected]a7e38572010-06-07 18:22:242685
[email protected]2431756e2010-09-29 20:26:132686 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2687 params_,
[email protected]bb1c4662013-11-14 00:00:072688 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522689 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132690 pool_.get(),
2691 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242692 EXPECT_EQ(OK, callback.WaitForResult());
2693 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2694}
2695
[email protected]6ecf2b92011-12-15 01:14:522696class ConnectWithinCallback : public TestCompletionCallbackBase {
[email protected]06f92462010-08-31 19:24:142697 public:
2698 ConnectWithinCallback(
2699 const std::string& group_name,
2700 const scoped_refptr<TestSocketParams>& params,
[email protected]2431756e2010-09-29 20:26:132701 TestClientSocketPool* pool)
[email protected]6ecf2b92011-12-15 01:14:522702 : group_name_(group_name),
2703 params_(params),
2704 pool_(pool),
[email protected]aa249b52013-04-30 01:04:322705 callback_(base::Bind(&ConnectWithinCallback::OnComplete,
2706 base::Unretained(this))) {
[email protected]06f92462010-08-31 19:24:142707 }
2708
dchengb03027d2014-10-21 12:00:202709 ~ConnectWithinCallback() override {}
[email protected]06f92462010-08-31 19:24:142710
2711 int WaitForNestedResult() {
2712 return nested_callback_.WaitForResult();
2713 }
2714
[email protected]6ecf2b92011-12-15 01:14:522715 const CompletionCallback& callback() const { return callback_; }
2716
[email protected]06f92462010-08-31 19:24:142717 private:
[email protected]6ecf2b92011-12-15 01:14:522718 void OnComplete(int result) {
2719 SetResult(result);
2720 EXPECT_EQ(ERR_IO_PENDING,
2721 handle_.Init(group_name_,
2722 params_,
[email protected]bb1c4662013-11-14 00:00:072723 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522724 nested_callback_.callback(),
2725 pool_,
2726 BoundNetLog()));
2727 }
2728
[email protected]06f92462010-08-31 19:24:142729 const std::string group_name_;
2730 const scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:132731 TestClientSocketPool* const pool_;
[email protected]06f92462010-08-31 19:24:142732 ClientSocketHandle handle_;
[email protected]6ecf2b92011-12-15 01:14:522733 CompletionCallback callback_;
2734 TestCompletionCallback nested_callback_;
2735
2736 DISALLOW_COPY_AND_ASSIGN(ConnectWithinCallback);
[email protected]06f92462010-08-31 19:24:142737};
2738
2739TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
2740 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2741
2742 // First job will be waiting until it gets aborted.
2743 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2744
2745 ClientSocketHandle handle;
[email protected]2431756e2010-09-29 20:26:132746 ConnectWithinCallback callback("a", params_, pool_.get());
2747 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2748 params_,
[email protected]bb1c4662013-11-14 00:00:072749 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522750 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132751 pool_.get(),
2752 BoundNetLog()));
[email protected]06f92462010-08-31 19:24:142753
2754 // Second job will be started during the first callback, and will
2755 // asynchronously complete with OK.
2756 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]7af985a2012-12-14 22:40:422757 pool_->FlushWithError(ERR_NETWORK_CHANGED);
2758 EXPECT_EQ(ERR_NETWORK_CHANGED, callback.WaitForResult());
[email protected]06f92462010-08-31 19:24:142759 EXPECT_EQ(OK, callback.WaitForNestedResult());
2760}
2761
[email protected]25eea382010-07-10 23:55:262762// Cancel a pending socket request while we're at max sockets,
2763// and verify that the backup socket firing doesn't cause a crash.
2764TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
2765 // Max 4 sockets globally, max 4 sockets per group.
2766 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
[email protected]06d94042010-08-25 01:45:222767 pool_->EnableConnectBackupJobs();
[email protected]25eea382010-07-10 23:55:262768
[email protected]4baaf9d2010-08-31 15:15:442769 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2770 // timer.
[email protected]25eea382010-07-10 23:55:262771 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2772 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522773 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132774 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2775 params_,
[email protected]bb1c4662013-11-14 00:00:072776 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522777 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132778 pool_.get(),
2779 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262780
2781 // Start (MaxSockets - 1) connected sockets to reach max sockets.
2782 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2783 ClientSocketHandle handles[kDefaultMaxSockets];
2784 for (int i = 1; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:522785 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132786 EXPECT_EQ(OK, handles[i].Init("bar",
2787 params_,
[email protected]bb1c4662013-11-14 00:00:072788 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522789 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132790 pool_.get(),
2791 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262792 }
2793
[email protected]2da659e2013-05-23 20:51:342794 base::MessageLoop::current()->RunUntilIdle();
[email protected]25eea382010-07-10 23:55:262795
2796 // Cancel the pending request.
2797 handle.Reset();
2798
2799 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]26b9973962012-01-28 00:57:002800 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2801 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]25eea382010-07-10 23:55:262802
[email protected]2da659e2013-05-23 20:51:342803 base::MessageLoop::current()->RunUntilIdle();
[email protected]25eea382010-07-10 23:55:262804 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
2805}
2806
[email protected]3f00be82010-09-27 19:50:022807TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
[email protected]4baaf9d2010-08-31 15:15:442808 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2809 pool_->EnableConnectBackupJobs();
2810
2811 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2812 // timer.
2813 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2814 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522815 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132816 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2817 params_,
[email protected]bb1c4662013-11-14 00:00:072818 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522819 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132820 pool_.get(),
2821 BoundNetLog()));
[email protected]4baaf9d2010-08-31 15:15:442822 ASSERT_TRUE(pool_->HasGroup("bar"));
2823 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
[email protected]8159a1c2012-06-07 00:00:102824 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("bar"));
[email protected]4baaf9d2010-08-31 15:15:442825
2826 // Cancel the socket request. This should cancel the backup timer. Wait for
2827 // the backup time to see if it indeed got canceled.
2828 handle.Reset();
2829 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]26b9973962012-01-28 00:57:002830 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2831 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]2da659e2013-05-23 20:51:342832 base::MessageLoop::current()->RunUntilIdle();
[email protected]4baaf9d2010-08-31 15:15:442833 ASSERT_TRUE(pool_->HasGroup("bar"));
2834 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2835}
2836
[email protected]3f00be82010-09-27 19:50:022837TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
2838 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2839 pool_->EnableConnectBackupJobs();
2840
2841 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2842 // timer.
2843 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2844 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522845 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132846 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2847 params_,
[email protected]bb1c4662013-11-14 00:00:072848 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522849 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132850 pool_.get(),
2851 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022852 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2853 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522854 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132855 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("bar",
2856 params_,
[email protected]bb1c4662013-11-14 00:00:072857 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522858 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132859 pool_.get(),
2860 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022861 ASSERT_TRUE(pool_->HasGroup("bar"));
2862 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("bar"));
2863
2864 // Cancel request 1 and then complete request 2. With the requests finished,
2865 // the backup timer should be cancelled.
2866 handle.Reset();
2867 EXPECT_EQ(OK, callback2.WaitForResult());
2868 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]26b9973962012-01-28 00:57:002869 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2870 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]2da659e2013-05-23 20:51:342871 base::MessageLoop::current()->RunUntilIdle();
[email protected]3f00be82010-09-27 19:50:022872}
2873
[email protected]eb5a99382010-07-11 03:18:262874// Test delayed socket binding for the case where we have two connects,
2875// and while one is waiting on a connect, the other frees up.
2876// The socket waiting on a connect should switch immediately to the freed
2877// up socket.
2878TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
2879 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2880 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2881
2882 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522883 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132884 EXPECT_EQ(ERR_IO_PENDING,
2885 handle1.Init("a",
2886 params_,
[email protected]bb1c4662013-11-14 00:00:072887 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522888 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132889 pool_.get(),
2890 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262891 EXPECT_EQ(OK, callback.WaitForResult());
2892
2893 // No idle sockets, no pending jobs.
2894 EXPECT_EQ(0, pool_->IdleSocketCount());
2895 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2896
2897 // Create a second socket to the same host, but this one will wait.
2898 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2899 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132900 EXPECT_EQ(ERR_IO_PENDING,
2901 handle2.Init("a",
2902 params_,
[email protected]bb1c4662013-11-14 00:00:072903 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522904 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132905 pool_.get(),
2906 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262907 // No idle sockets, and one connecting job.
2908 EXPECT_EQ(0, pool_->IdleSocketCount());
2909 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2910
2911 // Return the first handle to the pool. This will initiate the delayed
2912 // binding.
2913 handle1.Reset();
2914
[email protected]2da659e2013-05-23 20:51:342915 base::MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262916
2917 // Still no idle sockets, still one pending connect job.
2918 EXPECT_EQ(0, pool_->IdleSocketCount());
2919 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2920
2921 // The second socket connected, even though it was a Waiting Job.
2922 EXPECT_EQ(OK, callback.WaitForResult());
2923
2924 // And we can see there is still one job waiting.
2925 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2926
2927 // Finally, signal the waiting Connect.
2928 client_socket_factory_.SignalJobs();
2929 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2930
[email protected]2da659e2013-05-23 20:51:342931 base::MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262932}
2933
2934// Test delayed socket binding when a group is at capacity and one
2935// of the group's sockets frees up.
2936TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
2937 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2938 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2939
2940 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522941 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132942 EXPECT_EQ(ERR_IO_PENDING,
2943 handle1.Init("a",
2944 params_,
[email protected]bb1c4662013-11-14 00:00:072945 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522946 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132947 pool_.get(),
2948 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262949 EXPECT_EQ(OK, callback.WaitForResult());
2950
2951 // No idle sockets, no pending jobs.
2952 EXPECT_EQ(0, pool_->IdleSocketCount());
2953 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2954
2955 // Create a second socket to the same host, but this one will wait.
2956 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2957 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132958 EXPECT_EQ(ERR_IO_PENDING,
2959 handle2.Init("a",
2960 params_,
[email protected]bb1c4662013-11-14 00:00:072961 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522962 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132963 pool_.get(),
2964 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262965 // No idle sockets, and one connecting job.
2966 EXPECT_EQ(0, pool_->IdleSocketCount());
2967 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2968
2969 // Return the first handle to the pool. This will initiate the delayed
2970 // binding.
2971 handle1.Reset();
2972
[email protected]2da659e2013-05-23 20:51:342973 base::MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262974
2975 // Still no idle sockets, still one pending connect job.
2976 EXPECT_EQ(0, pool_->IdleSocketCount());
2977 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2978
2979 // The second socket connected, even though it was a Waiting Job.
2980 EXPECT_EQ(OK, callback.WaitForResult());
2981
2982 // And we can see there is still one job waiting.
2983 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2984
2985 // Finally, signal the waiting Connect.
2986 client_socket_factory_.SignalJobs();
2987 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2988
[email protected]2da659e2013-05-23 20:51:342989 base::MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262990}
2991
2992// Test out the case where we have one socket connected, one
2993// connecting, when the first socket finishes and goes idle.
[email protected]2abfe90a2010-08-25 17:49:512994// Although the second connection is pending, the second request
[email protected]eb5a99382010-07-11 03:18:262995// should complete, by taking the first socket's idle socket.
2996TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
2997 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2998 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2999
3000 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523001 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:133002 EXPECT_EQ(ERR_IO_PENDING,
3003 handle1.Init("a",
3004 params_,
[email protected]bb1c4662013-11-14 00:00:073005 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523006 callback.callback(),
[email protected]2431756e2010-09-29 20:26:133007 pool_.get(),
3008 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:263009 EXPECT_EQ(OK, callback.WaitForResult());
3010
3011 // No idle sockets, no pending jobs.
3012 EXPECT_EQ(0, pool_->IdleSocketCount());
3013 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3014
3015 // Create a second socket to the same host, but this one will wait.
3016 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3017 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:133018 EXPECT_EQ(ERR_IO_PENDING,
3019 handle2.Init("a",
3020 params_,
[email protected]bb1c4662013-11-14 00:00:073021 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523022 callback.callback(),
[email protected]2431756e2010-09-29 20:26:133023 pool_.get(),
3024 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:263025 // No idle sockets, and one connecting job.
3026 EXPECT_EQ(0, pool_->IdleSocketCount());
3027 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3028
3029 // Return the first handle to the pool. This will initiate the delayed
3030 // binding.
3031 handle1.Reset();
3032
[email protected]2da659e2013-05-23 20:51:343033 base::MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263034
3035 // Still no idle sockets, still one pending connect job.
3036 EXPECT_EQ(0, pool_->IdleSocketCount());
3037 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3038
3039 // The second socket connected, even though it was a Waiting Job.
3040 EXPECT_EQ(OK, callback.WaitForResult());
3041
3042 // And we can see there is still one job waiting.
3043 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3044
3045 // Finally, signal the waiting Connect.
3046 client_socket_factory_.SignalJobs();
3047 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3048
[email protected]2da659e2013-05-23 20:51:343049 base::MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263050}
3051
[email protected]2abfe90a2010-08-25 17:49:513052// Cover the case where on an available socket slot, we have one pending
3053// request that completes synchronously, thereby making the Group empty.
3054TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
3055 const int kUnlimitedSockets = 100;
3056 const int kOneSocketPerGroup = 1;
3057 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
3058
3059 // Make the first request asynchronous fail.
3060 // This will free up a socket slot later.
3061 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
3062
3063 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523064 TestCompletionCallback callback1;
[email protected]2431756e2010-09-29 20:26:133065 EXPECT_EQ(ERR_IO_PENDING,
3066 handle1.Init("a",
3067 params_,
[email protected]bb1c4662013-11-14 00:00:073068 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523069 callback1.callback(),
[email protected]2431756e2010-09-29 20:26:133070 pool_.get(),
3071 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:513072 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3073
3074 // Make the second request synchronously fail. This should make the Group
3075 // empty.
3076 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3077 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523078 TestCompletionCallback callback2;
[email protected]2abfe90a2010-08-25 17:49:513079 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
3080 // when created.
[email protected]2431756e2010-09-29 20:26:133081 EXPECT_EQ(ERR_IO_PENDING,
3082 handle2.Init("a",
3083 params_,
[email protected]bb1c4662013-11-14 00:00:073084 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523085 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:133086 pool_.get(),
3087 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:513088
3089 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3090
3091 EXPECT_EQ(ERR_CONNECTION_FAILED, callback1.WaitForResult());
3092 EXPECT_EQ(ERR_CONNECTION_FAILED, callback2.WaitForResult());
3093 EXPECT_FALSE(pool_->HasGroup("a"));
3094}
3095
[email protected]e1b54dc2010-10-06 21:27:223096TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
3097 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3098
3099 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3100
3101 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523102 TestCompletionCallback callback1;
[email protected]e1b54dc2010-10-06 21:27:223103 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3104 params_,
[email protected]bb1c4662013-11-14 00:00:073105 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523106 callback1.callback(),
[email protected]e1b54dc2010-10-06 21:27:223107 pool_.get(),
3108 BoundNetLog()));
3109
3110 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523111 TestCompletionCallback callback2;
[email protected]e1b54dc2010-10-06 21:27:223112 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3113 params_,
[email protected]bb1c4662013-11-14 00:00:073114 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523115 callback2.callback(),
[email protected]e1b54dc2010-10-06 21:27:223116 pool_.get(),
3117 BoundNetLog()));
3118 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:523119 TestCompletionCallback callback3;
[email protected]e1b54dc2010-10-06 21:27:223120 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
3121 params_,
[email protected]bb1c4662013-11-14 00:00:073122 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523123 callback3.callback(),
[email protected]e1b54dc2010-10-06 21:27:223124 pool_.get(),
3125 BoundNetLog()));
3126
3127 EXPECT_EQ(OK, callback1.WaitForResult());
3128 EXPECT_EQ(OK, callback2.WaitForResult());
3129 EXPECT_EQ(OK, callback3.WaitForResult());
3130
3131 // Use the socket.
[email protected]83039bb2011-12-09 18:43:553132 EXPECT_EQ(1, handle1.socket()->Write(NULL, 1, CompletionCallback()));
3133 EXPECT_EQ(1, handle3.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]e1b54dc2010-10-06 21:27:223134
3135 handle1.Reset();
3136 handle2.Reset();
3137 handle3.Reset();
3138
3139 EXPECT_EQ(OK, handle1.Init("a",
3140 params_,
[email protected]bb1c4662013-11-14 00:00:073141 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523142 callback1.callback(),
[email protected]e1b54dc2010-10-06 21:27:223143 pool_.get(),
3144 BoundNetLog()));
3145 EXPECT_EQ(OK, handle2.Init("a",
3146 params_,
[email protected]bb1c4662013-11-14 00:00:073147 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523148 callback2.callback(),
[email protected]e1b54dc2010-10-06 21:27:223149 pool_.get(),
3150 BoundNetLog()));
3151 EXPECT_EQ(OK, handle3.Init("a",
3152 params_,
[email protected]bb1c4662013-11-14 00:00:073153 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523154 callback3.callback(),
[email protected]e1b54dc2010-10-06 21:27:223155 pool_.get(),
3156 BoundNetLog()));
3157
3158 EXPECT_TRUE(handle1.socket()->WasEverUsed());
3159 EXPECT_TRUE(handle2.socket()->WasEverUsed());
3160 EXPECT_FALSE(handle3.socket()->WasEverUsed());
3161}
3162
[email protected]2c2bef152010-10-13 00:55:033163TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
3164 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3165 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3166
3167 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3168
3169 ASSERT_TRUE(pool_->HasGroup("a"));
3170 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103171 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033172 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3173
3174 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523175 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033176 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3177 params_,
[email protected]bb1c4662013-11-14 00:00:073178 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523179 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033180 pool_.get(),
3181 BoundNetLog()));
3182
3183 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523184 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033185 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3186 params_,
[email protected]bb1c4662013-11-14 00:00:073187 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523188 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033189 pool_.get(),
3190 BoundNetLog()));
3191
3192 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103193 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033194 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3195
3196 EXPECT_EQ(OK, callback1.WaitForResult());
3197 EXPECT_EQ(OK, callback2.WaitForResult());
3198 handle1.Reset();
3199 handle2.Reset();
3200
3201 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103202 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033203 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3204}
3205
3206TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
3207 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3208 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3209
3210 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523211 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033212 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3213 params_,
[email protected]bb1c4662013-11-14 00:00:073214 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523215 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033216 pool_.get(),
3217 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(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033222 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3223
3224 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3225
3226 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103227 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033228 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3229
3230 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523231 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033232 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3233 params_,
[email protected]bb1c4662013-11-14 00:00:073234 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523235 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033236 pool_.get(),
3237 BoundNetLog()));
3238
3239 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103240 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033241 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3242
3243 EXPECT_EQ(OK, callback1.WaitForResult());
3244 EXPECT_EQ(OK, callback2.WaitForResult());
3245 handle1.Reset();
3246 handle2.Reset();
3247
3248 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103249 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033250 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3251}
3252
3253TEST_F(ClientSocketPoolBaseTest,
3254 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
3255 CreatePool(4, 4);
3256 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3257
3258 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523259 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033260 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3261 params_,
[email protected]bb1c4662013-11-14 00:00:073262 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523263 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033264 pool_.get(),
3265 BoundNetLog()));
3266
3267 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523268 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033269 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3270 params_,
[email protected]bb1c4662013-11-14 00:00:073271 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523272 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033273 pool_.get(),
3274 BoundNetLog()));
3275
3276 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:523277 TestCompletionCallback callback3;
[email protected]2c2bef152010-10-13 00:55:033278 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
3279 params_,
[email protected]bb1c4662013-11-14 00:00:073280 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523281 callback3.callback(),
[email protected]2c2bef152010-10-13 00:55:033282 pool_.get(),
3283 BoundNetLog()));
3284
3285 ASSERT_TRUE(pool_->HasGroup("a"));
3286 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103287 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033288 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3289
3290 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3291
3292 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103293 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033294 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3295
3296 EXPECT_EQ(OK, callback1.WaitForResult());
3297 EXPECT_EQ(OK, callback2.WaitForResult());
3298 EXPECT_EQ(OK, callback3.WaitForResult());
3299 handle1.Reset();
3300 handle2.Reset();
3301 handle3.Reset();
3302
3303 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103304 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033305 EXPECT_EQ(3, pool_->IdleSocketCountInGroup("a"));
3306}
3307
3308TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
3309 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3310 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3311
3312 ASSERT_FALSE(pool_->HasGroup("a"));
3313
3314 pool_->RequestSockets("a", &params_, kDefaultMaxSockets,
3315 BoundNetLog());
3316
3317 ASSERT_TRUE(pool_->HasGroup("a"));
3318 EXPECT_EQ(kDefaultMaxSockets, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103319 EXPECT_EQ(kDefaultMaxSockets, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033320
3321 ASSERT_FALSE(pool_->HasGroup("b"));
3322
3323 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
3324 BoundNetLog());
3325
3326 ASSERT_FALSE(pool_->HasGroup("b"));
3327}
3328
3329TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
3330 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3331 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3332
3333 ASSERT_FALSE(pool_->HasGroup("a"));
3334
3335 pool_->RequestSockets("a", &params_, kDefaultMaxSockets - 1,
3336 BoundNetLog());
3337
3338 ASSERT_TRUE(pool_->HasGroup("a"));
3339 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103340 EXPECT_EQ(kDefaultMaxSockets - 1,
3341 pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]51fdc7c2012-04-10 19:19:483342 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033343
3344 ASSERT_FALSE(pool_->HasGroup("b"));
3345
3346 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
3347 BoundNetLog());
3348
3349 ASSERT_TRUE(pool_->HasGroup("b"));
3350 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("b"));
[email protected]51fdc7c2012-04-10 19:19:483351 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033352}
3353
3354TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
3355 CreatePool(4, 4);
3356 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3357
3358 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523359 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033360 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3361 params_,
[email protected]bb1c4662013-11-14 00:00:073362 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523363 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033364 pool_.get(),
3365 BoundNetLog()));
3366 ASSERT_EQ(OK, callback1.WaitForResult());
3367 handle1.Reset();
3368
3369 ASSERT_TRUE(pool_->HasGroup("a"));
3370 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103371 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033372 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3373
3374 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3375
3376 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103377 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033378 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3379}
3380
3381TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
3382 CreatePool(4, 4);
3383 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3384
3385 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523386 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033387 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3388 params_,
[email protected]bb1c4662013-11-14 00:00:073389 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523390 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033391 pool_.get(),
3392 BoundNetLog()));
3393 ASSERT_EQ(OK, callback1.WaitForResult());
3394
3395 ASSERT_TRUE(pool_->HasGroup("a"));
3396 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103397 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033398 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3399 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3400
3401 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3402
3403 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103404 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033405 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3406 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3407}
3408
3409TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
3410 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3411 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3412
3413 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3414 BoundNetLog());
3415
3416 ASSERT_TRUE(pool_->HasGroup("a"));
3417 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103418 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033419 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("a"));
3420
3421 pool_->RequestSockets("b", &params_, kDefaultMaxSocketsPerGroup,
3422 BoundNetLog());
3423
3424 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103425 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]2c2bef152010-10-13 00:55:033426 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("b"));
3427}
3428
[email protected]3c819f522010-12-02 02:03:123429TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
3430 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3431 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3432
3433 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3434 BoundNetLog());
3435
3436 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]fd2e53e2011-01-14 20:40:523437
3438 connect_job_factory_->set_job_type(
3439 TestConnectJob::kMockAdditionalErrorStateJob);
3440 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3441 BoundNetLog());
3442
3443 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]3c819f522010-12-02 02:03:123444}
3445
[email protected]8159a1c2012-06-07 00:00:103446TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
[email protected]2c2bef152010-10-13 00:55:033447 CreatePool(4, 4);
3448 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3449
3450 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3451
3452 ASSERT_TRUE(pool_->HasGroup("a"));
3453 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103454 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033455 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3456
3457 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3458 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103459 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033460 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3461
3462 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523463 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033464 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3465 params_,
[email protected]bb1c4662013-11-14 00:00:073466 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523467 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033468 pool_.get(),
3469 BoundNetLog()));
3470 ASSERT_EQ(OK, callback1.WaitForResult());
3471
3472 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523473 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033474 int rv = handle2.Init("a",
3475 params_,
[email protected]bb1c4662013-11-14 00:00:073476 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523477 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033478 pool_.get(),
3479 BoundNetLog());
3480 if (rv != OK) {
3481 EXPECT_EQ(ERR_IO_PENDING, rv);
3482 EXPECT_EQ(OK, callback2.WaitForResult());
3483 }
3484
[email protected]8159a1c2012-06-07 00:00:103485 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3486 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3487 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("a"));
3488 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3489
[email protected]2c2bef152010-10-13 00:55:033490 handle1.Reset();
3491 handle2.Reset();
3492
[email protected]8159a1c2012-06-07 00:00:103493 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3494 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033495 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3496
3497 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3498 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103499 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033500 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3501}
3502
3503TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
3504 CreatePool(4, 4);
3505 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3506
3507 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3508
3509 ASSERT_TRUE(pool_->HasGroup("a"));
3510 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103511 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033512 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3513
3514 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3515 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103516 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033517 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3518
3519 pool_->RequestSockets("a", &params_, 3, BoundNetLog());
3520 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103521 EXPECT_EQ(3, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033522 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3523
3524 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3525 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103526 EXPECT_EQ(3, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033527 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3528}
3529
3530TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
3531 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3532 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3533
3534 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3535
3536 ASSERT_TRUE(pool_->HasGroup("a"));
3537 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103538 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033539 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3540
3541 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523542 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033543 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3544 params_,
[email protected]bb1c4662013-11-14 00:00:073545 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523546 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033547 pool_.get(),
3548 BoundNetLog()));
3549
3550 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103551 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033552 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3553
3554 ASSERT_EQ(OK, callback1.WaitForResult());
3555
[email protected]0dc88b32014-03-26 20:12:283556 // Make sure if a preconnected socket is not fully connected when a request
[email protected]034df0f32013-01-07 23:17:483557 // starts, it has a connect start time.
3558 TestLoadTimingInfoConnectedNotReused(handle1);
[email protected]2c2bef152010-10-13 00:55:033559 handle1.Reset();
3560
3561 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3562}
3563
[email protected]034df0f32013-01-07 23:17:483564// Checks that fully connected preconnect jobs have no connect times, and are
3565// marked as reused.
3566TEST_F(ClientSocketPoolBaseTest, ConnectedPreconnectJobsHaveNoConnectTimes) {
3567 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3568 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3569 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3570
3571 ASSERT_TRUE(pool_->HasGroup("a"));
3572 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3573 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3574 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3575
3576 ClientSocketHandle handle;
3577 TestCompletionCallback callback;
3578 EXPECT_EQ(OK, handle.Init("a",
3579 params_,
[email protected]bb1c4662013-11-14 00:00:073580 DEFAULT_PRIORITY,
[email protected]034df0f32013-01-07 23:17:483581 callback.callback(),
3582 pool_.get(),
3583 BoundNetLog()));
3584
3585 // Make sure the idle socket was used.
3586 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3587
3588 TestLoadTimingInfoConnectedReused(handle);
3589 handle.Reset();
3590 TestLoadTimingInfoNotConnected(handle);
3591}
3592
[email protected]dcbe168a2010-12-02 03:14:463593// http://crbug.com/64940 regression test.
3594TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
3595 const int kMaxTotalSockets = 3;
3596 const int kMaxSocketsPerGroup = 2;
3597 CreatePool(kMaxTotalSockets, kMaxSocketsPerGroup);
3598 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3599
3600 // Note that group name ordering matters here. "a" comes before "b", so
3601 // CloseOneIdleSocket() will try to close "a"'s idle socket.
3602
3603 // Set up one idle socket in "a".
3604 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523605 TestCompletionCallback callback1;
[email protected]dcbe168a2010-12-02 03:14:463606 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3607 params_,
[email protected]bb1c4662013-11-14 00:00:073608 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523609 callback1.callback(),
[email protected]dcbe168a2010-12-02 03:14:463610 pool_.get(),
3611 BoundNetLog()));
3612
3613 ASSERT_EQ(OK, callback1.WaitForResult());
3614 handle1.Reset();
3615 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3616
3617 // Set up two active sockets in "b".
3618 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523619 TestCompletionCallback callback2;
[email protected]dcbe168a2010-12-02 03:14:463620 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("b",
3621 params_,
[email protected]bb1c4662013-11-14 00:00:073622 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523623 callback1.callback(),
[email protected]dcbe168a2010-12-02 03:14:463624 pool_.get(),
3625 BoundNetLog()));
3626 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("b",
3627 params_,
[email protected]bb1c4662013-11-14 00:00:073628 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523629 callback2.callback(),
[email protected]dcbe168a2010-12-02 03:14:463630 pool_.get(),
3631 BoundNetLog()));
3632
3633 ASSERT_EQ(OK, callback1.WaitForResult());
3634 ASSERT_EQ(OK, callback2.WaitForResult());
3635 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103636 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463637 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3638
3639 // Now we have 1 idle socket in "a" and 2 active sockets in "b". This means
3640 // we've maxed out on sockets, since we set |kMaxTotalSockets| to 3.
3641 // Requesting 2 preconnected sockets for "a" should fail to allocate any more
3642 // sockets for "a", and "b" should still have 2 active sockets.
3643
3644 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3645 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103646 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]dcbe168a2010-12-02 03:14:463647 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3648 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3649 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103650 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463651 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3652 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3653
3654 // Now release the 2 active sockets for "b". This will give us 1 idle socket
3655 // in "a" and 2 idle sockets in "b". Requesting 2 preconnected sockets for
3656 // "a" should result in closing 1 for "b".
3657 handle1.Reset();
3658 handle2.Reset();
3659 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("b"));
3660 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3661
3662 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3663 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103664 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]dcbe168a2010-12-02 03:14:463665 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3666 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3667 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103668 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463669 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("b"));
3670 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3671}
3672
[email protected]b7b8be42011-07-12 12:46:413673TEST_F(ClientSocketPoolBaseTest, PreconnectWithoutBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073674 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3675 pool_->EnableConnectBackupJobs();
3676
3677 // Make the ConnectJob hang until it times out, shorten the timeout.
3678 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3679 connect_job_factory_->set_timeout_duration(
3680 base::TimeDelta::FromMilliseconds(500));
3681 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3682 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103683 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073684 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073685
[email protected]b7b8be42011-07-12 12:46:413686 // Verify the backup timer doesn't create a backup job, by making
3687 // the backup job a pending job instead of a waiting job, so it
3688 // *would* complete if it were created.
[email protected]a9fc8fc2011-05-10 02:41:073689 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2da659e2013-05-23 20:51:343690 base::MessageLoop::current()->PostDelayedTask(
3691 FROM_HERE,
3692 base::MessageLoop::QuitClosure(),
3693 base::TimeDelta::FromSeconds(1));
3694 base::MessageLoop::current()->Run();
[email protected]a9fc8fc2011-05-10 02:41:073695 EXPECT_FALSE(pool_->HasGroup("a"));
3696}
3697
[email protected]b7b8be42011-07-12 12:46:413698TEST_F(ClientSocketPoolBaseTest, PreconnectWithBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073699 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3700 pool_->EnableConnectBackupJobs();
3701
3702 // Make the ConnectJob hang forever.
3703 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3704 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3705 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103706 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073707 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]2da659e2013-05-23 20:51:343708 base::MessageLoop::current()->RunUntilIdle();
[email protected]a9fc8fc2011-05-10 02:41:073709
3710 // Make the backup job be a pending job, so it completes normally.
3711 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3712 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:523713 TestCompletionCallback callback;
[email protected]a9fc8fc2011-05-10 02:41:073714 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
3715 params_,
[email protected]bb1c4662013-11-14 00:00:073716 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523717 callback.callback(),
[email protected]a9fc8fc2011-05-10 02:41:073718 pool_.get(),
3719 BoundNetLog()));
[email protected]b7b8be42011-07-12 12:46:413720 // Timer has started, but the backup connect job shouldn't be created yet.
[email protected]a9fc8fc2011-05-10 02:41:073721 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103722 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073723 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3724 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3725 ASSERT_EQ(OK, callback.WaitForResult());
3726
3727 // The hung connect job should still be there, but everything else should be
3728 // complete.
3729 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103730 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073731 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3732 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3733}
3734
[email protected]0dc88b32014-03-26 20:12:283735// Tests that a preconnect that starts out with unread data can still be used.
3736// http://crbug.com/334467
3737TEST_F(ClientSocketPoolBaseTest, PreconnectWithUnreadData) {
3738 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3739 connect_job_factory_->set_job_type(TestConnectJob::kMockUnreadDataJob);
3740
3741 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3742
3743 ASSERT_TRUE(pool_->HasGroup("a"));
3744 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3745 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3746 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3747
3748 // Fail future jobs to be sure that handle receives the preconnected socket
3749 // rather than closing it and making a new one.
3750 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3751 ClientSocketHandle handle;
3752 TestCompletionCallback callback;
3753 EXPECT_EQ(OK, handle.Init("a",
3754 params_,
3755 DEFAULT_PRIORITY,
3756 callback.callback(),
3757 pool_.get(),
3758 BoundNetLog()));
3759
3760 ASSERT_TRUE(pool_->HasGroup("a"));
3761 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3762 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3763 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3764
3765 // Drain the pending read.
3766 EXPECT_EQ(1, handle.socket()->Read(NULL, 1, CompletionCallback()));
3767
3768 TestLoadTimingInfoConnectedReused(handle);
3769 handle.Reset();
3770
3771 // The socket should be usable now that it's idle again.
3772 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3773}
3774
[email protected]043b68c82013-08-22 23:41:523775class MockLayeredPool : public HigherLayeredPool {
[email protected]58e562f2013-04-22 17:32:203776 public:
3777 MockLayeredPool(TestClientSocketPool* pool,
3778 const std::string& group_name)
3779 : pool_(pool),
[email protected]58e562f2013-04-22 17:32:203780 group_name_(group_name),
3781 can_release_connection_(true) {
[email protected]043b68c82013-08-22 23:41:523782 pool_->AddHigherLayeredPool(this);
[email protected]58e562f2013-04-22 17:32:203783 }
3784
3785 ~MockLayeredPool() {
[email protected]043b68c82013-08-22 23:41:523786 pool_->RemoveHigherLayeredPool(this);
[email protected]58e562f2013-04-22 17:32:203787 }
3788
3789 int RequestSocket(TestClientSocketPool* pool) {
[email protected]bb1c4662013-11-14 00:00:073790 scoped_refptr<TestSocketParams> params(
3791 new TestSocketParams(false /* ignore_limits */));
3792 return handle_.Init(group_name_, params, DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203793 callback_.callback(), pool, BoundNetLog());
3794 }
3795
3796 int RequestSocketWithoutLimits(TestClientSocketPool* pool) {
[email protected]bb1c4662013-11-14 00:00:073797 scoped_refptr<TestSocketParams> params(
3798 new TestSocketParams(true /* ignore_limits */));
3799 return handle_.Init(group_name_, params, MAXIMUM_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203800 callback_.callback(), pool, BoundNetLog());
3801 }
3802
3803 bool ReleaseOneConnection() {
3804 if (!handle_.is_initialized() || !can_release_connection_) {
3805 return false;
3806 }
3807 handle_.socket()->Disconnect();
3808 handle_.Reset();
3809 return true;
3810 }
3811
3812 void set_can_release_connection(bool can_release_connection) {
3813 can_release_connection_ = can_release_connection;
3814 }
3815
3816 MOCK_METHOD0(CloseOneIdleConnection, bool());
3817
3818 private:
3819 TestClientSocketPool* const pool_;
[email protected]58e562f2013-04-22 17:32:203820 ClientSocketHandle handle_;
3821 TestCompletionCallback callback_;
3822 const std::string group_name_;
3823 bool can_release_connection_;
3824};
3825
3826TEST_F(ClientSocketPoolBaseTest, FailToCloseIdleSocketsNotHeldByLayeredPool) {
3827 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3828 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3829
3830 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
3831 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3832 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3833 .WillOnce(Return(false));
[email protected]043b68c82013-08-22 23:41:523834 EXPECT_FALSE(pool_->CloseOneIdleConnectionInHigherLayeredPool());
[email protected]58e562f2013-04-22 17:32:203835}
3836
3837TEST_F(ClientSocketPoolBaseTest, ForciblyCloseIdleSocketsHeldByLayeredPool) {
3838 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3839 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3840
3841 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
3842 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3843 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3844 .WillOnce(Invoke(&mock_layered_pool,
3845 &MockLayeredPool::ReleaseOneConnection));
[email protected]043b68c82013-08-22 23:41:523846 EXPECT_TRUE(pool_->CloseOneIdleConnectionInHigherLayeredPool());
[email protected]58e562f2013-04-22 17:32:203847}
3848
3849// Tests the basic case of closing an idle socket in a higher layered pool when
3850// a new request is issued and the lower layer pool is stalled.
3851TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsHeldByLayeredPoolWhenNeeded) {
3852 CreatePool(1, 1);
3853 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3854
3855 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
3856 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3857 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3858 .WillOnce(Invoke(&mock_layered_pool,
3859 &MockLayeredPool::ReleaseOneConnection));
3860 ClientSocketHandle handle;
3861 TestCompletionCallback callback;
3862 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
3863 params_,
[email protected]bb1c4662013-11-14 00:00:073864 DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203865 callback.callback(),
3866 pool_.get(),
3867 BoundNetLog()));
3868 EXPECT_EQ(OK, callback.WaitForResult());
3869}
3870
3871// Same as above, but the idle socket is in the same group as the stalled
3872// socket, and closes the only other request in its group when closing requests
3873// in higher layered pools. This generally shouldn't happen, but it may be
3874// possible if a higher level pool issues a request and the request is
3875// subsequently cancelled. Even if it's not possible, best not to crash.
3876TEST_F(ClientSocketPoolBaseTest,
3877 CloseIdleSocketsHeldByLayeredPoolWhenNeededSameGroup) {
3878 CreatePool(2, 2);
3879 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3880
3881 // Need a socket in another group for the pool to be stalled (If a group
3882 // has the maximum number of connections already, it's not stalled).
3883 ClientSocketHandle handle1;
3884 TestCompletionCallback callback1;
3885 EXPECT_EQ(OK, handle1.Init("group1",
3886 params_,
[email protected]bb1c4662013-11-14 00:00:073887 DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203888 callback1.callback(),
3889 pool_.get(),
3890 BoundNetLog()));
3891
3892 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
3893 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3894 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3895 .WillOnce(Invoke(&mock_layered_pool,
3896 &MockLayeredPool::ReleaseOneConnection));
3897 ClientSocketHandle handle;
3898 TestCompletionCallback callback2;
3899 EXPECT_EQ(ERR_IO_PENDING, handle.Init("group2",
3900 params_,
[email protected]bb1c4662013-11-14 00:00:073901 DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203902 callback2.callback(),
3903 pool_.get(),
3904 BoundNetLog()));
3905 EXPECT_EQ(OK, callback2.WaitForResult());
3906}
3907
3908// Tests the case when an idle socket can be closed when a new request is
3909// issued, and the new request belongs to a group that was previously stalled.
3910TEST_F(ClientSocketPoolBaseTest,
3911 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded) {
3912 CreatePool(2, 2);
3913 std::list<TestConnectJob::JobType> job_types;
3914 job_types.push_back(TestConnectJob::kMockJob);
3915 job_types.push_back(TestConnectJob::kMockJob);
3916 job_types.push_back(TestConnectJob::kMockJob);
3917 job_types.push_back(TestConnectJob::kMockJob);
3918 connect_job_factory_->set_job_types(&job_types);
3919
3920 ClientSocketHandle handle1;
3921 TestCompletionCallback callback1;
3922 EXPECT_EQ(OK, handle1.Init("group1",
3923 params_,
[email protected]bb1c4662013-11-14 00:00:073924 DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203925 callback1.callback(),
3926 pool_.get(),
3927 BoundNetLog()));
3928
3929 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
3930 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3931 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3932 .WillRepeatedly(Invoke(&mock_layered_pool,
3933 &MockLayeredPool::ReleaseOneConnection));
3934 mock_layered_pool.set_can_release_connection(false);
3935
3936 // The third request is made when the socket pool is in a stalled state.
3937 ClientSocketHandle handle3;
3938 TestCompletionCallback callback3;
3939 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("group3",
3940 params_,
[email protected]bb1c4662013-11-14 00:00:073941 DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203942 callback3.callback(),
3943 pool_.get(),
3944 BoundNetLog()));
3945
3946 base::RunLoop().RunUntilIdle();
3947 EXPECT_FALSE(callback3.have_result());
3948
3949 // The fourth request is made when the pool is no longer stalled. The third
3950 // request should be serviced first, since it was issued first and has the
3951 // same priority.
3952 mock_layered_pool.set_can_release_connection(true);
3953 ClientSocketHandle handle4;
3954 TestCompletionCallback callback4;
3955 EXPECT_EQ(ERR_IO_PENDING, handle4.Init("group3",
3956 params_,
[email protected]bb1c4662013-11-14 00:00:073957 DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203958 callback4.callback(),
3959 pool_.get(),
3960 BoundNetLog()));
3961 EXPECT_EQ(OK, callback3.WaitForResult());
3962 EXPECT_FALSE(callback4.have_result());
3963
3964 // Closing a handle should free up another socket slot.
3965 handle1.Reset();
3966 EXPECT_EQ(OK, callback4.WaitForResult());
3967}
3968
3969// Tests the case when an idle socket can be closed when a new request is
3970// issued, and the new request belongs to a group that was previously stalled.
3971//
3972// The two differences from the above test are that the stalled requests are not
3973// in the same group as the layered pool's request, and the the fourth request
3974// has a higher priority than the third one, so gets a socket first.
3975TEST_F(ClientSocketPoolBaseTest,
3976 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded2) {
3977 CreatePool(2, 2);
3978 std::list<TestConnectJob::JobType> job_types;
3979 job_types.push_back(TestConnectJob::kMockJob);
3980 job_types.push_back(TestConnectJob::kMockJob);
3981 job_types.push_back(TestConnectJob::kMockJob);
3982 job_types.push_back(TestConnectJob::kMockJob);
3983 connect_job_factory_->set_job_types(&job_types);
3984
3985 ClientSocketHandle handle1;
3986 TestCompletionCallback callback1;
3987 EXPECT_EQ(OK, handle1.Init("group1",
3988 params_,
[email protected]bb1c4662013-11-14 00:00:073989 DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203990 callback1.callback(),
3991 pool_.get(),
3992 BoundNetLog()));
3993
3994 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
3995 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3996 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3997 .WillRepeatedly(Invoke(&mock_layered_pool,
3998 &MockLayeredPool::ReleaseOneConnection));
3999 mock_layered_pool.set_can_release_connection(false);
4000
4001 // The third request is made when the socket pool is in a stalled state.
4002 ClientSocketHandle handle3;
4003 TestCompletionCallback callback3;
4004 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("group3",
4005 params_,
4006 MEDIUM,
4007 callback3.callback(),
4008 pool_.get(),
4009 BoundNetLog()));
4010
4011 base::RunLoop().RunUntilIdle();
4012 EXPECT_FALSE(callback3.have_result());
4013
4014 // The fourth request is made when the pool is no longer stalled. This
4015 // request has a higher priority than the third request, so is serviced first.
4016 mock_layered_pool.set_can_release_connection(true);
4017 ClientSocketHandle handle4;
4018 TestCompletionCallback callback4;
4019 EXPECT_EQ(ERR_IO_PENDING, handle4.Init("group3",
4020 params_,
4021 HIGHEST,
4022 callback4.callback(),
4023 pool_.get(),
4024 BoundNetLog()));
4025 EXPECT_EQ(OK, callback4.WaitForResult());
4026 EXPECT_FALSE(callback3.have_result());
4027
4028 // Closing a handle should free up another socket slot.
4029 handle1.Reset();
4030 EXPECT_EQ(OK, callback3.WaitForResult());
4031}
4032
4033TEST_F(ClientSocketPoolBaseTest,
4034 CloseMultipleIdleSocketsHeldByLayeredPoolWhenNeeded) {
4035 CreatePool(1, 1);
4036 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4037
4038 MockLayeredPool mock_layered_pool1(pool_.get(), "foo");
4039 EXPECT_EQ(OK, mock_layered_pool1.RequestSocket(pool_.get()));
4040 EXPECT_CALL(mock_layered_pool1, CloseOneIdleConnection())
4041 .WillRepeatedly(Invoke(&mock_layered_pool1,
4042 &MockLayeredPool::ReleaseOneConnection));
4043 MockLayeredPool mock_layered_pool2(pool_.get(), "bar");
4044 EXPECT_EQ(OK, mock_layered_pool2.RequestSocketWithoutLimits(pool_.get()));
4045 EXPECT_CALL(mock_layered_pool2, CloseOneIdleConnection())
4046 .WillRepeatedly(Invoke(&mock_layered_pool2,
4047 &MockLayeredPool::ReleaseOneConnection));
4048 ClientSocketHandle handle;
4049 TestCompletionCallback callback;
4050 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
4051 params_,
[email protected]bb1c4662013-11-14 00:00:074052 DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:204053 callback.callback(),
4054 pool_.get(),
4055 BoundNetLog()));
4056 EXPECT_EQ(OK, callback.WaitForResult());
4057}
4058
[email protected]b021ece62013-06-11 11:06:334059// Test that when a socket pool and group are at their limits, a request
4060// with |ignore_limits| triggers creation of a new socket, and gets the socket
4061// instead of a request with the same priority that was issued earlier, but
4062// that does not have |ignore_limits| set.
4063TEST_F(ClientSocketPoolBaseTest, IgnoreLimits) {
[email protected]bb1c4662013-11-14 00:00:074064 scoped_refptr<TestSocketParams> params_ignore_limits(
4065 new TestSocketParams(true /* ignore_limits */));
[email protected]b021ece62013-06-11 11:06:334066 CreatePool(1, 1);
4067
4068 // Issue a request to reach the socket pool limit.
[email protected]bb1c4662013-11-14 00:00:074069 EXPECT_EQ(OK, StartRequestWithParams("a", MAXIMUM_PRIORITY, params_));
[email protected]b021ece62013-06-11 11:06:334070 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4071
4072 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4073
[email protected]bb1c4662013-11-14 00:00:074074 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithParams("a", MAXIMUM_PRIORITY,
[email protected]b021ece62013-06-11 11:06:334075 params_));
4076 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4077
[email protected]bb1c4662013-11-14 00:00:074078 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithParams("a", MAXIMUM_PRIORITY,
[email protected]b021ece62013-06-11 11:06:334079 params_ignore_limits));
4080 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4081
4082 EXPECT_EQ(OK, request(2)->WaitForResult());
4083 EXPECT_FALSE(request(1)->have_result());
4084}
4085
[email protected]c55fabd2013-11-04 23:26:564086// Test that when a socket pool and group are at their limits, a ConnectJob
4087// issued for a request with |ignore_limits| set is not cancelled when a request
4088// without |ignore_limits| issued to the same group is cancelled.
4089TEST_F(ClientSocketPoolBaseTest, IgnoreLimitsCancelOtherJob) {
[email protected]bb1c4662013-11-14 00:00:074090 scoped_refptr<TestSocketParams> params_ignore_limits(
4091 new TestSocketParams(true /* ignore_limits */));
[email protected]c55fabd2013-11-04 23:26:564092 CreatePool(1, 1);
4093
4094 // Issue a request to reach the socket pool limit.
[email protected]bb1c4662013-11-14 00:00:074095 EXPECT_EQ(OK, StartRequestWithParams("a", MAXIMUM_PRIORITY, params_));
[email protected]c55fabd2013-11-04 23:26:564096 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4097
4098 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4099
[email protected]bb1c4662013-11-14 00:00:074100 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithParams("a", MAXIMUM_PRIORITY,
4101 params_));
[email protected]c55fabd2013-11-04 23:26:564102 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4103
[email protected]bb1c4662013-11-14 00:00:074104 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithParams("a", MAXIMUM_PRIORITY,
[email protected]b021ece62013-06-11 11:06:334105 params_ignore_limits));
4106 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4107
4108 // Cancel the pending request without ignore_limits set. The ConnectJob
4109 // should not be cancelled.
4110 request(1)->handle()->Reset();
4111 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4112
4113 EXPECT_EQ(OK, request(2)->WaitForResult());
4114 EXPECT_FALSE(request(1)->have_result());
4115}
4116
[email protected]f6d1d6eb2009-06-24 20:16:094117} // namespace
4118
4119} // namespace net