blob: 779b8dee0f18aa9adba3166dd2f693921f2db051 [file] [log] [blame]
[email protected]3b63f8f42011-03-28 01:54:151// Copyright (c) 2011 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]2041cf342010-02-19 03:15:597#include "base/callback.h"
[email protected]f6d1d6eb2009-06-24 20:16:098#include "base/compiler_specific.h"
[email protected]3b63f8f42011-03-28 01:54:159#include "base/memory/ref_counted.h"
10#include "base/memory/scoped_vector.h"
[email protected]f6d1d6eb2009-06-24 20:16:0911#include "base/message_loop.h"
[email protected]1870d5cf2011-05-12 01:55:4012#include "base/stringprintf.h"
[email protected]e83326f2010-07-31 17:29:2513#include "base/string_number_conversions.h"
[email protected]f214f8792011-01-01 02:17:0814#include "base/threading/platform_thread.h"
[email protected]f3a1c642011-07-12 19:15:0315#include "base/values.h"
[email protected]d8eb84242010-09-25 02:25:0616#include "net/base/net_errors.h"
[email protected]9e743cd2010-03-16 07:03:5317#include "net/base/net_log.h"
18#include "net/base/net_log_unittest.h"
[email protected]ac790b42009-12-02 04:31:3119#include "net/base/request_priority.h"
[email protected]f6d1d6eb2009-06-24 20:16:0920#include "net/base/test_completion_callback.h"
[email protected]277d5942010-08-11 21:02:3521#include "net/http/http_response_headers.h"
[email protected]f6d1d6eb2009-06-24 20:16:0922#include "net/socket/client_socket_factory.h"
23#include "net/socket/client_socket_handle.h"
[email protected]b89f7e42010-05-20 20:37:0024#include "net/socket/client_socket_pool_histograms.h"
[email protected]75439d3b2009-07-23 22:11:1725#include "net/socket/socket_test_util.h"
[email protected]d0672be2010-10-20 16:30:1926#include "net/socket/ssl_host_info.h"
[email protected]3268023f2011-05-05 00:08:1027#include "net/socket/stream_socket.h"
[email protected]d4dfdab2011-12-07 16:56:5928#include "testing/gmock/include/gmock/gmock.h"
[email protected]f6d1d6eb2009-06-24 20:16:0929#include "testing/gtest/include/gtest/gtest.h"
30
[email protected]d4dfdab2011-12-07 16:56:5931using ::testing::Invoke;
32using ::testing::Return;
33
[email protected]f6d1d6eb2009-06-24 20:16:0934namespace net {
35
36namespace {
37
[email protected]211d21722009-07-22 15:48:5338const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2039const int kDefaultMaxSocketsPerGroup = 2;
[email protected]a554a8262010-05-20 00:13:5240const net::RequestPriority kDefaultPriority = MEDIUM;
[email protected]0b7648c2009-07-06 20:14:0141
[email protected]df4b4ef2010-07-12 18:25:2142class TestSocketParams : public base::RefCounted<TestSocketParams> {
[email protected]5acdce12011-03-30 13:00:2043 public:
[email protected]d4dfdab2011-12-07 16:56:5944 TestSocketParams() : ignore_limits_(false) {}
45
46 void set_ignore_limits(bool ignore_limits) {
47 ignore_limits_ = ignore_limits;
48 }
49 bool ignore_limits() { return ignore_limits_; }
50
[email protected]df4b4ef2010-07-12 18:25:2151 private:
52 friend class base::RefCounted<TestSocketParams>;
53 ~TestSocketParams() {}
[email protected]d4dfdab2011-12-07 16:56:5954
55 bool ignore_limits_;
[email protected]df4b4ef2010-07-12 18:25:2156};
[email protected]7fc5b09a2010-02-27 00:07:3857typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
[email protected]d80a4322009-08-14 07:07:4958
[email protected]3268023f2011-05-05 00:08:1059class MockClientSocket : public StreamSocket {
[email protected]f6d1d6eb2009-06-24 20:16:0960 public:
[email protected]5e6efa52011-06-27 17:26:4161 MockClientSocket() : connected_(false), was_used_to_convey_data_(false),
62 num_bytes_read_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:0963
[email protected]3f55aa12011-12-07 02:03:3364 // Socket implementation.
[email protected]ab838892009-06-30 18:49:0565 virtual int Read(
[email protected]f1f3f0f82011-10-01 20:38:1066 IOBuffer* /* buf */, int len, OldCompletionCallback* /* callback */) {
[email protected]5e6efa52011-06-27 17:26:4167 num_bytes_read_ += len;
68 return len;
[email protected]ab838892009-06-30 18:49:0569 }
[email protected]3f55aa12011-12-07 02:03:3370 virtual int Read(
71 IOBuffer* /* buf */, int len, const CompletionCallback& /* callback */) {
72 num_bytes_read_ += len;
73 return len;
74 }
[email protected]ab838892009-06-30 18:49:0575
76 virtual int Write(
[email protected]f1f3f0f82011-10-01 20:38:1077 IOBuffer* /* buf */, int len, OldCompletionCallback* /* callback */) {
[email protected]0f873e82010-09-02 16:09:0178 was_used_to_convey_data_ = true;
79 return len;
[email protected]ab838892009-06-30 18:49:0580 }
[email protected]06650c52010-06-03 00:49:1781 virtual bool SetReceiveBufferSize(int32 size) { return true; }
82 virtual bool SetSendBufferSize(int32 size) { return true; }
[email protected]ab838892009-06-30 18:49:0583
[email protected]dbf036f2011-12-06 23:33:2484 // StreamSocket implementation.
[email protected]f1f3f0f82011-10-01 20:38:1085 virtual int Connect(OldCompletionCallback* callback) {
[email protected]f6d1d6eb2009-06-24 20:16:0986 connected_ = true;
87 return OK;
88 }
[email protected]dbf036f2011-12-06 23:33:2489 virtual int Connect(const net::CompletionCallback& callback) {
90 connected_ = true;
91 return OK;
92 }
[email protected]f6d1d6eb2009-06-24 20:16:0993
[email protected]ab838892009-06-30 18:49:0594 virtual void Disconnect() { connected_ = false; }
95 virtual bool IsConnected() const { return connected_; }
96 virtual bool IsConnectedAndIdle() const { return connected_; }
[email protected]0b7648c2009-07-06 20:14:0197
[email protected]ac9eec62010-02-20 18:50:3898 virtual int GetPeerAddress(AddressList* /* address */) const {
[email protected]9f864b32010-01-20 15:01:1699 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:09100 }
[email protected]f6d1d6eb2009-06-24 20:16:09101
[email protected]e7f74da2011-04-19 23:49:35102 virtual int GetLocalAddress(IPEndPoint* /* address */) const {
103 return ERR_UNEXPECTED;
104 }
105
[email protected]a2006ece2010-04-23 16:44:02106 virtual const BoundNetLog& NetLog() const {
107 return net_log_;
108 }
109
[email protected]9b5614a2010-08-25 20:29:45110 virtual void SetSubresourceSpeculation() {}
111 virtual void SetOmniboxSpeculation() {}
[email protected]5e6efa52011-06-27 17:26:41112 virtual bool WasEverUsed() const {
113 return was_used_to_convey_data_ || num_bytes_read_ > 0;
114 }
[email protected]7f7e92392010-10-26 18:29:29115 virtual bool UsingTCPFastOpen() const { return false; }
[email protected]5e6efa52011-06-27 17:26:41116 virtual int64 NumBytesRead() const { return num_bytes_read_; }
117 virtual base::TimeDelta GetConnectTimeMicros() const {
118 static const base::TimeDelta kDummyConnectTimeMicros =
119 base::TimeDelta::FromMicroseconds(10);
120 return kDummyConnectTimeMicros; // Dummy value.
121 }
[email protected]9b5614a2010-08-25 20:29:45122
[email protected]f6d1d6eb2009-06-24 20:16:09123 private:
124 bool connected_;
[email protected]a2006ece2010-04-23 16:44:02125 BoundNetLog net_log_;
[email protected]0f873e82010-09-02 16:09:01126 bool was_used_to_convey_data_;
[email protected]5e6efa52011-06-27 17:26:41127 int num_bytes_read_;
[email protected]f6d1d6eb2009-06-24 20:16:09128
[email protected]ab838892009-06-30 18:49:05129 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:09130};
131
[email protected]5fc08e32009-07-15 17:09:57132class TestConnectJob;
133
[email protected]f6d1d6eb2009-06-24 20:16:09134class MockClientSocketFactory : public ClientSocketFactory {
135 public:
[email protected]ab838892009-06-30 18:49:05136 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:09137
[email protected]98b0e582011-06-22 14:31:41138 virtual DatagramClientSocket* CreateDatagramClientSocket(
[email protected]5370c012011-06-29 03:47:04139 DatagramSocket::BindType bind_type,
140 const RandIntCallback& rand_int_cb,
[email protected]98b0e582011-06-22 14:31:41141 NetLog* net_log,
142 const NetLog::Source& source) {
143 NOTREACHED();
144 return NULL;
145 }
146
[email protected]3268023f2011-05-05 00:08:10147 virtual StreamSocket* CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07148 const AddressList& addresses,
149 NetLog* /* net_log */,
150 const NetLog::Source& /*source*/) {
[email protected]f6d1d6eb2009-06-24 20:16:09151 allocation_count_++;
[email protected]ab838892009-06-30 18:49:05152 return NULL;
[email protected]f6d1d6eb2009-06-24 20:16:09153 }
154
155 virtual SSLClientSocket* CreateSSLClientSocket(
[email protected]e60e47a2010-07-14 03:37:18156 ClientSocketHandle* transport_socket,
[email protected]4f4de7e62010-11-12 19:55:27157 const HostPortPair& host_and_port,
[email protected]7ab5bbd12010-10-19 13:33:21158 const SSLConfig& ssl_config,
[email protected]d8fbf582010-11-04 21:51:12159 SSLHostInfo* ssl_host_info,
[email protected]feb79bcd2011-07-21 16:55:17160 const SSLClientSocketContext& context) {
[email protected]f6d1d6eb2009-06-24 20:16:09161 NOTIMPLEMENTED();
[email protected]7ab5bbd12010-10-19 13:33:21162 delete ssl_host_info;
[email protected]f6d1d6eb2009-06-24 20:16:09163 return NULL;
164 }
165
[email protected]25f47352011-02-25 16:31:59166 virtual void ClearSSLSessionCache() {
167 NOTIMPLEMENTED();
168 }
169
[email protected]5fc08e32009-07-15 17:09:57170 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
171 void SignalJobs();
172
[email protected]f6d1d6eb2009-06-24 20:16:09173 int allocation_count() const { return allocation_count_; }
174
[email protected]f6d1d6eb2009-06-24 20:16:09175 private:
176 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:57177 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09178};
179
[email protected]ab838892009-06-30 18:49:05180class TestConnectJob : public ConnectJob {
181 public:
182 enum JobType {
183 kMockJob,
184 kMockFailingJob,
185 kMockPendingJob,
186 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57187 kMockWaitingJob,
188 kMockAdvancingLoadStateJob,
[email protected]e772db3f2010-07-12 18:11:13189 kMockRecoverableJob,
190 kMockPendingRecoverableJob,
[email protected]e60e47a2010-07-14 03:37:18191 kMockAdditionalErrorStateJob,
192 kMockPendingAdditionalErrorStateJob,
[email protected]ab838892009-06-30 18:49:05193 };
194
[email protected]994d4932010-07-12 17:55:13195 // The kMockPendingJob uses a slight delay before allowing the connect
196 // to complete.
197 static const int kPendingConnectDelay = 2;
198
[email protected]ab838892009-06-30 18:49:05199 TestConnectJob(JobType job_type,
200 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49201 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34202 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05203 ConnectJob::Delegate* delegate,
[email protected]fd7b7c92009-08-20 19:38:30204 MockClientSocketFactory* client_socket_factory,
[email protected]06650c52010-06-03 00:49:17205 NetLog* net_log)
206 : ConnectJob(group_name, timeout_duration, delegate,
207 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
[email protected]2ab05b52009-07-01 23:57:58208 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05209 client_socket_factory_(client_socket_factory),
[email protected]46451352009-09-01 14:54:21210 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
[email protected]e60e47a2010-07-14 03:37:18211 load_state_(LOAD_STATE_IDLE),
212 store_additional_error_state_(false) {}
[email protected]ab838892009-06-30 18:49:05213
[email protected]974ebd62009-08-03 23:14:34214 void Signal() {
[email protected]e772db3f2010-07-12 18:11:13215 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
[email protected]974ebd62009-08-03 23:14:34216 }
217
[email protected]46451352009-09-01 14:54:21218 virtual LoadState GetLoadState() const { return load_state_; }
219
[email protected]e60e47a2010-07-14 03:37:18220 virtual void GetAdditionalErrorState(ClientSocketHandle* handle) {
221 if (store_additional_error_state_) {
222 // Set all of the additional error state fields in some way.
223 handle->set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43224 HttpResponseInfo info;
225 info.headers = new HttpResponseHeaders("");
226 handle->set_ssl_error_response_info(info);
[email protected]e60e47a2010-07-14 03:37:18227 }
228 }
229
[email protected]974ebd62009-08-03 23:14:34230 private:
[email protected]3f55aa12011-12-07 02:03:33231 // ConnectJob implementation.
[email protected]ab838892009-06-30 18:49:05232
[email protected]974ebd62009-08-03 23:14:34233 virtual int ConnectInternal() {
[email protected]ab838892009-06-30 18:49:05234 AddressList ignored;
[email protected]ab739042011-04-07 15:22:28235 client_socket_factory_->CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07236 ignored, NULL, net::NetLog::Source());
[email protected]6e713f02009-08-06 02:56:40237 set_socket(new MockClientSocket());
[email protected]ab838892009-06-30 18:49:05238 switch (job_type_) {
239 case kMockJob:
[email protected]e772db3f2010-07-12 18:11:13240 return DoConnect(true /* successful */, false /* sync */,
241 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05242 case kMockFailingJob:
[email protected]e772db3f2010-07-12 18:11:13243 return DoConnect(false /* error */, false /* sync */,
244 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05245 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57246 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47247
248 // Depending on execution timings, posting a delayed task can result
249 // in the task getting executed the at the earliest possible
250 // opportunity or only after returning once from the message loop and
251 // then a second call into the message loop. In order to make behavior
252 // more deterministic, we change the default delay to 2ms. This should
253 // always require us to wait for the second call into the message loop.
254 //
255 // N.B. The correct fix for this and similar timing problems is to
256 // abstract time for the purpose of unittests. Unfortunately, we have
257 // a lot of third-party components that directly call the various
258 // time functions, so this change would be rather invasive.
259 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05260 FROM_HERE,
261 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47262 &TestConnectJob::DoConnect,
263 true /* successful */,
[email protected]e772db3f2010-07-12 18:11:13264 true /* async */,
265 false /* recoverable */),
[email protected]994d4932010-07-12 17:55:13266 kPendingConnectDelay);
[email protected]ab838892009-06-30 18:49:05267 return ERR_IO_PENDING;
268 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57269 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47270 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05271 FROM_HERE,
272 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47273 &TestConnectJob::DoConnect,
274 false /* error */,
[email protected]e772db3f2010-07-12 18:11:13275 true /* async */,
276 false /* recoverable */),
[email protected]6b175382009-10-13 06:47:47277 2);
[email protected]ab838892009-06-30 18:49:05278 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57279 case kMockWaitingJob:
280 client_socket_factory_->WaitForSignal(this);
281 waiting_success_ = true;
282 return ERR_IO_PENDING;
283 case kMockAdvancingLoadStateJob:
[email protected]e6ec67b2010-06-16 00:12:46284 MessageLoop::current()->PostTask(
[email protected]5fc08e32009-07-15 17:09:57285 FROM_HERE,
286 method_factory_.NewRunnableMethod(
[email protected]e6ec67b2010-06-16 00:12:46287 &TestConnectJob::AdvanceLoadState, load_state_));
[email protected]5fc08e32009-07-15 17:09:57288 return ERR_IO_PENDING;
[email protected]e772db3f2010-07-12 18:11:13289 case kMockRecoverableJob:
290 return DoConnect(false /* error */, false /* sync */,
291 true /* recoverable */);
292 case kMockPendingRecoverableJob:
293 set_load_state(LOAD_STATE_CONNECTING);
294 MessageLoop::current()->PostDelayedTask(
295 FROM_HERE,
296 method_factory_.NewRunnableMethod(
297 &TestConnectJob::DoConnect,
298 false /* error */,
299 true /* async */,
300 true /* recoverable */),
301 2);
302 return ERR_IO_PENDING;
[email protected]e60e47a2010-07-14 03:37:18303 case kMockAdditionalErrorStateJob:
304 store_additional_error_state_ = true;
305 return DoConnect(false /* error */, false /* sync */,
306 false /* recoverable */);
307 case kMockPendingAdditionalErrorStateJob:
308 set_load_state(LOAD_STATE_CONNECTING);
309 store_additional_error_state_ = true;
310 MessageLoop::current()->PostDelayedTask(
311 FROM_HERE,
312 method_factory_.NewRunnableMethod(
313 &TestConnectJob::DoConnect,
314 false /* error */,
315 true /* async */,
316 false /* recoverable */),
317 2);
318 return ERR_IO_PENDING;
[email protected]ab838892009-06-30 18:49:05319 default:
320 NOTREACHED();
[email protected]6e713f02009-08-06 02:56:40321 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05322 return ERR_FAILED;
323 }
324 }
325
[email protected]46451352009-09-01 14:54:21326 void set_load_state(LoadState load_state) { load_state_ = load_state; }
327
[email protected]e772db3f2010-07-12 18:11:13328 int DoConnect(bool succeed, bool was_async, bool recoverable) {
329 int result = OK;
[email protected]ab838892009-06-30 18:49:05330 if (succeed) {
[email protected]a2006ece2010-04-23 16:44:02331 socket()->Connect(NULL);
[email protected]e772db3f2010-07-12 18:11:13332 } else if (recoverable) {
333 result = ERR_PROXY_AUTH_REQUESTED;
[email protected]6e713f02009-08-06 02:56:40334 } else {
[email protected]e772db3f2010-07-12 18:11:13335 result = ERR_CONNECTION_FAILED;
[email protected]6e713f02009-08-06 02:56:40336 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05337 }
[email protected]2ab05b52009-07-01 23:57:58338
339 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30340 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05341 return result;
342 }
343
[email protected]cfa8228c2010-06-17 01:07:56344 // This function helps simulate the progress of load states on a ConnectJob.
345 // Each time it is called it advances the load state and posts a task to be
346 // called again. It stops at the last connecting load state (the one
347 // before LOAD_STATE_SENDING_REQUEST).
[email protected]5fc08e32009-07-15 17:09:57348 void AdvanceLoadState(LoadState state) {
349 int tmp = state;
350 tmp++;
[email protected]cfa8228c2010-06-17 01:07:56351 if (tmp < LOAD_STATE_SENDING_REQUEST) {
352 state = static_cast<LoadState>(tmp);
353 set_load_state(state);
354 MessageLoop::current()->PostTask(
355 FROM_HERE,
356 method_factory_.NewRunnableMethod(&TestConnectJob::AdvanceLoadState,
357 state));
358 }
[email protected]5fc08e32009-07-15 17:09:57359 }
360
361 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05362 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57363 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05364 ScopedRunnableMethodFactory<TestConnectJob> method_factory_;
[email protected]46451352009-09-01 14:54:21365 LoadState load_state_;
[email protected]e60e47a2010-07-14 03:37:18366 bool store_additional_error_state_;
[email protected]ab838892009-06-30 18:49:05367
368 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
369};
370
[email protected]d80a4322009-08-14 07:07:49371class TestConnectJobFactory
372 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05373 public:
[email protected]5fc08e32009-07-15 17:09:57374 explicit TestConnectJobFactory(MockClientSocketFactory* client_socket_factory)
[email protected]ab838892009-06-30 18:49:05375 : job_type_(TestConnectJob::kMockJob),
376 client_socket_factory_(client_socket_factory) {}
377
378 virtual ~TestConnectJobFactory() {}
379
380 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
381
[email protected]974ebd62009-08-03 23:14:34382 void set_timeout_duration(base::TimeDelta timeout_duration) {
383 timeout_duration_ = timeout_duration;
384 }
385
[email protected]3f55aa12011-12-07 02:03:33386 // ConnectJobFactory implementation.
[email protected]ab838892009-06-30 18:49:05387 virtual ConnectJob* NewConnectJob(
388 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49389 const TestClientSocketPoolBase::Request& request,
[email protected]06650c52010-06-03 00:49:17390 ConnectJob::Delegate* delegate) const {
[email protected]ab838892009-06-30 18:49:05391 return new TestConnectJob(job_type_,
392 group_name,
393 request,
[email protected]974ebd62009-08-03 23:14:34394 timeout_duration_,
[email protected]ab838892009-06-30 18:49:05395 delegate,
[email protected]fd7b7c92009-08-20 19:38:30396 client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17397 NULL);
[email protected]ab838892009-06-30 18:49:05398 }
399
[email protected]a796bcec2010-03-22 17:17:26400 virtual base::TimeDelta ConnectionTimeout() const {
401 return timeout_duration_;
402 }
403
[email protected]ab838892009-06-30 18:49:05404 private:
405 TestConnectJob::JobType job_type_;
[email protected]974ebd62009-08-03 23:14:34406 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57407 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05408
409 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
410};
411
412class TestClientSocketPool : public ClientSocketPool {
413 public:
414 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53415 int max_sockets,
[email protected]ab838892009-06-30 18:49:05416 int max_sockets_per_group,
[email protected]2431756e2010-09-29 20:26:13417 ClientSocketPoolHistograms* histograms,
[email protected]9bf28db2009-08-29 01:35:16418 base::TimeDelta unused_idle_socket_timeout,
419 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49420 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
[email protected]b89f7e42010-05-20 20:37:00421 : base_(max_sockets, max_sockets_per_group, histograms,
[email protected]9bf28db2009-08-29 01:35:16422 unused_idle_socket_timeout, used_idle_socket_timeout,
[email protected]66761b952010-06-25 21:30:38423 connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05424
[email protected]2431756e2010-09-29 20:26:13425 virtual ~TestClientSocketPool() {}
426
[email protected]ab838892009-06-30 18:49:05427 virtual int RequestSocket(
428 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49429 const void* params,
[email protected]ac790b42009-12-02 04:31:31430 net::RequestPriority priority,
[email protected]ab838892009-06-30 18:49:05431 ClientSocketHandle* handle,
[email protected]f1f3f0f82011-10-01 20:38:10432 OldCompletionCallback* callback,
[email protected]d4dfdab2011-12-07 16:56:59433 const BoundNetLog& net_log) OVERRIDE {
[email protected]df4b4ef2010-07-12 18:25:21434 const scoped_refptr<TestSocketParams>* casted_socket_params =
435 static_cast<const scoped_refptr<TestSocketParams>*>(params);
436 return base_.RequestSocket(group_name, *casted_socket_params, priority,
437 handle, callback, net_log);
[email protected]ab838892009-06-30 18:49:05438 }
439
[email protected]2c2bef152010-10-13 00:55:03440 virtual void RequestSockets(const std::string& group_name,
441 const void* params,
442 int num_sockets,
[email protected]d4dfdab2011-12-07 16:56:59443 const BoundNetLog& net_log) OVERRIDE {
[email protected]2c2bef152010-10-13 00:55:03444 const scoped_refptr<TestSocketParams>* casted_params =
445 static_cast<const scoped_refptr<TestSocketParams>*>(params);
446
447 base_.RequestSockets(group_name, *casted_params, num_sockets, net_log);
448 }
449
[email protected]ab838892009-06-30 18:49:05450 virtual void CancelRequest(
451 const std::string& group_name,
[email protected]d4dfdab2011-12-07 16:56:59452 ClientSocketHandle* handle) OVERRIDE {
[email protected]d80a4322009-08-14 07:07:49453 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05454 }
455
456 virtual void ReleaseSocket(
457 const std::string& group_name,
[email protected]3268023f2011-05-05 00:08:10458 StreamSocket* socket,
[email protected]d4dfdab2011-12-07 16:56:59459 int id) OVERRIDE {
[email protected]a7e38572010-06-07 18:22:24460 base_.ReleaseSocket(group_name, socket, id);
461 }
462
[email protected]d4dfdab2011-12-07 16:56:59463 virtual void Flush() OVERRIDE {
[email protected]a7e38572010-06-07 18:22:24464 base_.Flush();
[email protected]ab838892009-06-30 18:49:05465 }
466
[email protected]d4dfdab2011-12-07 16:56:59467 virtual bool IsStalled() const OVERRIDE {
468 return base_.IsStalled();
469 }
470
471 virtual void CloseIdleSockets() OVERRIDE {
[email protected]d80a4322009-08-14 07:07:49472 base_.CloseIdleSockets();
[email protected]ab838892009-06-30 18:49:05473 }
474
[email protected]d4dfdab2011-12-07 16:56:59475 virtual int IdleSocketCount() const OVERRIDE {
476 return base_.idle_socket_count();
477 }
[email protected]ab838892009-06-30 18:49:05478
[email protected]d4dfdab2011-12-07 16:56:59479 virtual int IdleSocketCountInGroup(
480 const std::string& group_name) const OVERRIDE {
[email protected]d80a4322009-08-14 07:07:49481 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05482 }
483
[email protected]d4dfdab2011-12-07 16:56:59484 virtual LoadState GetLoadState(
485 const std::string& group_name,
486 const ClientSocketHandle* handle) const OVERRIDE {
[email protected]d80a4322009-08-14 07:07:49487 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05488 }
489
[email protected]d4dfdab2011-12-07 16:56:59490 virtual void AddLayeredPool(LayeredPool* pool) OVERRIDE {
491 base_.AddLayeredPool(pool);
492 }
493
494 virtual void RemoveLayeredPool(LayeredPool* pool) OVERRIDE {
495 base_.RemoveLayeredPool(pool);
496 }
497
498 virtual DictionaryValue* GetInfoAsValue(
499 const std::string& name,
500 const std::string& type,
501 bool include_nested_pools) const OVERRIDE {
[email protected]59d7a5a2010-08-30 16:44:27502 return base_.GetInfoAsValue(name, type);
503 }
504
[email protected]d4dfdab2011-12-07 16:56:59505 virtual base::TimeDelta ConnectionTimeout() const OVERRIDE {
[email protected]a796bcec2010-03-22 17:17:26506 return base_.ConnectionTimeout();
507 }
508
[email protected]d4dfdab2011-12-07 16:56:59509 virtual ClientSocketPoolHistograms* histograms() const OVERRIDE {
[email protected]b89f7e42010-05-20 20:37:00510 return base_.histograms();
511 }
[email protected]a796bcec2010-03-22 17:17:26512
[email protected]d80a4322009-08-14 07:07:49513 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20514
[email protected]974ebd62009-08-03 23:14:34515 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49516 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34517 }
518
[email protected]2c2bef152010-10-13 00:55:03519 int NumActiveSocketsInGroup(const std::string& group_name) const {
520 return base_.NumActiveSocketsInGroup(group_name);
521 }
522
[email protected]2abfe90a2010-08-25 17:49:51523 bool HasGroup(const std::string& group_name) const {
524 return base_.HasGroup(group_name);
525 }
526
[email protected]9bf28db2009-08-29 01:35:16527 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
528
[email protected]06d94042010-08-25 01:45:22529 void EnableConnectBackupJobs() { base_.EnableConnectBackupJobs(); }
[email protected]43a21b82010-06-10 21:30:54530
[email protected]d4dfdab2011-12-07 16:56:59531 bool CloseOneIdleConnectionInLayeredPool() {
532 return base_.CloseOneIdleConnectionInLayeredPool();
533 }
534
[email protected]ab838892009-06-30 18:49:05535 private:
[email protected]d80a4322009-08-14 07:07:49536 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05537
538 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
539};
540
[email protected]a937a06d2009-08-19 21:19:24541} // namespace
542
[email protected]7fc5b09a2010-02-27 00:07:38543REGISTER_SOCKET_PARAMS_FOR_POOL(TestClientSocketPool, TestSocketParams);
[email protected]a937a06d2009-08-19 21:19:24544
545namespace {
546
[email protected]5fc08e32009-07-15 17:09:57547void MockClientSocketFactory::SignalJobs() {
548 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
549 it != waiting_jobs_.end(); ++it) {
550 (*it)->Signal();
551 }
552 waiting_jobs_.clear();
553}
554
[email protected]974ebd62009-08-03 23:14:34555class TestConnectJobDelegate : public ConnectJob::Delegate {
556 public:
557 TestConnectJobDelegate()
558 : have_result_(false), waiting_for_result_(false), result_(OK) {}
559 virtual ~TestConnectJobDelegate() {}
560
561 virtual void OnConnectJobComplete(int result, ConnectJob* job) {
562 result_ = result;
[email protected]3268023f2011-05-05 00:08:10563 scoped_ptr<StreamSocket> socket(job->ReleaseSocket());
[email protected]9b6fee12009-09-29 18:13:07564 // socket.get() should be NULL iff result != OK
565 EXPECT_EQ(socket.get() == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34566 delete job;
567 have_result_ = true;
568 if (waiting_for_result_)
569 MessageLoop::current()->Quit();
570 }
571
572 int WaitForResult() {
573 DCHECK(!waiting_for_result_);
574 while (!have_result_) {
575 waiting_for_result_ = true;
576 MessageLoop::current()->Run();
577 waiting_for_result_ = false;
578 }
579 have_result_ = false; // auto-reset for next callback
580 return result_;
581 }
582
583 private:
584 bool have_result_;
585 bool waiting_for_result_;
586 int result_;
587};
588
[email protected]2431756e2010-09-29 20:26:13589class ClientSocketPoolBaseTest : public testing::Test {
[email protected]f6d1d6eb2009-06-24 20:16:09590 protected:
[email protected]b89f7e42010-05-20 20:37:00591 ClientSocketPoolBaseTest()
[email protected]df4b4ef2010-07-12 18:25:21592 : params_(new TestSocketParams()),
[email protected]636b8252011-04-08 19:56:54593 histograms_("ClientSocketPoolTest") {
594 connect_backup_jobs_enabled_ =
595 internal::ClientSocketPoolBaseHelper::connect_backup_jobs_enabled();
596 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(true);
[email protected]64770b7d2011-11-16 04:30:41597 cleanup_timer_enabled_ =
598 internal::ClientSocketPoolBaseHelper::cleanup_timer_enabled();
[email protected]636b8252011-04-08 19:56:54599 }
[email protected]2431756e2010-09-29 20:26:13600
[email protected]636b8252011-04-08 19:56:54601 virtual ~ClientSocketPoolBaseTest() {
602 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
603 connect_backup_jobs_enabled_);
[email protected]64770b7d2011-11-16 04:30:41604 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(
605 cleanup_timer_enabled_);
[email protected]636b8252011-04-08 19:56:54606 }
[email protected]c9d6a1d2009-07-14 16:15:20607
[email protected]211d21722009-07-22 15:48:53608 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16609 CreatePoolWithIdleTimeouts(
610 max_sockets,
611 max_sockets_per_group,
[email protected]82b8c962011-10-12 09:17:30612 ClientSocketPool::unused_idle_socket_timeout(),
613 ClientSocketPool::used_idle_socket_timeout());
[email protected]9bf28db2009-08-29 01:35:16614 }
615
616 void CreatePoolWithIdleTimeouts(
617 int max_sockets, int max_sockets_per_group,
618 base::TimeDelta unused_idle_socket_timeout,
619 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20620 DCHECK(!pool_.get());
[email protected]17a0c6c2009-08-04 00:07:04621 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_);
[email protected]2431756e2010-09-29 20:26:13622 pool_.reset(new TestClientSocketPool(max_sockets,
623 max_sockets_per_group,
624 &histograms_,
625 unused_idle_socket_timeout,
626 used_idle_socket_timeout,
627 connect_job_factory_));
[email protected]c9d6a1d2009-07-14 16:15:20628 }
[email protected]f6d1d6eb2009-06-24 20:16:09629
[email protected]ac790b42009-12-02 04:31:31630 int StartRequest(const std::string& group_name,
631 net::RequestPriority priority) {
[email protected]2431756e2010-09-29 20:26:13632 return test_base_.StartRequestUsingPool<
633 TestClientSocketPool, TestSocketParams>(
634 pool_.get(), group_name, priority, params_);
[email protected]f6d1d6eb2009-06-24 20:16:09635 }
636
[email protected]2431756e2010-09-29 20:26:13637 int GetOrderOfRequest(size_t index) const {
638 return test_base_.GetOrderOfRequest(index);
[email protected]f6d1d6eb2009-06-24 20:16:09639 }
640
[email protected]2431756e2010-09-29 20:26:13641 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
642 return test_base_.ReleaseOneConnection(keep_alive);
643 }
644
645 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
646 test_base_.ReleaseAllConnections(keep_alive);
647 }
648
649 TestSocketRequest* request(int i) { return test_base_.request(i); }
650 size_t requests_size() const { return test_base_.requests_size(); }
651 ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); }
652 size_t completion_count() const { return test_base_.completion_count(); }
653
[email protected]636b8252011-04-08 19:56:54654 bool connect_backup_jobs_enabled_;
[email protected]64770b7d2011-11-16 04:30:41655 bool cleanup_timer_enabled_;
[email protected]f6d1d6eb2009-06-24 20:16:09656 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04657 TestConnectJobFactory* connect_job_factory_;
[email protected]df4b4ef2010-07-12 18:25:21658 scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:13659 ClientSocketPoolHistograms histograms_;
660 scoped_ptr<TestClientSocketPool> pool_;
661 ClientSocketPoolTest test_base_;
[email protected]f6d1d6eb2009-06-24 20:16:09662};
663
[email protected]5e6efa52011-06-27 17:26:41664TEST_F(ClientSocketPoolBaseTest, AssignIdleSocketToGroup_WarmestSocket) {
665 CreatePool(4, 4);
666 net::SetSocketReusePolicy(0);
667
668 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
669 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
670 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
671 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
672
673 std::map<int, StreamSocket*> sockets_;
674 for (size_t i = 0; i < test_base_.requests_size(); i++) {
675 TestSocketRequest* req = test_base_.request(i);
676 StreamSocket* s = req->handle()->socket();
677 MockClientSocket* sock = static_cast<MockClientSocket*>(s);
678 CHECK(sock);
679 sockets_[i] = sock;
680 sock->Read(NULL, 1024 - i, NULL);
681 }
682
683 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
684
685 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
686 TestSocketRequest* req = test_base_.request(test_base_.requests_size() - 1);
687
688 // First socket is warmest.
689 EXPECT_EQ(sockets_[0], req->handle()->socket());
690
691 // Test that NumBytes are as expected.
692 EXPECT_EQ(1024, sockets_[0]->NumBytesRead());
693 EXPECT_EQ(1023, sockets_[1]->NumBytesRead());
694 EXPECT_EQ(1022, sockets_[2]->NumBytesRead());
695 EXPECT_EQ(1021, sockets_[3]->NumBytesRead());
696
697 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
698}
699
700TEST_F(ClientSocketPoolBaseTest, AssignIdleSocketToGroup_LastAccessedSocket) {
701 CreatePool(4, 4);
702 net::SetSocketReusePolicy(2);
703
704 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
705 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
706 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
707 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
708
709 std::map<int, StreamSocket*> sockets_;
710 for (size_t i = 0; i < test_base_.requests_size(); i++) {
711 TestSocketRequest* req = test_base_.request(i);
712 StreamSocket* s = req->handle()->socket();
713 MockClientSocket* sock = static_cast<MockClientSocket*>(s);
714 CHECK(sock);
715 sockets_[i] = sock;
716 sock->Read(NULL, 1024 - i, NULL);
717 }
718
719 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
720
721 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
722 TestSocketRequest* req = test_base_.request(test_base_.requests_size() - 1);
723
724 // Last socket is most recently accessed.
725 EXPECT_EQ(sockets_[3], req->handle()->socket());
726 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
727}
728
[email protected]974ebd62009-08-03 23:14:34729// Even though a timeout is specified, it doesn't time out on a synchronous
730// completion.
731TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
732 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06733 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49734 TestClientSocketPoolBase::Request request(
[email protected]2c2bef152010-10-13 00:55:03735 &ignored, NULL, kDefaultPriority,
736 internal::ClientSocketPoolBaseHelper::NORMAL,
[email protected]5acdce12011-03-30 13:00:20737 false, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34738 scoped_ptr<TestConnectJob> job(
739 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:12740 "a",
[email protected]974ebd62009-08-03 23:14:34741 request,
742 base::TimeDelta::FromMicroseconds(1),
743 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30744 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17745 NULL));
[email protected]974ebd62009-08-03 23:14:34746 EXPECT_EQ(OK, job->Connect());
747}
748
749TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
750 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06751 ClientSocketHandle ignored;
[email protected]06650c52010-06-03 00:49:17752 CapturingNetLog log(CapturingNetLog::kUnbounded);
[email protected]9e743cd2010-03-16 07:03:53753
[email protected]d80a4322009-08-14 07:07:49754 TestClientSocketPoolBase::Request request(
[email protected]2c2bef152010-10-13 00:55:03755 &ignored, NULL, kDefaultPriority,
756 internal::ClientSocketPoolBaseHelper::NORMAL,
[email protected]5acdce12011-03-30 13:00:20757 false, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34758 // Deleted by TestConnectJobDelegate.
759 TestConnectJob* job =
760 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12761 "a",
[email protected]974ebd62009-08-03 23:14:34762 request,
763 base::TimeDelta::FromMicroseconds(1),
764 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30765 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17766 &log);
[email protected]974ebd62009-08-03 23:14:34767 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
[email protected]f214f8792011-01-01 02:17:08768 base::PlatformThread::Sleep(1);
[email protected]974ebd62009-08-03 23:14:34769 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30770
[email protected]b2fcd0e2010-12-01 15:19:40771 net::CapturingNetLog::EntryList entries;
772 log.GetEntries(&entries);
773
774 EXPECT_EQ(6u, entries.size());
[email protected]e9002a92010-01-29 07:10:46775 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40776 entries, 0, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]06650c52010-06-03 00:49:17777 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40778 entries, 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]e9002a92010-01-29 07:10:46779 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40780 entries, 2, NetLog::TYPE_CONNECT_JOB_SET_SOCKET,
[email protected]06650c52010-06-03 00:49:17781 NetLog::PHASE_NONE));
782 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40783 entries, 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
[email protected]9e743cd2010-03-16 07:03:53784 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:46785 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40786 entries, 4, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]06650c52010-06-03 00:49:17787 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40788 entries, 5, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34789}
790
[email protected]5fc08e32009-07-15 17:09:57791TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53792 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20793
[email protected]f1f3f0f82011-10-01 20:38:10794 TestOldCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06795 ClientSocketHandle handle;
[email protected]9e743cd2010-03-16 07:03:53796 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
797
[email protected]2431756e2010-09-29 20:26:13798 EXPECT_EQ(OK,
799 handle.Init("a",
800 params_,
801 kDefaultPriority,
802 &callback,
803 pool_.get(),
804 log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09805 EXPECT_TRUE(handle.is_initialized());
806 EXPECT_TRUE(handle.socket());
[email protected]f6d1d6eb2009-06-24 20:16:09807 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:30808
[email protected]b2fcd0e2010-12-01 15:19:40809 net::CapturingNetLog::EntryList entries;
810 log.GetEntries(&entries);
811
812 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:46813 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40814 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]9e743cd2010-03-16 07:03:53815 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40816 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:17817 NetLog::PHASE_NONE));
818 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40819 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]9e743cd2010-03-16 07:03:53820 NetLog::PHASE_NONE));
821 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40822 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09823}
824
[email protected]ab838892009-06-30 18:49:05825TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53826 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20827
[email protected]ab838892009-06-30 18:49:05828 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]9e743cd2010-03-16 07:03:53829 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
830
[email protected]2431756e2010-09-29 20:26:13831 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:10832 TestOldCompletionCallback callback;
[email protected]e60e47a2010-07-14 03:37:18833 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:13834 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43835 HttpResponseInfo info;
836 info.headers = new HttpResponseHeaders("");
[email protected]2431756e2010-09-29 20:26:13837 handle.set_ssl_error_response_info(info);
838 EXPECT_EQ(ERR_CONNECTION_FAILED,
839 handle.Init("a",
840 params_,
841 kDefaultPriority,
842 &callback,
843 pool_.get(),
844 log.bound()));
845 EXPECT_FALSE(handle.socket());
846 EXPECT_FALSE(handle.is_ssl_error());
847 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:30848
[email protected]b2fcd0e2010-12-01 15:19:40849 net::CapturingNetLog::EntryList entries;
850 log.GetEntries(&entries);
851
852 EXPECT_EQ(3u, entries.size());
[email protected]5a1d7ca2010-04-28 20:12:27853 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40854 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:17855 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40856 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:17857 NetLog::PHASE_NONE));
[email protected]a2006ece2010-04-23 16:44:02858 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40859 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09860}
861
[email protected]211d21722009-07-22 15:48:53862TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
863 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
864
[email protected]9e743cd2010-03-16 07:03:53865 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30866
[email protected]211d21722009-07-22 15:48:53867 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
868 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
869 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
870 EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
871
[email protected]2431756e2010-09-29 20:26:13872 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53873 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13874 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53875
876 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
877 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
878 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
879
[email protected]2431756e2010-09-29 20:26:13880 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53881
[email protected]2431756e2010-09-29 20:26:13882 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53883 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13884 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53885
886 EXPECT_EQ(1, GetOrderOfRequest(1));
887 EXPECT_EQ(2, GetOrderOfRequest(2));
888 EXPECT_EQ(3, GetOrderOfRequest(3));
889 EXPECT_EQ(4, GetOrderOfRequest(4));
890 EXPECT_EQ(5, GetOrderOfRequest(5));
891 EXPECT_EQ(6, GetOrderOfRequest(6));
892 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17893
894 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13895 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53896}
897
898TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
899 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
900
[email protected]9e743cd2010-03-16 07:03:53901 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30902
[email protected]211d21722009-07-22 15:48:53903 // Reach all limits: max total sockets, and max sockets per group.
904 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
905 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
906 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
907 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
908
[email protected]2431756e2010-09-29 20:26:13909 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53910 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13911 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53912
913 // Now create a new group and verify that we don't starve it.
914 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
915
[email protected]2431756e2010-09-29 20:26:13916 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53917
[email protected]2431756e2010-09-29 20:26:13918 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53919 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13920 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53921
922 EXPECT_EQ(1, GetOrderOfRequest(1));
923 EXPECT_EQ(2, GetOrderOfRequest(2));
924 EXPECT_EQ(3, GetOrderOfRequest(3));
925 EXPECT_EQ(4, GetOrderOfRequest(4));
926 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17927
928 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13929 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53930}
931
932TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
933 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
934
[email protected]ac790b42009-12-02 04:31:31935 EXPECT_EQ(OK, StartRequest("b", LOWEST));
936 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
937 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
938 EXPECT_EQ(OK, StartRequest("a", LOWEST));
[email protected]211d21722009-07-22 15:48:53939
[email protected]2431756e2010-09-29 20:26:13940 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53941 client_socket_factory_.allocation_count());
942
[email protected]ac790b42009-12-02 04:31:31943 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
944 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
945 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53946
[email protected]2431756e2010-09-29 20:26:13947 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53948
[email protected]2431756e2010-09-29 20:26:13949 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53950
951 // First 4 requests don't have to wait, and finish in order.
952 EXPECT_EQ(1, GetOrderOfRequest(1));
953 EXPECT_EQ(2, GetOrderOfRequest(2));
954 EXPECT_EQ(3, GetOrderOfRequest(3));
955 EXPECT_EQ(4, GetOrderOfRequest(4));
956
[email protected]ac790b42009-12-02 04:31:31957 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
958 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53959 EXPECT_EQ(7, GetOrderOfRequest(5));
960 EXPECT_EQ(6, GetOrderOfRequest(6));
961 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17962
963 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13964 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]211d21722009-07-22 15:48:53965}
966
967TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
968 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
969
[email protected]ac790b42009-12-02 04:31:31970 EXPECT_EQ(OK, StartRequest("a", LOWEST));
971 EXPECT_EQ(OK, StartRequest("a", LOW));
972 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
973 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
[email protected]211d21722009-07-22 15:48:53974
[email protected]2431756e2010-09-29 20:26:13975 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53976 client_socket_factory_.allocation_count());
977
[email protected]ac790b42009-12-02 04:31:31978 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
979 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
980 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53981
[email protected]2431756e2010-09-29 20:26:13982 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53983
[email protected]2431756e2010-09-29 20:26:13984 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53985 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13986 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53987
988 // First 4 requests don't have to wait, and finish in order.
989 EXPECT_EQ(1, GetOrderOfRequest(1));
990 EXPECT_EQ(2, GetOrderOfRequest(2));
991 EXPECT_EQ(3, GetOrderOfRequest(3));
992 EXPECT_EQ(4, GetOrderOfRequest(4));
993
994 // Request ("b", 7) has the highest priority, but we can't make new socket for
995 // group "b", because it has reached the per-group limit. Then we make
996 // socket for ("c", 6), because it has higher priority than ("a", 4),
997 // and we still can't make a socket for group "b".
998 EXPECT_EQ(5, GetOrderOfRequest(5));
999 EXPECT_EQ(6, GetOrderOfRequest(6));
1000 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171001
1002 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131003 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:531004}
1005
1006// Make sure that we count connecting sockets against the total limit.
1007TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
1008 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1009
1010 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1011 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1012 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
1013
1014 // Create one asynchronous request.
1015 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1016 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
1017
[email protected]6b175382009-10-13 06:47:471018 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1019 // actually become pending until 2ms after they have been created. In order
1020 // to flush all tasks, we need to wait so that we know there are no
1021 // soon-to-be-pending tasks waiting.
[email protected]f214f8792011-01-01 02:17:081022 base::PlatformThread::Sleep(10);
[email protected]6b175382009-10-13 06:47:471023 MessageLoop::current()->RunAllPending();
1024
[email protected]211d21722009-07-22 15:48:531025 // The next synchronous request should wait for its turn.
1026 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1027 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
1028
[email protected]2431756e2010-09-29 20:26:131029 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531030
[email protected]2431756e2010-09-29 20:26:131031 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531032 client_socket_factory_.allocation_count());
1033
1034 EXPECT_EQ(1, GetOrderOfRequest(1));
1035 EXPECT_EQ(2, GetOrderOfRequest(2));
1036 EXPECT_EQ(3, GetOrderOfRequest(3));
1037 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:171038 EXPECT_EQ(5, GetOrderOfRequest(5));
1039
1040 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131041 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:531042}
1043
[email protected]6427fe22010-04-16 22:27:411044TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
1045 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1046 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1047
1048 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1049 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1050 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1051 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1052
1053 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1054
1055 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1056
1057 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", kDefaultPriority));
1058 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
1059
1060 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1061
[email protected]2431756e2010-09-29 20:26:131062 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411063 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131064 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411065 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131066 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1067 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411068 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
1069}
1070
[email protected]d7027bb2010-05-10 18:58:541071TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
1072 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1073 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1074
1075 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101076 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131077 EXPECT_EQ(ERR_IO_PENDING,
1078 handle.Init("a",
1079 params_,
1080 kDefaultPriority,
1081 &callback,
1082 pool_.get(),
1083 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541084
1085 ClientSocketHandle handles[4];
1086 for (size_t i = 0; i < arraysize(handles); ++i) {
[email protected]f1f3f0f82011-10-01 20:38:101087 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131088 EXPECT_EQ(ERR_IO_PENDING,
1089 handles[i].Init("b",
1090 params_,
1091 kDefaultPriority,
1092 &callback,
1093 pool_.get(),
1094 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541095 }
1096
1097 // One will be stalled, cancel all the handles now.
1098 // This should hit the OnAvailableSocketSlot() code where we previously had
1099 // stalled groups, but no longer have any.
1100 for (size_t i = 0; i < arraysize(handles); ++i)
1101 handles[i].Reset();
1102}
1103
[email protected]eb5a99382010-07-11 03:18:261104TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:541105 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1106 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1107
[email protected]eb5a99382010-07-11 03:18:261108 {
1109 ClientSocketHandle handles[kDefaultMaxSockets];
[email protected]f1f3f0f82011-10-01 20:38:101110 TestOldCompletionCallback callbacks[kDefaultMaxSockets];
[email protected]eb5a99382010-07-11 03:18:261111 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]2431756e2010-09-29 20:26:131112 EXPECT_EQ(OK, handles[i].Init(base::IntToString(i),
1113 params_,
[email protected]e83326f2010-07-31 17:29:251114 kDefaultPriority,
[email protected]2431756e2010-09-29 20:26:131115 &callbacks[i],
1116 pool_.get(),
1117 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261118 }
1119
1120 // Force a stalled group.
1121 ClientSocketHandle stalled_handle;
[email protected]f1f3f0f82011-10-01 20:38:101122 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131123 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1124 params_,
1125 kDefaultPriority,
1126 &callback,
1127 pool_.get(),
1128 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261129
1130 // Cancel the stalled request.
1131 stalled_handle.Reset();
1132
1133 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1134 EXPECT_EQ(0, pool_->IdleSocketCount());
1135
1136 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541137 }
1138
[email protected]43a21b82010-06-10 21:30:541139 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1140 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:261141}
[email protected]43a21b82010-06-10 21:30:541142
[email protected]eb5a99382010-07-11 03:18:261143TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
1144 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1145 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1146
1147 {
1148 ClientSocketHandle handles[kDefaultMaxSockets];
1149 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]f1f3f0f82011-10-01 20:38:101150 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131151 EXPECT_EQ(ERR_IO_PENDING, handles[i].Init(base::IntToString(i),
1152 params_,
1153 kDefaultPriority,
1154 &callback,
1155 pool_.get(),
1156 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261157 }
1158
1159 // Force a stalled group.
1160 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1161 ClientSocketHandle stalled_handle;
[email protected]f1f3f0f82011-10-01 20:38:101162 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131163 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1164 params_,
1165 kDefaultPriority,
1166 &callback,
1167 pool_.get(),
1168 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261169
1170 // Since it is stalled, it should have no connect jobs.
1171 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
1172
1173 // Cancel the stalled request.
1174 handles[0].Reset();
1175
[email protected]eb5a99382010-07-11 03:18:261176 // Now we should have a connect job.
1177 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("foo"));
1178
1179 // The stalled socket should connect.
1180 EXPECT_EQ(OK, callback.WaitForResult());
1181
1182 EXPECT_EQ(kDefaultMaxSockets + 1,
1183 client_socket_factory_.allocation_count());
1184 EXPECT_EQ(0, pool_->IdleSocketCount());
1185 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
1186
1187 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541188 }
1189
[email protected]eb5a99382010-07-11 03:18:261190 EXPECT_EQ(1, pool_->IdleSocketCount());
1191}
[email protected]43a21b82010-06-10 21:30:541192
[email protected]eb5a99382010-07-11 03:18:261193TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1194 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1195 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:541196
[email protected]eb5a99382010-07-11 03:18:261197 ClientSocketHandle stalled_handle;
[email protected]f1f3f0f82011-10-01 20:38:101198 TestOldCompletionCallback callback;
[email protected]eb5a99382010-07-11 03:18:261199 {
[email protected]d4dfdab2011-12-07 16:56:591200 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261201 ClientSocketHandle handles[kDefaultMaxSockets];
1202 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]f1f3f0f82011-10-01 20:38:101203 TestOldCompletionCallback callback;
[email protected]1870d5cf2011-05-12 01:55:401204 EXPECT_EQ(OK, handles[i].Init(base::StringPrintf(
1205 "Take 2: %d", i),
1206 params_,
1207 kDefaultPriority,
1208 &callback,
1209 pool_.get(),
1210 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261211 }
1212
1213 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1214 EXPECT_EQ(0, pool_->IdleSocketCount());
[email protected]d4dfdab2011-12-07 16:56:591215 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261216
1217 // Now we will hit the socket limit.
[email protected]2431756e2010-09-29 20:26:131218 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1219 params_,
1220 kDefaultPriority,
1221 &callback,
1222 pool_.get(),
1223 BoundNetLog()));
[email protected]d4dfdab2011-12-07 16:56:591224 EXPECT_TRUE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261225
1226 // Dropping out of scope will close all handles and return them to idle.
1227 }
[email protected]43a21b82010-06-10 21:30:541228
1229 // But if we wait for it, the released idle sockets will be closed in
1230 // preference of the waiting request.
[email protected]8ae03f42010-07-07 19:08:101231 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]eb5a99382010-07-11 03:18:261232
1233 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1234 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:541235}
1236
1237// Regression test for http://crbug.com/40952.
1238TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1239 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]06d94042010-08-25 01:45:221240 pool_->EnableConnectBackupJobs();
[email protected]43a21b82010-06-10 21:30:541241 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1242
1243 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1244 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101245 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131246 EXPECT_EQ(OK, handle.Init(base::IntToString(i),
1247 params_,
1248 kDefaultPriority,
1249 &callback,
1250 pool_.get(),
1251 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541252 }
1253
1254 // Flush all the DoReleaseSocket tasks.
1255 MessageLoop::current()->RunAllPending();
1256
1257 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1258 // reuse a socket.
1259 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1260 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101261 TestOldCompletionCallback callback;
[email protected]43a21b82010-06-10 21:30:541262
1263 // "0" is special here, since it should be the first entry in the sorted map,
1264 // which is the one which we would close an idle socket for. We shouldn't
1265 // close an idle socket though, since we should reuse the idle socket.
[email protected]2431756e2010-09-29 20:26:131266 EXPECT_EQ(OK, handle.Init("0",
1267 params_,
1268 kDefaultPriority,
1269 &callback,
1270 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211271 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541272
1273 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1274 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1275}
1276
[email protected]ab838892009-06-30 18:49:051277TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531278 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091279
[email protected]c9d6a1d2009-07-14 16:15:201280 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1281 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]c9c6f5c2010-07-31 01:30:031282 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", IDLE));
[email protected]ac790b42009-12-02 04:31:311283 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1284 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1285 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1286 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1287 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091288
[email protected]2431756e2010-09-29 20:26:131289 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091290
[email protected]c9d6a1d2009-07-14 16:15:201291 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1292 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131293 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1294 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091295
[email protected]c9d6a1d2009-07-14 16:15:201296 EXPECT_EQ(1, GetOrderOfRequest(1));
1297 EXPECT_EQ(2, GetOrderOfRequest(2));
[email protected]c9c6f5c2010-07-31 01:30:031298 EXPECT_EQ(8, GetOrderOfRequest(3));
1299 EXPECT_EQ(6, GetOrderOfRequest(4));
1300 EXPECT_EQ(4, GetOrderOfRequest(5));
1301 EXPECT_EQ(3, GetOrderOfRequest(6));
1302 EXPECT_EQ(5, GetOrderOfRequest(7));
1303 EXPECT_EQ(7, GetOrderOfRequest(8));
[email protected]75439d3b2009-07-23 22:11:171304
1305 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131306 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]f6d1d6eb2009-06-24 20:16:091307}
1308
[email protected]ab838892009-06-30 18:49:051309TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531310 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091311
[email protected]c9d6a1d2009-07-14 16:15:201312 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1313 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311314 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1315 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1316 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1317 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1318 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091319
[email protected]2431756e2010-09-29 20:26:131320 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091321
[email protected]2431756e2010-09-29 20:26:131322 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
1323 EXPECT_EQ(OK, request(i)->WaitForResult());
[email protected]c9d6a1d2009-07-14 16:15:201324
[email protected]2431756e2010-09-29 20:26:131325 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]c9d6a1d2009-07-14 16:15:201326 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131327 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1328 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091329}
1330
1331// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:051332// The pending connect job will be cancelled and should not call back into
1333// ClientSocketPoolBase.
1334TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531335 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201336
[email protected]ab838892009-06-30 18:49:051337 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131338 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101339 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131340 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1341 params_,
1342 kDefaultPriority,
1343 &callback,
1344 pool_.get(),
1345 BoundNetLog()));
1346 handle.Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091347}
1348
[email protected]ab838892009-06-30 18:49:051349TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531350 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201351
[email protected]ab838892009-06-30 18:49:051352 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061353 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101354 TestOldCompletionCallback callback;
[email protected]f6d1d6eb2009-06-24 20:16:091355
[email protected]2431756e2010-09-29 20:26:131356 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1357 params_,
1358 kDefaultPriority,
1359 &callback,
1360 pool_.get(),
1361 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091362
1363 handle.Reset();
1364
[email protected]f1f3f0f82011-10-01 20:38:101365 TestOldCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:131366 EXPECT_EQ(ERR_IO_PENDING,
1367 handle.Init("a",
1368 params_,
1369 kDefaultPriority,
1370 &callback2,
1371 pool_.get(),
1372 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091373
1374 EXPECT_EQ(OK, callback2.WaitForResult());
1375 EXPECT_FALSE(callback.have_result());
1376
1377 handle.Reset();
1378}
1379
[email protected]ab838892009-06-30 18:49:051380TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531381 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091382
[email protected]c9d6a1d2009-07-14 16:15:201383 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1384 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311385 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1386 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1387 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1388 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1389 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091390
1391 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201392 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]2431756e2010-09-29 20:26:131393 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1394 (*requests())[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091395
[email protected]2431756e2010-09-29 20:26:131396 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091397
[email protected]c9d6a1d2009-07-14 16:15:201398 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1399 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131400 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1401 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091402
[email protected]c9d6a1d2009-07-14 16:15:201403 EXPECT_EQ(1, GetOrderOfRequest(1));
1404 EXPECT_EQ(2, GetOrderOfRequest(2));
1405 EXPECT_EQ(5, GetOrderOfRequest(3));
1406 EXPECT_EQ(3, GetOrderOfRequest(4));
[email protected]2431756e2010-09-29 20:26:131407 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1408 GetOrderOfRequest(5)); // Canceled request.
[email protected]c9d6a1d2009-07-14 16:15:201409 EXPECT_EQ(4, GetOrderOfRequest(6));
1410 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171411
1412 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131413 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091414}
1415
1416class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
1417 public:
[email protected]2ab05b52009-07-01 23:57:581418 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:241419 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:581420 TestConnectJobFactory* test_connect_job_factory,
1421 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:091422 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:061423 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:581424 within_callback_(false),
1425 test_connect_job_factory_(test_connect_job_factory),
1426 next_job_type_(next_job_type) {}
[email protected]f6d1d6eb2009-06-24 20:16:091427
1428 virtual void RunWithParams(const Tuple1<int>& params) {
1429 callback_.RunWithParams(params);
1430 ASSERT_EQ(OK, params.a);
1431
1432 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:581433 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]5edbf8d2010-01-13 18:44:111434
1435 // Don't allow reuse of the socket. Disconnect it and then release it and
1436 // run through the MessageLoop once to get it completely released.
1437 handle_->socket()->Disconnect();
[email protected]f6d1d6eb2009-06-24 20:16:091438 handle_->Reset();
[email protected]5edbf8d2010-01-13 18:44:111439 {
1440 MessageLoop::ScopedNestableTaskAllower nestable(
1441 MessageLoop::current());
1442 MessageLoop::current()->RunAllPending();
1443 }
[email protected]f6d1d6eb2009-06-24 20:16:091444 within_callback_ = true;
[email protected]f1f3f0f82011-10-01 20:38:101445 TestOldCompletionCallback next_job_callback;
[email protected]ad8e04a2010-11-01 04:16:271446 scoped_refptr<TestSocketParams> params(new TestSocketParams());
[email protected]2431756e2010-09-29 20:26:131447 int rv = handle_->Init("a",
1448 params,
1449 kDefaultPriority,
1450 &next_job_callback,
1451 pool_,
1452 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581453 switch (next_job_type_) {
1454 case TestConnectJob::kMockJob:
1455 EXPECT_EQ(OK, rv);
1456 break;
1457 case TestConnectJob::kMockPendingJob:
1458 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:471459
1460 // For pending jobs, wait for new socket to be created. This makes
1461 // sure there are no more pending operations nor any unclosed sockets
1462 // when the test finishes.
1463 // We need to give it a little bit of time to run, so that all the
1464 // operations that happen on timers (e.g. cleanup of idle
1465 // connections) can execute.
[email protected]5edbf8d2010-01-13 18:44:111466 {
1467 MessageLoop::ScopedNestableTaskAllower nestable(
1468 MessageLoop::current());
[email protected]f214f8792011-01-01 02:17:081469 base::PlatformThread::Sleep(10);
[email protected]5edbf8d2010-01-13 18:44:111470 EXPECT_EQ(OK, next_job_callback.WaitForResult());
1471 }
[email protected]2ab05b52009-07-01 23:57:581472 break;
1473 default:
1474 FAIL() << "Unexpected job type: " << next_job_type_;
1475 break;
1476 }
[email protected]f6d1d6eb2009-06-24 20:16:091477 }
1478 }
1479
1480 int WaitForResult() {
1481 return callback_.WaitForResult();
1482 }
1483
1484 private:
1485 ClientSocketHandle* const handle_;
[email protected]2431756e2010-09-29 20:26:131486 TestClientSocketPool* const pool_;
[email protected]f6d1d6eb2009-06-24 20:16:091487 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:581488 TestConnectJobFactory* const test_connect_job_factory_;
1489 TestConnectJob::JobType next_job_type_;
[email protected]f1f3f0f82011-10-01 20:38:101490 TestOldCompletionCallback callback_;
[email protected]f6d1d6eb2009-06-24 20:16:091491};
1492
[email protected]2ab05b52009-07-01 23:57:581493TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531494 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201495
[email protected]0b7648c2009-07-06 20:14:011496 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061497 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581498 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061499 &handle, pool_.get(), connect_job_factory_,
1500 TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131501 int rv = handle.Init("a",
1502 params_,
1503 kDefaultPriority,
1504 &callback,
1505 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211506 BoundNetLog());
[email protected]f6d1d6eb2009-06-24 20:16:091507 ASSERT_EQ(ERR_IO_PENDING, rv);
1508
1509 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581510}
[email protected]f6d1d6eb2009-06-24 20:16:091511
[email protected]2ab05b52009-07-01 23:57:581512TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531513 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201514
[email protected]0b7648c2009-07-06 20:14:011515 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061516 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581517 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061518 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]2431756e2010-09-29 20:26:131519 int rv = handle.Init("a",
1520 params_,
1521 kDefaultPriority,
1522 &callback,
1523 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211524 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581525 ASSERT_EQ(ERR_IO_PENDING, rv);
1526
1527 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091528}
1529
1530// Make sure that pending requests get serviced after active requests get
1531// cancelled.
[email protected]ab838892009-06-30 18:49:051532TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531533 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201534
[email protected]0b7648c2009-07-06 20:14:011535 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091536
[email protected]c9d6a1d2009-07-14 16:15:201537 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1538 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1539 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1540 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1541 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1542 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1543 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091544
[email protected]c9d6a1d2009-07-14 16:15:201545 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1546 // Let's cancel them.
1547 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]2431756e2010-09-29 20:26:131548 ASSERT_FALSE(request(i)->handle()->is_initialized());
1549 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091550 }
1551
[email protected]f6d1d6eb2009-06-24 20:16:091552 // Let's wait for the rest to complete now.
[email protected]2431756e2010-09-29 20:26:131553 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
1554 EXPECT_EQ(OK, request(i)->WaitForResult());
1555 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091556 }
1557
[email protected]2431756e2010-09-29 20:26:131558 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1559 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091560}
1561
1562// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051563TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531564 const size_t kMaxSockets = 5;
1565 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201566
[email protected]0b7648c2009-07-06 20:14:011567 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091568
[email protected]211d21722009-07-22 15:48:531569 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1570 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091571
1572 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531573 for (size_t i = 0; i < kNumberOfRequests; ++i)
1574 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091575
[email protected]211d21722009-07-22 15:48:531576 for (size_t i = 0; i < kNumberOfRequests; ++i)
[email protected]2431756e2010-09-29 20:26:131577 EXPECT_EQ(ERR_CONNECTION_FAILED, request(i)->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091578}
1579
[email protected]5fc08e32009-07-15 17:09:571580TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531581 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571582
1583 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1584
[email protected]2431756e2010-09-29 20:26:131585 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101586 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131587 int rv = handle.Init("a",
1588 params_,
1589 kDefaultPriority,
1590 &callback,
1591 pool_.get(),
1592 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571593 EXPECT_EQ(ERR_IO_PENDING, rv);
1594
1595 // Cancel the active request.
[email protected]2431756e2010-09-29 20:26:131596 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571597
[email protected]2431756e2010-09-29 20:26:131598 rv = handle.Init("a",
1599 params_,
1600 kDefaultPriority,
1601 &callback,
1602 pool_.get(),
1603 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571604 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131605 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]5fc08e32009-07-15 17:09:571606
[email protected]2431756e2010-09-29 20:26:131607 EXPECT_FALSE(handle.is_reused());
[email protected]5fc08e32009-07-15 17:09:571608 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1609}
1610
[email protected]2b7523d2009-07-29 20:29:231611// Regression test for http://crbug.com/17985.
1612TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1613 const int kMaxSockets = 3;
1614 const int kMaxSocketsPerGroup = 2;
1615 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1616
[email protected]ac790b42009-12-02 04:31:311617 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231618
1619 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1620 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1621
1622 // This is going to be a pending request in an otherwise empty group.
1623 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1624
1625 // Reach the maximum socket limit.
1626 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1627
1628 // Create a stalled group with high priorities.
1629 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1630 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
[email protected]2b7523d2009-07-29 20:29:231631
[email protected]eb5a99382010-07-11 03:18:261632 // Release the first two sockets from "a". Because this is a keepalive,
1633 // the first release will unblock the pending request for "a". The
1634 // second release will unblock a request for "c", becaue it is the next
1635 // high priority socket.
[email protected]2431756e2010-09-29 20:26:131636 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1637 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]2b7523d2009-07-29 20:29:231638
1639 // Closing idle sockets should not get us into trouble, but in the bug
1640 // we were hitting a CHECK here.
[email protected]93054cc12010-06-08 06:12:411641 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]43a21b82010-06-10 21:30:541642 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261643
1644 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]2b7523d2009-07-29 20:29:231645}
1646
[email protected]4d3b05d2010-01-27 21:27:291647TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531648 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571649
1650 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131651 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101652 TestOldCompletionCallback callback;
[email protected]9e743cd2010-03-16 07:03:531653 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:131654 int rv = handle.Init("a",
1655 params_,
1656 LOWEST,
1657 &callback,
1658 pool_.get(),
1659 log.bound());
[email protected]5fc08e32009-07-15 17:09:571660 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131661 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1662 EXPECT_EQ(OK, callback.WaitForResult());
1663 EXPECT_TRUE(handle.is_initialized());
1664 EXPECT_TRUE(handle.socket());
1665 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:301666
[email protected]b2fcd0e2010-12-01 15:19:401667 net::CapturingNetLog::EntryList entries;
1668 log.GetEntries(&entries);
1669
1670 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:461671 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401672 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171673 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401674 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171675 NetLog::PHASE_NONE));
1676 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401677 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]06650c52010-06-03 00:49:171678 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:461679 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401680 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571681}
1682
[email protected]4d3b05d2010-01-27 21:27:291683TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571684 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531685 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571686
1687 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2431756e2010-09-29 20:26:131688 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101689 TestOldCompletionCallback callback;
[email protected]9e743cd2010-03-16 07:03:531690 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]e60e47a2010-07-14 03:37:181691 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:131692 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:431693 HttpResponseInfo info;
1694 info.headers = new HttpResponseHeaders("");
[email protected]2431756e2010-09-29 20:26:131695 handle.set_ssl_error_response_info(info);
1696 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1697 params_,
1698 kDefaultPriority,
1699 &callback,
1700 pool_.get(),
1701 log.bound()));
1702 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1703 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1704 EXPECT_FALSE(handle.is_ssl_error());
1705 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:301706
[email protected]b2fcd0e2010-12-01 15:19:401707 net::CapturingNetLog::EntryList entries;
1708 log.GetEntries(&entries);
1709
1710 EXPECT_EQ(3u, entries.size());
[email protected]e9002a92010-01-29 07:10:461711 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401712 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171713 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401714 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171715 NetLog::PHASE_NONE));
[email protected]6b624c62010-03-14 08:37:321716 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401717 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571718}
1719
[email protected]4d3b05d2010-01-27 21:27:291720TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101721 // TODO(eroman): Add back the log expectations! Removed them because the
1722 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531723 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571724
1725 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131726 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101727 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131728 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:101729 TestOldCompletionCallback callback2;
[email protected]5fc08e32009-07-15 17:09:571730
[email protected]2431756e2010-09-29 20:26:131731 EXPECT_EQ(ERR_IO_PENDING,
1732 handle.Init("a",
1733 params_,
1734 kDefaultPriority,
1735 &callback,
1736 pool_.get(),
1737 BoundNetLog()));
[email protected]9e743cd2010-03-16 07:03:531738 CapturingBoundNetLog log2(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:131739 EXPECT_EQ(ERR_IO_PENDING,
1740 handle2.Init("a",
1741 params_,
1742 kDefaultPriority,
1743 &callback2,
1744 pool_.get(),
1745 BoundNetLog()));
[email protected]5fc08e32009-07-15 17:09:571746
[email protected]2431756e2010-09-29 20:26:131747 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571748
[email protected]fd7b7c92009-08-20 19:38:301749
1750 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301751
[email protected]2431756e2010-09-29 20:26:131752 EXPECT_EQ(OK, callback2.WaitForResult());
1753 handle2.Reset();
[email protected]fd7b7c92009-08-20 19:38:301754
1755 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531756 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571757}
1758
[email protected]4d3b05d2010-01-27 21:27:291759TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341760 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1761
[email protected]17a0c6c2009-08-04 00:07:041762 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1763
[email protected]ac790b42009-12-02 04:31:311764 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1765 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1766 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1767 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341768
1769 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]2431756e2010-09-29 20:26:131770 (*requests())[2]->handle()->Reset();
1771 (*requests())[3]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341772 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1773
[email protected]2431756e2010-09-29 20:26:131774 (*requests())[1]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341775 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1776
[email protected]2431756e2010-09-29 20:26:131777 (*requests())[0]->handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261778 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]974ebd62009-08-03 23:14:341779}
1780
[email protected]5fc08e32009-07-15 17:09:571781// When requests and ConnectJobs are not coupled, the request will get serviced
1782// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291783TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531784 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571785
1786 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321787 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571788
[email protected]2431756e2010-09-29 20:26:131789 std::vector<TestSocketRequest*> request_order;
1790 size_t completion_count; // unused
1791 TestSocketRequest req1(&request_order, &completion_count);
1792 int rv = req1.handle()->Init("a",
1793 params_,
1794 kDefaultPriority,
1795 &req1, pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211796 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571797 EXPECT_EQ(ERR_IO_PENDING, rv);
1798 EXPECT_EQ(OK, req1.WaitForResult());
1799
1800 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1801 // without a job.
1802 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1803
[email protected]2431756e2010-09-29 20:26:131804 TestSocketRequest req2(&request_order, &completion_count);
1805 rv = req2.handle()->Init("a",
1806 params_,
1807 kDefaultPriority,
1808 &req2,
1809 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211810 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571811 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131812 TestSocketRequest req3(&request_order, &completion_count);
1813 rv = req3.handle()->Init("a",
1814 params_,
1815 kDefaultPriority,
1816 &req3,
1817 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211818 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571819 EXPECT_EQ(ERR_IO_PENDING, rv);
1820
1821 // Both Requests 2 and 3 are pending. We release socket 1 which should
1822 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331823 req1.handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261824 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]a6c59f62009-07-29 16:33:331825 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571826 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331827 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571828
1829 // Signal job 2, which should service request 3.
1830
1831 client_socket_factory_.SignalJobs();
1832 EXPECT_EQ(OK, req3.WaitForResult());
1833
[email protected]2431756e2010-09-29 20:26:131834 ASSERT_EQ(3U, request_order.size());
1835 EXPECT_EQ(&req1, request_order[0]);
1836 EXPECT_EQ(&req2, request_order[1]);
1837 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571838 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1839}
1840
1841// The requests are not coupled to the jobs. So, the requests should finish in
1842// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:291843TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531844 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571845 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321846 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571847
[email protected]2431756e2010-09-29 20:26:131848 std::vector<TestSocketRequest*> request_order;
1849 size_t completion_count; // unused
1850 TestSocketRequest req1(&request_order, &completion_count);
1851 int rv = req1.handle()->Init("a",
1852 params_,
1853 kDefaultPriority,
1854 &req1,
1855 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211856 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571857 EXPECT_EQ(ERR_IO_PENDING, rv);
1858
[email protected]2431756e2010-09-29 20:26:131859 TestSocketRequest req2(&request_order, &completion_count);
1860 rv = req2.handle()->Init("a",
1861 params_,
1862 kDefaultPriority,
1863 &req2,
1864 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211865 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571866 EXPECT_EQ(ERR_IO_PENDING, rv);
1867
1868 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321869 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571870
[email protected]2431756e2010-09-29 20:26:131871 TestSocketRequest req3(&request_order, &completion_count);
1872 rv = req3.handle()->Init("a",
1873 params_,
1874 kDefaultPriority,
1875 &req3,
1876 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211877 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571878 EXPECT_EQ(ERR_IO_PENDING, rv);
1879
1880 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1881 EXPECT_EQ(OK, req2.WaitForResult());
1882 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1883
[email protected]2431756e2010-09-29 20:26:131884 ASSERT_EQ(3U, request_order.size());
1885 EXPECT_EQ(&req1, request_order[0]);
1886 EXPECT_EQ(&req2, request_order[1]);
1887 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571888}
1889
[email protected]e6ec67b2010-06-16 00:12:461890TEST_F(ClientSocketPoolBaseTest, LoadState) {
[email protected]211d21722009-07-22 15:48:531891 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571892 connect_job_factory_->set_job_type(
[email protected]b59ff372009-07-15 22:04:321893 TestConnectJob::kMockAdvancingLoadStateJob);
[email protected]5fc08e32009-07-15 17:09:571894
[email protected]2431756e2010-09-29 20:26:131895 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101896 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131897 int rv = handle.Init("a",
1898 params_,
1899 kDefaultPriority,
1900 &callback,
1901 pool_.get(),
1902 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571903 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131904 EXPECT_EQ(LOAD_STATE_IDLE, handle.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571905
1906 MessageLoop::current()->RunAllPending();
1907
[email protected]2431756e2010-09-29 20:26:131908 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:101909 TestOldCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:131910 rv = handle2.Init("a",
1911 params_,
1912 kDefaultPriority,
1913 &callback2, pool_.get(),
1914 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571915 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131916 EXPECT_NE(LOAD_STATE_IDLE, handle.GetLoadState());
1917 EXPECT_NE(LOAD_STATE_IDLE, handle2.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571918}
1919
[email protected]e772db3f2010-07-12 18:11:131920TEST_F(ClientSocketPoolBaseTest, Recoverable) {
1921 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1922 connect_job_factory_->set_job_type(TestConnectJob::kMockRecoverableJob);
1923
[email protected]2431756e2010-09-29 20:26:131924 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101925 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131926 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, handle.Init("a",
1927 params_,
1928 kDefaultPriority,
1929 &callback, pool_.get(),
1930 BoundNetLog()));
1931 EXPECT_TRUE(handle.is_initialized());
1932 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:131933}
1934
1935TEST_F(ClientSocketPoolBaseTest, AsyncRecoverable) {
1936 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1937
1938 connect_job_factory_->set_job_type(
1939 TestConnectJob::kMockPendingRecoverableJob);
[email protected]2431756e2010-09-29 20:26:131940 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101941 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131942 EXPECT_EQ(ERR_IO_PENDING,
1943 handle.Init("a",
1944 params_,
1945 kDefaultPriority,
1946 &callback,
1947 pool_.get(),
1948 BoundNetLog()));
1949 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1950 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, callback.WaitForResult());
1951 EXPECT_TRUE(handle.is_initialized());
1952 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:131953}
1954
[email protected]e60e47a2010-07-14 03:37:181955TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
1956 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1957 connect_job_factory_->set_job_type(
1958 TestConnectJob::kMockAdditionalErrorStateJob);
1959
[email protected]2431756e2010-09-29 20:26:131960 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101961 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131962 EXPECT_EQ(ERR_CONNECTION_FAILED,
1963 handle.Init("a",
1964 params_,
1965 kDefaultPriority,
1966 &callback,
1967 pool_.get(),
1968 BoundNetLog()));
1969 EXPECT_FALSE(handle.is_initialized());
1970 EXPECT_FALSE(handle.socket());
1971 EXPECT_TRUE(handle.is_ssl_error());
1972 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181973}
1974
1975TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
1976 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1977
1978 connect_job_factory_->set_job_type(
1979 TestConnectJob::kMockPendingAdditionalErrorStateJob);
[email protected]2431756e2010-09-29 20:26:131980 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101981 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131982 EXPECT_EQ(ERR_IO_PENDING,
1983 handle.Init("a",
1984 params_,
1985 kDefaultPriority,
1986 &callback,
1987 pool_.get(),
1988 BoundNetLog()));
1989 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1990 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1991 EXPECT_FALSE(handle.is_initialized());
1992 EXPECT_FALSE(handle.socket());
1993 EXPECT_TRUE(handle.is_ssl_error());
1994 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181995}
1996
[email protected]64770b7d2011-11-16 04:30:411997TEST_F(ClientSocketPoolBaseTest, DisableCleanupTimer) {
1998 // Disable cleanup timer.
1999 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(false);
2000
2001 CreatePoolWithIdleTimeouts(
2002 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2003 base::TimeDelta::FromMilliseconds(10), // Time out unused sockets
2004 base::TimeDelta::FromMilliseconds(10)); // Time out used sockets
2005
2006 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2007
2008 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2009
2010 ClientSocketHandle handle;
2011 TestOldCompletionCallback callback;
2012 int rv = handle.Init("a",
2013 params_,
2014 LOWEST,
2015 &callback,
2016 pool_.get(),
2017 BoundNetLog());
2018 EXPECT_EQ(ERR_IO_PENDING, rv);
2019 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2020
2021 ClientSocketHandle handle2;
2022 TestOldCompletionCallback callback2;
2023 rv = handle2.Init("a",
2024 params_,
2025 LOWEST,
2026 &callback2,
2027 pool_.get(),
2028 BoundNetLog());
2029 EXPECT_EQ(ERR_IO_PENDING, rv);
2030 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
2031
2032 // Cancel one of the requests. Wait for the other, which will get the first
2033 // job. Release the socket. Run the loop again to make sure the second
2034 // socket is sitting idle and the first one is released (since ReleaseSocket()
2035 // just posts a DoReleaseSocket() task).
2036
2037 handle.Reset();
2038 EXPECT_EQ(OK, callback2.WaitForResult());
2039 // Use the socket.
2040 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, NULL));
2041 handle2.Reset();
2042
[email protected]d4dfdab2011-12-07 16:56:592043 // The idle socket timeout value was set to 10 milliseconds. Wait 100
[email protected]64770b7d2011-11-16 04:30:412044 // milliseconds so the sockets timeout.
[email protected]d4dfdab2011-12-07 16:56:592045 base::PlatformThread::Sleep(100);
[email protected]64770b7d2011-11-16 04:30:412046 MessageLoop::current()->RunAllPending();
2047
2048 ASSERT_EQ(2, pool_->IdleSocketCount());
2049
2050 // Request a new socket. This should cleanup the unused and timed out ones.
2051 // A new socket will be created rather than reusing the idle one.
2052 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
2053 rv = handle.Init("a",
2054 params_,
2055 LOWEST,
2056 &callback,
2057 pool_.get(),
2058 log.bound());
2059 EXPECT_EQ(ERR_IO_PENDING, rv);
2060 EXPECT_EQ(OK, callback.WaitForResult());
2061 EXPECT_FALSE(handle.is_reused());
2062
2063 // Make sure the idle socket is closed
2064 ASSERT_TRUE(pool_->HasGroup("a"));
2065 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2066 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2067
2068 net::CapturingNetLog::EntryList entries;
2069 log.GetEntries(&entries);
2070 EXPECT_FALSE(LogContainsEntryWithType(
2071 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
2072}
2073
[email protected]4d3b05d2010-01-27 21:27:292074TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
[email protected]9bf28db2009-08-29 01:35:162075 CreatePoolWithIdleTimeouts(
2076 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2077 base::TimeDelta(), // Time out unused sockets immediately.
2078 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2079
2080 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2081
2082 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2083
[email protected]2431756e2010-09-29 20:26:132084 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:102085 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132086 int rv = handle.Init("a",
2087 params_,
2088 LOWEST,
2089 &callback,
2090 pool_.get(),
2091 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:162092 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:132093 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
[email protected]9bf28db2009-08-29 01:35:162094
[email protected]2431756e2010-09-29 20:26:132095 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:102096 TestOldCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132097 rv = handle2.Init("a",
2098 params_,
2099 LOWEST,
2100 &callback2,
2101 pool_.get(),
2102 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:162103 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:132104 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
[email protected]9bf28db2009-08-29 01:35:162105
2106 // Cancel one of the requests. Wait for the other, which will get the first
2107 // job. Release the socket. Run the loop again to make sure the second
2108 // socket is sitting idle and the first one is released (since ReleaseSocket()
2109 // just posts a DoReleaseSocket() task).
2110
[email protected]2431756e2010-09-29 20:26:132111 handle.Reset();
2112 EXPECT_EQ(OK, callback2.WaitForResult());
[email protected]0f873e82010-09-02 16:09:012113 // Use the socket.
[email protected]2431756e2010-09-29 20:26:132114 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, NULL));
2115 handle2.Reset();
[email protected]6b175382009-10-13 06:47:472116
2117 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2118 // actually become pending until 2ms after they have been created. In order
2119 // to flush all tasks, we need to wait so that we know there are no
2120 // soon-to-be-pending tasks waiting.
[email protected]f214f8792011-01-01 02:17:082121 base::PlatformThread::Sleep(10);
[email protected]9bf28db2009-08-29 01:35:162122 MessageLoop::current()->RunAllPending();
2123
2124 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:042125
[email protected]9bf28db2009-08-29 01:35:162126 // Invoke the idle socket cleanup check. Only one socket should be left, the
2127 // used socket. Request it to make sure that it's used.
2128
2129 pool_->CleanupTimedOutIdleSockets();
[email protected]9e743cd2010-03-16 07:03:532130 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:132131 rv = handle.Init("a",
2132 params_,
2133 LOWEST,
2134 &callback,
2135 pool_.get(),
2136 log.bound());
[email protected]9bf28db2009-08-29 01:35:162137 EXPECT_EQ(OK, rv);
[email protected]2431756e2010-09-29 20:26:132138 EXPECT_TRUE(handle.is_reused());
[email protected]b2fcd0e2010-12-01 15:19:402139
2140 net::CapturingNetLog::EntryList entries;
2141 log.GetEntries(&entries);
[email protected]fd4fe0b2010-02-08 23:02:152142 EXPECT_TRUE(LogContainsEntryWithType(
[email protected]b2fcd0e2010-12-01 15:19:402143 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]9bf28db2009-08-29 01:35:162144}
2145
[email protected]2041cf342010-02-19 03:15:592146// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:162147// because of multiple releasing disconnected sockets.
2148TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
2149 CreatePoolWithIdleTimeouts(
2150 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2151 base::TimeDelta(), // Time out unused sockets immediately.
2152 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2153
2154 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2155
2156 // Startup 4 connect jobs. Two of them will be pending.
2157
[email protected]2431756e2010-09-29 20:26:132158 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:102159 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132160 int rv = handle.Init("a",
2161 params_,
2162 LOWEST,
2163 &callback,
2164 pool_.get(),
2165 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162166 EXPECT_EQ(OK, rv);
2167
[email protected]2431756e2010-09-29 20:26:132168 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:102169 TestOldCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132170 rv = handle2.Init("a",
2171 params_,
2172 LOWEST,
2173 &callback2,
2174 pool_.get(),
2175 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162176 EXPECT_EQ(OK, rv);
2177
[email protected]2431756e2010-09-29 20:26:132178 ClientSocketHandle handle3;
[email protected]f1f3f0f82011-10-01 20:38:102179 TestOldCompletionCallback callback3;
[email protected]2431756e2010-09-29 20:26:132180 rv = handle3.Init("a",
2181 params_,
2182 LOWEST,
2183 &callback3,
2184 pool_.get(),
2185 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162186 EXPECT_EQ(ERR_IO_PENDING, rv);
2187
[email protected]2431756e2010-09-29 20:26:132188 ClientSocketHandle handle4;
[email protected]f1f3f0f82011-10-01 20:38:102189 TestOldCompletionCallback callback4;
[email protected]2431756e2010-09-29 20:26:132190 rv = handle4.Init("a",
2191 params_,
2192 LOWEST,
2193 &callback4,
2194 pool_.get(),
2195 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162196 EXPECT_EQ(ERR_IO_PENDING, rv);
2197
2198 // Release two disconnected sockets.
2199
[email protected]2431756e2010-09-29 20:26:132200 handle.socket()->Disconnect();
2201 handle.Reset();
2202 handle2.socket()->Disconnect();
2203 handle2.Reset();
[email protected]4f2abec2010-02-03 18:10:162204
[email protected]2431756e2010-09-29 20:26:132205 EXPECT_EQ(OK, callback3.WaitForResult());
2206 EXPECT_FALSE(handle3.is_reused());
2207 EXPECT_EQ(OK, callback4.WaitForResult());
2208 EXPECT_FALSE(handle4.is_reused());
[email protected]4f2abec2010-02-03 18:10:162209}
2210
[email protected]d7027bb2010-05-10 18:58:542211// Regression test for http://crbug.com/42267.
2212// When DoReleaseSocket() is processed for one socket, it is blocked because the
2213// other stalled groups all have releasing sockets, so no progress can be made.
2214TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
2215 CreatePoolWithIdleTimeouts(
2216 4 /* socket limit */, 4 /* socket limit per group */,
2217 base::TimeDelta(), // Time out unused sockets immediately.
2218 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2219
2220 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2221
2222 // Max out the socket limit with 2 per group.
2223
[email protected]2431756e2010-09-29 20:26:132224 ClientSocketHandle handle_a[4];
[email protected]f1f3f0f82011-10-01 20:38:102225 TestOldCompletionCallback callback_a[4];
[email protected]2431756e2010-09-29 20:26:132226 ClientSocketHandle handle_b[4];
[email protected]f1f3f0f82011-10-01 20:38:102227 TestOldCompletionCallback callback_b[4];
[email protected]d7027bb2010-05-10 18:58:542228
2229 for (int i = 0; i < 2; ++i) {
[email protected]2431756e2010-09-29 20:26:132230 EXPECT_EQ(OK, handle_a[i].Init("a",
2231 params_,
2232 LOWEST,
2233 &callback_a[i],
2234 pool_.get(),
2235 BoundNetLog()));
2236 EXPECT_EQ(OK, handle_b[i].Init("b",
2237 params_,
2238 LOWEST,
2239 &callback_b[i],
2240 pool_.get(),
2241 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542242 }
[email protected]b89f7e42010-05-20 20:37:002243
[email protected]d7027bb2010-05-10 18:58:542244 // Make 4 pending requests, 2 per group.
2245
2246 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132247 EXPECT_EQ(ERR_IO_PENDING,
2248 handle_a[i].Init("a",
2249 params_,
2250 LOWEST,
2251 &callback_a[i],
2252 pool_.get(),
2253 BoundNetLog()));
2254 EXPECT_EQ(ERR_IO_PENDING,
2255 handle_b[i].Init("b",
2256 params_,
2257 LOWEST,
2258 &callback_b[i],
2259 pool_.get(),
2260 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542261 }
2262
2263 // Release b's socket first. The order is important, because in
2264 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2265 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2266 // first, which has a releasing socket, so it refuses to start up another
2267 // ConnectJob. So, we used to infinite loop on this.
[email protected]2431756e2010-09-29 20:26:132268 handle_b[0].socket()->Disconnect();
2269 handle_b[0].Reset();
2270 handle_a[0].socket()->Disconnect();
2271 handle_a[0].Reset();
[email protected]d7027bb2010-05-10 18:58:542272
2273 // Used to get stuck here.
2274 MessageLoop::current()->RunAllPending();
2275
[email protected]2431756e2010-09-29 20:26:132276 handle_b[1].socket()->Disconnect();
2277 handle_b[1].Reset();
2278 handle_a[1].socket()->Disconnect();
2279 handle_a[1].Reset();
[email protected]d7027bb2010-05-10 18:58:542280
2281 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132282 EXPECT_EQ(OK, callback_b[i].WaitForResult());
2283 EXPECT_EQ(OK, callback_a[i].WaitForResult());
[email protected]d7027bb2010-05-10 18:58:542284 }
2285}
2286
[email protected]fd4fe0b2010-02-08 23:02:152287TEST_F(ClientSocketPoolBaseTest,
2288 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2289 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2290
2291 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2292
2293 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2294 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2295 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2296 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2297
[email protected]2431756e2010-09-29 20:26:132298 EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
2299 EXPECT_EQ(OK, (*requests())[1]->WaitForResult());
2300 EXPECT_EQ(2u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152301
2302 // Releases one connection.
[email protected]2431756e2010-09-29 20:26:132303 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2304 EXPECT_EQ(OK, (*requests())[2]->WaitForResult());
[email protected]fd4fe0b2010-02-08 23:02:152305
[email protected]2431756e2010-09-29 20:26:132306 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2307 EXPECT_EQ(OK, (*requests())[3]->WaitForResult());
2308 EXPECT_EQ(4u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152309
2310 EXPECT_EQ(1, GetOrderOfRequest(1));
2311 EXPECT_EQ(2, GetOrderOfRequest(2));
2312 EXPECT_EQ(3, GetOrderOfRequest(3));
2313 EXPECT_EQ(4, GetOrderOfRequest(4));
2314
2315 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:132316 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
[email protected]fd4fe0b2010-02-08 23:02:152317}
2318
[email protected]4f1e4982010-03-02 18:31:042319class TestReleasingSocketRequest : public CallbackRunner< Tuple1<int> > {
2320 public:
[email protected]2431756e2010-09-29 20:26:132321 TestReleasingSocketRequest(TestClientSocketPool* pool,
2322 int expected_result,
[email protected]e60e47a2010-07-14 03:37:182323 bool reset_releasing_handle)
2324 : pool_(pool),
2325 expected_result_(expected_result),
2326 reset_releasing_handle_(reset_releasing_handle) {}
[email protected]4f1e4982010-03-02 18:31:042327
2328 ClientSocketHandle* handle() { return &handle_; }
2329
2330 int WaitForResult() {
2331 return callback_.WaitForResult();
2332 }
2333
2334 virtual void RunWithParams(const Tuple1<int>& params) {
2335 callback_.RunWithParams(params);
[email protected]e60e47a2010-07-14 03:37:182336 if (reset_releasing_handle_)
2337 handle_.Reset();
[email protected]ad8e04a2010-11-01 04:16:272338 scoped_refptr<TestSocketParams> con_params(new TestSocketParams());
[email protected]2431756e2010-09-29 20:26:132339 EXPECT_EQ(expected_result_, handle2_.Init("a",
2340 con_params,
2341 kDefaultPriority,
2342 &callback2_,
2343 pool_,
[email protected]e60e47a2010-07-14 03:37:182344 BoundNetLog()));
[email protected]4f1e4982010-03-02 18:31:042345 }
2346
2347 private:
[email protected]2431756e2010-09-29 20:26:132348 TestClientSocketPool* const pool_;
[email protected]e60e47a2010-07-14 03:37:182349 int expected_result_;
2350 bool reset_releasing_handle_;
[email protected]4f1e4982010-03-02 18:31:042351 ClientSocketHandle handle_;
2352 ClientSocketHandle handle2_;
[email protected]f1f3f0f82011-10-01 20:38:102353 TestOldCompletionCallback callback_;
2354 TestOldCompletionCallback callback2_;
[email protected]4f1e4982010-03-02 18:31:042355};
2356
[email protected]e60e47a2010-07-14 03:37:182357
2358TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2359 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2360
2361 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2362 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
2363 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2364
[email protected]2431756e2010-09-29 20:26:132365 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]e60e47a2010-07-14 03:37:182366 client_socket_factory_.allocation_count());
2367
2368 connect_job_factory_->set_job_type(
2369 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2370 TestReleasingSocketRequest req(pool_.get(), OK, false);
[email protected]2431756e2010-09-29 20:26:132371 EXPECT_EQ(ERR_IO_PENDING,
2372 req.handle()->Init("a",
2373 params_,
2374 kDefaultPriority,
2375 &req,
2376 pool_.get(),
2377 BoundNetLog()));
[email protected]e60e47a2010-07-14 03:37:182378 // The next job should complete synchronously
2379 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2380
2381 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
2382 EXPECT_FALSE(req.handle()->is_initialized());
2383 EXPECT_FALSE(req.handle()->socket());
2384 EXPECT_TRUE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:432385 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182386}
2387
[email protected]b6501d3d2010-06-03 23:53:342388// http://crbug.com/44724 regression test.
2389// We start releasing the pool when we flush on network change. When that
2390// happens, the only active references are in the ClientSocketHandles. When a
2391// ConnectJob completes and calls back into the last ClientSocketHandle, that
2392// callback can release the last reference and delete the pool. After the
2393// callback finishes, we go back to the stack frame within the now-deleted pool.
2394// Executing any code that refers to members of the now-deleted pool can cause
2395// crashes.
2396TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2397 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2398 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2399
2400 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:102401 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132402 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2403 params_,
2404 kDefaultPriority,
2405 &callback,
2406 pool_.get(),
2407 BoundNetLog()));
[email protected]b6501d3d2010-06-03 23:53:342408
[email protected]2431756e2010-09-29 20:26:132409 pool_->Flush();
[email protected]b6501d3d2010-06-03 23:53:342410
2411 // We'll call back into this now.
2412 callback.WaitForResult();
2413}
2414
[email protected]a7e38572010-06-07 18:22:242415TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2416 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2417 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2418
2419 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:102420 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132421 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2422 params_,
2423 kDefaultPriority,
2424 &callback,
2425 pool_.get(),
2426 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242427 EXPECT_EQ(OK, callback.WaitForResult());
2428 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2429
2430 pool_->Flush();
2431
2432 handle.Reset();
2433 MessageLoop::current()->RunAllPending();
2434
[email protected]2431756e2010-09-29 20:26:132435 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2436 params_,
2437 kDefaultPriority,
2438 &callback,
2439 pool_.get(),
2440 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242441 EXPECT_EQ(OK, callback.WaitForResult());
2442 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2443}
2444
[email protected]06f92462010-08-31 19:24:142445class ConnectWithinCallback : public CallbackRunner< Tuple1<int> > {
2446 public:
2447 ConnectWithinCallback(
2448 const std::string& group_name,
2449 const scoped_refptr<TestSocketParams>& params,
[email protected]2431756e2010-09-29 20:26:132450 TestClientSocketPool* pool)
[email protected]06f92462010-08-31 19:24:142451 : group_name_(group_name), params_(params), pool_(pool) {}
2452
2453 ~ConnectWithinCallback() {}
2454
2455 virtual void RunWithParams(const Tuple1<int>& params) {
2456 callback_.RunWithParams(params);
2457 EXPECT_EQ(ERR_IO_PENDING,
2458 handle_.Init(group_name_,
2459 params_,
2460 kDefaultPriority,
2461 &nested_callback_,
2462 pool_,
2463 BoundNetLog()));
2464 }
2465
2466 int WaitForResult() {
2467 return callback_.WaitForResult();
2468 }
2469
2470 int WaitForNestedResult() {
2471 return nested_callback_.WaitForResult();
2472 }
2473
2474 private:
2475 const std::string group_name_;
2476 const scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:132477 TestClientSocketPool* const pool_;
[email protected]06f92462010-08-31 19:24:142478 ClientSocketHandle handle_;
[email protected]f1f3f0f82011-10-01 20:38:102479 TestOldCompletionCallback callback_;
2480 TestOldCompletionCallback nested_callback_;
[email protected]06f92462010-08-31 19:24:142481};
2482
2483TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
2484 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2485
2486 // First job will be waiting until it gets aborted.
2487 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2488
2489 ClientSocketHandle handle;
[email protected]2431756e2010-09-29 20:26:132490 ConnectWithinCallback callback("a", params_, pool_.get());
2491 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2492 params_,
2493 kDefaultPriority,
2494 &callback,
2495 pool_.get(),
2496 BoundNetLog()));
[email protected]06f92462010-08-31 19:24:142497
2498 // Second job will be started during the first callback, and will
2499 // asynchronously complete with OK.
2500 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2501 pool_->Flush();
2502 EXPECT_EQ(ERR_ABORTED, callback.WaitForResult());
2503 EXPECT_EQ(OK, callback.WaitForNestedResult());
2504}
2505
[email protected]25eea382010-07-10 23:55:262506// Cancel a pending socket request while we're at max sockets,
2507// and verify that the backup socket firing doesn't cause a crash.
2508TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
2509 // Max 4 sockets globally, max 4 sockets per group.
2510 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
[email protected]06d94042010-08-25 01:45:222511 pool_->EnableConnectBackupJobs();
[email protected]25eea382010-07-10 23:55:262512
[email protected]4baaf9d2010-08-31 15:15:442513 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2514 // timer.
[email protected]25eea382010-07-10 23:55:262515 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2516 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:102517 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132518 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2519 params_,
2520 kDefaultPriority,
2521 &callback,
2522 pool_.get(),
2523 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262524
2525 // Start (MaxSockets - 1) connected sockets to reach max sockets.
2526 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2527 ClientSocketHandle handles[kDefaultMaxSockets];
2528 for (int i = 1; i < kDefaultMaxSockets; ++i) {
[email protected]f1f3f0f82011-10-01 20:38:102529 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132530 EXPECT_EQ(OK, handles[i].Init("bar",
2531 params_,
2532 kDefaultPriority,
2533 &callback,
2534 pool_.get(),
2535 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262536 }
2537
2538 MessageLoop::current()->RunAllPending();
2539
2540 // Cancel the pending request.
2541 handle.Reset();
2542
2543 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]f214f8792011-01-01 02:17:082544 base::PlatformThread::Sleep(
2545 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
[email protected]25eea382010-07-10 23:55:262546
2547 MessageLoop::current()->RunAllPending();
2548 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
2549}
2550
[email protected]3f00be82010-09-27 19:50:022551TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
[email protected]4baaf9d2010-08-31 15:15:442552 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2553 pool_->EnableConnectBackupJobs();
2554
2555 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2556 // timer.
2557 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2558 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:102559 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132560 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2561 params_,
2562 kDefaultPriority,
2563 &callback,
2564 pool_.get(),
2565 BoundNetLog()));
[email protected]4baaf9d2010-08-31 15:15:442566 ASSERT_TRUE(pool_->HasGroup("bar"));
2567 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2568
2569 // Cancel the socket request. This should cancel the backup timer. Wait for
2570 // the backup time to see if it indeed got canceled.
2571 handle.Reset();
2572 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]f214f8792011-01-01 02:17:082573 base::PlatformThread::Sleep(
2574 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
[email protected]4baaf9d2010-08-31 15:15:442575 MessageLoop::current()->RunAllPending();
2576 ASSERT_TRUE(pool_->HasGroup("bar"));
2577 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2578}
2579
[email protected]3f00be82010-09-27 19:50:022580TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
2581 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2582 pool_->EnableConnectBackupJobs();
2583
2584 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2585 // timer.
2586 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2587 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:102588 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132589 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2590 params_,
2591 kDefaultPriority,
2592 &callback,
2593 pool_.get(),
2594 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022595 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2596 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:102597 TestOldCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132598 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("bar",
2599 params_,
2600 kDefaultPriority,
2601 &callback2,
2602 pool_.get(),
2603 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022604 ASSERT_TRUE(pool_->HasGroup("bar"));
2605 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("bar"));
2606
2607 // Cancel request 1 and then complete request 2. With the requests finished,
2608 // the backup timer should be cancelled.
2609 handle.Reset();
2610 EXPECT_EQ(OK, callback2.WaitForResult());
2611 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]f214f8792011-01-01 02:17:082612 base::PlatformThread::Sleep(
2613 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
[email protected]3f00be82010-09-27 19:50:022614 MessageLoop::current()->RunAllPending();
2615}
2616
[email protected]eb5a99382010-07-11 03:18:262617// Test delayed socket binding for the case where we have two connects,
2618// and while one is waiting on a connect, the other frees up.
2619// The socket waiting on a connect should switch immediately to the freed
2620// up socket.
2621TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
2622 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2623 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2624
2625 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:102626 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132627 EXPECT_EQ(ERR_IO_PENDING,
2628 handle1.Init("a",
2629 params_,
2630 kDefaultPriority,
2631 &callback,
2632 pool_.get(),
2633 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262634 EXPECT_EQ(OK, callback.WaitForResult());
2635
2636 // No idle sockets, no pending jobs.
2637 EXPECT_EQ(0, pool_->IdleSocketCount());
2638 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2639
2640 // Create a second socket to the same host, but this one will wait.
2641 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2642 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132643 EXPECT_EQ(ERR_IO_PENDING,
2644 handle2.Init("a",
2645 params_,
2646 kDefaultPriority,
2647 &callback,
2648 pool_.get(),
2649 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262650 // No idle sockets, and one connecting job.
2651 EXPECT_EQ(0, pool_->IdleSocketCount());
2652 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2653
2654 // Return the first handle to the pool. This will initiate the delayed
2655 // binding.
2656 handle1.Reset();
2657
2658 MessageLoop::current()->RunAllPending();
2659
2660 // Still no idle sockets, still one pending connect job.
2661 EXPECT_EQ(0, pool_->IdleSocketCount());
2662 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2663
2664 // The second socket connected, even though it was a Waiting Job.
2665 EXPECT_EQ(OK, callback.WaitForResult());
2666
2667 // And we can see there is still one job waiting.
2668 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2669
2670 // Finally, signal the waiting Connect.
2671 client_socket_factory_.SignalJobs();
2672 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2673
2674 MessageLoop::current()->RunAllPending();
2675}
2676
2677// Test delayed socket binding when a group is at capacity and one
2678// of the group's sockets frees up.
2679TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
2680 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2681 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2682
2683 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:102684 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132685 EXPECT_EQ(ERR_IO_PENDING,
2686 handle1.Init("a",
2687 params_,
2688 kDefaultPriority,
2689 &callback,
2690 pool_.get(),
2691 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262692 EXPECT_EQ(OK, callback.WaitForResult());
2693
2694 // No idle sockets, no pending jobs.
2695 EXPECT_EQ(0, pool_->IdleSocketCount());
2696 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2697
2698 // Create a second socket to the same host, but this one will wait.
2699 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2700 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132701 EXPECT_EQ(ERR_IO_PENDING,
2702 handle2.Init("a",
2703 params_,
2704 kDefaultPriority,
2705 &callback,
2706 pool_.get(),
2707 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262708 // No idle sockets, and one connecting job.
2709 EXPECT_EQ(0, pool_->IdleSocketCount());
2710 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2711
2712 // Return the first handle to the pool. This will initiate the delayed
2713 // binding.
2714 handle1.Reset();
2715
2716 MessageLoop::current()->RunAllPending();
2717
2718 // Still no idle sockets, still one pending connect job.
2719 EXPECT_EQ(0, pool_->IdleSocketCount());
2720 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2721
2722 // The second socket connected, even though it was a Waiting Job.
2723 EXPECT_EQ(OK, callback.WaitForResult());
2724
2725 // And we can see there is still one job waiting.
2726 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2727
2728 // Finally, signal the waiting Connect.
2729 client_socket_factory_.SignalJobs();
2730 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2731
2732 MessageLoop::current()->RunAllPending();
2733}
2734
2735// Test out the case where we have one socket connected, one
2736// connecting, when the first socket finishes and goes idle.
[email protected]2abfe90a2010-08-25 17:49:512737// Although the second connection is pending, the second request
[email protected]eb5a99382010-07-11 03:18:262738// should complete, by taking the first socket's idle socket.
2739TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
2740 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2741 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2742
2743 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:102744 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132745 EXPECT_EQ(ERR_IO_PENDING,
2746 handle1.Init("a",
2747 params_,
2748 kDefaultPriority,
2749 &callback,
2750 pool_.get(),
2751 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262752 EXPECT_EQ(OK, callback.WaitForResult());
2753
2754 // No idle sockets, no pending jobs.
2755 EXPECT_EQ(0, pool_->IdleSocketCount());
2756 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2757
2758 // Create a second socket to the same host, but this one will wait.
2759 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2760 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132761 EXPECT_EQ(ERR_IO_PENDING,
2762 handle2.Init("a",
2763 params_,
2764 kDefaultPriority,
2765 &callback,
2766 pool_.get(),
2767 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262768 // No idle sockets, and one connecting job.
2769 EXPECT_EQ(0, pool_->IdleSocketCount());
2770 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2771
2772 // Return the first handle to the pool. This will initiate the delayed
2773 // binding.
2774 handle1.Reset();
2775
2776 MessageLoop::current()->RunAllPending();
2777
2778 // Still no idle sockets, still one pending connect job.
2779 EXPECT_EQ(0, pool_->IdleSocketCount());
2780 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2781
2782 // The second socket connected, even though it was a Waiting Job.
2783 EXPECT_EQ(OK, callback.WaitForResult());
2784
2785 // And we can see there is still one job waiting.
2786 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2787
2788 // Finally, signal the waiting Connect.
2789 client_socket_factory_.SignalJobs();
2790 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2791
2792 MessageLoop::current()->RunAllPending();
2793}
2794
[email protected]2abfe90a2010-08-25 17:49:512795// Cover the case where on an available socket slot, we have one pending
2796// request that completes synchronously, thereby making the Group empty.
2797TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
2798 const int kUnlimitedSockets = 100;
2799 const int kOneSocketPerGroup = 1;
2800 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
2801
2802 // Make the first request asynchronous fail.
2803 // This will free up a socket slot later.
2804 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2805
2806 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:102807 TestOldCompletionCallback callback1;
[email protected]2431756e2010-09-29 20:26:132808 EXPECT_EQ(ERR_IO_PENDING,
2809 handle1.Init("a",
2810 params_,
2811 kDefaultPriority,
2812 &callback1,
2813 pool_.get(),
2814 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:512815 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2816
2817 // Make the second request synchronously fail. This should make the Group
2818 // empty.
2819 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
2820 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:102821 TestOldCompletionCallback callback2;
[email protected]2abfe90a2010-08-25 17:49:512822 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
2823 // when created.
[email protected]2431756e2010-09-29 20:26:132824 EXPECT_EQ(ERR_IO_PENDING,
2825 handle2.Init("a",
2826 params_,
2827 kDefaultPriority,
2828 &callback2,
2829 pool_.get(),
2830 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:512831
2832 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2833
2834 EXPECT_EQ(ERR_CONNECTION_FAILED, callback1.WaitForResult());
2835 EXPECT_EQ(ERR_CONNECTION_FAILED, callback2.WaitForResult());
2836 EXPECT_FALSE(pool_->HasGroup("a"));
2837}
2838
[email protected]e1b54dc2010-10-06 21:27:222839TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
2840 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2841
2842 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2843
2844 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:102845 TestOldCompletionCallback callback1;
[email protected]e1b54dc2010-10-06 21:27:222846 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2847 params_,
2848 kDefaultPriority,
2849 &callback1,
2850 pool_.get(),
2851 BoundNetLog()));
2852
2853 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:102854 TestOldCompletionCallback callback2;
[email protected]e1b54dc2010-10-06 21:27:222855 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2856 params_,
2857 kDefaultPriority,
2858 &callback2,
2859 pool_.get(),
2860 BoundNetLog()));
2861 ClientSocketHandle handle3;
[email protected]f1f3f0f82011-10-01 20:38:102862 TestOldCompletionCallback callback3;
[email protected]e1b54dc2010-10-06 21:27:222863 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
2864 params_,
2865 kDefaultPriority,
2866 &callback3,
2867 pool_.get(),
2868 BoundNetLog()));
2869
2870 EXPECT_EQ(OK, callback1.WaitForResult());
2871 EXPECT_EQ(OK, callback2.WaitForResult());
2872 EXPECT_EQ(OK, callback3.WaitForResult());
2873
2874 // Use the socket.
2875 EXPECT_EQ(1, handle1.socket()->Write(NULL, 1, NULL));
2876 EXPECT_EQ(1, handle3.socket()->Write(NULL, 1, NULL));
2877
2878 handle1.Reset();
2879 handle2.Reset();
2880 handle3.Reset();
2881
2882 EXPECT_EQ(OK, handle1.Init("a",
2883 params_,
2884 kDefaultPriority,
2885 &callback1,
2886 pool_.get(),
2887 BoundNetLog()));
2888 EXPECT_EQ(OK, handle2.Init("a",
2889 params_,
2890 kDefaultPriority,
2891 &callback2,
2892 pool_.get(),
2893 BoundNetLog()));
2894 EXPECT_EQ(OK, handle3.Init("a",
2895 params_,
2896 kDefaultPriority,
2897 &callback3,
2898 pool_.get(),
2899 BoundNetLog()));
2900
2901 EXPECT_TRUE(handle1.socket()->WasEverUsed());
2902 EXPECT_TRUE(handle2.socket()->WasEverUsed());
2903 EXPECT_FALSE(handle3.socket()->WasEverUsed());
2904}
2905
[email protected]2c2bef152010-10-13 00:55:032906TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
2907 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2908 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2909
2910 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2911
2912 ASSERT_TRUE(pool_->HasGroup("a"));
2913 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2914 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2915
2916 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:102917 TestOldCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:032918 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2919 params_,
2920 kDefaultPriority,
2921 &callback1,
2922 pool_.get(),
2923 BoundNetLog()));
2924
2925 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:102926 TestOldCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:032927 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2928 params_,
2929 kDefaultPriority,
2930 &callback2,
2931 pool_.get(),
2932 BoundNetLog()));
2933
2934 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2935 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2936
2937 EXPECT_EQ(OK, callback1.WaitForResult());
2938 EXPECT_EQ(OK, callback2.WaitForResult());
2939 handle1.Reset();
2940 handle2.Reset();
2941
2942 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2943 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2944}
2945
2946TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
2947 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2948 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2949
2950 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:102951 TestOldCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:032952 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2953 params_,
2954 kDefaultPriority,
2955 &callback1,
2956 pool_.get(),
2957 BoundNetLog()));
2958
2959 ASSERT_TRUE(pool_->HasGroup("a"));
2960 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2961 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2962
2963 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2964
2965 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2966 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2967
2968 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:102969 TestOldCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:032970 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2971 params_,
2972 kDefaultPriority,
2973 &callback2,
2974 pool_.get(),
2975 BoundNetLog()));
2976
2977 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2978 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2979
2980 EXPECT_EQ(OK, callback1.WaitForResult());
2981 EXPECT_EQ(OK, callback2.WaitForResult());
2982 handle1.Reset();
2983 handle2.Reset();
2984
2985 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2986 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2987}
2988
2989TEST_F(ClientSocketPoolBaseTest,
2990 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
2991 CreatePool(4, 4);
2992 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2993
2994 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:102995 TestOldCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:032996 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2997 params_,
2998 kDefaultPriority,
2999 &callback1,
3000 pool_.get(),
3001 BoundNetLog()));
3002
3003 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:103004 TestOldCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033005 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3006 params_,
3007 kDefaultPriority,
3008 &callback2,
3009 pool_.get(),
3010 BoundNetLog()));
3011
3012 ClientSocketHandle handle3;
[email protected]f1f3f0f82011-10-01 20:38:103013 TestOldCompletionCallback callback3;
[email protected]2c2bef152010-10-13 00:55:033014 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
3015 params_,
3016 kDefaultPriority,
3017 &callback3,
3018 pool_.get(),
3019 BoundNetLog()));
3020
3021 ASSERT_TRUE(pool_->HasGroup("a"));
3022 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
3023 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3024
3025 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3026
3027 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
3028 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3029
3030 EXPECT_EQ(OK, callback1.WaitForResult());
3031 EXPECT_EQ(OK, callback2.WaitForResult());
3032 EXPECT_EQ(OK, callback3.WaitForResult());
3033 handle1.Reset();
3034 handle2.Reset();
3035 handle3.Reset();
3036
3037 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3038 EXPECT_EQ(3, pool_->IdleSocketCountInGroup("a"));
3039}
3040
3041TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
3042 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3043 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3044
3045 ASSERT_FALSE(pool_->HasGroup("a"));
3046
3047 pool_->RequestSockets("a", &params_, kDefaultMaxSockets,
3048 BoundNetLog());
3049
3050 ASSERT_TRUE(pool_->HasGroup("a"));
3051 EXPECT_EQ(kDefaultMaxSockets, pool_->NumConnectJobsInGroup("a"));
3052
3053 ASSERT_FALSE(pool_->HasGroup("b"));
3054
3055 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
3056 BoundNetLog());
3057
3058 ASSERT_FALSE(pool_->HasGroup("b"));
3059}
3060
3061TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
3062 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3063 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3064
3065 ASSERT_FALSE(pool_->HasGroup("a"));
3066
3067 pool_->RequestSockets("a", &params_, kDefaultMaxSockets - 1,
3068 BoundNetLog());
3069
3070 ASSERT_TRUE(pool_->HasGroup("a"));
3071 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->NumConnectJobsInGroup("a"));
[email protected]d4dfdab2011-12-07 16:56:593072 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033073
3074 ASSERT_FALSE(pool_->HasGroup("b"));
3075
3076 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
3077 BoundNetLog());
3078
3079 ASSERT_TRUE(pool_->HasGroup("b"));
3080 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("b"));
[email protected]d4dfdab2011-12-07 16:56:593081 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033082}
3083
3084TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
3085 CreatePool(4, 4);
3086 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3087
3088 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:103089 TestOldCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033090 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3091 params_,
3092 kDefaultPriority,
3093 &callback1,
3094 pool_.get(),
3095 BoundNetLog()));
3096 ASSERT_EQ(OK, callback1.WaitForResult());
3097 handle1.Reset();
3098
3099 ASSERT_TRUE(pool_->HasGroup("a"));
3100 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3101 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3102
3103 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3104
3105 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3106 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3107}
3108
3109TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
3110 CreatePool(4, 4);
3111 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3112
3113 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:103114 TestOldCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033115 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3116 params_,
3117 kDefaultPriority,
3118 &callback1,
3119 pool_.get(),
3120 BoundNetLog()));
3121 ASSERT_EQ(OK, callback1.WaitForResult());
3122
3123 ASSERT_TRUE(pool_->HasGroup("a"));
3124 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3125 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3126 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3127
3128 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3129
3130 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3131 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3132 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3133}
3134
3135TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
3136 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3137 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3138
3139 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3140 BoundNetLog());
3141
3142 ASSERT_TRUE(pool_->HasGroup("a"));
3143 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3144 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("a"));
3145
3146 pool_->RequestSockets("b", &params_, kDefaultMaxSocketsPerGroup,
3147 BoundNetLog());
3148
3149 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3150 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("b"));
3151}
3152
[email protected]3c819f522010-12-02 02:03:123153TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
3154 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3155 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3156
3157 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3158 BoundNetLog());
3159
3160 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]fd2e53e2011-01-14 20:40:523161
3162 connect_job_factory_->set_job_type(
3163 TestConnectJob::kMockAdditionalErrorStateJob);
3164 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3165 BoundNetLog());
3166
3167 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]3c819f522010-12-02 02:03:123168}
3169
[email protected]2c2bef152010-10-13 00:55:033170TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
3171 CreatePool(4, 4);
3172 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3173
3174 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3175
3176 ASSERT_TRUE(pool_->HasGroup("a"));
3177 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3178 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3179
3180 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3181 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3182 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3183
3184 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:103185 TestOldCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033186 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3187 params_,
3188 kDefaultPriority,
3189 &callback1,
3190 pool_.get(),
3191 BoundNetLog()));
3192 ASSERT_EQ(OK, callback1.WaitForResult());
3193
3194 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:103195 TestOldCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033196 int rv = handle2.Init("a",
3197 params_,
3198 kDefaultPriority,
3199 &callback2,
3200 pool_.get(),
3201 BoundNetLog());
3202 if (rv != OK) {
3203 EXPECT_EQ(ERR_IO_PENDING, rv);
3204 EXPECT_EQ(OK, callback2.WaitForResult());
3205 }
3206
3207 handle1.Reset();
3208 handle2.Reset();
3209
3210 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3211
3212 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3213 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3214 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3215}
3216
3217TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
3218 CreatePool(4, 4);
3219 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3220
3221 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3222
3223 ASSERT_TRUE(pool_->HasGroup("a"));
3224 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3225 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3226
3227 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3228 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3229 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3230
3231 pool_->RequestSockets("a", &params_, 3, BoundNetLog());
3232 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
3233 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3234
3235 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3236 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
3237 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3238}
3239
3240TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
3241 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3242 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3243
3244 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3245
3246 ASSERT_TRUE(pool_->HasGroup("a"));
3247 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3248 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3249
3250 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:103251 TestOldCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033252 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3253 params_,
3254 kDefaultPriority,
3255 &callback1,
3256 pool_.get(),
3257 BoundNetLog()));
3258
3259 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3260 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3261
3262 ASSERT_EQ(OK, callback1.WaitForResult());
3263
3264 handle1.Reset();
3265
3266 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3267}
3268
[email protected]dcbe168a2010-12-02 03:14:463269// http://crbug.com/64940 regression test.
3270TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
3271 const int kMaxTotalSockets = 3;
3272 const int kMaxSocketsPerGroup = 2;
3273 CreatePool(kMaxTotalSockets, kMaxSocketsPerGroup);
3274 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3275
3276 // Note that group name ordering matters here. "a" comes before "b", so
3277 // CloseOneIdleSocket() will try to close "a"'s idle socket.
3278
3279 // Set up one idle socket in "a".
3280 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:103281 TestOldCompletionCallback callback1;
[email protected]dcbe168a2010-12-02 03:14:463282 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3283 params_,
3284 kDefaultPriority,
3285 &callback1,
3286 pool_.get(),
3287 BoundNetLog()));
3288
3289 ASSERT_EQ(OK, callback1.WaitForResult());
3290 handle1.Reset();
3291 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3292
3293 // Set up two active sockets in "b".
3294 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:103295 TestOldCompletionCallback callback2;
[email protected]dcbe168a2010-12-02 03:14:463296 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("b",
3297 params_,
3298 kDefaultPriority,
3299 &callback1,
3300 pool_.get(),
3301 BoundNetLog()));
3302 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("b",
3303 params_,
3304 kDefaultPriority,
3305 &callback2,
3306 pool_.get(),
3307 BoundNetLog()));
3308
3309 ASSERT_EQ(OK, callback1.WaitForResult());
3310 ASSERT_EQ(OK, callback2.WaitForResult());
3311 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3312 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3313
3314 // Now we have 1 idle socket in "a" and 2 active sockets in "b". This means
3315 // we've maxed out on sockets, since we set |kMaxTotalSockets| to 3.
3316 // Requesting 2 preconnected sockets for "a" should fail to allocate any more
3317 // sockets for "a", and "b" should still have 2 active sockets.
3318
3319 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3320 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3321 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3322 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3323 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3324 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3325 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3326
3327 // Now release the 2 active sockets for "b". This will give us 1 idle socket
3328 // in "a" and 2 idle sockets in "b". Requesting 2 preconnected sockets for
3329 // "a" should result in closing 1 for "b".
3330 handle1.Reset();
3331 handle2.Reset();
3332 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("b"));
3333 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3334
3335 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3336 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3337 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3338 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3339 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3340 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("b"));
3341 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3342}
3343
[email protected]b7b8be42011-07-12 12:46:413344TEST_F(ClientSocketPoolBaseTest, PreconnectWithoutBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073345 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3346 pool_->EnableConnectBackupJobs();
3347
3348 // Make the ConnectJob hang until it times out, shorten the timeout.
3349 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3350 connect_job_factory_->set_timeout_duration(
3351 base::TimeDelta::FromMilliseconds(500));
3352 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3353 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3354 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073355
[email protected]b7b8be42011-07-12 12:46:413356 // Verify the backup timer doesn't create a backup job, by making
3357 // the backup job a pending job instead of a waiting job, so it
3358 // *would* complete if it were created.
[email protected]a9fc8fc2011-05-10 02:41:073359 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]b7b8be42011-07-12 12:46:413360 MessageLoop::current()->PostDelayedTask(FROM_HERE,
[email protected]72d27ce2011-12-09 00:41:123361 MessageLoop::QuitClosure(), 1000);
[email protected]b7b8be42011-07-12 12:46:413362 MessageLoop::current()->Run();
[email protected]a9fc8fc2011-05-10 02:41:073363 EXPECT_FALSE(pool_->HasGroup("a"));
3364}
3365
[email protected]b7b8be42011-07-12 12:46:413366TEST_F(ClientSocketPoolBaseTest, PreconnectWithBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073367 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3368 pool_->EnableConnectBackupJobs();
3369
3370 // Make the ConnectJob hang forever.
3371 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3372 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3373 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3374 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3375 MessageLoop::current()->RunAllPending();
3376
3377 // Make the backup job be a pending job, so it completes normally.
3378 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3379 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:103380 TestOldCompletionCallback callback;
[email protected]a9fc8fc2011-05-10 02:41:073381 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
3382 params_,
3383 kDefaultPriority,
3384 &callback,
3385 pool_.get(),
3386 BoundNetLog()));
[email protected]b7b8be42011-07-12 12:46:413387 // Timer has started, but the backup connect job shouldn't be created yet.
[email protected]a9fc8fc2011-05-10 02:41:073388 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3389 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3390 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3391 ASSERT_EQ(OK, callback.WaitForResult());
3392
3393 // The hung connect job should still be there, but everything else should be
3394 // complete.
3395 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3396 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3397 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3398}
3399
[email protected]d4dfdab2011-12-07 16:56:593400class MockLayeredPool : public LayeredPool {
3401 public:
3402 MockLayeredPool(TestClientSocketPool* pool,
3403 const std::string& group_name)
3404 : pool_(pool),
3405 params_(new TestSocketParams),
3406 group_name_(group_name) {
3407 pool_->AddLayeredPool(this);
3408 }
3409
3410 ~MockLayeredPool() {
3411 pool_->RemoveLayeredPool(this);
3412 }
3413
3414 int RequestSocket(TestClientSocketPool* pool) {
3415 return handle_.Init(group_name_, params_, kDefaultPriority, &callback_,
3416 pool, BoundNetLog());
3417 }
3418
3419 int RequestSocketWithoutLimits(TestClientSocketPool* pool) {
3420 params_->set_ignore_limits(true);
3421 return handle_.Init(group_name_, params_, kDefaultPriority, &callback_,
3422 pool, BoundNetLog());
3423 }
3424
3425 bool ReleaseOneConnection() {
3426 if (!handle_.is_initialized()) {
3427 return false;
3428 }
3429 handle_.socket()->Disconnect();
3430 handle_.Reset();
3431 return true;
3432 }
3433
3434 MOCK_METHOD0(CloseOneIdleConnection, bool());
3435
3436 private:
3437 TestClientSocketPool* const pool_;
3438 scoped_refptr<TestSocketParams> params_;
3439 ClientSocketHandle handle_;
3440 TestOldCompletionCallback callback_;
3441 const std::string group_name_;
3442};
3443
3444TEST_F(ClientSocketPoolBaseTest, FailToCloseIdleSocketsNotHeldByLayeredPool) {
3445 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3446 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3447
3448 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
3449 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3450 .WillOnce(Return(false));
3451 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3452 EXPECT_FALSE(pool_->CloseOneIdleConnectionInLayeredPool());
3453}
3454
3455TEST_F(ClientSocketPoolBaseTest, ForciblyCloseIdleSocketsHeldByLayeredPool) {
3456 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3457 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3458
3459 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
3460 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3461 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3462 .WillOnce(Invoke(&mock_layered_pool,
3463 &MockLayeredPool::ReleaseOneConnection));
3464 EXPECT_TRUE(pool_->CloseOneIdleConnectionInLayeredPool());
3465}
3466
3467TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsHeldByLayeredPoolWhenNeeded) {
3468 CreatePool(1, 1);
3469 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3470
3471 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
3472 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3473 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3474 .WillOnce(Invoke(&mock_layered_pool,
3475 &MockLayeredPool::ReleaseOneConnection));
3476 ClientSocketHandle handle;
3477 TestOldCompletionCallback callback;
3478 EXPECT_EQ(OK, handle.Init("a",
3479 params_,
3480 kDefaultPriority,
3481 &callback,
3482 pool_.get(),
3483 BoundNetLog()));
3484}
3485
3486TEST_F(ClientSocketPoolBaseTest,
3487 CloseMultipleIdleSocketsHeldByLayeredPoolWhenNeeded) {
3488 CreatePool(1, 1);
3489 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3490
3491 MockLayeredPool mock_layered_pool1(pool_.get(), "foo");
3492 EXPECT_EQ(OK, mock_layered_pool1.RequestSocket(pool_.get()));
3493 EXPECT_CALL(mock_layered_pool1, CloseOneIdleConnection())
3494 .WillRepeatedly(Invoke(&mock_layered_pool1,
3495 &MockLayeredPool::ReleaseOneConnection));
3496 MockLayeredPool mock_layered_pool2(pool_.get(), "bar");
3497 EXPECT_EQ(OK, mock_layered_pool2.RequestSocketWithoutLimits(pool_.get()));
3498 EXPECT_CALL(mock_layered_pool2, CloseOneIdleConnection())
3499 .WillRepeatedly(Invoke(&mock_layered_pool2,
3500 &MockLayeredPool::ReleaseOneConnection));
3501 ClientSocketHandle handle;
3502 TestOldCompletionCallback callback;
3503 EXPECT_EQ(OK, handle.Init("a",
3504 params_,
3505 kDefaultPriority,
3506 &callback,
3507 pool_.get(),
3508 BoundNetLog()));
3509}
3510
[email protected]f6d1d6eb2009-06-24 20:16:093511} // namespace
3512
3513} // namespace net