blob: 1c0b1cff00b0e70f0f293a0ac984998c25282b50 [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]9e743cd2010-03-16 07:03:5312#include "net/base/net_log.h"
13#include "net/base/net_log_unittest.h"
[email protected]f6d1d6eb2009-06-24 20:16:0914#include "net/base/net_errors.h"
[email protected]ac790b42009-12-02 04:31:3115#include "net/base/request_priority.h"
[email protected]f6d1d6eb2009-06-24 20:16:0916#include "net/base/test_completion_callback.h"
17#include "net/socket/client_socket.h"
18#include "net/socket/client_socket_factory.h"
19#include "net/socket/client_socket_handle.h"
[email protected]75439d3b2009-07-23 22:11:1720#include "net/socket/socket_test_util.h"
[email protected]f6d1d6eb2009-06-24 20:16:0921#include "testing/gtest/include/gtest/gtest.h"
22
23namespace net {
24
25namespace {
26
[email protected]211d21722009-07-22 15:48:5327const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2028const int kDefaultMaxSocketsPerGroup = 2;
[email protected]ac790b42009-12-02 04:31:3129const net::RequestPriority kDefaultPriority = MEDIUM;
[email protected]0b7648c2009-07-06 20:14:0130
[email protected]7fc5b09a2010-02-27 00:07:3831typedef const void* TestSocketParams;
32typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
[email protected]d80a4322009-08-14 07:07:4933
[email protected]f6d1d6eb2009-06-24 20:16:0934class MockClientSocket : public ClientSocket {
35 public:
36 MockClientSocket() : connected_(false) {}
37
[email protected]ab838892009-06-30 18:49:0538 // Socket methods:
39 virtual int Read(
40 IOBuffer* /* buf */, int /* len */, CompletionCallback* /* callback */) {
41 return ERR_UNEXPECTED;
42 }
43
44 virtual int Write(
45 IOBuffer* /* buf */, int /* len */, CompletionCallback* /* callback */) {
46 return ERR_UNEXPECTED;
47 }
[email protected]d3f66572009-09-09 22:38:0448 virtual bool SetReceiveBufferSize(int32 size) { return true; };
49 virtual bool SetSendBufferSize(int32 size) { return true; };
[email protected]ab838892009-06-30 18:49:0550
[email protected]f6d1d6eb2009-06-24 20:16:0951 // ClientSocket methods:
[email protected]ab838892009-06-30 18:49:0552
[email protected]9e743cd2010-03-16 07:03:5353 virtual int Connect(CompletionCallback* callback, const BoundNetLog& net_log) {
[email protected]f6d1d6eb2009-06-24 20:16:0954 connected_ = true;
55 return OK;
56 }
[email protected]f6d1d6eb2009-06-24 20:16:0957
[email protected]ab838892009-06-30 18:49:0558 virtual void Disconnect() { connected_ = false; }
59 virtual bool IsConnected() const { return connected_; }
60 virtual bool IsConnectedAndIdle() const { return connected_; }
[email protected]0b7648c2009-07-06 20:14:0161
[email protected]ac9eec62010-02-20 18:50:3862 virtual int GetPeerAddress(AddressList* /* address */) const {
[email protected]9f864b32010-01-20 15:01:1663 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:0964 }
[email protected]f6d1d6eb2009-06-24 20:16:0965
66 private:
67 bool connected_;
[email protected]f6d1d6eb2009-06-24 20:16:0968
[email protected]ab838892009-06-30 18:49:0569 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:0970};
71
[email protected]5fc08e32009-07-15 17:09:5772class TestConnectJob;
73
[email protected]f6d1d6eb2009-06-24 20:16:0974class MockClientSocketFactory : public ClientSocketFactory {
75 public:
[email protected]ab838892009-06-30 18:49:0576 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:0977
78 virtual ClientSocket* CreateTCPClientSocket(const AddressList& addresses) {
79 allocation_count_++;
[email protected]ab838892009-06-30 18:49:0580 return NULL;
[email protected]f6d1d6eb2009-06-24 20:16:0981 }
82
83 virtual SSLClientSocket* CreateSSLClientSocket(
84 ClientSocket* transport_socket,
85 const std::string& hostname,
86 const SSLConfig& ssl_config) {
87 NOTIMPLEMENTED();
88 return NULL;
89 }
90
[email protected]5fc08e32009-07-15 17:09:5791 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
92 void SignalJobs();
93
[email protected]f6d1d6eb2009-06-24 20:16:0994 int allocation_count() const { return allocation_count_; }
95
[email protected]f6d1d6eb2009-06-24 20:16:0996 private:
97 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:5798 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:0999};
100
[email protected]ab838892009-06-30 18:49:05101class TestConnectJob : public ConnectJob {
102 public:
103 enum JobType {
104 kMockJob,
105 kMockFailingJob,
106 kMockPendingJob,
107 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57108 kMockWaitingJob,
109 kMockAdvancingLoadStateJob,
[email protected]ab838892009-06-30 18:49:05110 };
111
112 TestConnectJob(JobType job_type,
113 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49114 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34115 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05116 ConnectJob::Delegate* delegate,
[email protected]fd7b7c92009-08-20 19:38:30117 MockClientSocketFactory* client_socket_factory,
[email protected]9e743cd2010-03-16 07:03:53118 const BoundNetLog& net_log)
119 : ConnectJob(group_name, timeout_duration, delegate, net_log),
[email protected]2ab05b52009-07-01 23:57:58120 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05121 client_socket_factory_(client_socket_factory),
[email protected]46451352009-09-01 14:54:21122 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
123 load_state_(LOAD_STATE_IDLE) {}
[email protected]ab838892009-06-30 18:49:05124
[email protected]974ebd62009-08-03 23:14:34125 void Signal() {
126 DoConnect(waiting_success_, true /* async */);
127 }
128
[email protected]46451352009-09-01 14:54:21129 virtual LoadState GetLoadState() const { return load_state_; }
130
[email protected]974ebd62009-08-03 23:14:34131 private:
[email protected]ab838892009-06-30 18:49:05132 // ConnectJob methods:
133
[email protected]974ebd62009-08-03 23:14:34134 virtual int ConnectInternal() {
[email protected]ab838892009-06-30 18:49:05135 AddressList ignored;
136 client_socket_factory_->CreateTCPClientSocket(ignored);
[email protected]6e713f02009-08-06 02:56:40137 set_socket(new MockClientSocket());
[email protected]ab838892009-06-30 18:49:05138 switch (job_type_) {
139 case kMockJob:
140 return DoConnect(true /* successful */, false /* sync */);
141 case kMockFailingJob:
142 return DoConnect(false /* error */, false /* sync */);
143 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57144 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47145
146 // Depending on execution timings, posting a delayed task can result
147 // in the task getting executed the at the earliest possible
148 // opportunity or only after returning once from the message loop and
149 // then a second call into the message loop. In order to make behavior
150 // more deterministic, we change the default delay to 2ms. This should
151 // always require us to wait for the second call into the message loop.
152 //
153 // N.B. The correct fix for this and similar timing problems is to
154 // abstract time for the purpose of unittests. Unfortunately, we have
155 // a lot of third-party components that directly call the various
156 // time functions, so this change would be rather invasive.
157 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05158 FROM_HERE,
159 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47160 &TestConnectJob::DoConnect,
161 true /* successful */,
162 true /* async */),
163 2);
[email protected]ab838892009-06-30 18:49:05164 return ERR_IO_PENDING;
165 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57166 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47167 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05168 FROM_HERE,
169 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47170 &TestConnectJob::DoConnect,
171 false /* error */,
172 true /* async */),
173 2);
[email protected]ab838892009-06-30 18:49:05174 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57175 case kMockWaitingJob:
176 client_socket_factory_->WaitForSignal(this);
177 waiting_success_ = true;
178 return ERR_IO_PENDING;
179 case kMockAdvancingLoadStateJob:
[email protected]6b175382009-10-13 06:47:47180 MessageLoop::current()->PostDelayedTask(
[email protected]5fc08e32009-07-15 17:09:57181 FROM_HERE,
182 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47183 &TestConnectJob::AdvanceLoadState, load_state_),
184 2);
[email protected]5fc08e32009-07-15 17:09:57185 return ERR_IO_PENDING;
[email protected]ab838892009-06-30 18:49:05186 default:
187 NOTREACHED();
[email protected]6e713f02009-08-06 02:56:40188 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05189 return ERR_FAILED;
190 }
191 }
192
[email protected]46451352009-09-01 14:54:21193 void set_load_state(LoadState load_state) { load_state_ = load_state; }
194
[email protected]ab838892009-06-30 18:49:05195 int DoConnect(bool succeed, bool was_async) {
196 int result = ERR_CONNECTION_FAILED;
[email protected]ab838892009-06-30 18:49:05197 if (succeed) {
198 result = OK;
[email protected]5a05c47a2009-11-02 23:25:19199 socket()->Connect(NULL, NULL);
[email protected]6e713f02009-08-06 02:56:40200 } else {
201 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05202 }
[email protected]2ab05b52009-07-01 23:57:58203
204 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30205 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05206 return result;
207 }
208
[email protected]5fc08e32009-07-15 17:09:57209 void AdvanceLoadState(LoadState state) {
210 int tmp = state;
211 tmp++;
212 state = static_cast<LoadState>(tmp);
213 set_load_state(state);
214 // Post a delayed task so RunAllPending() won't run it.
215 MessageLoop::current()->PostDelayedTask(
216 FROM_HERE,
217 method_factory_.NewRunnableMethod(&TestConnectJob::AdvanceLoadState,
218 state),
219 1 /* 1ms delay */);
220 }
221
222 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05223 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57224 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05225 ScopedRunnableMethodFactory<TestConnectJob> method_factory_;
[email protected]46451352009-09-01 14:54:21226 LoadState load_state_;
[email protected]ab838892009-06-30 18:49:05227
228 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
229};
230
[email protected]d80a4322009-08-14 07:07:49231class TestConnectJobFactory
232 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05233 public:
[email protected]5fc08e32009-07-15 17:09:57234 explicit TestConnectJobFactory(MockClientSocketFactory* client_socket_factory)
[email protected]ab838892009-06-30 18:49:05235 : job_type_(TestConnectJob::kMockJob),
236 client_socket_factory_(client_socket_factory) {}
237
238 virtual ~TestConnectJobFactory() {}
239
240 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
241
[email protected]974ebd62009-08-03 23:14:34242 void set_timeout_duration(base::TimeDelta timeout_duration) {
243 timeout_duration_ = timeout_duration;
244 }
245
[email protected]ab838892009-06-30 18:49:05246 // ConnectJobFactory methods:
247
248 virtual ConnectJob* NewConnectJob(
249 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49250 const TestClientSocketPoolBase::Request& request,
[email protected]fd7b7c92009-08-20 19:38:30251 ConnectJob::Delegate* delegate,
[email protected]9e743cd2010-03-16 07:03:53252 const BoundNetLog& net_log) const {
[email protected]ab838892009-06-30 18:49:05253 return new TestConnectJob(job_type_,
254 group_name,
255 request,
[email protected]974ebd62009-08-03 23:14:34256 timeout_duration_,
[email protected]ab838892009-06-30 18:49:05257 delegate,
[email protected]fd7b7c92009-08-20 19:38:30258 client_socket_factory_,
[email protected]9e743cd2010-03-16 07:03:53259 net_log);
[email protected]ab838892009-06-30 18:49:05260 }
261
262 private:
263 TestConnectJob::JobType job_type_;
[email protected]974ebd62009-08-03 23:14:34264 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57265 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05266
267 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
268};
269
270class TestClientSocketPool : public ClientSocketPool {
271 public:
272 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53273 int max_sockets,
[email protected]ab838892009-06-30 18:49:05274 int max_sockets_per_group,
[email protected]9bf28db2009-08-29 01:35:16275 base::TimeDelta unused_idle_socket_timeout,
276 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49277 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
[email protected]9bf28db2009-08-29 01:35:16278 : base_(max_sockets, max_sockets_per_group,
279 unused_idle_socket_timeout, used_idle_socket_timeout,
[email protected]100d5fb92009-12-21 21:08:35280 connect_job_factory, NULL) {}
[email protected]ab838892009-06-30 18:49:05281
282 virtual int RequestSocket(
283 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49284 const void* params,
[email protected]ac790b42009-12-02 04:31:31285 net::RequestPriority priority,
[email protected]ab838892009-06-30 18:49:05286 ClientSocketHandle* handle,
[email protected]684970b2009-08-14 04:54:46287 CompletionCallback* callback,
[email protected]9e743cd2010-03-16 07:03:53288 const BoundNetLog& net_log) {
[email protected]d80a4322009-08-14 07:07:49289 return base_.RequestSocket(
[email protected]9e743cd2010-03-16 07:03:53290 group_name, params, priority, handle, callback, net_log);
[email protected]ab838892009-06-30 18:49:05291 }
292
293 virtual void CancelRequest(
294 const std::string& group_name,
295 const ClientSocketHandle* handle) {
[email protected]d80a4322009-08-14 07:07:49296 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05297 }
298
299 virtual void ReleaseSocket(
300 const std::string& group_name,
301 ClientSocket* socket) {
[email protected]d80a4322009-08-14 07:07:49302 base_.ReleaseSocket(group_name, socket);
[email protected]ab838892009-06-30 18:49:05303 }
304
305 virtual void CloseIdleSockets() {
[email protected]d80a4322009-08-14 07:07:49306 base_.CloseIdleSockets();
[email protected]ab838892009-06-30 18:49:05307 }
308
[email protected]d80a4322009-08-14 07:07:49309 virtual int IdleSocketCount() const { return base_.idle_socket_count(); }
[email protected]ab838892009-06-30 18:49:05310
311 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49312 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05313 }
314
315 virtual LoadState GetLoadState(const std::string& group_name,
316 const ClientSocketHandle* handle) const {
[email protected]d80a4322009-08-14 07:07:49317 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05318 }
319
[email protected]d80a4322009-08-14 07:07:49320 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20321
[email protected]974ebd62009-08-03 23:14:34322 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49323 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34324 }
325
[email protected]9bf28db2009-08-29 01:35:16326 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
327
[email protected]ab838892009-06-30 18:49:05328 private:
[email protected]5389bc72009-11-05 23:34:24329 ~TestClientSocketPool() {}
330
[email protected]d80a4322009-08-14 07:07:49331 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05332
333 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
334};
335
[email protected]a937a06d2009-08-19 21:19:24336} // namespace
337
[email protected]7fc5b09a2010-02-27 00:07:38338REGISTER_SOCKET_PARAMS_FOR_POOL(TestClientSocketPool, TestSocketParams);
[email protected]a937a06d2009-08-19 21:19:24339
340namespace {
341
[email protected]5fc08e32009-07-15 17:09:57342void MockClientSocketFactory::SignalJobs() {
343 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
344 it != waiting_jobs_.end(); ++it) {
345 (*it)->Signal();
346 }
347 waiting_jobs_.clear();
348}
349
[email protected]974ebd62009-08-03 23:14:34350class TestConnectJobDelegate : public ConnectJob::Delegate {
351 public:
352 TestConnectJobDelegate()
353 : have_result_(false), waiting_for_result_(false), result_(OK) {}
354 virtual ~TestConnectJobDelegate() {}
355
356 virtual void OnConnectJobComplete(int result, ConnectJob* job) {
357 result_ = result;
[email protected]6e713f02009-08-06 02:56:40358 scoped_ptr<ClientSocket> socket(job->ReleaseSocket());
[email protected]9b6fee12009-09-29 18:13:07359 // socket.get() should be NULL iff result != OK
360 EXPECT_EQ(socket.get() == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34361 delete job;
362 have_result_ = true;
363 if (waiting_for_result_)
364 MessageLoop::current()->Quit();
365 }
366
367 int WaitForResult() {
368 DCHECK(!waiting_for_result_);
369 while (!have_result_) {
370 waiting_for_result_ = true;
371 MessageLoop::current()->Run();
372 waiting_for_result_ = false;
373 }
374 have_result_ = false; // auto-reset for next callback
375 return result_;
376 }
377
378 private:
379 bool have_result_;
380 bool waiting_for_result_;
381 int result_;
382};
383
[email protected]75439d3b2009-07-23 22:11:17384class ClientSocketPoolBaseTest : public ClientSocketPoolTest {
[email protected]f6d1d6eb2009-06-24 20:16:09385 protected:
[email protected]17a0c6c2009-08-04 00:07:04386 ClientSocketPoolBaseTest() {}
[email protected]c9d6a1d2009-07-14 16:15:20387
[email protected]211d21722009-07-22 15:48:53388 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16389 CreatePoolWithIdleTimeouts(
390 max_sockets,
391 max_sockets_per_group,
392 base::TimeDelta::FromSeconds(kUnusedIdleSocketTimeout),
393 base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout));
394 }
395
396 void CreatePoolWithIdleTimeouts(
397 int max_sockets, int max_sockets_per_group,
398 base::TimeDelta unused_idle_socket_timeout,
399 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20400 DCHECK(!pool_.get());
[email protected]17a0c6c2009-08-04 00:07:04401 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_);
[email protected]211d21722009-07-22 15:48:53402 pool_ = new TestClientSocketPool(max_sockets,
403 max_sockets_per_group,
[email protected]9bf28db2009-08-29 01:35:16404 unused_idle_socket_timeout,
405 used_idle_socket_timeout,
[email protected]c9d6a1d2009-07-14 16:15:20406 connect_job_factory_);
407 }
[email protected]f6d1d6eb2009-06-24 20:16:09408
[email protected]ac790b42009-12-02 04:31:31409 int StartRequest(const std::string& group_name,
410 net::RequestPriority priority) {
[email protected]7fc5b09a2010-02-27 00:07:38411 return StartRequestUsingPool<TestClientSocketPool, TestSocketParams>(
[email protected]a937a06d2009-08-19 21:19:24412 pool_.get(), group_name, priority, NULL);
[email protected]f6d1d6eb2009-06-24 20:16:09413 }
414
415 virtual void TearDown() {
[email protected]6b175382009-10-13 06:47:47416 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
417 // actually become pending until 2ms after they have been created. In order
418 // to flush all tasks, we need to wait so that we know there are no
419 // soon-to-be-pending tasks waiting.
420 PlatformThread::Sleep(10);
421 MessageLoop::current()->RunAllPending();
422
[email protected]211d21722009-07-22 15:48:53423 // Need to delete |pool_| before we turn late binding back off. We also need
424 // to delete |requests_| because the pool is reference counted and requests
425 // keep reference to it.
426 // TODO(willchan): Remove this part when late binding becomes the default.
[email protected]5fc08e32009-07-15 17:09:57427 pool_ = NULL;
[email protected]211d21722009-07-22 15:48:53428 requests_.reset();
429
[email protected]75439d3b2009-07-23 22:11:17430 ClientSocketPoolTest::TearDown();
[email protected]f6d1d6eb2009-06-24 20:16:09431 }
432
[email protected]f6d1d6eb2009-06-24 20:16:09433 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04434 TestConnectJobFactory* connect_job_factory_;
[email protected]c9d6a1d2009-07-14 16:15:20435 scoped_refptr<TestClientSocketPool> pool_;
[email protected]f6d1d6eb2009-06-24 20:16:09436};
437
[email protected]a937a06d2009-08-19 21:19:24438// Helper function which explicitly specifies the template parameters, since
439// the compiler will infer (in this case, incorrectly) that NULL is of type int.
440int InitHandle(ClientSocketHandle* handle,
441 const std::string& group_name,
[email protected]ac790b42009-12-02 04:31:31442 net::RequestPriority priority,
[email protected]a937a06d2009-08-19 21:19:24443 CompletionCallback* callback,
444 TestClientSocketPool* pool,
[email protected]9e743cd2010-03-16 07:03:53445 const BoundNetLog& net_log) {
[email protected]7fc5b09a2010-02-27 00:07:38446 return handle->Init<TestSocketParams, TestClientSocketPool>(
[email protected]9e743cd2010-03-16 07:03:53447 group_name, NULL, priority, callback, pool, net_log);
[email protected]a937a06d2009-08-19 21:19:24448}
449
[email protected]974ebd62009-08-03 23:14:34450// Even though a timeout is specified, it doesn't time out on a synchronous
451// completion.
452TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
453 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06454 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49455 TestClientSocketPoolBase::Request request(
456 &ignored, NULL, kDefaultPriority, NULL, NULL);
[email protected]974ebd62009-08-03 23:14:34457 scoped_ptr<TestConnectJob> job(
458 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:12459 "a",
[email protected]974ebd62009-08-03 23:14:34460 request,
461 base::TimeDelta::FromMicroseconds(1),
462 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30463 &client_socket_factory_,
464 NULL));
[email protected]974ebd62009-08-03 23:14:34465 EXPECT_EQ(OK, job->Connect());
466}
467
468TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
469 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06470 ClientSocketHandle ignored;
[email protected]9e743cd2010-03-16 07:03:53471 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
472
[email protected]d80a4322009-08-14 07:07:49473 TestClientSocketPoolBase::Request request(
474 &ignored, NULL, kDefaultPriority, NULL, NULL);
[email protected]974ebd62009-08-03 23:14:34475 // Deleted by TestConnectJobDelegate.
476 TestConnectJob* job =
477 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12478 "a",
[email protected]974ebd62009-08-03 23:14:34479 request,
480 base::TimeDelta::FromMicroseconds(1),
481 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30482 &client_socket_factory_,
[email protected]9e743cd2010-03-16 07:03:53483 log.bound());
[email protected]974ebd62009-08-03 23:14:34484 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
485 PlatformThread::Sleep(1);
486 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30487
[email protected]9e743cd2010-03-16 07:03:53488 EXPECT_EQ(3u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:46489 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:53490 log.entries(), 0, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]e9002a92010-01-29 07:10:46491 EXPECT_TRUE(LogContainsEvent(
[email protected]9e743cd2010-03-16 07:03:53492 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
493 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:46494 EXPECT_TRUE(LogContainsEndEvent(
[email protected]9e743cd2010-03-16 07:03:53495 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34496}
497
[email protected]5fc08e32009-07-15 17:09:57498TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53499 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20500
[email protected]f6d1d6eb2009-06-24 20:16:09501 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06502 ClientSocketHandle handle;
[email protected]9e743cd2010-03-16 07:03:53503 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
504
[email protected]a937a06d2009-08-19 21:19:24505 EXPECT_EQ(OK, InitHandle(&handle, "a", kDefaultPriority,
[email protected]9e743cd2010-03-16 07:03:53506 &callback, pool_.get(), log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09507 EXPECT_TRUE(handle.is_initialized());
508 EXPECT_TRUE(handle.socket());
[email protected]f6d1d6eb2009-06-24 20:16:09509 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:30510
[email protected]9e743cd2010-03-16 07:03:53511 EXPECT_EQ(5u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:46512 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:53513 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
514 EXPECT_TRUE(LogContainsBeginEvent(
515 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]e9002a92010-01-29 07:10:46516 EXPECT_TRUE(LogContainsEndEvent(
[email protected]9e743cd2010-03-16 07:03:53517 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
518 EXPECT_TRUE(LogContainsEvent(
519 log.entries(), 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_ID,
520 NetLog::PHASE_NONE));
521 EXPECT_TRUE(LogContainsEndEvent(
522 log.entries(), 4, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09523}
524
[email protected]ab838892009-06-30 18:49:05525TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53526 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20527
[email protected]ab838892009-06-30 18:49:05528 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]9e743cd2010-03-16 07:03:53529 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
530
[email protected]a512f5982009-08-18 16:01:06531 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]3ae82302009-06-26 06:01:21532 EXPECT_EQ(ERR_CONNECTION_FAILED,
[email protected]a937a06d2009-08-19 21:19:24533 InitHandle(req.handle(), "a", kDefaultPriority, &req,
[email protected]9e743cd2010-03-16 07:03:53534 pool_.get(), log.bound()));
[email protected]fd7b7c92009-08-20 19:38:30535
[email protected]9e743cd2010-03-16 07:03:53536 EXPECT_EQ(5u, log.entries().size());
537 EXPECT_TRUE(LogContainsBeginEvent(log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]e9002a92010-01-29 07:10:46538 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:53539 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]e9002a92010-01-29 07:10:46540 EXPECT_TRUE(LogContainsEndEvent(
[email protected]9e743cd2010-03-16 07:03:53541 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
542 EXPECT_TRUE(LogContainsEndEvent(log.entries(), 4, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09543}
544
[email protected]211d21722009-07-22 15:48:53545TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
546 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
547
[email protected]9e743cd2010-03-16 07:03:53548 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30549
[email protected]211d21722009-07-22 15:48:53550 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
551 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
552 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
553 EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
554
555 EXPECT_EQ(static_cast<int>(requests_.size()),
556 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17557 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53558
559 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
560 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
561 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
562
563 ReleaseAllConnections(KEEP_ALIVE);
564
565 EXPECT_EQ(static_cast<int>(requests_.size()),
566 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17567 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53568
569 EXPECT_EQ(1, GetOrderOfRequest(1));
570 EXPECT_EQ(2, GetOrderOfRequest(2));
571 EXPECT_EQ(3, GetOrderOfRequest(3));
572 EXPECT_EQ(4, GetOrderOfRequest(4));
573 EXPECT_EQ(5, GetOrderOfRequest(5));
574 EXPECT_EQ(6, GetOrderOfRequest(6));
575 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17576
577 // Make sure we test order of all requests made.
578 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53579}
580
581TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
582 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
583
[email protected]9e743cd2010-03-16 07:03:53584 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30585
[email protected]211d21722009-07-22 15:48:53586 // Reach all limits: max total sockets, and max sockets per group.
587 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
588 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
589 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
590 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
591
592 EXPECT_EQ(static_cast<int>(requests_.size()),
593 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17594 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53595
596 // Now create a new group and verify that we don't starve it.
597 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
598
599 ReleaseAllConnections(KEEP_ALIVE);
600
601 EXPECT_EQ(static_cast<int>(requests_.size()),
602 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17603 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53604
605 EXPECT_EQ(1, GetOrderOfRequest(1));
606 EXPECT_EQ(2, GetOrderOfRequest(2));
607 EXPECT_EQ(3, GetOrderOfRequest(3));
608 EXPECT_EQ(4, GetOrderOfRequest(4));
609 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17610
611 // Make sure we test order of all requests made.
612 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53613}
614
615TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
616 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
617
[email protected]ac790b42009-12-02 04:31:31618 EXPECT_EQ(OK, StartRequest("b", LOWEST));
619 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
620 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
621 EXPECT_EQ(OK, StartRequest("a", LOWEST));
[email protected]211d21722009-07-22 15:48:53622
623 EXPECT_EQ(static_cast<int>(requests_.size()),
624 client_socket_factory_.allocation_count());
625
[email protected]ac790b42009-12-02 04:31:31626 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
627 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
628 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53629
630 ReleaseAllConnections(KEEP_ALIVE);
631
632 // We're re-using one socket for group "a", and one for "b".
633 EXPECT_EQ(static_cast<int>(requests_.size()) - 2,
634 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17635 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53636
637 // First 4 requests don't have to wait, and finish in order.
638 EXPECT_EQ(1, GetOrderOfRequest(1));
639 EXPECT_EQ(2, GetOrderOfRequest(2));
640 EXPECT_EQ(3, GetOrderOfRequest(3));
641 EXPECT_EQ(4, GetOrderOfRequest(4));
642
[email protected]ac790b42009-12-02 04:31:31643 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
644 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53645 EXPECT_EQ(7, GetOrderOfRequest(5));
646 EXPECT_EQ(6, GetOrderOfRequest(6));
647 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17648
649 // Make sure we test order of all requests made.
650 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53651}
652
653TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
654 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
655
[email protected]ac790b42009-12-02 04:31:31656 EXPECT_EQ(OK, StartRequest("a", LOWEST));
657 EXPECT_EQ(OK, StartRequest("a", LOW));
658 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
659 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
[email protected]211d21722009-07-22 15:48:53660
661 EXPECT_EQ(static_cast<int>(requests_.size()),
662 client_socket_factory_.allocation_count());
663
[email protected]ac790b42009-12-02 04:31:31664 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
665 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
666 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53667
668 ReleaseAllConnections(KEEP_ALIVE);
669
670 // We're re-using one socket for group "a", and one for "b".
671 EXPECT_EQ(static_cast<int>(requests_.size()) - 2,
672 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17673 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53674
675 // First 4 requests don't have to wait, and finish in order.
676 EXPECT_EQ(1, GetOrderOfRequest(1));
677 EXPECT_EQ(2, GetOrderOfRequest(2));
678 EXPECT_EQ(3, GetOrderOfRequest(3));
679 EXPECT_EQ(4, GetOrderOfRequest(4));
680
681 // Request ("b", 7) has the highest priority, but we can't make new socket for
682 // group "b", because it has reached the per-group limit. Then we make
683 // socket for ("c", 6), because it has higher priority than ("a", 4),
684 // and we still can't make a socket for group "b".
685 EXPECT_EQ(5, GetOrderOfRequest(5));
686 EXPECT_EQ(6, GetOrderOfRequest(6));
687 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17688
689 // Make sure we test order of all requests made.
690 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53691}
692
693// Make sure that we count connecting sockets against the total limit.
694TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
695 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
696
697 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
698 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
699 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
700
701 // Create one asynchronous request.
702 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
703 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
704
[email protected]6b175382009-10-13 06:47:47705 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
706 // actually become pending until 2ms after they have been created. In order
707 // to flush all tasks, we need to wait so that we know there are no
708 // soon-to-be-pending tasks waiting.
709 PlatformThread::Sleep(10);
710 MessageLoop::current()->RunAllPending();
711
[email protected]211d21722009-07-22 15:48:53712 // The next synchronous request should wait for its turn.
713 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
714 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
715
716 ReleaseAllConnections(KEEP_ALIVE);
717
718 EXPECT_EQ(static_cast<int>(requests_.size()),
719 client_socket_factory_.allocation_count());
720
721 EXPECT_EQ(1, GetOrderOfRequest(1));
722 EXPECT_EQ(2, GetOrderOfRequest(2));
723 EXPECT_EQ(3, GetOrderOfRequest(3));
724 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:17725 EXPECT_EQ(5, GetOrderOfRequest(5));
726
727 // Make sure we test order of all requests made.
728 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53729}
730
731// Inside ClientSocketPoolBase we have a may_have_stalled_group flag,
732// which tells it to use more expensive, but accurate, group selection
733// algorithm. Make sure it doesn't get stuck in the "on" state.
734TEST_F(ClientSocketPoolBaseTest, MayHaveStalledGroupReset) {
735 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
736
737 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
738
739 // Reach group socket limit.
740 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
741 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
742 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
743
744 // Reach total limit, but don't request more sockets.
745 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
746 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
747 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
748
749 // Request one more socket while we are at the maximum sockets limit.
750 // This should flip the may_have_stalled_group flag.
751 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
752 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
753
754 // After releasing first connection for "a", we're still at the
755 // maximum sockets limit, but every group's pending queue is empty,
756 // so we reset the flag.
757 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
758 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
759
760 // Requesting additional socket while at the total limit should
761 // flip the flag back to "on".
762 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
763 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
764
765 // We'll request one more socket to verify that we don't reset the flag
766 // too eagerly.
767 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
768 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
769
770 // We're at the maximum socket limit, and still have one request pending
771 // for "d". Flag should be "on".
772 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
773 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
774
775 // Now every group's pending queue should be empty again.
776 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
777 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
778
779 ReleaseAllConnections(KEEP_ALIVE);
780 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
781}
782
[email protected]ab838892009-06-30 18:49:05783TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:53784 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09785
[email protected]c9d6a1d2009-07-14 16:15:20786 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
787 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:31788 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
789 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
790 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
791 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
792 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:09793
[email protected]c9d6a1d2009-07-14 16:15:20794 ReleaseAllConnections(KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09795
[email protected]c9d6a1d2009-07-14 16:15:20796 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
797 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17798 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09799
[email protected]c9d6a1d2009-07-14 16:15:20800 EXPECT_EQ(1, GetOrderOfRequest(1));
801 EXPECT_EQ(2, GetOrderOfRequest(2));
802 EXPECT_EQ(6, GetOrderOfRequest(3));
803 EXPECT_EQ(4, GetOrderOfRequest(4));
804 EXPECT_EQ(3, GetOrderOfRequest(5));
805 EXPECT_EQ(5, GetOrderOfRequest(6));
806 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17807
808 // Make sure we test order of all requests made.
809 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:09810}
811
[email protected]ab838892009-06-30 18:49:05812TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:53813 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09814
[email protected]c9d6a1d2009-07-14 16:15:20815 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
816 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:31817 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
818 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
819 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
820 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
821 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:09822
[email protected]c9d6a1d2009-07-14 16:15:20823 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09824
[email protected]c9d6a1d2009-07-14 16:15:20825 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i)
826 EXPECT_EQ(OK, requests_[i]->WaitForResult());
827
828 EXPECT_EQ(static_cast<int>(requests_.size()),
829 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17830 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09831}
832
833// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:05834// The pending connect job will be cancelled and should not call back into
835// ClientSocketPoolBase.
836TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:53837 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20838
[email protected]ab838892009-06-30 18:49:05839 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:06840 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]ab838892009-06-30 18:49:05841 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:24842 InitHandle(req.handle(), "a", kDefaultPriority, &req,
843 pool_.get(), NULL));
[email protected]a6c59f62009-07-29 16:33:33844 req.handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:09845}
846
[email protected]ab838892009-06-30 18:49:05847TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:53848 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20849
[email protected]ab838892009-06-30 18:49:05850 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:06851 ClientSocketHandle handle;
[email protected]f6d1d6eb2009-06-24 20:16:09852 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06853 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09854
[email protected]ab838892009-06-30 18:49:05855 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:24856 InitHandle(&handle, "a", kDefaultPriority, &callback,
857 pool_.get(), NULL));
[email protected]f6d1d6eb2009-06-24 20:16:09858
859 handle.Reset();
860
861 TestCompletionCallback callback2;
[email protected]ab838892009-06-30 18:49:05862 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:24863 InitHandle(&handle, "a", kDefaultPriority, &callback2,
864 pool_.get(), NULL));
[email protected]f6d1d6eb2009-06-24 20:16:09865
866 EXPECT_EQ(OK, callback2.WaitForResult());
867 EXPECT_FALSE(callback.have_result());
868
869 handle.Reset();
870}
871
[email protected]ab838892009-06-30 18:49:05872TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:53873 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09874
[email protected]c9d6a1d2009-07-14 16:15:20875 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
876 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:31877 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
878 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
879 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
880 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
881 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:09882
883 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:20884 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]a6c59f62009-07-29 16:33:33885 EXPECT_FALSE(requests_[index_to_cancel]->handle()->is_initialized());
886 requests_[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:09887
[email protected]c9d6a1d2009-07-14 16:15:20888 ReleaseAllConnections(KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09889
[email protected]c9d6a1d2009-07-14 16:15:20890 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
891 client_socket_factory_.allocation_count());
892 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup - 1,
[email protected]75439d3b2009-07-23 22:11:17893 completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09894
[email protected]c9d6a1d2009-07-14 16:15:20895 EXPECT_EQ(1, GetOrderOfRequest(1));
896 EXPECT_EQ(2, GetOrderOfRequest(2));
897 EXPECT_EQ(5, GetOrderOfRequest(3));
898 EXPECT_EQ(3, GetOrderOfRequest(4));
899 EXPECT_EQ(kRequestNotFound, GetOrderOfRequest(5)); // Canceled request.
900 EXPECT_EQ(4, GetOrderOfRequest(6));
901 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17902
903 // Make sure we test order of all requests made.
904 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:09905}
906
907class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
908 public:
[email protected]2ab05b52009-07-01 23:57:58909 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:24910 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:58911 TestConnectJobFactory* test_connect_job_factory,
912 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:09913 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:06914 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:58915 within_callback_(false),
916 test_connect_job_factory_(test_connect_job_factory),
917 next_job_type_(next_job_type) {}
[email protected]f6d1d6eb2009-06-24 20:16:09918
919 virtual void RunWithParams(const Tuple1<int>& params) {
920 callback_.RunWithParams(params);
921 ASSERT_EQ(OK, params.a);
922
923 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:58924 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]5edbf8d2010-01-13 18:44:11925
926 // Don't allow reuse of the socket. Disconnect it and then release it and
927 // run through the MessageLoop once to get it completely released.
928 handle_->socket()->Disconnect();
[email protected]f6d1d6eb2009-06-24 20:16:09929 handle_->Reset();
[email protected]5edbf8d2010-01-13 18:44:11930 {
931 MessageLoop::ScopedNestableTaskAllower nestable(
932 MessageLoop::current());
933 MessageLoop::current()->RunAllPending();
934 }
[email protected]f6d1d6eb2009-06-24 20:16:09935 within_callback_ = true;
[email protected]6b175382009-10-13 06:47:47936 TestCompletionCallback next_job_callback;
[email protected]a937a06d2009-08-19 21:19:24937 int rv = InitHandle(
[email protected]6b175382009-10-13 06:47:47938 handle_, "a", kDefaultPriority, &next_job_callback, pool_.get(),
939 NULL);
[email protected]2ab05b52009-07-01 23:57:58940 switch (next_job_type_) {
941 case TestConnectJob::kMockJob:
942 EXPECT_EQ(OK, rv);
943 break;
944 case TestConnectJob::kMockPendingJob:
945 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:47946
947 // For pending jobs, wait for new socket to be created. This makes
948 // sure there are no more pending operations nor any unclosed sockets
949 // when the test finishes.
950 // We need to give it a little bit of time to run, so that all the
951 // operations that happen on timers (e.g. cleanup of idle
952 // connections) can execute.
[email protected]5edbf8d2010-01-13 18:44:11953 {
954 MessageLoop::ScopedNestableTaskAllower nestable(
955 MessageLoop::current());
956 PlatformThread::Sleep(10);
957 EXPECT_EQ(OK, next_job_callback.WaitForResult());
958 }
[email protected]2ab05b52009-07-01 23:57:58959 break;
960 default:
961 FAIL() << "Unexpected job type: " << next_job_type_;
962 break;
963 }
[email protected]f6d1d6eb2009-06-24 20:16:09964 }
965 }
966
967 int WaitForResult() {
968 return callback_.WaitForResult();
969 }
970
971 private:
972 ClientSocketHandle* const handle_;
[email protected]a937a06d2009-08-19 21:19:24973 const scoped_refptr<TestClientSocketPool> pool_;
[email protected]f6d1d6eb2009-06-24 20:16:09974 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:58975 TestConnectJobFactory* const test_connect_job_factory_;
976 TestConnectJob::JobType next_job_type_;
[email protected]f6d1d6eb2009-06-24 20:16:09977 TestCompletionCallback callback_;
978};
979
[email protected]2ab05b52009-07-01 23:57:58980TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:53981 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20982
[email protected]0b7648c2009-07-06 20:14:01983 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:06984 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:58985 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:06986 &handle, pool_.get(), connect_job_factory_,
987 TestConnectJob::kMockPendingJob);
[email protected]a937a06d2009-08-19 21:19:24988 int rv = InitHandle(&handle, "a", kDefaultPriority, &callback,
989 pool_.get(), NULL);
[email protected]f6d1d6eb2009-06-24 20:16:09990 ASSERT_EQ(ERR_IO_PENDING, rv);
991
992 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:58993}
[email protected]f6d1d6eb2009-06-24 20:16:09994
[email protected]2ab05b52009-07-01 23:57:58995TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:53996 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20997
[email protected]0b7648c2009-07-06 20:14:01998 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:06999 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581000 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061001 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]a937a06d2009-08-19 21:19:241002 int rv = InitHandle(&handle, "a", kDefaultPriority, &callback,
1003 pool_.get(), NULL);
[email protected]2ab05b52009-07-01 23:57:581004 ASSERT_EQ(ERR_IO_PENDING, rv);
1005
1006 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091007}
1008
1009// Make sure that pending requests get serviced after active requests get
1010// cancelled.
[email protected]ab838892009-06-30 18:49:051011TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531012 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201013
[email protected]0b7648c2009-07-06 20:14:011014 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091015
[email protected]c9d6a1d2009-07-14 16:15:201016 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1017 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1018 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1019 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1020 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1021 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1022 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091023
[email protected]c9d6a1d2009-07-14 16:15:201024 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1025 // Let's cancel them.
1026 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]a6c59f62009-07-29 16:33:331027 ASSERT_FALSE(requests_[i]->handle()->is_initialized());
1028 requests_[i]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091029 }
1030
[email protected]f6d1d6eb2009-06-24 20:16:091031 // Let's wait for the rest to complete now.
[email protected]c9d6a1d2009-07-14 16:15:201032 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i) {
1033 EXPECT_EQ(OK, requests_[i]->WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331034 requests_[i]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091035 }
1036
[email protected]75439d3b2009-07-23 22:11:171037 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091038}
1039
1040// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051041TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531042 const size_t kMaxSockets = 5;
1043 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201044
[email protected]0b7648c2009-07-06 20:14:011045 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091046
[email protected]211d21722009-07-22 15:48:531047 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1048 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091049
1050 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531051 for (size_t i = 0; i < kNumberOfRequests; ++i)
1052 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091053
[email protected]211d21722009-07-22 15:48:531054 for (size_t i = 0; i < kNumberOfRequests; ++i)
1055 EXPECT_EQ(ERR_CONNECTION_FAILED, requests_[i]->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091056}
1057
[email protected]5fc08e32009-07-15 17:09:571058TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531059 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571060
1061 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1062
[email protected]a512f5982009-08-18 16:01:061063 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241064 int rv = InitHandle(req.handle(), "a", kDefaultPriority, &req,
1065 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571066 EXPECT_EQ(ERR_IO_PENDING, rv);
1067
1068 // Cancel the active request.
[email protected]a6c59f62009-07-29 16:33:331069 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571070
[email protected]a937a06d2009-08-19 21:19:241071 rv = InitHandle(req.handle(), "a", kDefaultPriority, &req,
1072 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571073 EXPECT_EQ(ERR_IO_PENDING, rv);
1074 EXPECT_EQ(OK, req.WaitForResult());
1075
[email protected]a6c59f62009-07-29 16:33:331076 EXPECT_FALSE(req.handle()->is_reused());
[email protected]75439d3b2009-07-23 22:11:171077 EXPECT_EQ(1U, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571078 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1079}
1080
[email protected]2b7523d2009-07-29 20:29:231081// Regression test for http://crbug.com/17985.
1082TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1083 const int kMaxSockets = 3;
1084 const int kMaxSocketsPerGroup = 2;
1085 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1086
[email protected]ac790b42009-12-02 04:31:311087 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231088
1089 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1090 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1091
1092 // This is going to be a pending request in an otherwise empty group.
1093 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1094
1095 // Reach the maximum socket limit.
1096 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1097
1098 // Create a stalled group with high priorities.
1099 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1100 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1101 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
1102
1103 // Release the first two sockets from "a", which will make room
1104 // for requests from "c". After that "a" will have no active sockets
1105 // and one pending request.
1106 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1107 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1108
1109 // Closing idle sockets should not get us into trouble, but in the bug
1110 // we were hitting a CHECK here.
1111 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
1112 pool_->CloseIdleSockets();
1113 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1114}
1115
[email protected]4d3b05d2010-01-27 21:27:291116TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531117 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571118
1119 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061120 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]9e743cd2010-03-16 07:03:531121 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
1122 int rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_.get(), log.bound());
[email protected]5fc08e32009-07-15 17:09:571123 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331124 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:571125 EXPECT_EQ(OK, req.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331126 EXPECT_TRUE(req.handle()->is_initialized());
1127 EXPECT_TRUE(req.handle()->socket());
1128 req.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:301129
[email protected]9e743cd2010-03-16 07:03:531130 EXPECT_EQ(7u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:461131 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:531132 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
1133 EXPECT_TRUE(LogContainsBeginEvent(
1134 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]e9002a92010-01-29 07:10:461135 EXPECT_TRUE(LogContainsEndEvent(
[email protected]9e743cd2010-03-16 07:03:531136 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]6b624c62010-03-14 08:37:321137 EXPECT_TRUE(LogContainsEvent(
[email protected]9e743cd2010-03-16 07:03:531138 log.entries(), 3, NetLog::TYPE_CANCELLED, NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:461139 EXPECT_TRUE(LogContainsEndEvent(
[email protected]9e743cd2010-03-16 07:03:531140 log.entries(), 4, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]6b624c62010-03-14 08:37:321141 EXPECT_TRUE(LogContainsEndEvent(
[email protected]9e743cd2010-03-16 07:03:531142 log.entries(), 6, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571143}
1144
[email protected]4d3b05d2010-01-27 21:27:291145TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571146 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531147 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571148
1149 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]a512f5982009-08-18 16:01:061150 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]9e743cd2010-03-16 07:03:531151 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]5fc08e32009-07-15 17:09:571152 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:241153 InitHandle(req.handle(), "a", kDefaultPriority, &req,
[email protected]9e743cd2010-03-16 07:03:531154 pool_.get(), log.bound()));
[email protected]a6c59f62009-07-29 16:33:331155 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:571156 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:301157
[email protected]9e743cd2010-03-16 07:03:531158 EXPECT_EQ(7u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:461159 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:531160 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
1161 EXPECT_TRUE(LogContainsBeginEvent(
1162 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]e9002a92010-01-29 07:10:461163 EXPECT_TRUE(LogContainsEndEvent(
[email protected]9e743cd2010-03-16 07:03:531164 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]6b624c62010-03-14 08:37:321165 EXPECT_TRUE(LogContainsEvent(
[email protected]9e743cd2010-03-16 07:03:531166 log.entries(), 3, NetLog::TYPE_CANCELLED, NetLog::PHASE_NONE));
[email protected]6b624c62010-03-14 08:37:321167 EXPECT_TRUE(LogContainsEndEvent(
[email protected]9e743cd2010-03-16 07:03:531168 log.entries(), 4, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]6b624c62010-03-14 08:37:321169 EXPECT_TRUE(LogContainsEndEvent(
[email protected]9e743cd2010-03-16 07:03:531170 log.entries(), 6, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571171}
1172
[email protected]4d3b05d2010-01-27 21:27:291173TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101174 // TODO(eroman): Add back the log expectations! Removed them because the
1175 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531176 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571177
1178 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061179 TestSocketRequest req(&request_order_, &completion_count_);
1180 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]5fc08e32009-07-15 17:09:571181
[email protected]5fc08e32009-07-15 17:09:571182 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:241183 InitHandle(req.handle(), "a", kDefaultPriority, &req,
[email protected]b22b5162010-03-16 07:53:101184 pool_.get(), BoundNetLog()));
[email protected]9e743cd2010-03-16 07:03:531185 CapturingBoundNetLog log2(CapturingNetLog::kUnbounded);
[email protected]5fc08e32009-07-15 17:09:571186 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:241187 InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
[email protected]b22b5162010-03-16 07:53:101188 pool_.get(), BoundNetLog()));
[email protected]5fc08e32009-07-15 17:09:571189
[email protected]a6c59f62009-07-29 16:33:331190 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571191
[email protected]fd7b7c92009-08-20 19:38:301192
1193 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301194
[email protected]5fc08e32009-07-15 17:09:571195 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331196 req2.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:301197
1198 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531199 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571200}
1201
[email protected]4d3b05d2010-01-27 21:27:291202TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341203 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1204
[email protected]17a0c6c2009-08-04 00:07:041205 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1206
[email protected]ac790b42009-12-02 04:31:311207 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1208 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1209 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1210 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341211
1212 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1213 requests_[2]->handle()->Reset();
1214 requests_[3]->handle()->Reset();
1215 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1216
1217 requests_[1]->handle()->Reset();
1218 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1219
1220 requests_[0]->handle()->Reset();
1221 EXPECT_EQ(kDefaultMaxSocketsPerGroup - 1, pool_->NumConnectJobsInGroup("a"));
1222}
1223
[email protected]5fc08e32009-07-15 17:09:571224// When requests and ConnectJobs are not coupled, the request will get serviced
1225// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291226TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531227 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571228
1229 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321230 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571231
[email protected]a512f5982009-08-18 16:01:061232 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241233 int rv = InitHandle(req1.handle(), "a", kDefaultPriority,
1234 &req1, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571235 EXPECT_EQ(ERR_IO_PENDING, rv);
1236 EXPECT_EQ(OK, req1.WaitForResult());
1237
1238 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1239 // without a job.
1240 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1241
[email protected]a512f5982009-08-18 16:01:061242 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241243 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
1244 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571245 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a512f5982009-08-18 16:01:061246 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241247 rv = InitHandle(
1248 req3.handle(), "a", kDefaultPriority, &req3, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571249 EXPECT_EQ(ERR_IO_PENDING, rv);
1250
1251 // Both Requests 2 and 3 are pending. We release socket 1 which should
1252 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331253 req1.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571254 MessageLoop::current()->RunAllPending(); // Run the DoReleaseSocket()
[email protected]a6c59f62009-07-29 16:33:331255 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571256 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331257 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571258
1259 // Signal job 2, which should service request 3.
1260
1261 client_socket_factory_.SignalJobs();
1262 EXPECT_EQ(OK, req3.WaitForResult());
1263
1264 ASSERT_EQ(3U, request_order_.size());
1265 EXPECT_EQ(&req1, request_order_[0]);
1266 EXPECT_EQ(&req2, request_order_[1]);
1267 EXPECT_EQ(&req3, request_order_[2]);
1268 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1269}
1270
1271// The requests are not coupled to the jobs. So, the requests should finish in
1272// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:291273TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531274 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571275 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321276 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571277
[email protected]a512f5982009-08-18 16:01:061278 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241279 int rv = InitHandle(
1280 req1.handle(), "a", kDefaultPriority, &req1, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571281 EXPECT_EQ(ERR_IO_PENDING, rv);
1282
[email protected]a512f5982009-08-18 16:01:061283 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241284 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
1285 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571286 EXPECT_EQ(ERR_IO_PENDING, rv);
1287
1288 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321289 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571290
[email protected]a512f5982009-08-18 16:01:061291 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241292 rv = InitHandle(
1293 req3.handle(), "a", kDefaultPriority, &req3, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571294 EXPECT_EQ(ERR_IO_PENDING, rv);
1295
1296 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1297 EXPECT_EQ(OK, req2.WaitForResult());
1298 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1299
1300 ASSERT_EQ(3U, request_order_.size());
1301 EXPECT_EQ(&req1, request_order_[0]);
1302 EXPECT_EQ(&req2, request_order_[1]);
1303 EXPECT_EQ(&req3, request_order_[2]);
1304}
1305
[email protected]4d3b05d2010-01-27 21:27:291306TEST_F(ClientSocketPoolBaseTest, DISABLED_LoadState) {
[email protected]211d21722009-07-22 15:48:531307 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571308 connect_job_factory_->set_job_type(
[email protected]b59ff372009-07-15 22:04:321309 TestConnectJob::kMockAdvancingLoadStateJob);
[email protected]5fc08e32009-07-15 17:09:571310
[email protected]a512f5982009-08-18 16:01:061311 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241312 int rv = InitHandle(
1313 req1.handle(), "a", kDefaultPriority, &req1, pool_.get(), NULL);
[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_IDLE, req1.handle()->GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571316
1317 MessageLoop::current()->RunAllPending();
1318
[email protected]a512f5982009-08-18 16:01:061319 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241320 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
1321 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571322 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331323 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, req1.handle()->GetLoadState());
1324 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, req2.handle()->GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571325}
1326
[email protected]4d3b05d2010-01-27 21:27:291327TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
[email protected]9bf28db2009-08-29 01:35:161328 CreatePoolWithIdleTimeouts(
1329 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1330 base::TimeDelta(), // Time out unused sockets immediately.
1331 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1332
1333 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1334
1335 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
1336
1337 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]ac790b42009-12-02 04:31:311338 int rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_.get(), NULL);
[email protected]9bf28db2009-08-29 01:35:161339 EXPECT_EQ(ERR_IO_PENDING, rv);
1340 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
1341
1342 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]ac790b42009-12-02 04:31:311343 rv = InitHandle(req2.handle(), "a", LOWEST, &req2, pool_.get(), NULL);
[email protected]9bf28db2009-08-29 01:35:161344 EXPECT_EQ(ERR_IO_PENDING, rv);
1345 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req2.handle()));
1346
1347 // Cancel one of the requests. Wait for the other, which will get the first
1348 // job. Release the socket. Run the loop again to make sure the second
1349 // socket is sitting idle and the first one is released (since ReleaseSocket()
1350 // just posts a DoReleaseSocket() task).
1351
1352 req.handle()->Reset();
1353 EXPECT_EQ(OK, req2.WaitForResult());
1354 req2.handle()->Reset();
[email protected]6b175382009-10-13 06:47:471355
1356 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1357 // actually become pending until 2ms after they have been created. In order
1358 // to flush all tasks, we need to wait so that we know there are no
1359 // soon-to-be-pending tasks waiting.
1360 PlatformThread::Sleep(10);
[email protected]9bf28db2009-08-29 01:35:161361 MessageLoop::current()->RunAllPending();
1362
1363 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:041364
[email protected]9bf28db2009-08-29 01:35:161365 // Invoke the idle socket cleanup check. Only one socket should be left, the
1366 // used socket. Request it to make sure that it's used.
1367
1368 pool_->CleanupTimedOutIdleSockets();
[email protected]9e743cd2010-03-16 07:03:531369 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
1370 rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_.get(), log.bound());
[email protected]9bf28db2009-08-29 01:35:161371 EXPECT_EQ(OK, rv);
1372 EXPECT_TRUE(req.handle()->is_reused());
[email protected]fd4fe0b2010-02-08 23:02:151373 EXPECT_TRUE(LogContainsEntryWithType(
[email protected]9e743cd2010-03-16 07:03:531374 log.entries(), 1, NetLog::Entry::TYPE_STRING_LITERAL));
[email protected]9bf28db2009-08-29 01:35:161375}
1376
[email protected]2041cf342010-02-19 03:15:591377// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:161378// because of multiple releasing disconnected sockets.
1379TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
1380 CreatePoolWithIdleTimeouts(
1381 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1382 base::TimeDelta(), // Time out unused sockets immediately.
1383 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1384
1385 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1386
1387 // Startup 4 connect jobs. Two of them will be pending.
1388
1389 TestSocketRequest req(&request_order_, &completion_count_);
1390 int rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_.get(), NULL);
1391 EXPECT_EQ(OK, rv);
1392
1393 TestSocketRequest req2(&request_order_, &completion_count_);
1394 rv = InitHandle(req2.handle(), "a", LOWEST, &req2, pool_.get(), NULL);
1395 EXPECT_EQ(OK, rv);
1396
1397 TestSocketRequest req3(&request_order_, &completion_count_);
1398 rv = InitHandle(req3.handle(), "a", LOWEST, &req3, pool_.get(), NULL);
1399 EXPECT_EQ(ERR_IO_PENDING, rv);
1400
1401 TestSocketRequest req4(&request_order_, &completion_count_);
1402 rv = InitHandle(req4.handle(), "a", LOWEST, &req4, pool_.get(), NULL);
1403 EXPECT_EQ(ERR_IO_PENDING, rv);
1404
1405 // Release two disconnected sockets.
1406
1407 req.handle()->socket()->Disconnect();
1408 req.handle()->Reset();
1409 req2.handle()->socket()->Disconnect();
1410 req2.handle()->Reset();
1411
1412 EXPECT_EQ(OK, req3.WaitForResult());
1413 EXPECT_FALSE(req3.handle()->is_reused());
1414 EXPECT_EQ(OK, req4.WaitForResult());
1415 EXPECT_FALSE(req4.handle()->is_reused());
1416}
1417
[email protected]fd4fe0b2010-02-08 23:02:151418TEST_F(ClientSocketPoolBaseTest,
1419 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
1420 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1421
1422 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1423
1424 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1425 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1426 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1427 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1428
1429 EXPECT_EQ(OK, requests_[0]->WaitForResult());
1430 EXPECT_EQ(OK, requests_[1]->WaitForResult());
1431 EXPECT_EQ(2u, completion_count_);
1432
1433 // Releases one connection.
1434 EXPECT_TRUE(ReleaseOneConnection(NO_KEEP_ALIVE));
1435 EXPECT_EQ(OK, requests_[2]->WaitForResult());
1436
1437 EXPECT_TRUE(ReleaseOneConnection(NO_KEEP_ALIVE));
1438 EXPECT_EQ(OK, requests_[3]->WaitForResult());
1439 EXPECT_EQ(4u, completion_count_);
1440
1441 EXPECT_EQ(1, GetOrderOfRequest(1));
1442 EXPECT_EQ(2, GetOrderOfRequest(2));
1443 EXPECT_EQ(3, GetOrderOfRequest(3));
1444 EXPECT_EQ(4, GetOrderOfRequest(4));
1445
1446 // Make sure we test order of all requests made.
1447 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(5));
1448}
1449
[email protected]4f1e4982010-03-02 18:31:041450class TestReleasingSocketRequest : public CallbackRunner< Tuple1<int> > {
1451 public:
1452 explicit TestReleasingSocketRequest(TestClientSocketPool* pool)
1453 : pool_(pool) {}
1454
1455 ClientSocketHandle* handle() { return &handle_; }
1456
1457 int WaitForResult() {
1458 return callback_.WaitForResult();
1459 }
1460
1461 virtual void RunWithParams(const Tuple1<int>& params) {
1462 callback_.RunWithParams(params);
1463 handle_.Reset();
1464 EXPECT_EQ(ERR_IO_PENDING,
1465 InitHandle(&handle2_, "a", kDefaultPriority,
1466 &callback2_, pool_, NULL));
1467 }
1468
1469 private:
1470 TestClientSocketPool* const pool_;
1471 ClientSocketHandle handle_;
1472 ClientSocketHandle handle2_;
1473 TestCompletionCallback callback_;
1474 TestCompletionCallback callback2_;
1475};
1476
1477// This test covers the case where, within the same DoReleaseSocket() callback,
1478// we release the just acquired socket and start up a new request. See bug
1479// 36871 for details.
1480TEST_F(ClientSocketPoolBaseTest, ReleasedSocketReleasesToo) {
1481 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1482
1483 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1484
1485 // Complete one request and release the socket.
1486 ClientSocketHandle handle;
1487 TestCompletionCallback callback;
1488 EXPECT_EQ(OK, InitHandle(
1489 &handle, "a", kDefaultPriority, &callback, pool_.get(), NULL));
1490 handle.Reset();
[email protected]6b624c62010-03-14 08:37:321491
[email protected]4f1e4982010-03-02 18:31:041492 // Before the DoReleaseSocket() task has run, start up a
1493 // TestReleasingSocketRequest. This one will be ERR_IO_PENDING since
1494 // num_releasing_sockets > 0 and there was no idle socket to use yet.
1495 TestReleasingSocketRequest request(pool_.get());
1496 EXPECT_EQ(ERR_IO_PENDING,
1497 InitHandle(request.handle(), "a", kDefaultPriority, &request,
1498 pool_.get(), NULL));
1499
1500 EXPECT_EQ(OK, request.WaitForResult());
1501}
1502
[email protected]f6d1d6eb2009-06-24 20:16:091503} // namespace
1504
1505} // namespace net