blob: 6cdbdd36de50340718d5822458275ce7f6c1442c [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]d8eb84242010-09-25 02:25:0615#include "net/base/net_errors.h"
[email protected]9e743cd2010-03-16 07:03:5316#include "net/base/net_log.h"
17#include "net/base/net_log_unittest.h"
[email protected]ac790b42009-12-02 04:31:3118#include "net/base/request_priority.h"
[email protected]f6d1d6eb2009-06-24 20:16:0919#include "net/base/test_completion_callback.h"
[email protected]277d5942010-08-11 21:02:3520#include "net/http/http_response_headers.h"
[email protected]f6d1d6eb2009-06-24 20:16:0921#include "net/socket/client_socket_factory.h"
22#include "net/socket/client_socket_handle.h"
[email protected]b89f7e42010-05-20 20:37:0023#include "net/socket/client_socket_pool_histograms.h"
[email protected]75439d3b2009-07-23 22:11:1724#include "net/socket/socket_test_util.h"
[email protected]d0672be2010-10-20 16:30:1925#include "net/socket/ssl_host_info.h"
[email protected]3268023f2011-05-05 00:08:1026#include "net/socket/stream_socket.h"
[email protected]f6d1d6eb2009-06-24 20:16:0927#include "testing/gtest/include/gtest/gtest.h"
28
29namespace net {
30
31namespace {
32
[email protected]211d21722009-07-22 15:48:5333const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2034const int kDefaultMaxSocketsPerGroup = 2;
[email protected]a554a8262010-05-20 00:13:5235const net::RequestPriority kDefaultPriority = MEDIUM;
[email protected]0b7648c2009-07-06 20:14:0136
[email protected]df4b4ef2010-07-12 18:25:2137class TestSocketParams : public base::RefCounted<TestSocketParams> {
[email protected]5acdce12011-03-30 13:00:2038 public:
39 bool ignore_limits() { return false; }
[email protected]df4b4ef2010-07-12 18:25:2140 private:
41 friend class base::RefCounted<TestSocketParams>;
42 ~TestSocketParams() {}
43};
[email protected]7fc5b09a2010-02-27 00:07:3844typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
[email protected]d80a4322009-08-14 07:07:4945
[email protected]3268023f2011-05-05 00:08:1046class MockClientSocket : public StreamSocket {
[email protected]f6d1d6eb2009-06-24 20:16:0947 public:
[email protected]5e6efa52011-06-27 17:26:4148 MockClientSocket() : connected_(false), was_used_to_convey_data_(false),
49 num_bytes_read_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:0950
[email protected]ab838892009-06-30 18:49:0551 // Socket methods:
52 virtual int Read(
[email protected]5e6efa52011-06-27 17:26:4153 IOBuffer* /* buf */, int len, CompletionCallback* /* callback */) {
54 num_bytes_read_ += len;
55 return len;
[email protected]ab838892009-06-30 18:49:0556 }
57
58 virtual int Write(
[email protected]0f873e82010-09-02 16:09:0159 IOBuffer* /* buf */, int len, CompletionCallback* /* callback */) {
60 was_used_to_convey_data_ = true;
61 return len;
[email protected]ab838892009-06-30 18:49:0562 }
[email protected]06650c52010-06-03 00:49:1763 virtual bool SetReceiveBufferSize(int32 size) { return true; }
64 virtual bool SetSendBufferSize(int32 size) { return true; }
[email protected]ab838892009-06-30 18:49:0565
[email protected]3268023f2011-05-05 00:08:1066 // StreamSocket methods:
[email protected]ab838892009-06-30 18:49:0567
[email protected]a2006ece2010-04-23 16:44:0268 virtual int Connect(CompletionCallback* callback) {
[email protected]f6d1d6eb2009-06-24 20:16:0969 connected_ = true;
70 return OK;
71 }
[email protected]f6d1d6eb2009-06-24 20:16:0972
[email protected]ab838892009-06-30 18:49:0573 virtual void Disconnect() { connected_ = false; }
74 virtual bool IsConnected() const { return connected_; }
75 virtual bool IsConnectedAndIdle() const { return connected_; }
[email protected]0b7648c2009-07-06 20:14:0176
[email protected]ac9eec62010-02-20 18:50:3877 virtual int GetPeerAddress(AddressList* /* address */) const {
[email protected]9f864b32010-01-20 15:01:1678 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:0979 }
[email protected]f6d1d6eb2009-06-24 20:16:0980
[email protected]e7f74da2011-04-19 23:49:3581 virtual int GetLocalAddress(IPEndPoint* /* address */) const {
82 return ERR_UNEXPECTED;
83 }
84
[email protected]a2006ece2010-04-23 16:44:0285 virtual const BoundNetLog& NetLog() const {
86 return net_log_;
87 }
88
[email protected]9b5614a2010-08-25 20:29:4589 virtual void SetSubresourceSpeculation() {}
90 virtual void SetOmniboxSpeculation() {}
[email protected]5e6efa52011-06-27 17:26:4191 virtual bool WasEverUsed() const {
92 return was_used_to_convey_data_ || num_bytes_read_ > 0;
93 }
[email protected]7f7e92392010-10-26 18:29:2994 virtual bool UsingTCPFastOpen() const { return false; }
[email protected]5e6efa52011-06-27 17:26:4195 virtual int64 NumBytesRead() const { return num_bytes_read_; }
96 virtual base::TimeDelta GetConnectTimeMicros() const {
97 static const base::TimeDelta kDummyConnectTimeMicros =
98 base::TimeDelta::FromMicroseconds(10);
99 return kDummyConnectTimeMicros; // Dummy value.
100 }
[email protected]9b5614a2010-08-25 20:29:45101
[email protected]f6d1d6eb2009-06-24 20:16:09102 private:
103 bool connected_;
[email protected]a2006ece2010-04-23 16:44:02104 BoundNetLog net_log_;
[email protected]0f873e82010-09-02 16:09:01105 bool was_used_to_convey_data_;
[email protected]5e6efa52011-06-27 17:26:41106 int num_bytes_read_;
[email protected]f6d1d6eb2009-06-24 20:16:09107
[email protected]ab838892009-06-30 18:49:05108 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:09109};
110
[email protected]5fc08e32009-07-15 17:09:57111class TestConnectJob;
112
[email protected]f6d1d6eb2009-06-24 20:16:09113class MockClientSocketFactory : public ClientSocketFactory {
114 public:
[email protected]ab838892009-06-30 18:49:05115 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:09116
[email protected]98b0e582011-06-22 14:31:41117 virtual DatagramClientSocket* CreateDatagramClientSocket(
118 NetLog* net_log,
119 const NetLog::Source& source) {
120 NOTREACHED();
121 return NULL;
122 }
123
[email protected]3268023f2011-05-05 00:08:10124 virtual StreamSocket* CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07125 const AddressList& addresses,
126 NetLog* /* net_log */,
127 const NetLog::Source& /*source*/) {
[email protected]f6d1d6eb2009-06-24 20:16:09128 allocation_count_++;
[email protected]ab838892009-06-30 18:49:05129 return NULL;
[email protected]f6d1d6eb2009-06-24 20:16:09130 }
131
132 virtual SSLClientSocket* CreateSSLClientSocket(
[email protected]e60e47a2010-07-14 03:37:18133 ClientSocketHandle* transport_socket,
[email protected]4f4de7e62010-11-12 19:55:27134 const HostPortPair& host_and_port,
[email protected]7ab5bbd12010-10-19 13:33:21135 const SSLConfig& ssl_config,
[email protected]d8fbf582010-11-04 21:51:12136 SSLHostInfo* ssl_host_info,
[email protected]822581d2010-12-16 17:27:15137 CertVerifier* cert_verifier,
[email protected]345c613b2010-11-22 19:33:18138 DnsCertProvenanceChecker* dns_cert_checker) {
[email protected]f6d1d6eb2009-06-24 20:16:09139 NOTIMPLEMENTED();
[email protected]7ab5bbd12010-10-19 13:33:21140 delete ssl_host_info;
[email protected]f6d1d6eb2009-06-24 20:16:09141 return NULL;
142 }
143
[email protected]25f47352011-02-25 16:31:59144 virtual void ClearSSLSessionCache() {
145 NOTIMPLEMENTED();
146 }
147
[email protected]5fc08e32009-07-15 17:09:57148 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
149 void SignalJobs();
150
[email protected]f6d1d6eb2009-06-24 20:16:09151 int allocation_count() const { return allocation_count_; }
152
[email protected]f6d1d6eb2009-06-24 20:16:09153 private:
154 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:57155 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09156};
157
[email protected]ab838892009-06-30 18:49:05158class TestConnectJob : public ConnectJob {
159 public:
160 enum JobType {
161 kMockJob,
162 kMockFailingJob,
163 kMockPendingJob,
164 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57165 kMockWaitingJob,
166 kMockAdvancingLoadStateJob,
[email protected]e772db3f2010-07-12 18:11:13167 kMockRecoverableJob,
168 kMockPendingRecoverableJob,
[email protected]e60e47a2010-07-14 03:37:18169 kMockAdditionalErrorStateJob,
170 kMockPendingAdditionalErrorStateJob,
[email protected]ab838892009-06-30 18:49:05171 };
172
[email protected]994d4932010-07-12 17:55:13173 // The kMockPendingJob uses a slight delay before allowing the connect
174 // to complete.
175 static const int kPendingConnectDelay = 2;
176
[email protected]ab838892009-06-30 18:49:05177 TestConnectJob(JobType job_type,
178 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49179 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34180 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05181 ConnectJob::Delegate* delegate,
[email protected]fd7b7c92009-08-20 19:38:30182 MockClientSocketFactory* client_socket_factory,
[email protected]06650c52010-06-03 00:49:17183 NetLog* net_log)
184 : ConnectJob(group_name, timeout_duration, delegate,
185 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
[email protected]2ab05b52009-07-01 23:57:58186 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05187 client_socket_factory_(client_socket_factory),
[email protected]46451352009-09-01 14:54:21188 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
[email protected]e60e47a2010-07-14 03:37:18189 load_state_(LOAD_STATE_IDLE),
190 store_additional_error_state_(false) {}
[email protected]ab838892009-06-30 18:49:05191
[email protected]974ebd62009-08-03 23:14:34192 void Signal() {
[email protected]e772db3f2010-07-12 18:11:13193 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
[email protected]974ebd62009-08-03 23:14:34194 }
195
[email protected]46451352009-09-01 14:54:21196 virtual LoadState GetLoadState() const { return load_state_; }
197
[email protected]e60e47a2010-07-14 03:37:18198 virtual void GetAdditionalErrorState(ClientSocketHandle* handle) {
199 if (store_additional_error_state_) {
200 // Set all of the additional error state fields in some way.
201 handle->set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43202 HttpResponseInfo info;
203 info.headers = new HttpResponseHeaders("");
204 handle->set_ssl_error_response_info(info);
[email protected]e60e47a2010-07-14 03:37:18205 }
206 }
207
[email protected]974ebd62009-08-03 23:14:34208 private:
[email protected]ab838892009-06-30 18:49:05209 // ConnectJob methods:
210
[email protected]974ebd62009-08-03 23:14:34211 virtual int ConnectInternal() {
[email protected]ab838892009-06-30 18:49:05212 AddressList ignored;
[email protected]ab739042011-04-07 15:22:28213 client_socket_factory_->CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07214 ignored, NULL, net::NetLog::Source());
[email protected]6e713f02009-08-06 02:56:40215 set_socket(new MockClientSocket());
[email protected]ab838892009-06-30 18:49:05216 switch (job_type_) {
217 case kMockJob:
[email protected]e772db3f2010-07-12 18:11:13218 return DoConnect(true /* successful */, false /* sync */,
219 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05220 case kMockFailingJob:
[email protected]e772db3f2010-07-12 18:11:13221 return DoConnect(false /* error */, false /* sync */,
222 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05223 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57224 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47225
226 // Depending on execution timings, posting a delayed task can result
227 // in the task getting executed the at the earliest possible
228 // opportunity or only after returning once from the message loop and
229 // then a second call into the message loop. In order to make behavior
230 // more deterministic, we change the default delay to 2ms. This should
231 // always require us to wait for the second call into the message loop.
232 //
233 // N.B. The correct fix for this and similar timing problems is to
234 // abstract time for the purpose of unittests. Unfortunately, we have
235 // a lot of third-party components that directly call the various
236 // time functions, so this change would be rather invasive.
237 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05238 FROM_HERE,
239 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47240 &TestConnectJob::DoConnect,
241 true /* successful */,
[email protected]e772db3f2010-07-12 18:11:13242 true /* async */,
243 false /* recoverable */),
[email protected]994d4932010-07-12 17:55:13244 kPendingConnectDelay);
[email protected]ab838892009-06-30 18:49:05245 return ERR_IO_PENDING;
246 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57247 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47248 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05249 FROM_HERE,
250 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47251 &TestConnectJob::DoConnect,
252 false /* error */,
[email protected]e772db3f2010-07-12 18:11:13253 true /* async */,
254 false /* recoverable */),
[email protected]6b175382009-10-13 06:47:47255 2);
[email protected]ab838892009-06-30 18:49:05256 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57257 case kMockWaitingJob:
258 client_socket_factory_->WaitForSignal(this);
259 waiting_success_ = true;
260 return ERR_IO_PENDING;
261 case kMockAdvancingLoadStateJob:
[email protected]e6ec67b2010-06-16 00:12:46262 MessageLoop::current()->PostTask(
[email protected]5fc08e32009-07-15 17:09:57263 FROM_HERE,
264 method_factory_.NewRunnableMethod(
[email protected]e6ec67b2010-06-16 00:12:46265 &TestConnectJob::AdvanceLoadState, load_state_));
[email protected]5fc08e32009-07-15 17:09:57266 return ERR_IO_PENDING;
[email protected]e772db3f2010-07-12 18:11:13267 case kMockRecoverableJob:
268 return DoConnect(false /* error */, false /* sync */,
269 true /* recoverable */);
270 case kMockPendingRecoverableJob:
271 set_load_state(LOAD_STATE_CONNECTING);
272 MessageLoop::current()->PostDelayedTask(
273 FROM_HERE,
274 method_factory_.NewRunnableMethod(
275 &TestConnectJob::DoConnect,
276 false /* error */,
277 true /* async */,
278 true /* recoverable */),
279 2);
280 return ERR_IO_PENDING;
[email protected]e60e47a2010-07-14 03:37:18281 case kMockAdditionalErrorStateJob:
282 store_additional_error_state_ = true;
283 return DoConnect(false /* error */, false /* sync */,
284 false /* recoverable */);
285 case kMockPendingAdditionalErrorStateJob:
286 set_load_state(LOAD_STATE_CONNECTING);
287 store_additional_error_state_ = true;
288 MessageLoop::current()->PostDelayedTask(
289 FROM_HERE,
290 method_factory_.NewRunnableMethod(
291 &TestConnectJob::DoConnect,
292 false /* error */,
293 true /* async */,
294 false /* recoverable */),
295 2);
296 return ERR_IO_PENDING;
[email protected]ab838892009-06-30 18:49:05297 default:
298 NOTREACHED();
[email protected]6e713f02009-08-06 02:56:40299 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05300 return ERR_FAILED;
301 }
302 }
303
[email protected]46451352009-09-01 14:54:21304 void set_load_state(LoadState load_state) { load_state_ = load_state; }
305
[email protected]e772db3f2010-07-12 18:11:13306 int DoConnect(bool succeed, bool was_async, bool recoverable) {
307 int result = OK;
[email protected]ab838892009-06-30 18:49:05308 if (succeed) {
[email protected]a2006ece2010-04-23 16:44:02309 socket()->Connect(NULL);
[email protected]e772db3f2010-07-12 18:11:13310 } else if (recoverable) {
311 result = ERR_PROXY_AUTH_REQUESTED;
[email protected]6e713f02009-08-06 02:56:40312 } else {
[email protected]e772db3f2010-07-12 18:11:13313 result = ERR_CONNECTION_FAILED;
[email protected]6e713f02009-08-06 02:56:40314 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05315 }
[email protected]2ab05b52009-07-01 23:57:58316
317 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30318 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05319 return result;
320 }
321
[email protected]cfa8228c2010-06-17 01:07:56322 // This function helps simulate the progress of load states on a ConnectJob.
323 // Each time it is called it advances the load state and posts a task to be
324 // called again. It stops at the last connecting load state (the one
325 // before LOAD_STATE_SENDING_REQUEST).
[email protected]5fc08e32009-07-15 17:09:57326 void AdvanceLoadState(LoadState state) {
327 int tmp = state;
328 tmp++;
[email protected]cfa8228c2010-06-17 01:07:56329 if (tmp < LOAD_STATE_SENDING_REQUEST) {
330 state = static_cast<LoadState>(tmp);
331 set_load_state(state);
332 MessageLoop::current()->PostTask(
333 FROM_HERE,
334 method_factory_.NewRunnableMethod(&TestConnectJob::AdvanceLoadState,
335 state));
336 }
[email protected]5fc08e32009-07-15 17:09:57337 }
338
339 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05340 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57341 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05342 ScopedRunnableMethodFactory<TestConnectJob> method_factory_;
[email protected]46451352009-09-01 14:54:21343 LoadState load_state_;
[email protected]e60e47a2010-07-14 03:37:18344 bool store_additional_error_state_;
[email protected]ab838892009-06-30 18:49:05345
346 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
347};
348
[email protected]d80a4322009-08-14 07:07:49349class TestConnectJobFactory
350 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05351 public:
[email protected]5fc08e32009-07-15 17:09:57352 explicit TestConnectJobFactory(MockClientSocketFactory* client_socket_factory)
[email protected]ab838892009-06-30 18:49:05353 : job_type_(TestConnectJob::kMockJob),
354 client_socket_factory_(client_socket_factory) {}
355
356 virtual ~TestConnectJobFactory() {}
357
358 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
359
[email protected]974ebd62009-08-03 23:14:34360 void set_timeout_duration(base::TimeDelta timeout_duration) {
361 timeout_duration_ = timeout_duration;
362 }
363
[email protected]ab838892009-06-30 18:49:05364 // ConnectJobFactory methods:
365
366 virtual ConnectJob* NewConnectJob(
367 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49368 const TestClientSocketPoolBase::Request& request,
[email protected]06650c52010-06-03 00:49:17369 ConnectJob::Delegate* delegate) const {
[email protected]ab838892009-06-30 18:49:05370 return new TestConnectJob(job_type_,
371 group_name,
372 request,
[email protected]974ebd62009-08-03 23:14:34373 timeout_duration_,
[email protected]ab838892009-06-30 18:49:05374 delegate,
[email protected]fd7b7c92009-08-20 19:38:30375 client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17376 NULL);
[email protected]ab838892009-06-30 18:49:05377 }
378
[email protected]a796bcec2010-03-22 17:17:26379 virtual base::TimeDelta ConnectionTimeout() const {
380 return timeout_duration_;
381 }
382
[email protected]ab838892009-06-30 18:49:05383 private:
384 TestConnectJob::JobType job_type_;
[email protected]974ebd62009-08-03 23:14:34385 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57386 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05387
388 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
389};
390
391class TestClientSocketPool : public ClientSocketPool {
392 public:
393 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53394 int max_sockets,
[email protected]ab838892009-06-30 18:49:05395 int max_sockets_per_group,
[email protected]2431756e2010-09-29 20:26:13396 ClientSocketPoolHistograms* histograms,
[email protected]9bf28db2009-08-29 01:35:16397 base::TimeDelta unused_idle_socket_timeout,
398 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49399 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
[email protected]b89f7e42010-05-20 20:37:00400 : base_(max_sockets, max_sockets_per_group, histograms,
[email protected]9bf28db2009-08-29 01:35:16401 unused_idle_socket_timeout, used_idle_socket_timeout,
[email protected]66761b952010-06-25 21:30:38402 connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05403
[email protected]2431756e2010-09-29 20:26:13404 virtual ~TestClientSocketPool() {}
405
[email protected]ab838892009-06-30 18:49:05406 virtual int RequestSocket(
407 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49408 const void* params,
[email protected]ac790b42009-12-02 04:31:31409 net::RequestPriority priority,
[email protected]ab838892009-06-30 18:49:05410 ClientSocketHandle* handle,
[email protected]684970b2009-08-14 04:54:46411 CompletionCallback* callback,
[email protected]9e743cd2010-03-16 07:03:53412 const BoundNetLog& net_log) {
[email protected]df4b4ef2010-07-12 18:25:21413 const scoped_refptr<TestSocketParams>* casted_socket_params =
414 static_cast<const scoped_refptr<TestSocketParams>*>(params);
415 return base_.RequestSocket(group_name, *casted_socket_params, priority,
416 handle, callback, net_log);
[email protected]ab838892009-06-30 18:49:05417 }
418
[email protected]2c2bef152010-10-13 00:55:03419 virtual void RequestSockets(const std::string& group_name,
420 const void* params,
421 int num_sockets,
422 const BoundNetLog& net_log) {
423 const scoped_refptr<TestSocketParams>* casted_params =
424 static_cast<const scoped_refptr<TestSocketParams>*>(params);
425
426 base_.RequestSockets(group_name, *casted_params, num_sockets, net_log);
427 }
428
[email protected]ab838892009-06-30 18:49:05429 virtual void CancelRequest(
430 const std::string& group_name,
[email protected]05ea9ff2010-07-15 19:08:21431 ClientSocketHandle* handle) {
[email protected]d80a4322009-08-14 07:07:49432 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05433 }
434
435 virtual void ReleaseSocket(
436 const std::string& group_name,
[email protected]3268023f2011-05-05 00:08:10437 StreamSocket* socket,
[email protected]a7e38572010-06-07 18:22:24438 int id) {
439 base_.ReleaseSocket(group_name, socket, id);
440 }
441
442 virtual void Flush() {
443 base_.Flush();
[email protected]ab838892009-06-30 18:49:05444 }
445
446 virtual void CloseIdleSockets() {
[email protected]d80a4322009-08-14 07:07:49447 base_.CloseIdleSockets();
[email protected]ab838892009-06-30 18:49:05448 }
449
[email protected]d80a4322009-08-14 07:07:49450 virtual int IdleSocketCount() const { return base_.idle_socket_count(); }
[email protected]ab838892009-06-30 18:49:05451
452 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49453 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05454 }
455
456 virtual LoadState GetLoadState(const std::string& group_name,
457 const ClientSocketHandle* handle) const {
[email protected]d80a4322009-08-14 07:07:49458 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05459 }
460
[email protected]ba00b492010-09-08 14:53:38461 virtual DictionaryValue* GetInfoAsValue(const std::string& name,
462 const std::string& type,
463 bool include_nested_pools) const {
[email protected]59d7a5a2010-08-30 16:44:27464 return base_.GetInfoAsValue(name, type);
465 }
466
[email protected]a796bcec2010-03-22 17:17:26467 virtual base::TimeDelta ConnectionTimeout() const {
468 return base_.ConnectionTimeout();
469 }
470
[email protected]2431756e2010-09-29 20:26:13471 virtual ClientSocketPoolHistograms* histograms() const {
[email protected]b89f7e42010-05-20 20:37:00472 return base_.histograms();
473 }
[email protected]a796bcec2010-03-22 17:17:26474
[email protected]d80a4322009-08-14 07:07:49475 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20476
[email protected]974ebd62009-08-03 23:14:34477 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49478 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34479 }
480
[email protected]2c2bef152010-10-13 00:55:03481 int NumActiveSocketsInGroup(const std::string& group_name) const {
482 return base_.NumActiveSocketsInGroup(group_name);
483 }
484
[email protected]2abfe90a2010-08-25 17:49:51485 bool HasGroup(const std::string& group_name) const {
486 return base_.HasGroup(group_name);
487 }
488
[email protected]9bf28db2009-08-29 01:35:16489 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
490
[email protected]06d94042010-08-25 01:45:22491 void EnableConnectBackupJobs() { base_.EnableConnectBackupJobs(); }
[email protected]43a21b82010-06-10 21:30:54492
[email protected]ab838892009-06-30 18:49:05493 private:
[email protected]d80a4322009-08-14 07:07:49494 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05495
496 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
497};
498
[email protected]a937a06d2009-08-19 21:19:24499} // namespace
500
[email protected]7fc5b09a2010-02-27 00:07:38501REGISTER_SOCKET_PARAMS_FOR_POOL(TestClientSocketPool, TestSocketParams);
[email protected]a937a06d2009-08-19 21:19:24502
503namespace {
504
[email protected]5fc08e32009-07-15 17:09:57505void MockClientSocketFactory::SignalJobs() {
506 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
507 it != waiting_jobs_.end(); ++it) {
508 (*it)->Signal();
509 }
510 waiting_jobs_.clear();
511}
512
[email protected]974ebd62009-08-03 23:14:34513class TestConnectJobDelegate : public ConnectJob::Delegate {
514 public:
515 TestConnectJobDelegate()
516 : have_result_(false), waiting_for_result_(false), result_(OK) {}
517 virtual ~TestConnectJobDelegate() {}
518
519 virtual void OnConnectJobComplete(int result, ConnectJob* job) {
520 result_ = result;
[email protected]3268023f2011-05-05 00:08:10521 scoped_ptr<StreamSocket> socket(job->ReleaseSocket());
[email protected]9b6fee12009-09-29 18:13:07522 // socket.get() should be NULL iff result != OK
523 EXPECT_EQ(socket.get() == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34524 delete job;
525 have_result_ = true;
526 if (waiting_for_result_)
527 MessageLoop::current()->Quit();
528 }
529
530 int WaitForResult() {
531 DCHECK(!waiting_for_result_);
532 while (!have_result_) {
533 waiting_for_result_ = true;
534 MessageLoop::current()->Run();
535 waiting_for_result_ = false;
536 }
537 have_result_ = false; // auto-reset for next callback
538 return result_;
539 }
540
541 private:
542 bool have_result_;
543 bool waiting_for_result_;
544 int result_;
545};
546
[email protected]2431756e2010-09-29 20:26:13547class ClientSocketPoolBaseTest : public testing::Test {
[email protected]f6d1d6eb2009-06-24 20:16:09548 protected:
[email protected]b89f7e42010-05-20 20:37:00549 ClientSocketPoolBaseTest()
[email protected]df4b4ef2010-07-12 18:25:21550 : params_(new TestSocketParams()),
[email protected]636b8252011-04-08 19:56:54551 histograms_("ClientSocketPoolTest") {
552 connect_backup_jobs_enabled_ =
553 internal::ClientSocketPoolBaseHelper::connect_backup_jobs_enabled();
554 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(true);
555 }
[email protected]2431756e2010-09-29 20:26:13556
[email protected]636b8252011-04-08 19:56:54557 virtual ~ClientSocketPoolBaseTest() {
558 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
559 connect_backup_jobs_enabled_);
560 }
[email protected]c9d6a1d2009-07-14 16:15:20561
[email protected]211d21722009-07-22 15:48:53562 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16563 CreatePoolWithIdleTimeouts(
564 max_sockets,
565 max_sockets_per_group,
[email protected]241c5c2c2010-06-21 18:46:00566 base::TimeDelta::FromSeconds(
567 ClientSocketPool::unused_idle_socket_timeout()),
[email protected]9bf28db2009-08-29 01:35:16568 base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout));
569 }
570
571 void CreatePoolWithIdleTimeouts(
572 int max_sockets, int max_sockets_per_group,
573 base::TimeDelta unused_idle_socket_timeout,
574 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20575 DCHECK(!pool_.get());
[email protected]17a0c6c2009-08-04 00:07:04576 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_);
[email protected]2431756e2010-09-29 20:26:13577 pool_.reset(new TestClientSocketPool(max_sockets,
578 max_sockets_per_group,
579 &histograms_,
580 unused_idle_socket_timeout,
581 used_idle_socket_timeout,
582 connect_job_factory_));
[email protected]c9d6a1d2009-07-14 16:15:20583 }
[email protected]f6d1d6eb2009-06-24 20:16:09584
[email protected]ac790b42009-12-02 04:31:31585 int StartRequest(const std::string& group_name,
586 net::RequestPriority priority) {
[email protected]2431756e2010-09-29 20:26:13587 return test_base_.StartRequestUsingPool<
588 TestClientSocketPool, TestSocketParams>(
589 pool_.get(), group_name, priority, params_);
[email protected]f6d1d6eb2009-06-24 20:16:09590 }
591
[email protected]2431756e2010-09-29 20:26:13592 int GetOrderOfRequest(size_t index) const {
593 return test_base_.GetOrderOfRequest(index);
[email protected]f6d1d6eb2009-06-24 20:16:09594 }
595
[email protected]2431756e2010-09-29 20:26:13596 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
597 return test_base_.ReleaseOneConnection(keep_alive);
598 }
599
600 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
601 test_base_.ReleaseAllConnections(keep_alive);
602 }
603
604 TestSocketRequest* request(int i) { return test_base_.request(i); }
605 size_t requests_size() const { return test_base_.requests_size(); }
606 ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); }
607 size_t completion_count() const { return test_base_.completion_count(); }
608
[email protected]636b8252011-04-08 19:56:54609 bool connect_backup_jobs_enabled_;
[email protected]f6d1d6eb2009-06-24 20:16:09610 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04611 TestConnectJobFactory* connect_job_factory_;
[email protected]df4b4ef2010-07-12 18:25:21612 scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:13613 ClientSocketPoolHistograms histograms_;
614 scoped_ptr<TestClientSocketPool> pool_;
615 ClientSocketPoolTest test_base_;
[email protected]f6d1d6eb2009-06-24 20:16:09616};
617
[email protected]5e6efa52011-06-27 17:26:41618TEST_F(ClientSocketPoolBaseTest, AssignIdleSocketToGroup_WarmestSocket) {
619 CreatePool(4, 4);
620 net::SetSocketReusePolicy(0);
621
622 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
623 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
624 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
625 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
626
627 std::map<int, StreamSocket*> sockets_;
628 for (size_t i = 0; i < test_base_.requests_size(); i++) {
629 TestSocketRequest* req = test_base_.request(i);
630 StreamSocket* s = req->handle()->socket();
631 MockClientSocket* sock = static_cast<MockClientSocket*>(s);
632 CHECK(sock);
633 sockets_[i] = sock;
634 sock->Read(NULL, 1024 - i, NULL);
635 }
636
637 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
638
639 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
640 TestSocketRequest* req = test_base_.request(test_base_.requests_size() - 1);
641
642 // First socket is warmest.
643 EXPECT_EQ(sockets_[0], req->handle()->socket());
644
645 // Test that NumBytes are as expected.
646 EXPECT_EQ(1024, sockets_[0]->NumBytesRead());
647 EXPECT_EQ(1023, sockets_[1]->NumBytesRead());
648 EXPECT_EQ(1022, sockets_[2]->NumBytesRead());
649 EXPECT_EQ(1021, sockets_[3]->NumBytesRead());
650
651 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
652}
653
654TEST_F(ClientSocketPoolBaseTest, AssignIdleSocketToGroup_LastAccessedSocket) {
655 CreatePool(4, 4);
656 net::SetSocketReusePolicy(2);
657
658 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
659 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
660 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
661 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
662
663 std::map<int, StreamSocket*> sockets_;
664 for (size_t i = 0; i < test_base_.requests_size(); i++) {
665 TestSocketRequest* req = test_base_.request(i);
666 StreamSocket* s = req->handle()->socket();
667 MockClientSocket* sock = static_cast<MockClientSocket*>(s);
668 CHECK(sock);
669 sockets_[i] = sock;
670 sock->Read(NULL, 1024 - i, NULL);
671 }
672
673 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
674
675 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
676 TestSocketRequest* req = test_base_.request(test_base_.requests_size() - 1);
677
678 // Last socket is most recently accessed.
679 EXPECT_EQ(sockets_[3], req->handle()->socket());
680 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
681}
682
[email protected]974ebd62009-08-03 23:14:34683// Even though a timeout is specified, it doesn't time out on a synchronous
684// completion.
685TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
686 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06687 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49688 TestClientSocketPoolBase::Request request(
[email protected]2c2bef152010-10-13 00:55:03689 &ignored, NULL, kDefaultPriority,
690 internal::ClientSocketPoolBaseHelper::NORMAL,
[email protected]5acdce12011-03-30 13:00:20691 false, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34692 scoped_ptr<TestConnectJob> job(
693 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:12694 "a",
[email protected]974ebd62009-08-03 23:14:34695 request,
696 base::TimeDelta::FromMicroseconds(1),
697 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30698 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17699 NULL));
[email protected]974ebd62009-08-03 23:14:34700 EXPECT_EQ(OK, job->Connect());
701}
702
703TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
704 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06705 ClientSocketHandle ignored;
[email protected]06650c52010-06-03 00:49:17706 CapturingNetLog log(CapturingNetLog::kUnbounded);
[email protected]9e743cd2010-03-16 07:03:53707
[email protected]d80a4322009-08-14 07:07:49708 TestClientSocketPoolBase::Request request(
[email protected]2c2bef152010-10-13 00:55:03709 &ignored, NULL, kDefaultPriority,
710 internal::ClientSocketPoolBaseHelper::NORMAL,
[email protected]5acdce12011-03-30 13:00:20711 false, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34712 // Deleted by TestConnectJobDelegate.
713 TestConnectJob* job =
714 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12715 "a",
[email protected]974ebd62009-08-03 23:14:34716 request,
717 base::TimeDelta::FromMicroseconds(1),
718 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30719 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17720 &log);
[email protected]974ebd62009-08-03 23:14:34721 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
[email protected]f214f8792011-01-01 02:17:08722 base::PlatformThread::Sleep(1);
[email protected]974ebd62009-08-03 23:14:34723 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30724
[email protected]b2fcd0e2010-12-01 15:19:40725 net::CapturingNetLog::EntryList entries;
726 log.GetEntries(&entries);
727
728 EXPECT_EQ(6u, entries.size());
[email protected]e9002a92010-01-29 07:10:46729 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40730 entries, 0, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]06650c52010-06-03 00:49:17731 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40732 entries, 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]e9002a92010-01-29 07:10:46733 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40734 entries, 2, NetLog::TYPE_CONNECT_JOB_SET_SOCKET,
[email protected]06650c52010-06-03 00:49:17735 NetLog::PHASE_NONE));
736 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40737 entries, 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
[email protected]9e743cd2010-03-16 07:03:53738 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:46739 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40740 entries, 4, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]06650c52010-06-03 00:49:17741 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40742 entries, 5, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34743}
744
[email protected]5fc08e32009-07-15 17:09:57745TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53746 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20747
[email protected]f6d1d6eb2009-06-24 20:16:09748 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06749 ClientSocketHandle handle;
[email protected]9e743cd2010-03-16 07:03:53750 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
751
[email protected]2431756e2010-09-29 20:26:13752 EXPECT_EQ(OK,
753 handle.Init("a",
754 params_,
755 kDefaultPriority,
756 &callback,
757 pool_.get(),
758 log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09759 EXPECT_TRUE(handle.is_initialized());
760 EXPECT_TRUE(handle.socket());
[email protected]f6d1d6eb2009-06-24 20:16:09761 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:30762
[email protected]b2fcd0e2010-12-01 15:19:40763 net::CapturingNetLog::EntryList entries;
764 log.GetEntries(&entries);
765
766 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:46767 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40768 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]9e743cd2010-03-16 07:03:53769 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40770 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:17771 NetLog::PHASE_NONE));
772 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40773 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]9e743cd2010-03-16 07:03:53774 NetLog::PHASE_NONE));
775 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40776 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09777}
778
[email protected]ab838892009-06-30 18:49:05779TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53780 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20781
[email protected]ab838892009-06-30 18:49:05782 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]9e743cd2010-03-16 07:03:53783 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
784
[email protected]2431756e2010-09-29 20:26:13785 ClientSocketHandle handle;
786 TestCompletionCallback callback;
[email protected]e60e47a2010-07-14 03:37:18787 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:13788 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43789 HttpResponseInfo info;
790 info.headers = new HttpResponseHeaders("");
[email protected]2431756e2010-09-29 20:26:13791 handle.set_ssl_error_response_info(info);
792 EXPECT_EQ(ERR_CONNECTION_FAILED,
793 handle.Init("a",
794 params_,
795 kDefaultPriority,
796 &callback,
797 pool_.get(),
798 log.bound()));
799 EXPECT_FALSE(handle.socket());
800 EXPECT_FALSE(handle.is_ssl_error());
801 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:30802
[email protected]b2fcd0e2010-12-01 15:19:40803 net::CapturingNetLog::EntryList entries;
804 log.GetEntries(&entries);
805
806 EXPECT_EQ(3u, entries.size());
[email protected]5a1d7ca2010-04-28 20:12:27807 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40808 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:17809 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40810 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:17811 NetLog::PHASE_NONE));
[email protected]a2006ece2010-04-23 16:44:02812 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40813 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09814}
815
[email protected]211d21722009-07-22 15:48:53816TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
817 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
818
[email protected]9e743cd2010-03-16 07:03:53819 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30820
[email protected]211d21722009-07-22 15:48:53821 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
822 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
823 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
824 EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
825
[email protected]2431756e2010-09-29 20:26:13826 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53827 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13828 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53829
830 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
831 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
832 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
833
[email protected]2431756e2010-09-29 20:26:13834 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53835
[email protected]2431756e2010-09-29 20:26:13836 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53837 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13838 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53839
840 EXPECT_EQ(1, GetOrderOfRequest(1));
841 EXPECT_EQ(2, GetOrderOfRequest(2));
842 EXPECT_EQ(3, GetOrderOfRequest(3));
843 EXPECT_EQ(4, GetOrderOfRequest(4));
844 EXPECT_EQ(5, GetOrderOfRequest(5));
845 EXPECT_EQ(6, GetOrderOfRequest(6));
846 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17847
848 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13849 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53850}
851
852TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
853 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
854
[email protected]9e743cd2010-03-16 07:03:53855 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30856
[email protected]211d21722009-07-22 15:48:53857 // Reach all limits: max total sockets, and max sockets per group.
858 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
859 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
860 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
861 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
862
[email protected]2431756e2010-09-29 20:26:13863 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53864 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13865 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53866
867 // Now create a new group and verify that we don't starve it.
868 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
869
[email protected]2431756e2010-09-29 20:26:13870 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53871
[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(1, GetOrderOfRequest(1));
877 EXPECT_EQ(2, GetOrderOfRequest(2));
878 EXPECT_EQ(3, GetOrderOfRequest(3));
879 EXPECT_EQ(4, GetOrderOfRequest(4));
880 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17881
882 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13883 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53884}
885
886TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
887 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
888
[email protected]ac790b42009-12-02 04:31:31889 EXPECT_EQ(OK, StartRequest("b", LOWEST));
890 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
891 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
892 EXPECT_EQ(OK, StartRequest("a", LOWEST));
[email protected]211d21722009-07-22 15:48:53893
[email protected]2431756e2010-09-29 20:26:13894 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53895 client_socket_factory_.allocation_count());
896
[email protected]ac790b42009-12-02 04:31:31897 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
898 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
899 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53900
[email protected]2431756e2010-09-29 20:26:13901 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53902
[email protected]2431756e2010-09-29 20:26:13903 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53904
905 // First 4 requests don't have to wait, and finish in order.
906 EXPECT_EQ(1, GetOrderOfRequest(1));
907 EXPECT_EQ(2, GetOrderOfRequest(2));
908 EXPECT_EQ(3, GetOrderOfRequest(3));
909 EXPECT_EQ(4, GetOrderOfRequest(4));
910
[email protected]ac790b42009-12-02 04:31:31911 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
912 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53913 EXPECT_EQ(7, GetOrderOfRequest(5));
914 EXPECT_EQ(6, GetOrderOfRequest(6));
915 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17916
917 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13918 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]211d21722009-07-22 15:48:53919}
920
921TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
922 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
923
[email protected]ac790b42009-12-02 04:31:31924 EXPECT_EQ(OK, StartRequest("a", LOWEST));
925 EXPECT_EQ(OK, StartRequest("a", LOW));
926 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
927 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
[email protected]211d21722009-07-22 15:48:53928
[email protected]2431756e2010-09-29 20:26:13929 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53930 client_socket_factory_.allocation_count());
931
[email protected]ac790b42009-12-02 04:31:31932 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
933 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
934 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53935
[email protected]2431756e2010-09-29 20:26:13936 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53937
[email protected]2431756e2010-09-29 20:26:13938 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53939 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13940 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53941
942 // First 4 requests don't have to wait, and finish in order.
943 EXPECT_EQ(1, GetOrderOfRequest(1));
944 EXPECT_EQ(2, GetOrderOfRequest(2));
945 EXPECT_EQ(3, GetOrderOfRequest(3));
946 EXPECT_EQ(4, GetOrderOfRequest(4));
947
948 // Request ("b", 7) has the highest priority, but we can't make new socket for
949 // group "b", because it has reached the per-group limit. Then we make
950 // socket for ("c", 6), because it has higher priority than ("a", 4),
951 // and we still can't make a socket for group "b".
952 EXPECT_EQ(5, GetOrderOfRequest(5));
953 EXPECT_EQ(6, GetOrderOfRequest(6));
954 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17955
956 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13957 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53958}
959
960// Make sure that we count connecting sockets against the total limit.
961TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
962 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
963
964 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
965 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
966 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
967
968 // Create one asynchronous request.
969 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
970 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
971
[email protected]6b175382009-10-13 06:47:47972 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
973 // actually become pending until 2ms after they have been created. In order
974 // to flush all tasks, we need to wait so that we know there are no
975 // soon-to-be-pending tasks waiting.
[email protected]f214f8792011-01-01 02:17:08976 base::PlatformThread::Sleep(10);
[email protected]6b175382009-10-13 06:47:47977 MessageLoop::current()->RunAllPending();
978
[email protected]211d21722009-07-22 15:48:53979 // The next synchronous request should wait for its turn.
980 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
981 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
982
[email protected]2431756e2010-09-29 20:26:13983 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53984
[email protected]2431756e2010-09-29 20:26:13985 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53986 client_socket_factory_.allocation_count());
987
988 EXPECT_EQ(1, GetOrderOfRequest(1));
989 EXPECT_EQ(2, GetOrderOfRequest(2));
990 EXPECT_EQ(3, GetOrderOfRequest(3));
991 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:17992 EXPECT_EQ(5, GetOrderOfRequest(5));
993
994 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13995 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53996}
997
[email protected]6427fe22010-04-16 22:27:41998TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
999 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1000 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1001
1002 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1003 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1004 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1005 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1006
1007 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1008
1009 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1010
1011 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", kDefaultPriority));
1012 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
1013
1014 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1015
[email protected]2431756e2010-09-29 20:26:131016 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411017 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131018 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411019 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131020 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1021 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411022 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
1023}
1024
[email protected]d7027bb2010-05-10 18:58:541025TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
1026 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1027 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1028
1029 ClientSocketHandle handle;
1030 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131031 EXPECT_EQ(ERR_IO_PENDING,
1032 handle.Init("a",
1033 params_,
1034 kDefaultPriority,
1035 &callback,
1036 pool_.get(),
1037 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541038
1039 ClientSocketHandle handles[4];
1040 for (size_t i = 0; i < arraysize(handles); ++i) {
1041 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131042 EXPECT_EQ(ERR_IO_PENDING,
1043 handles[i].Init("b",
1044 params_,
1045 kDefaultPriority,
1046 &callback,
1047 pool_.get(),
1048 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541049 }
1050
1051 // One will be stalled, cancel all the handles now.
1052 // This should hit the OnAvailableSocketSlot() code where we previously had
1053 // stalled groups, but no longer have any.
1054 for (size_t i = 0; i < arraysize(handles); ++i)
1055 handles[i].Reset();
1056}
1057
[email protected]eb5a99382010-07-11 03:18:261058TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:541059 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1060 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1061
[email protected]eb5a99382010-07-11 03:18:261062 {
1063 ClientSocketHandle handles[kDefaultMaxSockets];
1064 TestCompletionCallback callbacks[kDefaultMaxSockets];
1065 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]2431756e2010-09-29 20:26:131066 EXPECT_EQ(OK, handles[i].Init(base::IntToString(i),
1067 params_,
[email protected]e83326f2010-07-31 17:29:251068 kDefaultPriority,
[email protected]2431756e2010-09-29 20:26:131069 &callbacks[i],
1070 pool_.get(),
1071 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261072 }
1073
1074 // Force a stalled group.
1075 ClientSocketHandle stalled_handle;
[email protected]43a21b82010-06-10 21:30:541076 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131077 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1078 params_,
1079 kDefaultPriority,
1080 &callback,
1081 pool_.get(),
1082 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261083
1084 // Cancel the stalled request.
1085 stalled_handle.Reset();
1086
1087 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1088 EXPECT_EQ(0, pool_->IdleSocketCount());
1089
1090 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541091 }
1092
[email protected]43a21b82010-06-10 21:30:541093 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1094 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:261095}
[email protected]43a21b82010-06-10 21:30:541096
[email protected]eb5a99382010-07-11 03:18:261097TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
1098 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1099 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1100
1101 {
1102 ClientSocketHandle handles[kDefaultMaxSockets];
1103 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1104 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131105 EXPECT_EQ(ERR_IO_PENDING, handles[i].Init(base::IntToString(i),
1106 params_,
1107 kDefaultPriority,
1108 &callback,
1109 pool_.get(),
1110 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261111 }
1112
1113 // Force a stalled group.
1114 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1115 ClientSocketHandle stalled_handle;
[email protected]43a21b82010-06-10 21:30:541116 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131117 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1118 params_,
1119 kDefaultPriority,
1120 &callback,
1121 pool_.get(),
1122 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261123
1124 // Since it is stalled, it should have no connect jobs.
1125 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
1126
1127 // Cancel the stalled request.
1128 handles[0].Reset();
1129
[email protected]eb5a99382010-07-11 03:18:261130 // Now we should have a connect job.
1131 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("foo"));
1132
1133 // The stalled socket should connect.
1134 EXPECT_EQ(OK, callback.WaitForResult());
1135
1136 EXPECT_EQ(kDefaultMaxSockets + 1,
1137 client_socket_factory_.allocation_count());
1138 EXPECT_EQ(0, pool_->IdleSocketCount());
1139 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
1140
1141 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541142 }
1143
[email protected]eb5a99382010-07-11 03:18:261144 EXPECT_EQ(1, pool_->IdleSocketCount());
1145}
[email protected]43a21b82010-06-10 21:30:541146
[email protected]eb5a99382010-07-11 03:18:261147TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1148 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1149 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:541150
[email protected]eb5a99382010-07-11 03:18:261151 ClientSocketHandle stalled_handle;
1152 TestCompletionCallback callback;
1153 {
1154 ClientSocketHandle handles[kDefaultMaxSockets];
1155 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1156 TestCompletionCallback callback;
[email protected]1870d5cf2011-05-12 01:55:401157 EXPECT_EQ(OK, handles[i].Init(base::StringPrintf(
1158 "Take 2: %d", i),
1159 params_,
1160 kDefaultPriority,
1161 &callback,
1162 pool_.get(),
1163 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261164 }
1165
1166 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1167 EXPECT_EQ(0, pool_->IdleSocketCount());
1168
1169 // Now we will hit the socket limit.
[email protected]2431756e2010-09-29 20:26:131170 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1171 params_,
1172 kDefaultPriority,
1173 &callback,
1174 pool_.get(),
1175 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261176
1177 // Dropping out of scope will close all handles and return them to idle.
1178 }
[email protected]43a21b82010-06-10 21:30:541179
1180 // But if we wait for it, the released idle sockets will be closed in
1181 // preference of the waiting request.
[email protected]8ae03f42010-07-07 19:08:101182 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]eb5a99382010-07-11 03:18:261183
1184 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1185 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:541186}
1187
1188// Regression test for http://crbug.com/40952.
1189TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1190 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]06d94042010-08-25 01:45:221191 pool_->EnableConnectBackupJobs();
[email protected]43a21b82010-06-10 21:30:541192 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1193
1194 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1195 ClientSocketHandle handle;
1196 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131197 EXPECT_EQ(OK, handle.Init(base::IntToString(i),
1198 params_,
1199 kDefaultPriority,
1200 &callback,
1201 pool_.get(),
1202 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541203 }
1204
1205 // Flush all the DoReleaseSocket tasks.
1206 MessageLoop::current()->RunAllPending();
1207
1208 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1209 // reuse a socket.
1210 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1211 ClientSocketHandle handle;
1212 TestCompletionCallback callback;
1213
1214 // "0" is special here, since it should be the first entry in the sorted map,
1215 // which is the one which we would close an idle socket for. We shouldn't
1216 // close an idle socket though, since we should reuse the idle socket.
[email protected]2431756e2010-09-29 20:26:131217 EXPECT_EQ(OK, handle.Init("0",
1218 params_,
1219 kDefaultPriority,
1220 &callback,
1221 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211222 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541223
1224 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1225 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1226}
1227
[email protected]ab838892009-06-30 18:49:051228TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531229 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091230
[email protected]c9d6a1d2009-07-14 16:15:201231 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1232 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]c9c6f5c2010-07-31 01:30:031233 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", IDLE));
[email protected]ac790b42009-12-02 04:31:311234 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1235 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1236 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1237 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1238 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091239
[email protected]2431756e2010-09-29 20:26:131240 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091241
[email protected]c9d6a1d2009-07-14 16:15:201242 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1243 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131244 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1245 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091246
[email protected]c9d6a1d2009-07-14 16:15:201247 EXPECT_EQ(1, GetOrderOfRequest(1));
1248 EXPECT_EQ(2, GetOrderOfRequest(2));
[email protected]c9c6f5c2010-07-31 01:30:031249 EXPECT_EQ(8, GetOrderOfRequest(3));
1250 EXPECT_EQ(6, GetOrderOfRequest(4));
1251 EXPECT_EQ(4, GetOrderOfRequest(5));
1252 EXPECT_EQ(3, GetOrderOfRequest(6));
1253 EXPECT_EQ(5, GetOrderOfRequest(7));
1254 EXPECT_EQ(7, GetOrderOfRequest(8));
[email protected]75439d3b2009-07-23 22:11:171255
1256 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131257 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]f6d1d6eb2009-06-24 20:16:091258}
1259
[email protected]ab838892009-06-30 18:49:051260TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531261 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091262
[email protected]c9d6a1d2009-07-14 16:15:201263 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1264 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311265 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1266 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1267 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1268 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1269 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091270
[email protected]2431756e2010-09-29 20:26:131271 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091272
[email protected]2431756e2010-09-29 20:26:131273 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
1274 EXPECT_EQ(OK, request(i)->WaitForResult());
[email protected]c9d6a1d2009-07-14 16:15:201275
[email protected]2431756e2010-09-29 20:26:131276 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]c9d6a1d2009-07-14 16:15:201277 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131278 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1279 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091280}
1281
1282// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:051283// The pending connect job will be cancelled and should not call back into
1284// ClientSocketPoolBase.
1285TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531286 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201287
[email protected]ab838892009-06-30 18:49:051288 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131289 ClientSocketHandle handle;
1290 TestCompletionCallback callback;
1291 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1292 params_,
1293 kDefaultPriority,
1294 &callback,
1295 pool_.get(),
1296 BoundNetLog()));
1297 handle.Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091298}
1299
[email protected]ab838892009-06-30 18:49:051300TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531301 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201302
[email protected]ab838892009-06-30 18:49:051303 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061304 ClientSocketHandle handle;
[email protected]f6d1d6eb2009-06-24 20:16:091305 TestCompletionCallback callback;
[email protected]f6d1d6eb2009-06-24 20:16:091306
[email protected]2431756e2010-09-29 20:26:131307 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1308 params_,
1309 kDefaultPriority,
1310 &callback,
1311 pool_.get(),
1312 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091313
1314 handle.Reset();
1315
1316 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:131317 EXPECT_EQ(ERR_IO_PENDING,
1318 handle.Init("a",
1319 params_,
1320 kDefaultPriority,
1321 &callback2,
1322 pool_.get(),
1323 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091324
1325 EXPECT_EQ(OK, callback2.WaitForResult());
1326 EXPECT_FALSE(callback.have_result());
1327
1328 handle.Reset();
1329}
1330
[email protected]ab838892009-06-30 18:49:051331TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531332 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091333
[email protected]c9d6a1d2009-07-14 16:15:201334 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1335 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311336 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1337 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1338 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1339 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1340 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091341
1342 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201343 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]2431756e2010-09-29 20:26:131344 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1345 (*requests())[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091346
[email protected]2431756e2010-09-29 20:26:131347 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091348
[email protected]c9d6a1d2009-07-14 16:15:201349 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1350 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131351 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1352 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091353
[email protected]c9d6a1d2009-07-14 16:15:201354 EXPECT_EQ(1, GetOrderOfRequest(1));
1355 EXPECT_EQ(2, GetOrderOfRequest(2));
1356 EXPECT_EQ(5, GetOrderOfRequest(3));
1357 EXPECT_EQ(3, GetOrderOfRequest(4));
[email protected]2431756e2010-09-29 20:26:131358 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1359 GetOrderOfRequest(5)); // Canceled request.
[email protected]c9d6a1d2009-07-14 16:15:201360 EXPECT_EQ(4, GetOrderOfRequest(6));
1361 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171362
1363 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131364 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091365}
1366
1367class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
1368 public:
[email protected]2ab05b52009-07-01 23:57:581369 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:241370 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:581371 TestConnectJobFactory* test_connect_job_factory,
1372 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:091373 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:061374 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:581375 within_callback_(false),
1376 test_connect_job_factory_(test_connect_job_factory),
1377 next_job_type_(next_job_type) {}
[email protected]f6d1d6eb2009-06-24 20:16:091378
1379 virtual void RunWithParams(const Tuple1<int>& params) {
1380 callback_.RunWithParams(params);
1381 ASSERT_EQ(OK, params.a);
1382
1383 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:581384 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]5edbf8d2010-01-13 18:44:111385
1386 // Don't allow reuse of the socket. Disconnect it and then release it and
1387 // run through the MessageLoop once to get it completely released.
1388 handle_->socket()->Disconnect();
[email protected]f6d1d6eb2009-06-24 20:16:091389 handle_->Reset();
[email protected]5edbf8d2010-01-13 18:44:111390 {
1391 MessageLoop::ScopedNestableTaskAllower nestable(
1392 MessageLoop::current());
1393 MessageLoop::current()->RunAllPending();
1394 }
[email protected]f6d1d6eb2009-06-24 20:16:091395 within_callback_ = true;
[email protected]6b175382009-10-13 06:47:471396 TestCompletionCallback next_job_callback;
[email protected]ad8e04a2010-11-01 04:16:271397 scoped_refptr<TestSocketParams> params(new TestSocketParams());
[email protected]2431756e2010-09-29 20:26:131398 int rv = handle_->Init("a",
1399 params,
1400 kDefaultPriority,
1401 &next_job_callback,
1402 pool_,
1403 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581404 switch (next_job_type_) {
1405 case TestConnectJob::kMockJob:
1406 EXPECT_EQ(OK, rv);
1407 break;
1408 case TestConnectJob::kMockPendingJob:
1409 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:471410
1411 // For pending jobs, wait for new socket to be created. This makes
1412 // sure there are no more pending operations nor any unclosed sockets
1413 // when the test finishes.
1414 // We need to give it a little bit of time to run, so that all the
1415 // operations that happen on timers (e.g. cleanup of idle
1416 // connections) can execute.
[email protected]5edbf8d2010-01-13 18:44:111417 {
1418 MessageLoop::ScopedNestableTaskAllower nestable(
1419 MessageLoop::current());
[email protected]f214f8792011-01-01 02:17:081420 base::PlatformThread::Sleep(10);
[email protected]5edbf8d2010-01-13 18:44:111421 EXPECT_EQ(OK, next_job_callback.WaitForResult());
1422 }
[email protected]2ab05b52009-07-01 23:57:581423 break;
1424 default:
1425 FAIL() << "Unexpected job type: " << next_job_type_;
1426 break;
1427 }
[email protected]f6d1d6eb2009-06-24 20:16:091428 }
1429 }
1430
1431 int WaitForResult() {
1432 return callback_.WaitForResult();
1433 }
1434
1435 private:
1436 ClientSocketHandle* const handle_;
[email protected]2431756e2010-09-29 20:26:131437 TestClientSocketPool* const pool_;
[email protected]f6d1d6eb2009-06-24 20:16:091438 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:581439 TestConnectJobFactory* const test_connect_job_factory_;
1440 TestConnectJob::JobType next_job_type_;
[email protected]f6d1d6eb2009-06-24 20:16:091441 TestCompletionCallback callback_;
1442};
1443
[email protected]2ab05b52009-07-01 23:57:581444TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531445 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201446
[email protected]0b7648c2009-07-06 20:14:011447 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061448 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581449 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061450 &handle, pool_.get(), connect_job_factory_,
1451 TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131452 int rv = handle.Init("a",
1453 params_,
1454 kDefaultPriority,
1455 &callback,
1456 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211457 BoundNetLog());
[email protected]f6d1d6eb2009-06-24 20:16:091458 ASSERT_EQ(ERR_IO_PENDING, rv);
1459
1460 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581461}
[email protected]f6d1d6eb2009-06-24 20:16:091462
[email protected]2ab05b52009-07-01 23:57:581463TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531464 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201465
[email protected]0b7648c2009-07-06 20:14:011466 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061467 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581468 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061469 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]2431756e2010-09-29 20:26:131470 int rv = handle.Init("a",
1471 params_,
1472 kDefaultPriority,
1473 &callback,
1474 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211475 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581476 ASSERT_EQ(ERR_IO_PENDING, rv);
1477
1478 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091479}
1480
1481// Make sure that pending requests get serviced after active requests get
1482// cancelled.
[email protected]ab838892009-06-30 18:49:051483TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531484 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201485
[email protected]0b7648c2009-07-06 20:14:011486 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091487
[email protected]c9d6a1d2009-07-14 16:15:201488 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1489 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1490 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1491 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1492 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1493 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1494 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091495
[email protected]c9d6a1d2009-07-14 16:15:201496 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1497 // Let's cancel them.
1498 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]2431756e2010-09-29 20:26:131499 ASSERT_FALSE(request(i)->handle()->is_initialized());
1500 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091501 }
1502
[email protected]f6d1d6eb2009-06-24 20:16:091503 // Let's wait for the rest to complete now.
[email protected]2431756e2010-09-29 20:26:131504 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
1505 EXPECT_EQ(OK, request(i)->WaitForResult());
1506 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091507 }
1508
[email protected]2431756e2010-09-29 20:26:131509 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1510 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091511}
1512
1513// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051514TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531515 const size_t kMaxSockets = 5;
1516 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201517
[email protected]0b7648c2009-07-06 20:14:011518 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091519
[email protected]211d21722009-07-22 15:48:531520 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1521 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091522
1523 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531524 for (size_t i = 0; i < kNumberOfRequests; ++i)
1525 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091526
[email protected]211d21722009-07-22 15:48:531527 for (size_t i = 0; i < kNumberOfRequests; ++i)
[email protected]2431756e2010-09-29 20:26:131528 EXPECT_EQ(ERR_CONNECTION_FAILED, request(i)->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091529}
1530
[email protected]5fc08e32009-07-15 17:09:571531TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531532 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571533
1534 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1535
[email protected]2431756e2010-09-29 20:26:131536 ClientSocketHandle handle;
1537 TestCompletionCallback callback;
1538 int rv = handle.Init("a",
1539 params_,
1540 kDefaultPriority,
1541 &callback,
1542 pool_.get(),
1543 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571544 EXPECT_EQ(ERR_IO_PENDING, rv);
1545
1546 // Cancel the active request.
[email protected]2431756e2010-09-29 20:26:131547 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571548
[email protected]2431756e2010-09-29 20:26:131549 rv = handle.Init("a",
1550 params_,
1551 kDefaultPriority,
1552 &callback,
1553 pool_.get(),
1554 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571555 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131556 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]5fc08e32009-07-15 17:09:571557
[email protected]2431756e2010-09-29 20:26:131558 EXPECT_FALSE(handle.is_reused());
[email protected]5fc08e32009-07-15 17:09:571559 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1560}
1561
[email protected]2b7523d2009-07-29 20:29:231562// Regression test for http://crbug.com/17985.
1563TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1564 const int kMaxSockets = 3;
1565 const int kMaxSocketsPerGroup = 2;
1566 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1567
[email protected]ac790b42009-12-02 04:31:311568 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231569
1570 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1571 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1572
1573 // This is going to be a pending request in an otherwise empty group.
1574 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1575
1576 // Reach the maximum socket limit.
1577 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1578
1579 // Create a stalled group with high priorities.
1580 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1581 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
[email protected]2b7523d2009-07-29 20:29:231582
[email protected]eb5a99382010-07-11 03:18:261583 // Release the first two sockets from "a". Because this is a keepalive,
1584 // the first release will unblock the pending request for "a". The
1585 // second release will unblock a request for "c", becaue it is the next
1586 // high priority socket.
[email protected]2431756e2010-09-29 20:26:131587 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1588 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]2b7523d2009-07-29 20:29:231589
1590 // Closing idle sockets should not get us into trouble, but in the bug
1591 // we were hitting a CHECK here.
[email protected]93054cc12010-06-08 06:12:411592 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]43a21b82010-06-10 21:30:541593 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261594
1595 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]2b7523d2009-07-29 20:29:231596}
1597
[email protected]4d3b05d2010-01-27 21:27:291598TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531599 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571600
1601 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131602 ClientSocketHandle handle;
1603 TestCompletionCallback callback;
[email protected]9e743cd2010-03-16 07:03:531604 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:131605 int rv = handle.Init("a",
1606 params_,
1607 LOWEST,
1608 &callback,
1609 pool_.get(),
1610 log.bound());
[email protected]5fc08e32009-07-15 17:09:571611 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131612 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1613 EXPECT_EQ(OK, callback.WaitForResult());
1614 EXPECT_TRUE(handle.is_initialized());
1615 EXPECT_TRUE(handle.socket());
1616 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:301617
[email protected]b2fcd0e2010-12-01 15:19:401618 net::CapturingNetLog::EntryList entries;
1619 log.GetEntries(&entries);
1620
1621 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:461622 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401623 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171624 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401625 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171626 NetLog::PHASE_NONE));
1627 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401628 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]06650c52010-06-03 00:49:171629 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:461630 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401631 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571632}
1633
[email protected]4d3b05d2010-01-27 21:27:291634TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571635 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531636 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571637
1638 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2431756e2010-09-29 20:26:131639 ClientSocketHandle handle;
1640 TestCompletionCallback callback;
[email protected]9e743cd2010-03-16 07:03:531641 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]e60e47a2010-07-14 03:37:181642 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:131643 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:431644 HttpResponseInfo info;
1645 info.headers = new HttpResponseHeaders("");
[email protected]2431756e2010-09-29 20:26:131646 handle.set_ssl_error_response_info(info);
1647 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1648 params_,
1649 kDefaultPriority,
1650 &callback,
1651 pool_.get(),
1652 log.bound()));
1653 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1654 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1655 EXPECT_FALSE(handle.is_ssl_error());
1656 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:301657
[email protected]b2fcd0e2010-12-01 15:19:401658 net::CapturingNetLog::EntryList entries;
1659 log.GetEntries(&entries);
1660
1661 EXPECT_EQ(3u, entries.size());
[email protected]e9002a92010-01-29 07:10:461662 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401663 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171664 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401665 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171666 NetLog::PHASE_NONE));
[email protected]6b624c62010-03-14 08:37:321667 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401668 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571669}
1670
[email protected]4d3b05d2010-01-27 21:27:291671TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101672 // TODO(eroman): Add back the log expectations! Removed them because the
1673 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531674 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571675
1676 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131677 ClientSocketHandle handle;
1678 TestCompletionCallback callback;
1679 ClientSocketHandle handle2;
1680 TestCompletionCallback callback2;
[email protected]5fc08e32009-07-15 17:09:571681
[email protected]2431756e2010-09-29 20:26:131682 EXPECT_EQ(ERR_IO_PENDING,
1683 handle.Init("a",
1684 params_,
1685 kDefaultPriority,
1686 &callback,
1687 pool_.get(),
1688 BoundNetLog()));
[email protected]9e743cd2010-03-16 07:03:531689 CapturingBoundNetLog log2(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:131690 EXPECT_EQ(ERR_IO_PENDING,
1691 handle2.Init("a",
1692 params_,
1693 kDefaultPriority,
1694 &callback2,
1695 pool_.get(),
1696 BoundNetLog()));
[email protected]5fc08e32009-07-15 17:09:571697
[email protected]2431756e2010-09-29 20:26:131698 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571699
[email protected]fd7b7c92009-08-20 19:38:301700
1701 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301702
[email protected]2431756e2010-09-29 20:26:131703 EXPECT_EQ(OK, callback2.WaitForResult());
1704 handle2.Reset();
[email protected]fd7b7c92009-08-20 19:38:301705
1706 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531707 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571708}
1709
[email protected]4d3b05d2010-01-27 21:27:291710TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341711 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1712
[email protected]17a0c6c2009-08-04 00:07:041713 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1714
[email protected]ac790b42009-12-02 04:31:311715 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1716 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1717 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1718 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341719
1720 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]2431756e2010-09-29 20:26:131721 (*requests())[2]->handle()->Reset();
1722 (*requests())[3]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341723 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1724
[email protected]2431756e2010-09-29 20:26:131725 (*requests())[1]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341726 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1727
[email protected]2431756e2010-09-29 20:26:131728 (*requests())[0]->handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261729 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]974ebd62009-08-03 23:14:341730}
1731
[email protected]5fc08e32009-07-15 17:09:571732// When requests and ConnectJobs are not coupled, the request will get serviced
1733// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291734TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531735 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571736
1737 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321738 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571739
[email protected]2431756e2010-09-29 20:26:131740 std::vector<TestSocketRequest*> request_order;
1741 size_t completion_count; // unused
1742 TestSocketRequest req1(&request_order, &completion_count);
1743 int rv = req1.handle()->Init("a",
1744 params_,
1745 kDefaultPriority,
1746 &req1, pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211747 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571748 EXPECT_EQ(ERR_IO_PENDING, rv);
1749 EXPECT_EQ(OK, req1.WaitForResult());
1750
1751 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1752 // without a job.
1753 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1754
[email protected]2431756e2010-09-29 20:26:131755 TestSocketRequest req2(&request_order, &completion_count);
1756 rv = req2.handle()->Init("a",
1757 params_,
1758 kDefaultPriority,
1759 &req2,
1760 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211761 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571762 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131763 TestSocketRequest req3(&request_order, &completion_count);
1764 rv = req3.handle()->Init("a",
1765 params_,
1766 kDefaultPriority,
1767 &req3,
1768 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211769 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571770 EXPECT_EQ(ERR_IO_PENDING, rv);
1771
1772 // Both Requests 2 and 3 are pending. We release socket 1 which should
1773 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331774 req1.handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261775 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]a6c59f62009-07-29 16:33:331776 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571777 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331778 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571779
1780 // Signal job 2, which should service request 3.
1781
1782 client_socket_factory_.SignalJobs();
1783 EXPECT_EQ(OK, req3.WaitForResult());
1784
[email protected]2431756e2010-09-29 20:26:131785 ASSERT_EQ(3U, request_order.size());
1786 EXPECT_EQ(&req1, request_order[0]);
1787 EXPECT_EQ(&req2, request_order[1]);
1788 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571789 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1790}
1791
1792// The requests are not coupled to the jobs. So, the requests should finish in
1793// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:291794TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531795 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571796 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321797 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571798
[email protected]2431756e2010-09-29 20:26:131799 std::vector<TestSocketRequest*> request_order;
1800 size_t completion_count; // unused
1801 TestSocketRequest req1(&request_order, &completion_count);
1802 int rv = req1.handle()->Init("a",
1803 params_,
1804 kDefaultPriority,
1805 &req1,
1806 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211807 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571808 EXPECT_EQ(ERR_IO_PENDING, rv);
1809
[email protected]2431756e2010-09-29 20:26:131810 TestSocketRequest req2(&request_order, &completion_count);
1811 rv = req2.handle()->Init("a",
1812 params_,
1813 kDefaultPriority,
1814 &req2,
1815 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211816 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571817 EXPECT_EQ(ERR_IO_PENDING, rv);
1818
1819 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321820 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571821
[email protected]2431756e2010-09-29 20:26:131822 TestSocketRequest req3(&request_order, &completion_count);
1823 rv = req3.handle()->Init("a",
1824 params_,
1825 kDefaultPriority,
1826 &req3,
1827 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211828 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571829 EXPECT_EQ(ERR_IO_PENDING, rv);
1830
1831 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1832 EXPECT_EQ(OK, req2.WaitForResult());
1833 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1834
[email protected]2431756e2010-09-29 20:26:131835 ASSERT_EQ(3U, request_order.size());
1836 EXPECT_EQ(&req1, request_order[0]);
1837 EXPECT_EQ(&req2, request_order[1]);
1838 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571839}
1840
[email protected]e6ec67b2010-06-16 00:12:461841TEST_F(ClientSocketPoolBaseTest, LoadState) {
[email protected]211d21722009-07-22 15:48:531842 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571843 connect_job_factory_->set_job_type(
[email protected]b59ff372009-07-15 22:04:321844 TestConnectJob::kMockAdvancingLoadStateJob);
[email protected]5fc08e32009-07-15 17:09:571845
[email protected]2431756e2010-09-29 20:26:131846 ClientSocketHandle handle;
1847 TestCompletionCallback callback;
1848 int rv = handle.Init("a",
1849 params_,
1850 kDefaultPriority,
1851 &callback,
1852 pool_.get(),
1853 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571854 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131855 EXPECT_EQ(LOAD_STATE_IDLE, handle.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571856
1857 MessageLoop::current()->RunAllPending();
1858
[email protected]2431756e2010-09-29 20:26:131859 ClientSocketHandle handle2;
1860 TestCompletionCallback callback2;
1861 rv = handle2.Init("a",
1862 params_,
1863 kDefaultPriority,
1864 &callback2, pool_.get(),
1865 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571866 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131867 EXPECT_NE(LOAD_STATE_IDLE, handle.GetLoadState());
1868 EXPECT_NE(LOAD_STATE_IDLE, handle2.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571869}
1870
[email protected]e772db3f2010-07-12 18:11:131871TEST_F(ClientSocketPoolBaseTest, Recoverable) {
1872 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1873 connect_job_factory_->set_job_type(TestConnectJob::kMockRecoverableJob);
1874
[email protected]2431756e2010-09-29 20:26:131875 ClientSocketHandle handle;
1876 TestCompletionCallback callback;
1877 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, handle.Init("a",
1878 params_,
1879 kDefaultPriority,
1880 &callback, pool_.get(),
1881 BoundNetLog()));
1882 EXPECT_TRUE(handle.is_initialized());
1883 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:131884}
1885
1886TEST_F(ClientSocketPoolBaseTest, AsyncRecoverable) {
1887 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1888
1889 connect_job_factory_->set_job_type(
1890 TestConnectJob::kMockPendingRecoverableJob);
[email protected]2431756e2010-09-29 20:26:131891 ClientSocketHandle handle;
1892 TestCompletionCallback callback;
1893 EXPECT_EQ(ERR_IO_PENDING,
1894 handle.Init("a",
1895 params_,
1896 kDefaultPriority,
1897 &callback,
1898 pool_.get(),
1899 BoundNetLog()));
1900 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1901 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, callback.WaitForResult());
1902 EXPECT_TRUE(handle.is_initialized());
1903 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:131904}
1905
[email protected]e60e47a2010-07-14 03:37:181906TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
1907 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1908 connect_job_factory_->set_job_type(
1909 TestConnectJob::kMockAdditionalErrorStateJob);
1910
[email protected]2431756e2010-09-29 20:26:131911 ClientSocketHandle handle;
1912 TestCompletionCallback callback;
1913 EXPECT_EQ(ERR_CONNECTION_FAILED,
1914 handle.Init("a",
1915 params_,
1916 kDefaultPriority,
1917 &callback,
1918 pool_.get(),
1919 BoundNetLog()));
1920 EXPECT_FALSE(handle.is_initialized());
1921 EXPECT_FALSE(handle.socket());
1922 EXPECT_TRUE(handle.is_ssl_error());
1923 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181924}
1925
1926TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
1927 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1928
1929 connect_job_factory_->set_job_type(
1930 TestConnectJob::kMockPendingAdditionalErrorStateJob);
[email protected]2431756e2010-09-29 20:26:131931 ClientSocketHandle handle;
1932 TestCompletionCallback callback;
1933 EXPECT_EQ(ERR_IO_PENDING,
1934 handle.Init("a",
1935 params_,
1936 kDefaultPriority,
1937 &callback,
1938 pool_.get(),
1939 BoundNetLog()));
1940 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1941 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1942 EXPECT_FALSE(handle.is_initialized());
1943 EXPECT_FALSE(handle.socket());
1944 EXPECT_TRUE(handle.is_ssl_error());
1945 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181946}
1947
[email protected]4d3b05d2010-01-27 21:27:291948TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
[email protected]9bf28db2009-08-29 01:35:161949 CreatePoolWithIdleTimeouts(
1950 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1951 base::TimeDelta(), // Time out unused sockets immediately.
1952 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1953
1954 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1955
1956 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
1957
[email protected]2431756e2010-09-29 20:26:131958 ClientSocketHandle handle;
1959 TestCompletionCallback callback;
1960 int rv = handle.Init("a",
1961 params_,
1962 LOWEST,
1963 &callback,
1964 pool_.get(),
1965 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:161966 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131967 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
[email protected]9bf28db2009-08-29 01:35:161968
[email protected]2431756e2010-09-29 20:26:131969 ClientSocketHandle handle2;
1970 TestCompletionCallback callback2;
1971 rv = handle2.Init("a",
1972 params_,
1973 LOWEST,
1974 &callback2,
1975 pool_.get(),
1976 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:161977 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131978 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
[email protected]9bf28db2009-08-29 01:35:161979
1980 // Cancel one of the requests. Wait for the other, which will get the first
1981 // job. Release the socket. Run the loop again to make sure the second
1982 // socket is sitting idle and the first one is released (since ReleaseSocket()
1983 // just posts a DoReleaseSocket() task).
1984
[email protected]2431756e2010-09-29 20:26:131985 handle.Reset();
1986 EXPECT_EQ(OK, callback2.WaitForResult());
[email protected]0f873e82010-09-02 16:09:011987 // Use the socket.
[email protected]2431756e2010-09-29 20:26:131988 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, NULL));
1989 handle2.Reset();
[email protected]6b175382009-10-13 06:47:471990
1991 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1992 // actually become pending until 2ms after they have been created. In order
1993 // to flush all tasks, we need to wait so that we know there are no
1994 // soon-to-be-pending tasks waiting.
[email protected]f214f8792011-01-01 02:17:081995 base::PlatformThread::Sleep(10);
[email protected]9bf28db2009-08-29 01:35:161996 MessageLoop::current()->RunAllPending();
1997
1998 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:041999
[email protected]9bf28db2009-08-29 01:35:162000 // Invoke the idle socket cleanup check. Only one socket should be left, the
2001 // used socket. Request it to make sure that it's used.
2002
2003 pool_->CleanupTimedOutIdleSockets();
[email protected]9e743cd2010-03-16 07:03:532004 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:132005 rv = handle.Init("a",
2006 params_,
2007 LOWEST,
2008 &callback,
2009 pool_.get(),
2010 log.bound());
[email protected]9bf28db2009-08-29 01:35:162011 EXPECT_EQ(OK, rv);
[email protected]2431756e2010-09-29 20:26:132012 EXPECT_TRUE(handle.is_reused());
[email protected]b2fcd0e2010-12-01 15:19:402013
2014 net::CapturingNetLog::EntryList entries;
2015 log.GetEntries(&entries);
[email protected]fd4fe0b2010-02-08 23:02:152016 EXPECT_TRUE(LogContainsEntryWithType(
[email protected]b2fcd0e2010-12-01 15:19:402017 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]9bf28db2009-08-29 01:35:162018}
2019
[email protected]2041cf342010-02-19 03:15:592020// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:162021// because of multiple releasing disconnected sockets.
2022TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
2023 CreatePoolWithIdleTimeouts(
2024 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2025 base::TimeDelta(), // Time out unused sockets immediately.
2026 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2027
2028 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2029
2030 // Startup 4 connect jobs. Two of them will be pending.
2031
[email protected]2431756e2010-09-29 20:26:132032 ClientSocketHandle handle;
2033 TestCompletionCallback callback;
2034 int rv = handle.Init("a",
2035 params_,
2036 LOWEST,
2037 &callback,
2038 pool_.get(),
2039 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162040 EXPECT_EQ(OK, rv);
2041
[email protected]2431756e2010-09-29 20:26:132042 ClientSocketHandle handle2;
2043 TestCompletionCallback callback2;
2044 rv = handle2.Init("a",
2045 params_,
2046 LOWEST,
2047 &callback2,
2048 pool_.get(),
2049 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162050 EXPECT_EQ(OK, rv);
2051
[email protected]2431756e2010-09-29 20:26:132052 ClientSocketHandle handle3;
2053 TestCompletionCallback callback3;
2054 rv = handle3.Init("a",
2055 params_,
2056 LOWEST,
2057 &callback3,
2058 pool_.get(),
2059 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162060 EXPECT_EQ(ERR_IO_PENDING, rv);
2061
[email protected]2431756e2010-09-29 20:26:132062 ClientSocketHandle handle4;
2063 TestCompletionCallback callback4;
2064 rv = handle4.Init("a",
2065 params_,
2066 LOWEST,
2067 &callback4,
2068 pool_.get(),
2069 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162070 EXPECT_EQ(ERR_IO_PENDING, rv);
2071
2072 // Release two disconnected sockets.
2073
[email protected]2431756e2010-09-29 20:26:132074 handle.socket()->Disconnect();
2075 handle.Reset();
2076 handle2.socket()->Disconnect();
2077 handle2.Reset();
[email protected]4f2abec2010-02-03 18:10:162078
[email protected]2431756e2010-09-29 20:26:132079 EXPECT_EQ(OK, callback3.WaitForResult());
2080 EXPECT_FALSE(handle3.is_reused());
2081 EXPECT_EQ(OK, callback4.WaitForResult());
2082 EXPECT_FALSE(handle4.is_reused());
[email protected]4f2abec2010-02-03 18:10:162083}
2084
[email protected]d7027bb2010-05-10 18:58:542085// Regression test for http://crbug.com/42267.
2086// When DoReleaseSocket() is processed for one socket, it is blocked because the
2087// other stalled groups all have releasing sockets, so no progress can be made.
2088TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
2089 CreatePoolWithIdleTimeouts(
2090 4 /* socket limit */, 4 /* socket limit per group */,
2091 base::TimeDelta(), // Time out unused sockets immediately.
2092 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2093
2094 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2095
2096 // Max out the socket limit with 2 per group.
2097
[email protected]2431756e2010-09-29 20:26:132098 ClientSocketHandle handle_a[4];
2099 TestCompletionCallback callback_a[4];
2100 ClientSocketHandle handle_b[4];
2101 TestCompletionCallback callback_b[4];
[email protected]d7027bb2010-05-10 18:58:542102
2103 for (int i = 0; i < 2; ++i) {
[email protected]2431756e2010-09-29 20:26:132104 EXPECT_EQ(OK, handle_a[i].Init("a",
2105 params_,
2106 LOWEST,
2107 &callback_a[i],
2108 pool_.get(),
2109 BoundNetLog()));
2110 EXPECT_EQ(OK, handle_b[i].Init("b",
2111 params_,
2112 LOWEST,
2113 &callback_b[i],
2114 pool_.get(),
2115 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542116 }
[email protected]b89f7e42010-05-20 20:37:002117
[email protected]d7027bb2010-05-10 18:58:542118 // Make 4 pending requests, 2 per group.
2119
2120 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132121 EXPECT_EQ(ERR_IO_PENDING,
2122 handle_a[i].Init("a",
2123 params_,
2124 LOWEST,
2125 &callback_a[i],
2126 pool_.get(),
2127 BoundNetLog()));
2128 EXPECT_EQ(ERR_IO_PENDING,
2129 handle_b[i].Init("b",
2130 params_,
2131 LOWEST,
2132 &callback_b[i],
2133 pool_.get(),
2134 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542135 }
2136
2137 // Release b's socket first. The order is important, because in
2138 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2139 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2140 // first, which has a releasing socket, so it refuses to start up another
2141 // ConnectJob. So, we used to infinite loop on this.
[email protected]2431756e2010-09-29 20:26:132142 handle_b[0].socket()->Disconnect();
2143 handle_b[0].Reset();
2144 handle_a[0].socket()->Disconnect();
2145 handle_a[0].Reset();
[email protected]d7027bb2010-05-10 18:58:542146
2147 // Used to get stuck here.
2148 MessageLoop::current()->RunAllPending();
2149
[email protected]2431756e2010-09-29 20:26:132150 handle_b[1].socket()->Disconnect();
2151 handle_b[1].Reset();
2152 handle_a[1].socket()->Disconnect();
2153 handle_a[1].Reset();
[email protected]d7027bb2010-05-10 18:58:542154
2155 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132156 EXPECT_EQ(OK, callback_b[i].WaitForResult());
2157 EXPECT_EQ(OK, callback_a[i].WaitForResult());
[email protected]d7027bb2010-05-10 18:58:542158 }
2159}
2160
[email protected]fd4fe0b2010-02-08 23:02:152161TEST_F(ClientSocketPoolBaseTest,
2162 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2163 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2164
2165 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2166
2167 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2168 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2169 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2170 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2171
[email protected]2431756e2010-09-29 20:26:132172 EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
2173 EXPECT_EQ(OK, (*requests())[1]->WaitForResult());
2174 EXPECT_EQ(2u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152175
2176 // Releases one connection.
[email protected]2431756e2010-09-29 20:26:132177 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2178 EXPECT_EQ(OK, (*requests())[2]->WaitForResult());
[email protected]fd4fe0b2010-02-08 23:02:152179
[email protected]2431756e2010-09-29 20:26:132180 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2181 EXPECT_EQ(OK, (*requests())[3]->WaitForResult());
2182 EXPECT_EQ(4u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152183
2184 EXPECT_EQ(1, GetOrderOfRequest(1));
2185 EXPECT_EQ(2, GetOrderOfRequest(2));
2186 EXPECT_EQ(3, GetOrderOfRequest(3));
2187 EXPECT_EQ(4, GetOrderOfRequest(4));
2188
2189 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:132190 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
[email protected]fd4fe0b2010-02-08 23:02:152191}
2192
[email protected]4f1e4982010-03-02 18:31:042193class TestReleasingSocketRequest : public CallbackRunner< Tuple1<int> > {
2194 public:
[email protected]2431756e2010-09-29 20:26:132195 TestReleasingSocketRequest(TestClientSocketPool* pool,
2196 int expected_result,
[email protected]e60e47a2010-07-14 03:37:182197 bool reset_releasing_handle)
2198 : pool_(pool),
2199 expected_result_(expected_result),
2200 reset_releasing_handle_(reset_releasing_handle) {}
[email protected]4f1e4982010-03-02 18:31:042201
2202 ClientSocketHandle* handle() { return &handle_; }
2203
2204 int WaitForResult() {
2205 return callback_.WaitForResult();
2206 }
2207
2208 virtual void RunWithParams(const Tuple1<int>& params) {
2209 callback_.RunWithParams(params);
[email protected]e60e47a2010-07-14 03:37:182210 if (reset_releasing_handle_)
2211 handle_.Reset();
[email protected]ad8e04a2010-11-01 04:16:272212 scoped_refptr<TestSocketParams> con_params(new TestSocketParams());
[email protected]2431756e2010-09-29 20:26:132213 EXPECT_EQ(expected_result_, handle2_.Init("a",
2214 con_params,
2215 kDefaultPriority,
2216 &callback2_,
2217 pool_,
[email protected]e60e47a2010-07-14 03:37:182218 BoundNetLog()));
[email protected]4f1e4982010-03-02 18:31:042219 }
2220
2221 private:
[email protected]2431756e2010-09-29 20:26:132222 TestClientSocketPool* const pool_;
[email protected]e60e47a2010-07-14 03:37:182223 int expected_result_;
2224 bool reset_releasing_handle_;
[email protected]4f1e4982010-03-02 18:31:042225 ClientSocketHandle handle_;
2226 ClientSocketHandle handle2_;
2227 TestCompletionCallback callback_;
2228 TestCompletionCallback callback2_;
2229};
2230
[email protected]e60e47a2010-07-14 03:37:182231
2232TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2233 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2234
2235 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2236 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
2237 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2238
[email protected]2431756e2010-09-29 20:26:132239 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]e60e47a2010-07-14 03:37:182240 client_socket_factory_.allocation_count());
2241
2242 connect_job_factory_->set_job_type(
2243 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2244 TestReleasingSocketRequest req(pool_.get(), OK, false);
[email protected]2431756e2010-09-29 20:26:132245 EXPECT_EQ(ERR_IO_PENDING,
2246 req.handle()->Init("a",
2247 params_,
2248 kDefaultPriority,
2249 &req,
2250 pool_.get(),
2251 BoundNetLog()));
[email protected]e60e47a2010-07-14 03:37:182252 // The next job should complete synchronously
2253 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2254
2255 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
2256 EXPECT_FALSE(req.handle()->is_initialized());
2257 EXPECT_FALSE(req.handle()->socket());
2258 EXPECT_TRUE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:432259 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182260}
2261
[email protected]b6501d3d2010-06-03 23:53:342262// http://crbug.com/44724 regression test.
2263// We start releasing the pool when we flush on network change. When that
2264// happens, the only active references are in the ClientSocketHandles. When a
2265// ConnectJob completes and calls back into the last ClientSocketHandle, that
2266// callback can release the last reference and delete the pool. After the
2267// callback finishes, we go back to the stack frame within the now-deleted pool.
2268// Executing any code that refers to members of the now-deleted pool can cause
2269// crashes.
2270TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2271 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2272 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2273
2274 ClientSocketHandle handle;
2275 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132276 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2277 params_,
2278 kDefaultPriority,
2279 &callback,
2280 pool_.get(),
2281 BoundNetLog()));
[email protected]b6501d3d2010-06-03 23:53:342282
[email protected]2431756e2010-09-29 20:26:132283 pool_->Flush();
[email protected]b6501d3d2010-06-03 23:53:342284
2285 // We'll call back into this now.
2286 callback.WaitForResult();
2287}
2288
[email protected]a7e38572010-06-07 18:22:242289TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2290 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2291 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2292
2293 ClientSocketHandle handle;
2294 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132295 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2296 params_,
2297 kDefaultPriority,
2298 &callback,
2299 pool_.get(),
2300 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242301 EXPECT_EQ(OK, callback.WaitForResult());
2302 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2303
2304 pool_->Flush();
2305
2306 handle.Reset();
2307 MessageLoop::current()->RunAllPending();
2308
[email protected]2431756e2010-09-29 20:26:132309 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2310 params_,
2311 kDefaultPriority,
2312 &callback,
2313 pool_.get(),
2314 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242315 EXPECT_EQ(OK, callback.WaitForResult());
2316 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2317}
2318
[email protected]06f92462010-08-31 19:24:142319class ConnectWithinCallback : public CallbackRunner< Tuple1<int> > {
2320 public:
2321 ConnectWithinCallback(
2322 const std::string& group_name,
2323 const scoped_refptr<TestSocketParams>& params,
[email protected]2431756e2010-09-29 20:26:132324 TestClientSocketPool* pool)
[email protected]06f92462010-08-31 19:24:142325 : group_name_(group_name), params_(params), pool_(pool) {}
2326
2327 ~ConnectWithinCallback() {}
2328
2329 virtual void RunWithParams(const Tuple1<int>& params) {
2330 callback_.RunWithParams(params);
2331 EXPECT_EQ(ERR_IO_PENDING,
2332 handle_.Init(group_name_,
2333 params_,
2334 kDefaultPriority,
2335 &nested_callback_,
2336 pool_,
2337 BoundNetLog()));
2338 }
2339
2340 int WaitForResult() {
2341 return callback_.WaitForResult();
2342 }
2343
2344 int WaitForNestedResult() {
2345 return nested_callback_.WaitForResult();
2346 }
2347
2348 private:
2349 const std::string group_name_;
2350 const scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:132351 TestClientSocketPool* const pool_;
[email protected]06f92462010-08-31 19:24:142352 ClientSocketHandle handle_;
2353 TestCompletionCallback callback_;
2354 TestCompletionCallback nested_callback_;
2355};
2356
2357TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
2358 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2359
2360 // First job will be waiting until it gets aborted.
2361 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2362
2363 ClientSocketHandle handle;
[email protected]2431756e2010-09-29 20:26:132364 ConnectWithinCallback callback("a", params_, pool_.get());
2365 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2366 params_,
2367 kDefaultPriority,
2368 &callback,
2369 pool_.get(),
2370 BoundNetLog()));
[email protected]06f92462010-08-31 19:24:142371
2372 // Second job will be started during the first callback, and will
2373 // asynchronously complete with OK.
2374 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2375 pool_->Flush();
2376 EXPECT_EQ(ERR_ABORTED, callback.WaitForResult());
2377 EXPECT_EQ(OK, callback.WaitForNestedResult());
2378}
2379
[email protected]25eea382010-07-10 23:55:262380// Cancel a pending socket request while we're at max sockets,
2381// and verify that the backup socket firing doesn't cause a crash.
2382TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
2383 // Max 4 sockets globally, max 4 sockets per group.
2384 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
[email protected]06d94042010-08-25 01:45:222385 pool_->EnableConnectBackupJobs();
[email protected]25eea382010-07-10 23:55:262386
[email protected]4baaf9d2010-08-31 15:15:442387 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2388 // timer.
[email protected]25eea382010-07-10 23:55:262389 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2390 ClientSocketHandle handle;
2391 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132392 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2393 params_,
2394 kDefaultPriority,
2395 &callback,
2396 pool_.get(),
2397 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262398
2399 // Start (MaxSockets - 1) connected sockets to reach max sockets.
2400 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2401 ClientSocketHandle handles[kDefaultMaxSockets];
2402 for (int i = 1; i < kDefaultMaxSockets; ++i) {
2403 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132404 EXPECT_EQ(OK, handles[i].Init("bar",
2405 params_,
2406 kDefaultPriority,
2407 &callback,
2408 pool_.get(),
2409 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262410 }
2411
2412 MessageLoop::current()->RunAllPending();
2413
2414 // Cancel the pending request.
2415 handle.Reset();
2416
2417 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]f214f8792011-01-01 02:17:082418 base::PlatformThread::Sleep(
2419 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
[email protected]25eea382010-07-10 23:55:262420
2421 MessageLoop::current()->RunAllPending();
2422 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
2423}
2424
[email protected]3f00be82010-09-27 19:50:022425TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
[email protected]4baaf9d2010-08-31 15:15:442426 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2427 pool_->EnableConnectBackupJobs();
2428
2429 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2430 // timer.
2431 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2432 ClientSocketHandle handle;
2433 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132434 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2435 params_,
2436 kDefaultPriority,
2437 &callback,
2438 pool_.get(),
2439 BoundNetLog()));
[email protected]4baaf9d2010-08-31 15:15:442440 ASSERT_TRUE(pool_->HasGroup("bar"));
2441 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2442
2443 // Cancel the socket request. This should cancel the backup timer. Wait for
2444 // the backup time to see if it indeed got canceled.
2445 handle.Reset();
2446 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]f214f8792011-01-01 02:17:082447 base::PlatformThread::Sleep(
2448 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
[email protected]4baaf9d2010-08-31 15:15:442449 MessageLoop::current()->RunAllPending();
2450 ASSERT_TRUE(pool_->HasGroup("bar"));
2451 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2452}
2453
[email protected]3f00be82010-09-27 19:50:022454TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
2455 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2456 pool_->EnableConnectBackupJobs();
2457
2458 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2459 // timer.
2460 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2461 ClientSocketHandle handle;
2462 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132463 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2464 params_,
2465 kDefaultPriority,
2466 &callback,
2467 pool_.get(),
2468 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022469 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2470 ClientSocketHandle handle2;
2471 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132472 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("bar",
2473 params_,
2474 kDefaultPriority,
2475 &callback2,
2476 pool_.get(),
2477 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022478 ASSERT_TRUE(pool_->HasGroup("bar"));
2479 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("bar"));
2480
2481 // Cancel request 1 and then complete request 2. With the requests finished,
2482 // the backup timer should be cancelled.
2483 handle.Reset();
2484 EXPECT_EQ(OK, callback2.WaitForResult());
2485 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]f214f8792011-01-01 02:17:082486 base::PlatformThread::Sleep(
2487 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
[email protected]3f00be82010-09-27 19:50:022488 MessageLoop::current()->RunAllPending();
2489}
2490
[email protected]eb5a99382010-07-11 03:18:262491// Test delayed socket binding for the case where we have two connects,
2492// and while one is waiting on a connect, the other frees up.
2493// The socket waiting on a connect should switch immediately to the freed
2494// up socket.
2495TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
2496 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2497 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2498
2499 ClientSocketHandle handle1;
2500 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132501 EXPECT_EQ(ERR_IO_PENDING,
2502 handle1.Init("a",
2503 params_,
2504 kDefaultPriority,
2505 &callback,
2506 pool_.get(),
2507 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262508 EXPECT_EQ(OK, callback.WaitForResult());
2509
2510 // No idle sockets, no pending jobs.
2511 EXPECT_EQ(0, pool_->IdleSocketCount());
2512 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2513
2514 // Create a second socket to the same host, but this one will wait.
2515 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2516 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132517 EXPECT_EQ(ERR_IO_PENDING,
2518 handle2.Init("a",
2519 params_,
2520 kDefaultPriority,
2521 &callback,
2522 pool_.get(),
2523 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262524 // No idle sockets, and one connecting job.
2525 EXPECT_EQ(0, pool_->IdleSocketCount());
2526 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2527
2528 // Return the first handle to the pool. This will initiate the delayed
2529 // binding.
2530 handle1.Reset();
2531
2532 MessageLoop::current()->RunAllPending();
2533
2534 // Still no idle sockets, still one pending connect job.
2535 EXPECT_EQ(0, pool_->IdleSocketCount());
2536 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2537
2538 // The second socket connected, even though it was a Waiting Job.
2539 EXPECT_EQ(OK, callback.WaitForResult());
2540
2541 // And we can see there is still one job waiting.
2542 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2543
2544 // Finally, signal the waiting Connect.
2545 client_socket_factory_.SignalJobs();
2546 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2547
2548 MessageLoop::current()->RunAllPending();
2549}
2550
2551// Test delayed socket binding when a group is at capacity and one
2552// of the group's sockets frees up.
2553TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
2554 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2555 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2556
2557 ClientSocketHandle handle1;
2558 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132559 EXPECT_EQ(ERR_IO_PENDING,
2560 handle1.Init("a",
2561 params_,
2562 kDefaultPriority,
2563 &callback,
2564 pool_.get(),
2565 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262566 EXPECT_EQ(OK, callback.WaitForResult());
2567
2568 // No idle sockets, no pending jobs.
2569 EXPECT_EQ(0, pool_->IdleSocketCount());
2570 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2571
2572 // Create a second socket to the same host, but this one will wait.
2573 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2574 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132575 EXPECT_EQ(ERR_IO_PENDING,
2576 handle2.Init("a",
2577 params_,
2578 kDefaultPriority,
2579 &callback,
2580 pool_.get(),
2581 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262582 // No idle sockets, and one connecting job.
2583 EXPECT_EQ(0, pool_->IdleSocketCount());
2584 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2585
2586 // Return the first handle to the pool. This will initiate the delayed
2587 // binding.
2588 handle1.Reset();
2589
2590 MessageLoop::current()->RunAllPending();
2591
2592 // Still no idle sockets, still one pending connect job.
2593 EXPECT_EQ(0, pool_->IdleSocketCount());
2594 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2595
2596 // The second socket connected, even though it was a Waiting Job.
2597 EXPECT_EQ(OK, callback.WaitForResult());
2598
2599 // And we can see there is still one job waiting.
2600 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2601
2602 // Finally, signal the waiting Connect.
2603 client_socket_factory_.SignalJobs();
2604 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2605
2606 MessageLoop::current()->RunAllPending();
2607}
2608
2609// Test out the case where we have one socket connected, one
2610// connecting, when the first socket finishes and goes idle.
[email protected]2abfe90a2010-08-25 17:49:512611// Although the second connection is pending, the second request
[email protected]eb5a99382010-07-11 03:18:262612// should complete, by taking the first socket's idle socket.
2613TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
2614 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2615 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2616
2617 ClientSocketHandle handle1;
2618 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132619 EXPECT_EQ(ERR_IO_PENDING,
2620 handle1.Init("a",
2621 params_,
2622 kDefaultPriority,
2623 &callback,
2624 pool_.get(),
2625 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262626 EXPECT_EQ(OK, callback.WaitForResult());
2627
2628 // No idle sockets, no pending jobs.
2629 EXPECT_EQ(0, pool_->IdleSocketCount());
2630 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2631
2632 // Create a second socket to the same host, but this one will wait.
2633 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2634 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132635 EXPECT_EQ(ERR_IO_PENDING,
2636 handle2.Init("a",
2637 params_,
2638 kDefaultPriority,
2639 &callback,
2640 pool_.get(),
2641 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262642 // No idle sockets, and one connecting job.
2643 EXPECT_EQ(0, pool_->IdleSocketCount());
2644 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2645
2646 // Return the first handle to the pool. This will initiate the delayed
2647 // binding.
2648 handle1.Reset();
2649
2650 MessageLoop::current()->RunAllPending();
2651
2652 // Still no idle sockets, still one pending connect job.
2653 EXPECT_EQ(0, pool_->IdleSocketCount());
2654 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2655
2656 // The second socket connected, even though it was a Waiting Job.
2657 EXPECT_EQ(OK, callback.WaitForResult());
2658
2659 // And we can see there is still one job waiting.
2660 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2661
2662 // Finally, signal the waiting Connect.
2663 client_socket_factory_.SignalJobs();
2664 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2665
2666 MessageLoop::current()->RunAllPending();
2667}
2668
[email protected]2abfe90a2010-08-25 17:49:512669// Cover the case where on an available socket slot, we have one pending
2670// request that completes synchronously, thereby making the Group empty.
2671TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
2672 const int kUnlimitedSockets = 100;
2673 const int kOneSocketPerGroup = 1;
2674 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
2675
2676 // Make the first request asynchronous fail.
2677 // This will free up a socket slot later.
2678 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2679
2680 ClientSocketHandle handle1;
2681 TestCompletionCallback callback1;
[email protected]2431756e2010-09-29 20:26:132682 EXPECT_EQ(ERR_IO_PENDING,
2683 handle1.Init("a",
2684 params_,
2685 kDefaultPriority,
2686 &callback1,
2687 pool_.get(),
2688 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:512689 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2690
2691 // Make the second request synchronously fail. This should make the Group
2692 // empty.
2693 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
2694 ClientSocketHandle handle2;
2695 TestCompletionCallback callback2;
2696 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
2697 // when created.
[email protected]2431756e2010-09-29 20:26:132698 EXPECT_EQ(ERR_IO_PENDING,
2699 handle2.Init("a",
2700 params_,
2701 kDefaultPriority,
2702 &callback2,
2703 pool_.get(),
2704 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:512705
2706 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2707
2708 EXPECT_EQ(ERR_CONNECTION_FAILED, callback1.WaitForResult());
2709 EXPECT_EQ(ERR_CONNECTION_FAILED, callback2.WaitForResult());
2710 EXPECT_FALSE(pool_->HasGroup("a"));
2711}
2712
[email protected]e1b54dc2010-10-06 21:27:222713TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
2714 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2715
2716 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2717
2718 ClientSocketHandle handle1;
2719 TestCompletionCallback callback1;
2720 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2721 params_,
2722 kDefaultPriority,
2723 &callback1,
2724 pool_.get(),
2725 BoundNetLog()));
2726
2727 ClientSocketHandle handle2;
2728 TestCompletionCallback callback2;
2729 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2730 params_,
2731 kDefaultPriority,
2732 &callback2,
2733 pool_.get(),
2734 BoundNetLog()));
2735 ClientSocketHandle handle3;
2736 TestCompletionCallback callback3;
2737 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
2738 params_,
2739 kDefaultPriority,
2740 &callback3,
2741 pool_.get(),
2742 BoundNetLog()));
2743
2744 EXPECT_EQ(OK, callback1.WaitForResult());
2745 EXPECT_EQ(OK, callback2.WaitForResult());
2746 EXPECT_EQ(OK, callback3.WaitForResult());
2747
2748 // Use the socket.
2749 EXPECT_EQ(1, handle1.socket()->Write(NULL, 1, NULL));
2750 EXPECT_EQ(1, handle3.socket()->Write(NULL, 1, NULL));
2751
2752 handle1.Reset();
2753 handle2.Reset();
2754 handle3.Reset();
2755
2756 EXPECT_EQ(OK, handle1.Init("a",
2757 params_,
2758 kDefaultPriority,
2759 &callback1,
2760 pool_.get(),
2761 BoundNetLog()));
2762 EXPECT_EQ(OK, handle2.Init("a",
2763 params_,
2764 kDefaultPriority,
2765 &callback2,
2766 pool_.get(),
2767 BoundNetLog()));
2768 EXPECT_EQ(OK, handle3.Init("a",
2769 params_,
2770 kDefaultPriority,
2771 &callback3,
2772 pool_.get(),
2773 BoundNetLog()));
2774
2775 EXPECT_TRUE(handle1.socket()->WasEverUsed());
2776 EXPECT_TRUE(handle2.socket()->WasEverUsed());
2777 EXPECT_FALSE(handle3.socket()->WasEverUsed());
2778}
2779
[email protected]2c2bef152010-10-13 00:55:032780TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
2781 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2782 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2783
2784 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2785
2786 ASSERT_TRUE(pool_->HasGroup("a"));
2787 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2788 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2789
2790 ClientSocketHandle handle1;
2791 TestCompletionCallback callback1;
2792 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2793 params_,
2794 kDefaultPriority,
2795 &callback1,
2796 pool_.get(),
2797 BoundNetLog()));
2798
2799 ClientSocketHandle handle2;
2800 TestCompletionCallback callback2;
2801 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2802 params_,
2803 kDefaultPriority,
2804 &callback2,
2805 pool_.get(),
2806 BoundNetLog()));
2807
2808 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2809 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2810
2811 EXPECT_EQ(OK, callback1.WaitForResult());
2812 EXPECT_EQ(OK, callback2.WaitForResult());
2813 handle1.Reset();
2814 handle2.Reset();
2815
2816 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2817 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2818}
2819
2820TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
2821 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2822 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2823
2824 ClientSocketHandle handle1;
2825 TestCompletionCallback callback1;
2826 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2827 params_,
2828 kDefaultPriority,
2829 &callback1,
2830 pool_.get(),
2831 BoundNetLog()));
2832
2833 ASSERT_TRUE(pool_->HasGroup("a"));
2834 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2835 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2836
2837 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2838
2839 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2840 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2841
2842 ClientSocketHandle handle2;
2843 TestCompletionCallback callback2;
2844 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2845 params_,
2846 kDefaultPriority,
2847 &callback2,
2848 pool_.get(),
2849 BoundNetLog()));
2850
2851 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2852 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2853
2854 EXPECT_EQ(OK, callback1.WaitForResult());
2855 EXPECT_EQ(OK, callback2.WaitForResult());
2856 handle1.Reset();
2857 handle2.Reset();
2858
2859 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2860 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2861}
2862
2863TEST_F(ClientSocketPoolBaseTest,
2864 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
2865 CreatePool(4, 4);
2866 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2867
2868 ClientSocketHandle handle1;
2869 TestCompletionCallback callback1;
2870 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2871 params_,
2872 kDefaultPriority,
2873 &callback1,
2874 pool_.get(),
2875 BoundNetLog()));
2876
2877 ClientSocketHandle handle2;
2878 TestCompletionCallback callback2;
2879 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2880 params_,
2881 kDefaultPriority,
2882 &callback2,
2883 pool_.get(),
2884 BoundNetLog()));
2885
2886 ClientSocketHandle handle3;
2887 TestCompletionCallback callback3;
2888 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
2889 params_,
2890 kDefaultPriority,
2891 &callback3,
2892 pool_.get(),
2893 BoundNetLog()));
2894
2895 ASSERT_TRUE(pool_->HasGroup("a"));
2896 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2897 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2898
2899 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2900
2901 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2902 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2903
2904 EXPECT_EQ(OK, callback1.WaitForResult());
2905 EXPECT_EQ(OK, callback2.WaitForResult());
2906 EXPECT_EQ(OK, callback3.WaitForResult());
2907 handle1.Reset();
2908 handle2.Reset();
2909 handle3.Reset();
2910
2911 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2912 EXPECT_EQ(3, pool_->IdleSocketCountInGroup("a"));
2913}
2914
2915TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
2916 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2917 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2918
2919 ASSERT_FALSE(pool_->HasGroup("a"));
2920
2921 pool_->RequestSockets("a", &params_, kDefaultMaxSockets,
2922 BoundNetLog());
2923
2924 ASSERT_TRUE(pool_->HasGroup("a"));
2925 EXPECT_EQ(kDefaultMaxSockets, pool_->NumConnectJobsInGroup("a"));
2926
2927 ASSERT_FALSE(pool_->HasGroup("b"));
2928
2929 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
2930 BoundNetLog());
2931
2932 ASSERT_FALSE(pool_->HasGroup("b"));
2933}
2934
2935TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
2936 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2937 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2938
2939 ASSERT_FALSE(pool_->HasGroup("a"));
2940
2941 pool_->RequestSockets("a", &params_, kDefaultMaxSockets - 1,
2942 BoundNetLog());
2943
2944 ASSERT_TRUE(pool_->HasGroup("a"));
2945 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->NumConnectJobsInGroup("a"));
2946
2947 ASSERT_FALSE(pool_->HasGroup("b"));
2948
2949 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
2950 BoundNetLog());
2951
2952 ASSERT_TRUE(pool_->HasGroup("b"));
2953 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("b"));
2954}
2955
2956TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
2957 CreatePool(4, 4);
2958 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2959
2960 ClientSocketHandle handle1;
2961 TestCompletionCallback callback1;
2962 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2963 params_,
2964 kDefaultPriority,
2965 &callback1,
2966 pool_.get(),
2967 BoundNetLog()));
2968 ASSERT_EQ(OK, callback1.WaitForResult());
2969 handle1.Reset();
2970
2971 ASSERT_TRUE(pool_->HasGroup("a"));
2972 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2973 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
2974
2975 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2976
2977 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2978 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
2979}
2980
2981TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
2982 CreatePool(4, 4);
2983 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2984
2985 ClientSocketHandle handle1;
2986 TestCompletionCallback callback1;
2987 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2988 params_,
2989 kDefaultPriority,
2990 &callback1,
2991 pool_.get(),
2992 BoundNetLog()));
2993 ASSERT_EQ(OK, callback1.WaitForResult());
2994
2995 ASSERT_TRUE(pool_->HasGroup("a"));
2996 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2997 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2998 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2999
3000 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3001
3002 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3003 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3004 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3005}
3006
3007TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
3008 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3009 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3010
3011 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3012 BoundNetLog());
3013
3014 ASSERT_TRUE(pool_->HasGroup("a"));
3015 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3016 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("a"));
3017
3018 pool_->RequestSockets("b", &params_, kDefaultMaxSocketsPerGroup,
3019 BoundNetLog());
3020
3021 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3022 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("b"));
3023}
3024
[email protected]3c819f522010-12-02 02:03:123025TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
3026 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3027 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3028
3029 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3030 BoundNetLog());
3031
3032 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]fd2e53e2011-01-14 20:40:523033
3034 connect_job_factory_->set_job_type(
3035 TestConnectJob::kMockAdditionalErrorStateJob);
3036 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3037 BoundNetLog());
3038
3039 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]3c819f522010-12-02 02:03:123040}
3041
[email protected]2c2bef152010-10-13 00:55:033042TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
3043 CreatePool(4, 4);
3044 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3045
3046 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3047
3048 ASSERT_TRUE(pool_->HasGroup("a"));
3049 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3050 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3051
3052 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3053 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3054 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3055
3056 ClientSocketHandle handle1;
3057 TestCompletionCallback callback1;
3058 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3059 params_,
3060 kDefaultPriority,
3061 &callback1,
3062 pool_.get(),
3063 BoundNetLog()));
3064 ASSERT_EQ(OK, callback1.WaitForResult());
3065
3066 ClientSocketHandle handle2;
3067 TestCompletionCallback callback2;
3068 int rv = handle2.Init("a",
3069 params_,
3070 kDefaultPriority,
3071 &callback2,
3072 pool_.get(),
3073 BoundNetLog());
3074 if (rv != OK) {
3075 EXPECT_EQ(ERR_IO_PENDING, rv);
3076 EXPECT_EQ(OK, callback2.WaitForResult());
3077 }
3078
3079 handle1.Reset();
3080 handle2.Reset();
3081
3082 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3083
3084 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3085 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3086 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3087}
3088
3089TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
3090 CreatePool(4, 4);
3091 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3092
3093 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3094
3095 ASSERT_TRUE(pool_->HasGroup("a"));
3096 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3097 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3098
3099 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3100 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3101 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3102
3103 pool_->RequestSockets("a", &params_, 3, BoundNetLog());
3104 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
3105 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3106
3107 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3108 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
3109 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3110}
3111
3112TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
3113 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3114 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3115
3116 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3117
3118 ASSERT_TRUE(pool_->HasGroup("a"));
3119 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3120 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3121
3122 ClientSocketHandle handle1;
3123 TestCompletionCallback callback1;
3124 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3125 params_,
3126 kDefaultPriority,
3127 &callback1,
3128 pool_.get(),
3129 BoundNetLog()));
3130
3131 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3132 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3133
3134 ASSERT_EQ(OK, callback1.WaitForResult());
3135
3136 handle1.Reset();
3137
3138 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3139}
3140
[email protected]dcbe168a2010-12-02 03:14:463141// http://crbug.com/64940 regression test.
3142TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
3143 const int kMaxTotalSockets = 3;
3144 const int kMaxSocketsPerGroup = 2;
3145 CreatePool(kMaxTotalSockets, kMaxSocketsPerGroup);
3146 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3147
3148 // Note that group name ordering matters here. "a" comes before "b", so
3149 // CloseOneIdleSocket() will try to close "a"'s idle socket.
3150
3151 // Set up one idle socket in "a".
3152 ClientSocketHandle handle1;
3153 TestCompletionCallback callback1;
3154 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3155 params_,
3156 kDefaultPriority,
3157 &callback1,
3158 pool_.get(),
3159 BoundNetLog()));
3160
3161 ASSERT_EQ(OK, callback1.WaitForResult());
3162 handle1.Reset();
3163 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3164
3165 // Set up two active sockets in "b".
3166 ClientSocketHandle handle2;
3167 TestCompletionCallback callback2;
3168 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("b",
3169 params_,
3170 kDefaultPriority,
3171 &callback1,
3172 pool_.get(),
3173 BoundNetLog()));
3174 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("b",
3175 params_,
3176 kDefaultPriority,
3177 &callback2,
3178 pool_.get(),
3179 BoundNetLog()));
3180
3181 ASSERT_EQ(OK, callback1.WaitForResult());
3182 ASSERT_EQ(OK, callback2.WaitForResult());
3183 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3184 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3185
3186 // Now we have 1 idle socket in "a" and 2 active sockets in "b". This means
3187 // we've maxed out on sockets, since we set |kMaxTotalSockets| to 3.
3188 // Requesting 2 preconnected sockets for "a" should fail to allocate any more
3189 // sockets for "a", and "b" should still have 2 active sockets.
3190
3191 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3192 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3193 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3194 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3195 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3196 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3197 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3198
3199 // Now release the 2 active sockets for "b". This will give us 1 idle socket
3200 // in "a" and 2 idle sockets in "b". Requesting 2 preconnected sockets for
3201 // "a" should result in closing 1 for "b".
3202 handle1.Reset();
3203 handle2.Reset();
3204 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("b"));
3205 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3206
3207 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3208 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3209 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3210 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3211 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3212 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("b"));
3213 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3214}
3215
[email protected]a9fc8fc2011-05-10 02:41:073216TEST_F(ClientSocketPoolBaseTest, PreconnectWithoutBackupTimer) {
3217 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3218 pool_->EnableConnectBackupJobs();
3219
3220 // Make the ConnectJob hang until it times out, shorten the timeout.
3221 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3222 connect_job_factory_->set_timeout_duration(
3223 base::TimeDelta::FromMilliseconds(500));
3224 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3225 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3226 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3227 MessageLoop::current()->RunAllPending();
3228
3229 // Make sure the backup timer doesn't fire, by making it a pending job instead
3230 // of a waiting job, so it *would* complete if the timer fired.
3231 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3232 base::PlatformThread::Sleep(1000);
3233 MessageLoop::current()->RunAllPending();
3234 EXPECT_FALSE(pool_->HasGroup("a"));
3235}
3236
3237TEST_F(ClientSocketPoolBaseTest, PreconnectWithBackupTimer) {
3238 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3239 pool_->EnableConnectBackupJobs();
3240
3241 // Make the ConnectJob hang forever.
3242 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3243 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3244 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3245 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3246 MessageLoop::current()->RunAllPending();
3247
3248 // Make the backup job be a pending job, so it completes normally.
3249 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3250 ClientSocketHandle handle;
3251 TestCompletionCallback callback;
3252 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
3253 params_,
3254 kDefaultPriority,
3255 &callback,
3256 pool_.get(),
3257 BoundNetLog()));
3258 // Timer has started, but the other connect job shouldn't be created yet.
3259 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3260 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3261 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3262 ASSERT_EQ(OK, callback.WaitForResult());
3263
3264 // The hung connect job should still be there, but everything else should be
3265 // complete.
3266 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3267 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3268 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3269}
3270
[email protected]f6d1d6eb2009-06-24 20:16:093271} // namespace
3272
3273} // namespace net