blob: a936c8bc900ace21a6485e867b2da8db0c2bb49b [file] [log] [blame]
[email protected]7fc5b09a2010-02-27 00:07:381// Copyright (c) 2010 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"
9#include "base/message_loop.h"
[email protected]974ebd62009-08-03 23:14:3410#include "base/platform_thread.h"
[email protected]c9d6a1d2009-07-14 16:15:2011#include "base/scoped_vector.h"
[email protected]43a21b82010-06-10 21:30:5412#include "base/string_util.h"
[email protected]9e743cd2010-03-16 07:03:5313#include "net/base/net_log.h"
14#include "net/base/net_log_unittest.h"
[email protected]f6d1d6eb2009-06-24 20:16:0915#include "net/base/net_errors.h"
[email protected]ac790b42009-12-02 04:31:3116#include "net/base/request_priority.h"
[email protected]f6d1d6eb2009-06-24 20:16:0917#include "net/base/test_completion_callback.h"
18#include "net/socket/client_socket.h"
19#include "net/socket/client_socket_factory.h"
20#include "net/socket/client_socket_handle.h"
[email protected]b89f7e42010-05-20 20:37:0021#include "net/socket/client_socket_pool_histograms.h"
[email protected]75439d3b2009-07-23 22:11:1722#include "net/socket/socket_test_util.h"
[email protected]f6d1d6eb2009-06-24 20:16:0923#include "testing/gtest/include/gtest/gtest.h"
24
25namespace net {
26
27namespace {
28
[email protected]211d21722009-07-22 15:48:5329const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2030const int kDefaultMaxSocketsPerGroup = 2;
[email protected]a554a8262010-05-20 00:13:5231const net::RequestPriority kDefaultPriority = MEDIUM;
[email protected]0b7648c2009-07-06 20:14:0132
[email protected]951269b2010-06-15 19:39:2433struct TestSocketParams {};
[email protected]7fc5b09a2010-02-27 00:07:3834typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
[email protected]d80a4322009-08-14 07:07:4935
[email protected]f6d1d6eb2009-06-24 20:16:0936class MockClientSocket : public ClientSocket {
37 public:
38 MockClientSocket() : connected_(false) {}
39
[email protected]ab838892009-06-30 18:49:0540 // Socket methods:
41 virtual int Read(
42 IOBuffer* /* buf */, int /* len */, CompletionCallback* /* callback */) {
43 return ERR_UNEXPECTED;
44 }
45
46 virtual int Write(
47 IOBuffer* /* buf */, int /* len */, CompletionCallback* /* callback */) {
48 return ERR_UNEXPECTED;
49 }
[email protected]06650c52010-06-03 00:49:1750 virtual bool SetReceiveBufferSize(int32 size) { return true; }
51 virtual bool SetSendBufferSize(int32 size) { return true; }
[email protected]ab838892009-06-30 18:49:0552
[email protected]f6d1d6eb2009-06-24 20:16:0953 // ClientSocket methods:
[email protected]ab838892009-06-30 18:49:0554
[email protected]a2006ece2010-04-23 16:44:0255 virtual int Connect(CompletionCallback* callback) {
[email protected]f6d1d6eb2009-06-24 20:16:0956 connected_ = true;
57 return OK;
58 }
[email protected]f6d1d6eb2009-06-24 20:16:0959
[email protected]ab838892009-06-30 18:49:0560 virtual void Disconnect() { connected_ = false; }
61 virtual bool IsConnected() const { return connected_; }
62 virtual bool IsConnectedAndIdle() const { return connected_; }
[email protected]0b7648c2009-07-06 20:14:0163
[email protected]ac9eec62010-02-20 18:50:3864 virtual int GetPeerAddress(AddressList* /* address */) const {
[email protected]9f864b32010-01-20 15:01:1665 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:0966 }
[email protected]f6d1d6eb2009-06-24 20:16:0967
[email protected]a2006ece2010-04-23 16:44:0268 virtual const BoundNetLog& NetLog() const {
69 return net_log_;
70 }
71
[email protected]f6d1d6eb2009-06-24 20:16:0972 private:
73 bool connected_;
[email protected]a2006ece2010-04-23 16:44:0274 BoundNetLog net_log_;
[email protected]f6d1d6eb2009-06-24 20:16:0975
[email protected]ab838892009-06-30 18:49:0576 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:0977};
78
[email protected]5fc08e32009-07-15 17:09:5779class TestConnectJob;
80
[email protected]f6d1d6eb2009-06-24 20:16:0981class MockClientSocketFactory : public ClientSocketFactory {
82 public:
[email protected]ab838892009-06-30 18:49:0583 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:0984
[email protected]a2006ece2010-04-23 16:44:0285 virtual ClientSocket* CreateTCPClientSocket(const AddressList& addresses,
86 NetLog* /* net_log */) {
[email protected]f6d1d6eb2009-06-24 20:16:0987 allocation_count_++;
[email protected]ab838892009-06-30 18:49:0588 return NULL;
[email protected]f6d1d6eb2009-06-24 20:16:0989 }
90
91 virtual SSLClientSocket* CreateSSLClientSocket(
92 ClientSocket* transport_socket,
93 const std::string& hostname,
94 const SSLConfig& ssl_config) {
95 NOTIMPLEMENTED();
96 return NULL;
97 }
98
[email protected]5fc08e32009-07-15 17:09:5799 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
100 void SignalJobs();
101
[email protected]f6d1d6eb2009-06-24 20:16:09102 int allocation_count() const { return allocation_count_; }
103
[email protected]f6d1d6eb2009-06-24 20:16:09104 private:
105 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:57106 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09107};
108
[email protected]ab838892009-06-30 18:49:05109class TestConnectJob : public ConnectJob {
110 public:
111 enum JobType {
112 kMockJob,
113 kMockFailingJob,
114 kMockPendingJob,
115 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57116 kMockWaitingJob,
117 kMockAdvancingLoadStateJob,
[email protected]ab838892009-06-30 18:49:05118 };
119
120 TestConnectJob(JobType job_type,
121 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49122 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34123 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05124 ConnectJob::Delegate* delegate,
[email protected]fd7b7c92009-08-20 19:38:30125 MockClientSocketFactory* client_socket_factory,
[email protected]06650c52010-06-03 00:49:17126 NetLog* net_log)
127 : ConnectJob(group_name, timeout_duration, delegate,
128 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
[email protected]2ab05b52009-07-01 23:57:58129 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05130 client_socket_factory_(client_socket_factory),
[email protected]46451352009-09-01 14:54:21131 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
132 load_state_(LOAD_STATE_IDLE) {}
[email protected]ab838892009-06-30 18:49:05133
[email protected]974ebd62009-08-03 23:14:34134 void Signal() {
135 DoConnect(waiting_success_, true /* async */);
136 }
137
[email protected]46451352009-09-01 14:54:21138 virtual LoadState GetLoadState() const { return load_state_; }
139
[email protected]974ebd62009-08-03 23:14:34140 private:
[email protected]ab838892009-06-30 18:49:05141 // ConnectJob methods:
142
[email protected]974ebd62009-08-03 23:14:34143 virtual int ConnectInternal() {
[email protected]ab838892009-06-30 18:49:05144 AddressList ignored;
[email protected]a2006ece2010-04-23 16:44:02145 client_socket_factory_->CreateTCPClientSocket(ignored, NULL);
[email protected]6e713f02009-08-06 02:56:40146 set_socket(new MockClientSocket());
[email protected]ab838892009-06-30 18:49:05147 switch (job_type_) {
148 case kMockJob:
149 return DoConnect(true /* successful */, false /* sync */);
150 case kMockFailingJob:
151 return DoConnect(false /* error */, false /* sync */);
152 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57153 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47154
155 // Depending on execution timings, posting a delayed task can result
156 // in the task getting executed the at the earliest possible
157 // opportunity or only after returning once from the message loop and
158 // then a second call into the message loop. In order to make behavior
159 // more deterministic, we change the default delay to 2ms. This should
160 // always require us to wait for the second call into the message loop.
161 //
162 // N.B. The correct fix for this and similar timing problems is to
163 // abstract time for the purpose of unittests. Unfortunately, we have
164 // a lot of third-party components that directly call the various
165 // time functions, so this change would be rather invasive.
166 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05167 FROM_HERE,
168 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47169 &TestConnectJob::DoConnect,
170 true /* successful */,
171 true /* async */),
172 2);
[email protected]ab838892009-06-30 18:49:05173 return ERR_IO_PENDING;
174 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57175 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47176 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05177 FROM_HERE,
178 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47179 &TestConnectJob::DoConnect,
180 false /* error */,
181 true /* async */),
182 2);
[email protected]ab838892009-06-30 18:49:05183 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57184 case kMockWaitingJob:
185 client_socket_factory_->WaitForSignal(this);
186 waiting_success_ = true;
187 return ERR_IO_PENDING;
188 case kMockAdvancingLoadStateJob:
[email protected]e6ec67b2010-06-16 00:12:46189 MessageLoop::current()->PostTask(
[email protected]5fc08e32009-07-15 17:09:57190 FROM_HERE,
191 method_factory_.NewRunnableMethod(
[email protected]e6ec67b2010-06-16 00:12:46192 &TestConnectJob::AdvanceLoadState, load_state_));
[email protected]5fc08e32009-07-15 17:09:57193 return ERR_IO_PENDING;
[email protected]ab838892009-06-30 18:49:05194 default:
195 NOTREACHED();
[email protected]6e713f02009-08-06 02:56:40196 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05197 return ERR_FAILED;
198 }
199 }
200
[email protected]46451352009-09-01 14:54:21201 void set_load_state(LoadState load_state) { load_state_ = load_state; }
202
[email protected]ab838892009-06-30 18:49:05203 int DoConnect(bool succeed, bool was_async) {
204 int result = ERR_CONNECTION_FAILED;
[email protected]ab838892009-06-30 18:49:05205 if (succeed) {
206 result = OK;
[email protected]a2006ece2010-04-23 16:44:02207 socket()->Connect(NULL);
[email protected]6e713f02009-08-06 02:56:40208 } else {
209 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05210 }
[email protected]2ab05b52009-07-01 23:57:58211
212 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30213 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05214 return result;
215 }
216
[email protected]cfa8228c2010-06-17 01:07:56217 // This function helps simulate the progress of load states on a ConnectJob.
218 // Each time it is called it advances the load state and posts a task to be
219 // called again. It stops at the last connecting load state (the one
220 // before LOAD_STATE_SENDING_REQUEST).
[email protected]5fc08e32009-07-15 17:09:57221 void AdvanceLoadState(LoadState state) {
222 int tmp = state;
223 tmp++;
[email protected]cfa8228c2010-06-17 01:07:56224 if (tmp < LOAD_STATE_SENDING_REQUEST) {
225 state = static_cast<LoadState>(tmp);
226 set_load_state(state);
227 MessageLoop::current()->PostTask(
228 FROM_HERE,
229 method_factory_.NewRunnableMethod(&TestConnectJob::AdvanceLoadState,
230 state));
231 }
[email protected]5fc08e32009-07-15 17:09:57232 }
233
234 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05235 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57236 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05237 ScopedRunnableMethodFactory<TestConnectJob> method_factory_;
[email protected]46451352009-09-01 14:54:21238 LoadState load_state_;
[email protected]ab838892009-06-30 18:49:05239
240 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
241};
242
[email protected]d80a4322009-08-14 07:07:49243class TestConnectJobFactory
244 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05245 public:
[email protected]5fc08e32009-07-15 17:09:57246 explicit TestConnectJobFactory(MockClientSocketFactory* client_socket_factory)
[email protected]ab838892009-06-30 18:49:05247 : job_type_(TestConnectJob::kMockJob),
248 client_socket_factory_(client_socket_factory) {}
249
250 virtual ~TestConnectJobFactory() {}
251
252 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
253
[email protected]974ebd62009-08-03 23:14:34254 void set_timeout_duration(base::TimeDelta timeout_duration) {
255 timeout_duration_ = timeout_duration;
256 }
257
[email protected]ab838892009-06-30 18:49:05258 // ConnectJobFactory methods:
259
260 virtual ConnectJob* NewConnectJob(
261 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49262 const TestClientSocketPoolBase::Request& request,
[email protected]06650c52010-06-03 00:49:17263 ConnectJob::Delegate* delegate) const {
[email protected]ab838892009-06-30 18:49:05264 return new TestConnectJob(job_type_,
265 group_name,
266 request,
[email protected]974ebd62009-08-03 23:14:34267 timeout_duration_,
[email protected]ab838892009-06-30 18:49:05268 delegate,
[email protected]fd7b7c92009-08-20 19:38:30269 client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17270 NULL);
[email protected]ab838892009-06-30 18:49:05271 }
272
[email protected]a796bcec2010-03-22 17:17:26273 virtual base::TimeDelta ConnectionTimeout() const {
274 return timeout_duration_;
275 }
276
[email protected]ab838892009-06-30 18:49:05277 private:
278 TestConnectJob::JobType job_type_;
[email protected]974ebd62009-08-03 23:14:34279 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57280 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05281
282 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
283};
284
285class TestClientSocketPool : public ClientSocketPool {
286 public:
287 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53288 int max_sockets,
[email protected]ab838892009-06-30 18:49:05289 int max_sockets_per_group,
[email protected]b89f7e42010-05-20 20:37:00290 const scoped_refptr<ClientSocketPoolHistograms>& histograms,
[email protected]9bf28db2009-08-29 01:35:16291 base::TimeDelta unused_idle_socket_timeout,
292 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49293 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
[email protected]b89f7e42010-05-20 20:37:00294 : base_(max_sockets, max_sockets_per_group, histograms,
[email protected]9bf28db2009-08-29 01:35:16295 unused_idle_socket_timeout, used_idle_socket_timeout,
[email protected]66761b952010-06-25 21:30:38296 connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05297
298 virtual int RequestSocket(
299 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49300 const void* params,
[email protected]ac790b42009-12-02 04:31:31301 net::RequestPriority priority,
[email protected]ab838892009-06-30 18:49:05302 ClientSocketHandle* handle,
[email protected]684970b2009-08-14 04:54:46303 CompletionCallback* callback,
[email protected]9e743cd2010-03-16 07:03:53304 const BoundNetLog& net_log) {
[email protected]951269b2010-06-15 19:39:24305 const TestSocketParams* casted_socket_params =
306 static_cast<const TestSocketParams*>(params);
[email protected]d80a4322009-08-14 07:07:49307 return base_.RequestSocket(
[email protected]951269b2010-06-15 19:39:24308 group_name, *casted_socket_params, priority, handle, callback, net_log);
[email protected]ab838892009-06-30 18:49:05309 }
310
311 virtual void CancelRequest(
312 const std::string& group_name,
313 const ClientSocketHandle* handle) {
[email protected]d80a4322009-08-14 07:07:49314 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05315 }
316
317 virtual void ReleaseSocket(
318 const std::string& group_name,
[email protected]a7e38572010-06-07 18:22:24319 ClientSocket* socket,
320 int id) {
321 base_.ReleaseSocket(group_name, socket, id);
322 }
323
324 virtual void Flush() {
325 base_.Flush();
[email protected]ab838892009-06-30 18:49:05326 }
327
328 virtual void CloseIdleSockets() {
[email protected]d80a4322009-08-14 07:07:49329 base_.CloseIdleSockets();
[email protected]ab838892009-06-30 18:49:05330 }
331
[email protected]d80a4322009-08-14 07:07:49332 virtual int IdleSocketCount() const { return base_.idle_socket_count(); }
[email protected]ab838892009-06-30 18:49:05333
334 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49335 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05336 }
337
338 virtual LoadState GetLoadState(const std::string& group_name,
339 const ClientSocketHandle* handle) const {
[email protected]d80a4322009-08-14 07:07:49340 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05341 }
342
[email protected]a796bcec2010-03-22 17:17:26343 virtual base::TimeDelta ConnectionTimeout() const {
344 return base_.ConnectionTimeout();
345 }
346
[email protected]b89f7e42010-05-20 20:37:00347 virtual scoped_refptr<ClientSocketPoolHistograms> histograms() const {
348 return base_.histograms();
349 }
[email protected]a796bcec2010-03-22 17:17:26350
[email protected]d80a4322009-08-14 07:07:49351 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20352
[email protected]974ebd62009-08-03 23:14:34353 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49354 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34355 }
356
[email protected]9bf28db2009-08-29 01:35:16357 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
358
[email protected]43a21b82010-06-10 21:30:54359 void EnableBackupJobs() { base_.EnableBackupJobs(); }
360
[email protected]ab838892009-06-30 18:49:05361 private:
[email protected]5389bc72009-11-05 23:34:24362 ~TestClientSocketPool() {}
363
[email protected]d80a4322009-08-14 07:07:49364 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05365
366 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
367};
368
[email protected]a937a06d2009-08-19 21:19:24369} // namespace
370
[email protected]7fc5b09a2010-02-27 00:07:38371REGISTER_SOCKET_PARAMS_FOR_POOL(TestClientSocketPool, TestSocketParams);
[email protected]a937a06d2009-08-19 21:19:24372
373namespace {
374
[email protected]5fc08e32009-07-15 17:09:57375void MockClientSocketFactory::SignalJobs() {
376 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
377 it != waiting_jobs_.end(); ++it) {
378 (*it)->Signal();
379 }
380 waiting_jobs_.clear();
381}
382
[email protected]974ebd62009-08-03 23:14:34383class TestConnectJobDelegate : public ConnectJob::Delegate {
384 public:
385 TestConnectJobDelegate()
386 : have_result_(false), waiting_for_result_(false), result_(OK) {}
387 virtual ~TestConnectJobDelegate() {}
388
389 virtual void OnConnectJobComplete(int result, ConnectJob* job) {
390 result_ = result;
[email protected]6e713f02009-08-06 02:56:40391 scoped_ptr<ClientSocket> socket(job->ReleaseSocket());
[email protected]9b6fee12009-09-29 18:13:07392 // socket.get() should be NULL iff result != OK
393 EXPECT_EQ(socket.get() == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34394 delete job;
395 have_result_ = true;
396 if (waiting_for_result_)
397 MessageLoop::current()->Quit();
398 }
399
400 int WaitForResult() {
401 DCHECK(!waiting_for_result_);
402 while (!have_result_) {
403 waiting_for_result_ = true;
404 MessageLoop::current()->Run();
405 waiting_for_result_ = false;
406 }
407 have_result_ = false; // auto-reset for next callback
408 return result_;
409 }
410
411 private:
412 bool have_result_;
413 bool waiting_for_result_;
414 int result_;
415};
416
[email protected]75439d3b2009-07-23 22:11:17417class ClientSocketPoolBaseTest : public ClientSocketPoolTest {
[email protected]f6d1d6eb2009-06-24 20:16:09418 protected:
[email protected]b89f7e42010-05-20 20:37:00419 ClientSocketPoolBaseTest()
420 : histograms_(new ClientSocketPoolHistograms("ClientSocketPoolTest")) {}
[email protected]c9d6a1d2009-07-14 16:15:20421
[email protected]211d21722009-07-22 15:48:53422 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16423 CreatePoolWithIdleTimeouts(
424 max_sockets,
425 max_sockets_per_group,
[email protected]241c5c2c2010-06-21 18:46:00426 base::TimeDelta::FromSeconds(
427 ClientSocketPool::unused_idle_socket_timeout()),
[email protected]9bf28db2009-08-29 01:35:16428 base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout));
429 }
430
431 void CreatePoolWithIdleTimeouts(
432 int max_sockets, int max_sockets_per_group,
433 base::TimeDelta unused_idle_socket_timeout,
434 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20435 DCHECK(!pool_.get());
[email protected]17a0c6c2009-08-04 00:07:04436 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_);
[email protected]211d21722009-07-22 15:48:53437 pool_ = new TestClientSocketPool(max_sockets,
438 max_sockets_per_group,
[email protected]b89f7e42010-05-20 20:37:00439 histograms_,
[email protected]9bf28db2009-08-29 01:35:16440 unused_idle_socket_timeout,
441 used_idle_socket_timeout,
[email protected]c9d6a1d2009-07-14 16:15:20442 connect_job_factory_);
443 }
[email protected]f6d1d6eb2009-06-24 20:16:09444
[email protected]ac790b42009-12-02 04:31:31445 int StartRequest(const std::string& group_name,
446 net::RequestPriority priority) {
[email protected]951269b2010-06-15 19:39:24447 TestSocketParams params;
[email protected]7fc5b09a2010-02-27 00:07:38448 return StartRequestUsingPool<TestClientSocketPool, TestSocketParams>(
[email protected]951269b2010-06-15 19:39:24449 pool_, group_name, priority, params);
[email protected]f6d1d6eb2009-06-24 20:16:09450 }
451
452 virtual void TearDown() {
[email protected]6b175382009-10-13 06:47:47453 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
454 // actually become pending until 2ms after they have been created. In order
455 // to flush all tasks, we need to wait so that we know there are no
456 // soon-to-be-pending tasks waiting.
457 PlatformThread::Sleep(10);
458 MessageLoop::current()->RunAllPending();
459
[email protected]211d21722009-07-22 15:48:53460 // Need to delete |pool_| before we turn late binding back off. We also need
461 // to delete |requests_| because the pool is reference counted and requests
462 // keep reference to it.
463 // TODO(willchan): Remove this part when late binding becomes the default.
[email protected]5fc08e32009-07-15 17:09:57464 pool_ = NULL;
[email protected]211d21722009-07-22 15:48:53465 requests_.reset();
466
[email protected]75439d3b2009-07-23 22:11:17467 ClientSocketPoolTest::TearDown();
[email protected]f6d1d6eb2009-06-24 20:16:09468 }
469
[email protected]f6d1d6eb2009-06-24 20:16:09470 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04471 TestConnectJobFactory* connect_job_factory_;
[email protected]c9d6a1d2009-07-14 16:15:20472 scoped_refptr<TestClientSocketPool> pool_;
[email protected]b89f7e42010-05-20 20:37:00473 scoped_refptr<ClientSocketPoolHistograms> histograms_;
[email protected]f6d1d6eb2009-06-24 20:16:09474};
475
[email protected]a937a06d2009-08-19 21:19:24476// Helper function which explicitly specifies the template parameters, since
477// the compiler will infer (in this case, incorrectly) that NULL is of type int.
478int InitHandle(ClientSocketHandle* handle,
479 const std::string& group_name,
[email protected]ac790b42009-12-02 04:31:31480 net::RequestPriority priority,
[email protected]a937a06d2009-08-19 21:19:24481 CompletionCallback* callback,
[email protected]a796bcec2010-03-22 17:17:26482 const scoped_refptr<TestClientSocketPool>& pool,
[email protected]9e743cd2010-03-16 07:03:53483 const BoundNetLog& net_log) {
[email protected]951269b2010-06-15 19:39:24484 TestSocketParams params;
[email protected]7fc5b09a2010-02-27 00:07:38485 return handle->Init<TestSocketParams, TestClientSocketPool>(
[email protected]951269b2010-06-15 19:39:24486 group_name, params, priority, callback, pool, net_log);
[email protected]a937a06d2009-08-19 21:19:24487}
488
[email protected]974ebd62009-08-03 23:14:34489// Even though a timeout is specified, it doesn't time out on a synchronous
490// completion.
491TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
492 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06493 ClientSocketHandle ignored;
[email protected]951269b2010-06-15 19:39:24494 TestSocketParams params;
[email protected]d80a4322009-08-14 07:07:49495 TestClientSocketPoolBase::Request request(
[email protected]951269b2010-06-15 19:39:24496 &ignored, NULL, kDefaultPriority, params, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34497 scoped_ptr<TestConnectJob> job(
498 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:12499 "a",
[email protected]974ebd62009-08-03 23:14:34500 request,
501 base::TimeDelta::FromMicroseconds(1),
502 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30503 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17504 NULL));
[email protected]974ebd62009-08-03 23:14:34505 EXPECT_EQ(OK, job->Connect());
506}
507
508TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
509 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06510 ClientSocketHandle ignored;
[email protected]06650c52010-06-03 00:49:17511 CapturingNetLog log(CapturingNetLog::kUnbounded);
[email protected]9e743cd2010-03-16 07:03:53512
[email protected]951269b2010-06-15 19:39:24513 TestSocketParams params;
[email protected]d80a4322009-08-14 07:07:49514 TestClientSocketPoolBase::Request request(
[email protected]951269b2010-06-15 19:39:24515 &ignored, NULL, kDefaultPriority, params, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34516 // Deleted by TestConnectJobDelegate.
517 TestConnectJob* job =
518 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12519 "a",
[email protected]974ebd62009-08-03 23:14:34520 request,
521 base::TimeDelta::FromMicroseconds(1),
522 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30523 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17524 &log);
[email protected]974ebd62009-08-03 23:14:34525 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
526 PlatformThread::Sleep(1);
527 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30528
[email protected]06650c52010-06-03 00:49:17529 EXPECT_EQ(6u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:46530 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:53531 log.entries(), 0, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]06650c52010-06-03 00:49:17532 EXPECT_TRUE(LogContainsBeginEvent(
533 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]e9002a92010-01-29 07:10:46534 EXPECT_TRUE(LogContainsEvent(
[email protected]06650c52010-06-03 00:49:17535 log.entries(), 2, NetLog::TYPE_CONNECT_JOB_SET_SOCKET,
536 NetLog::PHASE_NONE));
537 EXPECT_TRUE(LogContainsEvent(
538 log.entries(), 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
[email protected]9e743cd2010-03-16 07:03:53539 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:46540 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:17541 log.entries(), 4, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
542 EXPECT_TRUE(LogContainsEndEvent(
543 log.entries(), 5, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34544}
545
[email protected]5fc08e32009-07-15 17:09:57546TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53547 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20548
[email protected]f6d1d6eb2009-06-24 20:16:09549 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06550 ClientSocketHandle handle;
[email protected]9e743cd2010-03-16 07:03:53551 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
552
[email protected]a796bcec2010-03-22 17:17:26553 EXPECT_EQ(OK, InitHandle(&handle, "a", kDefaultPriority, &callback, pool_,
554 log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09555 EXPECT_TRUE(handle.is_initialized());
556 EXPECT_TRUE(handle.socket());
[email protected]f6d1d6eb2009-06-24 20:16:09557 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:30558
[email protected]06650c52010-06-03 00:49:17559 EXPECT_EQ(4u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:46560 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:53561 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]9e743cd2010-03-16 07:03:53562 EXPECT_TRUE(LogContainsEvent(
[email protected]06650c52010-06-03 00:49:17563 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
564 NetLog::PHASE_NONE));
565 EXPECT_TRUE(LogContainsEvent(
566 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]9e743cd2010-03-16 07:03:53567 NetLog::PHASE_NONE));
568 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:17569 log.entries(), 3, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09570}
571
[email protected]ab838892009-06-30 18:49:05572TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53573 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20574
[email protected]ab838892009-06-30 18:49:05575 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]9e743cd2010-03-16 07:03:53576 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
577
[email protected]a512f5982009-08-18 16:01:06578 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]3ae82302009-06-26 06:01:21579 EXPECT_EQ(ERR_CONNECTION_FAILED,
[email protected]a796bcec2010-03-22 17:17:26580 InitHandle(req.handle(), "a", kDefaultPriority, &req, pool_,
581 log.bound()));
[email protected]fd7b7c92009-08-20 19:38:30582
[email protected]06650c52010-06-03 00:49:17583 EXPECT_EQ(3u, log.entries().size());
[email protected]5a1d7ca2010-04-28 20:12:27584 EXPECT_TRUE(LogContainsBeginEvent(
585 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:17586 EXPECT_TRUE(LogContainsEvent(
587 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
588 NetLog::PHASE_NONE));
[email protected]a2006ece2010-04-23 16:44:02589 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:17590 log.entries(), 2, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09591}
592
[email protected]211d21722009-07-22 15:48:53593TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
594 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
595
[email protected]9e743cd2010-03-16 07:03:53596 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30597
[email protected]211d21722009-07-22 15:48:53598 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
599 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
600 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
601 EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
602
603 EXPECT_EQ(static_cast<int>(requests_.size()),
604 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17605 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53606
607 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
608 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
609 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
610
[email protected]43a21b82010-06-10 21:30:54611 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53612
613 EXPECT_EQ(static_cast<int>(requests_.size()),
614 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17615 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53616
617 EXPECT_EQ(1, GetOrderOfRequest(1));
618 EXPECT_EQ(2, GetOrderOfRequest(2));
619 EXPECT_EQ(3, GetOrderOfRequest(3));
620 EXPECT_EQ(4, GetOrderOfRequest(4));
621 EXPECT_EQ(5, GetOrderOfRequest(5));
622 EXPECT_EQ(6, GetOrderOfRequest(6));
623 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17624
625 // Make sure we test order of all requests made.
626 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53627}
628
629TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
630 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
631
[email protected]9e743cd2010-03-16 07:03:53632 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30633
[email protected]211d21722009-07-22 15:48:53634 // Reach all limits: max total sockets, and max sockets per group.
635 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
636 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
637 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
638 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
639
640 EXPECT_EQ(static_cast<int>(requests_.size()),
641 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17642 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53643
644 // Now create a new group and verify that we don't starve it.
645 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
646
[email protected]43a21b82010-06-10 21:30:54647 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53648
649 EXPECT_EQ(static_cast<int>(requests_.size()),
650 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17651 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53652
653 EXPECT_EQ(1, GetOrderOfRequest(1));
654 EXPECT_EQ(2, GetOrderOfRequest(2));
655 EXPECT_EQ(3, GetOrderOfRequest(3));
656 EXPECT_EQ(4, GetOrderOfRequest(4));
657 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17658
659 // Make sure we test order of all requests made.
660 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53661}
662
663TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
664 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
665
[email protected]ac790b42009-12-02 04:31:31666 EXPECT_EQ(OK, StartRequest("b", LOWEST));
667 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
668 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
669 EXPECT_EQ(OK, StartRequest("a", LOWEST));
[email protected]211d21722009-07-22 15:48:53670
671 EXPECT_EQ(static_cast<int>(requests_.size()),
672 client_socket_factory_.allocation_count());
673
[email protected]ac790b42009-12-02 04:31:31674 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
675 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
676 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53677
[email protected]43a21b82010-06-10 21:30:54678 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53679
[email protected]75439d3b2009-07-23 22:11:17680 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53681
682 // First 4 requests don't have to wait, and finish in order.
683 EXPECT_EQ(1, GetOrderOfRequest(1));
684 EXPECT_EQ(2, GetOrderOfRequest(2));
685 EXPECT_EQ(3, GetOrderOfRequest(3));
686 EXPECT_EQ(4, GetOrderOfRequest(4));
687
[email protected]ac790b42009-12-02 04:31:31688 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
689 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53690 EXPECT_EQ(7, GetOrderOfRequest(5));
691 EXPECT_EQ(6, GetOrderOfRequest(6));
692 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17693
694 // Make sure we test order of all requests made.
695 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53696}
697
698TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
699 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
700
[email protected]ac790b42009-12-02 04:31:31701 EXPECT_EQ(OK, StartRequest("a", LOWEST));
702 EXPECT_EQ(OK, StartRequest("a", LOW));
703 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
704 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
[email protected]211d21722009-07-22 15:48:53705
706 EXPECT_EQ(static_cast<int>(requests_.size()),
707 client_socket_factory_.allocation_count());
708
[email protected]ac790b42009-12-02 04:31:31709 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
710 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
711 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53712
[email protected]43a21b82010-06-10 21:30:54713 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53714
[email protected]43a21b82010-06-10 21:30:54715 EXPECT_EQ(static_cast<int>(requests_.size()),
[email protected]211d21722009-07-22 15:48:53716 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17717 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53718
719 // First 4 requests don't have to wait, and finish in order.
720 EXPECT_EQ(1, GetOrderOfRequest(1));
721 EXPECT_EQ(2, GetOrderOfRequest(2));
722 EXPECT_EQ(3, GetOrderOfRequest(3));
723 EXPECT_EQ(4, GetOrderOfRequest(4));
724
725 // Request ("b", 7) has the highest priority, but we can't make new socket for
726 // group "b", because it has reached the per-group limit. Then we make
727 // socket for ("c", 6), because it has higher priority than ("a", 4),
728 // and we still can't make a socket for group "b".
729 EXPECT_EQ(5, GetOrderOfRequest(5));
730 EXPECT_EQ(6, GetOrderOfRequest(6));
731 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17732
733 // Make sure we test order of all requests made.
734 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53735}
736
737// Make sure that we count connecting sockets against the total limit.
738TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
739 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
740
741 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
742 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
743 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
744
745 // Create one asynchronous request.
746 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
747 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
748
[email protected]6b175382009-10-13 06:47:47749 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
750 // actually become pending until 2ms after they have been created. In order
751 // to flush all tasks, we need to wait so that we know there are no
752 // soon-to-be-pending tasks waiting.
753 PlatformThread::Sleep(10);
754 MessageLoop::current()->RunAllPending();
755
[email protected]211d21722009-07-22 15:48:53756 // The next synchronous request should wait for its turn.
757 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
758 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
759
[email protected]43a21b82010-06-10 21:30:54760 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53761
762 EXPECT_EQ(static_cast<int>(requests_.size()),
763 client_socket_factory_.allocation_count());
764
765 EXPECT_EQ(1, GetOrderOfRequest(1));
766 EXPECT_EQ(2, GetOrderOfRequest(2));
767 EXPECT_EQ(3, GetOrderOfRequest(3));
768 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:17769 EXPECT_EQ(5, GetOrderOfRequest(5));
770
771 // Make sure we test order of all requests made.
772 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53773}
774
[email protected]6427fe22010-04-16 22:27:41775TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
776 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
777 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
778
779 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
780 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
781 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
782 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
783
784 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
785
786 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
787
788 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", kDefaultPriority));
789 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
790
791 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
792
793 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
794 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
795 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
796 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
797 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
798 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
799 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
800}
801
[email protected]d7027bb2010-05-10 18:58:54802TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
803 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
804 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
805
806 ClientSocketHandle handle;
807 TestCompletionCallback callback;
808 EXPECT_EQ(ERR_IO_PENDING,
809 InitHandle(&handle, "a", kDefaultPriority, &callback, pool_,
810 BoundNetLog()));
811
812 ClientSocketHandle handles[4];
813 for (size_t i = 0; i < arraysize(handles); ++i) {
814 TestCompletionCallback callback;
815 EXPECT_EQ(ERR_IO_PENDING,
816 InitHandle(&handles[i], "b", kDefaultPriority, &callback, pool_,
817 BoundNetLog()));
818 }
819
820 // One will be stalled, cancel all the handles now.
821 // This should hit the OnAvailableSocketSlot() code where we previously had
822 // stalled groups, but no longer have any.
823 for (size_t i = 0; i < arraysize(handles); ++i)
824 handles[i].Reset();
825}
826
[email protected]eb5a99382010-07-11 03:18:26827TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:54828 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
829 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
830
[email protected]eb5a99382010-07-11 03:18:26831 {
832 ClientSocketHandle handles[kDefaultMaxSockets];
833 TestCompletionCallback callbacks[kDefaultMaxSockets];
834 for (int i = 0; i < kDefaultMaxSockets; ++i) {
835 EXPECT_EQ(OK,
836 InitHandle(&handles[i], IntToString(i), kDefaultPriority,
837 &callbacks[i], pool_, BoundNetLog()));
838 }
839
840 // Force a stalled group.
841 ClientSocketHandle stalled_handle;
[email protected]43a21b82010-06-10 21:30:54842 TestCompletionCallback callback;
[email protected]eb5a99382010-07-11 03:18:26843 EXPECT_EQ(ERR_IO_PENDING,
844 InitHandle(&stalled_handle, "foo", kDefaultPriority, &callback,
[email protected]43a21b82010-06-10 21:30:54845 pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26846
847 // Cancel the stalled request.
848 stalled_handle.Reset();
849
850 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
851 EXPECT_EQ(0, pool_->IdleSocketCount());
852
853 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:54854 }
855
[email protected]43a21b82010-06-10 21:30:54856 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
857 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:26858}
[email protected]43a21b82010-06-10 21:30:54859
[email protected]eb5a99382010-07-11 03:18:26860TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
861 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
862 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
863
864 {
865 ClientSocketHandle handles[kDefaultMaxSockets];
866 for (int i = 0; i < kDefaultMaxSockets; ++i) {
867 TestCompletionCallback callback;
868 EXPECT_EQ(ERR_IO_PENDING,
869 InitHandle(&handles[i], IntToString(i), kDefaultPriority,
870 &callback, pool_, BoundNetLog()));
871 }
872
873 // Force a stalled group.
874 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
875 ClientSocketHandle stalled_handle;
[email protected]43a21b82010-06-10 21:30:54876 TestCompletionCallback callback;
[email protected]eb5a99382010-07-11 03:18:26877 EXPECT_EQ(ERR_IO_PENDING,
878 InitHandle(&stalled_handle, "foo", kDefaultPriority, &callback,
879 pool_, BoundNetLog()));
880
881 // Since it is stalled, it should have no connect jobs.
882 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
883
884 // Cancel the stalled request.
885 handles[0].Reset();
886
887 MessageLoop::current()->RunAllPending();
888
889 // Now we should have a connect job.
890 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("foo"));
891
892 // The stalled socket should connect.
893 EXPECT_EQ(OK, callback.WaitForResult());
894
895 EXPECT_EQ(kDefaultMaxSockets + 1,
896 client_socket_factory_.allocation_count());
897 EXPECT_EQ(0, pool_->IdleSocketCount());
898 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
899
900 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:54901 }
902
[email protected]eb5a99382010-07-11 03:18:26903 EXPECT_EQ(1, pool_->IdleSocketCount());
904}
[email protected]43a21b82010-06-10 21:30:54905
[email protected]eb5a99382010-07-11 03:18:26906TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
907 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
908 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:54909
[email protected]eb5a99382010-07-11 03:18:26910 ClientSocketHandle stalled_handle;
911 TestCompletionCallback callback;
912 {
913 ClientSocketHandle handles[kDefaultMaxSockets];
914 for (int i = 0; i < kDefaultMaxSockets; ++i) {
915 TestCompletionCallback callback;
916 EXPECT_EQ(OK,
917 InitHandle(&handles[i], StringPrintf("Take 2: %d", i),
918 kDefaultPriority, &callback, pool_, BoundNetLog()));
919 }
920
921 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
922 EXPECT_EQ(0, pool_->IdleSocketCount());
923
924 // Now we will hit the socket limit.
925 EXPECT_EQ(ERR_IO_PENDING,
926 InitHandle(&stalled_handle, "foo", kDefaultPriority, &callback,
927 pool_, BoundNetLog()));
928
929 // Dropping out of scope will close all handles and return them to idle.
930 }
[email protected]43a21b82010-06-10 21:30:54931
932 // But if we wait for it, the released idle sockets will be closed in
933 // preference of the waiting request.
[email protected]8ae03f42010-07-07 19:08:10934 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]eb5a99382010-07-11 03:18:26935
936 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
937 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:54938}
939
940// Regression test for http://crbug.com/40952.
941TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
942 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
943 pool_->EnableBackupJobs();
944 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
945
946 for (int i = 0; i < kDefaultMaxSockets; ++i) {
947 ClientSocketHandle handle;
948 TestCompletionCallback callback;
949 EXPECT_EQ(OK,
950 InitHandle(&handle, IntToString(i), kDefaultPriority, &callback,
951 pool_, BoundNetLog()));
952 }
953
954 // Flush all the DoReleaseSocket tasks.
955 MessageLoop::current()->RunAllPending();
956
957 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
958 // reuse a socket.
959 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
960 ClientSocketHandle handle;
961 TestCompletionCallback callback;
962
963 // "0" is special here, since it should be the first entry in the sorted map,
964 // which is the one which we would close an idle socket for. We shouldn't
965 // close an idle socket though, since we should reuse the idle socket.
966 EXPECT_EQ(
967 OK,
968 InitHandle(
969 &handle, "0", kDefaultPriority, &callback, pool_, BoundNetLog()));
970
971 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
972 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
973}
974
[email protected]ab838892009-06-30 18:49:05975TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:53976 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09977
[email protected]c9d6a1d2009-07-14 16:15:20978 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
979 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:31980 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
981 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
982 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
983 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
984 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:09985
[email protected]c9d6a1d2009-07-14 16:15:20986 ReleaseAllConnections(KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09987
[email protected]c9d6a1d2009-07-14 16:15:20988 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
989 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17990 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09991
[email protected]c9d6a1d2009-07-14 16:15:20992 EXPECT_EQ(1, GetOrderOfRequest(1));
993 EXPECT_EQ(2, GetOrderOfRequest(2));
994 EXPECT_EQ(6, GetOrderOfRequest(3));
995 EXPECT_EQ(4, GetOrderOfRequest(4));
996 EXPECT_EQ(3, GetOrderOfRequest(5));
997 EXPECT_EQ(5, GetOrderOfRequest(6));
998 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17999
1000 // Make sure we test order of all requests made.
1001 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091002}
1003
[email protected]ab838892009-06-30 18:49:051004TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531005 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091006
[email protected]c9d6a1d2009-07-14 16:15:201007 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1008 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311009 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1010 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1011 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1012 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1013 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091014
[email protected]c9d6a1d2009-07-14 16:15:201015 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091016
[email protected]c9d6a1d2009-07-14 16:15:201017 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i)
1018 EXPECT_EQ(OK, requests_[i]->WaitForResult());
1019
1020 EXPECT_EQ(static_cast<int>(requests_.size()),
1021 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:171022 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091023}
1024
1025// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:051026// The pending connect job will be cancelled and should not call back into
1027// ClientSocketPoolBase.
1028TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531029 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201030
[email protected]ab838892009-06-30 18:49:051031 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061032 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]ab838892009-06-30 18:49:051033 EXPECT_EQ(ERR_IO_PENDING,
[email protected]5a1d7ca2010-04-28 20:12:271034 InitHandle(req.handle(), "a", kDefaultPriority, &req, pool_,
1035 BoundNetLog()));
[email protected]a6c59f62009-07-29 16:33:331036 req.handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091037}
1038
[email protected]ab838892009-06-30 18:49:051039TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531040 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201041
[email protected]ab838892009-06-30 18:49:051042 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061043 ClientSocketHandle handle;
[email protected]f6d1d6eb2009-06-24 20:16:091044 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:061045 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091046
[email protected]ab838892009-06-30 18:49:051047 EXPECT_EQ(ERR_IO_PENDING,
[email protected]5a1d7ca2010-04-28 20:12:271048 InitHandle(&handle, "a", kDefaultPriority, &callback, pool_,
1049 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091050
1051 handle.Reset();
1052
1053 TestCompletionCallback callback2;
[email protected]a796bcec2010-03-22 17:17:261054 EXPECT_EQ(ERR_IO_PENDING, InitHandle(&handle, "a", kDefaultPriority,
[email protected]5a1d7ca2010-04-28 20:12:271055 &callback2, pool_, BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091056
1057 EXPECT_EQ(OK, callback2.WaitForResult());
1058 EXPECT_FALSE(callback.have_result());
1059
1060 handle.Reset();
1061}
1062
[email protected]ab838892009-06-30 18:49:051063TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531064 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091065
[email protected]c9d6a1d2009-07-14 16:15:201066 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1067 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311068 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1069 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1070 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1071 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1072 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091073
1074 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201075 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]a6c59f62009-07-29 16:33:331076 EXPECT_FALSE(requests_[index_to_cancel]->handle()->is_initialized());
1077 requests_[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091078
[email protected]c9d6a1d2009-07-14 16:15:201079 ReleaseAllConnections(KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091080
[email protected]c9d6a1d2009-07-14 16:15:201081 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1082 client_socket_factory_.allocation_count());
1083 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup - 1,
[email protected]75439d3b2009-07-23 22:11:171084 completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091085
[email protected]c9d6a1d2009-07-14 16:15:201086 EXPECT_EQ(1, GetOrderOfRequest(1));
1087 EXPECT_EQ(2, GetOrderOfRequest(2));
1088 EXPECT_EQ(5, GetOrderOfRequest(3));
1089 EXPECT_EQ(3, GetOrderOfRequest(4));
1090 EXPECT_EQ(kRequestNotFound, GetOrderOfRequest(5)); // Canceled request.
1091 EXPECT_EQ(4, GetOrderOfRequest(6));
1092 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171093
1094 // Make sure we test order of all requests made.
1095 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091096}
1097
1098class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
1099 public:
[email protected]2ab05b52009-07-01 23:57:581100 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:241101 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:581102 TestConnectJobFactory* test_connect_job_factory,
1103 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:091104 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:061105 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:581106 within_callback_(false),
1107 test_connect_job_factory_(test_connect_job_factory),
1108 next_job_type_(next_job_type) {}
[email protected]f6d1d6eb2009-06-24 20:16:091109
1110 virtual void RunWithParams(const Tuple1<int>& params) {
1111 callback_.RunWithParams(params);
1112 ASSERT_EQ(OK, params.a);
1113
1114 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:581115 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]5edbf8d2010-01-13 18:44:111116
1117 // Don't allow reuse of the socket. Disconnect it and then release it and
1118 // run through the MessageLoop once to get it completely released.
1119 handle_->socket()->Disconnect();
[email protected]f6d1d6eb2009-06-24 20:16:091120 handle_->Reset();
[email protected]5edbf8d2010-01-13 18:44:111121 {
1122 MessageLoop::ScopedNestableTaskAllower nestable(
1123 MessageLoop::current());
1124 MessageLoop::current()->RunAllPending();
1125 }
[email protected]f6d1d6eb2009-06-24 20:16:091126 within_callback_ = true;
[email protected]6b175382009-10-13 06:47:471127 TestCompletionCallback next_job_callback;
[email protected]a796bcec2010-03-22 17:17:261128 int rv = InitHandle(handle_, "a", kDefaultPriority, &next_job_callback,
[email protected]5a1d7ca2010-04-28 20:12:271129 pool_, BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581130 switch (next_job_type_) {
1131 case TestConnectJob::kMockJob:
1132 EXPECT_EQ(OK, rv);
1133 break;
1134 case TestConnectJob::kMockPendingJob:
1135 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:471136
1137 // For pending jobs, wait for new socket to be created. This makes
1138 // sure there are no more pending operations nor any unclosed sockets
1139 // when the test finishes.
1140 // We need to give it a little bit of time to run, so that all the
1141 // operations that happen on timers (e.g. cleanup of idle
1142 // connections) can execute.
[email protected]5edbf8d2010-01-13 18:44:111143 {
1144 MessageLoop::ScopedNestableTaskAllower nestable(
1145 MessageLoop::current());
1146 PlatformThread::Sleep(10);
1147 EXPECT_EQ(OK, next_job_callback.WaitForResult());
1148 }
[email protected]2ab05b52009-07-01 23:57:581149 break;
1150 default:
1151 FAIL() << "Unexpected job type: " << next_job_type_;
1152 break;
1153 }
[email protected]f6d1d6eb2009-06-24 20:16:091154 }
1155 }
1156
1157 int WaitForResult() {
1158 return callback_.WaitForResult();
1159 }
1160
1161 private:
1162 ClientSocketHandle* const handle_;
[email protected]a937a06d2009-08-19 21:19:241163 const scoped_refptr<TestClientSocketPool> pool_;
[email protected]f6d1d6eb2009-06-24 20:16:091164 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:581165 TestConnectJobFactory* const test_connect_job_factory_;
1166 TestConnectJob::JobType next_job_type_;
[email protected]f6d1d6eb2009-06-24 20:16:091167 TestCompletionCallback callback_;
1168};
1169
[email protected]2ab05b52009-07-01 23:57:581170TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531171 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201172
[email protected]0b7648c2009-07-06 20:14:011173 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061174 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581175 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061176 &handle, pool_.get(), connect_job_factory_,
1177 TestConnectJob::kMockPendingJob);
[email protected]5a1d7ca2010-04-28 20:12:271178 int rv = InitHandle(&handle, "a", kDefaultPriority, &callback, pool_,
1179 BoundNetLog());
[email protected]f6d1d6eb2009-06-24 20:16:091180 ASSERT_EQ(ERR_IO_PENDING, rv);
1181
1182 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581183}
[email protected]f6d1d6eb2009-06-24 20:16:091184
[email protected]2ab05b52009-07-01 23:57:581185TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531186 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201187
[email protected]0b7648c2009-07-06 20:14:011188 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061189 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581190 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061191 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]5a1d7ca2010-04-28 20:12:271192 int rv = InitHandle(&handle, "a", kDefaultPriority, &callback, pool_,
1193 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581194 ASSERT_EQ(ERR_IO_PENDING, rv);
1195
1196 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091197}
1198
1199// Make sure that pending requests get serviced after active requests get
1200// cancelled.
[email protected]ab838892009-06-30 18:49:051201TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531202 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201203
[email protected]0b7648c2009-07-06 20:14:011204 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091205
[email protected]c9d6a1d2009-07-14 16:15:201206 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1207 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1208 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1209 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1210 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1211 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1212 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091213
[email protected]c9d6a1d2009-07-14 16:15:201214 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1215 // Let's cancel them.
1216 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]a6c59f62009-07-29 16:33:331217 ASSERT_FALSE(requests_[i]->handle()->is_initialized());
1218 requests_[i]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091219 }
1220
[email protected]f6d1d6eb2009-06-24 20:16:091221 // Let's wait for the rest to complete now.
[email protected]c9d6a1d2009-07-14 16:15:201222 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i) {
1223 EXPECT_EQ(OK, requests_[i]->WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331224 requests_[i]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091225 }
1226
[email protected]75439d3b2009-07-23 22:11:171227 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091228}
1229
1230// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051231TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531232 const size_t kMaxSockets = 5;
1233 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201234
[email protected]0b7648c2009-07-06 20:14:011235 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091236
[email protected]211d21722009-07-22 15:48:531237 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1238 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091239
1240 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531241 for (size_t i = 0; i < kNumberOfRequests; ++i)
1242 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091243
[email protected]211d21722009-07-22 15:48:531244 for (size_t i = 0; i < kNumberOfRequests; ++i)
1245 EXPECT_EQ(ERR_CONNECTION_FAILED, requests_[i]->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091246}
1247
[email protected]5fc08e32009-07-15 17:09:571248TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531249 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571250
1251 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1252
[email protected]a512f5982009-08-18 16:01:061253 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271254 int rv = InitHandle(req.handle(), "a", kDefaultPriority, &req, pool_,
1255 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571256 EXPECT_EQ(ERR_IO_PENDING, rv);
1257
1258 // Cancel the active request.
[email protected]a6c59f62009-07-29 16:33:331259 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571260
[email protected]5a1d7ca2010-04-28 20:12:271261 rv = InitHandle(req.handle(), "a", kDefaultPriority, &req, pool_,
1262 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571263 EXPECT_EQ(ERR_IO_PENDING, rv);
1264 EXPECT_EQ(OK, req.WaitForResult());
1265
[email protected]a6c59f62009-07-29 16:33:331266 EXPECT_FALSE(req.handle()->is_reused());
[email protected]75439d3b2009-07-23 22:11:171267 EXPECT_EQ(1U, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571268 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1269}
1270
[email protected]2b7523d2009-07-29 20:29:231271// Regression test for http://crbug.com/17985.
1272TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1273 const int kMaxSockets = 3;
1274 const int kMaxSocketsPerGroup = 2;
1275 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1276
[email protected]ac790b42009-12-02 04:31:311277 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231278
1279 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1280 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1281
1282 // This is going to be a pending request in an otherwise empty group.
1283 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1284
1285 // Reach the maximum socket limit.
1286 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1287
1288 // Create a stalled group with high priorities.
1289 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1290 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
[email protected]2b7523d2009-07-29 20:29:231291
[email protected]eb5a99382010-07-11 03:18:261292 // Release the first two sockets from "a". Because this is a keepalive,
1293 // the first release will unblock the pending request for "a". The
1294 // second release will unblock a request for "c", becaue it is the next
1295 // high priority socket.
[email protected]2b7523d2009-07-29 20:29:231296 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1297 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1298
1299 // Closing idle sockets should not get us into trouble, but in the bug
1300 // we were hitting a CHECK here.
[email protected]93054cc12010-06-08 06:12:411301 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]43a21b82010-06-10 21:30:541302 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261303
1304 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]2b7523d2009-07-29 20:29:231305}
1306
[email protected]4d3b05d2010-01-27 21:27:291307TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531308 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571309
1310 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061311 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]9e743cd2010-03-16 07:03:531312 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]a796bcec2010-03-22 17:17:261313 int rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_, log.bound());
[email protected]5fc08e32009-07-15 17:09:571314 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331315 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:571316 EXPECT_EQ(OK, req.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331317 EXPECT_TRUE(req.handle()->is_initialized());
1318 EXPECT_TRUE(req.handle()->socket());
1319 req.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:301320
[email protected]06650c52010-06-03 00:49:171321 EXPECT_EQ(4u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:461322 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:531323 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171324 EXPECT_TRUE(LogContainsEvent(
1325 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1326 NetLog::PHASE_NONE));
1327 EXPECT_TRUE(LogContainsEvent(
1328 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
1329 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:461330 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:171331 log.entries(), 3, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571332}
1333
[email protected]4d3b05d2010-01-27 21:27:291334TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571335 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531336 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571337
1338 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]a512f5982009-08-18 16:01:061339 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]9e743cd2010-03-16 07:03:531340 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]5fc08e32009-07-15 17:09:571341 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a796bcec2010-03-22 17:17:261342 InitHandle(req.handle(), "a", kDefaultPriority, &req, pool_,
1343 log.bound()));
[email protected]a6c59f62009-07-29 16:33:331344 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:571345 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:301346
[email protected]06650c52010-06-03 00:49:171347 EXPECT_EQ(3u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:461348 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:531349 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171350 EXPECT_TRUE(LogContainsEvent(
1351 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1352 NetLog::PHASE_NONE));
[email protected]6b624c62010-03-14 08:37:321353 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:171354 log.entries(), 2, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571355}
1356
[email protected]4d3b05d2010-01-27 21:27:291357TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101358 // TODO(eroman): Add back the log expectations! Removed them because the
1359 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531360 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571361
1362 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061363 TestSocketRequest req(&request_order_, &completion_count_);
1364 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]5fc08e32009-07-15 17:09:571365
1366 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a796bcec2010-03-22 17:17:261367 InitHandle(req.handle(), "a", kDefaultPriority, &req, pool_,
1368 BoundNetLog()));
[email protected]9e743cd2010-03-16 07:03:531369 CapturingBoundNetLog log2(CapturingNetLog::kUnbounded);
[email protected]5fc08e32009-07-15 17:09:571370 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a796bcec2010-03-22 17:17:261371 InitHandle(req2.handle(), "a", kDefaultPriority, &req2, pool_,
1372 BoundNetLog()));
[email protected]5fc08e32009-07-15 17:09:571373
[email protected]a6c59f62009-07-29 16:33:331374 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571375
[email protected]fd7b7c92009-08-20 19:38:301376
1377 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301378
[email protected]5fc08e32009-07-15 17:09:571379 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331380 req2.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:301381
1382 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531383 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571384}
1385
[email protected]4d3b05d2010-01-27 21:27:291386TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341387 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1388
[email protected]17a0c6c2009-08-04 00:07:041389 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1390
[email protected]ac790b42009-12-02 04:31:311391 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1392 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1393 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1394 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341395
1396 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1397 requests_[2]->handle()->Reset();
1398 requests_[3]->handle()->Reset();
1399 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1400
1401 requests_[1]->handle()->Reset();
1402 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1403
1404 requests_[0]->handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261405 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]974ebd62009-08-03 23:14:341406}
1407
[email protected]5fc08e32009-07-15 17:09:571408// When requests and ConnectJobs are not coupled, the request will get serviced
1409// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291410TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531411 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571412
1413 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321414 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571415
[email protected]a512f5982009-08-18 16:01:061416 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271417 int rv = InitHandle(req1.handle(), "a", kDefaultPriority, &req1, pool_,
1418 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571419 EXPECT_EQ(ERR_IO_PENDING, rv);
1420 EXPECT_EQ(OK, req1.WaitForResult());
1421
1422 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1423 // without a job.
1424 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1425
[email protected]a512f5982009-08-18 16:01:061426 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271427 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2, pool_,
1428 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571429 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a512f5982009-08-18 16:01:061430 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271431 rv = InitHandle(req3.handle(), "a", kDefaultPriority, &req3, pool_,
1432 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571433 EXPECT_EQ(ERR_IO_PENDING, rv);
1434
1435 // Both Requests 2 and 3 are pending. We release socket 1 which should
1436 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331437 req1.handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261438 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]a6c59f62009-07-29 16:33:331439 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571440 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331441 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571442
1443 // Signal job 2, which should service request 3.
1444
1445 client_socket_factory_.SignalJobs();
1446 EXPECT_EQ(OK, req3.WaitForResult());
1447
1448 ASSERT_EQ(3U, request_order_.size());
1449 EXPECT_EQ(&req1, request_order_[0]);
1450 EXPECT_EQ(&req2, request_order_[1]);
1451 EXPECT_EQ(&req3, request_order_[2]);
1452 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1453}
1454
1455// The requests are not coupled to the jobs. So, the requests should finish in
1456// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:291457TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531458 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571459 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321460 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571461
[email protected]a512f5982009-08-18 16:01:061462 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271463 int rv = InitHandle(req1.handle(), "a", kDefaultPriority, &req1, pool_,
1464 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571465 EXPECT_EQ(ERR_IO_PENDING, rv);
1466
[email protected]a512f5982009-08-18 16:01:061467 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271468 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2, pool_,
1469 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571470 EXPECT_EQ(ERR_IO_PENDING, rv);
1471
1472 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321473 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571474
[email protected]a512f5982009-08-18 16:01:061475 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271476 rv = InitHandle(req3.handle(), "a", kDefaultPriority, &req3, pool_,
1477 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571478 EXPECT_EQ(ERR_IO_PENDING, rv);
1479
1480 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1481 EXPECT_EQ(OK, req2.WaitForResult());
1482 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1483
1484 ASSERT_EQ(3U, request_order_.size());
1485 EXPECT_EQ(&req1, request_order_[0]);
1486 EXPECT_EQ(&req2, request_order_[1]);
1487 EXPECT_EQ(&req3, request_order_[2]);
1488}
1489
[email protected]e6ec67b2010-06-16 00:12:461490TEST_F(ClientSocketPoolBaseTest, LoadState) {
[email protected]211d21722009-07-22 15:48:531491 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571492 connect_job_factory_->set_job_type(
[email protected]b59ff372009-07-15 22:04:321493 TestConnectJob::kMockAdvancingLoadStateJob);
[email protected]5fc08e32009-07-15 17:09:571494
[email protected]a512f5982009-08-18 16:01:061495 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271496 int rv = InitHandle(req1.handle(), "a", kDefaultPriority, &req1, pool_,
1497 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571498 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331499 EXPECT_EQ(LOAD_STATE_IDLE, req1.handle()->GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571500
1501 MessageLoop::current()->RunAllPending();
1502
[email protected]a512f5982009-08-18 16:01:061503 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271504 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2, pool_,
1505 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571506 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]cfa8228c2010-06-17 01:07:561507 EXPECT_NE(LOAD_STATE_IDLE, req1.handle()->GetLoadState());
1508 EXPECT_NE(LOAD_STATE_IDLE, req2.handle()->GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571509}
1510
[email protected]4d3b05d2010-01-27 21:27:291511TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
[email protected]9bf28db2009-08-29 01:35:161512 CreatePoolWithIdleTimeouts(
1513 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1514 base::TimeDelta(), // Time out unused sockets immediately.
1515 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1516
1517 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1518
1519 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
1520
1521 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271522 int rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_, BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:161523 EXPECT_EQ(ERR_IO_PENDING, rv);
1524 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
1525
1526 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271527 rv = InitHandle(req2.handle(), "a", LOWEST, &req2, pool_, BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:161528 EXPECT_EQ(ERR_IO_PENDING, rv);
1529 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req2.handle()));
1530
1531 // Cancel one of the requests. Wait for the other, which will get the first
1532 // job. Release the socket. Run the loop again to make sure the second
1533 // socket is sitting idle and the first one is released (since ReleaseSocket()
1534 // just posts a DoReleaseSocket() task).
1535
1536 req.handle()->Reset();
1537 EXPECT_EQ(OK, req2.WaitForResult());
1538 req2.handle()->Reset();
[email protected]6b175382009-10-13 06:47:471539
1540 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1541 // actually become pending until 2ms after they have been created. In order
1542 // to flush all tasks, we need to wait so that we know there are no
1543 // soon-to-be-pending tasks waiting.
1544 PlatformThread::Sleep(10);
[email protected]9bf28db2009-08-29 01:35:161545 MessageLoop::current()->RunAllPending();
1546
1547 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:041548
[email protected]9bf28db2009-08-29 01:35:161549 // Invoke the idle socket cleanup check. Only one socket should be left, the
1550 // used socket. Request it to make sure that it's used.
1551
1552 pool_->CleanupTimedOutIdleSockets();
[email protected]9e743cd2010-03-16 07:03:531553 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]a796bcec2010-03-22 17:17:261554 rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_, log.bound());
[email protected]9bf28db2009-08-29 01:35:161555 EXPECT_EQ(OK, rv);
1556 EXPECT_TRUE(req.handle()->is_reused());
[email protected]fd4fe0b2010-02-08 23:02:151557 EXPECT_TRUE(LogContainsEntryWithType(
[email protected]d13f51b2010-04-27 23:20:451558 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]9bf28db2009-08-29 01:35:161559}
1560
[email protected]2041cf342010-02-19 03:15:591561// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:161562// because of multiple releasing disconnected sockets.
1563TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
1564 CreatePoolWithIdleTimeouts(
1565 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1566 base::TimeDelta(), // Time out unused sockets immediately.
1567 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1568
1569 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1570
1571 // Startup 4 connect jobs. Two of them will be pending.
1572
1573 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271574 int rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_, BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161575 EXPECT_EQ(OK, rv);
1576
1577 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271578 rv = InitHandle(req2.handle(), "a", LOWEST, &req2, pool_, BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161579 EXPECT_EQ(OK, rv);
1580
1581 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271582 rv = InitHandle(req3.handle(), "a", LOWEST, &req3, pool_, BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161583 EXPECT_EQ(ERR_IO_PENDING, rv);
1584
1585 TestSocketRequest req4(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271586 rv = InitHandle(req4.handle(), "a", LOWEST, &req4, pool_, BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161587 EXPECT_EQ(ERR_IO_PENDING, rv);
1588
1589 // Release two disconnected sockets.
1590
1591 req.handle()->socket()->Disconnect();
1592 req.handle()->Reset();
1593 req2.handle()->socket()->Disconnect();
1594 req2.handle()->Reset();
1595
1596 EXPECT_EQ(OK, req3.WaitForResult());
1597 EXPECT_FALSE(req3.handle()->is_reused());
1598 EXPECT_EQ(OK, req4.WaitForResult());
1599 EXPECT_FALSE(req4.handle()->is_reused());
1600}
1601
[email protected]d7027bb2010-05-10 18:58:541602// Regression test for http://crbug.com/42267.
1603// When DoReleaseSocket() is processed for one socket, it is blocked because the
1604// other stalled groups all have releasing sockets, so no progress can be made.
1605TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
1606 CreatePoolWithIdleTimeouts(
1607 4 /* socket limit */, 4 /* socket limit per group */,
1608 base::TimeDelta(), // Time out unused sockets immediately.
1609 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1610
1611 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1612
1613 // Max out the socket limit with 2 per group.
1614
1615 scoped_ptr<TestSocketRequest> req_a[4];
1616 scoped_ptr<TestSocketRequest> req_b[4];
1617
1618 for (int i = 0; i < 2; ++i) {
1619 req_a[i].reset(new TestSocketRequest(&request_order_, &completion_count_));
1620 req_b[i].reset(new TestSocketRequest(&request_order_, &completion_count_));
1621 EXPECT_EQ(OK,
1622 InitHandle(req_a[i]->handle(), "a", LOWEST, req_a[i].get(), pool_,
1623 BoundNetLog()));
1624 EXPECT_EQ(OK,
1625 InitHandle(req_b[i]->handle(), "b", LOWEST, req_b[i].get(), pool_,
1626 BoundNetLog()));
1627 }
[email protected]b89f7e42010-05-20 20:37:001628
[email protected]d7027bb2010-05-10 18:58:541629 // Make 4 pending requests, 2 per group.
1630
1631 for (int i = 2; i < 4; ++i) {
1632 req_a[i].reset(new TestSocketRequest(&request_order_, &completion_count_));
1633 req_b[i].reset(new TestSocketRequest(&request_order_, &completion_count_));
1634 EXPECT_EQ(ERR_IO_PENDING,
1635 InitHandle(req_a[i]->handle(), "a", LOWEST, req_a[i].get(), pool_,
1636 BoundNetLog()));
1637 EXPECT_EQ(ERR_IO_PENDING,
1638 InitHandle(req_b[i]->handle(), "b", LOWEST, req_b[i].get(), pool_,
1639 BoundNetLog()));
1640 }
1641
1642 // Release b's socket first. The order is important, because in
1643 // DoReleaseSocket(), we'll process b's released socket, and since both b and
1644 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
1645 // first, which has a releasing socket, so it refuses to start up another
1646 // ConnectJob. So, we used to infinite loop on this.
1647 req_b[0]->handle()->socket()->Disconnect();
1648 req_b[0]->handle()->Reset();
1649 req_a[0]->handle()->socket()->Disconnect();
1650 req_a[0]->handle()->Reset();
1651
1652 // Used to get stuck here.
1653 MessageLoop::current()->RunAllPending();
1654
1655 req_b[1]->handle()->socket()->Disconnect();
1656 req_b[1]->handle()->Reset();
1657 req_a[1]->handle()->socket()->Disconnect();
1658 req_a[1]->handle()->Reset();
1659
1660 for (int i = 2; i < 4; ++i) {
1661 EXPECT_EQ(OK, req_b[i]->WaitForResult());
1662 EXPECT_EQ(OK, req_a[i]->WaitForResult());
1663 }
1664}
1665
[email protected]fd4fe0b2010-02-08 23:02:151666TEST_F(ClientSocketPoolBaseTest,
1667 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
1668 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1669
1670 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1671
1672 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1673 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1674 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1675 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1676
1677 EXPECT_EQ(OK, requests_[0]->WaitForResult());
1678 EXPECT_EQ(OK, requests_[1]->WaitForResult());
1679 EXPECT_EQ(2u, completion_count_);
1680
1681 // Releases one connection.
1682 EXPECT_TRUE(ReleaseOneConnection(NO_KEEP_ALIVE));
1683 EXPECT_EQ(OK, requests_[2]->WaitForResult());
1684
1685 EXPECT_TRUE(ReleaseOneConnection(NO_KEEP_ALIVE));
1686 EXPECT_EQ(OK, requests_[3]->WaitForResult());
1687 EXPECT_EQ(4u, completion_count_);
1688
1689 EXPECT_EQ(1, GetOrderOfRequest(1));
1690 EXPECT_EQ(2, GetOrderOfRequest(2));
1691 EXPECT_EQ(3, GetOrderOfRequest(3));
1692 EXPECT_EQ(4, GetOrderOfRequest(4));
1693
1694 // Make sure we test order of all requests made.
1695 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(5));
1696}
1697
[email protected]4f1e4982010-03-02 18:31:041698class TestReleasingSocketRequest : public CallbackRunner< Tuple1<int> > {
1699 public:
1700 explicit TestReleasingSocketRequest(TestClientSocketPool* pool)
1701 : pool_(pool) {}
1702
1703 ClientSocketHandle* handle() { return &handle_; }
1704
1705 int WaitForResult() {
1706 return callback_.WaitForResult();
1707 }
1708
1709 virtual void RunWithParams(const Tuple1<int>& params) {
1710 callback_.RunWithParams(params);
1711 handle_.Reset();
[email protected]a796bcec2010-03-22 17:17:261712 EXPECT_EQ(ERR_IO_PENDING, InitHandle(&handle2_, "a", kDefaultPriority,
[email protected]5a1d7ca2010-04-28 20:12:271713 &callback2_, pool_, BoundNetLog()));
[email protected]4f1e4982010-03-02 18:31:041714 }
1715
1716 private:
1717 TestClientSocketPool* const pool_;
1718 ClientSocketHandle handle_;
1719 ClientSocketHandle handle2_;
1720 TestCompletionCallback callback_;
1721 TestCompletionCallback callback2_;
1722};
1723
[email protected]b6501d3d2010-06-03 23:53:341724// http://crbug.com/44724 regression test.
1725// We start releasing the pool when we flush on network change. When that
1726// happens, the only active references are in the ClientSocketHandles. When a
1727// ConnectJob completes and calls back into the last ClientSocketHandle, that
1728// callback can release the last reference and delete the pool. After the
1729// callback finishes, we go back to the stack frame within the now-deleted pool.
1730// Executing any code that refers to members of the now-deleted pool can cause
1731// crashes.
1732TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
1733 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1734 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1735
1736 ClientSocketHandle handle;
1737 TestCompletionCallback callback;
1738 EXPECT_EQ(ERR_IO_PENDING,
1739 InitHandle(&handle, "a", kDefaultPriority,
1740 &callback, pool_, BoundNetLog()));
1741
1742 // Simulate flushing the pool.
1743 pool_ = NULL;
1744
1745 // We'll call back into this now.
1746 callback.WaitForResult();
1747}
1748
[email protected]a7e38572010-06-07 18:22:241749TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
1750 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1751 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1752
1753 ClientSocketHandle handle;
1754 TestCompletionCallback callback;
1755 EXPECT_EQ(ERR_IO_PENDING,
1756 InitHandle(&handle, "a", kDefaultPriority,
1757 &callback, pool_, BoundNetLog()));
1758 EXPECT_EQ(OK, callback.WaitForResult());
1759 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
1760
1761 pool_->Flush();
1762
1763 handle.Reset();
1764 MessageLoop::current()->RunAllPending();
1765
1766 EXPECT_EQ(ERR_IO_PENDING,
1767 InitHandle(&handle, "a", kDefaultPriority,
1768 &callback, pool_, BoundNetLog()));
1769 EXPECT_EQ(OK, callback.WaitForResult());
1770 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
1771}
1772
[email protected]25eea382010-07-10 23:55:261773// Cancel a pending socket request while we're at max sockets,
1774// and verify that the backup socket firing doesn't cause a crash.
1775TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
1776 // Max 4 sockets globally, max 4 sockets per group.
1777 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1778 pool_->EnableBackupJobs();
1779
1780 // Create the first socket and set to ERR_IO_PENDING. This creates a
1781 // backup job.
1782 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1783 ClientSocketHandle handle;
1784 TestCompletionCallback callback;
1785 EXPECT_EQ(
1786 ERR_IO_PENDING,
1787 InitHandle(
1788 &handle, "bar", kDefaultPriority, &callback, pool_, BoundNetLog()));
1789
1790 // Start (MaxSockets - 1) connected sockets to reach max sockets.
1791 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1792 ClientSocketHandle handles[kDefaultMaxSockets];
1793 for (int i = 1; i < kDefaultMaxSockets; ++i) {
1794 TestCompletionCallback callback;
1795 EXPECT_EQ(OK,
1796 InitHandle(&handles[i], "bar", kDefaultPriority,
1797 &callback, pool_, BoundNetLog()));
1798 }
1799
1800 MessageLoop::current()->RunAllPending();
1801
1802 // Cancel the pending request.
1803 handle.Reset();
1804
1805 // Wait for the backup timer to fire (add some slop to ensure it fires)
1806 PlatformThread::Sleep(ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
1807
1808 MessageLoop::current()->RunAllPending();
1809 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1810}
1811
[email protected]eb5a99382010-07-11 03:18:261812// Test delayed socket binding for the case where we have two connects,
1813// and while one is waiting on a connect, the other frees up.
1814// The socket waiting on a connect should switch immediately to the freed
1815// up socket.
1816TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
1817 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1818 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1819
1820 ClientSocketHandle handle1;
1821 TestCompletionCallback callback;
1822 EXPECT_EQ(ERR_IO_PENDING,
1823 InitHandle(&handle1, "a", kDefaultPriority,
1824 &callback, pool_, BoundNetLog()));
1825 EXPECT_EQ(OK, callback.WaitForResult());
1826
1827 // No idle sockets, no pending jobs.
1828 EXPECT_EQ(0, pool_->IdleSocketCount());
1829 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
1830
1831 // Create a second socket to the same host, but this one will wait.
1832 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1833 ClientSocketHandle handle2;
1834 EXPECT_EQ(ERR_IO_PENDING,
1835 InitHandle(&handle2, "a", kDefaultPriority,
1836 &callback, pool_, BoundNetLog()));
1837 // No idle sockets, and one connecting job.
1838 EXPECT_EQ(0, pool_->IdleSocketCount());
1839 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
1840
1841 // Return the first handle to the pool. This will initiate the delayed
1842 // binding.
1843 handle1.Reset();
1844
1845 MessageLoop::current()->RunAllPending();
1846
1847 // Still no idle sockets, still one pending connect job.
1848 EXPECT_EQ(0, pool_->IdleSocketCount());
1849 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
1850
1851 // The second socket connected, even though it was a Waiting Job.
1852 EXPECT_EQ(OK, callback.WaitForResult());
1853
1854 // And we can see there is still one job waiting.
1855 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
1856
1857 // Finally, signal the waiting Connect.
1858 client_socket_factory_.SignalJobs();
1859 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
1860
1861 MessageLoop::current()->RunAllPending();
1862}
1863
1864// Test delayed socket binding when a group is at capacity and one
1865// of the group's sockets frees up.
1866TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
1867 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1868 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1869
1870 ClientSocketHandle handle1;
1871 TestCompletionCallback callback;
1872 EXPECT_EQ(ERR_IO_PENDING,
1873 InitHandle(&handle1, "a", kDefaultPriority,
1874 &callback, pool_, BoundNetLog()));
1875 EXPECT_EQ(OK, callback.WaitForResult());
1876
1877 // No idle sockets, no pending jobs.
1878 EXPECT_EQ(0, pool_->IdleSocketCount());
1879 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
1880
1881 // Create a second socket to the same host, but this one will wait.
1882 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1883 ClientSocketHandle handle2;
1884 EXPECT_EQ(ERR_IO_PENDING,
1885 InitHandle(&handle2, "a", kDefaultPriority,
1886 &callback, pool_, BoundNetLog()));
1887 // No idle sockets, and one connecting job.
1888 EXPECT_EQ(0, pool_->IdleSocketCount());
1889 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
1890
1891 // Return the first handle to the pool. This will initiate the delayed
1892 // binding.
1893 handle1.Reset();
1894
1895 MessageLoop::current()->RunAllPending();
1896
1897 // Still no idle sockets, still one pending connect job.
1898 EXPECT_EQ(0, pool_->IdleSocketCount());
1899 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
1900
1901 // The second socket connected, even though it was a Waiting Job.
1902 EXPECT_EQ(OK, callback.WaitForResult());
1903
1904 // And we can see there is still one job waiting.
1905 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
1906
1907 // Finally, signal the waiting Connect.
1908 client_socket_factory_.SignalJobs();
1909 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
1910
1911 MessageLoop::current()->RunAllPending();
1912}
1913
1914// Test out the case where we have one socket connected, one
1915// connecting, when the first socket finishes and goes idle.
1916// Although the second connection is pending, th second request
1917// should complete, by taking the first socket's idle socket.
1918TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
1919 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1920 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1921
1922 ClientSocketHandle handle1;
1923 TestCompletionCallback callback;
1924 EXPECT_EQ(ERR_IO_PENDING,
1925 InitHandle(&handle1, "a", kDefaultPriority,
1926 &callback, pool_, BoundNetLog()));
1927 EXPECT_EQ(OK, callback.WaitForResult());
1928
1929 // No idle sockets, no pending jobs.
1930 EXPECT_EQ(0, pool_->IdleSocketCount());
1931 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
1932
1933 // Create a second socket to the same host, but this one will wait.
1934 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1935 ClientSocketHandle handle2;
1936 EXPECT_EQ(ERR_IO_PENDING,
1937 InitHandle(&handle2, "a", kDefaultPriority,
1938 &callback, pool_, BoundNetLog()));
1939 // No idle sockets, and one connecting job.
1940 EXPECT_EQ(0, pool_->IdleSocketCount());
1941 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
1942
1943 // Return the first handle to the pool. This will initiate the delayed
1944 // binding.
1945 handle1.Reset();
1946
1947 MessageLoop::current()->RunAllPending();
1948
1949 // Still no idle sockets, still one pending connect job.
1950 EXPECT_EQ(0, pool_->IdleSocketCount());
1951 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
1952
1953 // The second socket connected, even though it was a Waiting Job.
1954 EXPECT_EQ(OK, callback.WaitForResult());
1955
1956 // And we can see there is still one job waiting.
1957 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
1958
1959 // Finally, signal the waiting Connect.
1960 client_socket_factory_.SignalJobs();
1961 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
1962
1963 MessageLoop::current()->RunAllPending();
1964}
1965
[email protected]f6d1d6eb2009-06-24 20:16:091966} // namespace
1967
1968} // namespace net