blob: 2b25785fc594fdd0e78fbbb6d80cc8a45edf42f2 [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]9b3ef462010-04-08 01:48:31285 connect_job_factory) {}
[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
[email protected]42df4e8e2010-04-13 22:02:56575 ReleaseAllConnections(KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53576
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
[email protected]42df4e8e2010-04-13 22:02:56611 ReleaseAllConnections(KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53612
613 EXPECT_EQ(static_cast<int>(requests_.size()),
614 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17615 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53616
617 EXPECT_EQ(1, GetOrderOfRequest(1));
618 EXPECT_EQ(2, GetOrderOfRequest(2));
619 EXPECT_EQ(3, GetOrderOfRequest(3));
620 EXPECT_EQ(4, GetOrderOfRequest(4));
621 EXPECT_EQ(5, GetOrderOfRequest(5));
[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
[email protected]42df4e8e2010-04-13 22:02:56642 ReleaseAllConnections(KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53643
[email protected]42df4e8e2010-04-13 22:02:56644 // 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
[email protected]42df4e8e2010-04-13 22:02:56680 ReleaseAllConnections(KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53681
[email protected]42df4e8e2010-04-13 22:02:56682 // We're re-using one socket for group "a", and one for "b".
683 EXPECT_EQ(static_cast<int>(requests_.size()) - 2,
[email protected]211d21722009-07-22 15:48:53684 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
[email protected]42df4e8e2010-04-13 22:02:56728 ReleaseAllConnections(KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53729
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.
[email protected]42df4e8e2010-04-13 22:02:56769 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
[email protected]211d21722009-07-22 15:48:53770 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".
[email protected]42df4e8e2010-04-13 22:02:56784 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
[email protected]211d21722009-07-22 15:48:53785 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
786
787 // Now every group's pending queue should be empty again.
[email protected]42df4e8e2010-04-13 22:02:56788 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
[email protected]211d21722009-07-22 15:48:53789 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
790
[email protected]42df4e8e2010-04-13 22:02:56791 ReleaseAllConnections(KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53792 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
793}
794
[email protected]6427fe22010-04-16 22:27:41795TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
796 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
797 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
798
799 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
800 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
801 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
802 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
803
804 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
805
806 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
807
808 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", kDefaultPriority));
809 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
810
811 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
812
813 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
814 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
815 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
816 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
817 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
818 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
819 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
820}
821
[email protected]ab838892009-06-30 18:49:05822TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:53823 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09824
[email protected]c9d6a1d2009-07-14 16:15:20825 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
826 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:31827 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
828 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
829 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
830 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
831 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:09832
[email protected]c9d6a1d2009-07-14 16:15:20833 ReleaseAllConnections(KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09834
[email protected]c9d6a1d2009-07-14 16:15:20835 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
836 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17837 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09838
[email protected]c9d6a1d2009-07-14 16:15:20839 EXPECT_EQ(1, GetOrderOfRequest(1));
840 EXPECT_EQ(2, GetOrderOfRequest(2));
841 EXPECT_EQ(6, GetOrderOfRequest(3));
842 EXPECT_EQ(4, GetOrderOfRequest(4));
843 EXPECT_EQ(3, GetOrderOfRequest(5));
844 EXPECT_EQ(5, GetOrderOfRequest(6));
845 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17846
847 // Make sure we test order of all requests made.
848 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:09849}
850
[email protected]ab838892009-06-30 18:49:05851TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:53852 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09853
[email protected]c9d6a1d2009-07-14 16:15:20854 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
855 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:31856 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
857 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
858 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
859 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
860 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:09861
[email protected]c9d6a1d2009-07-14 16:15:20862 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09863
[email protected]c9d6a1d2009-07-14 16:15:20864 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i)
865 EXPECT_EQ(OK, requests_[i]->WaitForResult());
866
867 EXPECT_EQ(static_cast<int>(requests_.size()),
868 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17869 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09870}
871
872// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:05873// The pending connect job will be cancelled and should not call back into
874// ClientSocketPoolBase.
875TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:53876 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20877
[email protected]ab838892009-06-30 18:49:05878 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:06879 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]ab838892009-06-30 18:49:05880 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a796bcec2010-03-22 17:17:26881 InitHandle(req.handle(), "a", kDefaultPriority, &req, pool_, NULL));
[email protected]a6c59f62009-07-29 16:33:33882 req.handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:09883}
884
[email protected]ab838892009-06-30 18:49:05885TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:53886 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20887
[email protected]ab838892009-06-30 18:49:05888 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:06889 ClientSocketHandle handle;
[email protected]f6d1d6eb2009-06-24 20:16:09890 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06891 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09892
[email protected]ab838892009-06-30 18:49:05893 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a796bcec2010-03-22 17:17:26894 InitHandle(&handle, "a", kDefaultPriority, &callback, pool_, NULL));
[email protected]f6d1d6eb2009-06-24 20:16:09895
896 handle.Reset();
897
898 TestCompletionCallback callback2;
[email protected]a796bcec2010-03-22 17:17:26899 EXPECT_EQ(ERR_IO_PENDING, InitHandle(&handle, "a", kDefaultPriority,
900 &callback2, pool_, NULL));
[email protected]f6d1d6eb2009-06-24 20:16:09901
902 EXPECT_EQ(OK, callback2.WaitForResult());
903 EXPECT_FALSE(callback.have_result());
904
905 handle.Reset();
906}
907
[email protected]ab838892009-06-30 18:49:05908TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:53909 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09910
[email protected]c9d6a1d2009-07-14 16:15:20911 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
912 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:31913 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
914 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
915 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
916 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
917 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:09918
919 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:20920 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]a6c59f62009-07-29 16:33:33921 EXPECT_FALSE(requests_[index_to_cancel]->handle()->is_initialized());
922 requests_[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:09923
[email protected]c9d6a1d2009-07-14 16:15:20924 ReleaseAllConnections(KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09925
[email protected]c9d6a1d2009-07-14 16:15:20926 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
927 client_socket_factory_.allocation_count());
928 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup - 1,
[email protected]75439d3b2009-07-23 22:11:17929 completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09930
[email protected]c9d6a1d2009-07-14 16:15:20931 EXPECT_EQ(1, GetOrderOfRequest(1));
932 EXPECT_EQ(2, GetOrderOfRequest(2));
933 EXPECT_EQ(5, GetOrderOfRequest(3));
934 EXPECT_EQ(3, GetOrderOfRequest(4));
935 EXPECT_EQ(kRequestNotFound, GetOrderOfRequest(5)); // Canceled request.
936 EXPECT_EQ(4, GetOrderOfRequest(6));
937 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17938
939 // Make sure we test order of all requests made.
940 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:09941}
942
943class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
944 public:
[email protected]2ab05b52009-07-01 23:57:58945 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:24946 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:58947 TestConnectJobFactory* test_connect_job_factory,
948 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:09949 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:06950 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:58951 within_callback_(false),
952 test_connect_job_factory_(test_connect_job_factory),
953 next_job_type_(next_job_type) {}
[email protected]f6d1d6eb2009-06-24 20:16:09954
955 virtual void RunWithParams(const Tuple1<int>& params) {
956 callback_.RunWithParams(params);
957 ASSERT_EQ(OK, params.a);
958
959 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:58960 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]5edbf8d2010-01-13 18:44:11961
962 // Don't allow reuse of the socket. Disconnect it and then release it and
963 // run through the MessageLoop once to get it completely released.
964 handle_->socket()->Disconnect();
[email protected]f6d1d6eb2009-06-24 20:16:09965 handle_->Reset();
[email protected]5edbf8d2010-01-13 18:44:11966 {
967 MessageLoop::ScopedNestableTaskAllower nestable(
968 MessageLoop::current());
969 MessageLoop::current()->RunAllPending();
970 }
[email protected]f6d1d6eb2009-06-24 20:16:09971 within_callback_ = true;
[email protected]6b175382009-10-13 06:47:47972 TestCompletionCallback next_job_callback;
[email protected]a796bcec2010-03-22 17:17:26973 int rv = InitHandle(handle_, "a", kDefaultPriority, &next_job_callback,
974 pool_, NULL);
[email protected]2ab05b52009-07-01 23:57:58975 switch (next_job_type_) {
976 case TestConnectJob::kMockJob:
977 EXPECT_EQ(OK, rv);
978 break;
979 case TestConnectJob::kMockPendingJob:
980 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:47981
982 // For pending jobs, wait for new socket to be created. This makes
983 // sure there are no more pending operations nor any unclosed sockets
984 // when the test finishes.
985 // We need to give it a little bit of time to run, so that all the
986 // operations that happen on timers (e.g. cleanup of idle
987 // connections) can execute.
[email protected]5edbf8d2010-01-13 18:44:11988 {
989 MessageLoop::ScopedNestableTaskAllower nestable(
990 MessageLoop::current());
991 PlatformThread::Sleep(10);
992 EXPECT_EQ(OK, next_job_callback.WaitForResult());
993 }
[email protected]2ab05b52009-07-01 23:57:58994 break;
995 default:
996 FAIL() << "Unexpected job type: " << next_job_type_;
997 break;
998 }
[email protected]f6d1d6eb2009-06-24 20:16:09999 }
1000 }
1001
1002 int WaitForResult() {
1003 return callback_.WaitForResult();
1004 }
1005
1006 private:
1007 ClientSocketHandle* const handle_;
[email protected]a937a06d2009-08-19 21:19:241008 const scoped_refptr<TestClientSocketPool> pool_;
[email protected]f6d1d6eb2009-06-24 20:16:091009 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:581010 TestConnectJobFactory* const test_connect_job_factory_;
1011 TestConnectJob::JobType next_job_type_;
[email protected]f6d1d6eb2009-06-24 20:16:091012 TestCompletionCallback callback_;
1013};
1014
[email protected]2ab05b52009-07-01 23:57:581015TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531016 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201017
[email protected]0b7648c2009-07-06 20:14:011018 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061019 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581020 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061021 &handle, pool_.get(), connect_job_factory_,
1022 TestConnectJob::kMockPendingJob);
[email protected]a796bcec2010-03-22 17:17:261023 int rv = InitHandle(&handle, "a", kDefaultPriority, &callback, pool_, NULL);
[email protected]f6d1d6eb2009-06-24 20:16:091024 ASSERT_EQ(ERR_IO_PENDING, rv);
1025
1026 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581027}
[email protected]f6d1d6eb2009-06-24 20:16:091028
[email protected]2ab05b52009-07-01 23:57:581029TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531030 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201031
[email protected]0b7648c2009-07-06 20:14:011032 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061033 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581034 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061035 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]a796bcec2010-03-22 17:17:261036 int rv = InitHandle(&handle, "a", kDefaultPriority, &callback, pool_, NULL);
[email protected]2ab05b52009-07-01 23:57:581037 ASSERT_EQ(ERR_IO_PENDING, rv);
1038
1039 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091040}
1041
1042// Make sure that pending requests get serviced after active requests get
1043// cancelled.
[email protected]ab838892009-06-30 18:49:051044TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531045 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201046
[email protected]0b7648c2009-07-06 20:14:011047 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091048
[email protected]c9d6a1d2009-07-14 16:15:201049 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1050 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1051 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1052 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1053 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1054 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1055 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091056
[email protected]c9d6a1d2009-07-14 16:15:201057 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1058 // Let's cancel them.
1059 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]a6c59f62009-07-29 16:33:331060 ASSERT_FALSE(requests_[i]->handle()->is_initialized());
1061 requests_[i]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091062 }
1063
[email protected]f6d1d6eb2009-06-24 20:16:091064 // Let's wait for the rest to complete now.
[email protected]c9d6a1d2009-07-14 16:15:201065 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i) {
1066 EXPECT_EQ(OK, requests_[i]->WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331067 requests_[i]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091068 }
1069
[email protected]75439d3b2009-07-23 22:11:171070 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091071}
1072
1073// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051074TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531075 const size_t kMaxSockets = 5;
1076 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201077
[email protected]0b7648c2009-07-06 20:14:011078 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091079
[email protected]211d21722009-07-22 15:48:531080 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1081 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091082
1083 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531084 for (size_t i = 0; i < kNumberOfRequests; ++i)
1085 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091086
[email protected]211d21722009-07-22 15:48:531087 for (size_t i = 0; i < kNumberOfRequests; ++i)
1088 EXPECT_EQ(ERR_CONNECTION_FAILED, requests_[i]->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091089}
1090
[email protected]5fc08e32009-07-15 17:09:571091TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531092 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571093
1094 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1095
[email protected]a512f5982009-08-18 16:01:061096 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261097 int rv = InitHandle(req.handle(), "a", kDefaultPriority, &req, pool_, NULL);
[email protected]5fc08e32009-07-15 17:09:571098 EXPECT_EQ(ERR_IO_PENDING, rv);
1099
1100 // Cancel the active request.
[email protected]a6c59f62009-07-29 16:33:331101 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571102
[email protected]a796bcec2010-03-22 17:17:261103 rv = InitHandle(req.handle(), "a", kDefaultPriority, &req, pool_, NULL);
[email protected]5fc08e32009-07-15 17:09:571104 EXPECT_EQ(ERR_IO_PENDING, rv);
1105 EXPECT_EQ(OK, req.WaitForResult());
1106
[email protected]a6c59f62009-07-29 16:33:331107 EXPECT_FALSE(req.handle()->is_reused());
[email protected]75439d3b2009-07-23 22:11:171108 EXPECT_EQ(1U, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571109 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1110}
1111
[email protected]2b7523d2009-07-29 20:29:231112// Regression test for http://crbug.com/17985.
1113TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1114 const int kMaxSockets = 3;
1115 const int kMaxSocketsPerGroup = 2;
1116 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1117
[email protected]ac790b42009-12-02 04:31:311118 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231119
1120 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1121 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1122
1123 // This is going to be a pending request in an otherwise empty group.
1124 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1125
1126 // Reach the maximum socket limit.
1127 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1128
1129 // Create a stalled group with high priorities.
1130 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1131 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1132 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
1133
1134 // Release the first two sockets from "a", which will make room
1135 // for requests from "c". After that "a" will have no active sockets
1136 // and one pending request.
1137 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1138 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1139
1140 // Closing idle sockets should not get us into trouble, but in the bug
1141 // we were hitting a CHECK here.
[email protected]42df4e8e2010-04-13 22:02:561142 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
[email protected]d43002e2010-04-07 21:29:491143 pool_->CloseIdleSockets();
[email protected]42df4e8e2010-04-13 22:02:561144 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]2b7523d2009-07-29 20:29:231145}
1146
[email protected]4d3b05d2010-01-27 21:27:291147TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531148 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571149
1150 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061151 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]9e743cd2010-03-16 07:03:531152 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]a796bcec2010-03-22 17:17:261153 int rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_, log.bound());
[email protected]5fc08e32009-07-15 17:09:571154 EXPECT_EQ(ERR_IO_PENDING, rv);
[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(OK, req.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331157 EXPECT_TRUE(req.handle()->is_initialized());
1158 EXPECT_TRUE(req.handle()->socket());
1159 req.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:301160
[email protected]7c28e9a2010-03-20 01:16:131161 EXPECT_EQ(5u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:461162 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:531163 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
1164 EXPECT_TRUE(LogContainsBeginEvent(
1165 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]e9002a92010-01-29 07:10:461166 EXPECT_TRUE(LogContainsEndEvent(
[email protected]9e743cd2010-03-16 07:03:531167 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]e9002a92010-01-29 07:10:461168 EXPECT_TRUE(LogContainsEndEvent(
[email protected]7c28e9a2010-03-20 01:16:131169 log.entries(), 4, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571170}
1171
[email protected]4d3b05d2010-01-27 21:27:291172TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571173 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531174 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571175
1176 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]a512f5982009-08-18 16:01:061177 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]9e743cd2010-03-16 07:03:531178 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]5fc08e32009-07-15 17:09:571179 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a796bcec2010-03-22 17:17:261180 InitHandle(req.handle(), "a", kDefaultPriority, &req, pool_,
1181 log.bound()));
[email protected]a6c59f62009-07-29 16:33:331182 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:571183 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:301184
[email protected]7c28e9a2010-03-20 01:16:131185 EXPECT_EQ(5u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:461186 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:531187 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
1188 EXPECT_TRUE(LogContainsBeginEvent(
1189 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]e9002a92010-01-29 07:10:461190 EXPECT_TRUE(LogContainsEndEvent(
[email protected]9e743cd2010-03-16 07:03:531191 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]6b624c62010-03-14 08:37:321192 EXPECT_TRUE(LogContainsEndEvent(
[email protected]7c28e9a2010-03-20 01:16:131193 log.entries(), 4, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571194}
1195
[email protected]4d3b05d2010-01-27 21:27:291196TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101197 // TODO(eroman): Add back the log expectations! Removed them because the
1198 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531199 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571200
1201 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061202 TestSocketRequest req(&request_order_, &completion_count_);
1203 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]5fc08e32009-07-15 17:09:571204
1205 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a796bcec2010-03-22 17:17:261206 InitHandle(req.handle(), "a", kDefaultPriority, &req, pool_,
1207 BoundNetLog()));
[email protected]9e743cd2010-03-16 07:03:531208 CapturingBoundNetLog log2(CapturingNetLog::kUnbounded);
[email protected]5fc08e32009-07-15 17:09:571209 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a796bcec2010-03-22 17:17:261210 InitHandle(req2.handle(), "a", kDefaultPriority, &req2, pool_,
1211 BoundNetLog()));
[email protected]5fc08e32009-07-15 17:09:571212
[email protected]a6c59f62009-07-29 16:33:331213 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571214
[email protected]fd7b7c92009-08-20 19:38:301215
1216 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301217
[email protected]5fc08e32009-07-15 17:09:571218 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331219 req2.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:301220
1221 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531222 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571223}
1224
[email protected]4d3b05d2010-01-27 21:27:291225TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341226 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1227
[email protected]17a0c6c2009-08-04 00:07:041228 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1229
[email protected]ac790b42009-12-02 04:31:311230 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1231 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1232 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1233 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341234
1235 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1236 requests_[2]->handle()->Reset();
1237 requests_[3]->handle()->Reset();
1238 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1239
1240 requests_[1]->handle()->Reset();
1241 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1242
1243 requests_[0]->handle()->Reset();
1244 EXPECT_EQ(kDefaultMaxSocketsPerGroup - 1, pool_->NumConnectJobsInGroup("a"));
1245}
1246
[email protected]5fc08e32009-07-15 17:09:571247// When requests and ConnectJobs are not coupled, the request will get serviced
1248// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291249TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531250 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571251
1252 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321253 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571254
[email protected]a512f5982009-08-18 16:01:061255 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261256 int rv = InitHandle(req1.handle(), "a", kDefaultPriority, &req1, pool_, NULL);
[email protected]5fc08e32009-07-15 17:09:571257 EXPECT_EQ(ERR_IO_PENDING, rv);
1258 EXPECT_EQ(OK, req1.WaitForResult());
1259
1260 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1261 // without a job.
1262 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1263
[email protected]a512f5982009-08-18 16:01:061264 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261265 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2, pool_, NULL);
[email protected]5fc08e32009-07-15 17:09:571266 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a512f5982009-08-18 16:01:061267 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261268 rv = InitHandle(req3.handle(), "a", kDefaultPriority, &req3, pool_, NULL);
[email protected]5fc08e32009-07-15 17:09:571269 EXPECT_EQ(ERR_IO_PENDING, rv);
1270
1271 // Both Requests 2 and 3 are pending. We release socket 1 which should
1272 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331273 req1.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571274 MessageLoop::current()->RunAllPending(); // Run the DoReleaseSocket()
[email protected]a6c59f62009-07-29 16:33:331275 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571276 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331277 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571278
1279 // Signal job 2, which should service request 3.
1280
1281 client_socket_factory_.SignalJobs();
1282 EXPECT_EQ(OK, req3.WaitForResult());
1283
1284 ASSERT_EQ(3U, request_order_.size());
1285 EXPECT_EQ(&req1, request_order_[0]);
1286 EXPECT_EQ(&req2, request_order_[1]);
1287 EXPECT_EQ(&req3, request_order_[2]);
1288 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1289}
1290
1291// The requests are not coupled to the jobs. So, the requests should finish in
1292// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:291293TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531294 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571295 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321296 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571297
[email protected]a512f5982009-08-18 16:01:061298 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261299 int rv = InitHandle(req1.handle(), "a", kDefaultPriority, &req1, pool_, NULL);
[email protected]5fc08e32009-07-15 17:09:571300 EXPECT_EQ(ERR_IO_PENDING, rv);
1301
[email protected]a512f5982009-08-18 16:01:061302 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261303 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2, pool_, NULL);
[email protected]5fc08e32009-07-15 17:09:571304 EXPECT_EQ(ERR_IO_PENDING, rv);
1305
1306 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321307 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571308
[email protected]a512f5982009-08-18 16:01:061309 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261310 rv = InitHandle(req3.handle(), "a", kDefaultPriority, &req3, pool_, NULL);
[email protected]5fc08e32009-07-15 17:09:571311 EXPECT_EQ(ERR_IO_PENDING, rv);
1312
1313 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1314 EXPECT_EQ(OK, req2.WaitForResult());
1315 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1316
1317 ASSERT_EQ(3U, request_order_.size());
1318 EXPECT_EQ(&req1, request_order_[0]);
1319 EXPECT_EQ(&req2, request_order_[1]);
1320 EXPECT_EQ(&req3, request_order_[2]);
1321}
1322
[email protected]4d3b05d2010-01-27 21:27:291323TEST_F(ClientSocketPoolBaseTest, DISABLED_LoadState) {
[email protected]211d21722009-07-22 15:48:531324 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571325 connect_job_factory_->set_job_type(
[email protected]b59ff372009-07-15 22:04:321326 TestConnectJob::kMockAdvancingLoadStateJob);
[email protected]5fc08e32009-07-15 17:09:571327
[email protected]a512f5982009-08-18 16:01:061328 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261329 int rv = InitHandle(req1.handle(), "a", kDefaultPriority, &req1, pool_, NULL);
[email protected]5fc08e32009-07-15 17:09:571330 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331331 EXPECT_EQ(LOAD_STATE_IDLE, req1.handle()->GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571332
1333 MessageLoop::current()->RunAllPending();
1334
[email protected]a512f5982009-08-18 16:01:061335 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261336 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2, pool_, NULL);
[email protected]5fc08e32009-07-15 17:09:571337 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331338 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, req1.handle()->GetLoadState());
1339 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, req2.handle()->GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571340}
1341
[email protected]4d3b05d2010-01-27 21:27:291342TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
[email protected]9bf28db2009-08-29 01:35:161343 CreatePoolWithIdleTimeouts(
1344 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1345 base::TimeDelta(), // Time out unused sockets immediately.
1346 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1347
1348 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1349
1350 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
1351
1352 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261353 int rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_, NULL);
[email protected]9bf28db2009-08-29 01:35:161354 EXPECT_EQ(ERR_IO_PENDING, rv);
1355 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
1356
1357 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261358 rv = InitHandle(req2.handle(), "a", LOWEST, &req2, pool_, NULL);
[email protected]9bf28db2009-08-29 01:35:161359 EXPECT_EQ(ERR_IO_PENDING, rv);
1360 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req2.handle()));
1361
1362 // Cancel one of the requests. Wait for the other, which will get the first
1363 // job. Release the socket. Run the loop again to make sure the second
1364 // socket is sitting idle and the first one is released (since ReleaseSocket()
1365 // just posts a DoReleaseSocket() task).
1366
1367 req.handle()->Reset();
1368 EXPECT_EQ(OK, req2.WaitForResult());
1369 req2.handle()->Reset();
[email protected]6b175382009-10-13 06:47:471370
1371 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1372 // actually become pending until 2ms after they have been created. In order
1373 // to flush all tasks, we need to wait so that we know there are no
1374 // soon-to-be-pending tasks waiting.
1375 PlatformThread::Sleep(10);
[email protected]9bf28db2009-08-29 01:35:161376 MessageLoop::current()->RunAllPending();
1377
1378 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:041379
[email protected]9bf28db2009-08-29 01:35:161380 // Invoke the idle socket cleanup check. Only one socket should be left, the
1381 // used socket. Request it to make sure that it's used.
1382
1383 pool_->CleanupTimedOutIdleSockets();
[email protected]9e743cd2010-03-16 07:03:531384 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]a796bcec2010-03-22 17:17:261385 rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_, log.bound());
[email protected]9bf28db2009-08-29 01:35:161386 EXPECT_EQ(OK, rv);
1387 EXPECT_TRUE(req.handle()->is_reused());
[email protected]fd4fe0b2010-02-08 23:02:151388 EXPECT_TRUE(LogContainsEntryWithType(
[email protected]1f0e32b2010-04-09 04:34:471389 log.entries(), 1, NetLog::TYPE_TODO_STRING_LITERAL));
[email protected]9bf28db2009-08-29 01:35:161390}
1391
[email protected]2041cf342010-02-19 03:15:591392// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:161393// because of multiple releasing disconnected sockets.
1394TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
1395 CreatePoolWithIdleTimeouts(
1396 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1397 base::TimeDelta(), // Time out unused sockets immediately.
1398 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1399
1400 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1401
1402 // Startup 4 connect jobs. Two of them will be pending.
1403
1404 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261405 int rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_, NULL);
[email protected]4f2abec2010-02-03 18:10:161406 EXPECT_EQ(OK, rv);
1407
1408 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261409 rv = InitHandle(req2.handle(), "a", LOWEST, &req2, pool_, NULL);
[email protected]4f2abec2010-02-03 18:10:161410 EXPECT_EQ(OK, rv);
1411
1412 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261413 rv = InitHandle(req3.handle(), "a", LOWEST, &req3, pool_, NULL);
[email protected]4f2abec2010-02-03 18:10:161414 EXPECT_EQ(ERR_IO_PENDING, rv);
1415
1416 TestSocketRequest req4(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261417 rv = InitHandle(req4.handle(), "a", LOWEST, &req4, pool_, NULL);
[email protected]4f2abec2010-02-03 18:10:161418 EXPECT_EQ(ERR_IO_PENDING, rv);
1419
1420 // Release two disconnected sockets.
1421
1422 req.handle()->socket()->Disconnect();
1423 req.handle()->Reset();
1424 req2.handle()->socket()->Disconnect();
1425 req2.handle()->Reset();
1426
1427 EXPECT_EQ(OK, req3.WaitForResult());
1428 EXPECT_FALSE(req3.handle()->is_reused());
1429 EXPECT_EQ(OK, req4.WaitForResult());
1430 EXPECT_FALSE(req4.handle()->is_reused());
1431}
1432
[email protected]fd4fe0b2010-02-08 23:02:151433TEST_F(ClientSocketPoolBaseTest,
1434 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
1435 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1436
1437 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1438
1439 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1440 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1441 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1442 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1443
1444 EXPECT_EQ(OK, requests_[0]->WaitForResult());
1445 EXPECT_EQ(OK, requests_[1]->WaitForResult());
1446 EXPECT_EQ(2u, completion_count_);
1447
1448 // Releases one connection.
1449 EXPECT_TRUE(ReleaseOneConnection(NO_KEEP_ALIVE));
1450 EXPECT_EQ(OK, requests_[2]->WaitForResult());
1451
1452 EXPECT_TRUE(ReleaseOneConnection(NO_KEEP_ALIVE));
1453 EXPECT_EQ(OK, requests_[3]->WaitForResult());
1454 EXPECT_EQ(4u, completion_count_);
1455
1456 EXPECT_EQ(1, GetOrderOfRequest(1));
1457 EXPECT_EQ(2, GetOrderOfRequest(2));
1458 EXPECT_EQ(3, GetOrderOfRequest(3));
1459 EXPECT_EQ(4, GetOrderOfRequest(4));
1460
1461 // Make sure we test order of all requests made.
1462 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(5));
1463}
1464
[email protected]4f1e4982010-03-02 18:31:041465class TestReleasingSocketRequest : public CallbackRunner< Tuple1<int> > {
1466 public:
1467 explicit TestReleasingSocketRequest(TestClientSocketPool* pool)
1468 : pool_(pool) {}
1469
1470 ClientSocketHandle* handle() { return &handle_; }
1471
1472 int WaitForResult() {
1473 return callback_.WaitForResult();
1474 }
1475
1476 virtual void RunWithParams(const Tuple1<int>& params) {
1477 callback_.RunWithParams(params);
1478 handle_.Reset();
[email protected]a796bcec2010-03-22 17:17:261479 EXPECT_EQ(ERR_IO_PENDING, InitHandle(&handle2_, "a", kDefaultPriority,
1480 &callback2_, pool_, NULL));
[email protected]4f1e4982010-03-02 18:31:041481 }
1482
1483 private:
1484 TestClientSocketPool* const pool_;
1485 ClientSocketHandle handle_;
1486 ClientSocketHandle handle2_;
1487 TestCompletionCallback callback_;
1488 TestCompletionCallback callback2_;
1489};
1490
1491// This test covers the case where, within the same DoReleaseSocket() callback,
1492// we release the just acquired socket and start up a new request. See bug
1493// 36871 for details.
1494TEST_F(ClientSocketPoolBaseTest, ReleasedSocketReleasesToo) {
1495 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1496
1497 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1498
1499 // Complete one request and release the socket.
1500 ClientSocketHandle handle;
1501 TestCompletionCallback callback;
[email protected]a796bcec2010-03-22 17:17:261502 EXPECT_EQ(OK, InitHandle(&handle, "a", kDefaultPriority, &callback, pool_,
1503 NULL));
[email protected]4f1e4982010-03-02 18:31:041504 handle.Reset();
[email protected]6b624c62010-03-14 08:37:321505
[email protected]4f1e4982010-03-02 18:31:041506 // Before the DoReleaseSocket() task has run, start up a
1507 // TestReleasingSocketRequest. This one will be ERR_IO_PENDING since
1508 // num_releasing_sockets > 0 and there was no idle socket to use yet.
1509 TestReleasingSocketRequest request(pool_.get());
[email protected]a796bcec2010-03-22 17:17:261510 EXPECT_EQ(ERR_IO_PENDING, InitHandle(request.handle(), "a", kDefaultPriority,
1511 &request, pool_, NULL));
[email protected]4f1e4982010-03-02 18:31:041512
1513 EXPECT_EQ(OK, request.WaitForResult());
1514}
1515
[email protected]f6d1d6eb2009-06-24 20:16:091516} // namespace
1517
1518} // namespace net