blob: 391fb61e6d0557b28932f96059d13bf8db2b30ff [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]ac790b42009-12-02 04:31:3124#include "net/base/request_priority.h"
[email protected]f6d1d6eb2009-06-24 20:16:0925#include "net/base/test_completion_callback.h"
[email protected]277d5942010-08-11 21:02:3526#include "net/http/http_response_headers.h"
eroman87c53d62015-04-02 06:51:0727#include "net/log/net_log.h"
28#include "net/log/net_log_unittest.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]75439d3b2009-07-23 22:11:1731#include "net/socket/socket_test_util.h"
[email protected]18ccfdb2013-08-15 00:13:4432#include "net/socket/ssl_client_socket.h"
[email protected]3268023f2011-05-05 00:08:1033#include "net/socket/stream_socket.h"
[email protected]18ccfdb2013-08-15 00:13:4434#include "net/udp/datagram_client_socket.h"
[email protected]51fdc7c2012-04-10 19:19:4835#include "testing/gmock/include/gmock/gmock.h"
[email protected]f6d1d6eb2009-06-24 20:16:0936#include "testing/gtest/include/gtest/gtest.h"
37
[email protected]51fdc7c2012-04-10 19:19:4838using ::testing::Invoke;
39using ::testing::Return;
40
[email protected]f6d1d6eb2009-06-24 20:16:0941namespace net {
42
43namespace {
44
[email protected]211d21722009-07-22 15:48:5345const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2046const int kDefaultMaxSocketsPerGroup = 2;
[email protected]0b7648c2009-07-06 20:14:0147
[email protected]034df0f32013-01-07 23:17:4848// Make sure |handle| sets load times correctly when it has been assigned a
49// reused socket.
50void TestLoadTimingInfoConnectedReused(const ClientSocketHandle& handle) {
51 LoadTimingInfo load_timing_info;
52 // Only pass true in as |is_reused|, as in general, HttpStream types should
53 // have stricter concepts of reuse than socket pools.
54 EXPECT_TRUE(handle.GetLoadTimingInfo(true, &load_timing_info));
55
56 EXPECT_EQ(true, load_timing_info.socket_reused);
57 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
58
[email protected]b258e0792013-01-12 07:11:5959 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
60 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:4861}
62
63// Make sure |handle| sets load times correctly when it has been assigned a
[email protected]b021ece62013-06-11 11:06:3364// fresh socket. Also runs TestLoadTimingInfoConnectedReused, since the owner
[email protected]034df0f32013-01-07 23:17:4865// of a connection where |is_reused| is false may consider the connection
66// reused.
67void TestLoadTimingInfoConnectedNotReused(const ClientSocketHandle& handle) {
68 EXPECT_FALSE(handle.is_reused());
69
70 LoadTimingInfo load_timing_info;
71 EXPECT_TRUE(handle.GetLoadTimingInfo(false, &load_timing_info));
72
73 EXPECT_FALSE(load_timing_info.socket_reused);
74 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
75
[email protected]b258e0792013-01-12 07:11:5976 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
77 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
78 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:4879
80 TestLoadTimingInfoConnectedReused(handle);
81}
82
83// Make sure |handle| sets load times correctly, in the case that it does not
84// currently have a socket.
85void TestLoadTimingInfoNotConnected(const ClientSocketHandle& handle) {
86 // Should only be set to true once a socket is assigned, if at all.
87 EXPECT_FALSE(handle.is_reused());
88
89 LoadTimingInfo load_timing_info;
90 EXPECT_FALSE(handle.GetLoadTimingInfo(false, &load_timing_info));
91
92 EXPECT_FALSE(load_timing_info.socket_reused);
93 EXPECT_EQ(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
94
[email protected]b258e0792013-01-12 07:11:5995 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
96 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:4897}
98
[email protected]df4b4ef2010-07-12 18:25:2199class TestSocketParams : public base::RefCounted<TestSocketParams> {
[email protected]5acdce12011-03-30 13:00:20100 public:
[email protected]bb1c4662013-11-14 00:00:07101 explicit TestSocketParams(bool ignore_limits)
102 : ignore_limits_(ignore_limits) {}
[email protected]51fdc7c2012-04-10 19:19:48103
[email protected]51fdc7c2012-04-10 19:19:48104 bool ignore_limits() { return ignore_limits_; }
105
[email protected]df4b4ef2010-07-12 18:25:21106 private:
107 friend class base::RefCounted<TestSocketParams>;
108 ~TestSocketParams() {}
[email protected]51fdc7c2012-04-10 19:19:48109
[email protected]bb1c4662013-11-14 00:00:07110 const bool ignore_limits_;
[email protected]df4b4ef2010-07-12 18:25:21111};
[email protected]7fc5b09a2010-02-27 00:07:38112typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
[email protected]d80a4322009-08-14 07:07:49113
[email protected]3268023f2011-05-05 00:08:10114class MockClientSocket : public StreamSocket {
[email protected]f6d1d6eb2009-06-24 20:16:09115 public:
[email protected]034df0f32013-01-07 23:17:48116 explicit MockClientSocket(net::NetLog* net_log)
117 : connected_(false),
[email protected]0dc88b32014-03-26 20:12:28118 has_unread_data_(false),
[email protected]034df0f32013-01-07 23:17:48119 net_log_(BoundNetLog::Make(net_log, net::NetLog::SOURCE_SOCKET)),
[email protected]e86df8dc2013-03-30 13:18:28120 was_used_to_convey_data_(false) {
[email protected]034df0f32013-01-07 23:17:48121 }
[email protected]f6d1d6eb2009-06-24 20:16:09122
[email protected]0dc88b32014-03-26 20:12:28123 // Sets whether the socket has unread data. If true, the next call to Read()
124 // will return 1 byte and IsConnectedAndIdle() will return false.
125 void set_has_unread_data(bool has_unread_data) {
126 has_unread_data_ = has_unread_data;
127 }
128
[email protected]3f55aa12011-12-07 02:03:33129 // Socket implementation.
dchengb03027d2014-10-21 12:00:20130 int Read(IOBuffer* /* buf */,
131 int len,
132 const CompletionCallback& /* callback */) override {
[email protected]0dc88b32014-03-26 20:12:28133 if (has_unread_data_ && len > 0) {
134 has_unread_data_ = false;
135 was_used_to_convey_data_ = true;
136 return 1;
137 }
[email protected]e86df8dc2013-03-30 13:18:28138 return ERR_UNEXPECTED;
[email protected]3f55aa12011-12-07 02:03:33139 }
[email protected]ab838892009-06-30 18:49:05140
dchengb03027d2014-10-21 12:00:20141 int Write(IOBuffer* /* buf */,
142 int len,
143 const CompletionCallback& /* callback */) override {
[email protected]0f873e82010-09-02 16:09:01144 was_used_to_convey_data_ = true;
145 return len;
[email protected]ab838892009-06-30 18:49:05146 }
dchengb03027d2014-10-21 12:00:20147 int SetReceiveBufferSize(int32 size) override { return OK; }
148 int SetSendBufferSize(int32 size) override { return OK; }
[email protected]ab838892009-06-30 18:49:05149
[email protected]dbf036f2011-12-06 23:33:24150 // StreamSocket implementation.
dchengb03027d2014-10-21 12:00:20151 int Connect(const CompletionCallback& callback) override {
[email protected]dbf036f2011-12-06 23:33:24152 connected_ = true;
153 return OK;
154 }
[email protected]f6d1d6eb2009-06-24 20:16:09155
dchengb03027d2014-10-21 12:00:20156 void Disconnect() override { connected_ = false; }
157 bool IsConnected() const override { return connected_; }
158 bool IsConnectedAndIdle() const override {
[email protected]0dc88b32014-03-26 20:12:28159 return connected_ && !has_unread_data_;
160 }
[email protected]0b7648c2009-07-06 20:14:01161
dchengb03027d2014-10-21 12:00:20162 int GetPeerAddress(IPEndPoint* /* address */) const override {
[email protected]9f864b32010-01-20 15:01:16163 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:09164 }
[email protected]f6d1d6eb2009-06-24 20:16:09165
dchengb03027d2014-10-21 12:00:20166 int GetLocalAddress(IPEndPoint* /* address */) const override {
[email protected]e7f74da2011-04-19 23:49:35167 return ERR_UNEXPECTED;
168 }
169
dchengb03027d2014-10-21 12:00:20170 const BoundNetLog& NetLog() const override { return net_log_; }
[email protected]a2006ece2010-04-23 16:44:02171
dchengb03027d2014-10-21 12:00:20172 void SetSubresourceSpeculation() override {}
173 void SetOmniboxSpeculation() override {}
174 bool WasEverUsed() const override { return was_used_to_convey_data_; }
175 bool UsingTCPFastOpen() const override { return false; }
176 bool WasNpnNegotiated() const override { return false; }
177 NextProto GetNegotiatedProtocol() const override { return kProtoUnknown; }
178 bool GetSSLInfo(SSLInfo* ssl_info) override { return false; }
[email protected]9b5614a2010-08-25 20:29:45179
[email protected]f6d1d6eb2009-06-24 20:16:09180 private:
181 bool connected_;
[email protected]0dc88b32014-03-26 20:12:28182 bool has_unread_data_;
[email protected]a2006ece2010-04-23 16:44:02183 BoundNetLog net_log_;
[email protected]0f873e82010-09-02 16:09:01184 bool was_used_to_convey_data_;
[email protected]f6d1d6eb2009-06-24 20:16:09185
[email protected]ab838892009-06-30 18:49:05186 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:09187};
188
[email protected]5fc08e32009-07-15 17:09:57189class TestConnectJob;
190
[email protected]f6d1d6eb2009-06-24 20:16:09191class MockClientSocketFactory : public ClientSocketFactory {
192 public:
[email protected]ab838892009-06-30 18:49:05193 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:09194
dchengb03027d2014-10-21 12:00:20195 scoped_ptr<DatagramClientSocket> CreateDatagramClientSocket(
[email protected]5370c012011-06-29 03:47:04196 DatagramSocket::BindType bind_type,
197 const RandIntCallback& rand_int_cb,
[email protected]98b0e582011-06-22 14:31:41198 NetLog* net_log,
mostynbba063d6032014-10-09 11:01:13199 const NetLog::Source& source) override {
[email protected]98b0e582011-06-22 14:31:41200 NOTREACHED();
[email protected]18ccfdb2013-08-15 00:13:44201 return scoped_ptr<DatagramClientSocket>();
[email protected]98b0e582011-06-22 14:31:41202 }
203
dchengb03027d2014-10-21 12:00:20204 scoped_ptr<StreamSocket> CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07205 const AddressList& addresses,
206 NetLog* /* net_log */,
mostynbba063d6032014-10-09 11:01:13207 const NetLog::Source& /*source*/) override {
[email protected]f6d1d6eb2009-06-24 20:16:09208 allocation_count_++;
[email protected]18ccfdb2013-08-15 00:13:44209 return scoped_ptr<StreamSocket>();
[email protected]f6d1d6eb2009-06-24 20:16:09210 }
211
dchengb03027d2014-10-21 12:00:20212 scoped_ptr<SSLClientSocket> CreateSSLClientSocket(
[email protected]18ccfdb2013-08-15 00:13:44213 scoped_ptr<ClientSocketHandle> transport_socket,
[email protected]4f4de7e62010-11-12 19:55:27214 const HostPortPair& host_and_port,
[email protected]7ab5bbd12010-10-19 13:33:21215 const SSLConfig& ssl_config,
mostynbba063d6032014-10-09 11:01:13216 const SSLClientSocketContext& context) override {
[email protected]f6d1d6eb2009-06-24 20:16:09217 NOTIMPLEMENTED();
[email protected]18ccfdb2013-08-15 00:13:44218 return scoped_ptr<SSLClientSocket>();
[email protected]f6d1d6eb2009-06-24 20:16:09219 }
220
dchengb03027d2014-10-21 12:00:20221 void ClearSSLSessionCache() override { NOTIMPLEMENTED(); }
[email protected]25f47352011-02-25 16:31:59222
[email protected]5fc08e32009-07-15 17:09:57223 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
[email protected]03b7c8c2013-07-20 04:38:55224
[email protected]5fc08e32009-07-15 17:09:57225 void SignalJobs();
226
[email protected]03b7c8c2013-07-20 04:38:55227 void SignalJob(size_t job);
228
229 void SetJobLoadState(size_t job, LoadState load_state);
230
[email protected]f6d1d6eb2009-06-24 20:16:09231 int allocation_count() const { return allocation_count_; }
232
[email protected]f6d1d6eb2009-06-24 20:16:09233 private:
234 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:57235 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09236};
237
[email protected]ab838892009-06-30 18:49:05238class TestConnectJob : public ConnectJob {
239 public:
240 enum JobType {
241 kMockJob,
242 kMockFailingJob,
243 kMockPendingJob,
244 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57245 kMockWaitingJob,
[email protected]e772db3f2010-07-12 18:11:13246 kMockRecoverableJob,
247 kMockPendingRecoverableJob,
[email protected]e60e47a2010-07-14 03:37:18248 kMockAdditionalErrorStateJob,
249 kMockPendingAdditionalErrorStateJob,
[email protected]0dc88b32014-03-26 20:12:28250 kMockUnreadDataJob,
[email protected]ab838892009-06-30 18:49:05251 };
252
[email protected]994d4932010-07-12 17:55:13253 // The kMockPendingJob uses a slight delay before allowing the connect
254 // to complete.
255 static const int kPendingConnectDelay = 2;
256
[email protected]ab838892009-06-30 18:49:05257 TestConnectJob(JobType job_type,
258 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49259 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34260 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05261 ConnectJob::Delegate* delegate,
[email protected]fd7b7c92009-08-20 19:38:30262 MockClientSocketFactory* client_socket_factory,
[email protected]06650c52010-06-03 00:49:17263 NetLog* net_log)
[email protected]3f6007ab2013-08-22 19:45:39264 : ConnectJob(group_name, timeout_duration, request.priority(), delegate,
[email protected]06650c52010-06-03 00:49:17265 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
[email protected]2ab05b52009-07-01 23:57:58266 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05267 client_socket_factory_(client_socket_factory),
[email protected]e60e47a2010-07-14 03:37:18268 load_state_(LOAD_STATE_IDLE),
[email protected]d5492c52013-11-10 20:44:39269 store_additional_error_state_(false),
270 weak_factory_(this) {
271 }
[email protected]ab838892009-06-30 18:49:05272
[email protected]974ebd62009-08-03 23:14:34273 void Signal() {
[email protected]e772db3f2010-07-12 18:11:13274 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
[email protected]974ebd62009-08-03 23:14:34275 }
276
[email protected]03b7c8c2013-07-20 04:38:55277 void set_load_state(LoadState load_state) { load_state_ = load_state; }
278
279 // From ConnectJob:
280
dchengb03027d2014-10-21 12:00:20281 LoadState GetLoadState() const override { return load_state_; }
[email protected]46451352009-09-01 14:54:21282
dchengb03027d2014-10-21 12:00:20283 void GetAdditionalErrorState(ClientSocketHandle* handle) override {
[email protected]e60e47a2010-07-14 03:37:18284 if (store_additional_error_state_) {
285 // Set all of the additional error state fields in some way.
286 handle->set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43287 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:45288 info.headers = new HttpResponseHeaders(std::string());
[email protected]8b498692010-07-16 17:11:43289 handle->set_ssl_error_response_info(info);
[email protected]e60e47a2010-07-14 03:37:18290 }
291 }
292
[email protected]974ebd62009-08-03 23:14:34293 private:
[email protected]03b7c8c2013-07-20 04:38:55294 // From ConnectJob:
[email protected]ab838892009-06-30 18:49:05295
dchengb03027d2014-10-21 12:00:20296 int ConnectInternal() override {
[email protected]ab838892009-06-30 18:49:05297 AddressList ignored;
[email protected]ab739042011-04-07 15:22:28298 client_socket_factory_->CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07299 ignored, NULL, net::NetLog::Source());
[email protected]18ccfdb2013-08-15 00:13:44300 SetSocket(
301 scoped_ptr<StreamSocket>(new MockClientSocket(net_log().net_log())));
[email protected]ab838892009-06-30 18:49:05302 switch (job_type_) {
303 case kMockJob:
[email protected]e772db3f2010-07-12 18:11:13304 return DoConnect(true /* successful */, false /* sync */,
305 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05306 case kMockFailingJob:
[email protected]e772db3f2010-07-12 18:11:13307 return DoConnect(false /* error */, false /* sync */,
308 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05309 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57310 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47311
312 // Depending on execution timings, posting a delayed task can result
313 // in the task getting executed the at the earliest possible
314 // opportunity or only after returning once from the message loop and
315 // then a second call into the message loop. In order to make behavior
316 // more deterministic, we change the default delay to 2ms. This should
317 // always require us to wait for the second call into the message loop.
318 //
319 // N.B. The correct fix for this and similar timing problems is to
320 // abstract time for the purpose of unittests. Unfortunately, we have
321 // a lot of third-party components that directly call the various
322 // time functions, so this change would be rather invasive.
[email protected]2da659e2013-05-23 20:51:34323 base::MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05324 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13325 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
326 weak_factory_.GetWeakPtr(),
327 true /* successful */,
328 true /* async */,
329 false /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53330 base::TimeDelta::FromMilliseconds(kPendingConnectDelay));
[email protected]ab838892009-06-30 18:49:05331 return ERR_IO_PENDING;
332 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57333 set_load_state(LOAD_STATE_CONNECTING);
[email protected]2da659e2013-05-23 20:51:34334 base::MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05335 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13336 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
337 weak_factory_.GetWeakPtr(),
338 false /* error */,
339 true /* async */,
340 false /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53341 base::TimeDelta::FromMilliseconds(2));
[email protected]ab838892009-06-30 18:49:05342 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57343 case kMockWaitingJob:
[email protected]03b7c8c2013-07-20 04:38:55344 set_load_state(LOAD_STATE_CONNECTING);
[email protected]5fc08e32009-07-15 17:09:57345 client_socket_factory_->WaitForSignal(this);
346 waiting_success_ = true;
347 return ERR_IO_PENDING;
[email protected]e772db3f2010-07-12 18:11:13348 case kMockRecoverableJob:
349 return DoConnect(false /* error */, false /* sync */,
350 true /* recoverable */);
351 case kMockPendingRecoverableJob:
352 set_load_state(LOAD_STATE_CONNECTING);
[email protected]2da659e2013-05-23 20:51:34353 base::MessageLoop::current()->PostDelayedTask(
[email protected]e772db3f2010-07-12 18:11:13354 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13355 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
356 weak_factory_.GetWeakPtr(),
357 false /* error */,
358 true /* async */,
359 true /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53360 base::TimeDelta::FromMilliseconds(2));
[email protected]e772db3f2010-07-12 18:11:13361 return ERR_IO_PENDING;
[email protected]e60e47a2010-07-14 03:37:18362 case kMockAdditionalErrorStateJob:
363 store_additional_error_state_ = true;
364 return DoConnect(false /* error */, false /* sync */,
365 false /* recoverable */);
366 case kMockPendingAdditionalErrorStateJob:
367 set_load_state(LOAD_STATE_CONNECTING);
368 store_additional_error_state_ = true;
[email protected]2da659e2013-05-23 20:51:34369 base::MessageLoop::current()->PostDelayedTask(
[email protected]e60e47a2010-07-14 03:37:18370 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13371 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
372 weak_factory_.GetWeakPtr(),
373 false /* error */,
374 true /* async */,
375 false /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53376 base::TimeDelta::FromMilliseconds(2));
[email protected]e60e47a2010-07-14 03:37:18377 return ERR_IO_PENDING;
[email protected]0dc88b32014-03-26 20:12:28378 case kMockUnreadDataJob: {
379 int ret = DoConnect(true /* successful */, false /* sync */,
380 false /* recoverable */);
381 static_cast<MockClientSocket*>(socket())->set_has_unread_data(true);
382 return ret;
383 }
[email protected]ab838892009-06-30 18:49:05384 default:
385 NOTREACHED();
[email protected]18ccfdb2013-08-15 00:13:44386 SetSocket(scoped_ptr<StreamSocket>());
[email protected]ab838892009-06-30 18:49:05387 return ERR_FAILED;
388 }
389 }
390
[email protected]e772db3f2010-07-12 18:11:13391 int DoConnect(bool succeed, bool was_async, bool recoverable) {
392 int result = OK;
[email protected]ab838892009-06-30 18:49:05393 if (succeed) {
[email protected]83039bb2011-12-09 18:43:55394 socket()->Connect(CompletionCallback());
[email protected]e772db3f2010-07-12 18:11:13395 } else if (recoverable) {
396 result = ERR_PROXY_AUTH_REQUESTED;
[email protected]6e713f02009-08-06 02:56:40397 } else {
[email protected]e772db3f2010-07-12 18:11:13398 result = ERR_CONNECTION_FAILED;
[email protected]18ccfdb2013-08-15 00:13:44399 SetSocket(scoped_ptr<StreamSocket>());
[email protected]ab838892009-06-30 18:49:05400 }
[email protected]2ab05b52009-07-01 23:57:58401
402 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30403 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05404 return result;
405 }
406
[email protected]5fc08e32009-07-15 17:09:57407 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05408 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57409 MockClientSocketFactory* const client_socket_factory_;
[email protected]46451352009-09-01 14:54:21410 LoadState load_state_;
[email protected]e60e47a2010-07-14 03:37:18411 bool store_additional_error_state_;
[email protected]ab838892009-06-30 18:49:05412
[email protected]d5492c52013-11-10 20:44:39413 base::WeakPtrFactory<TestConnectJob> weak_factory_;
414
[email protected]ab838892009-06-30 18:49:05415 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
416};
417
[email protected]d80a4322009-08-14 07:07:49418class TestConnectJobFactory
419 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05420 public:
[email protected]034df0f32013-01-07 23:17:48421 TestConnectJobFactory(MockClientSocketFactory* client_socket_factory,
422 NetLog* net_log)
[email protected]ab838892009-06-30 18:49:05423 : job_type_(TestConnectJob::kMockJob),
[email protected]51fdc7c2012-04-10 19:19:48424 job_types_(NULL),
[email protected]034df0f32013-01-07 23:17:48425 client_socket_factory_(client_socket_factory),
426 net_log_(net_log) {
[email protected]b021ece62013-06-11 11:06:33427 }
[email protected]ab838892009-06-30 18:49:05428
dchengb03027d2014-10-21 12:00:20429 ~TestConnectJobFactory() override {}
[email protected]ab838892009-06-30 18:49:05430
431 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
432
[email protected]51fdc7c2012-04-10 19:19:48433 void set_job_types(std::list<TestConnectJob::JobType>* job_types) {
434 job_types_ = job_types;
435 CHECK(!job_types_->empty());
436 }
437
[email protected]974ebd62009-08-03 23:14:34438 void set_timeout_duration(base::TimeDelta timeout_duration) {
439 timeout_duration_ = timeout_duration;
440 }
441
[email protected]3f55aa12011-12-07 02:03:33442 // ConnectJobFactory implementation.
[email protected]83039bb2011-12-09 18:43:55443
dchengb03027d2014-10-21 12:00:20444 scoped_ptr<ConnectJob> NewConnectJob(
[email protected]ab838892009-06-30 18:49:05445 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49446 const TestClientSocketPoolBase::Request& request,
mostynbba063d6032014-10-09 11:01:13447 ConnectJob::Delegate* delegate) const override {
[email protected]51fdc7c2012-04-10 19:19:48448 EXPECT_TRUE(!job_types_ || !job_types_->empty());
449 TestConnectJob::JobType job_type = job_type_;
450 if (job_types_ && !job_types_->empty()) {
451 job_type = job_types_->front();
452 job_types_->pop_front();
453 }
[email protected]18ccfdb2013-08-15 00:13:44454 return scoped_ptr<ConnectJob>(new TestConnectJob(job_type,
455 group_name,
456 request,
457 timeout_duration_,
458 delegate,
459 client_socket_factory_,
460 net_log_));
[email protected]ab838892009-06-30 18:49:05461 }
462
dchengb03027d2014-10-21 12:00:20463 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26464 return timeout_duration_;
465 }
466
[email protected]ab838892009-06-30 18:49:05467 private:
468 TestConnectJob::JobType job_type_;
[email protected]51fdc7c2012-04-10 19:19:48469 std::list<TestConnectJob::JobType>* job_types_;
[email protected]974ebd62009-08-03 23:14:34470 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57471 MockClientSocketFactory* const client_socket_factory_;
[email protected]034df0f32013-01-07 23:17:48472 NetLog* net_log_;
[email protected]ab838892009-06-30 18:49:05473
474 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
475};
476
477class TestClientSocketPool : public ClientSocketPool {
478 public:
[email protected]12322e7e2013-08-15 17:49:26479 typedef TestSocketParams SocketParams;
480
[email protected]ab838892009-06-30 18:49:05481 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53482 int max_sockets,
[email protected]ab838892009-06-30 18:49:05483 int max_sockets_per_group,
[email protected]9bf28db2009-08-29 01:35:16484 base::TimeDelta unused_idle_socket_timeout,
485 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49486 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
rkaplowd90695c2015-03-25 22:12:41487 : base_(NULL,
488 max_sockets,
489 max_sockets_per_group,
490 unused_idle_socket_timeout,
491 used_idle_socket_timeout,
[email protected]66761b952010-06-25 21:30:38492 connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05493
dchengb03027d2014-10-21 12:00:20494 ~TestClientSocketPool() override {}
[email protected]2431756e2010-09-29 20:26:13495
dchengb03027d2014-10-21 12:00:20496 int RequestSocket(const std::string& group_name,
497 const void* params,
498 net::RequestPriority priority,
499 ClientSocketHandle* handle,
500 const CompletionCallback& callback,
501 const BoundNetLog& net_log) override {
[email protected]df4b4ef2010-07-12 18:25:21502 const scoped_refptr<TestSocketParams>* casted_socket_params =
503 static_cast<const scoped_refptr<TestSocketParams>*>(params);
504 return base_.RequestSocket(group_name, *casted_socket_params, priority,
505 handle, callback, net_log);
[email protected]ab838892009-06-30 18:49:05506 }
507
dchengb03027d2014-10-21 12:00:20508 void RequestSockets(const std::string& group_name,
509 const void* params,
510 int num_sockets,
511 const BoundNetLog& net_log) override {
[email protected]2c2bef152010-10-13 00:55:03512 const scoped_refptr<TestSocketParams>* casted_params =
513 static_cast<const scoped_refptr<TestSocketParams>*>(params);
514
515 base_.RequestSockets(group_name, *casted_params, num_sockets, net_log);
516 }
517
dchengb03027d2014-10-21 12:00:20518 void CancelRequest(const std::string& group_name,
519 ClientSocketHandle* handle) override {
[email protected]d80a4322009-08-14 07:07:49520 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05521 }
522
dchengb03027d2014-10-21 12:00:20523 void ReleaseSocket(const std::string& group_name,
524 scoped_ptr<StreamSocket> socket,
525 int id) override {
[email protected]18ccfdb2013-08-15 00:13:44526 base_.ReleaseSocket(group_name, socket.Pass(), id);
[email protected]a7e38572010-06-07 18:22:24527 }
528
dchengb03027d2014-10-21 12:00:20529 void FlushWithError(int error) override { base_.FlushWithError(error); }
[email protected]ab838892009-06-30 18:49:05530
dchengb03027d2014-10-21 12:00:20531 bool IsStalled() const override { return base_.IsStalled(); }
[email protected]51fdc7c2012-04-10 19:19:48532
dchengb03027d2014-10-21 12:00:20533 void CloseIdleSockets() override { base_.CloseIdleSockets(); }
[email protected]ab838892009-06-30 18:49:05534
dchengb03027d2014-10-21 12:00:20535 int IdleSocketCount() const override { return base_.idle_socket_count(); }
[email protected]ab838892009-06-30 18:49:05536
dchengb03027d2014-10-21 12:00:20537 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]d80a4322009-08-14 07:07:49538 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05539 }
540
dchengb03027d2014-10-21 12:00:20541 LoadState GetLoadState(const std::string& group_name,
542 const ClientSocketHandle* handle) const override {
[email protected]d80a4322009-08-14 07:07:49543 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05544 }
545
dchengb03027d2014-10-21 12:00:20546 void AddHigherLayeredPool(HigherLayeredPool* higher_pool) override {
[email protected]043b68c82013-08-22 23:41:52547 base_.AddHigherLayeredPool(higher_pool);
[email protected]51fdc7c2012-04-10 19:19:48548 }
549
dchengb03027d2014-10-21 12:00:20550 void RemoveHigherLayeredPool(HigherLayeredPool* higher_pool) override {
[email protected]043b68c82013-08-22 23:41:52551 base_.RemoveHigherLayeredPool(higher_pool);
[email protected]51fdc7c2012-04-10 19:19:48552 }
553
dchengb03027d2014-10-21 12:00:20554 base::DictionaryValue* GetInfoAsValue(
[email protected]d4dfdab2011-12-07 16:56:59555 const std::string& name,
556 const std::string& type,
mostynbba063d6032014-10-09 11:01:13557 bool include_nested_pools) const override {
[email protected]59d7a5a2010-08-30 16:44:27558 return base_.GetInfoAsValue(name, type);
559 }
560
dchengb03027d2014-10-21 12:00:20561 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26562 return base_.ConnectionTimeout();
563 }
564
[email protected]d80a4322009-08-14 07:07:49565 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20566
[email protected]8159a1c2012-06-07 00:00:10567 int NumUnassignedConnectJobsInGroup(const std::string& group_name) const {
568 return base_.NumUnassignedConnectJobsInGroup(group_name);
569 }
570
[email protected]974ebd62009-08-03 23:14:34571 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49572 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34573 }
574
[email protected]2c2bef152010-10-13 00:55:03575 int NumActiveSocketsInGroup(const std::string& group_name) const {
576 return base_.NumActiveSocketsInGroup(group_name);
577 }
578
[email protected]2abfe90a2010-08-25 17:49:51579 bool HasGroup(const std::string& group_name) const {
580 return base_.HasGroup(group_name);
581 }
582
[email protected]9bf28db2009-08-29 01:35:16583 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
584
[email protected]06d94042010-08-25 01:45:22585 void EnableConnectBackupJobs() { base_.EnableConnectBackupJobs(); }
[email protected]43a21b82010-06-10 21:30:54586
[email protected]043b68c82013-08-22 23:41:52587 bool CloseOneIdleConnectionInHigherLayeredPool() {
588 return base_.CloseOneIdleConnectionInHigherLayeredPool();
[email protected]51fdc7c2012-04-10 19:19:48589 }
590
[email protected]ab838892009-06-30 18:49:05591 private:
[email protected]d80a4322009-08-14 07:07:49592 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05593
594 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
595};
596
[email protected]a937a06d2009-08-19 21:19:24597} // namespace
598
[email protected]a937a06d2009-08-19 21:19:24599namespace {
600
[email protected]5fc08e32009-07-15 17:09:57601void MockClientSocketFactory::SignalJobs() {
602 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
603 it != waiting_jobs_.end(); ++it) {
604 (*it)->Signal();
605 }
606 waiting_jobs_.clear();
607}
608
[email protected]03b7c8c2013-07-20 04:38:55609void MockClientSocketFactory::SignalJob(size_t job) {
610 ASSERT_LT(job, waiting_jobs_.size());
611 waiting_jobs_[job]->Signal();
612 waiting_jobs_.erase(waiting_jobs_.begin() + job);
613}
614
615void MockClientSocketFactory::SetJobLoadState(size_t job,
616 LoadState load_state) {
617 ASSERT_LT(job, waiting_jobs_.size());
618 waiting_jobs_[job]->set_load_state(load_state);
619}
620
[email protected]974ebd62009-08-03 23:14:34621class TestConnectJobDelegate : public ConnectJob::Delegate {
622 public:
623 TestConnectJobDelegate()
624 : have_result_(false), waiting_for_result_(false), result_(OK) {}
dchengb03027d2014-10-21 12:00:20625 ~TestConnectJobDelegate() override {}
[email protected]974ebd62009-08-03 23:14:34626
dchengb03027d2014-10-21 12:00:20627 void OnConnectJobComplete(int result, ConnectJob* job) override {
[email protected]974ebd62009-08-03 23:14:34628 result_ = result;
[email protected]18ccfdb2013-08-15 00:13:44629 scoped_ptr<ConnectJob> owned_job(job);
630 scoped_ptr<StreamSocket> socket = owned_job->PassSocket();
[email protected]9b6fee12009-09-29 18:13:07631 // socket.get() should be NULL iff result != OK
[email protected]18ccfdb2013-08-15 00:13:44632 EXPECT_EQ(socket == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34633 have_result_ = true;
634 if (waiting_for_result_)
[email protected]2da659e2013-05-23 20:51:34635 base::MessageLoop::current()->Quit();
[email protected]974ebd62009-08-03 23:14:34636 }
637
638 int WaitForResult() {
639 DCHECK(!waiting_for_result_);
640 while (!have_result_) {
641 waiting_for_result_ = true;
[email protected]2da659e2013-05-23 20:51:34642 base::MessageLoop::current()->Run();
[email protected]974ebd62009-08-03 23:14:34643 waiting_for_result_ = false;
644 }
645 have_result_ = false; // auto-reset for next callback
646 return result_;
647 }
648
649 private:
650 bool have_result_;
651 bool waiting_for_result_;
652 int result_;
653};
654
[email protected]2431756e2010-09-29 20:26:13655class ClientSocketPoolBaseTest : public testing::Test {
[email protected]f6d1d6eb2009-06-24 20:16:09656 protected:
[email protected]b89f7e42010-05-20 20:37:00657 ClientSocketPoolBaseTest()
rkaplowd90695c2015-03-25 22:12:41658 : params_(new TestSocketParams(false /* ignore_limits */)) {
[email protected]636b8252011-04-08 19:56:54659 connect_backup_jobs_enabled_ =
660 internal::ClientSocketPoolBaseHelper::connect_backup_jobs_enabled();
661 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(true);
[email protected]64770b7d2011-11-16 04:30:41662 cleanup_timer_enabled_ =
663 internal::ClientSocketPoolBaseHelper::cleanup_timer_enabled();
[email protected]636b8252011-04-08 19:56:54664 }
[email protected]2431756e2010-09-29 20:26:13665
dcheng67be2b1f2014-10-27 21:47:29666 ~ClientSocketPoolBaseTest() override {
[email protected]636b8252011-04-08 19:56:54667 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
668 connect_backup_jobs_enabled_);
[email protected]64770b7d2011-11-16 04:30:41669 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(
670 cleanup_timer_enabled_);
[email protected]636b8252011-04-08 19:56:54671 }
[email protected]c9d6a1d2009-07-14 16:15:20672
[email protected]211d21722009-07-22 15:48:53673 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16674 CreatePoolWithIdleTimeouts(
675 max_sockets,
676 max_sockets_per_group,
[email protected]82b8c962011-10-12 09:17:30677 ClientSocketPool::unused_idle_socket_timeout(),
678 ClientSocketPool::used_idle_socket_timeout());
[email protected]9bf28db2009-08-29 01:35:16679 }
680
681 void CreatePoolWithIdleTimeouts(
682 int max_sockets, int max_sockets_per_group,
683 base::TimeDelta unused_idle_socket_timeout,
684 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20685 DCHECK(!pool_.get());
[email protected]034df0f32013-01-07 23:17:48686 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_,
687 &net_log_);
[email protected]2431756e2010-09-29 20:26:13688 pool_.reset(new TestClientSocketPool(max_sockets,
689 max_sockets_per_group,
[email protected]2431756e2010-09-29 20:26:13690 unused_idle_socket_timeout,
691 used_idle_socket_timeout,
692 connect_job_factory_));
[email protected]c9d6a1d2009-07-14 16:15:20693 }
[email protected]f6d1d6eb2009-06-24 20:16:09694
[email protected]b021ece62013-06-11 11:06:33695 int StartRequestWithParams(
696 const std::string& group_name,
697 RequestPriority priority,
698 const scoped_refptr<TestSocketParams>& params) {
[email protected]12322e7e2013-08-15 17:49:26699 return test_base_.StartRequestUsingPool(
700 pool_.get(), group_name, priority, params);
[email protected]b021ece62013-06-11 11:06:33701 }
702
703 int StartRequest(const std::string& group_name, RequestPriority priority) {
704 return StartRequestWithParams(group_name, priority, params_);
[email protected]f6d1d6eb2009-06-24 20:16:09705 }
706
[email protected]2431756e2010-09-29 20:26:13707 int GetOrderOfRequest(size_t index) const {
708 return test_base_.GetOrderOfRequest(index);
[email protected]f6d1d6eb2009-06-24 20:16:09709 }
710
[email protected]2431756e2010-09-29 20:26:13711 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
712 return test_base_.ReleaseOneConnection(keep_alive);
713 }
714
715 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
716 test_base_.ReleaseAllConnections(keep_alive);
717 }
718
719 TestSocketRequest* request(int i) { return test_base_.request(i); }
720 size_t requests_size() const { return test_base_.requests_size(); }
721 ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); }
722 size_t completion_count() const { return test_base_.completion_count(); }
723
[email protected]034df0f32013-01-07 23:17:48724 CapturingNetLog net_log_;
[email protected]636b8252011-04-08 19:56:54725 bool connect_backup_jobs_enabled_;
[email protected]64770b7d2011-11-16 04:30:41726 bool cleanup_timer_enabled_;
[email protected]f6d1d6eb2009-06-24 20:16:09727 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04728 TestConnectJobFactory* connect_job_factory_;
[email protected]df4b4ef2010-07-12 18:25:21729 scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:13730 scoped_ptr<TestClientSocketPool> pool_;
731 ClientSocketPoolTest test_base_;
[email protected]f6d1d6eb2009-06-24 20:16:09732};
733
[email protected]974ebd62009-08-03 23:14:34734// Even though a timeout is specified, it doesn't time out on a synchronous
735// completion.
736TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
737 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06738 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49739 TestClientSocketPoolBase::Request request(
[email protected]bb1c4662013-11-14 00:00:07740 &ignored, CompletionCallback(), DEFAULT_PRIORITY,
[email protected]2c2bef152010-10-13 00:55:03741 internal::ClientSocketPoolBaseHelper::NORMAL,
[email protected]5acdce12011-03-30 13:00:20742 false, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34743 scoped_ptr<TestConnectJob> job(
744 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:12745 "a",
[email protected]974ebd62009-08-03 23:14:34746 request,
747 base::TimeDelta::FromMicroseconds(1),
748 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30749 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17750 NULL));
[email protected]974ebd62009-08-03 23:14:34751 EXPECT_EQ(OK, job->Connect());
752}
753
754TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
755 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06756 ClientSocketHandle ignored;
[email protected]333bdf62012-06-08 22:57:29757 CapturingNetLog log;
[email protected]9e743cd2010-03-16 07:03:53758
[email protected]d80a4322009-08-14 07:07:49759 TestClientSocketPoolBase::Request request(
[email protected]bb1c4662013-11-14 00:00:07760 &ignored, CompletionCallback(), DEFAULT_PRIORITY,
[email protected]2c2bef152010-10-13 00:55:03761 internal::ClientSocketPoolBaseHelper::NORMAL,
[email protected]5acdce12011-03-30 13:00:20762 false, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34763 // Deleted by TestConnectJobDelegate.
764 TestConnectJob* job =
765 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12766 "a",
[email protected]974ebd62009-08-03 23:14:34767 request,
768 base::TimeDelta::FromMicroseconds(1),
769 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30770 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17771 &log);
[email protected]974ebd62009-08-03 23:14:34772 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
[email protected]26b9973962012-01-28 00:57:00773 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
[email protected]974ebd62009-08-03 23:14:34774 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30775
[email protected]333bdf62012-06-08 22:57:29776 CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:40777 log.GetEntries(&entries);
778
779 EXPECT_EQ(6u, entries.size());
[email protected]e9002a92010-01-29 07:10:46780 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40781 entries, 0, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]06650c52010-06-03 00:49:17782 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40783 entries, 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]e9002a92010-01-29 07:10:46784 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40785 entries, 2, NetLog::TYPE_CONNECT_JOB_SET_SOCKET,
[email protected]06650c52010-06-03 00:49:17786 NetLog::PHASE_NONE));
787 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40788 entries, 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
[email protected]9e743cd2010-03-16 07:03:53789 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:46790 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40791 entries, 4, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]06650c52010-06-03 00:49:17792 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40793 entries, 5, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34794}
795
[email protected]5fc08e32009-07-15 17:09:57796TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53797 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20798
[email protected]6ecf2b92011-12-15 01:14:52799 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06800 ClientSocketHandle handle;
[email protected]333bdf62012-06-08 22:57:29801 CapturingBoundNetLog log;
[email protected]034df0f32013-01-07 23:17:48802 TestLoadTimingInfoNotConnected(handle);
[email protected]9e743cd2010-03-16 07:03:53803
[email protected]2431756e2010-09-29 20:26:13804 EXPECT_EQ(OK,
805 handle.Init("a",
806 params_,
[email protected]bb1c4662013-11-14 00:00:07807 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:52808 callback.callback(),
[email protected]2431756e2010-09-29 20:26:13809 pool_.get(),
810 log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09811 EXPECT_TRUE(handle.is_initialized());
812 EXPECT_TRUE(handle.socket());
[email protected]034df0f32013-01-07 23:17:48813 TestLoadTimingInfoConnectedNotReused(handle);
814
[email protected]f6d1d6eb2009-06-24 20:16:09815 handle.Reset();
[email protected]034df0f32013-01-07 23:17:48816 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:30817
[email protected]333bdf62012-06-08 22:57:29818 CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:40819 log.GetEntries(&entries);
820
821 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:46822 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40823 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]9e743cd2010-03-16 07:03:53824 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40825 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:17826 NetLog::PHASE_NONE));
827 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40828 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]9e743cd2010-03-16 07:03:53829 NetLog::PHASE_NONE));
830 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40831 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09832}
833
[email protected]ab838892009-06-30 18:49:05834TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53835 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20836
[email protected]ab838892009-06-30 18:49:05837 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]333bdf62012-06-08 22:57:29838 CapturingBoundNetLog log;
[email protected]9e743cd2010-03-16 07:03:53839
[email protected]2431756e2010-09-29 20:26:13840 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:52841 TestCompletionCallback callback;
[email protected]e60e47a2010-07-14 03:37:18842 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:13843 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43844 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:45845 info.headers = new HttpResponseHeaders(std::string());
[email protected]2431756e2010-09-29 20:26:13846 handle.set_ssl_error_response_info(info);
847 EXPECT_EQ(ERR_CONNECTION_FAILED,
848 handle.Init("a",
849 params_,
[email protected]bb1c4662013-11-14 00:00:07850 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:52851 callback.callback(),
[email protected]2431756e2010-09-29 20:26:13852 pool_.get(),
853 log.bound()));
854 EXPECT_FALSE(handle.socket());
855 EXPECT_FALSE(handle.is_ssl_error());
856 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]034df0f32013-01-07 23:17:48857 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:30858
[email protected]333bdf62012-06-08 22:57:29859 CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:40860 log.GetEntries(&entries);
861
862 EXPECT_EQ(3u, entries.size());
[email protected]5a1d7ca2010-04-28 20:12:27863 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40864 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:17865 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40866 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:17867 NetLog::PHASE_NONE));
[email protected]a2006ece2010-04-23 16:44:02868 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40869 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09870}
871
[email protected]211d21722009-07-22 15:48:53872TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
873 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
874
[email protected]9e743cd2010-03-16 07:03:53875 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30876
[email protected]bb1c4662013-11-14 00:00:07877 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
878 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
879 EXPECT_EQ(OK, StartRequest("c", DEFAULT_PRIORITY));
880 EXPECT_EQ(OK, StartRequest("d", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:53881
[email protected]2431756e2010-09-29 20:26:13882 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53883 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13884 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53885
[email protected]bb1c4662013-11-14 00:00:07886 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", DEFAULT_PRIORITY));
887 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", DEFAULT_PRIORITY));
888 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:53889
[email protected]2431756e2010-09-29 20:26:13890 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53891
[email protected]2431756e2010-09-29 20:26:13892 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53893 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13894 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53895
896 EXPECT_EQ(1, GetOrderOfRequest(1));
897 EXPECT_EQ(2, GetOrderOfRequest(2));
898 EXPECT_EQ(3, GetOrderOfRequest(3));
899 EXPECT_EQ(4, GetOrderOfRequest(4));
900 EXPECT_EQ(5, GetOrderOfRequest(5));
901 EXPECT_EQ(6, GetOrderOfRequest(6));
902 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17903
904 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13905 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53906}
907
908TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
909 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
910
[email protected]9e743cd2010-03-16 07:03:53911 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30912
[email protected]211d21722009-07-22 15:48:53913 // Reach all limits: max total sockets, and max sockets per group.
[email protected]bb1c4662013-11-14 00:00:07914 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
915 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
916 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
917 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:53918
[email protected]2431756e2010-09-29 20:26:13919 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53920 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13921 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53922
923 // Now create a new group and verify that we don't starve it.
[email protected]bb1c4662013-11-14 00:00:07924 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:53925
[email protected]2431756e2010-09-29 20:26:13926 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53927
[email protected]2431756e2010-09-29 20:26:13928 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53929 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13930 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53931
932 EXPECT_EQ(1, GetOrderOfRequest(1));
933 EXPECT_EQ(2, GetOrderOfRequest(2));
934 EXPECT_EQ(3, GetOrderOfRequest(3));
935 EXPECT_EQ(4, GetOrderOfRequest(4));
936 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17937
938 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13939 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53940}
941
942TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
943 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
944
[email protected]ac790b42009-12-02 04:31:31945 EXPECT_EQ(OK, StartRequest("b", LOWEST));
946 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
947 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
948 EXPECT_EQ(OK, StartRequest("a", LOWEST));
[email protected]211d21722009-07-22 15:48:53949
[email protected]2431756e2010-09-29 20:26:13950 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53951 client_socket_factory_.allocation_count());
952
[email protected]ac790b42009-12-02 04:31:31953 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
954 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
955 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53956
[email protected]2431756e2010-09-29 20:26:13957 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53958
[email protected]2431756e2010-09-29 20:26:13959 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53960
961 // First 4 requests don't have to wait, and finish in order.
962 EXPECT_EQ(1, GetOrderOfRequest(1));
963 EXPECT_EQ(2, GetOrderOfRequest(2));
964 EXPECT_EQ(3, GetOrderOfRequest(3));
965 EXPECT_EQ(4, GetOrderOfRequest(4));
966
[email protected]ac790b42009-12-02 04:31:31967 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
968 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53969 EXPECT_EQ(7, GetOrderOfRequest(5));
970 EXPECT_EQ(6, GetOrderOfRequest(6));
971 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17972
973 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13974 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]211d21722009-07-22 15:48:53975}
976
977TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
978 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
979
[email protected]ac790b42009-12-02 04:31:31980 EXPECT_EQ(OK, StartRequest("a", LOWEST));
981 EXPECT_EQ(OK, StartRequest("a", LOW));
982 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
983 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
[email protected]211d21722009-07-22 15:48:53984
[email protected]2431756e2010-09-29 20:26:13985 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53986 client_socket_factory_.allocation_count());
987
[email protected]ac790b42009-12-02 04:31:31988 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
989 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
990 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53991
[email protected]2431756e2010-09-29 20:26:13992 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53993
[email protected]2431756e2010-09-29 20:26:13994 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53995 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13996 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53997
998 // First 4 requests don't have to wait, and finish in order.
999 EXPECT_EQ(1, GetOrderOfRequest(1));
1000 EXPECT_EQ(2, GetOrderOfRequest(2));
1001 EXPECT_EQ(3, GetOrderOfRequest(3));
1002 EXPECT_EQ(4, GetOrderOfRequest(4));
1003
1004 // Request ("b", 7) has the highest priority, but we can't make new socket for
1005 // group "b", because it has reached the per-group limit. Then we make
1006 // socket for ("c", 6), because it has higher priority than ("a", 4),
1007 // and we still can't make a socket for group "b".
1008 EXPECT_EQ(5, GetOrderOfRequest(5));
1009 EXPECT_EQ(6, GetOrderOfRequest(6));
1010 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171011
1012 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131013 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:531014}
1015
1016// Make sure that we count connecting sockets against the total limit.
1017TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
1018 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1019
[email protected]bb1c4662013-11-14 00:00:071020 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1021 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
1022 EXPECT_EQ(OK, StartRequest("c", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:531023
1024 // Create one asynchronous request.
1025 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]bb1c4662013-11-14 00:00:071026 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:531027
[email protected]6b175382009-10-13 06:47:471028 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1029 // actually become pending until 2ms after they have been created. In order
1030 // to flush all tasks, we need to wait so that we know there are no
1031 // soon-to-be-pending tasks waiting.
[email protected]26b9973962012-01-28 00:57:001032 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
[email protected]2da659e2013-05-23 20:51:341033 base::MessageLoop::current()->RunUntilIdle();
[email protected]6b175382009-10-13 06:47:471034
[email protected]211d21722009-07-22 15:48:531035 // The next synchronous request should wait for its turn.
1036 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]bb1c4662013-11-14 00:00:071037 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:531038
[email protected]2431756e2010-09-29 20:26:131039 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531040
[email protected]2431756e2010-09-29 20:26:131041 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531042 client_socket_factory_.allocation_count());
1043
1044 EXPECT_EQ(1, GetOrderOfRequest(1));
1045 EXPECT_EQ(2, GetOrderOfRequest(2));
1046 EXPECT_EQ(3, GetOrderOfRequest(3));
1047 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:171048 EXPECT_EQ(5, GetOrderOfRequest(5));
1049
1050 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131051 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:531052}
1053
[email protected]6427fe22010-04-16 22:27:411054TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
1055 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1056 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1057
[email protected]bb1c4662013-11-14 00:00:071058 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1059 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1060 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1061 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
[email protected]6427fe22010-04-16 22:27:411062
1063 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1064
1065 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1066
[email protected]bb1c4662013-11-14 00:00:071067 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", DEFAULT_PRIORITY));
1068 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", DEFAULT_PRIORITY));
[email protected]6427fe22010-04-16 22:27:411069
1070 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1071
[email protected]2431756e2010-09-29 20:26:131072 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411073 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131074 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411075 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131076 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1077 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411078 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
1079}
1080
[email protected]d7027bb2010-05-10 18:58:541081TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
1082 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1083 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1084
1085 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521086 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131087 EXPECT_EQ(ERR_IO_PENDING,
1088 handle.Init("a",
1089 params_,
[email protected]bb1c4662013-11-14 00:00:071090 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521091 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131092 pool_.get(),
1093 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541094
1095 ClientSocketHandle handles[4];
1096 for (size_t i = 0; i < arraysize(handles); ++i) {
[email protected]6ecf2b92011-12-15 01:14:521097 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131098 EXPECT_EQ(ERR_IO_PENDING,
1099 handles[i].Init("b",
1100 params_,
[email protected]bb1c4662013-11-14 00:00:071101 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521102 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131103 pool_.get(),
1104 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541105 }
1106
1107 // One will be stalled, cancel all the handles now.
1108 // This should hit the OnAvailableSocketSlot() code where we previously had
1109 // stalled groups, but no longer have any.
1110 for (size_t i = 0; i < arraysize(handles); ++i)
1111 handles[i].Reset();
1112}
1113
[email protected]eb5a99382010-07-11 03:18:261114TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:541115 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1116 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1117
[email protected]eb5a99382010-07-11 03:18:261118 {
1119 ClientSocketHandle handles[kDefaultMaxSockets];
[email protected]6ecf2b92011-12-15 01:14:521120 TestCompletionCallback callbacks[kDefaultMaxSockets];
[email protected]eb5a99382010-07-11 03:18:261121 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]2431756e2010-09-29 20:26:131122 EXPECT_EQ(OK, handles[i].Init(base::IntToString(i),
1123 params_,
[email protected]bb1c4662013-11-14 00:00:071124 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521125 callbacks[i].callback(),
[email protected]2431756e2010-09-29 20:26:131126 pool_.get(),
1127 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261128 }
1129
1130 // Force a stalled group.
1131 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521132 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131133 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1134 params_,
[email protected]bb1c4662013-11-14 00:00:071135 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521136 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131137 pool_.get(),
1138 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261139
1140 // Cancel the stalled request.
1141 stalled_handle.Reset();
1142
1143 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1144 EXPECT_EQ(0, pool_->IdleSocketCount());
1145
1146 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541147 }
1148
[email protected]43a21b82010-06-10 21:30:541149 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1150 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:261151}
[email protected]43a21b82010-06-10 21:30:541152
[email protected]eb5a99382010-07-11 03:18:261153TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
1154 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1155 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1156
1157 {
1158 ClientSocketHandle handles[kDefaultMaxSockets];
1159 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521160 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131161 EXPECT_EQ(ERR_IO_PENDING, handles[i].Init(base::IntToString(i),
1162 params_,
[email protected]bb1c4662013-11-14 00:00:071163 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521164 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131165 pool_.get(),
1166 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261167 }
1168
1169 // Force a stalled group.
1170 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1171 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521172 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131173 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1174 params_,
[email protected]bb1c4662013-11-14 00:00:071175 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521176 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131177 pool_.get(),
1178 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261179
1180 // Since it is stalled, it should have no connect jobs.
1181 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101182 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261183
1184 // Cancel the stalled request.
1185 handles[0].Reset();
1186
[email protected]eb5a99382010-07-11 03:18:261187 // Now we should have a connect job.
1188 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101189 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261190
1191 // The stalled socket should connect.
1192 EXPECT_EQ(OK, callback.WaitForResult());
1193
1194 EXPECT_EQ(kDefaultMaxSockets + 1,
1195 client_socket_factory_.allocation_count());
1196 EXPECT_EQ(0, pool_->IdleSocketCount());
1197 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101198 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261199
1200 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541201 }
1202
[email protected]eb5a99382010-07-11 03:18:261203 EXPECT_EQ(1, pool_->IdleSocketCount());
1204}
[email protected]43a21b82010-06-10 21:30:541205
[email protected]eb5a99382010-07-11 03:18:261206TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1207 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1208 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:541209
[email protected]eb5a99382010-07-11 03:18:261210 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521211 TestCompletionCallback callback;
[email protected]eb5a99382010-07-11 03:18:261212 {
[email protected]51fdc7c2012-04-10 19:19:481213 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261214 ClientSocketHandle handles[kDefaultMaxSockets];
1215 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521216 TestCompletionCallback callback;
[email protected]1870d5cf2011-05-12 01:55:401217 EXPECT_EQ(OK, handles[i].Init(base::StringPrintf(
1218 "Take 2: %d", i),
1219 params_,
[email protected]bb1c4662013-11-14 00:00:071220 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521221 callback.callback(),
[email protected]1870d5cf2011-05-12 01:55:401222 pool_.get(),
1223 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261224 }
1225
1226 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1227 EXPECT_EQ(0, pool_->IdleSocketCount());
[email protected]51fdc7c2012-04-10 19:19:481228 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261229
1230 // Now we will hit the socket limit.
[email protected]2431756e2010-09-29 20:26:131231 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1232 params_,
[email protected]bb1c4662013-11-14 00:00:071233 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521234 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131235 pool_.get(),
1236 BoundNetLog()));
[email protected]51fdc7c2012-04-10 19:19:481237 EXPECT_TRUE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261238
1239 // Dropping out of scope will close all handles and return them to idle.
1240 }
[email protected]43a21b82010-06-10 21:30:541241
1242 // But if we wait for it, the released idle sockets will be closed in
1243 // preference of the waiting request.
[email protected]8ae03f42010-07-07 19:08:101244 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]eb5a99382010-07-11 03:18:261245
1246 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1247 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:541248}
1249
1250// Regression test for http://crbug.com/40952.
1251TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1252 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]06d94042010-08-25 01:45:221253 pool_->EnableConnectBackupJobs();
[email protected]43a21b82010-06-10 21:30:541254 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1255
1256 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1257 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521258 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131259 EXPECT_EQ(OK, handle.Init(base::IntToString(i),
1260 params_,
[email protected]bb1c4662013-11-14 00:00:071261 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521262 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131263 pool_.get(),
1264 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541265 }
1266
1267 // Flush all the DoReleaseSocket tasks.
[email protected]2da659e2013-05-23 20:51:341268 base::MessageLoop::current()->RunUntilIdle();
[email protected]43a21b82010-06-10 21:30:541269
1270 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1271 // reuse a socket.
1272 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1273 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521274 TestCompletionCallback callback;
[email protected]43a21b82010-06-10 21:30:541275
1276 // "0" is special here, since it should be the first entry in the sorted map,
1277 // which is the one which we would close an idle socket for. We shouldn't
1278 // close an idle socket though, since we should reuse the idle socket.
[email protected]2431756e2010-09-29 20:26:131279 EXPECT_EQ(OK, handle.Init("0",
1280 params_,
[email protected]bb1c4662013-11-14 00:00:071281 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521282 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131283 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211284 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541285
1286 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1287 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1288}
1289
[email protected]ab838892009-06-30 18:49:051290TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531291 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091292
[email protected]bb1c4662013-11-14 00:00:071293 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1294 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
[email protected]c9c6f5c2010-07-31 01:30:031295 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", IDLE));
[email protected]ac790b42009-12-02 04:31:311296 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1297 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1298 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1299 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1300 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091301
[email protected]2431756e2010-09-29 20:26:131302 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091303
[email protected]c9d6a1d2009-07-14 16:15:201304 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1305 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131306 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1307 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091308
[email protected]c9d6a1d2009-07-14 16:15:201309 EXPECT_EQ(1, GetOrderOfRequest(1));
1310 EXPECT_EQ(2, GetOrderOfRequest(2));
[email protected]c9c6f5c2010-07-31 01:30:031311 EXPECT_EQ(8, GetOrderOfRequest(3));
1312 EXPECT_EQ(6, GetOrderOfRequest(4));
1313 EXPECT_EQ(4, GetOrderOfRequest(5));
1314 EXPECT_EQ(3, GetOrderOfRequest(6));
1315 EXPECT_EQ(5, GetOrderOfRequest(7));
1316 EXPECT_EQ(7, GetOrderOfRequest(8));
[email protected]75439d3b2009-07-23 22:11:171317
1318 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131319 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]f6d1d6eb2009-06-24 20:16:091320}
1321
[email protected]ab838892009-06-30 18:49:051322TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531323 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091324
[email protected]bb1c4662013-11-14 00:00:071325 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1326 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
[email protected]ac790b42009-12-02 04:31:311327 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1328 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1329 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1330 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1331 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091332
[email protected]2431756e2010-09-29 20:26:131333 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091334
[email protected]2431756e2010-09-29 20:26:131335 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
1336 EXPECT_EQ(OK, request(i)->WaitForResult());
[email protected]c9d6a1d2009-07-14 16:15:201337
[email protected]2431756e2010-09-29 20:26:131338 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]c9d6a1d2009-07-14 16:15:201339 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131340 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1341 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091342}
1343
1344// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:051345// The pending connect job will be cancelled and should not call back into
1346// ClientSocketPoolBase.
1347TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531348 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201349
[email protected]ab838892009-06-30 18:49:051350 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131351 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521352 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131353 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1354 params_,
[email protected]bb1c4662013-11-14 00:00:071355 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521356 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131357 pool_.get(),
1358 BoundNetLog()));
1359 handle.Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091360}
1361
[email protected]ab838892009-06-30 18:49:051362TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531363 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201364
[email protected]ab838892009-06-30 18:49:051365 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061366 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521367 TestCompletionCallback callback;
[email protected]f6d1d6eb2009-06-24 20:16:091368
[email protected]2431756e2010-09-29 20:26:131369 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1370 params_,
[email protected]bb1c4662013-11-14 00:00:071371 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521372 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131373 pool_.get(),
1374 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091375
1376 handle.Reset();
1377
[email protected]6ecf2b92011-12-15 01:14:521378 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:131379 EXPECT_EQ(ERR_IO_PENDING,
1380 handle.Init("a",
1381 params_,
[email protected]bb1c4662013-11-14 00:00:071382 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521383 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:131384 pool_.get(),
1385 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091386
1387 EXPECT_EQ(OK, callback2.WaitForResult());
1388 EXPECT_FALSE(callback.have_result());
1389
1390 handle.Reset();
1391}
1392
[email protected]ab838892009-06-30 18:49:051393TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531394 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091395
[email protected]bb1c4662013-11-14 00:00:071396 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1397 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
[email protected]ac790b42009-12-02 04:31:311398 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1399 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1400 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1401 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1402 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091403
1404 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201405 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]2431756e2010-09-29 20:26:131406 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1407 (*requests())[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091408
[email protected]2431756e2010-09-29 20:26:131409 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091410
[email protected]c9d6a1d2009-07-14 16:15:201411 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1412 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131413 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1414 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091415
[email protected]c9d6a1d2009-07-14 16:15:201416 EXPECT_EQ(1, GetOrderOfRequest(1));
1417 EXPECT_EQ(2, GetOrderOfRequest(2));
1418 EXPECT_EQ(5, GetOrderOfRequest(3));
1419 EXPECT_EQ(3, GetOrderOfRequest(4));
[email protected]2431756e2010-09-29 20:26:131420 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1421 GetOrderOfRequest(5)); // Canceled request.
[email protected]c9d6a1d2009-07-14 16:15:201422 EXPECT_EQ(4, GetOrderOfRequest(6));
1423 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171424
1425 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131426 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091427}
1428
[email protected]6ecf2b92011-12-15 01:14:521429class RequestSocketCallback : public TestCompletionCallbackBase {
[email protected]f6d1d6eb2009-06-24 20:16:091430 public:
[email protected]2ab05b52009-07-01 23:57:581431 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:241432 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:581433 TestConnectJobFactory* test_connect_job_factory,
1434 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:091435 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:061436 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:581437 within_callback_(false),
1438 test_connect_job_factory_(test_connect_job_factory),
[email protected]6ecf2b92011-12-15 01:14:521439 next_job_type_(next_job_type),
[email protected]aa249b52013-04-30 01:04:321440 callback_(base::Bind(&RequestSocketCallback::OnComplete,
1441 base::Unretained(this))) {
[email protected]6ecf2b92011-12-15 01:14:521442 }
[email protected]f6d1d6eb2009-06-24 20:16:091443
dchengb03027d2014-10-21 12:00:201444 ~RequestSocketCallback() override {}
[email protected]6ecf2b92011-12-15 01:14:521445
1446 const CompletionCallback& callback() const { return callback_; }
1447
1448 private:
1449 void OnComplete(int result) {
1450 SetResult(result);
1451 ASSERT_EQ(OK, result);
[email protected]f6d1d6eb2009-06-24 20:16:091452
1453 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:581454 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]5edbf8d2010-01-13 18:44:111455
1456 // Don't allow reuse of the socket. Disconnect it and then release it and
1457 // run through the MessageLoop once to get it completely released.
1458 handle_->socket()->Disconnect();
[email protected]f6d1d6eb2009-06-24 20:16:091459 handle_->Reset();
[email protected]5edbf8d2010-01-13 18:44:111460 {
[email protected]b5717a42012-02-14 19:33:521461 // TODO: Resolve conflicting intentions of stopping recursion with the
[email protected]b4c62eb2012-11-14 18:36:511462 // |!within_callback_| test (above) and the call to |RunUntilIdle()|
[email protected]b5717a42012-02-14 19:33:521463 // below. http://crbug.com/114130.
[email protected]2da659e2013-05-23 20:51:341464 base::MessageLoop::ScopedNestableTaskAllower allow(
1465 base::MessageLoop::current());
1466 base::MessageLoop::current()->RunUntilIdle();
[email protected]5edbf8d2010-01-13 18:44:111467 }
[email protected]f6d1d6eb2009-06-24 20:16:091468 within_callback_ = true;
[email protected]6ecf2b92011-12-15 01:14:521469 TestCompletionCallback next_job_callback;
[email protected]bb1c4662013-11-14 00:00:071470 scoped_refptr<TestSocketParams> params(
1471 new TestSocketParams(false /* ignore_limits */));
[email protected]2431756e2010-09-29 20:26:131472 int rv = handle_->Init("a",
1473 params,
[email protected]bb1c4662013-11-14 00:00:071474 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521475 next_job_callback.callback(),
[email protected]2431756e2010-09-29 20:26:131476 pool_,
1477 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581478 switch (next_job_type_) {
1479 case TestConnectJob::kMockJob:
1480 EXPECT_EQ(OK, rv);
1481 break;
1482 case TestConnectJob::kMockPendingJob:
1483 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:471484
1485 // For pending jobs, wait for new socket to be created. This makes
1486 // sure there are no more pending operations nor any unclosed sockets
1487 // when the test finishes.
1488 // We need to give it a little bit of time to run, so that all the
1489 // operations that happen on timers (e.g. cleanup of idle
1490 // connections) can execute.
[email protected]5edbf8d2010-01-13 18:44:111491 {
[email protected]2da659e2013-05-23 20:51:341492 base::MessageLoop::ScopedNestableTaskAllower allow(
1493 base::MessageLoop::current());
[email protected]26b9973962012-01-28 00:57:001494 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
[email protected]5edbf8d2010-01-13 18:44:111495 EXPECT_EQ(OK, next_job_callback.WaitForResult());
1496 }
[email protected]2ab05b52009-07-01 23:57:581497 break;
1498 default:
1499 FAIL() << "Unexpected job type: " << next_job_type_;
1500 break;
1501 }
[email protected]f6d1d6eb2009-06-24 20:16:091502 }
1503 }
1504
[email protected]f6d1d6eb2009-06-24 20:16:091505 ClientSocketHandle* const handle_;
[email protected]2431756e2010-09-29 20:26:131506 TestClientSocketPool* const pool_;
[email protected]f6d1d6eb2009-06-24 20:16:091507 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:581508 TestConnectJobFactory* const test_connect_job_factory_;
1509 TestConnectJob::JobType next_job_type_;
[email protected]6ecf2b92011-12-15 01:14:521510 CompletionCallback callback_;
[email protected]f6d1d6eb2009-06-24 20:16:091511};
1512
[email protected]2ab05b52009-07-01 23:57:581513TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531514 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201515
[email protected]0b7648c2009-07-06 20:14:011516 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061517 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581518 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061519 &handle, pool_.get(), connect_job_factory_,
1520 TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131521 int rv = handle.Init("a",
1522 params_,
[email protected]bb1c4662013-11-14 00:00:071523 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521524 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131525 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211526 BoundNetLog());
[email protected]f6d1d6eb2009-06-24 20:16:091527 ASSERT_EQ(ERR_IO_PENDING, rv);
1528
1529 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581530}
[email protected]f6d1d6eb2009-06-24 20:16:091531
[email protected]2ab05b52009-07-01 23:57:581532TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531533 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201534
[email protected]0b7648c2009-07-06 20:14:011535 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061536 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581537 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061538 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]2431756e2010-09-29 20:26:131539 int rv = handle.Init("a",
1540 params_,
[email protected]bb1c4662013-11-14 00:00:071541 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521542 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131543 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211544 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581545 ASSERT_EQ(ERR_IO_PENDING, rv);
1546
1547 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091548}
1549
1550// Make sure that pending requests get serviced after active requests get
1551// cancelled.
[email protected]ab838892009-06-30 18:49:051552TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531553 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201554
[email protected]0b7648c2009-07-06 20:14:011555 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091556
[email protected]bb1c4662013-11-14 00:00:071557 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1558 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1559 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1560 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1561 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1562 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1563 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
[email protected]f6d1d6eb2009-06-24 20:16:091564
[email protected]c9d6a1d2009-07-14 16:15:201565 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1566 // Let's cancel them.
1567 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]2431756e2010-09-29 20:26:131568 ASSERT_FALSE(request(i)->handle()->is_initialized());
1569 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091570 }
1571
[email protected]f6d1d6eb2009-06-24 20:16:091572 // Let's wait for the rest to complete now.
[email protected]2431756e2010-09-29 20:26:131573 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
1574 EXPECT_EQ(OK, request(i)->WaitForResult());
1575 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091576 }
1577
[email protected]2431756e2010-09-29 20:26:131578 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1579 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091580}
1581
1582// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051583TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531584 const size_t kMaxSockets = 5;
1585 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201586
[email protected]0b7648c2009-07-06 20:14:011587 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091588
[email protected]211d21722009-07-22 15:48:531589 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1590 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091591
1592 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531593 for (size_t i = 0; i < kNumberOfRequests; ++i)
[email protected]bb1c4662013-11-14 00:00:071594 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
[email protected]f6d1d6eb2009-06-24 20:16:091595
[email protected]211d21722009-07-22 15:48:531596 for (size_t i = 0; i < kNumberOfRequests; ++i)
[email protected]2431756e2010-09-29 20:26:131597 EXPECT_EQ(ERR_CONNECTION_FAILED, request(i)->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091598}
1599
[email protected]5fc08e32009-07-15 17:09:571600TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531601 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571602
1603 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1604
[email protected]2431756e2010-09-29 20:26:131605 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521606 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131607 int rv = handle.Init("a",
1608 params_,
[email protected]bb1c4662013-11-14 00:00:071609 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521610 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131611 pool_.get(),
1612 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571613 EXPECT_EQ(ERR_IO_PENDING, rv);
1614
1615 // Cancel the active request.
[email protected]2431756e2010-09-29 20:26:131616 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571617
[email protected]2431756e2010-09-29 20:26:131618 rv = handle.Init("a",
1619 params_,
[email protected]bb1c4662013-11-14 00:00:071620 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521621 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131622 pool_.get(),
1623 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571624 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131625 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]5fc08e32009-07-15 17:09:571626
[email protected]2431756e2010-09-29 20:26:131627 EXPECT_FALSE(handle.is_reused());
[email protected]034df0f32013-01-07 23:17:481628 TestLoadTimingInfoConnectedNotReused(handle);
[email protected]5fc08e32009-07-15 17:09:571629 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1630}
1631
[email protected]2b7523d2009-07-29 20:29:231632// Regression test for http://crbug.com/17985.
1633TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1634 const int kMaxSockets = 3;
1635 const int kMaxSocketsPerGroup = 2;
1636 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1637
[email protected]ac790b42009-12-02 04:31:311638 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231639
[email protected]bb1c4662013-11-14 00:00:071640 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1641 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
[email protected]2b7523d2009-07-29 20:29:231642
1643 // This is going to be a pending request in an otherwise empty group.
[email protected]bb1c4662013-11-14 00:00:071644 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
[email protected]2b7523d2009-07-29 20:29:231645
1646 // Reach the maximum socket limit.
[email protected]bb1c4662013-11-14 00:00:071647 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
[email protected]2b7523d2009-07-29 20:29:231648
1649 // Create a stalled group with high priorities.
1650 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1651 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
[email protected]2b7523d2009-07-29 20:29:231652
[email protected]eb5a99382010-07-11 03:18:261653 // Release the first two sockets from "a". Because this is a keepalive,
1654 // the first release will unblock the pending request for "a". The
1655 // second release will unblock a request for "c", becaue it is the next
1656 // high priority socket.
[email protected]2431756e2010-09-29 20:26:131657 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1658 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]2b7523d2009-07-29 20:29:231659
1660 // Closing idle sockets should not get us into trouble, but in the bug
1661 // we were hitting a CHECK here.
[email protected]93054cc12010-06-08 06:12:411662 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]43a21b82010-06-10 21:30:541663 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261664
[email protected]2da659e2013-05-23 20:51:341665 // Run the released socket wakeups.
1666 base::MessageLoop::current()->RunUntilIdle();
[email protected]2b7523d2009-07-29 20:29:231667}
1668
[email protected]4d3b05d2010-01-27 21:27:291669TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531670 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571671
1672 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131673 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521674 TestCompletionCallback callback;
[email protected]333bdf62012-06-08 22:57:291675 CapturingBoundNetLog log;
[email protected]2431756e2010-09-29 20:26:131676 int rv = handle.Init("a",
1677 params_,
1678 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:521679 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131680 pool_.get(),
1681 log.bound());
[email protected]5fc08e32009-07-15 17:09:571682 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131683 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
[email protected]034df0f32013-01-07 23:17:481684 TestLoadTimingInfoNotConnected(handle);
1685
[email protected]2431756e2010-09-29 20:26:131686 EXPECT_EQ(OK, callback.WaitForResult());
1687 EXPECT_TRUE(handle.is_initialized());
1688 EXPECT_TRUE(handle.socket());
[email protected]034df0f32013-01-07 23:17:481689 TestLoadTimingInfoConnectedNotReused(handle);
1690
[email protected]2431756e2010-09-29 20:26:131691 handle.Reset();
[email protected]034df0f32013-01-07 23:17:481692 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:301693
[email protected]333bdf62012-06-08 22:57:291694 CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:401695 log.GetEntries(&entries);
1696
1697 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:461698 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401699 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171700 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401701 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171702 NetLog::PHASE_NONE));
1703 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401704 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]06650c52010-06-03 00:49:171705 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:461706 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401707 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571708}
1709
[email protected]4d3b05d2010-01-27 21:27:291710TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571711 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531712 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571713
1714 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2431756e2010-09-29 20:26:131715 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521716 TestCompletionCallback callback;
[email protected]333bdf62012-06-08 22:57:291717 CapturingBoundNetLog log;
[email protected]e60e47a2010-07-14 03:37:181718 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:131719 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:431720 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:451721 info.headers = new HttpResponseHeaders(std::string());
[email protected]2431756e2010-09-29 20:26:131722 handle.set_ssl_error_response_info(info);
1723 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1724 params_,
[email protected]bb1c4662013-11-14 00:00:071725 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521726 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131727 pool_.get(),
1728 log.bound()));
1729 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1730 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1731 EXPECT_FALSE(handle.is_ssl_error());
1732 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:301733
[email protected]333bdf62012-06-08 22:57:291734 CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:401735 log.GetEntries(&entries);
1736
1737 EXPECT_EQ(3u, entries.size());
[email protected]e9002a92010-01-29 07:10:461738 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401739 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171740 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401741 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171742 NetLog::PHASE_NONE));
[email protected]6b624c62010-03-14 08:37:321743 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401744 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571745}
1746
mmenke6be122f2015-03-09 22:22:471747// Check that an async ConnectJob failure does not result in creation of a new
1748// ConnectJob when there's another pending request also waiting on its own
1749// ConnectJob. See http://crbug.com/463960.
1750TEST_F(ClientSocketPoolBaseTest, AsyncFailureWithPendingRequestWithJob) {
1751 CreatePool(2, 2);
1752 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1753
1754 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1755 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1756
1757 EXPECT_EQ(ERR_CONNECTION_FAILED, request(0)->WaitForResult());
1758 EXPECT_EQ(ERR_CONNECTION_FAILED, request(1)->WaitForResult());
1759
1760 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1761}
1762
[email protected]4d3b05d2010-01-27 21:27:291763TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101764 // TODO(eroman): Add back the log expectations! Removed them because the
1765 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531766 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571767
1768 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131769 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521770 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131771 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:521772 TestCompletionCallback callback2;
[email protected]5fc08e32009-07-15 17:09:571773
[email protected]2431756e2010-09-29 20:26:131774 EXPECT_EQ(ERR_IO_PENDING,
1775 handle.Init("a",
1776 params_,
[email protected]bb1c4662013-11-14 00:00:071777 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521778 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131779 pool_.get(),
1780 BoundNetLog()));
[email protected]333bdf62012-06-08 22:57:291781 CapturingBoundNetLog log2;
[email protected]2431756e2010-09-29 20:26:131782 EXPECT_EQ(ERR_IO_PENDING,
1783 handle2.Init("a",
1784 params_,
[email protected]bb1c4662013-11-14 00:00:071785 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521786 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:131787 pool_.get(),
1788 BoundNetLog()));
[email protected]5fc08e32009-07-15 17:09:571789
[email protected]2431756e2010-09-29 20:26:131790 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571791
[email protected]fd7b7c92009-08-20 19:38:301792
1793 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301794
[email protected]2431756e2010-09-29 20:26:131795 EXPECT_EQ(OK, callback2.WaitForResult());
1796 handle2.Reset();
[email protected]fd7b7c92009-08-20 19:38:301797
1798 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531799 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571800}
1801
[email protected]4d3b05d2010-01-27 21:27:291802TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341803 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1804
[email protected]17a0c6c2009-08-04 00:07:041805 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1806
[email protected]ac790b42009-12-02 04:31:311807 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1808 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1809 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1810 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341811
1812 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]2431756e2010-09-29 20:26:131813 (*requests())[2]->handle()->Reset();
1814 (*requests())[3]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341815 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1816
[email protected]2431756e2010-09-29 20:26:131817 (*requests())[1]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341818 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1819
[email protected]2431756e2010-09-29 20:26:131820 (*requests())[0]->handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261821 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]974ebd62009-08-03 23:14:341822}
1823
[email protected]5fc08e32009-07-15 17:09:571824// When requests and ConnectJobs are not coupled, the request will get serviced
1825// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291826TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531827 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571828
1829 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321830 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571831
[email protected]2431756e2010-09-29 20:26:131832 std::vector<TestSocketRequest*> request_order;
1833 size_t completion_count; // unused
1834 TestSocketRequest req1(&request_order, &completion_count);
1835 int rv = req1.handle()->Init("a",
1836 params_,
[email protected]bb1c4662013-11-14 00:00:071837 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521838 req1.callback(), pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211839 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571840 EXPECT_EQ(ERR_IO_PENDING, rv);
1841 EXPECT_EQ(OK, req1.WaitForResult());
1842
1843 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1844 // without a job.
1845 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1846
[email protected]2431756e2010-09-29 20:26:131847 TestSocketRequest req2(&request_order, &completion_count);
1848 rv = req2.handle()->Init("a",
1849 params_,
[email protected]bb1c4662013-11-14 00:00:071850 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521851 req2.callback(),
[email protected]2431756e2010-09-29 20:26:131852 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211853 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571854 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131855 TestSocketRequest req3(&request_order, &completion_count);
1856 rv = req3.handle()->Init("a",
1857 params_,
[email protected]bb1c4662013-11-14 00:00:071858 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521859 req3.callback(),
[email protected]2431756e2010-09-29 20:26:131860 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211861 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571862 EXPECT_EQ(ERR_IO_PENDING, rv);
1863
1864 // Both Requests 2 and 3 are pending. We release socket 1 which should
1865 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331866 req1.handle()->Reset();
[email protected]2da659e2013-05-23 20:51:341867 // Run the released socket wakeups.
1868 base::MessageLoop::current()->RunUntilIdle();
[email protected]a6c59f62009-07-29 16:33:331869 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571870 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331871 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571872
1873 // Signal job 2, which should service request 3.
1874
1875 client_socket_factory_.SignalJobs();
1876 EXPECT_EQ(OK, req3.WaitForResult());
1877
[email protected]2431756e2010-09-29 20:26:131878 ASSERT_EQ(3U, request_order.size());
1879 EXPECT_EQ(&req1, request_order[0]);
1880 EXPECT_EQ(&req2, request_order[1]);
1881 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571882 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1883}
1884
1885// The requests are not coupled to the jobs. So, the requests should finish in
1886// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:291887TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531888 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571889 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321890 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571891
[email protected]2431756e2010-09-29 20:26:131892 std::vector<TestSocketRequest*> request_order;
1893 size_t completion_count; // unused
1894 TestSocketRequest req1(&request_order, &completion_count);
1895 int rv = req1.handle()->Init("a",
1896 params_,
[email protected]bb1c4662013-11-14 00:00:071897 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521898 req1.callback(),
[email protected]2431756e2010-09-29 20:26:131899 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211900 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571901 EXPECT_EQ(ERR_IO_PENDING, rv);
1902
[email protected]2431756e2010-09-29 20:26:131903 TestSocketRequest req2(&request_order, &completion_count);
1904 rv = req2.handle()->Init("a",
1905 params_,
[email protected]bb1c4662013-11-14 00:00:071906 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521907 req2.callback(),
[email protected]2431756e2010-09-29 20:26:131908 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211909 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571910 EXPECT_EQ(ERR_IO_PENDING, rv);
1911
1912 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321913 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571914
[email protected]2431756e2010-09-29 20:26:131915 TestSocketRequest req3(&request_order, &completion_count);
1916 rv = req3.handle()->Init("a",
1917 params_,
[email protected]bb1c4662013-11-14 00:00:071918 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521919 req3.callback(),
[email protected]2431756e2010-09-29 20:26:131920 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211921 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571922 EXPECT_EQ(ERR_IO_PENDING, rv);
1923
1924 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1925 EXPECT_EQ(OK, req2.WaitForResult());
1926 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1927
[email protected]2431756e2010-09-29 20:26:131928 ASSERT_EQ(3U, request_order.size());
1929 EXPECT_EQ(&req1, request_order[0]);
1930 EXPECT_EQ(&req2, request_order[1]);
1931 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571932}
1933
[email protected]03b7c8c2013-07-20 04:38:551934// Test GetLoadState in the case there's only one socket request.
1935TEST_F(ClientSocketPoolBaseTest, LoadStateOneRequest) {
[email protected]211d21722009-07-22 15:48:531936 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]03b7c8c2013-07-20 04:38:551937 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]5fc08e32009-07-15 17:09:571938
[email protected]2431756e2010-09-29 20:26:131939 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521940 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131941 int rv = handle.Init("a",
1942 params_,
[email protected]bb1c4662013-11-14 00:00:071943 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521944 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131945 pool_.get(),
1946 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571947 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]03b7c8c2013-07-20 04:38:551948 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571949
[email protected]03b7c8c2013-07-20 04:38:551950 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
1951 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
1952
1953 // No point in completing the connection, since ClientSocketHandles only
1954 // expect the LoadState to be checked while connecting.
1955}
1956
1957// Test GetLoadState in the case there are two socket requests.
1958TEST_F(ClientSocketPoolBaseTest, LoadStateTwoRequests) {
1959 CreatePool(2, 2);
1960 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1961
1962 ClientSocketHandle handle;
1963 TestCompletionCallback callback;
1964 int rv = handle.Init("a",
1965 params_,
[email protected]bb1c4662013-11-14 00:00:071966 DEFAULT_PRIORITY,
[email protected]03b7c8c2013-07-20 04:38:551967 callback.callback(),
1968 pool_.get(),
1969 BoundNetLog());
1970 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]5fc08e32009-07-15 17:09:571971
[email protected]2431756e2010-09-29 20:26:131972 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:521973 TestCompletionCallback callback2;
[email protected]03b7c8c2013-07-20 04:38:551974 rv = handle2.Init("a",
1975 params_,
[email protected]bb1c4662013-11-14 00:00:071976 DEFAULT_PRIORITY,
[email protected]03b7c8c2013-07-20 04:38:551977 callback2.callback(),
1978 pool_.get(),
1979 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571980 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]03b7c8c2013-07-20 04:38:551981
1982 // If the first Job is in an earlier state than the second, the state of
1983 // the second job should be used for both handles.
1984 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
1985 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
1986 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
1987
1988 // If the second Job is in an earlier state than the second, the state of
1989 // the first job should be used for both handles.
1990 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
1991 // One request is farther
1992 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
1993 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle2.GetLoadState());
1994
1995 // Farthest along job connects and the first request gets the socket. The
1996 // second handle switches to the state of the remaining ConnectJob.
1997 client_socket_factory_.SignalJob(0);
1998 EXPECT_EQ(OK, callback.WaitForResult());
1999 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
2000}
2001
2002// Test GetLoadState in the case the per-group limit is reached.
2003TEST_F(ClientSocketPoolBaseTest, LoadStateGroupLimit) {
2004 CreatePool(2, 1);
2005 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2006
2007 ClientSocketHandle handle;
2008 TestCompletionCallback callback;
2009 int rv = handle.Init("a",
2010 params_,
2011 MEDIUM,
2012 callback.callback(),
2013 pool_.get(),
2014 BoundNetLog());
2015 EXPECT_EQ(ERR_IO_PENDING, rv);
2016 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2017
2018 // Request another socket from the same pool, buth with a higher priority.
2019 // The first request should now be stalled at the socket group limit.
2020 ClientSocketHandle handle2;
2021 TestCompletionCallback callback2;
2022 rv = handle2.Init("a",
2023 params_,
2024 HIGHEST,
2025 callback2.callback(),
2026 pool_.get(),
2027 BoundNetLog());
2028 EXPECT_EQ(ERR_IO_PENDING, rv);
2029 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2030 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
2031
2032 // The first handle should remain stalled as the other socket goes through
2033 // the connect process.
2034
2035 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2036 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2037 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle2.GetLoadState());
2038
2039 client_socket_factory_.SignalJob(0);
2040 EXPECT_EQ(OK, callback2.WaitForResult());
2041 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2042
2043 // Closing the second socket should cause the stalled handle to finally get a
2044 // ConnectJob.
2045 handle2.socket()->Disconnect();
2046 handle2.Reset();
2047 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2048}
2049
2050// Test GetLoadState in the case the per-pool limit is reached.
2051TEST_F(ClientSocketPoolBaseTest, LoadStatePoolLimit) {
2052 CreatePool(2, 2);
2053 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2054
2055 ClientSocketHandle handle;
2056 TestCompletionCallback callback;
2057 int rv = handle.Init("a",
2058 params_,
[email protected]bb1c4662013-11-14 00:00:072059 DEFAULT_PRIORITY,
[email protected]03b7c8c2013-07-20 04:38:552060 callback.callback(),
2061 pool_.get(),
2062 BoundNetLog());
2063 EXPECT_EQ(ERR_IO_PENDING, rv);
2064
2065 // Request for socket from another pool.
2066 ClientSocketHandle handle2;
2067 TestCompletionCallback callback2;
2068 rv = handle2.Init("b",
2069 params_,
[email protected]bb1c4662013-11-14 00:00:072070 DEFAULT_PRIORITY,
[email protected]03b7c8c2013-07-20 04:38:552071 callback2.callback(),
2072 pool_.get(),
2073 BoundNetLog());
2074 EXPECT_EQ(ERR_IO_PENDING, rv);
2075
2076 // Request another socket from the first pool. Request should stall at the
2077 // socket pool limit.
2078 ClientSocketHandle handle3;
2079 TestCompletionCallback callback3;
2080 rv = handle3.Init("a",
2081 params_,
[email protected]bb1c4662013-11-14 00:00:072082 DEFAULT_PRIORITY,
[email protected]03b7c8c2013-07-20 04:38:552083 callback2.callback(),
2084 pool_.get(),
2085 BoundNetLog());
2086 EXPECT_EQ(ERR_IO_PENDING, rv);
2087
2088 // The third handle should remain stalled as the other sockets in its group
2089 // goes through the connect process.
2090
2091 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2092 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2093
2094 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2095 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
2096 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2097
2098 client_socket_factory_.SignalJob(0);
2099 EXPECT_EQ(OK, callback.WaitForResult());
2100 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2101
2102 // Closing a socket should allow the stalled handle to finally get a new
2103 // ConnectJob.
2104 handle.socket()->Disconnect();
2105 handle.Reset();
2106 EXPECT_EQ(LOAD_STATE_CONNECTING, handle3.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:572107}
2108
[email protected]e772db3f2010-07-12 18:11:132109TEST_F(ClientSocketPoolBaseTest, Recoverable) {
2110 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2111 connect_job_factory_->set_job_type(TestConnectJob::kMockRecoverableJob);
2112
[email protected]2431756e2010-09-29 20:26:132113 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522114 TestCompletionCallback callback;
2115 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED,
[email protected]bb1c4662013-11-14 00:00:072116 handle.Init("a", params_, DEFAULT_PRIORITY, callback.callback(),
[email protected]6ecf2b92011-12-15 01:14:522117 pool_.get(), BoundNetLog()));
[email protected]2431756e2010-09-29 20:26:132118 EXPECT_TRUE(handle.is_initialized());
2119 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:132120}
2121
2122TEST_F(ClientSocketPoolBaseTest, AsyncRecoverable) {
2123 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2124
2125 connect_job_factory_->set_job_type(
2126 TestConnectJob::kMockPendingRecoverableJob);
[email protected]2431756e2010-09-29 20:26:132127 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522128 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132129 EXPECT_EQ(ERR_IO_PENDING,
2130 handle.Init("a",
2131 params_,
[email protected]bb1c4662013-11-14 00:00:072132 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522133 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132134 pool_.get(),
2135 BoundNetLog()));
2136 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2137 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, callback.WaitForResult());
2138 EXPECT_TRUE(handle.is_initialized());
2139 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:132140}
2141
[email protected]e60e47a2010-07-14 03:37:182142TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
2143 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2144 connect_job_factory_->set_job_type(
2145 TestConnectJob::kMockAdditionalErrorStateJob);
2146
[email protected]2431756e2010-09-29 20:26:132147 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522148 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132149 EXPECT_EQ(ERR_CONNECTION_FAILED,
2150 handle.Init("a",
2151 params_,
[email protected]bb1c4662013-11-14 00:00:072152 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522153 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132154 pool_.get(),
2155 BoundNetLog()));
2156 EXPECT_FALSE(handle.is_initialized());
2157 EXPECT_FALSE(handle.socket());
2158 EXPECT_TRUE(handle.is_ssl_error());
2159 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182160}
2161
2162TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
2163 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2164
2165 connect_job_factory_->set_job_type(
2166 TestConnectJob::kMockPendingAdditionalErrorStateJob);
[email protected]2431756e2010-09-29 20:26:132167 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522168 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132169 EXPECT_EQ(ERR_IO_PENDING,
2170 handle.Init("a",
2171 params_,
[email protected]bb1c4662013-11-14 00:00:072172 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522173 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132174 pool_.get(),
2175 BoundNetLog()));
2176 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2177 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
2178 EXPECT_FALSE(handle.is_initialized());
2179 EXPECT_FALSE(handle.socket());
2180 EXPECT_TRUE(handle.is_ssl_error());
2181 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182182}
2183
[email protected]e7b1c6d2c2012-05-05 00:54:032184// Make sure we can reuse sockets when the cleanup timer is disabled.
2185TEST_F(ClientSocketPoolBaseTest, DisableCleanupTimerReuse) {
[email protected]64770b7d2011-11-16 04:30:412186 // Disable cleanup timer.
2187 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(false);
2188
2189 CreatePoolWithIdleTimeouts(
2190 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
[email protected]e7b1c6d2c2012-05-05 00:54:032191 base::TimeDelta(), // Time out unused sockets immediately.
2192 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2193
2194 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2195
2196 ClientSocketHandle handle;
2197 TestCompletionCallback callback;
2198 int rv = handle.Init("a",
2199 params_,
2200 LOWEST,
2201 callback.callback(),
2202 pool_.get(),
2203 BoundNetLog());
2204 ASSERT_EQ(ERR_IO_PENDING, rv);
2205 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2206 ASSERT_EQ(OK, callback.WaitForResult());
2207
2208 // Use and release the socket.
2209 EXPECT_EQ(1, handle.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]034df0f32013-01-07 23:17:482210 TestLoadTimingInfoConnectedNotReused(handle);
[email protected]e7b1c6d2c2012-05-05 00:54:032211 handle.Reset();
2212
2213 // Should now have one idle socket.
2214 ASSERT_EQ(1, pool_->IdleSocketCount());
2215
2216 // Request a new socket. This should reuse the old socket and complete
2217 // synchronously.
[email protected]333bdf62012-06-08 22:57:292218 CapturingBoundNetLog log;
[email protected]e7b1c6d2c2012-05-05 00:54:032219 rv = handle.Init("a",
2220 params_,
2221 LOWEST,
2222 CompletionCallback(),
2223 pool_.get(),
2224 log.bound());
2225 ASSERT_EQ(OK, rv);
2226 EXPECT_TRUE(handle.is_reused());
[email protected]034df0f32013-01-07 23:17:482227 TestLoadTimingInfoConnectedReused(handle);
[email protected]e7b1c6d2c2012-05-05 00:54:032228
2229 ASSERT_TRUE(pool_->HasGroup("a"));
2230 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2231 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2232
[email protected]333bdf62012-06-08 22:57:292233 CapturingNetLog::CapturedEntryList entries;
[email protected]e7b1c6d2c2012-05-05 00:54:032234 log.GetEntries(&entries);
2235 EXPECT_TRUE(LogContainsEntryWithType(
2236 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
2237}
2238
2239// Make sure we cleanup old unused sockets when the cleanup timer is disabled.
2240TEST_F(ClientSocketPoolBaseTest, DisableCleanupTimerNoReuse) {
2241 // Disable cleanup timer.
2242 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(false);
2243
2244 CreatePoolWithIdleTimeouts(
2245 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2246 base::TimeDelta(), // Time out unused sockets immediately
2247 base::TimeDelta()); // Time out used sockets immediately
[email protected]64770b7d2011-11-16 04:30:412248
2249 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2250
2251 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2252
2253 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522254 TestCompletionCallback callback;
[email protected]64770b7d2011-11-16 04:30:412255 int rv = handle.Init("a",
2256 params_,
2257 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522258 callback.callback(),
[email protected]64770b7d2011-11-16 04:30:412259 pool_.get(),
2260 BoundNetLog());
[email protected]e7b1c6d2c2012-05-05 00:54:032261 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]64770b7d2011-11-16 04:30:412262 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2263
2264 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522265 TestCompletionCallback callback2;
[email protected]64770b7d2011-11-16 04:30:412266 rv = handle2.Init("a",
2267 params_,
2268 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522269 callback2.callback(),
[email protected]64770b7d2011-11-16 04:30:412270 pool_.get(),
2271 BoundNetLog());
[email protected]e7b1c6d2c2012-05-05 00:54:032272 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]64770b7d2011-11-16 04:30:412273 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
2274
2275 // Cancel one of the requests. Wait for the other, which will get the first
2276 // job. Release the socket. Run the loop again to make sure the second
2277 // socket is sitting idle and the first one is released (since ReleaseSocket()
2278 // just posts a DoReleaseSocket() task).
2279
2280 handle.Reset();
[email protected]e7b1c6d2c2012-05-05 00:54:032281 ASSERT_EQ(OK, callback2.WaitForResult());
[email protected]64770b7d2011-11-16 04:30:412282 // Use the socket.
[email protected]83039bb2011-12-09 18:43:552283 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]64770b7d2011-11-16 04:30:412284 handle2.Reset();
2285
[email protected]e7b1c6d2c2012-05-05 00:54:032286 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2287 // actually become pending until 2ms after they have been created. In order
2288 // to flush all tasks, we need to wait so that we know there are no
2289 // soon-to-be-pending tasks waiting.
2290 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
[email protected]2da659e2013-05-23 20:51:342291 base::MessageLoop::current()->RunUntilIdle();
[email protected]64770b7d2011-11-16 04:30:412292
[email protected]e7b1c6d2c2012-05-05 00:54:032293 // Both sockets should now be idle.
[email protected]64770b7d2011-11-16 04:30:412294 ASSERT_EQ(2, pool_->IdleSocketCount());
2295
2296 // Request a new socket. This should cleanup the unused and timed out ones.
2297 // A new socket will be created rather than reusing the idle one.
[email protected]333bdf62012-06-08 22:57:292298 CapturingBoundNetLog log;
[email protected]6ecf2b92011-12-15 01:14:522299 TestCompletionCallback callback3;
[email protected]64770b7d2011-11-16 04:30:412300 rv = handle.Init("a",
2301 params_,
2302 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522303 callback3.callback(),
[email protected]64770b7d2011-11-16 04:30:412304 pool_.get(),
2305 log.bound());
[email protected]e7b1c6d2c2012-05-05 00:54:032306 ASSERT_EQ(ERR_IO_PENDING, rv);
2307 ASSERT_EQ(OK, callback3.WaitForResult());
[email protected]64770b7d2011-11-16 04:30:412308 EXPECT_FALSE(handle.is_reused());
2309
[email protected]e7b1c6d2c2012-05-05 00:54:032310 // Make sure the idle socket is closed.
[email protected]64770b7d2011-11-16 04:30:412311 ASSERT_TRUE(pool_->HasGroup("a"));
2312 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2313 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2314
[email protected]333bdf62012-06-08 22:57:292315 CapturingNetLog::CapturedEntryList entries;
[email protected]64770b7d2011-11-16 04:30:412316 log.GetEntries(&entries);
2317 EXPECT_FALSE(LogContainsEntryWithType(
2318 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
2319}
2320
[email protected]4d3b05d2010-01-27 21:27:292321TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
[email protected]9bf28db2009-08-29 01:35:162322 CreatePoolWithIdleTimeouts(
2323 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2324 base::TimeDelta(), // Time out unused sockets immediately.
2325 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2326
2327 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2328
2329 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2330
[email protected]2431756e2010-09-29 20:26:132331 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522332 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132333 int rv = handle.Init("a",
2334 params_,
2335 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522336 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132337 pool_.get(),
2338 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:162339 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:132340 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
[email protected]9bf28db2009-08-29 01:35:162341
[email protected]2431756e2010-09-29 20:26:132342 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522343 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132344 rv = handle2.Init("a",
2345 params_,
2346 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522347 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132348 pool_.get(),
2349 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:162350 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:132351 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
[email protected]9bf28db2009-08-29 01:35:162352
2353 // Cancel one of the requests. Wait for the other, which will get the first
2354 // job. Release the socket. Run the loop again to make sure the second
2355 // socket is sitting idle and the first one is released (since ReleaseSocket()
2356 // just posts a DoReleaseSocket() task).
2357
[email protected]2431756e2010-09-29 20:26:132358 handle.Reset();
2359 EXPECT_EQ(OK, callback2.WaitForResult());
[email protected]0f873e82010-09-02 16:09:012360 // Use the socket.
[email protected]83039bb2011-12-09 18:43:552361 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]2431756e2010-09-29 20:26:132362 handle2.Reset();
[email protected]6b175382009-10-13 06:47:472363
2364 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2365 // actually become pending until 2ms after they have been created. In order
2366 // to flush all tasks, we need to wait so that we know there are no
2367 // soon-to-be-pending tasks waiting.
[email protected]26b9973962012-01-28 00:57:002368 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
[email protected]2da659e2013-05-23 20:51:342369 base::MessageLoop::current()->RunUntilIdle();
[email protected]9bf28db2009-08-29 01:35:162370
2371 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:042372
[email protected]9bf28db2009-08-29 01:35:162373 // Invoke the idle socket cleanup check. Only one socket should be left, the
2374 // used socket. Request it to make sure that it's used.
2375
2376 pool_->CleanupTimedOutIdleSockets();
[email protected]333bdf62012-06-08 22:57:292377 CapturingBoundNetLog log;
[email protected]2431756e2010-09-29 20:26:132378 rv = handle.Init("a",
2379 params_,
2380 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522381 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132382 pool_.get(),
2383 log.bound());
[email protected]9bf28db2009-08-29 01:35:162384 EXPECT_EQ(OK, rv);
[email protected]2431756e2010-09-29 20:26:132385 EXPECT_TRUE(handle.is_reused());
[email protected]b2fcd0e2010-12-01 15:19:402386
[email protected]333bdf62012-06-08 22:57:292387 CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402388 log.GetEntries(&entries);
[email protected]fd4fe0b2010-02-08 23:02:152389 EXPECT_TRUE(LogContainsEntryWithType(
[email protected]b2fcd0e2010-12-01 15:19:402390 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]9bf28db2009-08-29 01:35:162391}
2392
[email protected]2041cf342010-02-19 03:15:592393// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:162394// because of multiple releasing disconnected sockets.
2395TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
2396 CreatePoolWithIdleTimeouts(
2397 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2398 base::TimeDelta(), // Time out unused sockets immediately.
2399 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2400
2401 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2402
2403 // Startup 4 connect jobs. Two of them will be pending.
2404
[email protected]2431756e2010-09-29 20:26:132405 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522406 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132407 int rv = handle.Init("a",
2408 params_,
2409 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522410 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132411 pool_.get(),
2412 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162413 EXPECT_EQ(OK, rv);
2414
[email protected]2431756e2010-09-29 20:26:132415 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522416 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132417 rv = handle2.Init("a",
2418 params_,
2419 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522420 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132421 pool_.get(),
2422 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162423 EXPECT_EQ(OK, rv);
2424
[email protected]2431756e2010-09-29 20:26:132425 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:522426 TestCompletionCallback callback3;
[email protected]2431756e2010-09-29 20:26:132427 rv = handle3.Init("a",
2428 params_,
2429 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522430 callback3.callback(),
[email protected]2431756e2010-09-29 20:26:132431 pool_.get(),
2432 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162433 EXPECT_EQ(ERR_IO_PENDING, rv);
2434
[email protected]2431756e2010-09-29 20:26:132435 ClientSocketHandle handle4;
[email protected]6ecf2b92011-12-15 01:14:522436 TestCompletionCallback callback4;
[email protected]2431756e2010-09-29 20:26:132437 rv = handle4.Init("a",
2438 params_,
2439 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522440 callback4.callback(),
[email protected]2431756e2010-09-29 20:26:132441 pool_.get(),
2442 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162443 EXPECT_EQ(ERR_IO_PENDING, rv);
2444
2445 // Release two disconnected sockets.
2446
[email protected]2431756e2010-09-29 20:26:132447 handle.socket()->Disconnect();
2448 handle.Reset();
2449 handle2.socket()->Disconnect();
2450 handle2.Reset();
[email protected]4f2abec2010-02-03 18:10:162451
[email protected]2431756e2010-09-29 20:26:132452 EXPECT_EQ(OK, callback3.WaitForResult());
2453 EXPECT_FALSE(handle3.is_reused());
2454 EXPECT_EQ(OK, callback4.WaitForResult());
2455 EXPECT_FALSE(handle4.is_reused());
[email protected]4f2abec2010-02-03 18:10:162456}
2457
[email protected]d7027bb2010-05-10 18:58:542458// Regression test for http://crbug.com/42267.
2459// When DoReleaseSocket() is processed for one socket, it is blocked because the
2460// other stalled groups all have releasing sockets, so no progress can be made.
2461TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
2462 CreatePoolWithIdleTimeouts(
2463 4 /* socket limit */, 4 /* socket limit per group */,
2464 base::TimeDelta(), // Time out unused sockets immediately.
2465 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2466
2467 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2468
2469 // Max out the socket limit with 2 per group.
2470
[email protected]2431756e2010-09-29 20:26:132471 ClientSocketHandle handle_a[4];
[email protected]6ecf2b92011-12-15 01:14:522472 TestCompletionCallback callback_a[4];
[email protected]2431756e2010-09-29 20:26:132473 ClientSocketHandle handle_b[4];
[email protected]6ecf2b92011-12-15 01:14:522474 TestCompletionCallback callback_b[4];
[email protected]d7027bb2010-05-10 18:58:542475
2476 for (int i = 0; i < 2; ++i) {
[email protected]2431756e2010-09-29 20:26:132477 EXPECT_EQ(OK, handle_a[i].Init("a",
2478 params_,
2479 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522480 callback_a[i].callback(),
[email protected]2431756e2010-09-29 20:26:132481 pool_.get(),
2482 BoundNetLog()));
2483 EXPECT_EQ(OK, handle_b[i].Init("b",
2484 params_,
2485 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522486 callback_b[i].callback(),
[email protected]2431756e2010-09-29 20:26:132487 pool_.get(),
2488 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542489 }
[email protected]b89f7e42010-05-20 20:37:002490
[email protected]d7027bb2010-05-10 18:58:542491 // Make 4 pending requests, 2 per group.
2492
2493 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132494 EXPECT_EQ(ERR_IO_PENDING,
2495 handle_a[i].Init("a",
2496 params_,
2497 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522498 callback_a[i].callback(),
[email protected]2431756e2010-09-29 20:26:132499 pool_.get(),
2500 BoundNetLog()));
2501 EXPECT_EQ(ERR_IO_PENDING,
2502 handle_b[i].Init("b",
2503 params_,
2504 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522505 callback_b[i].callback(),
[email protected]2431756e2010-09-29 20:26:132506 pool_.get(),
2507 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542508 }
2509
2510 // Release b's socket first. The order is important, because in
2511 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2512 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2513 // first, which has a releasing socket, so it refuses to start up another
2514 // ConnectJob. So, we used to infinite loop on this.
[email protected]2431756e2010-09-29 20:26:132515 handle_b[0].socket()->Disconnect();
2516 handle_b[0].Reset();
2517 handle_a[0].socket()->Disconnect();
2518 handle_a[0].Reset();
[email protected]d7027bb2010-05-10 18:58:542519
2520 // Used to get stuck here.
[email protected]2da659e2013-05-23 20:51:342521 base::MessageLoop::current()->RunUntilIdle();
[email protected]d7027bb2010-05-10 18:58:542522
[email protected]2431756e2010-09-29 20:26:132523 handle_b[1].socket()->Disconnect();
2524 handle_b[1].Reset();
2525 handle_a[1].socket()->Disconnect();
2526 handle_a[1].Reset();
[email protected]d7027bb2010-05-10 18:58:542527
2528 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132529 EXPECT_EQ(OK, callback_b[i].WaitForResult());
2530 EXPECT_EQ(OK, callback_a[i].WaitForResult());
[email protected]d7027bb2010-05-10 18:58:542531 }
2532}
2533
[email protected]fd4fe0b2010-02-08 23:02:152534TEST_F(ClientSocketPoolBaseTest,
2535 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2536 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2537
2538 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2539
[email protected]bb1c4662013-11-14 00:00:072540 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
2541 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
2542 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
2543 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
[email protected]fd4fe0b2010-02-08 23:02:152544
[email protected]2431756e2010-09-29 20:26:132545 EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
2546 EXPECT_EQ(OK, (*requests())[1]->WaitForResult());
2547 EXPECT_EQ(2u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152548
2549 // Releases one connection.
[email protected]2431756e2010-09-29 20:26:132550 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2551 EXPECT_EQ(OK, (*requests())[2]->WaitForResult());
[email protected]fd4fe0b2010-02-08 23:02:152552
[email protected]2431756e2010-09-29 20:26:132553 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2554 EXPECT_EQ(OK, (*requests())[3]->WaitForResult());
2555 EXPECT_EQ(4u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152556
2557 EXPECT_EQ(1, GetOrderOfRequest(1));
2558 EXPECT_EQ(2, GetOrderOfRequest(2));
2559 EXPECT_EQ(3, GetOrderOfRequest(3));
2560 EXPECT_EQ(4, GetOrderOfRequest(4));
2561
2562 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:132563 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
[email protected]fd4fe0b2010-02-08 23:02:152564}
2565
[email protected]6ecf2b92011-12-15 01:14:522566class TestReleasingSocketRequest : public TestCompletionCallbackBase {
[email protected]4f1e4982010-03-02 18:31:042567 public:
[email protected]2431756e2010-09-29 20:26:132568 TestReleasingSocketRequest(TestClientSocketPool* pool,
2569 int expected_result,
[email protected]e60e47a2010-07-14 03:37:182570 bool reset_releasing_handle)
2571 : pool_(pool),
2572 expected_result_(expected_result),
[email protected]6ecf2b92011-12-15 01:14:522573 reset_releasing_handle_(reset_releasing_handle),
[email protected]aa249b52013-04-30 01:04:322574 callback_(base::Bind(&TestReleasingSocketRequest::OnComplete,
2575 base::Unretained(this))) {
[email protected]6ecf2b92011-12-15 01:14:522576 }
2577
dchengb03027d2014-10-21 12:00:202578 ~TestReleasingSocketRequest() override {}
[email protected]4f1e4982010-03-02 18:31:042579
2580 ClientSocketHandle* handle() { return &handle_; }
2581
[email protected]6ecf2b92011-12-15 01:14:522582 const CompletionCallback& callback() const { return callback_; }
[email protected]4f1e4982010-03-02 18:31:042583
2584 private:
[email protected]6ecf2b92011-12-15 01:14:522585 void OnComplete(int result) {
2586 SetResult(result);
2587 if (reset_releasing_handle_)
2588 handle_.Reset();
2589
[email protected]bb1c4662013-11-14 00:00:072590 scoped_refptr<TestSocketParams> con_params(
2591 new TestSocketParams(false /* ignore_limits */));
[email protected]6ecf2b92011-12-15 01:14:522592 EXPECT_EQ(expected_result_,
[email protected]bb1c4662013-11-14 00:00:072593 handle2_.Init("a", con_params, DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522594 callback2_.callback(), pool_, BoundNetLog()));
2595 }
2596
[email protected]2431756e2010-09-29 20:26:132597 TestClientSocketPool* const pool_;
[email protected]e60e47a2010-07-14 03:37:182598 int expected_result_;
2599 bool reset_releasing_handle_;
[email protected]4f1e4982010-03-02 18:31:042600 ClientSocketHandle handle_;
2601 ClientSocketHandle handle2_;
[email protected]6ecf2b92011-12-15 01:14:522602 CompletionCallback callback_;
2603 TestCompletionCallback callback2_;
[email protected]4f1e4982010-03-02 18:31:042604};
2605
[email protected]e60e47a2010-07-14 03:37:182606
2607TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2608 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2609
[email protected]bb1c4662013-11-14 00:00:072610 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
2611 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
2612 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
[email protected]e60e47a2010-07-14 03:37:182613
[email protected]2431756e2010-09-29 20:26:132614 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]e60e47a2010-07-14 03:37:182615 client_socket_factory_.allocation_count());
2616
2617 connect_job_factory_->set_job_type(
2618 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2619 TestReleasingSocketRequest req(pool_.get(), OK, false);
[email protected]2431756e2010-09-29 20:26:132620 EXPECT_EQ(ERR_IO_PENDING,
[email protected]bb1c4662013-11-14 00:00:072621 req.handle()->Init("a", params_, DEFAULT_PRIORITY, req.callback(),
[email protected]6ecf2b92011-12-15 01:14:522622 pool_.get(), BoundNetLog()));
[email protected]e60e47a2010-07-14 03:37:182623 // The next job should complete synchronously
2624 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2625
2626 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
2627 EXPECT_FALSE(req.handle()->is_initialized());
2628 EXPECT_FALSE(req.handle()->socket());
2629 EXPECT_TRUE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:432630 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182631}
2632
[email protected]b6501d3d2010-06-03 23:53:342633// http://crbug.com/44724 regression test.
2634// We start releasing the pool when we flush on network change. When that
2635// happens, the only active references are in the ClientSocketHandles. When a
2636// ConnectJob completes and calls back into the last ClientSocketHandle, that
2637// callback can release the last reference and delete the pool. After the
2638// callback finishes, we go back to the stack frame within the now-deleted pool.
2639// Executing any code that refers to members of the now-deleted pool can cause
2640// crashes.
2641TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2642 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2643 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2644
2645 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522646 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132647 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2648 params_,
[email protected]bb1c4662013-11-14 00:00:072649 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522650 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132651 pool_.get(),
2652 BoundNetLog()));
[email protected]b6501d3d2010-06-03 23:53:342653
[email protected]7af985a2012-12-14 22:40:422654 pool_->FlushWithError(ERR_NETWORK_CHANGED);
[email protected]b6501d3d2010-06-03 23:53:342655
2656 // We'll call back into this now.
2657 callback.WaitForResult();
2658}
2659
[email protected]a7e38572010-06-07 18:22:242660TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2661 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2662 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2663
2664 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522665 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132666 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2667 params_,
[email protected]bb1c4662013-11-14 00:00:072668 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522669 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132670 pool_.get(),
2671 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242672 EXPECT_EQ(OK, callback.WaitForResult());
2673 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2674
[email protected]7af985a2012-12-14 22:40:422675 pool_->FlushWithError(ERR_NETWORK_CHANGED);
[email protected]a7e38572010-06-07 18:22:242676
2677 handle.Reset();
[email protected]2da659e2013-05-23 20:51:342678 base::MessageLoop::current()->RunUntilIdle();
[email protected]a7e38572010-06-07 18:22:242679
[email protected]2431756e2010-09-29 20:26:132680 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2681 params_,
[email protected]bb1c4662013-11-14 00:00:072682 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522683 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132684 pool_.get(),
2685 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242686 EXPECT_EQ(OK, callback.WaitForResult());
2687 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2688}
2689
[email protected]6ecf2b92011-12-15 01:14:522690class ConnectWithinCallback : public TestCompletionCallbackBase {
[email protected]06f92462010-08-31 19:24:142691 public:
2692 ConnectWithinCallback(
2693 const std::string& group_name,
2694 const scoped_refptr<TestSocketParams>& params,
[email protected]2431756e2010-09-29 20:26:132695 TestClientSocketPool* pool)
[email protected]6ecf2b92011-12-15 01:14:522696 : group_name_(group_name),
2697 params_(params),
2698 pool_(pool),
[email protected]aa249b52013-04-30 01:04:322699 callback_(base::Bind(&ConnectWithinCallback::OnComplete,
2700 base::Unretained(this))) {
[email protected]06f92462010-08-31 19:24:142701 }
2702
dchengb03027d2014-10-21 12:00:202703 ~ConnectWithinCallback() override {}
[email protected]06f92462010-08-31 19:24:142704
2705 int WaitForNestedResult() {
2706 return nested_callback_.WaitForResult();
2707 }
2708
[email protected]6ecf2b92011-12-15 01:14:522709 const CompletionCallback& callback() const { return callback_; }
2710
[email protected]06f92462010-08-31 19:24:142711 private:
[email protected]6ecf2b92011-12-15 01:14:522712 void OnComplete(int result) {
2713 SetResult(result);
2714 EXPECT_EQ(ERR_IO_PENDING,
2715 handle_.Init(group_name_,
2716 params_,
[email protected]bb1c4662013-11-14 00:00:072717 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522718 nested_callback_.callback(),
2719 pool_,
2720 BoundNetLog()));
2721 }
2722
[email protected]06f92462010-08-31 19:24:142723 const std::string group_name_;
2724 const scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:132725 TestClientSocketPool* const pool_;
[email protected]06f92462010-08-31 19:24:142726 ClientSocketHandle handle_;
[email protected]6ecf2b92011-12-15 01:14:522727 CompletionCallback callback_;
2728 TestCompletionCallback nested_callback_;
2729
2730 DISALLOW_COPY_AND_ASSIGN(ConnectWithinCallback);
[email protected]06f92462010-08-31 19:24:142731};
2732
2733TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
2734 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2735
2736 // First job will be waiting until it gets aborted.
2737 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2738
2739 ClientSocketHandle handle;
[email protected]2431756e2010-09-29 20:26:132740 ConnectWithinCallback callback("a", params_, pool_.get());
2741 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2742 params_,
[email protected]bb1c4662013-11-14 00:00:072743 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522744 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132745 pool_.get(),
2746 BoundNetLog()));
[email protected]06f92462010-08-31 19:24:142747
2748 // Second job will be started during the first callback, and will
2749 // asynchronously complete with OK.
2750 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]7af985a2012-12-14 22:40:422751 pool_->FlushWithError(ERR_NETWORK_CHANGED);
2752 EXPECT_EQ(ERR_NETWORK_CHANGED, callback.WaitForResult());
[email protected]06f92462010-08-31 19:24:142753 EXPECT_EQ(OK, callback.WaitForNestedResult());
2754}
2755
[email protected]25eea382010-07-10 23:55:262756// Cancel a pending socket request while we're at max sockets,
2757// and verify that the backup socket firing doesn't cause a crash.
2758TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
2759 // Max 4 sockets globally, max 4 sockets per group.
2760 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
[email protected]06d94042010-08-25 01:45:222761 pool_->EnableConnectBackupJobs();
[email protected]25eea382010-07-10 23:55:262762
[email protected]4baaf9d2010-08-31 15:15:442763 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2764 // timer.
[email protected]25eea382010-07-10 23:55:262765 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2766 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522767 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132768 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2769 params_,
[email protected]bb1c4662013-11-14 00:00:072770 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522771 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132772 pool_.get(),
2773 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262774
2775 // Start (MaxSockets - 1) connected sockets to reach max sockets.
2776 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2777 ClientSocketHandle handles[kDefaultMaxSockets];
2778 for (int i = 1; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:522779 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132780 EXPECT_EQ(OK, handles[i].Init("bar",
2781 params_,
[email protected]bb1c4662013-11-14 00:00:072782 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522783 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132784 pool_.get(),
2785 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262786 }
2787
[email protected]2da659e2013-05-23 20:51:342788 base::MessageLoop::current()->RunUntilIdle();
[email protected]25eea382010-07-10 23:55:262789
2790 // Cancel the pending request.
2791 handle.Reset();
2792
2793 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]26b9973962012-01-28 00:57:002794 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2795 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]25eea382010-07-10 23:55:262796
[email protected]2da659e2013-05-23 20:51:342797 base::MessageLoop::current()->RunUntilIdle();
[email protected]25eea382010-07-10 23:55:262798 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
2799}
2800
[email protected]3f00be82010-09-27 19:50:022801TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
[email protected]4baaf9d2010-08-31 15:15:442802 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2803 pool_->EnableConnectBackupJobs();
2804
2805 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2806 // timer.
2807 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2808 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522809 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132810 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2811 params_,
[email protected]bb1c4662013-11-14 00:00:072812 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522813 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132814 pool_.get(),
2815 BoundNetLog()));
[email protected]4baaf9d2010-08-31 15:15:442816 ASSERT_TRUE(pool_->HasGroup("bar"));
2817 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
[email protected]8159a1c2012-06-07 00:00:102818 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("bar"));
[email protected]4baaf9d2010-08-31 15:15:442819
2820 // Cancel the socket request. This should cancel the backup timer. Wait for
2821 // the backup time to see if it indeed got canceled.
2822 handle.Reset();
2823 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]26b9973962012-01-28 00:57:002824 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2825 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]2da659e2013-05-23 20:51:342826 base::MessageLoop::current()->RunUntilIdle();
[email protected]4baaf9d2010-08-31 15:15:442827 ASSERT_TRUE(pool_->HasGroup("bar"));
2828 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2829}
2830
[email protected]3f00be82010-09-27 19:50:022831TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
2832 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2833 pool_->EnableConnectBackupJobs();
2834
2835 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2836 // timer.
2837 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2838 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522839 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132840 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2841 params_,
[email protected]bb1c4662013-11-14 00:00:072842 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522843 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132844 pool_.get(),
2845 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022846 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2847 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522848 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132849 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("bar",
2850 params_,
[email protected]bb1c4662013-11-14 00:00:072851 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522852 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132853 pool_.get(),
2854 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022855 ASSERT_TRUE(pool_->HasGroup("bar"));
2856 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("bar"));
2857
2858 // Cancel request 1 and then complete request 2. With the requests finished,
2859 // the backup timer should be cancelled.
2860 handle.Reset();
2861 EXPECT_EQ(OK, callback2.WaitForResult());
2862 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]26b9973962012-01-28 00:57:002863 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2864 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]2da659e2013-05-23 20:51:342865 base::MessageLoop::current()->RunUntilIdle();
[email protected]3f00be82010-09-27 19:50:022866}
2867
[email protected]eb5a99382010-07-11 03:18:262868// Test delayed socket binding for the case where we have two connects,
2869// and while one is waiting on a connect, the other frees up.
2870// The socket waiting on a connect should switch immediately to the freed
2871// up socket.
2872TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
2873 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2874 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2875
2876 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522877 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132878 EXPECT_EQ(ERR_IO_PENDING,
2879 handle1.Init("a",
2880 params_,
[email protected]bb1c4662013-11-14 00:00:072881 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522882 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132883 pool_.get(),
2884 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262885 EXPECT_EQ(OK, callback.WaitForResult());
2886
2887 // No idle sockets, no pending jobs.
2888 EXPECT_EQ(0, pool_->IdleSocketCount());
2889 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2890
2891 // Create a second socket to the same host, but this one will wait.
2892 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2893 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132894 EXPECT_EQ(ERR_IO_PENDING,
2895 handle2.Init("a",
2896 params_,
[email protected]bb1c4662013-11-14 00:00:072897 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522898 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132899 pool_.get(),
2900 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262901 // No idle sockets, and one connecting job.
2902 EXPECT_EQ(0, pool_->IdleSocketCount());
2903 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2904
2905 // Return the first handle to the pool. This will initiate the delayed
2906 // binding.
2907 handle1.Reset();
2908
[email protected]2da659e2013-05-23 20:51:342909 base::MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262910
2911 // Still no idle sockets, still one pending connect job.
2912 EXPECT_EQ(0, pool_->IdleSocketCount());
2913 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2914
2915 // The second socket connected, even though it was a Waiting Job.
2916 EXPECT_EQ(OK, callback.WaitForResult());
2917
2918 // And we can see there is still one job waiting.
2919 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2920
2921 // Finally, signal the waiting Connect.
2922 client_socket_factory_.SignalJobs();
2923 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2924
[email protected]2da659e2013-05-23 20:51:342925 base::MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262926}
2927
2928// Test delayed socket binding when a group is at capacity and one
2929// of the group's sockets frees up.
2930TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
2931 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2932 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2933
2934 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522935 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132936 EXPECT_EQ(ERR_IO_PENDING,
2937 handle1.Init("a",
2938 params_,
[email protected]bb1c4662013-11-14 00:00:072939 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522940 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132941 pool_.get(),
2942 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262943 EXPECT_EQ(OK, callback.WaitForResult());
2944
2945 // No idle sockets, no pending jobs.
2946 EXPECT_EQ(0, pool_->IdleSocketCount());
2947 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2948
2949 // Create a second socket to the same host, but this one will wait.
2950 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2951 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132952 EXPECT_EQ(ERR_IO_PENDING,
2953 handle2.Init("a",
2954 params_,
[email protected]bb1c4662013-11-14 00:00:072955 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522956 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132957 pool_.get(),
2958 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262959 // No idle sockets, and one connecting job.
2960 EXPECT_EQ(0, pool_->IdleSocketCount());
2961 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2962
2963 // Return the first handle to the pool. This will initiate the delayed
2964 // binding.
2965 handle1.Reset();
2966
[email protected]2da659e2013-05-23 20:51:342967 base::MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262968
2969 // Still no idle sockets, still one pending connect job.
2970 EXPECT_EQ(0, pool_->IdleSocketCount());
2971 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2972
2973 // The second socket connected, even though it was a Waiting Job.
2974 EXPECT_EQ(OK, callback.WaitForResult());
2975
2976 // And we can see there is still one job waiting.
2977 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2978
2979 // Finally, signal the waiting Connect.
2980 client_socket_factory_.SignalJobs();
2981 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2982
[email protected]2da659e2013-05-23 20:51:342983 base::MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262984}
2985
2986// Test out the case where we have one socket connected, one
2987// connecting, when the first socket finishes and goes idle.
[email protected]2abfe90a2010-08-25 17:49:512988// Although the second connection is pending, the second request
[email protected]eb5a99382010-07-11 03:18:262989// should complete, by taking the first socket's idle socket.
2990TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
2991 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2992 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2993
2994 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522995 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132996 EXPECT_EQ(ERR_IO_PENDING,
2997 handle1.Init("a",
2998 params_,
[email protected]bb1c4662013-11-14 00:00:072999 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523000 callback.callback(),
[email protected]2431756e2010-09-29 20:26:133001 pool_.get(),
3002 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:263003 EXPECT_EQ(OK, callback.WaitForResult());
3004
3005 // No idle sockets, no pending jobs.
3006 EXPECT_EQ(0, pool_->IdleSocketCount());
3007 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3008
3009 // Create a second socket to the same host, but this one will wait.
3010 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3011 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:133012 EXPECT_EQ(ERR_IO_PENDING,
3013 handle2.Init("a",
3014 params_,
[email protected]bb1c4662013-11-14 00:00:073015 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523016 callback.callback(),
[email protected]2431756e2010-09-29 20:26:133017 pool_.get(),
3018 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:263019 // No idle sockets, and one connecting job.
3020 EXPECT_EQ(0, pool_->IdleSocketCount());
3021 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3022
3023 // Return the first handle to the pool. This will initiate the delayed
3024 // binding.
3025 handle1.Reset();
3026
[email protected]2da659e2013-05-23 20:51:343027 base::MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263028
3029 // Still no idle sockets, still one pending connect job.
3030 EXPECT_EQ(0, pool_->IdleSocketCount());
3031 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3032
3033 // The second socket connected, even though it was a Waiting Job.
3034 EXPECT_EQ(OK, callback.WaitForResult());
3035
3036 // And we can see there is still one job waiting.
3037 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3038
3039 // Finally, signal the waiting Connect.
3040 client_socket_factory_.SignalJobs();
3041 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3042
[email protected]2da659e2013-05-23 20:51:343043 base::MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263044}
3045
[email protected]2abfe90a2010-08-25 17:49:513046// Cover the case where on an available socket slot, we have one pending
3047// request that completes synchronously, thereby making the Group empty.
3048TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
3049 const int kUnlimitedSockets = 100;
3050 const int kOneSocketPerGroup = 1;
3051 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
3052
3053 // Make the first request asynchronous fail.
3054 // This will free up a socket slot later.
3055 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
3056
3057 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523058 TestCompletionCallback callback1;
[email protected]2431756e2010-09-29 20:26:133059 EXPECT_EQ(ERR_IO_PENDING,
3060 handle1.Init("a",
3061 params_,
[email protected]bb1c4662013-11-14 00:00:073062 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523063 callback1.callback(),
[email protected]2431756e2010-09-29 20:26:133064 pool_.get(),
3065 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:513066 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3067
3068 // Make the second request synchronously fail. This should make the Group
3069 // empty.
3070 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3071 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523072 TestCompletionCallback callback2;
[email protected]2abfe90a2010-08-25 17:49:513073 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
3074 // when created.
[email protected]2431756e2010-09-29 20:26:133075 EXPECT_EQ(ERR_IO_PENDING,
3076 handle2.Init("a",
3077 params_,
[email protected]bb1c4662013-11-14 00:00:073078 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523079 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:133080 pool_.get(),
3081 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:513082
3083 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3084
3085 EXPECT_EQ(ERR_CONNECTION_FAILED, callback1.WaitForResult());
3086 EXPECT_EQ(ERR_CONNECTION_FAILED, callback2.WaitForResult());
3087 EXPECT_FALSE(pool_->HasGroup("a"));
3088}
3089
[email protected]e1b54dc2010-10-06 21:27:223090TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
3091 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3092
3093 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3094
3095 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523096 TestCompletionCallback callback1;
[email protected]e1b54dc2010-10-06 21:27:223097 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3098 params_,
[email protected]bb1c4662013-11-14 00:00:073099 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523100 callback1.callback(),
[email protected]e1b54dc2010-10-06 21:27:223101 pool_.get(),
3102 BoundNetLog()));
3103
3104 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523105 TestCompletionCallback callback2;
[email protected]e1b54dc2010-10-06 21:27:223106 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3107 params_,
[email protected]bb1c4662013-11-14 00:00:073108 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523109 callback2.callback(),
[email protected]e1b54dc2010-10-06 21:27:223110 pool_.get(),
3111 BoundNetLog()));
3112 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:523113 TestCompletionCallback callback3;
[email protected]e1b54dc2010-10-06 21:27:223114 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
3115 params_,
[email protected]bb1c4662013-11-14 00:00:073116 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523117 callback3.callback(),
[email protected]e1b54dc2010-10-06 21:27:223118 pool_.get(),
3119 BoundNetLog()));
3120
3121 EXPECT_EQ(OK, callback1.WaitForResult());
3122 EXPECT_EQ(OK, callback2.WaitForResult());
3123 EXPECT_EQ(OK, callback3.WaitForResult());
3124
3125 // Use the socket.
[email protected]83039bb2011-12-09 18:43:553126 EXPECT_EQ(1, handle1.socket()->Write(NULL, 1, CompletionCallback()));
3127 EXPECT_EQ(1, handle3.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]e1b54dc2010-10-06 21:27:223128
3129 handle1.Reset();
3130 handle2.Reset();
3131 handle3.Reset();
3132
3133 EXPECT_EQ(OK, handle1.Init("a",
3134 params_,
[email protected]bb1c4662013-11-14 00:00:073135 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523136 callback1.callback(),
[email protected]e1b54dc2010-10-06 21:27:223137 pool_.get(),
3138 BoundNetLog()));
3139 EXPECT_EQ(OK, handle2.Init("a",
3140 params_,
[email protected]bb1c4662013-11-14 00:00:073141 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523142 callback2.callback(),
[email protected]e1b54dc2010-10-06 21:27:223143 pool_.get(),
3144 BoundNetLog()));
3145 EXPECT_EQ(OK, handle3.Init("a",
3146 params_,
[email protected]bb1c4662013-11-14 00:00:073147 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523148 callback3.callback(),
[email protected]e1b54dc2010-10-06 21:27:223149 pool_.get(),
3150 BoundNetLog()));
3151
3152 EXPECT_TRUE(handle1.socket()->WasEverUsed());
3153 EXPECT_TRUE(handle2.socket()->WasEverUsed());
3154 EXPECT_FALSE(handle3.socket()->WasEverUsed());
3155}
3156
[email protected]2c2bef152010-10-13 00:55:033157TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
3158 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3159 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3160
3161 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3162
3163 ASSERT_TRUE(pool_->HasGroup("a"));
3164 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103165 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033166 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3167
3168 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523169 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033170 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3171 params_,
[email protected]bb1c4662013-11-14 00:00:073172 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523173 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033174 pool_.get(),
3175 BoundNetLog()));
3176
3177 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523178 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033179 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3180 params_,
[email protected]bb1c4662013-11-14 00:00:073181 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523182 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033183 pool_.get(),
3184 BoundNetLog()));
3185
3186 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103187 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033188 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3189
3190 EXPECT_EQ(OK, callback1.WaitForResult());
3191 EXPECT_EQ(OK, callback2.WaitForResult());
3192 handle1.Reset();
3193 handle2.Reset();
3194
3195 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103196 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033197 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3198}
3199
3200TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
3201 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3202 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3203
3204 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523205 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033206 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3207 params_,
[email protected]bb1c4662013-11-14 00:00:073208 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523209 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033210 pool_.get(),
3211 BoundNetLog()));
3212
3213 ASSERT_TRUE(pool_->HasGroup("a"));
3214 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103215 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033216 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3217
3218 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3219
3220 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103221 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033222 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3223
3224 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523225 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033226 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3227 params_,
[email protected]bb1c4662013-11-14 00:00:073228 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523229 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033230 pool_.get(),
3231 BoundNetLog()));
3232
3233 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103234 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033235 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3236
3237 EXPECT_EQ(OK, callback1.WaitForResult());
3238 EXPECT_EQ(OK, callback2.WaitForResult());
3239 handle1.Reset();
3240 handle2.Reset();
3241
3242 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103243 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033244 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3245}
3246
3247TEST_F(ClientSocketPoolBaseTest,
3248 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
3249 CreatePool(4, 4);
3250 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3251
3252 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523253 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033254 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3255 params_,
[email protected]bb1c4662013-11-14 00:00:073256 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523257 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033258 pool_.get(),
3259 BoundNetLog()));
3260
3261 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523262 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033263 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3264 params_,
[email protected]bb1c4662013-11-14 00:00:073265 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523266 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033267 pool_.get(),
3268 BoundNetLog()));
3269
3270 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:523271 TestCompletionCallback callback3;
[email protected]2c2bef152010-10-13 00:55:033272 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
3273 params_,
[email protected]bb1c4662013-11-14 00:00:073274 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523275 callback3.callback(),
[email protected]2c2bef152010-10-13 00:55:033276 pool_.get(),
3277 BoundNetLog()));
3278
3279 ASSERT_TRUE(pool_->HasGroup("a"));
3280 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103281 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033282 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3283
3284 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3285
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 EXPECT_EQ(OK, callback1.WaitForResult());
3291 EXPECT_EQ(OK, callback2.WaitForResult());
3292 EXPECT_EQ(OK, callback3.WaitForResult());
3293 handle1.Reset();
3294 handle2.Reset();
3295 handle3.Reset();
3296
3297 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103298 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033299 EXPECT_EQ(3, pool_->IdleSocketCountInGroup("a"));
3300}
3301
3302TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
3303 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3304 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3305
3306 ASSERT_FALSE(pool_->HasGroup("a"));
3307
3308 pool_->RequestSockets("a", &params_, kDefaultMaxSockets,
3309 BoundNetLog());
3310
3311 ASSERT_TRUE(pool_->HasGroup("a"));
3312 EXPECT_EQ(kDefaultMaxSockets, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103313 EXPECT_EQ(kDefaultMaxSockets, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033314
3315 ASSERT_FALSE(pool_->HasGroup("b"));
3316
3317 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
3318 BoundNetLog());
3319
3320 ASSERT_FALSE(pool_->HasGroup("b"));
3321}
3322
3323TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
3324 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3325 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3326
3327 ASSERT_FALSE(pool_->HasGroup("a"));
3328
3329 pool_->RequestSockets("a", &params_, kDefaultMaxSockets - 1,
3330 BoundNetLog());
3331
3332 ASSERT_TRUE(pool_->HasGroup("a"));
3333 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103334 EXPECT_EQ(kDefaultMaxSockets - 1,
3335 pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]51fdc7c2012-04-10 19:19:483336 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033337
3338 ASSERT_FALSE(pool_->HasGroup("b"));
3339
3340 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
3341 BoundNetLog());
3342
3343 ASSERT_TRUE(pool_->HasGroup("b"));
3344 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("b"));
[email protected]51fdc7c2012-04-10 19:19:483345 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033346}
3347
3348TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
3349 CreatePool(4, 4);
3350 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3351
3352 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523353 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033354 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3355 params_,
[email protected]bb1c4662013-11-14 00:00:073356 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523357 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033358 pool_.get(),
3359 BoundNetLog()));
3360 ASSERT_EQ(OK, callback1.WaitForResult());
3361 handle1.Reset();
3362
3363 ASSERT_TRUE(pool_->HasGroup("a"));
3364 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103365 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033366 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3367
3368 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3369
3370 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103371 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033372 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3373}
3374
3375TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
3376 CreatePool(4, 4);
3377 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3378
3379 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523380 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033381 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3382 params_,
[email protected]bb1c4662013-11-14 00:00:073383 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523384 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033385 pool_.get(),
3386 BoundNetLog()));
3387 ASSERT_EQ(OK, callback1.WaitForResult());
3388
3389 ASSERT_TRUE(pool_->HasGroup("a"));
3390 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103391 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033392 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3393 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3394
3395 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3396
3397 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103398 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033399 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3400 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3401}
3402
3403TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
3404 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3405 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3406
3407 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3408 BoundNetLog());
3409
3410 ASSERT_TRUE(pool_->HasGroup("a"));
3411 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103412 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033413 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("a"));
3414
3415 pool_->RequestSockets("b", &params_, kDefaultMaxSocketsPerGroup,
3416 BoundNetLog());
3417
3418 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103419 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]2c2bef152010-10-13 00:55:033420 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("b"));
3421}
3422
[email protected]3c819f522010-12-02 02:03:123423TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
3424 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3425 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3426
3427 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3428 BoundNetLog());
3429
3430 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]fd2e53e2011-01-14 20:40:523431
3432 connect_job_factory_->set_job_type(
3433 TestConnectJob::kMockAdditionalErrorStateJob);
3434 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3435 BoundNetLog());
3436
3437 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]3c819f522010-12-02 02:03:123438}
3439
[email protected]8159a1c2012-06-07 00:00:103440TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
[email protected]2c2bef152010-10-13 00:55:033441 CreatePool(4, 4);
3442 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3443
3444 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3445
3446 ASSERT_TRUE(pool_->HasGroup("a"));
3447 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103448 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033449 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3450
3451 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3452 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103453 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033454 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3455
3456 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523457 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033458 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3459 params_,
[email protected]bb1c4662013-11-14 00:00:073460 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523461 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033462 pool_.get(),
3463 BoundNetLog()));
3464 ASSERT_EQ(OK, callback1.WaitForResult());
3465
3466 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523467 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033468 int rv = handle2.Init("a",
3469 params_,
[email protected]bb1c4662013-11-14 00:00:073470 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523471 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033472 pool_.get(),
3473 BoundNetLog());
3474 if (rv != OK) {
3475 EXPECT_EQ(ERR_IO_PENDING, rv);
3476 EXPECT_EQ(OK, callback2.WaitForResult());
3477 }
3478
[email protected]8159a1c2012-06-07 00:00:103479 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3480 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3481 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("a"));
3482 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3483
[email protected]2c2bef152010-10-13 00:55:033484 handle1.Reset();
3485 handle2.Reset();
3486
[email protected]8159a1c2012-06-07 00:00:103487 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3488 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033489 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3490
3491 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3492 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103493 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033494 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3495}
3496
3497TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
3498 CreatePool(4, 4);
3499 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3500
3501 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3502
3503 ASSERT_TRUE(pool_->HasGroup("a"));
3504 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103505 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033506 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3507
3508 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3509 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103510 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033511 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3512
3513 pool_->RequestSockets("a", &params_, 3, BoundNetLog());
3514 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103515 EXPECT_EQ(3, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033516 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3517
3518 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3519 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103520 EXPECT_EQ(3, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033521 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3522}
3523
3524TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
3525 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3526 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3527
3528 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3529
3530 ASSERT_TRUE(pool_->HasGroup("a"));
3531 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103532 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033533 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3534
3535 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523536 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033537 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3538 params_,
[email protected]bb1c4662013-11-14 00:00:073539 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523540 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033541 pool_.get(),
3542 BoundNetLog()));
3543
3544 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103545 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033546 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3547
3548 ASSERT_EQ(OK, callback1.WaitForResult());
3549
[email protected]0dc88b32014-03-26 20:12:283550 // Make sure if a preconnected socket is not fully connected when a request
[email protected]034df0f32013-01-07 23:17:483551 // starts, it has a connect start time.
3552 TestLoadTimingInfoConnectedNotReused(handle1);
[email protected]2c2bef152010-10-13 00:55:033553 handle1.Reset();
3554
3555 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3556}
3557
[email protected]034df0f32013-01-07 23:17:483558// Checks that fully connected preconnect jobs have no connect times, and are
3559// marked as reused.
3560TEST_F(ClientSocketPoolBaseTest, ConnectedPreconnectJobsHaveNoConnectTimes) {
3561 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3562 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3563 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3564
3565 ASSERT_TRUE(pool_->HasGroup("a"));
3566 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3567 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3568 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3569
3570 ClientSocketHandle handle;
3571 TestCompletionCallback callback;
3572 EXPECT_EQ(OK, handle.Init("a",
3573 params_,
[email protected]bb1c4662013-11-14 00:00:073574 DEFAULT_PRIORITY,
[email protected]034df0f32013-01-07 23:17:483575 callback.callback(),
3576 pool_.get(),
3577 BoundNetLog()));
3578
3579 // Make sure the idle socket was used.
3580 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3581
3582 TestLoadTimingInfoConnectedReused(handle);
3583 handle.Reset();
3584 TestLoadTimingInfoNotConnected(handle);
3585}
3586
[email protected]dcbe168a2010-12-02 03:14:463587// http://crbug.com/64940 regression test.
3588TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
3589 const int kMaxTotalSockets = 3;
3590 const int kMaxSocketsPerGroup = 2;
3591 CreatePool(kMaxTotalSockets, kMaxSocketsPerGroup);
3592 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3593
3594 // Note that group name ordering matters here. "a" comes before "b", so
3595 // CloseOneIdleSocket() will try to close "a"'s idle socket.
3596
3597 // Set up one idle socket in "a".
3598 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523599 TestCompletionCallback callback1;
[email protected]dcbe168a2010-12-02 03:14:463600 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3601 params_,
[email protected]bb1c4662013-11-14 00:00:073602 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523603 callback1.callback(),
[email protected]dcbe168a2010-12-02 03:14:463604 pool_.get(),
3605 BoundNetLog()));
3606
3607 ASSERT_EQ(OK, callback1.WaitForResult());
3608 handle1.Reset();
3609 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3610
3611 // Set up two active sockets in "b".
3612 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523613 TestCompletionCallback callback2;
[email protected]dcbe168a2010-12-02 03:14:463614 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("b",
3615 params_,
[email protected]bb1c4662013-11-14 00:00:073616 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523617 callback1.callback(),
[email protected]dcbe168a2010-12-02 03:14:463618 pool_.get(),
3619 BoundNetLog()));
3620 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("b",
3621 params_,
[email protected]bb1c4662013-11-14 00:00:073622 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523623 callback2.callback(),
[email protected]dcbe168a2010-12-02 03:14:463624 pool_.get(),
3625 BoundNetLog()));
3626
3627 ASSERT_EQ(OK, callback1.WaitForResult());
3628 ASSERT_EQ(OK, callback2.WaitForResult());
3629 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103630 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463631 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3632
3633 // Now we have 1 idle socket in "a" and 2 active sockets in "b". This means
3634 // we've maxed out on sockets, since we set |kMaxTotalSockets| to 3.
3635 // Requesting 2 preconnected sockets for "a" should fail to allocate any more
3636 // sockets for "a", and "b" should still have 2 active sockets.
3637
3638 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3639 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103640 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]dcbe168a2010-12-02 03:14:463641 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3642 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3643 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103644 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463645 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3646 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3647
3648 // Now release the 2 active sockets for "b". This will give us 1 idle socket
3649 // in "a" and 2 idle sockets in "b". Requesting 2 preconnected sockets for
3650 // "a" should result in closing 1 for "b".
3651 handle1.Reset();
3652 handle2.Reset();
3653 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("b"));
3654 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3655
3656 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3657 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103658 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]dcbe168a2010-12-02 03:14:463659 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3660 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3661 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103662 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463663 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("b"));
3664 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3665}
3666
[email protected]b7b8be42011-07-12 12:46:413667TEST_F(ClientSocketPoolBaseTest, PreconnectWithoutBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073668 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3669 pool_->EnableConnectBackupJobs();
3670
3671 // Make the ConnectJob hang until it times out, shorten the timeout.
3672 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3673 connect_job_factory_->set_timeout_duration(
3674 base::TimeDelta::FromMilliseconds(500));
3675 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3676 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103677 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073678 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073679
[email protected]b7b8be42011-07-12 12:46:413680 // Verify the backup timer doesn't create a backup job, by making
3681 // the backup job a pending job instead of a waiting job, so it
3682 // *would* complete if it were created.
[email protected]a9fc8fc2011-05-10 02:41:073683 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2da659e2013-05-23 20:51:343684 base::MessageLoop::current()->PostDelayedTask(
3685 FROM_HERE,
3686 base::MessageLoop::QuitClosure(),
3687 base::TimeDelta::FromSeconds(1));
3688 base::MessageLoop::current()->Run();
[email protected]a9fc8fc2011-05-10 02:41:073689 EXPECT_FALSE(pool_->HasGroup("a"));
3690}
3691
[email protected]b7b8be42011-07-12 12:46:413692TEST_F(ClientSocketPoolBaseTest, PreconnectWithBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073693 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3694 pool_->EnableConnectBackupJobs();
3695
3696 // Make the ConnectJob hang forever.
3697 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3698 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3699 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103700 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073701 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]2da659e2013-05-23 20:51:343702 base::MessageLoop::current()->RunUntilIdle();
[email protected]a9fc8fc2011-05-10 02:41:073703
3704 // Make the backup job be a pending job, so it completes normally.
3705 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3706 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:523707 TestCompletionCallback callback;
[email protected]a9fc8fc2011-05-10 02:41:073708 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
3709 params_,
[email protected]bb1c4662013-11-14 00:00:073710 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523711 callback.callback(),
[email protected]a9fc8fc2011-05-10 02:41:073712 pool_.get(),
3713 BoundNetLog()));
[email protected]b7b8be42011-07-12 12:46:413714 // Timer has started, but the backup connect job shouldn't be created yet.
[email protected]a9fc8fc2011-05-10 02:41:073715 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103716 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073717 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3718 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3719 ASSERT_EQ(OK, callback.WaitForResult());
3720
3721 // The hung connect job should still be there, but everything else should be
3722 // complete.
3723 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103724 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073725 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3726 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3727}
3728
[email protected]0dc88b32014-03-26 20:12:283729// Tests that a preconnect that starts out with unread data can still be used.
3730// http://crbug.com/334467
3731TEST_F(ClientSocketPoolBaseTest, PreconnectWithUnreadData) {
3732 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3733 connect_job_factory_->set_job_type(TestConnectJob::kMockUnreadDataJob);
3734
3735 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3736
3737 ASSERT_TRUE(pool_->HasGroup("a"));
3738 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3739 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3740 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3741
3742 // Fail future jobs to be sure that handle receives the preconnected socket
3743 // rather than closing it and making a new one.
3744 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3745 ClientSocketHandle handle;
3746 TestCompletionCallback callback;
3747 EXPECT_EQ(OK, handle.Init("a",
3748 params_,
3749 DEFAULT_PRIORITY,
3750 callback.callback(),
3751 pool_.get(),
3752 BoundNetLog()));
3753
3754 ASSERT_TRUE(pool_->HasGroup("a"));
3755 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3756 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3757 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3758
3759 // Drain the pending read.
3760 EXPECT_EQ(1, handle.socket()->Read(NULL, 1, CompletionCallback()));
3761
3762 TestLoadTimingInfoConnectedReused(handle);
3763 handle.Reset();
3764
3765 // The socket should be usable now that it's idle again.
3766 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3767}
3768
[email protected]043b68c82013-08-22 23:41:523769class MockLayeredPool : public HigherLayeredPool {
[email protected]58e562f2013-04-22 17:32:203770 public:
3771 MockLayeredPool(TestClientSocketPool* pool,
3772 const std::string& group_name)
3773 : pool_(pool),
[email protected]58e562f2013-04-22 17:32:203774 group_name_(group_name),
3775 can_release_connection_(true) {
[email protected]043b68c82013-08-22 23:41:523776 pool_->AddHigherLayeredPool(this);
[email protected]58e562f2013-04-22 17:32:203777 }
3778
3779 ~MockLayeredPool() {
[email protected]043b68c82013-08-22 23:41:523780 pool_->RemoveHigherLayeredPool(this);
[email protected]58e562f2013-04-22 17:32:203781 }
3782
3783 int RequestSocket(TestClientSocketPool* pool) {
[email protected]bb1c4662013-11-14 00:00:073784 scoped_refptr<TestSocketParams> params(
3785 new TestSocketParams(false /* ignore_limits */));
3786 return handle_.Init(group_name_, params, DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203787 callback_.callback(), pool, BoundNetLog());
3788 }
3789
3790 int RequestSocketWithoutLimits(TestClientSocketPool* pool) {
[email protected]bb1c4662013-11-14 00:00:073791 scoped_refptr<TestSocketParams> params(
3792 new TestSocketParams(true /* ignore_limits */));
3793 return handle_.Init(group_name_, params, MAXIMUM_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203794 callback_.callback(), pool, BoundNetLog());
3795 }
3796
3797 bool ReleaseOneConnection() {
3798 if (!handle_.is_initialized() || !can_release_connection_) {
3799 return false;
3800 }
3801 handle_.socket()->Disconnect();
3802 handle_.Reset();
3803 return true;
3804 }
3805
3806 void set_can_release_connection(bool can_release_connection) {
3807 can_release_connection_ = can_release_connection;
3808 }
3809
3810 MOCK_METHOD0(CloseOneIdleConnection, bool());
3811
3812 private:
3813 TestClientSocketPool* const pool_;
[email protected]58e562f2013-04-22 17:32:203814 ClientSocketHandle handle_;
3815 TestCompletionCallback callback_;
3816 const std::string group_name_;
3817 bool can_release_connection_;
3818};
3819
3820TEST_F(ClientSocketPoolBaseTest, FailToCloseIdleSocketsNotHeldByLayeredPool) {
3821 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3822 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3823
3824 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
3825 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3826 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3827 .WillOnce(Return(false));
[email protected]043b68c82013-08-22 23:41:523828 EXPECT_FALSE(pool_->CloseOneIdleConnectionInHigherLayeredPool());
[email protected]58e562f2013-04-22 17:32:203829}
3830
3831TEST_F(ClientSocketPoolBaseTest, ForciblyCloseIdleSocketsHeldByLayeredPool) {
3832 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3833 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3834
3835 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
3836 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3837 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3838 .WillOnce(Invoke(&mock_layered_pool,
3839 &MockLayeredPool::ReleaseOneConnection));
[email protected]043b68c82013-08-22 23:41:523840 EXPECT_TRUE(pool_->CloseOneIdleConnectionInHigherLayeredPool());
[email protected]58e562f2013-04-22 17:32:203841}
3842
3843// Tests the basic case of closing an idle socket in a higher layered pool when
3844// a new request is issued and the lower layer pool is stalled.
3845TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsHeldByLayeredPoolWhenNeeded) {
3846 CreatePool(1, 1);
3847 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3848
3849 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
3850 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3851 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3852 .WillOnce(Invoke(&mock_layered_pool,
3853 &MockLayeredPool::ReleaseOneConnection));
3854 ClientSocketHandle handle;
3855 TestCompletionCallback callback;
3856 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
3857 params_,
[email protected]bb1c4662013-11-14 00:00:073858 DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203859 callback.callback(),
3860 pool_.get(),
3861 BoundNetLog()));
3862 EXPECT_EQ(OK, callback.WaitForResult());
3863}
3864
3865// Same as above, but the idle socket is in the same group as the stalled
3866// socket, and closes the only other request in its group when closing requests
3867// in higher layered pools. This generally shouldn't happen, but it may be
3868// possible if a higher level pool issues a request and the request is
3869// subsequently cancelled. Even if it's not possible, best not to crash.
3870TEST_F(ClientSocketPoolBaseTest,
3871 CloseIdleSocketsHeldByLayeredPoolWhenNeededSameGroup) {
3872 CreatePool(2, 2);
3873 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3874
3875 // Need a socket in another group for the pool to be stalled (If a group
3876 // has the maximum number of connections already, it's not stalled).
3877 ClientSocketHandle handle1;
3878 TestCompletionCallback callback1;
3879 EXPECT_EQ(OK, handle1.Init("group1",
3880 params_,
[email protected]bb1c4662013-11-14 00:00:073881 DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203882 callback1.callback(),
3883 pool_.get(),
3884 BoundNetLog()));
3885
3886 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
3887 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3888 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3889 .WillOnce(Invoke(&mock_layered_pool,
3890 &MockLayeredPool::ReleaseOneConnection));
3891 ClientSocketHandle handle;
3892 TestCompletionCallback callback2;
3893 EXPECT_EQ(ERR_IO_PENDING, handle.Init("group2",
3894 params_,
[email protected]bb1c4662013-11-14 00:00:073895 DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203896 callback2.callback(),
3897 pool_.get(),
3898 BoundNetLog()));
3899 EXPECT_EQ(OK, callback2.WaitForResult());
3900}
3901
3902// Tests the case when an idle socket can be closed when a new request is
3903// issued, and the new request belongs to a group that was previously stalled.
3904TEST_F(ClientSocketPoolBaseTest,
3905 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded) {
3906 CreatePool(2, 2);
3907 std::list<TestConnectJob::JobType> job_types;
3908 job_types.push_back(TestConnectJob::kMockJob);
3909 job_types.push_back(TestConnectJob::kMockJob);
3910 job_types.push_back(TestConnectJob::kMockJob);
3911 job_types.push_back(TestConnectJob::kMockJob);
3912 connect_job_factory_->set_job_types(&job_types);
3913
3914 ClientSocketHandle handle1;
3915 TestCompletionCallback callback1;
3916 EXPECT_EQ(OK, handle1.Init("group1",
3917 params_,
[email protected]bb1c4662013-11-14 00:00:073918 DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203919 callback1.callback(),
3920 pool_.get(),
3921 BoundNetLog()));
3922
3923 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
3924 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3925 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3926 .WillRepeatedly(Invoke(&mock_layered_pool,
3927 &MockLayeredPool::ReleaseOneConnection));
3928 mock_layered_pool.set_can_release_connection(false);
3929
3930 // The third request is made when the socket pool is in a stalled state.
3931 ClientSocketHandle handle3;
3932 TestCompletionCallback callback3;
3933 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("group3",
3934 params_,
[email protected]bb1c4662013-11-14 00:00:073935 DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203936 callback3.callback(),
3937 pool_.get(),
3938 BoundNetLog()));
3939
3940 base::RunLoop().RunUntilIdle();
3941 EXPECT_FALSE(callback3.have_result());
3942
3943 // The fourth request is made when the pool is no longer stalled. The third
3944 // request should be serviced first, since it was issued first and has the
3945 // same priority.
3946 mock_layered_pool.set_can_release_connection(true);
3947 ClientSocketHandle handle4;
3948 TestCompletionCallback callback4;
3949 EXPECT_EQ(ERR_IO_PENDING, handle4.Init("group3",
3950 params_,
[email protected]bb1c4662013-11-14 00:00:073951 DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203952 callback4.callback(),
3953 pool_.get(),
3954 BoundNetLog()));
3955 EXPECT_EQ(OK, callback3.WaitForResult());
3956 EXPECT_FALSE(callback4.have_result());
3957
3958 // Closing a handle should free up another socket slot.
3959 handle1.Reset();
3960 EXPECT_EQ(OK, callback4.WaitForResult());
3961}
3962
3963// Tests the case when an idle socket can be closed when a new request is
3964// issued, and the new request belongs to a group that was previously stalled.
3965//
3966// The two differences from the above test are that the stalled requests are not
3967// in the same group as the layered pool's request, and the the fourth request
3968// has a higher priority than the third one, so gets a socket first.
3969TEST_F(ClientSocketPoolBaseTest,
3970 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded2) {
3971 CreatePool(2, 2);
3972 std::list<TestConnectJob::JobType> job_types;
3973 job_types.push_back(TestConnectJob::kMockJob);
3974 job_types.push_back(TestConnectJob::kMockJob);
3975 job_types.push_back(TestConnectJob::kMockJob);
3976 job_types.push_back(TestConnectJob::kMockJob);
3977 connect_job_factory_->set_job_types(&job_types);
3978
3979 ClientSocketHandle handle1;
3980 TestCompletionCallback callback1;
3981 EXPECT_EQ(OK, handle1.Init("group1",
3982 params_,
[email protected]bb1c4662013-11-14 00:00:073983 DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203984 callback1.callback(),
3985 pool_.get(),
3986 BoundNetLog()));
3987
3988 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
3989 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3990 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3991 .WillRepeatedly(Invoke(&mock_layered_pool,
3992 &MockLayeredPool::ReleaseOneConnection));
3993 mock_layered_pool.set_can_release_connection(false);
3994
3995 // The third request is made when the socket pool is in a stalled state.
3996 ClientSocketHandle handle3;
3997 TestCompletionCallback callback3;
3998 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("group3",
3999 params_,
4000 MEDIUM,
4001 callback3.callback(),
4002 pool_.get(),
4003 BoundNetLog()));
4004
4005 base::RunLoop().RunUntilIdle();
4006 EXPECT_FALSE(callback3.have_result());
4007
4008 // The fourth request is made when the pool is no longer stalled. This
4009 // request has a higher priority than the third request, so is serviced first.
4010 mock_layered_pool.set_can_release_connection(true);
4011 ClientSocketHandle handle4;
4012 TestCompletionCallback callback4;
4013 EXPECT_EQ(ERR_IO_PENDING, handle4.Init("group3",
4014 params_,
4015 HIGHEST,
4016 callback4.callback(),
4017 pool_.get(),
4018 BoundNetLog()));
4019 EXPECT_EQ(OK, callback4.WaitForResult());
4020 EXPECT_FALSE(callback3.have_result());
4021
4022 // Closing a handle should free up another socket slot.
4023 handle1.Reset();
4024 EXPECT_EQ(OK, callback3.WaitForResult());
4025}
4026
4027TEST_F(ClientSocketPoolBaseTest,
4028 CloseMultipleIdleSocketsHeldByLayeredPoolWhenNeeded) {
4029 CreatePool(1, 1);
4030 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4031
4032 MockLayeredPool mock_layered_pool1(pool_.get(), "foo");
4033 EXPECT_EQ(OK, mock_layered_pool1.RequestSocket(pool_.get()));
4034 EXPECT_CALL(mock_layered_pool1, CloseOneIdleConnection())
4035 .WillRepeatedly(Invoke(&mock_layered_pool1,
4036 &MockLayeredPool::ReleaseOneConnection));
4037 MockLayeredPool mock_layered_pool2(pool_.get(), "bar");
4038 EXPECT_EQ(OK, mock_layered_pool2.RequestSocketWithoutLimits(pool_.get()));
4039 EXPECT_CALL(mock_layered_pool2, CloseOneIdleConnection())
4040 .WillRepeatedly(Invoke(&mock_layered_pool2,
4041 &MockLayeredPool::ReleaseOneConnection));
4042 ClientSocketHandle handle;
4043 TestCompletionCallback callback;
4044 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
4045 params_,
[email protected]bb1c4662013-11-14 00:00:074046 DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:204047 callback.callback(),
4048 pool_.get(),
4049 BoundNetLog()));
4050 EXPECT_EQ(OK, callback.WaitForResult());
4051}
4052
[email protected]b021ece62013-06-11 11:06:334053// Test that when a socket pool and group are at their limits, a request
4054// with |ignore_limits| triggers creation of a new socket, and gets the socket
4055// instead of a request with the same priority that was issued earlier, but
4056// that does not have |ignore_limits| set.
4057TEST_F(ClientSocketPoolBaseTest, IgnoreLimits) {
[email protected]bb1c4662013-11-14 00:00:074058 scoped_refptr<TestSocketParams> params_ignore_limits(
4059 new TestSocketParams(true /* ignore_limits */));
[email protected]b021ece62013-06-11 11:06:334060 CreatePool(1, 1);
4061
4062 // Issue a request to reach the socket pool limit.
[email protected]bb1c4662013-11-14 00:00:074063 EXPECT_EQ(OK, StartRequestWithParams("a", MAXIMUM_PRIORITY, params_));
[email protected]b021ece62013-06-11 11:06:334064 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4065
4066 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4067
[email protected]bb1c4662013-11-14 00:00:074068 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithParams("a", MAXIMUM_PRIORITY,
[email protected]b021ece62013-06-11 11:06:334069 params_));
4070 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4071
[email protected]bb1c4662013-11-14 00:00:074072 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithParams("a", MAXIMUM_PRIORITY,
[email protected]b021ece62013-06-11 11:06:334073 params_ignore_limits));
4074 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4075
4076 EXPECT_EQ(OK, request(2)->WaitForResult());
4077 EXPECT_FALSE(request(1)->have_result());
4078}
4079
[email protected]c55fabd2013-11-04 23:26:564080// Test that when a socket pool and group are at their limits, a ConnectJob
4081// issued for a request with |ignore_limits| set is not cancelled when a request
4082// without |ignore_limits| issued to the same group is cancelled.
4083TEST_F(ClientSocketPoolBaseTest, IgnoreLimitsCancelOtherJob) {
[email protected]bb1c4662013-11-14 00:00:074084 scoped_refptr<TestSocketParams> params_ignore_limits(
4085 new TestSocketParams(true /* ignore_limits */));
[email protected]c55fabd2013-11-04 23:26:564086 CreatePool(1, 1);
4087
4088 // Issue a request to reach the socket pool limit.
[email protected]bb1c4662013-11-14 00:00:074089 EXPECT_EQ(OK, StartRequestWithParams("a", MAXIMUM_PRIORITY, params_));
[email protected]c55fabd2013-11-04 23:26:564090 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4091
4092 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4093
[email protected]bb1c4662013-11-14 00:00:074094 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithParams("a", MAXIMUM_PRIORITY,
4095 params_));
[email protected]c55fabd2013-11-04 23:26:564096 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4097
[email protected]bb1c4662013-11-14 00:00:074098 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithParams("a", MAXIMUM_PRIORITY,
[email protected]b021ece62013-06-11 11:06:334099 params_ignore_limits));
4100 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4101
4102 // Cancel the pending request without ignore_limits set. The ConnectJob
4103 // should not be cancelled.
4104 request(1)->handle()->Reset();
4105 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4106
4107 EXPECT_EQ(OK, request(2)->WaitForResult());
4108 EXPECT_FALSE(request(1)->have_result());
4109}
4110
[email protected]f6d1d6eb2009-06-24 20:16:094111} // namespace
4112
4113} // namespace net