blob: 363010aba61fcda0f729c05846f4220db2f586fd [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]f6d1d6eb2009-06-24 20:16:0912#include "base/compiler_specific.h"
[email protected]3b63f8f42011-03-28 01:54:1513#include "base/memory/ref_counted.h"
14#include "base/memory/scoped_vector.h"
[email protected]6ea7b152011-12-21 21:21:1315#include "base/memory/weak_ptr.h"
[email protected]f6d1d6eb2009-06-24 20:16:0916#include "base/message_loop.h"
[email protected]1870d5cf2011-05-12 01:55:4017#include "base/stringprintf.h"
[email protected]e83326f2010-07-31 17:29:2518#include "base/string_number_conversions.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]d8eb84242010-09-25 02:25:0621#include "net/base/net_errors.h"
[email protected]9e743cd2010-03-16 07:03:5322#include "net/base/net_log.h"
23#include "net/base/net_log_unittest.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"
[email protected]f6d1d6eb2009-06-24 20:16:0927#include "net/socket/client_socket_factory.h"
28#include "net/socket/client_socket_handle.h"
[email protected]b89f7e42010-05-20 20:37:0029#include "net/socket/client_socket_pool_histograms.h"
[email protected]75439d3b2009-07-23 22:11:1730#include "net/socket/socket_test_util.h"
[email protected]3268023f2011-05-05 00:08:1031#include "net/socket/stream_socket.h"
[email protected]51fdc7c2012-04-10 19:19:4832#include "testing/gmock/include/gmock/gmock.h"
[email protected]f6d1d6eb2009-06-24 20:16:0933#include "testing/gtest/include/gtest/gtest.h"
34
[email protected]51fdc7c2012-04-10 19:19:4835using ::testing::Invoke;
36using ::testing::Return;
37
[email protected]f6d1d6eb2009-06-24 20:16:0938namespace net {
39
40namespace {
41
[email protected]211d21722009-07-22 15:48:5342const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2043const int kDefaultMaxSocketsPerGroup = 2;
[email protected]a554a8262010-05-20 00:13:5244const net::RequestPriority kDefaultPriority = MEDIUM;
[email protected]0b7648c2009-07-06 20:14:0145
[email protected]df4b4ef2010-07-12 18:25:2146class TestSocketParams : public base::RefCounted<TestSocketParams> {
[email protected]5acdce12011-03-30 13:00:2047 public:
[email protected]51fdc7c2012-04-10 19:19:4848 TestSocketParams() : ignore_limits_(false) {}
49
50 void set_ignore_limits(bool ignore_limits) {
51 ignore_limits_ = ignore_limits;
52 }
53 bool ignore_limits() { return ignore_limits_; }
54
[email protected]df4b4ef2010-07-12 18:25:2155 private:
56 friend class base::RefCounted<TestSocketParams>;
57 ~TestSocketParams() {}
[email protected]51fdc7c2012-04-10 19:19:4858
59 bool ignore_limits_;
[email protected]df4b4ef2010-07-12 18:25:2160};
[email protected]7fc5b09a2010-02-27 00:07:3861typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
[email protected]d80a4322009-08-14 07:07:4962
[email protected]3268023f2011-05-05 00:08:1063class MockClientSocket : public StreamSocket {
[email protected]f6d1d6eb2009-06-24 20:16:0964 public:
[email protected]5e6efa52011-06-27 17:26:4165 MockClientSocket() : connected_(false), was_used_to_convey_data_(false),
66 num_bytes_read_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:0967
[email protected]3f55aa12011-12-07 02:03:3368 // Socket implementation.
[email protected]ab838892009-06-30 18:49:0569 virtual int Read(
[email protected]83039bb2011-12-09 18:43:5570 IOBuffer* /* buf */, int len,
71 const CompletionCallback& /* callback */) OVERRIDE {
[email protected]3f55aa12011-12-07 02:03:3372 num_bytes_read_ += len;
73 return len;
74 }
[email protected]ab838892009-06-30 18:49:0575
76 virtual int Write(
[email protected]83039bb2011-12-09 18:43:5577 IOBuffer* /* buf */, int len,
78 const CompletionCallback& /* callback */) OVERRIDE {
[email protected]0f873e82010-09-02 16:09:0179 was_used_to_convey_data_ = true;
80 return len;
[email protected]ab838892009-06-30 18:49:0581 }
[email protected]06650c52010-06-03 00:49:1782 virtual bool SetReceiveBufferSize(int32 size) { return true; }
83 virtual bool SetSendBufferSize(int32 size) { return true; }
[email protected]ab838892009-06-30 18:49:0584
[email protected]dbf036f2011-12-06 23:33:2485 // StreamSocket implementation.
[email protected]83039bb2011-12-09 18:43:5586 virtual int Connect(const CompletionCallback& callback) OVERRIDE {
[email protected]dbf036f2011-12-06 23:33:2487 connected_ = true;
88 return OK;
89 }
[email protected]f6d1d6eb2009-06-24 20:16:0990
[email protected]ab838892009-06-30 18:49:0591 virtual void Disconnect() { connected_ = false; }
92 virtual bool IsConnected() const { return connected_; }
93 virtual bool IsConnectedAndIdle() const { return connected_; }
[email protected]0b7648c2009-07-06 20:14:0194
[email protected]a3528692012-06-08 00:11:4295 virtual int GetPeerAddress(IPEndPoint* /* address */) const {
[email protected]9f864b32010-01-20 15:01:1696 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:0997 }
[email protected]f6d1d6eb2009-06-24 20:16:0998
[email protected]e7f74da2011-04-19 23:49:3599 virtual int GetLocalAddress(IPEndPoint* /* address */) const {
100 return ERR_UNEXPECTED;
101 }
102
[email protected]a2006ece2010-04-23 16:44:02103 virtual const BoundNetLog& NetLog() const {
104 return net_log_;
105 }
106
[email protected]9b5614a2010-08-25 20:29:45107 virtual void SetSubresourceSpeculation() {}
108 virtual void SetOmniboxSpeculation() {}
[email protected]5e6efa52011-06-27 17:26:41109 virtual bool WasEverUsed() const {
110 return was_used_to_convey_data_ || num_bytes_read_ > 0;
111 }
[email protected]7f7e92392010-10-26 18:29:29112 virtual bool UsingTCPFastOpen() const { return false; }
[email protected]5e6efa52011-06-27 17:26:41113 virtual int64 NumBytesRead() const { return num_bytes_read_; }
114 virtual base::TimeDelta GetConnectTimeMicros() const {
115 static const base::TimeDelta kDummyConnectTimeMicros =
116 base::TimeDelta::FromMicroseconds(10);
117 return kDummyConnectTimeMicros; // Dummy value.
118 }
[email protected]2d88e7d2012-07-19 17:55:17119 virtual bool WasNpnNegotiated() const {
120 return false;
121 }
[email protected]33661e482012-04-03 16:16:26122 virtual NextProto GetNegotiatedProtocol() const {
123 return kProtoUnknown;
124 }
[email protected]2d88e7d2012-07-19 17:55:17125 virtual bool GetSSLInfo(SSLInfo* ssl_info) {
126 return false;
127 }
[email protected]9b5614a2010-08-25 20:29:45128
[email protected]f6d1d6eb2009-06-24 20:16:09129 private:
130 bool connected_;
[email protected]a2006ece2010-04-23 16:44:02131 BoundNetLog net_log_;
[email protected]0f873e82010-09-02 16:09:01132 bool was_used_to_convey_data_;
[email protected]5e6efa52011-06-27 17:26:41133 int num_bytes_read_;
[email protected]f6d1d6eb2009-06-24 20:16:09134
[email protected]ab838892009-06-30 18:49:05135 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:09136};
137
[email protected]5fc08e32009-07-15 17:09:57138class TestConnectJob;
139
[email protected]f6d1d6eb2009-06-24 20:16:09140class MockClientSocketFactory : public ClientSocketFactory {
141 public:
[email protected]ab838892009-06-30 18:49:05142 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:09143
[email protected]98b0e582011-06-22 14:31:41144 virtual DatagramClientSocket* CreateDatagramClientSocket(
[email protected]5370c012011-06-29 03:47:04145 DatagramSocket::BindType bind_type,
146 const RandIntCallback& rand_int_cb,
[email protected]98b0e582011-06-22 14:31:41147 NetLog* net_log,
148 const NetLog::Source& source) {
149 NOTREACHED();
150 return NULL;
151 }
152
[email protected]3268023f2011-05-05 00:08:10153 virtual StreamSocket* CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07154 const AddressList& addresses,
155 NetLog* /* net_log */,
156 const NetLog::Source& /*source*/) {
[email protected]f6d1d6eb2009-06-24 20:16:09157 allocation_count_++;
[email protected]ab838892009-06-30 18:49:05158 return NULL;
[email protected]f6d1d6eb2009-06-24 20:16:09159 }
160
161 virtual SSLClientSocket* CreateSSLClientSocket(
[email protected]e60e47a2010-07-14 03:37:18162 ClientSocketHandle* transport_socket,
[email protected]4f4de7e62010-11-12 19:55:27163 const HostPortPair& host_and_port,
[email protected]7ab5bbd12010-10-19 13:33:21164 const SSLConfig& ssl_config,
[email protected]feb79bcd2011-07-21 16:55:17165 const SSLClientSocketContext& context) {
[email protected]f6d1d6eb2009-06-24 20:16:09166 NOTIMPLEMENTED();
167 return NULL;
168 }
169
[email protected]25f47352011-02-25 16:31:59170 virtual void ClearSSLSessionCache() {
171 NOTIMPLEMENTED();
172 }
173
[email protected]5fc08e32009-07-15 17:09:57174 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
175 void SignalJobs();
176
[email protected]f6d1d6eb2009-06-24 20:16:09177 int allocation_count() const { return allocation_count_; }
178
[email protected]f6d1d6eb2009-06-24 20:16:09179 private:
180 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:57181 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09182};
183
[email protected]ab838892009-06-30 18:49:05184class TestConnectJob : public ConnectJob {
185 public:
186 enum JobType {
187 kMockJob,
188 kMockFailingJob,
189 kMockPendingJob,
190 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57191 kMockWaitingJob,
192 kMockAdvancingLoadStateJob,
[email protected]e772db3f2010-07-12 18:11:13193 kMockRecoverableJob,
194 kMockPendingRecoverableJob,
[email protected]e60e47a2010-07-14 03:37:18195 kMockAdditionalErrorStateJob,
196 kMockPendingAdditionalErrorStateJob,
[email protected]ab838892009-06-30 18:49:05197 };
198
[email protected]994d4932010-07-12 17:55:13199 // The kMockPendingJob uses a slight delay before allowing the connect
200 // to complete.
201 static const int kPendingConnectDelay = 2;
202
[email protected]ab838892009-06-30 18:49:05203 TestConnectJob(JobType job_type,
204 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49205 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34206 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05207 ConnectJob::Delegate* delegate,
[email protected]fd7b7c92009-08-20 19:38:30208 MockClientSocketFactory* client_socket_factory,
[email protected]06650c52010-06-03 00:49:17209 NetLog* net_log)
210 : ConnectJob(group_name, timeout_duration, delegate,
211 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
[email protected]2ab05b52009-07-01 23:57:58212 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05213 client_socket_factory_(client_socket_factory),
[email protected]6ea7b152011-12-21 21:21:13214 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
[email protected]e60e47a2010-07-14 03:37:18215 load_state_(LOAD_STATE_IDLE),
216 store_additional_error_state_(false) {}
[email protected]ab838892009-06-30 18:49:05217
[email protected]974ebd62009-08-03 23:14:34218 void Signal() {
[email protected]e772db3f2010-07-12 18:11:13219 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
[email protected]974ebd62009-08-03 23:14:34220 }
221
[email protected]46451352009-09-01 14:54:21222 virtual LoadState GetLoadState() const { return load_state_; }
223
[email protected]e60e47a2010-07-14 03:37:18224 virtual void GetAdditionalErrorState(ClientSocketHandle* handle) {
225 if (store_additional_error_state_) {
226 // Set all of the additional error state fields in some way.
227 handle->set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43228 HttpResponseInfo info;
229 info.headers = new HttpResponseHeaders("");
230 handle->set_ssl_error_response_info(info);
[email protected]e60e47a2010-07-14 03:37:18231 }
232 }
233
[email protected]974ebd62009-08-03 23:14:34234 private:
[email protected]3f55aa12011-12-07 02:03:33235 // ConnectJob implementation.
[email protected]ab838892009-06-30 18:49:05236
[email protected]974ebd62009-08-03 23:14:34237 virtual int ConnectInternal() {
[email protected]ab838892009-06-30 18:49:05238 AddressList ignored;
[email protected]ab739042011-04-07 15:22:28239 client_socket_factory_->CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07240 ignored, NULL, net::NetLog::Source());
[email protected]6e713f02009-08-06 02:56:40241 set_socket(new MockClientSocket());
[email protected]ab838892009-06-30 18:49:05242 switch (job_type_) {
243 case kMockJob:
[email protected]e772db3f2010-07-12 18:11:13244 return DoConnect(true /* successful */, false /* sync */,
245 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05246 case kMockFailingJob:
[email protected]e772db3f2010-07-12 18:11:13247 return DoConnect(false /* error */, false /* sync */,
248 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05249 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57250 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47251
252 // Depending on execution timings, posting a delayed task can result
253 // in the task getting executed the at the earliest possible
254 // opportunity or only after returning once from the message loop and
255 // then a second call into the message loop. In order to make behavior
256 // more deterministic, we change the default delay to 2ms. This should
257 // always require us to wait for the second call into the message loop.
258 //
259 // N.B. The correct fix for this and similar timing problems is to
260 // abstract time for the purpose of unittests. Unfortunately, we have
261 // a lot of third-party components that directly call the various
262 // time functions, so this change would be rather invasive.
263 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05264 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13265 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
266 weak_factory_.GetWeakPtr(),
267 true /* successful */,
268 true /* async */,
269 false /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53270 base::TimeDelta::FromMilliseconds(kPendingConnectDelay));
[email protected]ab838892009-06-30 18:49:05271 return ERR_IO_PENDING;
272 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57273 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47274 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05275 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13276 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
277 weak_factory_.GetWeakPtr(),
278 false /* error */,
279 true /* async */,
280 false /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53281 base::TimeDelta::FromMilliseconds(2));
[email protected]ab838892009-06-30 18:49:05282 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57283 case kMockWaitingJob:
284 client_socket_factory_->WaitForSignal(this);
285 waiting_success_ = true;
286 return ERR_IO_PENDING;
287 case kMockAdvancingLoadStateJob:
[email protected]e6ec67b2010-06-16 00:12:46288 MessageLoop::current()->PostTask(
[email protected]6ea7b152011-12-21 21:21:13289 FROM_HERE, base::Bind(&TestConnectJob::AdvanceLoadState,
290 weak_factory_.GetWeakPtr(), load_state_));
[email protected]5fc08e32009-07-15 17:09:57291 return ERR_IO_PENDING;
[email protected]e772db3f2010-07-12 18:11:13292 case kMockRecoverableJob:
293 return DoConnect(false /* error */, false /* sync */,
294 true /* recoverable */);
295 case kMockPendingRecoverableJob:
296 set_load_state(LOAD_STATE_CONNECTING);
297 MessageLoop::current()->PostDelayedTask(
298 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13299 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
300 weak_factory_.GetWeakPtr(),
301 false /* error */,
302 true /* async */,
303 true /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53304 base::TimeDelta::FromMilliseconds(2));
[email protected]e772db3f2010-07-12 18:11:13305 return ERR_IO_PENDING;
[email protected]e60e47a2010-07-14 03:37:18306 case kMockAdditionalErrorStateJob:
307 store_additional_error_state_ = true;
308 return DoConnect(false /* error */, false /* sync */,
309 false /* recoverable */);
310 case kMockPendingAdditionalErrorStateJob:
311 set_load_state(LOAD_STATE_CONNECTING);
312 store_additional_error_state_ = true;
313 MessageLoop::current()->PostDelayedTask(
314 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13315 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
316 weak_factory_.GetWeakPtr(),
317 false /* error */,
318 true /* async */,
319 false /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53320 base::TimeDelta::FromMilliseconds(2));
[email protected]e60e47a2010-07-14 03:37:18321 return ERR_IO_PENDING;
[email protected]ab838892009-06-30 18:49:05322 default:
323 NOTREACHED();
[email protected]6e713f02009-08-06 02:56:40324 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05325 return ERR_FAILED;
326 }
327 }
328
[email protected]46451352009-09-01 14:54:21329 void set_load_state(LoadState load_state) { load_state_ = load_state; }
330
[email protected]e772db3f2010-07-12 18:11:13331 int DoConnect(bool succeed, bool was_async, bool recoverable) {
332 int result = OK;
[email protected]ab838892009-06-30 18:49:05333 if (succeed) {
[email protected]83039bb2011-12-09 18:43:55334 socket()->Connect(CompletionCallback());
[email protected]e772db3f2010-07-12 18:11:13335 } else if (recoverable) {
336 result = ERR_PROXY_AUTH_REQUESTED;
[email protected]6e713f02009-08-06 02:56:40337 } else {
[email protected]e772db3f2010-07-12 18:11:13338 result = ERR_CONNECTION_FAILED;
[email protected]6e713f02009-08-06 02:56:40339 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05340 }
[email protected]2ab05b52009-07-01 23:57:58341
342 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30343 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05344 return result;
345 }
346
[email protected]cfa8228c2010-06-17 01:07:56347 // This function helps simulate the progress of load states on a ConnectJob.
348 // Each time it is called it advances the load state and posts a task to be
349 // called again. It stops at the last connecting load state (the one
350 // before LOAD_STATE_SENDING_REQUEST).
[email protected]5fc08e32009-07-15 17:09:57351 void AdvanceLoadState(LoadState state) {
352 int tmp = state;
353 tmp++;
[email protected]cfa8228c2010-06-17 01:07:56354 if (tmp < LOAD_STATE_SENDING_REQUEST) {
355 state = static_cast<LoadState>(tmp);
356 set_load_state(state);
357 MessageLoop::current()->PostTask(
[email protected]6ea7b152011-12-21 21:21:13358 FROM_HERE, base::Bind(&TestConnectJob::AdvanceLoadState,
359 weak_factory_.GetWeakPtr(), state));
[email protected]cfa8228c2010-06-17 01:07:56360 }
[email protected]5fc08e32009-07-15 17:09:57361 }
362
363 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05364 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57365 MockClientSocketFactory* const client_socket_factory_;
[email protected]6ea7b152011-12-21 21:21:13366 base::WeakPtrFactory<TestConnectJob> weak_factory_;
[email protected]46451352009-09-01 14:54:21367 LoadState load_state_;
[email protected]e60e47a2010-07-14 03:37:18368 bool store_additional_error_state_;
[email protected]ab838892009-06-30 18:49:05369
370 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
371};
372
[email protected]d80a4322009-08-14 07:07:49373class TestConnectJobFactory
374 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05375 public:
[email protected]5fc08e32009-07-15 17:09:57376 explicit TestConnectJobFactory(MockClientSocketFactory* client_socket_factory)
[email protected]ab838892009-06-30 18:49:05377 : job_type_(TestConnectJob::kMockJob),
[email protected]51fdc7c2012-04-10 19:19:48378 job_types_(NULL),
[email protected]ab838892009-06-30 18:49:05379 client_socket_factory_(client_socket_factory) {}
380
381 virtual ~TestConnectJobFactory() {}
382
383 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
384
[email protected]51fdc7c2012-04-10 19:19:48385 void set_job_types(std::list<TestConnectJob::JobType>* job_types) {
386 job_types_ = job_types;
387 CHECK(!job_types_->empty());
388 }
389
[email protected]974ebd62009-08-03 23:14:34390 void set_timeout_duration(base::TimeDelta timeout_duration) {
391 timeout_duration_ = timeout_duration;
392 }
393
[email protected]3f55aa12011-12-07 02:03:33394 // ConnectJobFactory implementation.
[email protected]83039bb2011-12-09 18:43:55395
[email protected]ab838892009-06-30 18:49:05396 virtual ConnectJob* NewConnectJob(
397 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49398 const TestClientSocketPoolBase::Request& request,
[email protected]06650c52010-06-03 00:49:17399 ConnectJob::Delegate* delegate) const {
[email protected]51fdc7c2012-04-10 19:19:48400 EXPECT_TRUE(!job_types_ || !job_types_->empty());
401 TestConnectJob::JobType job_type = job_type_;
402 if (job_types_ && !job_types_->empty()) {
403 job_type = job_types_->front();
404 job_types_->pop_front();
405 }
406 return new TestConnectJob(job_type,
[email protected]ab838892009-06-30 18:49:05407 group_name,
408 request,
[email protected]974ebd62009-08-03 23:14:34409 timeout_duration_,
[email protected]ab838892009-06-30 18:49:05410 delegate,
[email protected]fd7b7c92009-08-20 19:38:30411 client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17412 NULL);
[email protected]ab838892009-06-30 18:49:05413 }
414
[email protected]a796bcec2010-03-22 17:17:26415 virtual base::TimeDelta ConnectionTimeout() const {
416 return timeout_duration_;
417 }
418
[email protected]ab838892009-06-30 18:49:05419 private:
420 TestConnectJob::JobType job_type_;
[email protected]51fdc7c2012-04-10 19:19:48421 std::list<TestConnectJob::JobType>* job_types_;
[email protected]974ebd62009-08-03 23:14:34422 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57423 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05424
425 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
426};
427
428class TestClientSocketPool : public ClientSocketPool {
429 public:
430 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53431 int max_sockets,
[email protected]ab838892009-06-30 18:49:05432 int max_sockets_per_group,
[email protected]2431756e2010-09-29 20:26:13433 ClientSocketPoolHistograms* histograms,
[email protected]9bf28db2009-08-29 01:35:16434 base::TimeDelta unused_idle_socket_timeout,
435 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49436 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
[email protected]b89f7e42010-05-20 20:37:00437 : base_(max_sockets, max_sockets_per_group, histograms,
[email protected]9bf28db2009-08-29 01:35:16438 unused_idle_socket_timeout, used_idle_socket_timeout,
[email protected]66761b952010-06-25 21:30:38439 connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05440
[email protected]2431756e2010-09-29 20:26:13441 virtual ~TestClientSocketPool() {}
442
[email protected]ab838892009-06-30 18:49:05443 virtual int RequestSocket(
444 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49445 const void* params,
[email protected]ac790b42009-12-02 04:31:31446 net::RequestPriority priority,
[email protected]ab838892009-06-30 18:49:05447 ClientSocketHandle* handle,
[email protected]49639fa2011-12-20 23:22:41448 const CompletionCallback& callback,
[email protected]d4dfdab2011-12-07 16:56:59449 const BoundNetLog& net_log) OVERRIDE {
[email protected]df4b4ef2010-07-12 18:25:21450 const scoped_refptr<TestSocketParams>* casted_socket_params =
451 static_cast<const scoped_refptr<TestSocketParams>*>(params);
452 return base_.RequestSocket(group_name, *casted_socket_params, priority,
453 handle, callback, net_log);
[email protected]ab838892009-06-30 18:49:05454 }
455
[email protected]2c2bef152010-10-13 00:55:03456 virtual void RequestSockets(const std::string& group_name,
457 const void* params,
458 int num_sockets,
[email protected]d4dfdab2011-12-07 16:56:59459 const BoundNetLog& net_log) OVERRIDE {
[email protected]2c2bef152010-10-13 00:55:03460 const scoped_refptr<TestSocketParams>* casted_params =
461 static_cast<const scoped_refptr<TestSocketParams>*>(params);
462
463 base_.RequestSockets(group_name, *casted_params, num_sockets, net_log);
464 }
465
[email protected]ab838892009-06-30 18:49:05466 virtual void CancelRequest(
467 const std::string& group_name,
[email protected]d4dfdab2011-12-07 16:56:59468 ClientSocketHandle* handle) OVERRIDE {
[email protected]d80a4322009-08-14 07:07:49469 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05470 }
471
472 virtual void ReleaseSocket(
473 const std::string& group_name,
[email protected]3268023f2011-05-05 00:08:10474 StreamSocket* socket,
[email protected]d4dfdab2011-12-07 16:56:59475 int id) OVERRIDE {
[email protected]a7e38572010-06-07 18:22:24476 base_.ReleaseSocket(group_name, socket, id);
477 }
478
[email protected]d4dfdab2011-12-07 16:56:59479 virtual void Flush() OVERRIDE {
[email protected]a7e38572010-06-07 18:22:24480 base_.Flush();
[email protected]ab838892009-06-30 18:49:05481 }
482
[email protected]51fdc7c2012-04-10 19:19:48483 virtual bool IsStalled() const OVERRIDE {
484 return base_.IsStalled();
485 }
486
[email protected]d4dfdab2011-12-07 16:56:59487 virtual void CloseIdleSockets() OVERRIDE {
[email protected]d80a4322009-08-14 07:07:49488 base_.CloseIdleSockets();
[email protected]ab838892009-06-30 18:49:05489 }
490
[email protected]d4dfdab2011-12-07 16:56:59491 virtual int IdleSocketCount() const OVERRIDE {
492 return base_.idle_socket_count();
493 }
[email protected]ab838892009-06-30 18:49:05494
[email protected]d4dfdab2011-12-07 16:56:59495 virtual int IdleSocketCountInGroup(
496 const std::string& group_name) const OVERRIDE {
[email protected]d80a4322009-08-14 07:07:49497 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05498 }
499
[email protected]d4dfdab2011-12-07 16:56:59500 virtual LoadState GetLoadState(
501 const std::string& group_name,
502 const ClientSocketHandle* handle) const OVERRIDE {
[email protected]d80a4322009-08-14 07:07:49503 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05504 }
505
[email protected]51fdc7c2012-04-10 19:19:48506 virtual void AddLayeredPool(LayeredPool* pool) OVERRIDE {
507 base_.AddLayeredPool(pool);
508 }
509
510 virtual void RemoveLayeredPool(LayeredPool* pool) OVERRIDE {
511 base_.RemoveLayeredPool(pool);
512 }
513
[email protected]d4dfdab2011-12-07 16:56:59514 virtual DictionaryValue* GetInfoAsValue(
515 const std::string& name,
516 const std::string& type,
517 bool include_nested_pools) const OVERRIDE {
[email protected]59d7a5a2010-08-30 16:44:27518 return base_.GetInfoAsValue(name, type);
519 }
520
[email protected]d4dfdab2011-12-07 16:56:59521 virtual base::TimeDelta ConnectionTimeout() const OVERRIDE {
[email protected]a796bcec2010-03-22 17:17:26522 return base_.ConnectionTimeout();
523 }
524
[email protected]d4dfdab2011-12-07 16:56:59525 virtual ClientSocketPoolHistograms* histograms() const OVERRIDE {
[email protected]b89f7e42010-05-20 20:37:00526 return base_.histograms();
527 }
[email protected]a796bcec2010-03-22 17:17:26528
[email protected]d80a4322009-08-14 07:07:49529 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20530
[email protected]8159a1c2012-06-07 00:00:10531 int NumUnassignedConnectJobsInGroup(const std::string& group_name) const {
532 return base_.NumUnassignedConnectJobsInGroup(group_name);
533 }
534
[email protected]974ebd62009-08-03 23:14:34535 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49536 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34537 }
538
[email protected]2c2bef152010-10-13 00:55:03539 int NumActiveSocketsInGroup(const std::string& group_name) const {
540 return base_.NumActiveSocketsInGroup(group_name);
541 }
542
[email protected]2abfe90a2010-08-25 17:49:51543 bool HasGroup(const std::string& group_name) const {
544 return base_.HasGroup(group_name);
545 }
546
[email protected]9bf28db2009-08-29 01:35:16547 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
548
[email protected]06d94042010-08-25 01:45:22549 void EnableConnectBackupJobs() { base_.EnableConnectBackupJobs(); }
[email protected]43a21b82010-06-10 21:30:54550
[email protected]51fdc7c2012-04-10 19:19:48551 bool CloseOneIdleConnectionInLayeredPool() {
552 return base_.CloseOneIdleConnectionInLayeredPool();
553 }
554
[email protected]ab838892009-06-30 18:49:05555 private:
[email protected]d80a4322009-08-14 07:07:49556 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05557
558 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
559};
560
[email protected]a937a06d2009-08-19 21:19:24561} // namespace
562
[email protected]7fc5b09a2010-02-27 00:07:38563REGISTER_SOCKET_PARAMS_FOR_POOL(TestClientSocketPool, TestSocketParams);
[email protected]a937a06d2009-08-19 21:19:24564
565namespace {
566
[email protected]5fc08e32009-07-15 17:09:57567void MockClientSocketFactory::SignalJobs() {
568 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
569 it != waiting_jobs_.end(); ++it) {
570 (*it)->Signal();
571 }
572 waiting_jobs_.clear();
573}
574
[email protected]974ebd62009-08-03 23:14:34575class TestConnectJobDelegate : public ConnectJob::Delegate {
576 public:
577 TestConnectJobDelegate()
578 : have_result_(false), waiting_for_result_(false), result_(OK) {}
579 virtual ~TestConnectJobDelegate() {}
580
581 virtual void OnConnectJobComplete(int result, ConnectJob* job) {
582 result_ = result;
[email protected]3268023f2011-05-05 00:08:10583 scoped_ptr<StreamSocket> socket(job->ReleaseSocket());
[email protected]9b6fee12009-09-29 18:13:07584 // socket.get() should be NULL iff result != OK
585 EXPECT_EQ(socket.get() == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34586 delete job;
587 have_result_ = true;
588 if (waiting_for_result_)
589 MessageLoop::current()->Quit();
590 }
591
592 int WaitForResult() {
593 DCHECK(!waiting_for_result_);
594 while (!have_result_) {
595 waiting_for_result_ = true;
596 MessageLoop::current()->Run();
597 waiting_for_result_ = false;
598 }
599 have_result_ = false; // auto-reset for next callback
600 return result_;
601 }
602
603 private:
604 bool have_result_;
605 bool waiting_for_result_;
606 int result_;
607};
608
[email protected]2431756e2010-09-29 20:26:13609class ClientSocketPoolBaseTest : public testing::Test {
[email protected]f6d1d6eb2009-06-24 20:16:09610 protected:
[email protected]b89f7e42010-05-20 20:37:00611 ClientSocketPoolBaseTest()
[email protected]df4b4ef2010-07-12 18:25:21612 : params_(new TestSocketParams()),
[email protected]636b8252011-04-08 19:56:54613 histograms_("ClientSocketPoolTest") {
614 connect_backup_jobs_enabled_ =
615 internal::ClientSocketPoolBaseHelper::connect_backup_jobs_enabled();
616 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(true);
[email protected]64770b7d2011-11-16 04:30:41617 cleanup_timer_enabled_ =
618 internal::ClientSocketPoolBaseHelper::cleanup_timer_enabled();
[email protected]636b8252011-04-08 19:56:54619 }
[email protected]2431756e2010-09-29 20:26:13620
[email protected]636b8252011-04-08 19:56:54621 virtual ~ClientSocketPoolBaseTest() {
622 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
623 connect_backup_jobs_enabled_);
[email protected]64770b7d2011-11-16 04:30:41624 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(
625 cleanup_timer_enabled_);
[email protected]636b8252011-04-08 19:56:54626 }
[email protected]c9d6a1d2009-07-14 16:15:20627
[email protected]211d21722009-07-22 15:48:53628 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16629 CreatePoolWithIdleTimeouts(
630 max_sockets,
631 max_sockets_per_group,
[email protected]82b8c962011-10-12 09:17:30632 ClientSocketPool::unused_idle_socket_timeout(),
633 ClientSocketPool::used_idle_socket_timeout());
[email protected]9bf28db2009-08-29 01:35:16634 }
635
636 void CreatePoolWithIdleTimeouts(
637 int max_sockets, int max_sockets_per_group,
638 base::TimeDelta unused_idle_socket_timeout,
639 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20640 DCHECK(!pool_.get());
[email protected]17a0c6c2009-08-04 00:07:04641 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_);
[email protected]2431756e2010-09-29 20:26:13642 pool_.reset(new TestClientSocketPool(max_sockets,
643 max_sockets_per_group,
644 &histograms_,
645 unused_idle_socket_timeout,
646 used_idle_socket_timeout,
647 connect_job_factory_));
[email protected]c9d6a1d2009-07-14 16:15:20648 }
[email protected]f6d1d6eb2009-06-24 20:16:09649
[email protected]ac790b42009-12-02 04:31:31650 int StartRequest(const std::string& group_name,
651 net::RequestPriority priority) {
[email protected]2431756e2010-09-29 20:26:13652 return test_base_.StartRequestUsingPool<
653 TestClientSocketPool, TestSocketParams>(
654 pool_.get(), group_name, priority, params_);
[email protected]f6d1d6eb2009-06-24 20:16:09655 }
656
[email protected]2431756e2010-09-29 20:26:13657 int GetOrderOfRequest(size_t index) const {
658 return test_base_.GetOrderOfRequest(index);
[email protected]f6d1d6eb2009-06-24 20:16:09659 }
660
[email protected]2431756e2010-09-29 20:26:13661 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
662 return test_base_.ReleaseOneConnection(keep_alive);
663 }
664
665 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
666 test_base_.ReleaseAllConnections(keep_alive);
667 }
668
669 TestSocketRequest* request(int i) { return test_base_.request(i); }
670 size_t requests_size() const { return test_base_.requests_size(); }
671 ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); }
672 size_t completion_count() const { return test_base_.completion_count(); }
673
[email protected]636b8252011-04-08 19:56:54674 bool connect_backup_jobs_enabled_;
[email protected]64770b7d2011-11-16 04:30:41675 bool cleanup_timer_enabled_;
[email protected]f6d1d6eb2009-06-24 20:16:09676 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04677 TestConnectJobFactory* connect_job_factory_;
[email protected]df4b4ef2010-07-12 18:25:21678 scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:13679 ClientSocketPoolHistograms histograms_;
680 scoped_ptr<TestClientSocketPool> pool_;
681 ClientSocketPoolTest test_base_;
[email protected]f6d1d6eb2009-06-24 20:16:09682};
683
[email protected]5e6efa52011-06-27 17:26:41684TEST_F(ClientSocketPoolBaseTest, AssignIdleSocketToGroup_WarmestSocket) {
685 CreatePool(4, 4);
686 net::SetSocketReusePolicy(0);
687
688 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
689 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
690 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
691 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
692
693 std::map<int, StreamSocket*> sockets_;
694 for (size_t i = 0; i < test_base_.requests_size(); i++) {
695 TestSocketRequest* req = test_base_.request(i);
696 StreamSocket* s = req->handle()->socket();
697 MockClientSocket* sock = static_cast<MockClientSocket*>(s);
698 CHECK(sock);
699 sockets_[i] = sock;
[email protected]83039bb2011-12-09 18:43:55700 sock->Read(NULL, 1024 - i, CompletionCallback());
[email protected]5e6efa52011-06-27 17:26:41701 }
702
703 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
704
705 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
706 TestSocketRequest* req = test_base_.request(test_base_.requests_size() - 1);
707
708 // First socket is warmest.
709 EXPECT_EQ(sockets_[0], req->handle()->socket());
710
711 // Test that NumBytes are as expected.
712 EXPECT_EQ(1024, sockets_[0]->NumBytesRead());
713 EXPECT_EQ(1023, sockets_[1]->NumBytesRead());
714 EXPECT_EQ(1022, sockets_[2]->NumBytesRead());
715 EXPECT_EQ(1021, sockets_[3]->NumBytesRead());
716
717 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
718}
719
720TEST_F(ClientSocketPoolBaseTest, AssignIdleSocketToGroup_LastAccessedSocket) {
721 CreatePool(4, 4);
722 net::SetSocketReusePolicy(2);
723
724 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
725 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
726 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
727 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
728
729 std::map<int, StreamSocket*> sockets_;
730 for (size_t i = 0; i < test_base_.requests_size(); i++) {
731 TestSocketRequest* req = test_base_.request(i);
732 StreamSocket* s = req->handle()->socket();
733 MockClientSocket* sock = static_cast<MockClientSocket*>(s);
734 CHECK(sock);
735 sockets_[i] = sock;
[email protected]83039bb2011-12-09 18:43:55736 sock->Read(NULL, 1024 - i, CompletionCallback());
[email protected]5e6efa52011-06-27 17:26:41737 }
738
739 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
740
741 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
742 TestSocketRequest* req = test_base_.request(test_base_.requests_size() - 1);
743
744 // Last socket is most recently accessed.
745 EXPECT_EQ(sockets_[3], req->handle()->socket());
746 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
747}
748
[email protected]974ebd62009-08-03 23:14:34749// Even though a timeout is specified, it doesn't time out on a synchronous
750// completion.
751TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
752 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06753 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49754 TestClientSocketPoolBase::Request request(
[email protected]49639fa2011-12-20 23:22:41755 &ignored, CompletionCallback(), kDefaultPriority,
[email protected]2c2bef152010-10-13 00:55:03756 internal::ClientSocketPoolBaseHelper::NORMAL,
[email protected]5acdce12011-03-30 13:00:20757 false, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34758 scoped_ptr<TestConnectJob> job(
759 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:12760 "a",
[email protected]974ebd62009-08-03 23:14:34761 request,
762 base::TimeDelta::FromMicroseconds(1),
763 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30764 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17765 NULL));
[email protected]974ebd62009-08-03 23:14:34766 EXPECT_EQ(OK, job->Connect());
767}
768
769TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
770 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06771 ClientSocketHandle ignored;
[email protected]333bdf62012-06-08 22:57:29772 CapturingNetLog log;
[email protected]9e743cd2010-03-16 07:03:53773
[email protected]d80a4322009-08-14 07:07:49774 TestClientSocketPoolBase::Request request(
[email protected]49639fa2011-12-20 23:22:41775 &ignored, CompletionCallback(), kDefaultPriority,
[email protected]2c2bef152010-10-13 00:55:03776 internal::ClientSocketPoolBaseHelper::NORMAL,
[email protected]5acdce12011-03-30 13:00:20777 false, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34778 // Deleted by TestConnectJobDelegate.
779 TestConnectJob* job =
780 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12781 "a",
[email protected]974ebd62009-08-03 23:14:34782 request,
783 base::TimeDelta::FromMicroseconds(1),
784 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30785 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17786 &log);
[email protected]974ebd62009-08-03 23:14:34787 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
[email protected]26b9973962012-01-28 00:57:00788 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
[email protected]974ebd62009-08-03 23:14:34789 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30790
[email protected]333bdf62012-06-08 22:57:29791 CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:40792 log.GetEntries(&entries);
793
794 EXPECT_EQ(6u, entries.size());
[email protected]e9002a92010-01-29 07:10:46795 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40796 entries, 0, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]06650c52010-06-03 00:49:17797 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40798 entries, 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]e9002a92010-01-29 07:10:46799 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40800 entries, 2, NetLog::TYPE_CONNECT_JOB_SET_SOCKET,
[email protected]06650c52010-06-03 00:49:17801 NetLog::PHASE_NONE));
802 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40803 entries, 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
[email protected]9e743cd2010-03-16 07:03:53804 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:46805 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40806 entries, 4, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]06650c52010-06-03 00:49:17807 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40808 entries, 5, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34809}
810
[email protected]5fc08e32009-07-15 17:09:57811TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53812 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20813
[email protected]6ecf2b92011-12-15 01:14:52814 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06815 ClientSocketHandle handle;
[email protected]333bdf62012-06-08 22:57:29816 CapturingBoundNetLog log;
[email protected]9e743cd2010-03-16 07:03:53817
[email protected]2431756e2010-09-29 20:26:13818 EXPECT_EQ(OK,
819 handle.Init("a",
820 params_,
821 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:52822 callback.callback(),
[email protected]2431756e2010-09-29 20:26:13823 pool_.get(),
824 log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09825 EXPECT_TRUE(handle.is_initialized());
826 EXPECT_TRUE(handle.socket());
[email protected]f6d1d6eb2009-06-24 20:16:09827 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:30828
[email protected]333bdf62012-06-08 22:57:29829 CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:40830 log.GetEntries(&entries);
831
832 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:46833 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40834 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]9e743cd2010-03-16 07:03:53835 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40836 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:17837 NetLog::PHASE_NONE));
838 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40839 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]9e743cd2010-03-16 07:03:53840 NetLog::PHASE_NONE));
841 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40842 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09843}
844
[email protected]ab838892009-06-30 18:49:05845TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53846 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20847
[email protected]ab838892009-06-30 18:49:05848 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]333bdf62012-06-08 22:57:29849 CapturingBoundNetLog log;
[email protected]9e743cd2010-03-16 07:03:53850
[email protected]2431756e2010-09-29 20:26:13851 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:52852 TestCompletionCallback callback;
[email protected]e60e47a2010-07-14 03:37:18853 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:13854 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43855 HttpResponseInfo info;
856 info.headers = new HttpResponseHeaders("");
[email protected]2431756e2010-09-29 20:26:13857 handle.set_ssl_error_response_info(info);
858 EXPECT_EQ(ERR_CONNECTION_FAILED,
859 handle.Init("a",
860 params_,
861 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:52862 callback.callback(),
[email protected]2431756e2010-09-29 20:26:13863 pool_.get(),
864 log.bound()));
865 EXPECT_FALSE(handle.socket());
866 EXPECT_FALSE(handle.is_ssl_error());
867 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:30868
[email protected]333bdf62012-06-08 22:57:29869 CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:40870 log.GetEntries(&entries);
871
872 EXPECT_EQ(3u, entries.size());
[email protected]5a1d7ca2010-04-28 20:12:27873 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40874 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:17875 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40876 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:17877 NetLog::PHASE_NONE));
[email protected]a2006ece2010-04-23 16:44:02878 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40879 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09880}
881
[email protected]211d21722009-07-22 15:48:53882TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
883 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
884
[email protected]9e743cd2010-03-16 07:03:53885 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30886
[email protected]211d21722009-07-22 15:48:53887 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
888 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
889 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
890 EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
891
[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(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
897 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
898 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
899
[email protected]2431756e2010-09-29 20:26:13900 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53901
[email protected]2431756e2010-09-29 20:26:13902 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53903 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13904 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53905
906 EXPECT_EQ(1, GetOrderOfRequest(1));
907 EXPECT_EQ(2, GetOrderOfRequest(2));
908 EXPECT_EQ(3, GetOrderOfRequest(3));
909 EXPECT_EQ(4, GetOrderOfRequest(4));
910 EXPECT_EQ(5, GetOrderOfRequest(5));
911 EXPECT_EQ(6, GetOrderOfRequest(6));
912 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17913
914 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13915 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53916}
917
918TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
919 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
920
[email protected]9e743cd2010-03-16 07:03:53921 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30922
[email protected]211d21722009-07-22 15:48:53923 // Reach all limits: max total sockets, and max sockets per group.
924 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
925 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
926 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
927 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
928
[email protected]2431756e2010-09-29 20:26:13929 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53930 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13931 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53932
933 // Now create a new group and verify that we don't starve it.
934 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
935
[email protected]2431756e2010-09-29 20:26:13936 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53937
[email protected]2431756e2010-09-29 20:26:13938 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53939 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13940 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53941
942 EXPECT_EQ(1, GetOrderOfRequest(1));
943 EXPECT_EQ(2, GetOrderOfRequest(2));
944 EXPECT_EQ(3, GetOrderOfRequest(3));
945 EXPECT_EQ(4, GetOrderOfRequest(4));
946 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17947
948 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13949 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53950}
951
952TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
953 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
954
[email protected]ac790b42009-12-02 04:31:31955 EXPECT_EQ(OK, StartRequest("b", LOWEST));
956 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
957 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
958 EXPECT_EQ(OK, StartRequest("a", LOWEST));
[email protected]211d21722009-07-22 15:48:53959
[email protected]2431756e2010-09-29 20:26:13960 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53961 client_socket_factory_.allocation_count());
962
[email protected]ac790b42009-12-02 04:31:31963 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
964 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
965 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53966
[email protected]2431756e2010-09-29 20:26:13967 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53968
[email protected]2431756e2010-09-29 20:26:13969 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53970
971 // First 4 requests don't have to wait, and finish in order.
972 EXPECT_EQ(1, GetOrderOfRequest(1));
973 EXPECT_EQ(2, GetOrderOfRequest(2));
974 EXPECT_EQ(3, GetOrderOfRequest(3));
975 EXPECT_EQ(4, GetOrderOfRequest(4));
976
[email protected]ac790b42009-12-02 04:31:31977 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
978 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53979 EXPECT_EQ(7, GetOrderOfRequest(5));
980 EXPECT_EQ(6, GetOrderOfRequest(6));
981 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17982
983 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13984 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]211d21722009-07-22 15:48:53985}
986
987TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
988 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
989
[email protected]ac790b42009-12-02 04:31:31990 EXPECT_EQ(OK, StartRequest("a", LOWEST));
991 EXPECT_EQ(OK, StartRequest("a", LOW));
992 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
993 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
[email protected]211d21722009-07-22 15:48:53994
[email protected]2431756e2010-09-29 20:26:13995 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53996 client_socket_factory_.allocation_count());
997
[email protected]ac790b42009-12-02 04:31:31998 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
999 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1000 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:531001
[email protected]2431756e2010-09-29 20:26:131002 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531003
[email protected]2431756e2010-09-29 20:26:131004 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531005 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131006 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:531007
1008 // First 4 requests don't have to wait, and finish in order.
1009 EXPECT_EQ(1, GetOrderOfRequest(1));
1010 EXPECT_EQ(2, GetOrderOfRequest(2));
1011 EXPECT_EQ(3, GetOrderOfRequest(3));
1012 EXPECT_EQ(4, GetOrderOfRequest(4));
1013
1014 // Request ("b", 7) has the highest priority, but we can't make new socket for
1015 // group "b", because it has reached the per-group limit. Then we make
1016 // socket for ("c", 6), because it has higher priority than ("a", 4),
1017 // and we still can't make a socket for group "b".
1018 EXPECT_EQ(5, GetOrderOfRequest(5));
1019 EXPECT_EQ(6, GetOrderOfRequest(6));
1020 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171021
1022 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131023 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:531024}
1025
1026// Make sure that we count connecting sockets against the total limit.
1027TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
1028 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1029
1030 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1031 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1032 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
1033
1034 // Create one asynchronous request.
1035 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1036 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
1037
[email protected]6b175382009-10-13 06:47:471038 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1039 // actually become pending until 2ms after they have been created. In order
1040 // to flush all tasks, we need to wait so that we know there are no
1041 // soon-to-be-pending tasks waiting.
[email protected]26b9973962012-01-28 00:57:001042 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
[email protected]6b175382009-10-13 06:47:471043 MessageLoop::current()->RunAllPending();
1044
[email protected]211d21722009-07-22 15:48:531045 // The next synchronous request should wait for its turn.
1046 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1047 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
1048
[email protected]2431756e2010-09-29 20:26:131049 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531050
[email protected]2431756e2010-09-29 20:26:131051 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531052 client_socket_factory_.allocation_count());
1053
1054 EXPECT_EQ(1, GetOrderOfRequest(1));
1055 EXPECT_EQ(2, GetOrderOfRequest(2));
1056 EXPECT_EQ(3, GetOrderOfRequest(3));
1057 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:171058 EXPECT_EQ(5, GetOrderOfRequest(5));
1059
1060 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131061 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:531062}
1063
[email protected]6427fe22010-04-16 22:27:411064TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
1065 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1066 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1067
1068 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1069 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1070 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1071 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1072
1073 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1074
1075 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1076
1077 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", kDefaultPriority));
1078 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
1079
1080 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1081
[email protected]2431756e2010-09-29 20:26:131082 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411083 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131084 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411085 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131086 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1087 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411088 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
1089}
1090
[email protected]d7027bb2010-05-10 18:58:541091TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
1092 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1093 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1094
1095 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521096 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131097 EXPECT_EQ(ERR_IO_PENDING,
1098 handle.Init("a",
1099 params_,
1100 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521101 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131102 pool_.get(),
1103 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541104
1105 ClientSocketHandle handles[4];
1106 for (size_t i = 0; i < arraysize(handles); ++i) {
[email protected]6ecf2b92011-12-15 01:14:521107 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131108 EXPECT_EQ(ERR_IO_PENDING,
1109 handles[i].Init("b",
1110 params_,
1111 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521112 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131113 pool_.get(),
1114 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541115 }
1116
1117 // One will be stalled, cancel all the handles now.
1118 // This should hit the OnAvailableSocketSlot() code where we previously had
1119 // stalled groups, but no longer have any.
1120 for (size_t i = 0; i < arraysize(handles); ++i)
1121 handles[i].Reset();
1122}
1123
[email protected]eb5a99382010-07-11 03:18:261124TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:541125 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1126 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1127
[email protected]eb5a99382010-07-11 03:18:261128 {
1129 ClientSocketHandle handles[kDefaultMaxSockets];
[email protected]6ecf2b92011-12-15 01:14:521130 TestCompletionCallback callbacks[kDefaultMaxSockets];
[email protected]eb5a99382010-07-11 03:18:261131 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]2431756e2010-09-29 20:26:131132 EXPECT_EQ(OK, handles[i].Init(base::IntToString(i),
1133 params_,
[email protected]e83326f2010-07-31 17:29:251134 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521135 callbacks[i].callback(),
[email protected]2431756e2010-09-29 20:26:131136 pool_.get(),
1137 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261138 }
1139
1140 // Force a stalled group.
1141 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521142 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131143 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1144 params_,
1145 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521146 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131147 pool_.get(),
1148 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261149
1150 // Cancel the stalled request.
1151 stalled_handle.Reset();
1152
1153 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1154 EXPECT_EQ(0, pool_->IdleSocketCount());
1155
1156 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541157 }
1158
[email protected]43a21b82010-06-10 21:30:541159 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1160 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:261161}
[email protected]43a21b82010-06-10 21:30:541162
[email protected]eb5a99382010-07-11 03:18:261163TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
1164 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1165 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1166
1167 {
1168 ClientSocketHandle handles[kDefaultMaxSockets];
1169 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521170 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131171 EXPECT_EQ(ERR_IO_PENDING, handles[i].Init(base::IntToString(i),
1172 params_,
1173 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521174 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131175 pool_.get(),
1176 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261177 }
1178
1179 // Force a stalled group.
1180 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1181 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521182 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131183 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1184 params_,
1185 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521186 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131187 pool_.get(),
1188 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261189
1190 // Since it is stalled, it should have no connect jobs.
1191 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101192 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261193
1194 // Cancel the stalled request.
1195 handles[0].Reset();
1196
[email protected]eb5a99382010-07-11 03:18:261197 // Now we should have a connect job.
1198 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101199 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261200
1201 // The stalled socket should connect.
1202 EXPECT_EQ(OK, callback.WaitForResult());
1203
1204 EXPECT_EQ(kDefaultMaxSockets + 1,
1205 client_socket_factory_.allocation_count());
1206 EXPECT_EQ(0, pool_->IdleSocketCount());
1207 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101208 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261209
1210 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541211 }
1212
[email protected]eb5a99382010-07-11 03:18:261213 EXPECT_EQ(1, pool_->IdleSocketCount());
1214}
[email protected]43a21b82010-06-10 21:30:541215
[email protected]eb5a99382010-07-11 03:18:261216TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1217 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1218 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:541219
[email protected]eb5a99382010-07-11 03:18:261220 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521221 TestCompletionCallback callback;
[email protected]eb5a99382010-07-11 03:18:261222 {
[email protected]51fdc7c2012-04-10 19:19:481223 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261224 ClientSocketHandle handles[kDefaultMaxSockets];
1225 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521226 TestCompletionCallback callback;
[email protected]1870d5cf2011-05-12 01:55:401227 EXPECT_EQ(OK, handles[i].Init(base::StringPrintf(
1228 "Take 2: %d", i),
1229 params_,
1230 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521231 callback.callback(),
[email protected]1870d5cf2011-05-12 01:55:401232 pool_.get(),
1233 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261234 }
1235
1236 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1237 EXPECT_EQ(0, pool_->IdleSocketCount());
[email protected]51fdc7c2012-04-10 19:19:481238 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261239
1240 // Now we will hit the socket limit.
[email protected]2431756e2010-09-29 20:26:131241 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1242 params_,
1243 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521244 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131245 pool_.get(),
1246 BoundNetLog()));
[email protected]51fdc7c2012-04-10 19:19:481247 EXPECT_TRUE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261248
1249 // Dropping out of scope will close all handles and return them to idle.
1250 }
[email protected]43a21b82010-06-10 21:30:541251
1252 // But if we wait for it, the released idle sockets will be closed in
1253 // preference of the waiting request.
[email protected]8ae03f42010-07-07 19:08:101254 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]eb5a99382010-07-11 03:18:261255
1256 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1257 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:541258}
1259
1260// Regression test for http://crbug.com/40952.
1261TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1262 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]06d94042010-08-25 01:45:221263 pool_->EnableConnectBackupJobs();
[email protected]43a21b82010-06-10 21:30:541264 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1265
1266 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1267 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521268 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131269 EXPECT_EQ(OK, handle.Init(base::IntToString(i),
1270 params_,
1271 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521272 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131273 pool_.get(),
1274 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541275 }
1276
1277 // Flush all the DoReleaseSocket tasks.
1278 MessageLoop::current()->RunAllPending();
1279
1280 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1281 // reuse a socket.
1282 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1283 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521284 TestCompletionCallback callback;
[email protected]43a21b82010-06-10 21:30:541285
1286 // "0" is special here, since it should be the first entry in the sorted map,
1287 // which is the one which we would close an idle socket for. We shouldn't
1288 // close an idle socket though, since we should reuse the idle socket.
[email protected]2431756e2010-09-29 20:26:131289 EXPECT_EQ(OK, handle.Init("0",
1290 params_,
1291 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521292 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131293 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211294 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541295
1296 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1297 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1298}
1299
[email protected]ab838892009-06-30 18:49:051300TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531301 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091302
[email protected]c9d6a1d2009-07-14 16:15:201303 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1304 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]c9c6f5c2010-07-31 01:30:031305 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", IDLE));
[email protected]ac790b42009-12-02 04:31:311306 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1307 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1308 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1309 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1310 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091311
[email protected]2431756e2010-09-29 20:26:131312 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091313
[email protected]c9d6a1d2009-07-14 16:15:201314 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1315 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131316 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1317 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091318
[email protected]c9d6a1d2009-07-14 16:15:201319 EXPECT_EQ(1, GetOrderOfRequest(1));
1320 EXPECT_EQ(2, GetOrderOfRequest(2));
[email protected]c9c6f5c2010-07-31 01:30:031321 EXPECT_EQ(8, GetOrderOfRequest(3));
1322 EXPECT_EQ(6, GetOrderOfRequest(4));
1323 EXPECT_EQ(4, GetOrderOfRequest(5));
1324 EXPECT_EQ(3, GetOrderOfRequest(6));
1325 EXPECT_EQ(5, GetOrderOfRequest(7));
1326 EXPECT_EQ(7, GetOrderOfRequest(8));
[email protected]75439d3b2009-07-23 22:11:171327
1328 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131329 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]f6d1d6eb2009-06-24 20:16:091330}
1331
[email protected]ab838892009-06-30 18:49:051332TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531333 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091334
[email protected]c9d6a1d2009-07-14 16:15:201335 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1336 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311337 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1338 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1339 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1340 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1341 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091342
[email protected]2431756e2010-09-29 20:26:131343 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091344
[email protected]2431756e2010-09-29 20:26:131345 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
1346 EXPECT_EQ(OK, request(i)->WaitForResult());
[email protected]c9d6a1d2009-07-14 16:15:201347
[email protected]2431756e2010-09-29 20:26:131348 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]c9d6a1d2009-07-14 16:15:201349 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131350 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1351 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091352}
1353
1354// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:051355// The pending connect job will be cancelled and should not call back into
1356// ClientSocketPoolBase.
1357TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531358 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201359
[email protected]ab838892009-06-30 18:49:051360 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131361 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521362 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131363 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1364 params_,
1365 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521366 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131367 pool_.get(),
1368 BoundNetLog()));
1369 handle.Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091370}
1371
[email protected]ab838892009-06-30 18:49:051372TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531373 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201374
[email protected]ab838892009-06-30 18:49:051375 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061376 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521377 TestCompletionCallback callback;
[email protected]f6d1d6eb2009-06-24 20:16:091378
[email protected]2431756e2010-09-29 20:26:131379 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1380 params_,
1381 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521382 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131383 pool_.get(),
1384 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091385
1386 handle.Reset();
1387
[email protected]6ecf2b92011-12-15 01:14:521388 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:131389 EXPECT_EQ(ERR_IO_PENDING,
1390 handle.Init("a",
1391 params_,
1392 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521393 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:131394 pool_.get(),
1395 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091396
1397 EXPECT_EQ(OK, callback2.WaitForResult());
1398 EXPECT_FALSE(callback.have_result());
1399
1400 handle.Reset();
1401}
1402
[email protected]ab838892009-06-30 18:49:051403TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531404 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091405
[email protected]c9d6a1d2009-07-14 16:15:201406 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1407 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311408 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1409 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1410 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1411 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1412 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091413
1414 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201415 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]2431756e2010-09-29 20:26:131416 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1417 (*requests())[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091418
[email protected]2431756e2010-09-29 20:26:131419 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091420
[email protected]c9d6a1d2009-07-14 16:15:201421 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1422 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131423 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1424 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091425
[email protected]c9d6a1d2009-07-14 16:15:201426 EXPECT_EQ(1, GetOrderOfRequest(1));
1427 EXPECT_EQ(2, GetOrderOfRequest(2));
1428 EXPECT_EQ(5, GetOrderOfRequest(3));
1429 EXPECT_EQ(3, GetOrderOfRequest(4));
[email protected]2431756e2010-09-29 20:26:131430 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1431 GetOrderOfRequest(5)); // Canceled request.
[email protected]c9d6a1d2009-07-14 16:15:201432 EXPECT_EQ(4, GetOrderOfRequest(6));
1433 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171434
1435 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131436 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091437}
1438
[email protected]6ecf2b92011-12-15 01:14:521439class RequestSocketCallback : public TestCompletionCallbackBase {
[email protected]f6d1d6eb2009-06-24 20:16:091440 public:
[email protected]2ab05b52009-07-01 23:57:581441 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:241442 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:581443 TestConnectJobFactory* test_connect_job_factory,
1444 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:091445 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:061446 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:581447 within_callback_(false),
1448 test_connect_job_factory_(test_connect_job_factory),
[email protected]6ecf2b92011-12-15 01:14:521449 next_job_type_(next_job_type),
1450 ALLOW_THIS_IN_INITIALIZER_LIST(callback_(
1451 base::Bind(&RequestSocketCallback::OnComplete,
1452 base::Unretained(this)))) {
1453 }
[email protected]f6d1d6eb2009-06-24 20:16:091454
[email protected]6ecf2b92011-12-15 01:14:521455 virtual ~RequestSocketCallback() {}
1456
1457 const CompletionCallback& callback() const { return callback_; }
1458
1459 private:
1460 void OnComplete(int result) {
1461 SetResult(result);
1462 ASSERT_EQ(OK, result);
[email protected]f6d1d6eb2009-06-24 20:16:091463
1464 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:581465 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]5edbf8d2010-01-13 18:44:111466
1467 // Don't allow reuse of the socket. Disconnect it and then release it and
1468 // run through the MessageLoop once to get it completely released.
1469 handle_->socket()->Disconnect();
[email protected]f6d1d6eb2009-06-24 20:16:091470 handle_->Reset();
[email protected]5edbf8d2010-01-13 18:44:111471 {
[email protected]b5717a42012-02-14 19:33:521472 // TODO: Resolve conflicting intentions of stopping recursion with the
1473 // |!within_callback_| test (above) and the call to |RunAllPending()|
1474 // below. http://crbug.com/114130.
1475 MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current());
[email protected]5edbf8d2010-01-13 18:44:111476 MessageLoop::current()->RunAllPending();
1477 }
[email protected]f6d1d6eb2009-06-24 20:16:091478 within_callback_ = true;
[email protected]6ecf2b92011-12-15 01:14:521479 TestCompletionCallback next_job_callback;
[email protected]ad8e04a2010-11-01 04:16:271480 scoped_refptr<TestSocketParams> params(new TestSocketParams());
[email protected]2431756e2010-09-29 20:26:131481 int rv = handle_->Init("a",
1482 params,
1483 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521484 next_job_callback.callback(),
[email protected]2431756e2010-09-29 20:26:131485 pool_,
1486 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581487 switch (next_job_type_) {
1488 case TestConnectJob::kMockJob:
1489 EXPECT_EQ(OK, rv);
1490 break;
1491 case TestConnectJob::kMockPendingJob:
1492 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:471493
1494 // For pending jobs, wait for new socket to be created. This makes
1495 // sure there are no more pending operations nor any unclosed sockets
1496 // when the test finishes.
1497 // We need to give it a little bit of time to run, so that all the
1498 // operations that happen on timers (e.g. cleanup of idle
1499 // connections) can execute.
[email protected]5edbf8d2010-01-13 18:44:111500 {
[email protected]b5717a42012-02-14 19:33:521501 MessageLoop::ScopedNestableTaskAllower allow(
[email protected]5edbf8d2010-01-13 18:44:111502 MessageLoop::current());
[email protected]26b9973962012-01-28 00:57:001503 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
[email protected]5edbf8d2010-01-13 18:44:111504 EXPECT_EQ(OK, next_job_callback.WaitForResult());
1505 }
[email protected]2ab05b52009-07-01 23:57:581506 break;
1507 default:
1508 FAIL() << "Unexpected job type: " << next_job_type_;
1509 break;
1510 }
[email protected]f6d1d6eb2009-06-24 20:16:091511 }
1512 }
1513
[email protected]f6d1d6eb2009-06-24 20:16:091514 ClientSocketHandle* const handle_;
[email protected]2431756e2010-09-29 20:26:131515 TestClientSocketPool* const pool_;
[email protected]f6d1d6eb2009-06-24 20:16:091516 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:581517 TestConnectJobFactory* const test_connect_job_factory_;
1518 TestConnectJob::JobType next_job_type_;
[email protected]6ecf2b92011-12-15 01:14:521519 CompletionCallback callback_;
[email protected]f6d1d6eb2009-06-24 20:16:091520};
1521
[email protected]2ab05b52009-07-01 23:57:581522TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531523 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201524
[email protected]0b7648c2009-07-06 20:14:011525 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061526 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581527 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061528 &handle, pool_.get(), connect_job_factory_,
1529 TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131530 int rv = handle.Init("a",
1531 params_,
1532 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521533 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131534 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211535 BoundNetLog());
[email protected]f6d1d6eb2009-06-24 20:16:091536 ASSERT_EQ(ERR_IO_PENDING, rv);
1537
1538 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581539}
[email protected]f6d1d6eb2009-06-24 20:16:091540
[email protected]2ab05b52009-07-01 23:57:581541TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531542 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201543
[email protected]0b7648c2009-07-06 20:14:011544 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061545 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581546 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061547 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]2431756e2010-09-29 20:26:131548 int rv = handle.Init("a",
1549 params_,
1550 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521551 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131552 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211553 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581554 ASSERT_EQ(ERR_IO_PENDING, rv);
1555
1556 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091557}
1558
1559// Make sure that pending requests get serviced after active requests get
1560// cancelled.
[email protected]ab838892009-06-30 18:49:051561TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531562 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201563
[email protected]0b7648c2009-07-06 20:14:011564 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091565
[email protected]c9d6a1d2009-07-14 16:15:201566 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1567 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1568 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1569 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1570 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1571 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1572 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091573
[email protected]c9d6a1d2009-07-14 16:15:201574 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1575 // Let's cancel them.
1576 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]2431756e2010-09-29 20:26:131577 ASSERT_FALSE(request(i)->handle()->is_initialized());
1578 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091579 }
1580
[email protected]f6d1d6eb2009-06-24 20:16:091581 // Let's wait for the rest to complete now.
[email protected]2431756e2010-09-29 20:26:131582 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
1583 EXPECT_EQ(OK, request(i)->WaitForResult());
1584 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091585 }
1586
[email protected]2431756e2010-09-29 20:26:131587 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1588 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091589}
1590
1591// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051592TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531593 const size_t kMaxSockets = 5;
1594 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201595
[email protected]0b7648c2009-07-06 20:14:011596 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091597
[email protected]211d21722009-07-22 15:48:531598 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1599 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091600
1601 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531602 for (size_t i = 0; i < kNumberOfRequests; ++i)
1603 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091604
[email protected]211d21722009-07-22 15:48:531605 for (size_t i = 0; i < kNumberOfRequests; ++i)
[email protected]2431756e2010-09-29 20:26:131606 EXPECT_EQ(ERR_CONNECTION_FAILED, request(i)->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091607}
1608
[email protected]5fc08e32009-07-15 17:09:571609TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531610 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571611
1612 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1613
[email protected]2431756e2010-09-29 20:26:131614 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521615 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131616 int rv = handle.Init("a",
1617 params_,
1618 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521619 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131620 pool_.get(),
1621 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571622 EXPECT_EQ(ERR_IO_PENDING, rv);
1623
1624 // Cancel the active request.
[email protected]2431756e2010-09-29 20:26:131625 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571626
[email protected]2431756e2010-09-29 20:26:131627 rv = handle.Init("a",
1628 params_,
1629 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521630 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131631 pool_.get(),
1632 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571633 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131634 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]5fc08e32009-07-15 17:09:571635
[email protected]2431756e2010-09-29 20:26:131636 EXPECT_FALSE(handle.is_reused());
[email protected]5fc08e32009-07-15 17:09:571637 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1638}
1639
[email protected]2b7523d2009-07-29 20:29:231640// Regression test for http://crbug.com/17985.
1641TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1642 const int kMaxSockets = 3;
1643 const int kMaxSocketsPerGroup = 2;
1644 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1645
[email protected]ac790b42009-12-02 04:31:311646 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231647
1648 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1649 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1650
1651 // This is going to be a pending request in an otherwise empty group.
1652 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1653
1654 // Reach the maximum socket limit.
1655 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1656
1657 // Create a stalled group with high priorities.
1658 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1659 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
[email protected]2b7523d2009-07-29 20:29:231660
[email protected]eb5a99382010-07-11 03:18:261661 // Release the first two sockets from "a". Because this is a keepalive,
1662 // the first release will unblock the pending request for "a". The
1663 // second release will unblock a request for "c", becaue it is the next
1664 // high priority socket.
[email protected]2431756e2010-09-29 20:26:131665 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1666 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]2b7523d2009-07-29 20:29:231667
1668 // Closing idle sockets should not get us into trouble, but in the bug
1669 // we were hitting a CHECK here.
[email protected]93054cc12010-06-08 06:12:411670 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]43a21b82010-06-10 21:30:541671 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261672
1673 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]2b7523d2009-07-29 20:29:231674}
1675
[email protected]4d3b05d2010-01-27 21:27:291676TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531677 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571678
1679 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131680 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521681 TestCompletionCallback callback;
[email protected]333bdf62012-06-08 22:57:291682 CapturingBoundNetLog log;
[email protected]2431756e2010-09-29 20:26:131683 int rv = handle.Init("a",
1684 params_,
1685 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:521686 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131687 pool_.get(),
1688 log.bound());
[email protected]5fc08e32009-07-15 17:09:571689 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131690 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1691 EXPECT_EQ(OK, callback.WaitForResult());
1692 EXPECT_TRUE(handle.is_initialized());
1693 EXPECT_TRUE(handle.socket());
1694 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:301695
[email protected]333bdf62012-06-08 22:57:291696 CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:401697 log.GetEntries(&entries);
1698
1699 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:461700 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401701 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171702 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401703 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171704 NetLog::PHASE_NONE));
1705 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401706 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]06650c52010-06-03 00:49:171707 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:461708 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401709 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571710}
1711
[email protected]4d3b05d2010-01-27 21:27:291712TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571713 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531714 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571715
1716 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2431756e2010-09-29 20:26:131717 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521718 TestCompletionCallback callback;
[email protected]333bdf62012-06-08 22:57:291719 CapturingBoundNetLog log;
[email protected]e60e47a2010-07-14 03:37:181720 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:131721 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:431722 HttpResponseInfo info;
1723 info.headers = new HttpResponseHeaders("");
[email protected]2431756e2010-09-29 20:26:131724 handle.set_ssl_error_response_info(info);
1725 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1726 params_,
1727 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521728 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131729 pool_.get(),
1730 log.bound()));
1731 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1732 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1733 EXPECT_FALSE(handle.is_ssl_error());
1734 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:301735
[email protected]333bdf62012-06-08 22:57:291736 CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:401737 log.GetEntries(&entries);
1738
1739 EXPECT_EQ(3u, entries.size());
[email protected]e9002a92010-01-29 07:10:461740 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401741 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171742 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401743 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171744 NetLog::PHASE_NONE));
[email protected]6b624c62010-03-14 08:37:321745 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401746 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571747}
1748
[email protected]4d3b05d2010-01-27 21:27:291749TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101750 // TODO(eroman): Add back the log expectations! Removed them because the
1751 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531752 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571753
1754 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131755 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521756 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131757 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:521758 TestCompletionCallback callback2;
[email protected]5fc08e32009-07-15 17:09:571759
[email protected]2431756e2010-09-29 20:26:131760 EXPECT_EQ(ERR_IO_PENDING,
1761 handle.Init("a",
1762 params_,
1763 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521764 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131765 pool_.get(),
1766 BoundNetLog()));
[email protected]333bdf62012-06-08 22:57:291767 CapturingBoundNetLog log2;
[email protected]2431756e2010-09-29 20:26:131768 EXPECT_EQ(ERR_IO_PENDING,
1769 handle2.Init("a",
1770 params_,
1771 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521772 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:131773 pool_.get(),
1774 BoundNetLog()));
[email protected]5fc08e32009-07-15 17:09:571775
[email protected]2431756e2010-09-29 20:26:131776 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571777
[email protected]fd7b7c92009-08-20 19:38:301778
1779 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301780
[email protected]2431756e2010-09-29 20:26:131781 EXPECT_EQ(OK, callback2.WaitForResult());
1782 handle2.Reset();
[email protected]fd7b7c92009-08-20 19:38:301783
1784 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531785 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571786}
1787
[email protected]4d3b05d2010-01-27 21:27:291788TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341789 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1790
[email protected]17a0c6c2009-08-04 00:07:041791 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1792
[email protected]ac790b42009-12-02 04:31:311793 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1794 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1795 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1796 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341797
1798 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]2431756e2010-09-29 20:26:131799 (*requests())[2]->handle()->Reset();
1800 (*requests())[3]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341801 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1802
[email protected]2431756e2010-09-29 20:26:131803 (*requests())[1]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341804 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1805
[email protected]2431756e2010-09-29 20:26:131806 (*requests())[0]->handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261807 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]974ebd62009-08-03 23:14:341808}
1809
[email protected]5fc08e32009-07-15 17:09:571810// When requests and ConnectJobs are not coupled, the request will get serviced
1811// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291812TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531813 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571814
1815 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321816 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571817
[email protected]2431756e2010-09-29 20:26:131818 std::vector<TestSocketRequest*> request_order;
1819 size_t completion_count; // unused
1820 TestSocketRequest req1(&request_order, &completion_count);
1821 int rv = req1.handle()->Init("a",
1822 params_,
1823 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521824 req1.callback(), pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211825 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571826 EXPECT_EQ(ERR_IO_PENDING, rv);
1827 EXPECT_EQ(OK, req1.WaitForResult());
1828
1829 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1830 // without a job.
1831 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1832
[email protected]2431756e2010-09-29 20:26:131833 TestSocketRequest req2(&request_order, &completion_count);
1834 rv = req2.handle()->Init("a",
1835 params_,
1836 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521837 req2.callback(),
[email protected]2431756e2010-09-29 20:26:131838 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);
[email protected]2431756e2010-09-29 20:26:131841 TestSocketRequest req3(&request_order, &completion_count);
1842 rv = req3.handle()->Init("a",
1843 params_,
1844 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521845 req3.callback(),
[email protected]2431756e2010-09-29 20:26:131846 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211847 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571848 EXPECT_EQ(ERR_IO_PENDING, rv);
1849
1850 // Both Requests 2 and 3 are pending. We release socket 1 which should
1851 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331852 req1.handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261853 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]a6c59f62009-07-29 16:33:331854 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571855 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331856 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571857
1858 // Signal job 2, which should service request 3.
1859
1860 client_socket_factory_.SignalJobs();
1861 EXPECT_EQ(OK, req3.WaitForResult());
1862
[email protected]2431756e2010-09-29 20:26:131863 ASSERT_EQ(3U, request_order.size());
1864 EXPECT_EQ(&req1, request_order[0]);
1865 EXPECT_EQ(&req2, request_order[1]);
1866 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571867 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1868}
1869
1870// The requests are not coupled to the jobs. So, the requests should finish in
1871// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:291872TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531873 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571874 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321875 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571876
[email protected]2431756e2010-09-29 20:26:131877 std::vector<TestSocketRequest*> request_order;
1878 size_t completion_count; // unused
1879 TestSocketRequest req1(&request_order, &completion_count);
1880 int rv = req1.handle()->Init("a",
1881 params_,
1882 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521883 req1.callback(),
[email protected]2431756e2010-09-29 20:26:131884 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211885 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571886 EXPECT_EQ(ERR_IO_PENDING, rv);
1887
[email protected]2431756e2010-09-29 20:26:131888 TestSocketRequest req2(&request_order, &completion_count);
1889 rv = req2.handle()->Init("a",
1890 params_,
1891 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521892 req2.callback(),
[email protected]2431756e2010-09-29 20:26:131893 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211894 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571895 EXPECT_EQ(ERR_IO_PENDING, rv);
1896
1897 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321898 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571899
[email protected]2431756e2010-09-29 20:26:131900 TestSocketRequest req3(&request_order, &completion_count);
1901 rv = req3.handle()->Init("a",
1902 params_,
1903 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521904 req3.callback(),
[email protected]2431756e2010-09-29 20:26:131905 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211906 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571907 EXPECT_EQ(ERR_IO_PENDING, rv);
1908
1909 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1910 EXPECT_EQ(OK, req2.WaitForResult());
1911 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1912
[email protected]2431756e2010-09-29 20:26:131913 ASSERT_EQ(3U, request_order.size());
1914 EXPECT_EQ(&req1, request_order[0]);
1915 EXPECT_EQ(&req2, request_order[1]);
1916 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571917}
1918
[email protected]e6ec67b2010-06-16 00:12:461919TEST_F(ClientSocketPoolBaseTest, LoadState) {
[email protected]211d21722009-07-22 15:48:531920 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571921 connect_job_factory_->set_job_type(
[email protected]b59ff372009-07-15 22:04:321922 TestConnectJob::kMockAdvancingLoadStateJob);
[email protected]5fc08e32009-07-15 17:09:571923
[email protected]2431756e2010-09-29 20:26:131924 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521925 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131926 int rv = handle.Init("a",
1927 params_,
1928 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521929 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131930 pool_.get(),
1931 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571932 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131933 EXPECT_EQ(LOAD_STATE_IDLE, handle.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571934
1935 MessageLoop::current()->RunAllPending();
1936
[email protected]2431756e2010-09-29 20:26:131937 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:521938 TestCompletionCallback callback2;
1939 rv = handle2.Init("a", params_, kDefaultPriority, callback2.callback(),
1940 pool_.get(), BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571941 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131942 EXPECT_NE(LOAD_STATE_IDLE, handle.GetLoadState());
1943 EXPECT_NE(LOAD_STATE_IDLE, handle2.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571944}
1945
[email protected]e772db3f2010-07-12 18:11:131946TEST_F(ClientSocketPoolBaseTest, Recoverable) {
1947 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1948 connect_job_factory_->set_job_type(TestConnectJob::kMockRecoverableJob);
1949
[email protected]2431756e2010-09-29 20:26:131950 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521951 TestCompletionCallback callback;
1952 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED,
1953 handle.Init("a", params_, kDefaultPriority, callback.callback(),
1954 pool_.get(), BoundNetLog()));
[email protected]2431756e2010-09-29 20:26:131955 EXPECT_TRUE(handle.is_initialized());
1956 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:131957}
1958
1959TEST_F(ClientSocketPoolBaseTest, AsyncRecoverable) {
1960 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1961
1962 connect_job_factory_->set_job_type(
1963 TestConnectJob::kMockPendingRecoverableJob);
[email protected]2431756e2010-09-29 20:26:131964 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521965 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131966 EXPECT_EQ(ERR_IO_PENDING,
1967 handle.Init("a",
1968 params_,
1969 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521970 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131971 pool_.get(),
1972 BoundNetLog()));
1973 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1974 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, callback.WaitForResult());
1975 EXPECT_TRUE(handle.is_initialized());
1976 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:131977}
1978
[email protected]e60e47a2010-07-14 03:37:181979TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
1980 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1981 connect_job_factory_->set_job_type(
1982 TestConnectJob::kMockAdditionalErrorStateJob);
1983
[email protected]2431756e2010-09-29 20:26:131984 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521985 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131986 EXPECT_EQ(ERR_CONNECTION_FAILED,
1987 handle.Init("a",
1988 params_,
1989 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521990 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131991 pool_.get(),
1992 BoundNetLog()));
1993 EXPECT_FALSE(handle.is_initialized());
1994 EXPECT_FALSE(handle.socket());
1995 EXPECT_TRUE(handle.is_ssl_error());
1996 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181997}
1998
1999TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
2000 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2001
2002 connect_job_factory_->set_job_type(
2003 TestConnectJob::kMockPendingAdditionalErrorStateJob);
[email protected]2431756e2010-09-29 20:26:132004 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522005 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132006 EXPECT_EQ(ERR_IO_PENDING,
2007 handle.Init("a",
2008 params_,
2009 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522010 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132011 pool_.get(),
2012 BoundNetLog()));
2013 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2014 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
2015 EXPECT_FALSE(handle.is_initialized());
2016 EXPECT_FALSE(handle.socket());
2017 EXPECT_TRUE(handle.is_ssl_error());
2018 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182019}
2020
[email protected]e7b1c6d2c2012-05-05 00:54:032021// Make sure we can reuse sockets when the cleanup timer is disabled.
2022TEST_F(ClientSocketPoolBaseTest, DisableCleanupTimerReuse) {
[email protected]64770b7d2011-11-16 04:30:412023 // Disable cleanup timer.
2024 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(false);
2025
2026 CreatePoolWithIdleTimeouts(
2027 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
[email protected]e7b1c6d2c2012-05-05 00:54:032028 base::TimeDelta(), // Time out unused sockets immediately.
2029 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2030
2031 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2032
2033 ClientSocketHandle handle;
2034 TestCompletionCallback callback;
2035 int rv = handle.Init("a",
2036 params_,
2037 LOWEST,
2038 callback.callback(),
2039 pool_.get(),
2040 BoundNetLog());
2041 ASSERT_EQ(ERR_IO_PENDING, rv);
2042 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2043 ASSERT_EQ(OK, callback.WaitForResult());
2044
2045 // Use and release the socket.
2046 EXPECT_EQ(1, handle.socket()->Write(NULL, 1, CompletionCallback()));
2047 handle.Reset();
2048
2049 // Should now have one idle socket.
2050 ASSERT_EQ(1, pool_->IdleSocketCount());
2051
2052 // Request a new socket. This should reuse the old socket and complete
2053 // synchronously.
[email protected]333bdf62012-06-08 22:57:292054 CapturingBoundNetLog log;
[email protected]e7b1c6d2c2012-05-05 00:54:032055 rv = handle.Init("a",
2056 params_,
2057 LOWEST,
2058 CompletionCallback(),
2059 pool_.get(),
2060 log.bound());
2061 ASSERT_EQ(OK, rv);
2062 EXPECT_TRUE(handle.is_reused());
2063
2064 ASSERT_TRUE(pool_->HasGroup("a"));
2065 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2066 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2067
[email protected]333bdf62012-06-08 22:57:292068 CapturingNetLog::CapturedEntryList entries;
[email protected]e7b1c6d2c2012-05-05 00:54:032069 log.GetEntries(&entries);
2070 EXPECT_TRUE(LogContainsEntryWithType(
2071 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
2072}
2073
2074// Make sure we cleanup old unused sockets when the cleanup timer is disabled.
2075TEST_F(ClientSocketPoolBaseTest, DisableCleanupTimerNoReuse) {
2076 // Disable cleanup timer.
2077 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(false);
2078
2079 CreatePoolWithIdleTimeouts(
2080 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2081 base::TimeDelta(), // Time out unused sockets immediately
2082 base::TimeDelta()); // Time out used sockets immediately
[email protected]64770b7d2011-11-16 04:30:412083
2084 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2085
2086 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2087
2088 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522089 TestCompletionCallback callback;
[email protected]64770b7d2011-11-16 04:30:412090 int rv = handle.Init("a",
2091 params_,
2092 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522093 callback.callback(),
[email protected]64770b7d2011-11-16 04:30:412094 pool_.get(),
2095 BoundNetLog());
[email protected]e7b1c6d2c2012-05-05 00:54:032096 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]64770b7d2011-11-16 04:30:412097 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2098
2099 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522100 TestCompletionCallback callback2;
[email protected]64770b7d2011-11-16 04:30:412101 rv = handle2.Init("a",
2102 params_,
2103 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522104 callback2.callback(),
[email protected]64770b7d2011-11-16 04:30:412105 pool_.get(),
2106 BoundNetLog());
[email protected]e7b1c6d2c2012-05-05 00:54:032107 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]64770b7d2011-11-16 04:30:412108 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
2109
2110 // Cancel one of the requests. Wait for the other, which will get the first
2111 // job. Release the socket. Run the loop again to make sure the second
2112 // socket is sitting idle and the first one is released (since ReleaseSocket()
2113 // just posts a DoReleaseSocket() task).
2114
2115 handle.Reset();
[email protected]e7b1c6d2c2012-05-05 00:54:032116 ASSERT_EQ(OK, callback2.WaitForResult());
[email protected]64770b7d2011-11-16 04:30:412117 // Use the socket.
[email protected]83039bb2011-12-09 18:43:552118 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]64770b7d2011-11-16 04:30:412119 handle2.Reset();
2120
[email protected]e7b1c6d2c2012-05-05 00:54:032121 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2122 // actually become pending until 2ms after they have been created. In order
2123 // to flush all tasks, we need to wait so that we know there are no
2124 // soon-to-be-pending tasks waiting.
2125 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
[email protected]64770b7d2011-11-16 04:30:412126 MessageLoop::current()->RunAllPending();
2127
[email protected]e7b1c6d2c2012-05-05 00:54:032128 // Both sockets should now be idle.
[email protected]64770b7d2011-11-16 04:30:412129 ASSERT_EQ(2, pool_->IdleSocketCount());
2130
2131 // Request a new socket. This should cleanup the unused and timed out ones.
2132 // A new socket will be created rather than reusing the idle one.
[email protected]333bdf62012-06-08 22:57:292133 CapturingBoundNetLog log;
[email protected]6ecf2b92011-12-15 01:14:522134 TestCompletionCallback callback3;
[email protected]64770b7d2011-11-16 04:30:412135 rv = handle.Init("a",
2136 params_,
2137 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522138 callback3.callback(),
[email protected]64770b7d2011-11-16 04:30:412139 pool_.get(),
2140 log.bound());
[email protected]e7b1c6d2c2012-05-05 00:54:032141 ASSERT_EQ(ERR_IO_PENDING, rv);
2142 ASSERT_EQ(OK, callback3.WaitForResult());
[email protected]64770b7d2011-11-16 04:30:412143 EXPECT_FALSE(handle.is_reused());
2144
[email protected]e7b1c6d2c2012-05-05 00:54:032145 // Make sure the idle socket is closed.
[email protected]64770b7d2011-11-16 04:30:412146 ASSERT_TRUE(pool_->HasGroup("a"));
2147 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2148 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2149
[email protected]333bdf62012-06-08 22:57:292150 CapturingNetLog::CapturedEntryList entries;
[email protected]64770b7d2011-11-16 04:30:412151 log.GetEntries(&entries);
2152 EXPECT_FALSE(LogContainsEntryWithType(
2153 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
2154}
2155
[email protected]4d3b05d2010-01-27 21:27:292156TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
[email protected]9bf28db2009-08-29 01:35:162157 CreatePoolWithIdleTimeouts(
2158 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2159 base::TimeDelta(), // Time out unused sockets immediately.
2160 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2161
2162 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2163
2164 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2165
[email protected]2431756e2010-09-29 20:26:132166 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522167 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132168 int rv = handle.Init("a",
2169 params_,
2170 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522171 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132172 pool_.get(),
2173 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:162174 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:132175 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
[email protected]9bf28db2009-08-29 01:35:162176
[email protected]2431756e2010-09-29 20:26:132177 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522178 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132179 rv = handle2.Init("a",
2180 params_,
2181 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522182 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132183 pool_.get(),
2184 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:162185 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:132186 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
[email protected]9bf28db2009-08-29 01:35:162187
2188 // Cancel one of the requests. Wait for the other, which will get the first
2189 // job. Release the socket. Run the loop again to make sure the second
2190 // socket is sitting idle and the first one is released (since ReleaseSocket()
2191 // just posts a DoReleaseSocket() task).
2192
[email protected]2431756e2010-09-29 20:26:132193 handle.Reset();
2194 EXPECT_EQ(OK, callback2.WaitForResult());
[email protected]0f873e82010-09-02 16:09:012195 // Use the socket.
[email protected]83039bb2011-12-09 18:43:552196 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]2431756e2010-09-29 20:26:132197 handle2.Reset();
[email protected]6b175382009-10-13 06:47:472198
2199 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2200 // actually become pending until 2ms after they have been created. In order
2201 // to flush all tasks, we need to wait so that we know there are no
2202 // soon-to-be-pending tasks waiting.
[email protected]26b9973962012-01-28 00:57:002203 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
[email protected]9bf28db2009-08-29 01:35:162204 MessageLoop::current()->RunAllPending();
2205
2206 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:042207
[email protected]9bf28db2009-08-29 01:35:162208 // Invoke the idle socket cleanup check. Only one socket should be left, the
2209 // used socket. Request it to make sure that it's used.
2210
2211 pool_->CleanupTimedOutIdleSockets();
[email protected]333bdf62012-06-08 22:57:292212 CapturingBoundNetLog log;
[email protected]2431756e2010-09-29 20:26:132213 rv = handle.Init("a",
2214 params_,
2215 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522216 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132217 pool_.get(),
2218 log.bound());
[email protected]9bf28db2009-08-29 01:35:162219 EXPECT_EQ(OK, rv);
[email protected]2431756e2010-09-29 20:26:132220 EXPECT_TRUE(handle.is_reused());
[email protected]b2fcd0e2010-12-01 15:19:402221
[email protected]333bdf62012-06-08 22:57:292222 CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402223 log.GetEntries(&entries);
[email protected]fd4fe0b2010-02-08 23:02:152224 EXPECT_TRUE(LogContainsEntryWithType(
[email protected]b2fcd0e2010-12-01 15:19:402225 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]9bf28db2009-08-29 01:35:162226}
2227
[email protected]2041cf342010-02-19 03:15:592228// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:162229// because of multiple releasing disconnected sockets.
2230TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
2231 CreatePoolWithIdleTimeouts(
2232 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2233 base::TimeDelta(), // Time out unused sockets immediately.
2234 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2235
2236 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2237
2238 // Startup 4 connect jobs. Two of them will be pending.
2239
[email protected]2431756e2010-09-29 20:26:132240 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522241 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132242 int rv = handle.Init("a",
2243 params_,
2244 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522245 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132246 pool_.get(),
2247 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162248 EXPECT_EQ(OK, rv);
2249
[email protected]2431756e2010-09-29 20:26:132250 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522251 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132252 rv = handle2.Init("a",
2253 params_,
2254 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522255 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132256 pool_.get(),
2257 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162258 EXPECT_EQ(OK, rv);
2259
[email protected]2431756e2010-09-29 20:26:132260 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:522261 TestCompletionCallback callback3;
[email protected]2431756e2010-09-29 20:26:132262 rv = handle3.Init("a",
2263 params_,
2264 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522265 callback3.callback(),
[email protected]2431756e2010-09-29 20:26:132266 pool_.get(),
2267 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162268 EXPECT_EQ(ERR_IO_PENDING, rv);
2269
[email protected]2431756e2010-09-29 20:26:132270 ClientSocketHandle handle4;
[email protected]6ecf2b92011-12-15 01:14:522271 TestCompletionCallback callback4;
[email protected]2431756e2010-09-29 20:26:132272 rv = handle4.Init("a",
2273 params_,
2274 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522275 callback4.callback(),
[email protected]2431756e2010-09-29 20:26:132276 pool_.get(),
2277 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162278 EXPECT_EQ(ERR_IO_PENDING, rv);
2279
2280 // Release two disconnected sockets.
2281
[email protected]2431756e2010-09-29 20:26:132282 handle.socket()->Disconnect();
2283 handle.Reset();
2284 handle2.socket()->Disconnect();
2285 handle2.Reset();
[email protected]4f2abec2010-02-03 18:10:162286
[email protected]2431756e2010-09-29 20:26:132287 EXPECT_EQ(OK, callback3.WaitForResult());
2288 EXPECT_FALSE(handle3.is_reused());
2289 EXPECT_EQ(OK, callback4.WaitForResult());
2290 EXPECT_FALSE(handle4.is_reused());
[email protected]4f2abec2010-02-03 18:10:162291}
2292
[email protected]d7027bb2010-05-10 18:58:542293// Regression test for http://crbug.com/42267.
2294// When DoReleaseSocket() is processed for one socket, it is blocked because the
2295// other stalled groups all have releasing sockets, so no progress can be made.
2296TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
2297 CreatePoolWithIdleTimeouts(
2298 4 /* socket limit */, 4 /* socket limit per group */,
2299 base::TimeDelta(), // Time out unused sockets immediately.
2300 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2301
2302 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2303
2304 // Max out the socket limit with 2 per group.
2305
[email protected]2431756e2010-09-29 20:26:132306 ClientSocketHandle handle_a[4];
[email protected]6ecf2b92011-12-15 01:14:522307 TestCompletionCallback callback_a[4];
[email protected]2431756e2010-09-29 20:26:132308 ClientSocketHandle handle_b[4];
[email protected]6ecf2b92011-12-15 01:14:522309 TestCompletionCallback callback_b[4];
[email protected]d7027bb2010-05-10 18:58:542310
2311 for (int i = 0; i < 2; ++i) {
[email protected]2431756e2010-09-29 20:26:132312 EXPECT_EQ(OK, handle_a[i].Init("a",
2313 params_,
2314 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522315 callback_a[i].callback(),
[email protected]2431756e2010-09-29 20:26:132316 pool_.get(),
2317 BoundNetLog()));
2318 EXPECT_EQ(OK, handle_b[i].Init("b",
2319 params_,
2320 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522321 callback_b[i].callback(),
[email protected]2431756e2010-09-29 20:26:132322 pool_.get(),
2323 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542324 }
[email protected]b89f7e42010-05-20 20:37:002325
[email protected]d7027bb2010-05-10 18:58:542326 // Make 4 pending requests, 2 per group.
2327
2328 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132329 EXPECT_EQ(ERR_IO_PENDING,
2330 handle_a[i].Init("a",
2331 params_,
2332 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522333 callback_a[i].callback(),
[email protected]2431756e2010-09-29 20:26:132334 pool_.get(),
2335 BoundNetLog()));
2336 EXPECT_EQ(ERR_IO_PENDING,
2337 handle_b[i].Init("b",
2338 params_,
2339 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522340 callback_b[i].callback(),
[email protected]2431756e2010-09-29 20:26:132341 pool_.get(),
2342 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542343 }
2344
2345 // Release b's socket first. The order is important, because in
2346 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2347 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2348 // first, which has a releasing socket, so it refuses to start up another
2349 // ConnectJob. So, we used to infinite loop on this.
[email protected]2431756e2010-09-29 20:26:132350 handle_b[0].socket()->Disconnect();
2351 handle_b[0].Reset();
2352 handle_a[0].socket()->Disconnect();
2353 handle_a[0].Reset();
[email protected]d7027bb2010-05-10 18:58:542354
2355 // Used to get stuck here.
2356 MessageLoop::current()->RunAllPending();
2357
[email protected]2431756e2010-09-29 20:26:132358 handle_b[1].socket()->Disconnect();
2359 handle_b[1].Reset();
2360 handle_a[1].socket()->Disconnect();
2361 handle_a[1].Reset();
[email protected]d7027bb2010-05-10 18:58:542362
2363 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132364 EXPECT_EQ(OK, callback_b[i].WaitForResult());
2365 EXPECT_EQ(OK, callback_a[i].WaitForResult());
[email protected]d7027bb2010-05-10 18:58:542366 }
2367}
2368
[email protected]fd4fe0b2010-02-08 23:02:152369TEST_F(ClientSocketPoolBaseTest,
2370 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2371 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2372
2373 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2374
2375 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2376 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2377 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2378 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2379
[email protected]2431756e2010-09-29 20:26:132380 EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
2381 EXPECT_EQ(OK, (*requests())[1]->WaitForResult());
2382 EXPECT_EQ(2u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152383
2384 // Releases one connection.
[email protected]2431756e2010-09-29 20:26:132385 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2386 EXPECT_EQ(OK, (*requests())[2]->WaitForResult());
[email protected]fd4fe0b2010-02-08 23:02:152387
[email protected]2431756e2010-09-29 20:26:132388 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2389 EXPECT_EQ(OK, (*requests())[3]->WaitForResult());
2390 EXPECT_EQ(4u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152391
2392 EXPECT_EQ(1, GetOrderOfRequest(1));
2393 EXPECT_EQ(2, GetOrderOfRequest(2));
2394 EXPECT_EQ(3, GetOrderOfRequest(3));
2395 EXPECT_EQ(4, GetOrderOfRequest(4));
2396
2397 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:132398 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
[email protected]fd4fe0b2010-02-08 23:02:152399}
2400
[email protected]6ecf2b92011-12-15 01:14:522401class TestReleasingSocketRequest : public TestCompletionCallbackBase {
[email protected]4f1e4982010-03-02 18:31:042402 public:
[email protected]2431756e2010-09-29 20:26:132403 TestReleasingSocketRequest(TestClientSocketPool* pool,
2404 int expected_result,
[email protected]e60e47a2010-07-14 03:37:182405 bool reset_releasing_handle)
2406 : pool_(pool),
2407 expected_result_(expected_result),
[email protected]6ecf2b92011-12-15 01:14:522408 reset_releasing_handle_(reset_releasing_handle),
2409 ALLOW_THIS_IN_INITIALIZER_LIST(callback_(
2410 base::Bind(&TestReleasingSocketRequest::OnComplete,
2411 base::Unretained(this)))) {
2412 }
2413
2414 virtual ~TestReleasingSocketRequest() {}
[email protected]4f1e4982010-03-02 18:31:042415
2416 ClientSocketHandle* handle() { return &handle_; }
2417
[email protected]6ecf2b92011-12-15 01:14:522418 const CompletionCallback& callback() const { return callback_; }
[email protected]4f1e4982010-03-02 18:31:042419
2420 private:
[email protected]6ecf2b92011-12-15 01:14:522421 void OnComplete(int result) {
2422 SetResult(result);
2423 if (reset_releasing_handle_)
2424 handle_.Reset();
2425
2426 scoped_refptr<TestSocketParams> con_params(new TestSocketParams());
2427 EXPECT_EQ(expected_result_,
2428 handle2_.Init("a", con_params, kDefaultPriority,
2429 callback2_.callback(), pool_, BoundNetLog()));
2430 }
2431
[email protected]2431756e2010-09-29 20:26:132432 TestClientSocketPool* const pool_;
[email protected]e60e47a2010-07-14 03:37:182433 int expected_result_;
2434 bool reset_releasing_handle_;
[email protected]4f1e4982010-03-02 18:31:042435 ClientSocketHandle handle_;
2436 ClientSocketHandle handle2_;
[email protected]6ecf2b92011-12-15 01:14:522437 CompletionCallback callback_;
2438 TestCompletionCallback callback2_;
[email protected]4f1e4982010-03-02 18:31:042439};
2440
[email protected]e60e47a2010-07-14 03:37:182441
2442TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2443 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2444
2445 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2446 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
2447 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2448
[email protected]2431756e2010-09-29 20:26:132449 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]e60e47a2010-07-14 03:37:182450 client_socket_factory_.allocation_count());
2451
2452 connect_job_factory_->set_job_type(
2453 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2454 TestReleasingSocketRequest req(pool_.get(), OK, false);
[email protected]2431756e2010-09-29 20:26:132455 EXPECT_EQ(ERR_IO_PENDING,
[email protected]6ecf2b92011-12-15 01:14:522456 req.handle()->Init("a", params_, kDefaultPriority, req.callback(),
2457 pool_.get(), BoundNetLog()));
[email protected]e60e47a2010-07-14 03:37:182458 // The next job should complete synchronously
2459 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2460
2461 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
2462 EXPECT_FALSE(req.handle()->is_initialized());
2463 EXPECT_FALSE(req.handle()->socket());
2464 EXPECT_TRUE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:432465 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182466}
2467
[email protected]b6501d3d2010-06-03 23:53:342468// http://crbug.com/44724 regression test.
2469// We start releasing the pool when we flush on network change. When that
2470// happens, the only active references are in the ClientSocketHandles. When a
2471// ConnectJob completes and calls back into the last ClientSocketHandle, that
2472// callback can release the last reference and delete the pool. After the
2473// callback finishes, we go back to the stack frame within the now-deleted pool.
2474// Executing any code that refers to members of the now-deleted pool can cause
2475// crashes.
2476TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2477 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2478 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2479
2480 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522481 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132482 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2483 params_,
2484 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522485 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132486 pool_.get(),
2487 BoundNetLog()));
[email protected]b6501d3d2010-06-03 23:53:342488
[email protected]2431756e2010-09-29 20:26:132489 pool_->Flush();
[email protected]b6501d3d2010-06-03 23:53:342490
2491 // We'll call back into this now.
2492 callback.WaitForResult();
2493}
2494
[email protected]a7e38572010-06-07 18:22:242495TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2496 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2497 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2498
2499 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522500 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132501 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2502 params_,
2503 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522504 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132505 pool_.get(),
2506 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242507 EXPECT_EQ(OK, callback.WaitForResult());
2508 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2509
2510 pool_->Flush();
2511
2512 handle.Reset();
2513 MessageLoop::current()->RunAllPending();
2514
[email protected]2431756e2010-09-29 20:26:132515 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2516 params_,
2517 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522518 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132519 pool_.get(),
2520 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242521 EXPECT_EQ(OK, callback.WaitForResult());
2522 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2523}
2524
[email protected]6ecf2b92011-12-15 01:14:522525class ConnectWithinCallback : public TestCompletionCallbackBase {
[email protected]06f92462010-08-31 19:24:142526 public:
2527 ConnectWithinCallback(
2528 const std::string& group_name,
2529 const scoped_refptr<TestSocketParams>& params,
[email protected]2431756e2010-09-29 20:26:132530 TestClientSocketPool* pool)
[email protected]6ecf2b92011-12-15 01:14:522531 : group_name_(group_name),
2532 params_(params),
2533 pool_(pool),
2534 ALLOW_THIS_IN_INITIALIZER_LIST(callback_(
2535 base::Bind(&ConnectWithinCallback::OnComplete,
2536 base::Unretained(this)))) {
[email protected]06f92462010-08-31 19:24:142537 }
2538
[email protected]6ecf2b92011-12-15 01:14:522539 virtual ~ConnectWithinCallback() {}
[email protected]06f92462010-08-31 19:24:142540
2541 int WaitForNestedResult() {
2542 return nested_callback_.WaitForResult();
2543 }
2544
[email protected]6ecf2b92011-12-15 01:14:522545 const CompletionCallback& callback() const { return callback_; }
2546
[email protected]06f92462010-08-31 19:24:142547 private:
[email protected]6ecf2b92011-12-15 01:14:522548 void OnComplete(int result) {
2549 SetResult(result);
2550 EXPECT_EQ(ERR_IO_PENDING,
2551 handle_.Init(group_name_,
2552 params_,
2553 kDefaultPriority,
2554 nested_callback_.callback(),
2555 pool_,
2556 BoundNetLog()));
2557 }
2558
[email protected]06f92462010-08-31 19:24:142559 const std::string group_name_;
2560 const scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:132561 TestClientSocketPool* const pool_;
[email protected]06f92462010-08-31 19:24:142562 ClientSocketHandle handle_;
[email protected]6ecf2b92011-12-15 01:14:522563 CompletionCallback callback_;
2564 TestCompletionCallback nested_callback_;
2565
2566 DISALLOW_COPY_AND_ASSIGN(ConnectWithinCallback);
[email protected]06f92462010-08-31 19:24:142567};
2568
2569TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
2570 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2571
2572 // First job will be waiting until it gets aborted.
2573 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2574
2575 ClientSocketHandle handle;
[email protected]2431756e2010-09-29 20:26:132576 ConnectWithinCallback callback("a", params_, pool_.get());
2577 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2578 params_,
2579 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522580 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132581 pool_.get(),
2582 BoundNetLog()));
[email protected]06f92462010-08-31 19:24:142583
2584 // Second job will be started during the first callback, and will
2585 // asynchronously complete with OK.
2586 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2587 pool_->Flush();
2588 EXPECT_EQ(ERR_ABORTED, callback.WaitForResult());
2589 EXPECT_EQ(OK, callback.WaitForNestedResult());
2590}
2591
[email protected]25eea382010-07-10 23:55:262592// Cancel a pending socket request while we're at max sockets,
2593// and verify that the backup socket firing doesn't cause a crash.
2594TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
2595 // Max 4 sockets globally, max 4 sockets per group.
2596 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
[email protected]06d94042010-08-25 01:45:222597 pool_->EnableConnectBackupJobs();
[email protected]25eea382010-07-10 23:55:262598
[email protected]4baaf9d2010-08-31 15:15:442599 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2600 // timer.
[email protected]25eea382010-07-10 23:55:262601 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2602 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522603 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132604 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2605 params_,
2606 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522607 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132608 pool_.get(),
2609 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262610
2611 // Start (MaxSockets - 1) connected sockets to reach max sockets.
2612 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2613 ClientSocketHandle handles[kDefaultMaxSockets];
2614 for (int i = 1; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:522615 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132616 EXPECT_EQ(OK, handles[i].Init("bar",
2617 params_,
2618 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522619 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132620 pool_.get(),
2621 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262622 }
2623
2624 MessageLoop::current()->RunAllPending();
2625
2626 // Cancel the pending request.
2627 handle.Reset();
2628
2629 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]26b9973962012-01-28 00:57:002630 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2631 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]25eea382010-07-10 23:55:262632
2633 MessageLoop::current()->RunAllPending();
2634 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
2635}
2636
[email protected]3f00be82010-09-27 19:50:022637TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
[email protected]4baaf9d2010-08-31 15:15:442638 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2639 pool_->EnableConnectBackupJobs();
2640
2641 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2642 // timer.
2643 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2644 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522645 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132646 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2647 params_,
2648 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522649 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132650 pool_.get(),
2651 BoundNetLog()));
[email protected]4baaf9d2010-08-31 15:15:442652 ASSERT_TRUE(pool_->HasGroup("bar"));
2653 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
[email protected]8159a1c2012-06-07 00:00:102654 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("bar"));
[email protected]4baaf9d2010-08-31 15:15:442655
2656 // Cancel the socket request. This should cancel the backup timer. Wait for
2657 // the backup time to see if it indeed got canceled.
2658 handle.Reset();
2659 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]26b9973962012-01-28 00:57:002660 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2661 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]4baaf9d2010-08-31 15:15:442662 MessageLoop::current()->RunAllPending();
2663 ASSERT_TRUE(pool_->HasGroup("bar"));
2664 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2665}
2666
[email protected]3f00be82010-09-27 19:50:022667TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
2668 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2669 pool_->EnableConnectBackupJobs();
2670
2671 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2672 // timer.
2673 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2674 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522675 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132676 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2677 params_,
2678 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522679 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132680 pool_.get(),
2681 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022682 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2683 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522684 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132685 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("bar",
2686 params_,
2687 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522688 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132689 pool_.get(),
2690 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022691 ASSERT_TRUE(pool_->HasGroup("bar"));
2692 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("bar"));
2693
2694 // Cancel request 1 and then complete request 2. With the requests finished,
2695 // the backup timer should be cancelled.
2696 handle.Reset();
2697 EXPECT_EQ(OK, callback2.WaitForResult());
2698 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]26b9973962012-01-28 00:57:002699 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2700 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]3f00be82010-09-27 19:50:022701 MessageLoop::current()->RunAllPending();
2702}
2703
[email protected]eb5a99382010-07-11 03:18:262704// Test delayed socket binding for the case where we have two connects,
2705// and while one is waiting on a connect, the other frees up.
2706// The socket waiting on a connect should switch immediately to the freed
2707// up socket.
2708TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
2709 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2710 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2711
2712 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522713 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132714 EXPECT_EQ(ERR_IO_PENDING,
2715 handle1.Init("a",
2716 params_,
2717 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522718 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132719 pool_.get(),
2720 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262721 EXPECT_EQ(OK, callback.WaitForResult());
2722
2723 // No idle sockets, no pending jobs.
2724 EXPECT_EQ(0, pool_->IdleSocketCount());
2725 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2726
2727 // Create a second socket to the same host, but this one will wait.
2728 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2729 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132730 EXPECT_EQ(ERR_IO_PENDING,
2731 handle2.Init("a",
2732 params_,
2733 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522734 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132735 pool_.get(),
2736 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262737 // No idle sockets, and one connecting job.
2738 EXPECT_EQ(0, pool_->IdleSocketCount());
2739 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2740
2741 // Return the first handle to the pool. This will initiate the delayed
2742 // binding.
2743 handle1.Reset();
2744
2745 MessageLoop::current()->RunAllPending();
2746
2747 // Still no idle sockets, still one pending connect job.
2748 EXPECT_EQ(0, pool_->IdleSocketCount());
2749 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2750
2751 // The second socket connected, even though it was a Waiting Job.
2752 EXPECT_EQ(OK, callback.WaitForResult());
2753
2754 // And we can see there is still one job waiting.
2755 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2756
2757 // Finally, signal the waiting Connect.
2758 client_socket_factory_.SignalJobs();
2759 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2760
2761 MessageLoop::current()->RunAllPending();
2762}
2763
2764// Test delayed socket binding when a group is at capacity and one
2765// of the group's sockets frees up.
2766TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
2767 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2768 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2769
2770 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522771 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132772 EXPECT_EQ(ERR_IO_PENDING,
2773 handle1.Init("a",
2774 params_,
2775 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522776 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132777 pool_.get(),
2778 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262779 EXPECT_EQ(OK, callback.WaitForResult());
2780
2781 // No idle sockets, no pending jobs.
2782 EXPECT_EQ(0, pool_->IdleSocketCount());
2783 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2784
2785 // Create a second socket to the same host, but this one will wait.
2786 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2787 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132788 EXPECT_EQ(ERR_IO_PENDING,
2789 handle2.Init("a",
2790 params_,
2791 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522792 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132793 pool_.get(),
2794 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262795 // No idle sockets, and one connecting job.
2796 EXPECT_EQ(0, pool_->IdleSocketCount());
2797 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2798
2799 // Return the first handle to the pool. This will initiate the delayed
2800 // binding.
2801 handle1.Reset();
2802
2803 MessageLoop::current()->RunAllPending();
2804
2805 // Still no idle sockets, still one pending connect job.
2806 EXPECT_EQ(0, pool_->IdleSocketCount());
2807 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2808
2809 // The second socket connected, even though it was a Waiting Job.
2810 EXPECT_EQ(OK, callback.WaitForResult());
2811
2812 // And we can see there is still one job waiting.
2813 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2814
2815 // Finally, signal the waiting Connect.
2816 client_socket_factory_.SignalJobs();
2817 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2818
2819 MessageLoop::current()->RunAllPending();
2820}
2821
2822// Test out the case where we have one socket connected, one
2823// connecting, when the first socket finishes and goes idle.
[email protected]2abfe90a2010-08-25 17:49:512824// Although the second connection is pending, the second request
[email protected]eb5a99382010-07-11 03:18:262825// should complete, by taking the first socket's idle socket.
2826TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
2827 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2828 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2829
2830 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522831 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132832 EXPECT_EQ(ERR_IO_PENDING,
2833 handle1.Init("a",
2834 params_,
2835 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522836 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132837 pool_.get(),
2838 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262839 EXPECT_EQ(OK, callback.WaitForResult());
2840
2841 // No idle sockets, no pending jobs.
2842 EXPECT_EQ(0, pool_->IdleSocketCount());
2843 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2844
2845 // Create a second socket to the same host, but this one will wait.
2846 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2847 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132848 EXPECT_EQ(ERR_IO_PENDING,
2849 handle2.Init("a",
2850 params_,
2851 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522852 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132853 pool_.get(),
2854 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262855 // No idle sockets, and one connecting job.
2856 EXPECT_EQ(0, pool_->IdleSocketCount());
2857 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2858
2859 // Return the first handle to the pool. This will initiate the delayed
2860 // binding.
2861 handle1.Reset();
2862
2863 MessageLoop::current()->RunAllPending();
2864
2865 // Still no idle sockets, still one pending connect job.
2866 EXPECT_EQ(0, pool_->IdleSocketCount());
2867 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2868
2869 // The second socket connected, even though it was a Waiting Job.
2870 EXPECT_EQ(OK, callback.WaitForResult());
2871
2872 // And we can see there is still one job waiting.
2873 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2874
2875 // Finally, signal the waiting Connect.
2876 client_socket_factory_.SignalJobs();
2877 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2878
2879 MessageLoop::current()->RunAllPending();
2880}
2881
[email protected]2abfe90a2010-08-25 17:49:512882// Cover the case where on an available socket slot, we have one pending
2883// request that completes synchronously, thereby making the Group empty.
2884TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
2885 const int kUnlimitedSockets = 100;
2886 const int kOneSocketPerGroup = 1;
2887 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
2888
2889 // Make the first request asynchronous fail.
2890 // This will free up a socket slot later.
2891 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2892
2893 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522894 TestCompletionCallback callback1;
[email protected]2431756e2010-09-29 20:26:132895 EXPECT_EQ(ERR_IO_PENDING,
2896 handle1.Init("a",
2897 params_,
2898 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522899 callback1.callback(),
[email protected]2431756e2010-09-29 20:26:132900 pool_.get(),
2901 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:512902 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2903
2904 // Make the second request synchronously fail. This should make the Group
2905 // empty.
2906 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
2907 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522908 TestCompletionCallback callback2;
[email protected]2abfe90a2010-08-25 17:49:512909 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
2910 // when created.
[email protected]2431756e2010-09-29 20:26:132911 EXPECT_EQ(ERR_IO_PENDING,
2912 handle2.Init("a",
2913 params_,
2914 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522915 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132916 pool_.get(),
2917 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:512918
2919 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2920
2921 EXPECT_EQ(ERR_CONNECTION_FAILED, callback1.WaitForResult());
2922 EXPECT_EQ(ERR_CONNECTION_FAILED, callback2.WaitForResult());
2923 EXPECT_FALSE(pool_->HasGroup("a"));
2924}
2925
[email protected]e1b54dc2010-10-06 21:27:222926TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
2927 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2928
2929 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2930
2931 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522932 TestCompletionCallback callback1;
[email protected]e1b54dc2010-10-06 21:27:222933 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2934 params_,
2935 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522936 callback1.callback(),
[email protected]e1b54dc2010-10-06 21:27:222937 pool_.get(),
2938 BoundNetLog()));
2939
2940 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522941 TestCompletionCallback callback2;
[email protected]e1b54dc2010-10-06 21:27:222942 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2943 params_,
2944 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522945 callback2.callback(),
[email protected]e1b54dc2010-10-06 21:27:222946 pool_.get(),
2947 BoundNetLog()));
2948 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:522949 TestCompletionCallback callback3;
[email protected]e1b54dc2010-10-06 21:27:222950 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
2951 params_,
2952 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522953 callback3.callback(),
[email protected]e1b54dc2010-10-06 21:27:222954 pool_.get(),
2955 BoundNetLog()));
2956
2957 EXPECT_EQ(OK, callback1.WaitForResult());
2958 EXPECT_EQ(OK, callback2.WaitForResult());
2959 EXPECT_EQ(OK, callback3.WaitForResult());
2960
2961 // Use the socket.
[email protected]83039bb2011-12-09 18:43:552962 EXPECT_EQ(1, handle1.socket()->Write(NULL, 1, CompletionCallback()));
2963 EXPECT_EQ(1, handle3.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]e1b54dc2010-10-06 21:27:222964
2965 handle1.Reset();
2966 handle2.Reset();
2967 handle3.Reset();
2968
2969 EXPECT_EQ(OK, handle1.Init("a",
2970 params_,
2971 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522972 callback1.callback(),
[email protected]e1b54dc2010-10-06 21:27:222973 pool_.get(),
2974 BoundNetLog()));
2975 EXPECT_EQ(OK, handle2.Init("a",
2976 params_,
2977 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522978 callback2.callback(),
[email protected]e1b54dc2010-10-06 21:27:222979 pool_.get(),
2980 BoundNetLog()));
2981 EXPECT_EQ(OK, handle3.Init("a",
2982 params_,
2983 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522984 callback3.callback(),
[email protected]e1b54dc2010-10-06 21:27:222985 pool_.get(),
2986 BoundNetLog()));
2987
2988 EXPECT_TRUE(handle1.socket()->WasEverUsed());
2989 EXPECT_TRUE(handle2.socket()->WasEverUsed());
2990 EXPECT_FALSE(handle3.socket()->WasEverUsed());
2991}
2992
[email protected]2c2bef152010-10-13 00:55:032993TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
2994 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2995 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2996
2997 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2998
2999 ASSERT_TRUE(pool_->HasGroup("a"));
3000 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103001 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033002 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3003
3004 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523005 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033006 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3007 params_,
3008 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523009 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033010 pool_.get(),
3011 BoundNetLog()));
3012
3013 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523014 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033015 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3016 params_,
3017 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523018 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033019 pool_.get(),
3020 BoundNetLog()));
3021
3022 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103023 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033024 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3025
3026 EXPECT_EQ(OK, callback1.WaitForResult());
3027 EXPECT_EQ(OK, callback2.WaitForResult());
3028 handle1.Reset();
3029 handle2.Reset();
3030
3031 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103032 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033033 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3034}
3035
3036TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
3037 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3038 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3039
3040 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523041 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033042 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3043 params_,
3044 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523045 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033046 pool_.get(),
3047 BoundNetLog()));
3048
3049 ASSERT_TRUE(pool_->HasGroup("a"));
3050 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103051 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033052 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3053
3054 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3055
3056 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103057 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033058 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3059
3060 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523061 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033062 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3063 params_,
3064 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523065 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033066 pool_.get(),
3067 BoundNetLog()));
3068
3069 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103070 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033071 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3072
3073 EXPECT_EQ(OK, callback1.WaitForResult());
3074 EXPECT_EQ(OK, callback2.WaitForResult());
3075 handle1.Reset();
3076 handle2.Reset();
3077
3078 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103079 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033080 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3081}
3082
3083TEST_F(ClientSocketPoolBaseTest,
3084 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
3085 CreatePool(4, 4);
3086 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3087
3088 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523089 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033090 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3091 params_,
3092 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523093 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033094 pool_.get(),
3095 BoundNetLog()));
3096
3097 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523098 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033099 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3100 params_,
3101 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523102 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033103 pool_.get(),
3104 BoundNetLog()));
3105
3106 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:523107 TestCompletionCallback callback3;
[email protected]2c2bef152010-10-13 00:55:033108 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
3109 params_,
3110 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523111 callback3.callback(),
[email protected]2c2bef152010-10-13 00:55:033112 pool_.get(),
3113 BoundNetLog()));
3114
3115 ASSERT_TRUE(pool_->HasGroup("a"));
3116 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103117 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033118 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3119
3120 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3121
3122 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103123 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033124 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3125
3126 EXPECT_EQ(OK, callback1.WaitForResult());
3127 EXPECT_EQ(OK, callback2.WaitForResult());
3128 EXPECT_EQ(OK, callback3.WaitForResult());
3129 handle1.Reset();
3130 handle2.Reset();
3131 handle3.Reset();
3132
3133 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103134 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033135 EXPECT_EQ(3, pool_->IdleSocketCountInGroup("a"));
3136}
3137
3138TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
3139 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3140 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3141
3142 ASSERT_FALSE(pool_->HasGroup("a"));
3143
3144 pool_->RequestSockets("a", &params_, kDefaultMaxSockets,
3145 BoundNetLog());
3146
3147 ASSERT_TRUE(pool_->HasGroup("a"));
3148 EXPECT_EQ(kDefaultMaxSockets, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103149 EXPECT_EQ(kDefaultMaxSockets, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033150
3151 ASSERT_FALSE(pool_->HasGroup("b"));
3152
3153 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
3154 BoundNetLog());
3155
3156 ASSERT_FALSE(pool_->HasGroup("b"));
3157}
3158
3159TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
3160 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3161 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3162
3163 ASSERT_FALSE(pool_->HasGroup("a"));
3164
3165 pool_->RequestSockets("a", &params_, kDefaultMaxSockets - 1,
3166 BoundNetLog());
3167
3168 ASSERT_TRUE(pool_->HasGroup("a"));
3169 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103170 EXPECT_EQ(kDefaultMaxSockets - 1,
3171 pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]51fdc7c2012-04-10 19:19:483172 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033173
3174 ASSERT_FALSE(pool_->HasGroup("b"));
3175
3176 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
3177 BoundNetLog());
3178
3179 ASSERT_TRUE(pool_->HasGroup("b"));
3180 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("b"));
[email protected]51fdc7c2012-04-10 19:19:483181 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033182}
3183
3184TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
3185 CreatePool(4, 4);
3186 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3187
3188 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523189 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033190 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3191 params_,
3192 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523193 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033194 pool_.get(),
3195 BoundNetLog()));
3196 ASSERT_EQ(OK, callback1.WaitForResult());
3197 handle1.Reset();
3198
3199 ASSERT_TRUE(pool_->HasGroup("a"));
3200 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103201 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033202 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3203
3204 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3205
3206 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103207 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033208 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3209}
3210
3211TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
3212 CreatePool(4, 4);
3213 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3214
3215 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523216 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033217 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3218 params_,
3219 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523220 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033221 pool_.get(),
3222 BoundNetLog()));
3223 ASSERT_EQ(OK, callback1.WaitForResult());
3224
3225 ASSERT_TRUE(pool_->HasGroup("a"));
3226 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103227 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033228 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3229 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3230
3231 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3232
3233 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103234 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033235 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3236 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3237}
3238
3239TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
3240 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3241 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3242
3243 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3244 BoundNetLog());
3245
3246 ASSERT_TRUE(pool_->HasGroup("a"));
3247 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103248 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033249 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("a"));
3250
3251 pool_->RequestSockets("b", &params_, kDefaultMaxSocketsPerGroup,
3252 BoundNetLog());
3253
3254 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103255 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]2c2bef152010-10-13 00:55:033256 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("b"));
3257}
3258
[email protected]3c819f522010-12-02 02:03:123259TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
3260 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3261 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3262
3263 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3264 BoundNetLog());
3265
3266 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]fd2e53e2011-01-14 20:40:523267
3268 connect_job_factory_->set_job_type(
3269 TestConnectJob::kMockAdditionalErrorStateJob);
3270 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3271 BoundNetLog());
3272
3273 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]3c819f522010-12-02 02:03:123274}
3275
[email protected]8159a1c2012-06-07 00:00:103276TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
[email protected]2c2bef152010-10-13 00:55:033277 CreatePool(4, 4);
3278 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3279
3280 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3281
3282 ASSERT_TRUE(pool_->HasGroup("a"));
3283 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103284 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033285 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3286
3287 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3288 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103289 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033290 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3291
3292 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523293 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033294 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3295 params_,
3296 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523297 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033298 pool_.get(),
3299 BoundNetLog()));
3300 ASSERT_EQ(OK, callback1.WaitForResult());
3301
3302 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523303 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033304 int rv = handle2.Init("a",
3305 params_,
3306 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523307 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033308 pool_.get(),
3309 BoundNetLog());
3310 if (rv != OK) {
3311 EXPECT_EQ(ERR_IO_PENDING, rv);
3312 EXPECT_EQ(OK, callback2.WaitForResult());
3313 }
3314
[email protected]8159a1c2012-06-07 00:00:103315 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3316 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3317 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("a"));
3318 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3319
[email protected]2c2bef152010-10-13 00:55:033320 handle1.Reset();
3321 handle2.Reset();
3322
[email protected]8159a1c2012-06-07 00:00:103323 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3324 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033325 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3326
3327 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3328 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103329 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033330 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3331}
3332
3333TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
3334 CreatePool(4, 4);
3335 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3336
3337 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3338
3339 ASSERT_TRUE(pool_->HasGroup("a"));
3340 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103341 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033342 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3343
3344 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3345 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103346 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033347 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3348
3349 pool_->RequestSockets("a", &params_, 3, BoundNetLog());
3350 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103351 EXPECT_EQ(3, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033352 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3353
3354 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3355 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103356 EXPECT_EQ(3, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033357 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3358}
3359
3360TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
3361 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3362 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3363
3364 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3365
3366 ASSERT_TRUE(pool_->HasGroup("a"));
3367 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103368 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033369 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3370
3371 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523372 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033373 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3374 params_,
3375 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523376 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033377 pool_.get(),
3378 BoundNetLog()));
3379
3380 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103381 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033382 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3383
3384 ASSERT_EQ(OK, callback1.WaitForResult());
3385
3386 handle1.Reset();
3387
3388 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3389}
3390
[email protected]dcbe168a2010-12-02 03:14:463391// http://crbug.com/64940 regression test.
3392TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
3393 const int kMaxTotalSockets = 3;
3394 const int kMaxSocketsPerGroup = 2;
3395 CreatePool(kMaxTotalSockets, kMaxSocketsPerGroup);
3396 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3397
3398 // Note that group name ordering matters here. "a" comes before "b", so
3399 // CloseOneIdleSocket() will try to close "a"'s idle socket.
3400
3401 // Set up one idle socket in "a".
3402 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523403 TestCompletionCallback callback1;
[email protected]dcbe168a2010-12-02 03:14:463404 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3405 params_,
3406 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523407 callback1.callback(),
[email protected]dcbe168a2010-12-02 03:14:463408 pool_.get(),
3409 BoundNetLog()));
3410
3411 ASSERT_EQ(OK, callback1.WaitForResult());
3412 handle1.Reset();
3413 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3414
3415 // Set up two active sockets in "b".
3416 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523417 TestCompletionCallback callback2;
[email protected]dcbe168a2010-12-02 03:14:463418 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("b",
3419 params_,
3420 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523421 callback1.callback(),
[email protected]dcbe168a2010-12-02 03:14:463422 pool_.get(),
3423 BoundNetLog()));
3424 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("b",
3425 params_,
3426 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523427 callback2.callback(),
[email protected]dcbe168a2010-12-02 03:14:463428 pool_.get(),
3429 BoundNetLog()));
3430
3431 ASSERT_EQ(OK, callback1.WaitForResult());
3432 ASSERT_EQ(OK, callback2.WaitForResult());
3433 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103434 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463435 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3436
3437 // Now we have 1 idle socket in "a" and 2 active sockets in "b". This means
3438 // we've maxed out on sockets, since we set |kMaxTotalSockets| to 3.
3439 // Requesting 2 preconnected sockets for "a" should fail to allocate any more
3440 // sockets for "a", and "b" should still have 2 active sockets.
3441
3442 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3443 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103444 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]dcbe168a2010-12-02 03:14:463445 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3446 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3447 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103448 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463449 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3450 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3451
3452 // Now release the 2 active sockets for "b". This will give us 1 idle socket
3453 // in "a" and 2 idle sockets in "b". Requesting 2 preconnected sockets for
3454 // "a" should result in closing 1 for "b".
3455 handle1.Reset();
3456 handle2.Reset();
3457 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("b"));
3458 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3459
3460 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3461 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103462 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]dcbe168a2010-12-02 03:14:463463 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3464 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3465 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103466 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463467 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("b"));
3468 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3469}
3470
[email protected]b7b8be42011-07-12 12:46:413471TEST_F(ClientSocketPoolBaseTest, PreconnectWithoutBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073472 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3473 pool_->EnableConnectBackupJobs();
3474
3475 // Make the ConnectJob hang until it times out, shorten the timeout.
3476 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3477 connect_job_factory_->set_timeout_duration(
3478 base::TimeDelta::FromMilliseconds(500));
3479 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3480 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103481 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073482 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073483
[email protected]b7b8be42011-07-12 12:46:413484 // Verify the backup timer doesn't create a backup job, by making
3485 // the backup job a pending job instead of a waiting job, so it
3486 // *would* complete if it were created.
[email protected]a9fc8fc2011-05-10 02:41:073487 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5761ab9c2012-02-04 16:44:533488 MessageLoop::current()->PostDelayedTask(
3489 FROM_HERE, MessageLoop::QuitClosure(), base::TimeDelta::FromSeconds(1));
[email protected]b7b8be42011-07-12 12:46:413490 MessageLoop::current()->Run();
[email protected]a9fc8fc2011-05-10 02:41:073491 EXPECT_FALSE(pool_->HasGroup("a"));
3492}
3493
[email protected]b7b8be42011-07-12 12:46:413494TEST_F(ClientSocketPoolBaseTest, PreconnectWithBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073495 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3496 pool_->EnableConnectBackupJobs();
3497
3498 // Make the ConnectJob hang forever.
3499 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3500 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3501 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103502 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073503 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3504 MessageLoop::current()->RunAllPending();
3505
3506 // Make the backup job be a pending job, so it completes normally.
3507 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3508 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:523509 TestCompletionCallback callback;
[email protected]a9fc8fc2011-05-10 02:41:073510 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
3511 params_,
3512 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523513 callback.callback(),
[email protected]a9fc8fc2011-05-10 02:41:073514 pool_.get(),
3515 BoundNetLog()));
[email protected]b7b8be42011-07-12 12:46:413516 // Timer has started, but the backup connect job shouldn't be created yet.
[email protected]a9fc8fc2011-05-10 02:41:073517 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103518 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073519 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3520 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3521 ASSERT_EQ(OK, callback.WaitForResult());
3522
3523 // The hung connect job should still be there, but everything else should be
3524 // complete.
3525 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103526 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073527 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3528 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3529}
3530
[email protected]f6d1d6eb2009-06-24 20:16:093531} // namespace
3532
3533} // namespace net