blob: 65feffd167341a6f7810bcb56f25e4983a555a34 [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
[email protected]a796bcec2010-03-22 17:17:26262 virtual base::TimeDelta ConnectionTimeout() const {
263 return timeout_duration_;
264 }
265
[email protected]ab838892009-06-30 18:49:05266 private:
267 TestConnectJob::JobType job_type_;
[email protected]974ebd62009-08-03 23:14:34268 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57269 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05270
271 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
272};
273
274class TestClientSocketPool : public ClientSocketPool {
275 public:
276 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53277 int max_sockets,
[email protected]ab838892009-06-30 18:49:05278 int max_sockets_per_group,
[email protected]a796bcec2010-03-22 17:17:26279 const std::string& name,
[email protected]9bf28db2009-08-29 01:35:16280 base::TimeDelta unused_idle_socket_timeout,
281 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49282 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
[email protected]a796bcec2010-03-22 17:17:26283 : base_(max_sockets, max_sockets_per_group, name,
[email protected]9bf28db2009-08-29 01:35:16284 unused_idle_socket_timeout, used_idle_socket_timeout,
[email protected]100d5fb92009-12-21 21:08:35285 connect_job_factory, NULL) {}
[email protected]ab838892009-06-30 18:49:05286
287 virtual int RequestSocket(
288 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49289 const void* params,
[email protected]ac790b42009-12-02 04:31:31290 net::RequestPriority priority,
[email protected]ab838892009-06-30 18:49:05291 ClientSocketHandle* handle,
[email protected]684970b2009-08-14 04:54:46292 CompletionCallback* callback,
[email protected]9e743cd2010-03-16 07:03:53293 const BoundNetLog& net_log) {
[email protected]d80a4322009-08-14 07:07:49294 return base_.RequestSocket(
[email protected]9e743cd2010-03-16 07:03:53295 group_name, params, priority, handle, callback, net_log);
[email protected]ab838892009-06-30 18:49:05296 }
297
298 virtual void CancelRequest(
299 const std::string& group_name,
300 const ClientSocketHandle* handle) {
[email protected]d80a4322009-08-14 07:07:49301 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05302 }
303
304 virtual void ReleaseSocket(
305 const std::string& group_name,
306 ClientSocket* socket) {
[email protected]d80a4322009-08-14 07:07:49307 base_.ReleaseSocket(group_name, socket);
[email protected]ab838892009-06-30 18:49:05308 }
309
310 virtual void CloseIdleSockets() {
[email protected]d80a4322009-08-14 07:07:49311 base_.CloseIdleSockets();
[email protected]ab838892009-06-30 18:49:05312 }
313
[email protected]d80a4322009-08-14 07:07:49314 virtual int IdleSocketCount() const { return base_.idle_socket_count(); }
[email protected]ab838892009-06-30 18:49:05315
316 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49317 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05318 }
319
320 virtual LoadState GetLoadState(const std::string& group_name,
321 const ClientSocketHandle* handle) const {
[email protected]d80a4322009-08-14 07:07:49322 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05323 }
324
[email protected]a796bcec2010-03-22 17:17:26325 virtual base::TimeDelta ConnectionTimeout() const {
326 return base_.ConnectionTimeout();
327 }
328
329 virtual const std::string& name() const { return base_.name(); }
330
[email protected]d80a4322009-08-14 07:07:49331 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20332
[email protected]974ebd62009-08-03 23:14:34333 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49334 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34335 }
336
[email protected]9bf28db2009-08-29 01:35:16337 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
338
[email protected]ab838892009-06-30 18:49:05339 private:
[email protected]5389bc72009-11-05 23:34:24340 ~TestClientSocketPool() {}
341
[email protected]d80a4322009-08-14 07:07:49342 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05343
344 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
345};
346
[email protected]a937a06d2009-08-19 21:19:24347} // namespace
348
[email protected]7fc5b09a2010-02-27 00:07:38349REGISTER_SOCKET_PARAMS_FOR_POOL(TestClientSocketPool, TestSocketParams);
[email protected]a937a06d2009-08-19 21:19:24350
351namespace {
352
[email protected]5fc08e32009-07-15 17:09:57353void MockClientSocketFactory::SignalJobs() {
354 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
355 it != waiting_jobs_.end(); ++it) {
356 (*it)->Signal();
357 }
358 waiting_jobs_.clear();
359}
360
[email protected]974ebd62009-08-03 23:14:34361class TestConnectJobDelegate : public ConnectJob::Delegate {
362 public:
363 TestConnectJobDelegate()
364 : have_result_(false), waiting_for_result_(false), result_(OK) {}
365 virtual ~TestConnectJobDelegate() {}
366
367 virtual void OnConnectJobComplete(int result, ConnectJob* job) {
368 result_ = result;
[email protected]6e713f02009-08-06 02:56:40369 scoped_ptr<ClientSocket> socket(job->ReleaseSocket());
[email protected]9b6fee12009-09-29 18:13:07370 // socket.get() should be NULL iff result != OK
371 EXPECT_EQ(socket.get() == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34372 delete job;
373 have_result_ = true;
374 if (waiting_for_result_)
375 MessageLoop::current()->Quit();
376 }
377
378 int WaitForResult() {
379 DCHECK(!waiting_for_result_);
380 while (!have_result_) {
381 waiting_for_result_ = true;
382 MessageLoop::current()->Run();
383 waiting_for_result_ = false;
384 }
385 have_result_ = false; // auto-reset for next callback
386 return result_;
387 }
388
389 private:
390 bool have_result_;
391 bool waiting_for_result_;
392 int result_;
393};
394
[email protected]75439d3b2009-07-23 22:11:17395class ClientSocketPoolBaseTest : public ClientSocketPoolTest {
[email protected]f6d1d6eb2009-06-24 20:16:09396 protected:
[email protected]17a0c6c2009-08-04 00:07:04397 ClientSocketPoolBaseTest() {}
[email protected]c9d6a1d2009-07-14 16:15:20398
[email protected]211d21722009-07-22 15:48:53399 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16400 CreatePoolWithIdleTimeouts(
401 max_sockets,
402 max_sockets_per_group,
403 base::TimeDelta::FromSeconds(kUnusedIdleSocketTimeout),
404 base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout));
405 }
406
407 void CreatePoolWithIdleTimeouts(
408 int max_sockets, int max_sockets_per_group,
409 base::TimeDelta unused_idle_socket_timeout,
410 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20411 DCHECK(!pool_.get());
[email protected]17a0c6c2009-08-04 00:07:04412 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_);
[email protected]211d21722009-07-22 15:48:53413 pool_ = new TestClientSocketPool(max_sockets,
414 max_sockets_per_group,
[email protected]a796bcec2010-03-22 17:17:26415 "IdleTimeoutTestPool",
[email protected]9bf28db2009-08-29 01:35:16416 unused_idle_socket_timeout,
417 used_idle_socket_timeout,
[email protected]c9d6a1d2009-07-14 16:15:20418 connect_job_factory_);
419 }
[email protected]f6d1d6eb2009-06-24 20:16:09420
[email protected]ac790b42009-12-02 04:31:31421 int StartRequest(const std::string& group_name,
422 net::RequestPriority priority) {
[email protected]7fc5b09a2010-02-27 00:07:38423 return StartRequestUsingPool<TestClientSocketPool, TestSocketParams>(
[email protected]a796bcec2010-03-22 17:17:26424 pool_, group_name, priority, NULL);
[email protected]f6d1d6eb2009-06-24 20:16:09425 }
426
427 virtual void TearDown() {
[email protected]6b175382009-10-13 06:47:47428 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
429 // actually become pending until 2ms after they have been created. In order
430 // to flush all tasks, we need to wait so that we know there are no
431 // soon-to-be-pending tasks waiting.
432 PlatformThread::Sleep(10);
433 MessageLoop::current()->RunAllPending();
434
[email protected]211d21722009-07-22 15:48:53435 // Need to delete |pool_| before we turn late binding back off. We also need
436 // to delete |requests_| because the pool is reference counted and requests
437 // keep reference to it.
438 // TODO(willchan): Remove this part when late binding becomes the default.
[email protected]5fc08e32009-07-15 17:09:57439 pool_ = NULL;
[email protected]211d21722009-07-22 15:48:53440 requests_.reset();
441
[email protected]75439d3b2009-07-23 22:11:17442 ClientSocketPoolTest::TearDown();
[email protected]f6d1d6eb2009-06-24 20:16:09443 }
444
[email protected]f6d1d6eb2009-06-24 20:16:09445 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04446 TestConnectJobFactory* connect_job_factory_;
[email protected]c9d6a1d2009-07-14 16:15:20447 scoped_refptr<TestClientSocketPool> pool_;
[email protected]f6d1d6eb2009-06-24 20:16:09448};
449
[email protected]a937a06d2009-08-19 21:19:24450// Helper function which explicitly specifies the template parameters, since
451// the compiler will infer (in this case, incorrectly) that NULL is of type int.
452int InitHandle(ClientSocketHandle* handle,
453 const std::string& group_name,
[email protected]ac790b42009-12-02 04:31:31454 net::RequestPriority priority,
[email protected]a937a06d2009-08-19 21:19:24455 CompletionCallback* callback,
[email protected]a796bcec2010-03-22 17:17:26456 const scoped_refptr<TestClientSocketPool>& pool,
[email protected]9e743cd2010-03-16 07:03:53457 const BoundNetLog& net_log) {
[email protected]7fc5b09a2010-02-27 00:07:38458 return handle->Init<TestSocketParams, TestClientSocketPool>(
[email protected]9e743cd2010-03-16 07:03:53459 group_name, NULL, priority, callback, pool, net_log);
[email protected]a937a06d2009-08-19 21:19:24460}
461
[email protected]974ebd62009-08-03 23:14:34462// Even though a timeout is specified, it doesn't time out on a synchronous
463// completion.
464TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
465 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06466 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49467 TestClientSocketPoolBase::Request request(
468 &ignored, NULL, kDefaultPriority, NULL, NULL);
[email protected]974ebd62009-08-03 23:14:34469 scoped_ptr<TestConnectJob> job(
470 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:12471 "a",
[email protected]974ebd62009-08-03 23:14:34472 request,
473 base::TimeDelta::FromMicroseconds(1),
474 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30475 &client_socket_factory_,
476 NULL));
[email protected]974ebd62009-08-03 23:14:34477 EXPECT_EQ(OK, job->Connect());
478}
479
480TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
481 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06482 ClientSocketHandle ignored;
[email protected]9e743cd2010-03-16 07:03:53483 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
484
[email protected]d80a4322009-08-14 07:07:49485 TestClientSocketPoolBase::Request request(
486 &ignored, NULL, kDefaultPriority, NULL, NULL);
[email protected]974ebd62009-08-03 23:14:34487 // Deleted by TestConnectJobDelegate.
488 TestConnectJob* job =
489 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12490 "a",
[email protected]974ebd62009-08-03 23:14:34491 request,
492 base::TimeDelta::FromMicroseconds(1),
493 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30494 &client_socket_factory_,
[email protected]9e743cd2010-03-16 07:03:53495 log.bound());
[email protected]974ebd62009-08-03 23:14:34496 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
497 PlatformThread::Sleep(1);
498 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30499
[email protected]9e743cd2010-03-16 07:03:53500 EXPECT_EQ(3u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:46501 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:53502 log.entries(), 0, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]e9002a92010-01-29 07:10:46503 EXPECT_TRUE(LogContainsEvent(
[email protected]9e743cd2010-03-16 07:03:53504 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
505 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:46506 EXPECT_TRUE(LogContainsEndEvent(
[email protected]9e743cd2010-03-16 07:03:53507 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34508}
509
[email protected]5fc08e32009-07-15 17:09:57510TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53511 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20512
[email protected]f6d1d6eb2009-06-24 20:16:09513 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06514 ClientSocketHandle handle;
[email protected]9e743cd2010-03-16 07:03:53515 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
516
[email protected]a796bcec2010-03-22 17:17:26517 EXPECT_EQ(OK, InitHandle(&handle, "a", kDefaultPriority, &callback, pool_,
518 log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09519 EXPECT_TRUE(handle.is_initialized());
520 EXPECT_TRUE(handle.socket());
[email protected]f6d1d6eb2009-06-24 20:16:09521 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:30522
[email protected]9e743cd2010-03-16 07:03:53523 EXPECT_EQ(5u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:46524 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:53525 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
526 EXPECT_TRUE(LogContainsBeginEvent(
527 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]e9002a92010-01-29 07:10:46528 EXPECT_TRUE(LogContainsEndEvent(
[email protected]9e743cd2010-03-16 07:03:53529 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
530 EXPECT_TRUE(LogContainsEvent(
531 log.entries(), 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_ID,
532 NetLog::PHASE_NONE));
533 EXPECT_TRUE(LogContainsEndEvent(
534 log.entries(), 4, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09535}
536
[email protected]ab838892009-06-30 18:49:05537TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53538 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20539
[email protected]ab838892009-06-30 18:49:05540 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]9e743cd2010-03-16 07:03:53541 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
542
[email protected]a512f5982009-08-18 16:01:06543 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]3ae82302009-06-26 06:01:21544 EXPECT_EQ(ERR_CONNECTION_FAILED,
[email protected]a796bcec2010-03-22 17:17:26545 InitHandle(req.handle(), "a", kDefaultPriority, &req, pool_,
546 log.bound()));
[email protected]fd7b7c92009-08-20 19:38:30547
[email protected]9e743cd2010-03-16 07:03:53548 EXPECT_EQ(5u, log.entries().size());
549 EXPECT_TRUE(LogContainsBeginEvent(log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]e9002a92010-01-29 07:10:46550 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:53551 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]e9002a92010-01-29 07:10:46552 EXPECT_TRUE(LogContainsEndEvent(
[email protected]9e743cd2010-03-16 07:03:53553 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
554 EXPECT_TRUE(LogContainsEndEvent(log.entries(), 4, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09555}
556
[email protected]211d21722009-07-22 15:48:53557TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
558 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
559
[email protected]9e743cd2010-03-16 07:03:53560 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30561
[email protected]211d21722009-07-22 15:48:53562 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
563 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
564 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
565 EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
566
567 EXPECT_EQ(static_cast<int>(requests_.size()),
568 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17569 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53570
571 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
572 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
573 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
574
575 ReleaseAllConnections(KEEP_ALIVE);
576
577 EXPECT_EQ(static_cast<int>(requests_.size()),
578 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17579 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53580
581 EXPECT_EQ(1, GetOrderOfRequest(1));
582 EXPECT_EQ(2, GetOrderOfRequest(2));
583 EXPECT_EQ(3, GetOrderOfRequest(3));
584 EXPECT_EQ(4, GetOrderOfRequest(4));
585 EXPECT_EQ(5, GetOrderOfRequest(5));
586 EXPECT_EQ(6, GetOrderOfRequest(6));
587 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17588
589 // Make sure we test order of all requests made.
590 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53591}
592
593TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
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 // Reach all limits: max total sockets, and max sockets per group.
599 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
600 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
601 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
602 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
603
604 EXPECT_EQ(static_cast<int>(requests_.size()),
605 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17606 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53607
608 // Now create a new group and verify that we don't starve it.
609 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
610
611 ReleaseAllConnections(KEEP_ALIVE);
612
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));
[email protected]75439d3b2009-07-23 22:11:17622
623 // Make sure we test order of all requests made.
624 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53625}
626
627TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
628 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
629
[email protected]ac790b42009-12-02 04:31:31630 EXPECT_EQ(OK, StartRequest("b", LOWEST));
631 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
632 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
633 EXPECT_EQ(OK, StartRequest("a", LOWEST));
[email protected]211d21722009-07-22 15:48:53634
635 EXPECT_EQ(static_cast<int>(requests_.size()),
636 client_socket_factory_.allocation_count());
637
[email protected]ac790b42009-12-02 04:31:31638 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
639 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
640 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53641
642 ReleaseAllConnections(KEEP_ALIVE);
643
644 // We're re-using one socket for group "a", and one for "b".
645 EXPECT_EQ(static_cast<int>(requests_.size()) - 2,
646 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17647 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53648
649 // First 4 requests don't have to wait, and finish in order.
650 EXPECT_EQ(1, GetOrderOfRequest(1));
651 EXPECT_EQ(2, GetOrderOfRequest(2));
652 EXPECT_EQ(3, GetOrderOfRequest(3));
653 EXPECT_EQ(4, GetOrderOfRequest(4));
654
[email protected]ac790b42009-12-02 04:31:31655 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
656 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53657 EXPECT_EQ(7, GetOrderOfRequest(5));
658 EXPECT_EQ(6, GetOrderOfRequest(6));
659 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17660
661 // Make sure we test order of all requests made.
662 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53663}
664
665TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
666 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
667
[email protected]ac790b42009-12-02 04:31:31668 EXPECT_EQ(OK, StartRequest("a", LOWEST));
669 EXPECT_EQ(OK, StartRequest("a", LOW));
670 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
671 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
[email protected]211d21722009-07-22 15:48:53672
673 EXPECT_EQ(static_cast<int>(requests_.size()),
674 client_socket_factory_.allocation_count());
675
[email protected]ac790b42009-12-02 04:31:31676 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
677 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
678 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53679
680 ReleaseAllConnections(KEEP_ALIVE);
681
682 // We're re-using one socket for group "a", and one for "b".
683 EXPECT_EQ(static_cast<int>(requests_.size()) - 2,
684 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17685 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53686
687 // First 4 requests don't have to wait, and finish in order.
688 EXPECT_EQ(1, GetOrderOfRequest(1));
689 EXPECT_EQ(2, GetOrderOfRequest(2));
690 EXPECT_EQ(3, GetOrderOfRequest(3));
691 EXPECT_EQ(4, GetOrderOfRequest(4));
692
693 // Request ("b", 7) has the highest priority, but we can't make new socket for
694 // group "b", because it has reached the per-group limit. Then we make
695 // socket for ("c", 6), because it has higher priority than ("a", 4),
696 // and we still can't make a socket for group "b".
697 EXPECT_EQ(5, GetOrderOfRequest(5));
698 EXPECT_EQ(6, GetOrderOfRequest(6));
699 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17700
701 // Make sure we test order of all requests made.
702 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53703}
704
705// Make sure that we count connecting sockets against the total limit.
706TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
707 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
708
709 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
710 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
711 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
712
713 // Create one asynchronous request.
714 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
715 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
716
[email protected]6b175382009-10-13 06:47:47717 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
718 // actually become pending until 2ms after they have been created. In order
719 // to flush all tasks, we need to wait so that we know there are no
720 // soon-to-be-pending tasks waiting.
721 PlatformThread::Sleep(10);
722 MessageLoop::current()->RunAllPending();
723
[email protected]211d21722009-07-22 15:48:53724 // The next synchronous request should wait for its turn.
725 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
726 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
727
728 ReleaseAllConnections(KEEP_ALIVE);
729
730 EXPECT_EQ(static_cast<int>(requests_.size()),
731 client_socket_factory_.allocation_count());
732
733 EXPECT_EQ(1, GetOrderOfRequest(1));
734 EXPECT_EQ(2, GetOrderOfRequest(2));
735 EXPECT_EQ(3, GetOrderOfRequest(3));
736 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:17737 EXPECT_EQ(5, GetOrderOfRequest(5));
738
739 // Make sure we test order of all requests made.
740 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53741}
742
743// Inside ClientSocketPoolBase we have a may_have_stalled_group flag,
744// which tells it to use more expensive, but accurate, group selection
745// algorithm. Make sure it doesn't get stuck in the "on" state.
746TEST_F(ClientSocketPoolBaseTest, MayHaveStalledGroupReset) {
747 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
748
749 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
750
751 // Reach group socket limit.
752 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
753 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
754 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
755
756 // Reach total limit, but don't request more sockets.
757 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
758 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
759 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
760
761 // Request one more socket while we are at the maximum sockets limit.
762 // This should flip the may_have_stalled_group flag.
763 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
764 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
765
766 // After releasing first connection for "a", we're still at the
767 // maximum sockets limit, but every group's pending queue is empty,
768 // so we reset the flag.
769 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
770 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
771
772 // Requesting additional socket while at the total limit should
773 // flip the flag back to "on".
774 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
775 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
776
777 // We'll request one more socket to verify that we don't reset the flag
778 // too eagerly.
779 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
780 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
781
782 // We're at the maximum socket limit, and still have one request pending
783 // for "d". Flag should be "on".
784 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
785 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
786
787 // Now every group's pending queue should be empty again.
788 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
789 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
790
791 ReleaseAllConnections(KEEP_ALIVE);
792 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
793}
794
[email protected]ab838892009-06-30 18:49:05795TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:53796 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09797
[email protected]c9d6a1d2009-07-14 16:15:20798 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
799 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:31800 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
801 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
802 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
803 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
804 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:09805
[email protected]c9d6a1d2009-07-14 16:15:20806 ReleaseAllConnections(KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09807
[email protected]c9d6a1d2009-07-14 16:15:20808 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
809 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17810 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09811
[email protected]c9d6a1d2009-07-14 16:15:20812 EXPECT_EQ(1, GetOrderOfRequest(1));
813 EXPECT_EQ(2, GetOrderOfRequest(2));
814 EXPECT_EQ(6, GetOrderOfRequest(3));
815 EXPECT_EQ(4, GetOrderOfRequest(4));
816 EXPECT_EQ(3, GetOrderOfRequest(5));
817 EXPECT_EQ(5, GetOrderOfRequest(6));
818 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17819
820 // Make sure we test order of all requests made.
821 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:09822}
823
[email protected]ab838892009-06-30 18:49:05824TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:53825 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09826
[email protected]c9d6a1d2009-07-14 16:15:20827 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
828 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:31829 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
830 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
831 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
832 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
833 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:09834
[email protected]c9d6a1d2009-07-14 16:15:20835 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09836
[email protected]c9d6a1d2009-07-14 16:15:20837 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i)
838 EXPECT_EQ(OK, requests_[i]->WaitForResult());
839
840 EXPECT_EQ(static_cast<int>(requests_.size()),
841 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17842 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09843}
844
845// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:05846// The pending connect job will be cancelled and should not call back into
847// ClientSocketPoolBase.
848TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:53849 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20850
[email protected]ab838892009-06-30 18:49:05851 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:06852 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]ab838892009-06-30 18:49:05853 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a796bcec2010-03-22 17:17:26854 InitHandle(req.handle(), "a", kDefaultPriority, &req, pool_, NULL));
[email protected]a6c59f62009-07-29 16:33:33855 req.handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:09856}
857
[email protected]ab838892009-06-30 18:49:05858TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:53859 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20860
[email protected]ab838892009-06-30 18:49:05861 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:06862 ClientSocketHandle handle;
[email protected]f6d1d6eb2009-06-24 20:16:09863 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06864 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09865
[email protected]ab838892009-06-30 18:49:05866 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a796bcec2010-03-22 17:17:26867 InitHandle(&handle, "a", kDefaultPriority, &callback, pool_, NULL));
[email protected]f6d1d6eb2009-06-24 20:16:09868
869 handle.Reset();
870
871 TestCompletionCallback callback2;
[email protected]a796bcec2010-03-22 17:17:26872 EXPECT_EQ(ERR_IO_PENDING, InitHandle(&handle, "a", kDefaultPriority,
873 &callback2, pool_, NULL));
[email protected]f6d1d6eb2009-06-24 20:16:09874
875 EXPECT_EQ(OK, callback2.WaitForResult());
876 EXPECT_FALSE(callback.have_result());
877
878 handle.Reset();
879}
880
[email protected]ab838892009-06-30 18:49:05881TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:53882 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09883
[email protected]c9d6a1d2009-07-14 16:15:20884 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
885 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:31886 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
887 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
888 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
889 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
890 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:09891
892 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:20893 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]a6c59f62009-07-29 16:33:33894 EXPECT_FALSE(requests_[index_to_cancel]->handle()->is_initialized());
895 requests_[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:09896
[email protected]c9d6a1d2009-07-14 16:15:20897 ReleaseAllConnections(KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09898
[email protected]c9d6a1d2009-07-14 16:15:20899 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
900 client_socket_factory_.allocation_count());
901 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup - 1,
[email protected]75439d3b2009-07-23 22:11:17902 completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09903
[email protected]c9d6a1d2009-07-14 16:15:20904 EXPECT_EQ(1, GetOrderOfRequest(1));
905 EXPECT_EQ(2, GetOrderOfRequest(2));
906 EXPECT_EQ(5, GetOrderOfRequest(3));
907 EXPECT_EQ(3, GetOrderOfRequest(4));
908 EXPECT_EQ(kRequestNotFound, GetOrderOfRequest(5)); // Canceled request.
909 EXPECT_EQ(4, GetOrderOfRequest(6));
910 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17911
912 // Make sure we test order of all requests made.
913 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:09914}
915
916class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
917 public:
[email protected]2ab05b52009-07-01 23:57:58918 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:24919 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:58920 TestConnectJobFactory* test_connect_job_factory,
921 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:09922 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:06923 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:58924 within_callback_(false),
925 test_connect_job_factory_(test_connect_job_factory),
926 next_job_type_(next_job_type) {}
[email protected]f6d1d6eb2009-06-24 20:16:09927
928 virtual void RunWithParams(const Tuple1<int>& params) {
929 callback_.RunWithParams(params);
930 ASSERT_EQ(OK, params.a);
931
932 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:58933 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]5edbf8d2010-01-13 18:44:11934
935 // Don't allow reuse of the socket. Disconnect it and then release it and
936 // run through the MessageLoop once to get it completely released.
937 handle_->socket()->Disconnect();
[email protected]f6d1d6eb2009-06-24 20:16:09938 handle_->Reset();
[email protected]5edbf8d2010-01-13 18:44:11939 {
940 MessageLoop::ScopedNestableTaskAllower nestable(
941 MessageLoop::current());
942 MessageLoop::current()->RunAllPending();
943 }
[email protected]f6d1d6eb2009-06-24 20:16:09944 within_callback_ = true;
[email protected]6b175382009-10-13 06:47:47945 TestCompletionCallback next_job_callback;
[email protected]a796bcec2010-03-22 17:17:26946 int rv = InitHandle(handle_, "a", kDefaultPriority, &next_job_callback,
947 pool_, NULL);
[email protected]2ab05b52009-07-01 23:57:58948 switch (next_job_type_) {
949 case TestConnectJob::kMockJob:
950 EXPECT_EQ(OK, rv);
951 break;
952 case TestConnectJob::kMockPendingJob:
953 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:47954
955 // For pending jobs, wait for new socket to be created. This makes
956 // sure there are no more pending operations nor any unclosed sockets
957 // when the test finishes.
958 // We need to give it a little bit of time to run, so that all the
959 // operations that happen on timers (e.g. cleanup of idle
960 // connections) can execute.
[email protected]5edbf8d2010-01-13 18:44:11961 {
962 MessageLoop::ScopedNestableTaskAllower nestable(
963 MessageLoop::current());
964 PlatformThread::Sleep(10);
965 EXPECT_EQ(OK, next_job_callback.WaitForResult());
966 }
[email protected]2ab05b52009-07-01 23:57:58967 break;
968 default:
969 FAIL() << "Unexpected job type: " << next_job_type_;
970 break;
971 }
[email protected]f6d1d6eb2009-06-24 20:16:09972 }
973 }
974
975 int WaitForResult() {
976 return callback_.WaitForResult();
977 }
978
979 private:
980 ClientSocketHandle* const handle_;
[email protected]a937a06d2009-08-19 21:19:24981 const scoped_refptr<TestClientSocketPool> pool_;
[email protected]f6d1d6eb2009-06-24 20:16:09982 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:58983 TestConnectJobFactory* const test_connect_job_factory_;
984 TestConnectJob::JobType next_job_type_;
[email protected]f6d1d6eb2009-06-24 20:16:09985 TestCompletionCallback callback_;
986};
987
[email protected]2ab05b52009-07-01 23:57:58988TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:53989 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20990
[email protected]0b7648c2009-07-06 20:14:01991 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:06992 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:58993 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:06994 &handle, pool_.get(), connect_job_factory_,
995 TestConnectJob::kMockPendingJob);
[email protected]a796bcec2010-03-22 17:17:26996 int rv = InitHandle(&handle, "a", kDefaultPriority, &callback, pool_, NULL);
[email protected]f6d1d6eb2009-06-24 20:16:09997 ASSERT_EQ(ERR_IO_PENDING, rv);
998
999 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581000}
[email protected]f6d1d6eb2009-06-24 20:16:091001
[email protected]2ab05b52009-07-01 23:57:581002TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531003 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201004
[email protected]0b7648c2009-07-06 20:14:011005 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061006 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581007 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061008 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]a796bcec2010-03-22 17:17:261009 int rv = InitHandle(&handle, "a", kDefaultPriority, &callback, pool_, NULL);
[email protected]2ab05b52009-07-01 23:57:581010 ASSERT_EQ(ERR_IO_PENDING, rv);
1011
1012 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091013}
1014
1015// Make sure that pending requests get serviced after active requests get
1016// cancelled.
[email protected]ab838892009-06-30 18:49:051017TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531018 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201019
[email protected]0b7648c2009-07-06 20:14:011020 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091021
[email protected]c9d6a1d2009-07-14 16:15:201022 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1023 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1024 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1025 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1026 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1027 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1028 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091029
[email protected]c9d6a1d2009-07-14 16:15:201030 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1031 // Let's cancel them.
1032 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]a6c59f62009-07-29 16:33:331033 ASSERT_FALSE(requests_[i]->handle()->is_initialized());
1034 requests_[i]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091035 }
1036
[email protected]f6d1d6eb2009-06-24 20:16:091037 // Let's wait for the rest to complete now.
[email protected]c9d6a1d2009-07-14 16:15:201038 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i) {
1039 EXPECT_EQ(OK, requests_[i]->WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331040 requests_[i]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091041 }
1042
[email protected]75439d3b2009-07-23 22:11:171043 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091044}
1045
1046// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051047TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531048 const size_t kMaxSockets = 5;
1049 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201050
[email protected]0b7648c2009-07-06 20:14:011051 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091052
[email protected]211d21722009-07-22 15:48:531053 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1054 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091055
1056 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531057 for (size_t i = 0; i < kNumberOfRequests; ++i)
1058 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091059
[email protected]211d21722009-07-22 15:48:531060 for (size_t i = 0; i < kNumberOfRequests; ++i)
1061 EXPECT_EQ(ERR_CONNECTION_FAILED, requests_[i]->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091062}
1063
[email protected]5fc08e32009-07-15 17:09:571064TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531065 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571066
1067 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1068
[email protected]a512f5982009-08-18 16:01:061069 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261070 int rv = InitHandle(req.handle(), "a", kDefaultPriority, &req, pool_, NULL);
[email protected]5fc08e32009-07-15 17:09:571071 EXPECT_EQ(ERR_IO_PENDING, rv);
1072
1073 // Cancel the active request.
[email protected]a6c59f62009-07-29 16:33:331074 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571075
[email protected]a796bcec2010-03-22 17:17:261076 rv = InitHandle(req.handle(), "a", kDefaultPriority, &req, pool_, NULL);
[email protected]5fc08e32009-07-15 17:09:571077 EXPECT_EQ(ERR_IO_PENDING, rv);
1078 EXPECT_EQ(OK, req.WaitForResult());
1079
[email protected]a6c59f62009-07-29 16:33:331080 EXPECT_FALSE(req.handle()->is_reused());
[email protected]75439d3b2009-07-23 22:11:171081 EXPECT_EQ(1U, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571082 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1083}
1084
[email protected]2b7523d2009-07-29 20:29:231085// Regression test for http://crbug.com/17985.
1086TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1087 const int kMaxSockets = 3;
1088 const int kMaxSocketsPerGroup = 2;
1089 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1090
[email protected]ac790b42009-12-02 04:31:311091 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231092
1093 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1094 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1095
1096 // This is going to be a pending request in an otherwise empty group.
1097 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1098
1099 // Reach the maximum socket limit.
1100 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1101
1102 // Create a stalled group with high priorities.
1103 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1104 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1105 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
1106
1107 // Release the first two sockets from "a", which will make room
1108 // for requests from "c". After that "a" will have no active sockets
1109 // and one pending request.
1110 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1111 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1112
1113 // Closing idle sockets should not get us into trouble, but in the bug
1114 // we were hitting a CHECK here.
1115 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
1116 pool_->CloseIdleSockets();
1117 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1118}
1119
[email protected]4d3b05d2010-01-27 21:27:291120TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531121 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571122
1123 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061124 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]9e743cd2010-03-16 07:03:531125 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]a796bcec2010-03-22 17:17:261126 int rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_, log.bound());
[email protected]5fc08e32009-07-15 17:09:571127 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331128 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:571129 EXPECT_EQ(OK, req.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331130 EXPECT_TRUE(req.handle()->is_initialized());
1131 EXPECT_TRUE(req.handle()->socket());
1132 req.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:301133
[email protected]7c28e9a2010-03-20 01:16:131134 EXPECT_EQ(5u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:461135 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:531136 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
1137 EXPECT_TRUE(LogContainsBeginEvent(
1138 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]e9002a92010-01-29 07:10:461139 EXPECT_TRUE(LogContainsEndEvent(
[email protected]9e743cd2010-03-16 07:03:531140 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]e9002a92010-01-29 07:10:461141 EXPECT_TRUE(LogContainsEndEvent(
[email protected]7c28e9a2010-03-20 01:16:131142 log.entries(), 4, 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]a796bcec2010-03-22 17:17:261153 InitHandle(req.handle(), "a", kDefaultPriority, &req, pool_,
1154 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]7c28e9a2010-03-20 01:16:131158 EXPECT_EQ(5u, 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(LogContainsEndEvent(
[email protected]7c28e9a2010-03-20 01:16:131166 log.entries(), 4, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571167}
1168
[email protected]4d3b05d2010-01-27 21:27:291169TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101170 // TODO(eroman): Add back the log expectations! Removed them because the
1171 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531172 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571173
1174 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061175 TestSocketRequest req(&request_order_, &completion_count_);
1176 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]5fc08e32009-07-15 17:09:571177
1178 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a796bcec2010-03-22 17:17:261179 InitHandle(req.handle(), "a", kDefaultPriority, &req, pool_,
1180 BoundNetLog()));
[email protected]9e743cd2010-03-16 07:03:531181 CapturingBoundNetLog log2(CapturingNetLog::kUnbounded);
[email protected]5fc08e32009-07-15 17:09:571182 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a796bcec2010-03-22 17:17:261183 InitHandle(req2.handle(), "a", kDefaultPriority, &req2, pool_,
1184 BoundNetLog()));
[email protected]5fc08e32009-07-15 17:09:571185
[email protected]a6c59f62009-07-29 16:33:331186 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571187
[email protected]fd7b7c92009-08-20 19:38:301188
1189 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301190
[email protected]5fc08e32009-07-15 17:09:571191 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331192 req2.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:301193
1194 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531195 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571196}
1197
[email protected]4d3b05d2010-01-27 21:27:291198TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341199 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1200
[email protected]17a0c6c2009-08-04 00:07:041201 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1202
[email protected]ac790b42009-12-02 04:31:311203 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1204 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1205 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1206 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341207
1208 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1209 requests_[2]->handle()->Reset();
1210 requests_[3]->handle()->Reset();
1211 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1212
1213 requests_[1]->handle()->Reset();
1214 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1215
1216 requests_[0]->handle()->Reset();
1217 EXPECT_EQ(kDefaultMaxSocketsPerGroup - 1, pool_->NumConnectJobsInGroup("a"));
1218}
1219
[email protected]5fc08e32009-07-15 17:09:571220// When requests and ConnectJobs are not coupled, the request will get serviced
1221// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291222TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531223 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571224
1225 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321226 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571227
[email protected]a512f5982009-08-18 16:01:061228 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261229 int rv = InitHandle(req1.handle(), "a", kDefaultPriority, &req1, pool_, NULL);
[email protected]5fc08e32009-07-15 17:09:571230 EXPECT_EQ(ERR_IO_PENDING, rv);
1231 EXPECT_EQ(OK, req1.WaitForResult());
1232
1233 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1234 // without a job.
1235 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1236
[email protected]a512f5982009-08-18 16:01:061237 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261238 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2, pool_, NULL);
[email protected]5fc08e32009-07-15 17:09:571239 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a512f5982009-08-18 16:01:061240 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261241 rv = InitHandle(req3.handle(), "a", kDefaultPriority, &req3, pool_, NULL);
[email protected]5fc08e32009-07-15 17:09:571242 EXPECT_EQ(ERR_IO_PENDING, rv);
1243
1244 // Both Requests 2 and 3 are pending. We release socket 1 which should
1245 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331246 req1.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571247 MessageLoop::current()->RunAllPending(); // Run the DoReleaseSocket()
[email protected]a6c59f62009-07-29 16:33:331248 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571249 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331250 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571251
1252 // Signal job 2, which should service request 3.
1253
1254 client_socket_factory_.SignalJobs();
1255 EXPECT_EQ(OK, req3.WaitForResult());
1256
1257 ASSERT_EQ(3U, request_order_.size());
1258 EXPECT_EQ(&req1, request_order_[0]);
1259 EXPECT_EQ(&req2, request_order_[1]);
1260 EXPECT_EQ(&req3, request_order_[2]);
1261 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1262}
1263
1264// The requests are not coupled to the jobs. So, the requests should finish in
1265// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:291266TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531267 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571268 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321269 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571270
[email protected]a512f5982009-08-18 16:01:061271 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261272 int rv = InitHandle(req1.handle(), "a", kDefaultPriority, &req1, pool_, NULL);
[email protected]5fc08e32009-07-15 17:09:571273 EXPECT_EQ(ERR_IO_PENDING, rv);
1274
[email protected]a512f5982009-08-18 16:01:061275 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261276 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2, pool_, NULL);
[email protected]5fc08e32009-07-15 17:09:571277 EXPECT_EQ(ERR_IO_PENDING, rv);
1278
1279 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321280 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571281
[email protected]a512f5982009-08-18 16:01:061282 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261283 rv = InitHandle(req3.handle(), "a", kDefaultPriority, &req3, pool_, NULL);
[email protected]5fc08e32009-07-15 17:09:571284 EXPECT_EQ(ERR_IO_PENDING, rv);
1285
1286 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1287 EXPECT_EQ(OK, req2.WaitForResult());
1288 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1289
1290 ASSERT_EQ(3U, request_order_.size());
1291 EXPECT_EQ(&req1, request_order_[0]);
1292 EXPECT_EQ(&req2, request_order_[1]);
1293 EXPECT_EQ(&req3, request_order_[2]);
1294}
1295
[email protected]4d3b05d2010-01-27 21:27:291296TEST_F(ClientSocketPoolBaseTest, DISABLED_LoadState) {
[email protected]211d21722009-07-22 15:48:531297 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571298 connect_job_factory_->set_job_type(
[email protected]b59ff372009-07-15 22:04:321299 TestConnectJob::kMockAdvancingLoadStateJob);
[email protected]5fc08e32009-07-15 17:09:571300
[email protected]a512f5982009-08-18 16:01:061301 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261302 int rv = InitHandle(req1.handle(), "a", kDefaultPriority, &req1, pool_, NULL);
[email protected]5fc08e32009-07-15 17:09:571303 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331304 EXPECT_EQ(LOAD_STATE_IDLE, req1.handle()->GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571305
1306 MessageLoop::current()->RunAllPending();
1307
[email protected]a512f5982009-08-18 16:01:061308 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261309 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2, pool_, NULL);
[email protected]5fc08e32009-07-15 17:09:571310 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331311 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, req1.handle()->GetLoadState());
1312 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, req2.handle()->GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571313}
1314
[email protected]4d3b05d2010-01-27 21:27:291315TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
[email protected]9bf28db2009-08-29 01:35:161316 CreatePoolWithIdleTimeouts(
1317 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1318 base::TimeDelta(), // Time out unused sockets immediately.
1319 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1320
1321 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1322
1323 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
1324
1325 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261326 int rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_, NULL);
[email protected]9bf28db2009-08-29 01:35:161327 EXPECT_EQ(ERR_IO_PENDING, rv);
1328 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
1329
1330 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261331 rv = InitHandle(req2.handle(), "a", LOWEST, &req2, pool_, NULL);
[email protected]9bf28db2009-08-29 01:35:161332 EXPECT_EQ(ERR_IO_PENDING, rv);
1333 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req2.handle()));
1334
1335 // Cancel one of the requests. Wait for the other, which will get the first
1336 // job. Release the socket. Run the loop again to make sure the second
1337 // socket is sitting idle and the first one is released (since ReleaseSocket()
1338 // just posts a DoReleaseSocket() task).
1339
1340 req.handle()->Reset();
1341 EXPECT_EQ(OK, req2.WaitForResult());
1342 req2.handle()->Reset();
[email protected]6b175382009-10-13 06:47:471343
1344 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1345 // actually become pending until 2ms after they have been created. In order
1346 // to flush all tasks, we need to wait so that we know there are no
1347 // soon-to-be-pending tasks waiting.
1348 PlatformThread::Sleep(10);
[email protected]9bf28db2009-08-29 01:35:161349 MessageLoop::current()->RunAllPending();
1350
1351 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:041352
[email protected]9bf28db2009-08-29 01:35:161353 // Invoke the idle socket cleanup check. Only one socket should be left, the
1354 // used socket. Request it to make sure that it's used.
1355
1356 pool_->CleanupTimedOutIdleSockets();
[email protected]9e743cd2010-03-16 07:03:531357 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]a796bcec2010-03-22 17:17:261358 rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_, log.bound());
[email protected]9bf28db2009-08-29 01:35:161359 EXPECT_EQ(OK, rv);
1360 EXPECT_TRUE(req.handle()->is_reused());
[email protected]fd4fe0b2010-02-08 23:02:151361 EXPECT_TRUE(LogContainsEntryWithType(
[email protected]9e743cd2010-03-16 07:03:531362 log.entries(), 1, NetLog::Entry::TYPE_STRING_LITERAL));
[email protected]9bf28db2009-08-29 01:35:161363}
1364
[email protected]2041cf342010-02-19 03:15:591365// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:161366// because of multiple releasing disconnected sockets.
1367TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
1368 CreatePoolWithIdleTimeouts(
1369 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1370 base::TimeDelta(), // Time out unused sockets immediately.
1371 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1372
1373 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1374
1375 // Startup 4 connect jobs. Two of them will be pending.
1376
1377 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261378 int rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_, NULL);
[email protected]4f2abec2010-02-03 18:10:161379 EXPECT_EQ(OK, rv);
1380
1381 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261382 rv = InitHandle(req2.handle(), "a", LOWEST, &req2, pool_, NULL);
[email protected]4f2abec2010-02-03 18:10:161383 EXPECT_EQ(OK, rv);
1384
1385 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261386 rv = InitHandle(req3.handle(), "a", LOWEST, &req3, pool_, NULL);
[email protected]4f2abec2010-02-03 18:10:161387 EXPECT_EQ(ERR_IO_PENDING, rv);
1388
1389 TestSocketRequest req4(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261390 rv = InitHandle(req4.handle(), "a", LOWEST, &req4, pool_, NULL);
[email protected]4f2abec2010-02-03 18:10:161391 EXPECT_EQ(ERR_IO_PENDING, rv);
1392
1393 // Release two disconnected sockets.
1394
1395 req.handle()->socket()->Disconnect();
1396 req.handle()->Reset();
1397 req2.handle()->socket()->Disconnect();
1398 req2.handle()->Reset();
1399
1400 EXPECT_EQ(OK, req3.WaitForResult());
1401 EXPECT_FALSE(req3.handle()->is_reused());
1402 EXPECT_EQ(OK, req4.WaitForResult());
1403 EXPECT_FALSE(req4.handle()->is_reused());
1404}
1405
[email protected]fd4fe0b2010-02-08 23:02:151406TEST_F(ClientSocketPoolBaseTest,
1407 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
1408 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1409
1410 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1411
1412 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1413 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1414 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1415 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1416
1417 EXPECT_EQ(OK, requests_[0]->WaitForResult());
1418 EXPECT_EQ(OK, requests_[1]->WaitForResult());
1419 EXPECT_EQ(2u, completion_count_);
1420
1421 // Releases one connection.
1422 EXPECT_TRUE(ReleaseOneConnection(NO_KEEP_ALIVE));
1423 EXPECT_EQ(OK, requests_[2]->WaitForResult());
1424
1425 EXPECT_TRUE(ReleaseOneConnection(NO_KEEP_ALIVE));
1426 EXPECT_EQ(OK, requests_[3]->WaitForResult());
1427 EXPECT_EQ(4u, completion_count_);
1428
1429 EXPECT_EQ(1, GetOrderOfRequest(1));
1430 EXPECT_EQ(2, GetOrderOfRequest(2));
1431 EXPECT_EQ(3, GetOrderOfRequest(3));
1432 EXPECT_EQ(4, GetOrderOfRequest(4));
1433
1434 // Make sure we test order of all requests made.
1435 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(5));
1436}
1437
[email protected]4f1e4982010-03-02 18:31:041438class TestReleasingSocketRequest : public CallbackRunner< Tuple1<int> > {
1439 public:
1440 explicit TestReleasingSocketRequest(TestClientSocketPool* pool)
1441 : pool_(pool) {}
1442
1443 ClientSocketHandle* handle() { return &handle_; }
1444
1445 int WaitForResult() {
1446 return callback_.WaitForResult();
1447 }
1448
1449 virtual void RunWithParams(const Tuple1<int>& params) {
1450 callback_.RunWithParams(params);
1451 handle_.Reset();
[email protected]a796bcec2010-03-22 17:17:261452 EXPECT_EQ(ERR_IO_PENDING, InitHandle(&handle2_, "a", kDefaultPriority,
1453 &callback2_, pool_, NULL));
[email protected]4f1e4982010-03-02 18:31:041454 }
1455
1456 private:
1457 TestClientSocketPool* const pool_;
1458 ClientSocketHandle handle_;
1459 ClientSocketHandle handle2_;
1460 TestCompletionCallback callback_;
1461 TestCompletionCallback callback2_;
1462};
1463
1464// This test covers the case where, within the same DoReleaseSocket() callback,
1465// we release the just acquired socket and start up a new request. See bug
1466// 36871 for details.
1467TEST_F(ClientSocketPoolBaseTest, ReleasedSocketReleasesToo) {
1468 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1469
1470 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1471
1472 // Complete one request and release the socket.
1473 ClientSocketHandle handle;
1474 TestCompletionCallback callback;
[email protected]a796bcec2010-03-22 17:17:261475 EXPECT_EQ(OK, InitHandle(&handle, "a", kDefaultPriority, &callback, pool_,
1476 NULL));
[email protected]4f1e4982010-03-02 18:31:041477 handle.Reset();
[email protected]6b624c62010-03-14 08:37:321478
[email protected]4f1e4982010-03-02 18:31:041479 // Before the DoReleaseSocket() task has run, start up a
1480 // TestReleasingSocketRequest. This one will be ERR_IO_PENDING since
1481 // num_releasing_sockets > 0 and there was no idle socket to use yet.
1482 TestReleasingSocketRequest request(pool_.get());
[email protected]a796bcec2010-03-22 17:17:261483 EXPECT_EQ(ERR_IO_PENDING, InitHandle(request.handle(), "a", kDefaultPriority,
1484 &request, pool_, NULL));
[email protected]4f1e4982010-03-02 18:31:041485
1486 EXPECT_EQ(OK, request.WaitForResult());
1487}
1488
[email protected]f6d1d6eb2009-06-24 20:16:091489} // namespace
1490
1491} // namespace net