blob: d2676e814672d45abef1cf563ff19b1637562e20 [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]d43002e2010-04-07 21:29:4912#include "base/string_util.h"
[email protected]9e743cd2010-03-16 07:03:5313#include "net/base/net_log.h"
14#include "net/base/net_log_unittest.h"
[email protected]f6d1d6eb2009-06-24 20:16:0915#include "net/base/net_errors.h"
[email protected]ac790b42009-12-02 04:31:3116#include "net/base/request_priority.h"
[email protected]f6d1d6eb2009-06-24 20:16:0917#include "net/base/test_completion_callback.h"
18#include "net/socket/client_socket.h"
19#include "net/socket/client_socket_factory.h"
20#include "net/socket/client_socket_handle.h"
[email protected]75439d3b2009-07-23 22:11:1721#include "net/socket/socket_test_util.h"
[email protected]f6d1d6eb2009-06-24 20:16:0922#include "testing/gtest/include/gtest/gtest.h"
23
24namespace net {
25
26namespace {
27
[email protected]211d21722009-07-22 15:48:5328const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2029const int kDefaultMaxSocketsPerGroup = 2;
[email protected]ac790b42009-12-02 04:31:3130const net::RequestPriority kDefaultPriority = MEDIUM;
[email protected]0b7648c2009-07-06 20:14:0131
[email protected]7fc5b09a2010-02-27 00:07:3832typedef const void* TestSocketParams;
33typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
[email protected]d80a4322009-08-14 07:07:4934
[email protected]f6d1d6eb2009-06-24 20:16:0935class MockClientSocket : public ClientSocket {
36 public:
37 MockClientSocket() : connected_(false) {}
38
[email protected]ab838892009-06-30 18:49:0539 // Socket methods:
40 virtual int Read(
41 IOBuffer* /* buf */, int /* len */, CompletionCallback* /* callback */) {
42 return ERR_UNEXPECTED;
43 }
44
45 virtual int Write(
46 IOBuffer* /* buf */, int /* len */, CompletionCallback* /* callback */) {
47 return ERR_UNEXPECTED;
48 }
[email protected]d3f66572009-09-09 22:38:0449 virtual bool SetReceiveBufferSize(int32 size) { return true; };
50 virtual bool SetSendBufferSize(int32 size) { return true; };
[email protected]ab838892009-06-30 18:49:0551
[email protected]f6d1d6eb2009-06-24 20:16:0952 // ClientSocket methods:
[email protected]ab838892009-06-30 18:49:0553
[email protected]9e743cd2010-03-16 07:03:5354 virtual int Connect(CompletionCallback* callback, const BoundNetLog& net_log) {
[email protected]f6d1d6eb2009-06-24 20:16:0955 connected_ = true;
56 return OK;
57 }
[email protected]f6d1d6eb2009-06-24 20:16:0958
[email protected]ab838892009-06-30 18:49:0559 virtual void Disconnect() { connected_ = false; }
60 virtual bool IsConnected() const { return connected_; }
61 virtual bool IsConnectedAndIdle() const { return connected_; }
[email protected]0b7648c2009-07-06 20:14:0162
[email protected]ac9eec62010-02-20 18:50:3863 virtual int GetPeerAddress(AddressList* /* address */) const {
[email protected]9f864b32010-01-20 15:01:1664 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:0965 }
[email protected]f6d1d6eb2009-06-24 20:16:0966
67 private:
68 bool connected_;
[email protected]f6d1d6eb2009-06-24 20:16:0969
[email protected]ab838892009-06-30 18:49:0570 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:0971};
72
[email protected]5fc08e32009-07-15 17:09:5773class TestConnectJob;
74
[email protected]f6d1d6eb2009-06-24 20:16:0975class MockClientSocketFactory : public ClientSocketFactory {
76 public:
[email protected]ab838892009-06-30 18:49:0577 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:0978
79 virtual ClientSocket* CreateTCPClientSocket(const AddressList& addresses) {
80 allocation_count_++;
[email protected]ab838892009-06-30 18:49:0581 return NULL;
[email protected]f6d1d6eb2009-06-24 20:16:0982 }
83
84 virtual SSLClientSocket* CreateSSLClientSocket(
85 ClientSocket* transport_socket,
86 const std::string& hostname,
87 const SSLConfig& ssl_config) {
88 NOTIMPLEMENTED();
89 return NULL;
90 }
91
[email protected]5fc08e32009-07-15 17:09:5792 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
93 void SignalJobs();
94
[email protected]f6d1d6eb2009-06-24 20:16:0995 int allocation_count() const { return allocation_count_; }
96
[email protected]f6d1d6eb2009-06-24 20:16:0997 private:
98 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:5799 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09100};
101
[email protected]ab838892009-06-30 18:49:05102class TestConnectJob : public ConnectJob {
103 public:
104 enum JobType {
105 kMockJob,
106 kMockFailingJob,
107 kMockPendingJob,
108 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57109 kMockWaitingJob,
110 kMockAdvancingLoadStateJob,
[email protected]ab838892009-06-30 18:49:05111 };
112
113 TestConnectJob(JobType job_type,
114 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49115 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34116 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05117 ConnectJob::Delegate* delegate,
[email protected]fd7b7c92009-08-20 19:38:30118 MockClientSocketFactory* client_socket_factory,
[email protected]9e743cd2010-03-16 07:03:53119 const BoundNetLog& net_log)
120 : ConnectJob(group_name, timeout_duration, delegate, net_log),
[email protected]2ab05b52009-07-01 23:57:58121 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05122 client_socket_factory_(client_socket_factory),
[email protected]46451352009-09-01 14:54:21123 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
124 load_state_(LOAD_STATE_IDLE) {}
[email protected]ab838892009-06-30 18:49:05125
[email protected]974ebd62009-08-03 23:14:34126 void Signal() {
127 DoConnect(waiting_success_, true /* async */);
128 }
129
[email protected]46451352009-09-01 14:54:21130 virtual LoadState GetLoadState() const { return load_state_; }
131
[email protected]974ebd62009-08-03 23:14:34132 private:
[email protected]ab838892009-06-30 18:49:05133 // ConnectJob methods:
134
[email protected]974ebd62009-08-03 23:14:34135 virtual int ConnectInternal() {
[email protected]ab838892009-06-30 18:49:05136 AddressList ignored;
137 client_socket_factory_->CreateTCPClientSocket(ignored);
[email protected]6e713f02009-08-06 02:56:40138 set_socket(new MockClientSocket());
[email protected]ab838892009-06-30 18:49:05139 switch (job_type_) {
140 case kMockJob:
141 return DoConnect(true /* successful */, false /* sync */);
142 case kMockFailingJob:
143 return DoConnect(false /* error */, false /* sync */);
144 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57145 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47146
147 // Depending on execution timings, posting a delayed task can result
148 // in the task getting executed the at the earliest possible
149 // opportunity or only after returning once from the message loop and
150 // then a second call into the message loop. In order to make behavior
151 // more deterministic, we change the default delay to 2ms. This should
152 // always require us to wait for the second call into the message loop.
153 //
154 // N.B. The correct fix for this and similar timing problems is to
155 // abstract time for the purpose of unittests. Unfortunately, we have
156 // a lot of third-party components that directly call the various
157 // time functions, so this change would be rather invasive.
158 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05159 FROM_HERE,
160 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47161 &TestConnectJob::DoConnect,
162 true /* successful */,
163 true /* async */),
164 2);
[email protected]ab838892009-06-30 18:49:05165 return ERR_IO_PENDING;
166 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57167 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47168 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05169 FROM_HERE,
170 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47171 &TestConnectJob::DoConnect,
172 false /* error */,
173 true /* async */),
174 2);
[email protected]ab838892009-06-30 18:49:05175 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57176 case kMockWaitingJob:
177 client_socket_factory_->WaitForSignal(this);
178 waiting_success_ = true;
179 return ERR_IO_PENDING;
180 case kMockAdvancingLoadStateJob:
[email protected]6b175382009-10-13 06:47:47181 MessageLoop::current()->PostDelayedTask(
[email protected]5fc08e32009-07-15 17:09:57182 FROM_HERE,
183 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47184 &TestConnectJob::AdvanceLoadState, load_state_),
185 2);
[email protected]5fc08e32009-07-15 17:09:57186 return ERR_IO_PENDING;
[email protected]ab838892009-06-30 18:49:05187 default:
188 NOTREACHED();
[email protected]6e713f02009-08-06 02:56:40189 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05190 return ERR_FAILED;
191 }
192 }
193
[email protected]46451352009-09-01 14:54:21194 void set_load_state(LoadState load_state) { load_state_ = load_state; }
195
[email protected]ab838892009-06-30 18:49:05196 int DoConnect(bool succeed, bool was_async) {
197 int result = ERR_CONNECTION_FAILED;
[email protected]ab838892009-06-30 18:49:05198 if (succeed) {
199 result = OK;
[email protected]5a05c47a2009-11-02 23:25:19200 socket()->Connect(NULL, NULL);
[email protected]6e713f02009-08-06 02:56:40201 } else {
202 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05203 }
[email protected]2ab05b52009-07-01 23:57:58204
205 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30206 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05207 return result;
208 }
209
[email protected]5fc08e32009-07-15 17:09:57210 void AdvanceLoadState(LoadState state) {
211 int tmp = state;
212 tmp++;
213 state = static_cast<LoadState>(tmp);
214 set_load_state(state);
215 // Post a delayed task so RunAllPending() won't run it.
216 MessageLoop::current()->PostDelayedTask(
217 FROM_HERE,
218 method_factory_.NewRunnableMethod(&TestConnectJob::AdvanceLoadState,
219 state),
220 1 /* 1ms delay */);
221 }
222
223 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05224 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57225 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05226 ScopedRunnableMethodFactory<TestConnectJob> method_factory_;
[email protected]46451352009-09-01 14:54:21227 LoadState load_state_;
[email protected]ab838892009-06-30 18:49:05228
229 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
230};
231
[email protected]d80a4322009-08-14 07:07:49232class TestConnectJobFactory
233 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05234 public:
[email protected]5fc08e32009-07-15 17:09:57235 explicit TestConnectJobFactory(MockClientSocketFactory* client_socket_factory)
[email protected]ab838892009-06-30 18:49:05236 : job_type_(TestConnectJob::kMockJob),
237 client_socket_factory_(client_socket_factory) {}
238
239 virtual ~TestConnectJobFactory() {}
240
241 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
242
[email protected]974ebd62009-08-03 23:14:34243 void set_timeout_duration(base::TimeDelta timeout_duration) {
244 timeout_duration_ = timeout_duration;
245 }
246
[email protected]ab838892009-06-30 18:49:05247 // ConnectJobFactory methods:
248
249 virtual ConnectJob* NewConnectJob(
250 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49251 const TestClientSocketPoolBase::Request& request,
[email protected]fd7b7c92009-08-20 19:38:30252 ConnectJob::Delegate* delegate,
[email protected]9e743cd2010-03-16 07:03:53253 const BoundNetLog& net_log) const {
[email protected]ab838892009-06-30 18:49:05254 return new TestConnectJob(job_type_,
255 group_name,
256 request,
[email protected]974ebd62009-08-03 23:14:34257 timeout_duration_,
[email protected]ab838892009-06-30 18:49:05258 delegate,
[email protected]fd7b7c92009-08-20 19:38:30259 client_socket_factory_,
[email protected]9e743cd2010-03-16 07:03:53260 net_log);
[email protected]ab838892009-06-30 18:49:05261 }
262
[email protected]a796bcec2010-03-22 17:17:26263 virtual base::TimeDelta ConnectionTimeout() const {
264 return timeout_duration_;
265 }
266
[email protected]ab838892009-06-30 18:49:05267 private:
268 TestConnectJob::JobType job_type_;
[email protected]974ebd62009-08-03 23:14:34269 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57270 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05271
272 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
273};
274
275class TestClientSocketPool : public ClientSocketPool {
276 public:
277 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53278 int max_sockets,
[email protected]ab838892009-06-30 18:49:05279 int max_sockets_per_group,
[email protected]a796bcec2010-03-22 17:17:26280 const std::string& name,
[email protected]9bf28db2009-08-29 01:35:16281 base::TimeDelta unused_idle_socket_timeout,
282 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49283 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
[email protected]a796bcec2010-03-22 17:17:26284 : base_(max_sockets, max_sockets_per_group, name,
[email protected]9bf28db2009-08-29 01:35:16285 unused_idle_socket_timeout, used_idle_socket_timeout,
[email protected]100d5fb92009-12-21 21:08:35286 connect_job_factory, NULL) {}
[email protected]ab838892009-06-30 18:49:05287
288 virtual int RequestSocket(
289 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49290 const void* params,
[email protected]ac790b42009-12-02 04:31:31291 net::RequestPriority priority,
[email protected]ab838892009-06-30 18:49:05292 ClientSocketHandle* handle,
[email protected]684970b2009-08-14 04:54:46293 CompletionCallback* callback,
[email protected]9e743cd2010-03-16 07:03:53294 const BoundNetLog& net_log) {
[email protected]d80a4322009-08-14 07:07:49295 return base_.RequestSocket(
[email protected]9e743cd2010-03-16 07:03:53296 group_name, params, priority, handle, callback, net_log);
[email protected]ab838892009-06-30 18:49:05297 }
298
299 virtual void CancelRequest(
300 const std::string& group_name,
301 const ClientSocketHandle* handle) {
[email protected]d80a4322009-08-14 07:07:49302 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05303 }
304
305 virtual void ReleaseSocket(
306 const std::string& group_name,
307 ClientSocket* socket) {
[email protected]d80a4322009-08-14 07:07:49308 base_.ReleaseSocket(group_name, socket);
[email protected]ab838892009-06-30 18:49:05309 }
310
311 virtual void CloseIdleSockets() {
[email protected]d80a4322009-08-14 07:07:49312 base_.CloseIdleSockets();
[email protected]ab838892009-06-30 18:49:05313 }
314
[email protected]d80a4322009-08-14 07:07:49315 virtual int IdleSocketCount() const { return base_.idle_socket_count(); }
[email protected]ab838892009-06-30 18:49:05316
317 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49318 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05319 }
320
321 virtual LoadState GetLoadState(const std::string& group_name,
322 const ClientSocketHandle* handle) const {
[email protected]d80a4322009-08-14 07:07:49323 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05324 }
325
[email protected]a796bcec2010-03-22 17:17:26326 virtual base::TimeDelta ConnectionTimeout() const {
327 return base_.ConnectionTimeout();
328 }
329
330 virtual const std::string& name() const { return base_.name(); }
331
[email protected]d80a4322009-08-14 07:07:49332 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20333
[email protected]974ebd62009-08-03 23:14:34334 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49335 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34336 }
337
[email protected]9bf28db2009-08-29 01:35:16338 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
339
[email protected]ab838892009-06-30 18:49:05340 private:
[email protected]5389bc72009-11-05 23:34:24341 ~TestClientSocketPool() {}
342
[email protected]d80a4322009-08-14 07:07:49343 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05344
345 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
346};
347
[email protected]a937a06d2009-08-19 21:19:24348} // namespace
349
[email protected]7fc5b09a2010-02-27 00:07:38350REGISTER_SOCKET_PARAMS_FOR_POOL(TestClientSocketPool, TestSocketParams);
[email protected]a937a06d2009-08-19 21:19:24351
352namespace {
353
[email protected]5fc08e32009-07-15 17:09:57354void MockClientSocketFactory::SignalJobs() {
355 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
356 it != waiting_jobs_.end(); ++it) {
357 (*it)->Signal();
358 }
359 waiting_jobs_.clear();
360}
361
[email protected]974ebd62009-08-03 23:14:34362class TestConnectJobDelegate : public ConnectJob::Delegate {
363 public:
364 TestConnectJobDelegate()
365 : have_result_(false), waiting_for_result_(false), result_(OK) {}
366 virtual ~TestConnectJobDelegate() {}
367
368 virtual void OnConnectJobComplete(int result, ConnectJob* job) {
369 result_ = result;
[email protected]6e713f02009-08-06 02:56:40370 scoped_ptr<ClientSocket> socket(job->ReleaseSocket());
[email protected]9b6fee12009-09-29 18:13:07371 // socket.get() should be NULL iff result != OK
372 EXPECT_EQ(socket.get() == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34373 delete job;
374 have_result_ = true;
375 if (waiting_for_result_)
376 MessageLoop::current()->Quit();
377 }
378
379 int WaitForResult() {
380 DCHECK(!waiting_for_result_);
381 while (!have_result_) {
382 waiting_for_result_ = true;
383 MessageLoop::current()->Run();
384 waiting_for_result_ = false;
385 }
386 have_result_ = false; // auto-reset for next callback
387 return result_;
388 }
389
390 private:
391 bool have_result_;
392 bool waiting_for_result_;
393 int result_;
394};
395
[email protected]75439d3b2009-07-23 22:11:17396class ClientSocketPoolBaseTest : public ClientSocketPoolTest {
[email protected]f6d1d6eb2009-06-24 20:16:09397 protected:
[email protected]17a0c6c2009-08-04 00:07:04398 ClientSocketPoolBaseTest() {}
[email protected]c9d6a1d2009-07-14 16:15:20399
[email protected]211d21722009-07-22 15:48:53400 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16401 CreatePoolWithIdleTimeouts(
402 max_sockets,
403 max_sockets_per_group,
404 base::TimeDelta::FromSeconds(kUnusedIdleSocketTimeout),
405 base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout));
406 }
407
408 void CreatePoolWithIdleTimeouts(
409 int max_sockets, int max_sockets_per_group,
410 base::TimeDelta unused_idle_socket_timeout,
411 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20412 DCHECK(!pool_.get());
[email protected]17a0c6c2009-08-04 00:07:04413 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_);
[email protected]211d21722009-07-22 15:48:53414 pool_ = new TestClientSocketPool(max_sockets,
415 max_sockets_per_group,
[email protected]a796bcec2010-03-22 17:17:26416 "IdleTimeoutTestPool",
[email protected]9bf28db2009-08-29 01:35:16417 unused_idle_socket_timeout,
418 used_idle_socket_timeout,
[email protected]c9d6a1d2009-07-14 16:15:20419 connect_job_factory_);
420 }
[email protected]f6d1d6eb2009-06-24 20:16:09421
[email protected]ac790b42009-12-02 04:31:31422 int StartRequest(const std::string& group_name,
423 net::RequestPriority priority) {
[email protected]7fc5b09a2010-02-27 00:07:38424 return StartRequestUsingPool<TestClientSocketPool, TestSocketParams>(
[email protected]a796bcec2010-03-22 17:17:26425 pool_, group_name, priority, NULL);
[email protected]f6d1d6eb2009-06-24 20:16:09426 }
427
428 virtual void TearDown() {
[email protected]6b175382009-10-13 06:47:47429 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
430 // actually become pending until 2ms after they have been created. In order
431 // to flush all tasks, we need to wait so that we know there are no
432 // soon-to-be-pending tasks waiting.
433 PlatformThread::Sleep(10);
434 MessageLoop::current()->RunAllPending();
435
[email protected]211d21722009-07-22 15:48:53436 // Need to delete |pool_| before we turn late binding back off. We also need
437 // to delete |requests_| because the pool is reference counted and requests
438 // keep reference to it.
439 // TODO(willchan): Remove this part when late binding becomes the default.
[email protected]5fc08e32009-07-15 17:09:57440 pool_ = NULL;
[email protected]211d21722009-07-22 15:48:53441 requests_.reset();
442
[email protected]75439d3b2009-07-23 22:11:17443 ClientSocketPoolTest::TearDown();
[email protected]f6d1d6eb2009-06-24 20:16:09444 }
445
[email protected]f6d1d6eb2009-06-24 20:16:09446 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04447 TestConnectJobFactory* connect_job_factory_;
[email protected]c9d6a1d2009-07-14 16:15:20448 scoped_refptr<TestClientSocketPool> pool_;
[email protected]f6d1d6eb2009-06-24 20:16:09449};
450
[email protected]a937a06d2009-08-19 21:19:24451// Helper function which explicitly specifies the template parameters, since
452// the compiler will infer (in this case, incorrectly) that NULL is of type int.
453int InitHandle(ClientSocketHandle* handle,
454 const std::string& group_name,
[email protected]ac790b42009-12-02 04:31:31455 net::RequestPriority priority,
[email protected]a937a06d2009-08-19 21:19:24456 CompletionCallback* callback,
[email protected]a796bcec2010-03-22 17:17:26457 const scoped_refptr<TestClientSocketPool>& pool,
[email protected]9e743cd2010-03-16 07:03:53458 const BoundNetLog& net_log) {
[email protected]7fc5b09a2010-02-27 00:07:38459 return handle->Init<TestSocketParams, TestClientSocketPool>(
[email protected]9e743cd2010-03-16 07:03:53460 group_name, NULL, priority, callback, pool, net_log);
[email protected]a937a06d2009-08-19 21:19:24461}
462
[email protected]974ebd62009-08-03 23:14:34463// Even though a timeout is specified, it doesn't time out on a synchronous
464// completion.
465TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
466 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06467 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49468 TestClientSocketPoolBase::Request request(
469 &ignored, NULL, kDefaultPriority, NULL, NULL);
[email protected]974ebd62009-08-03 23:14:34470 scoped_ptr<TestConnectJob> job(
471 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:12472 "a",
[email protected]974ebd62009-08-03 23:14:34473 request,
474 base::TimeDelta::FromMicroseconds(1),
475 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30476 &client_socket_factory_,
477 NULL));
[email protected]974ebd62009-08-03 23:14:34478 EXPECT_EQ(OK, job->Connect());
479}
480
481TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
482 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06483 ClientSocketHandle ignored;
[email protected]9e743cd2010-03-16 07:03:53484 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
485
[email protected]d80a4322009-08-14 07:07:49486 TestClientSocketPoolBase::Request request(
487 &ignored, NULL, kDefaultPriority, NULL, NULL);
[email protected]974ebd62009-08-03 23:14:34488 // Deleted by TestConnectJobDelegate.
489 TestConnectJob* job =
490 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12491 "a",
[email protected]974ebd62009-08-03 23:14:34492 request,
493 base::TimeDelta::FromMicroseconds(1),
494 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30495 &client_socket_factory_,
[email protected]9e743cd2010-03-16 07:03:53496 log.bound());
[email protected]974ebd62009-08-03 23:14:34497 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
498 PlatformThread::Sleep(1);
499 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30500
[email protected]9e743cd2010-03-16 07:03:53501 EXPECT_EQ(3u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:46502 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:53503 log.entries(), 0, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]e9002a92010-01-29 07:10:46504 EXPECT_TRUE(LogContainsEvent(
[email protected]9e743cd2010-03-16 07:03:53505 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
506 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:46507 EXPECT_TRUE(LogContainsEndEvent(
[email protected]9e743cd2010-03-16 07:03:53508 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34509}
510
[email protected]5fc08e32009-07-15 17:09:57511TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53512 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20513
[email protected]f6d1d6eb2009-06-24 20:16:09514 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06515 ClientSocketHandle handle;
[email protected]9e743cd2010-03-16 07:03:53516 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
517
[email protected]a796bcec2010-03-22 17:17:26518 EXPECT_EQ(OK, InitHandle(&handle, "a", kDefaultPriority, &callback, pool_,
519 log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09520 EXPECT_TRUE(handle.is_initialized());
521 EXPECT_TRUE(handle.socket());
[email protected]f6d1d6eb2009-06-24 20:16:09522 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:30523
[email protected]9e743cd2010-03-16 07:03:53524 EXPECT_EQ(5u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:46525 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:53526 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
527 EXPECT_TRUE(LogContainsBeginEvent(
528 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]e9002a92010-01-29 07:10:46529 EXPECT_TRUE(LogContainsEndEvent(
[email protected]9e743cd2010-03-16 07:03:53530 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
531 EXPECT_TRUE(LogContainsEvent(
532 log.entries(), 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_ID,
533 NetLog::PHASE_NONE));
534 EXPECT_TRUE(LogContainsEndEvent(
535 log.entries(), 4, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09536}
537
[email protected]ab838892009-06-30 18:49:05538TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53539 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20540
[email protected]ab838892009-06-30 18:49:05541 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]9e743cd2010-03-16 07:03:53542 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
543
[email protected]a512f5982009-08-18 16:01:06544 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]3ae82302009-06-26 06:01:21545 EXPECT_EQ(ERR_CONNECTION_FAILED,
[email protected]a796bcec2010-03-22 17:17:26546 InitHandle(req.handle(), "a", kDefaultPriority, &req, pool_,
547 log.bound()));
[email protected]fd7b7c92009-08-20 19:38:30548
[email protected]9e743cd2010-03-16 07:03:53549 EXPECT_EQ(5u, log.entries().size());
550 EXPECT_TRUE(LogContainsBeginEvent(log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]e9002a92010-01-29 07:10:46551 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:53552 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]e9002a92010-01-29 07:10:46553 EXPECT_TRUE(LogContainsEndEvent(
[email protected]9e743cd2010-03-16 07:03:53554 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
555 EXPECT_TRUE(LogContainsEndEvent(log.entries(), 4, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09556}
557
[email protected]211d21722009-07-22 15:48:53558TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
559 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
560
[email protected]9e743cd2010-03-16 07:03:53561 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30562
[email protected]211d21722009-07-22 15:48:53563 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
564 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
565 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
566 EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
567
568 EXPECT_EQ(static_cast<int>(requests_.size()),
569 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17570 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53571
572 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
573 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
574 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
575
[email protected]d43002e2010-04-07 21:29:49576 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53577
578 EXPECT_EQ(static_cast<int>(requests_.size()),
579 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17580 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53581
582 EXPECT_EQ(1, GetOrderOfRequest(1));
583 EXPECT_EQ(2, GetOrderOfRequest(2));
584 EXPECT_EQ(3, GetOrderOfRequest(3));
585 EXPECT_EQ(4, GetOrderOfRequest(4));
586 EXPECT_EQ(5, GetOrderOfRequest(5));
587 EXPECT_EQ(6, GetOrderOfRequest(6));
588 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17589
590 // Make sure we test order of all requests made.
591 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53592}
593
594TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
595 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
596
[email protected]9e743cd2010-03-16 07:03:53597 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30598
[email protected]211d21722009-07-22 15:48:53599 // Reach all limits: max total sockets, and max sockets per group.
600 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
601 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
602 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
603 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
604
605 EXPECT_EQ(static_cast<int>(requests_.size()),
606 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17607 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53608
609 // Now create a new group and verify that we don't starve it.
610 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
611
[email protected]d43002e2010-04-07 21:29:49612 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53613
614 EXPECT_EQ(static_cast<int>(requests_.size()),
615 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17616 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53617
618 EXPECT_EQ(1, GetOrderOfRequest(1));
619 EXPECT_EQ(2, GetOrderOfRequest(2));
620 EXPECT_EQ(3, GetOrderOfRequest(3));
621 EXPECT_EQ(4, GetOrderOfRequest(4));
622 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17623
624 // Make sure we test order of all requests made.
625 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53626}
627
628TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
629 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
630
[email protected]ac790b42009-12-02 04:31:31631 EXPECT_EQ(OK, StartRequest("b", LOWEST));
632 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
633 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
634 EXPECT_EQ(OK, StartRequest("a", LOWEST));
[email protected]211d21722009-07-22 15:48:53635
636 EXPECT_EQ(static_cast<int>(requests_.size()),
637 client_socket_factory_.allocation_count());
638
[email protected]ac790b42009-12-02 04:31:31639 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
640 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
641 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53642
[email protected]d43002e2010-04-07 21:29:49643 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53644
[email protected]75439d3b2009-07-23 22:11:17645 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53646
647 // First 4 requests don't have to wait, and finish in order.
648 EXPECT_EQ(1, GetOrderOfRequest(1));
649 EXPECT_EQ(2, GetOrderOfRequest(2));
650 EXPECT_EQ(3, GetOrderOfRequest(3));
651 EXPECT_EQ(4, GetOrderOfRequest(4));
652
[email protected]ac790b42009-12-02 04:31:31653 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
654 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53655 EXPECT_EQ(7, GetOrderOfRequest(5));
656 EXPECT_EQ(6, GetOrderOfRequest(6));
657 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17658
659 // Make sure we test order of all requests made.
660 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53661}
662
663TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
664 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
665
[email protected]ac790b42009-12-02 04:31:31666 EXPECT_EQ(OK, StartRequest("a", LOWEST));
667 EXPECT_EQ(OK, StartRequest("a", LOW));
668 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
669 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
[email protected]211d21722009-07-22 15:48:53670
671 EXPECT_EQ(static_cast<int>(requests_.size()),
672 client_socket_factory_.allocation_count());
673
[email protected]ac790b42009-12-02 04:31:31674 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
675 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
676 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53677
[email protected]d43002e2010-04-07 21:29:49678 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53679
[email protected]d43002e2010-04-07 21:29:49680 EXPECT_EQ(static_cast<int>(requests_.size()),
[email protected]211d21722009-07-22 15:48:53681 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17682 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53683
684 // First 4 requests don't have to wait, and finish in order.
685 EXPECT_EQ(1, GetOrderOfRequest(1));
686 EXPECT_EQ(2, GetOrderOfRequest(2));
687 EXPECT_EQ(3, GetOrderOfRequest(3));
688 EXPECT_EQ(4, GetOrderOfRequest(4));
689
690 // Request ("b", 7) has the highest priority, but we can't make new socket for
691 // group "b", because it has reached the per-group limit. Then we make
692 // socket for ("c", 6), because it has higher priority than ("a", 4),
693 // and we still can't make a socket for group "b".
694 EXPECT_EQ(5, GetOrderOfRequest(5));
695 EXPECT_EQ(6, GetOrderOfRequest(6));
696 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17697
698 // Make sure we test order of all requests made.
699 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53700}
701
702// Make sure that we count connecting sockets against the total limit.
703TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
704 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
705
706 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
707 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
708 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
709
710 // Create one asynchronous request.
711 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
712 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
713
[email protected]6b175382009-10-13 06:47:47714 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
715 // actually become pending until 2ms after they have been created. In order
716 // to flush all tasks, we need to wait so that we know there are no
717 // soon-to-be-pending tasks waiting.
718 PlatformThread::Sleep(10);
719 MessageLoop::current()->RunAllPending();
720
[email protected]211d21722009-07-22 15:48:53721 // The next synchronous request should wait for its turn.
722 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
723 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
724
[email protected]d43002e2010-04-07 21:29:49725 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53726
727 EXPECT_EQ(static_cast<int>(requests_.size()),
728 client_socket_factory_.allocation_count());
729
730 EXPECT_EQ(1, GetOrderOfRequest(1));
731 EXPECT_EQ(2, GetOrderOfRequest(2));
732 EXPECT_EQ(3, GetOrderOfRequest(3));
733 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:17734 EXPECT_EQ(5, GetOrderOfRequest(5));
735
736 // Make sure we test order of all requests made.
737 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53738}
739
740// Inside ClientSocketPoolBase we have a may_have_stalled_group flag,
741// which tells it to use more expensive, but accurate, group selection
742// algorithm. Make sure it doesn't get stuck in the "on" state.
743TEST_F(ClientSocketPoolBaseTest, MayHaveStalledGroupReset) {
744 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
745
746 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
747
748 // Reach group socket limit.
749 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
750 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
751 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
752
753 // Reach total limit, but don't request more sockets.
754 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
755 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
756 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
757
758 // Request one more socket while we are at the maximum sockets limit.
759 // This should flip the may_have_stalled_group flag.
760 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
761 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
762
763 // After releasing first connection for "a", we're still at the
764 // maximum sockets limit, but every group's pending queue is empty,
765 // so we reset the flag.
[email protected]d43002e2010-04-07 21:29:49766 EXPECT_TRUE(ReleaseOneConnection(NO_KEEP_ALIVE));
[email protected]211d21722009-07-22 15:48:53767 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
768
769 // Requesting additional socket while at the total limit should
770 // flip the flag back to "on".
771 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
772 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
773
774 // We'll request one more socket to verify that we don't reset the flag
775 // too eagerly.
776 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
777 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
778
779 // We're at the maximum socket limit, and still have one request pending
780 // for "d". Flag should be "on".
[email protected]d43002e2010-04-07 21:29:49781 EXPECT_TRUE(ReleaseOneConnection(NO_KEEP_ALIVE));
[email protected]211d21722009-07-22 15:48:53782 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
783
784 // Now every group's pending queue should be empty again.
[email protected]d43002e2010-04-07 21:29:49785 EXPECT_TRUE(ReleaseOneConnection(NO_KEEP_ALIVE));
[email protected]211d21722009-07-22 15:48:53786 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
787
[email protected]d43002e2010-04-07 21:29:49788 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53789 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
790}
791
[email protected]d43002e2010-04-07 21:29:49792TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimit) {
793 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
794 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
795
796 for (int i = 0; i < kDefaultMaxSockets; ++i) {
797 ClientSocketHandle handle;
798 TestCompletionCallback callback;
799 EXPECT_EQ(OK,
800 InitHandle(&handle, IntToString(i), kDefaultPriority, &callback,
801 pool_, NULL));
802 }
803
804 // Stall a group
805 ClientSocketHandle handle;
806 TestCompletionCallback callback;
807 EXPECT_EQ(ERR_IO_PENDING,
808 InitHandle(&handle, "foo", kDefaultPriority, &callback, pool_,
809 NULL));
810
811 // Cancel the stalled request.
812 handle.Reset();
813
814 // Flush all the DoReleaseSocket tasks.
815 MessageLoop::current()->RunAllPending();
816
817 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
818 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
819
820 for (int i = 0; i < kDefaultMaxSockets; ++i) {
821 ClientSocketHandle handle;
822 TestCompletionCallback callback;
823 EXPECT_EQ(OK,
824 InitHandle(&handle, StringPrintf("Take 2: %d", i),
825 kDefaultPriority, &callback, pool_, NULL));
826 }
827
828 EXPECT_EQ(2 * kDefaultMaxSockets, client_socket_factory_.allocation_count());
829 EXPECT_EQ(0, pool_->IdleSocketCount());
830
831 // Before the next round of DoReleaseSocket tasks run, we will hit the
832 // socket limit.
833
834 EXPECT_EQ(ERR_IO_PENDING,
835 InitHandle(&handle, "foo", kDefaultPriority, &callback, pool_,
836 NULL));
837
838 // But if we wait for it, the released idle sockets will be closed in
839 // preference of the waiting request.
840
841 EXPECT_EQ(OK, callback.WaitForResult());
842}
843
[email protected]ab838892009-06-30 18:49:05844TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:53845 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09846
[email protected]c9d6a1d2009-07-14 16:15:20847 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
848 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:31849 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
850 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
851 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
852 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
853 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:09854
[email protected]c9d6a1d2009-07-14 16:15:20855 ReleaseAllConnections(KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09856
[email protected]c9d6a1d2009-07-14 16:15:20857 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
858 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17859 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09860
[email protected]c9d6a1d2009-07-14 16:15:20861 EXPECT_EQ(1, GetOrderOfRequest(1));
862 EXPECT_EQ(2, GetOrderOfRequest(2));
863 EXPECT_EQ(6, GetOrderOfRequest(3));
864 EXPECT_EQ(4, GetOrderOfRequest(4));
865 EXPECT_EQ(3, GetOrderOfRequest(5));
866 EXPECT_EQ(5, GetOrderOfRequest(6));
867 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17868
869 // Make sure we test order of all requests made.
870 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:09871}
872
[email protected]ab838892009-06-30 18:49:05873TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:53874 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09875
[email protected]c9d6a1d2009-07-14 16:15:20876 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
877 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:31878 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
879 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
880 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
881 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
882 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:09883
[email protected]c9d6a1d2009-07-14 16:15:20884 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09885
[email protected]c9d6a1d2009-07-14 16:15:20886 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i)
887 EXPECT_EQ(OK, requests_[i]->WaitForResult());
888
889 EXPECT_EQ(static_cast<int>(requests_.size()),
890 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17891 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09892}
893
894// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:05895// The pending connect job will be cancelled and should not call back into
896// ClientSocketPoolBase.
897TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:53898 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20899
[email protected]ab838892009-06-30 18:49:05900 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:06901 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]ab838892009-06-30 18:49:05902 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a796bcec2010-03-22 17:17:26903 InitHandle(req.handle(), "a", kDefaultPriority, &req, pool_, NULL));
[email protected]a6c59f62009-07-29 16:33:33904 req.handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:09905}
906
[email protected]ab838892009-06-30 18:49:05907TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:53908 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20909
[email protected]ab838892009-06-30 18:49:05910 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:06911 ClientSocketHandle handle;
[email protected]f6d1d6eb2009-06-24 20:16:09912 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06913 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09914
[email protected]ab838892009-06-30 18:49:05915 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a796bcec2010-03-22 17:17:26916 InitHandle(&handle, "a", kDefaultPriority, &callback, pool_, NULL));
[email protected]f6d1d6eb2009-06-24 20:16:09917
918 handle.Reset();
919
920 TestCompletionCallback callback2;
[email protected]a796bcec2010-03-22 17:17:26921 EXPECT_EQ(ERR_IO_PENDING, InitHandle(&handle, "a", kDefaultPriority,
922 &callback2, pool_, NULL));
[email protected]f6d1d6eb2009-06-24 20:16:09923
924 EXPECT_EQ(OK, callback2.WaitForResult());
925 EXPECT_FALSE(callback.have_result());
926
927 handle.Reset();
928}
929
[email protected]ab838892009-06-30 18:49:05930TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:53931 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09932
[email protected]c9d6a1d2009-07-14 16:15:20933 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
934 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:31935 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
936 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
937 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
938 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
939 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:09940
941 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:20942 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]a6c59f62009-07-29 16:33:33943 EXPECT_FALSE(requests_[index_to_cancel]->handle()->is_initialized());
944 requests_[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:09945
[email protected]c9d6a1d2009-07-14 16:15:20946 ReleaseAllConnections(KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09947
[email protected]c9d6a1d2009-07-14 16:15:20948 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
949 client_socket_factory_.allocation_count());
950 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup - 1,
[email protected]75439d3b2009-07-23 22:11:17951 completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09952
[email protected]c9d6a1d2009-07-14 16:15:20953 EXPECT_EQ(1, GetOrderOfRequest(1));
954 EXPECT_EQ(2, GetOrderOfRequest(2));
955 EXPECT_EQ(5, GetOrderOfRequest(3));
956 EXPECT_EQ(3, GetOrderOfRequest(4));
957 EXPECT_EQ(kRequestNotFound, GetOrderOfRequest(5)); // Canceled request.
958 EXPECT_EQ(4, GetOrderOfRequest(6));
959 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17960
961 // Make sure we test order of all requests made.
962 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:09963}
964
965class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
966 public:
[email protected]2ab05b52009-07-01 23:57:58967 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:24968 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:58969 TestConnectJobFactory* test_connect_job_factory,
970 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:09971 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:06972 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:58973 within_callback_(false),
974 test_connect_job_factory_(test_connect_job_factory),
975 next_job_type_(next_job_type) {}
[email protected]f6d1d6eb2009-06-24 20:16:09976
977 virtual void RunWithParams(const Tuple1<int>& params) {
978 callback_.RunWithParams(params);
979 ASSERT_EQ(OK, params.a);
980
981 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:58982 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]5edbf8d2010-01-13 18:44:11983
984 // Don't allow reuse of the socket. Disconnect it and then release it and
985 // run through the MessageLoop once to get it completely released.
986 handle_->socket()->Disconnect();
[email protected]f6d1d6eb2009-06-24 20:16:09987 handle_->Reset();
[email protected]5edbf8d2010-01-13 18:44:11988 {
989 MessageLoop::ScopedNestableTaskAllower nestable(
990 MessageLoop::current());
991 MessageLoop::current()->RunAllPending();
992 }
[email protected]f6d1d6eb2009-06-24 20:16:09993 within_callback_ = true;
[email protected]6b175382009-10-13 06:47:47994 TestCompletionCallback next_job_callback;
[email protected]a796bcec2010-03-22 17:17:26995 int rv = InitHandle(handle_, "a", kDefaultPriority, &next_job_callback,
996 pool_, NULL);
[email protected]2ab05b52009-07-01 23:57:58997 switch (next_job_type_) {
998 case TestConnectJob::kMockJob:
999 EXPECT_EQ(OK, rv);
1000 break;
1001 case TestConnectJob::kMockPendingJob:
1002 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:471003
1004 // For pending jobs, wait for new socket to be created. This makes
1005 // sure there are no more pending operations nor any unclosed sockets
1006 // when the test finishes.
1007 // We need to give it a little bit of time to run, so that all the
1008 // operations that happen on timers (e.g. cleanup of idle
1009 // connections) can execute.
[email protected]5edbf8d2010-01-13 18:44:111010 {
1011 MessageLoop::ScopedNestableTaskAllower nestable(
1012 MessageLoop::current());
1013 PlatformThread::Sleep(10);
1014 EXPECT_EQ(OK, next_job_callback.WaitForResult());
1015 }
[email protected]2ab05b52009-07-01 23:57:581016 break;
1017 default:
1018 FAIL() << "Unexpected job type: " << next_job_type_;
1019 break;
1020 }
[email protected]f6d1d6eb2009-06-24 20:16:091021 }
1022 }
1023
1024 int WaitForResult() {
1025 return callback_.WaitForResult();
1026 }
1027
1028 private:
1029 ClientSocketHandle* const handle_;
[email protected]a937a06d2009-08-19 21:19:241030 const scoped_refptr<TestClientSocketPool> pool_;
[email protected]f6d1d6eb2009-06-24 20:16:091031 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:581032 TestConnectJobFactory* const test_connect_job_factory_;
1033 TestConnectJob::JobType next_job_type_;
[email protected]f6d1d6eb2009-06-24 20:16:091034 TestCompletionCallback callback_;
1035};
1036
[email protected]2ab05b52009-07-01 23:57:581037TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531038 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201039
[email protected]0b7648c2009-07-06 20:14:011040 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061041 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581042 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061043 &handle, pool_.get(), connect_job_factory_,
1044 TestConnectJob::kMockPendingJob);
[email protected]a796bcec2010-03-22 17:17:261045 int rv = InitHandle(&handle, "a", kDefaultPriority, &callback, pool_, NULL);
[email protected]f6d1d6eb2009-06-24 20:16:091046 ASSERT_EQ(ERR_IO_PENDING, rv);
1047
1048 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581049}
[email protected]f6d1d6eb2009-06-24 20:16:091050
[email protected]2ab05b52009-07-01 23:57:581051TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531052 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201053
[email protected]0b7648c2009-07-06 20:14:011054 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061055 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581056 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061057 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]a796bcec2010-03-22 17:17:261058 int rv = InitHandle(&handle, "a", kDefaultPriority, &callback, pool_, NULL);
[email protected]2ab05b52009-07-01 23:57:581059 ASSERT_EQ(ERR_IO_PENDING, rv);
1060
1061 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091062}
1063
1064// Make sure that pending requests get serviced after active requests get
1065// cancelled.
[email protected]ab838892009-06-30 18:49:051066TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531067 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201068
[email protected]0b7648c2009-07-06 20:14:011069 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091070
[email protected]c9d6a1d2009-07-14 16:15:201071 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1072 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1073 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1074 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1075 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1076 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1077 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091078
[email protected]c9d6a1d2009-07-14 16:15:201079 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1080 // Let's cancel them.
1081 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]a6c59f62009-07-29 16:33:331082 ASSERT_FALSE(requests_[i]->handle()->is_initialized());
1083 requests_[i]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091084 }
1085
[email protected]f6d1d6eb2009-06-24 20:16:091086 // Let's wait for the rest to complete now.
[email protected]c9d6a1d2009-07-14 16:15:201087 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i) {
1088 EXPECT_EQ(OK, requests_[i]->WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331089 requests_[i]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091090 }
1091
[email protected]75439d3b2009-07-23 22:11:171092 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091093}
1094
1095// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051096TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531097 const size_t kMaxSockets = 5;
1098 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201099
[email protected]0b7648c2009-07-06 20:14:011100 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091101
[email protected]211d21722009-07-22 15:48:531102 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1103 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091104
1105 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531106 for (size_t i = 0; i < kNumberOfRequests; ++i)
1107 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091108
[email protected]211d21722009-07-22 15:48:531109 for (size_t i = 0; i < kNumberOfRequests; ++i)
1110 EXPECT_EQ(ERR_CONNECTION_FAILED, requests_[i]->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091111}
1112
[email protected]5fc08e32009-07-15 17:09:571113TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531114 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571115
1116 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1117
[email protected]a512f5982009-08-18 16:01:061118 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261119 int rv = InitHandle(req.handle(), "a", kDefaultPriority, &req, pool_, NULL);
[email protected]5fc08e32009-07-15 17:09:571120 EXPECT_EQ(ERR_IO_PENDING, rv);
1121
1122 // Cancel the active request.
[email protected]a6c59f62009-07-29 16:33:331123 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571124
[email protected]a796bcec2010-03-22 17:17:261125 rv = InitHandle(req.handle(), "a", kDefaultPriority, &req, pool_, NULL);
[email protected]5fc08e32009-07-15 17:09:571126 EXPECT_EQ(ERR_IO_PENDING, rv);
1127 EXPECT_EQ(OK, req.WaitForResult());
1128
[email protected]a6c59f62009-07-29 16:33:331129 EXPECT_FALSE(req.handle()->is_reused());
[email protected]75439d3b2009-07-23 22:11:171130 EXPECT_EQ(1U, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571131 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1132}
1133
[email protected]2b7523d2009-07-29 20:29:231134// Regression test for http://crbug.com/17985.
1135TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1136 const int kMaxSockets = 3;
1137 const int kMaxSocketsPerGroup = 2;
1138 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1139
[email protected]ac790b42009-12-02 04:31:311140 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231141
1142 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1143 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1144
1145 // This is going to be a pending request in an otherwise empty group.
1146 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1147
1148 // Reach the maximum socket limit.
1149 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1150
1151 // Create a stalled group with high priorities.
1152 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1153 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1154 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
1155
1156 // Release the first two sockets from "a", which will make room
1157 // for requests from "c". After that "a" will have no active sockets
1158 // and one pending request.
1159 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1160 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1161
1162 // Closing idle sockets should not get us into trouble, but in the bug
1163 // we were hitting a CHECK here.
[email protected]2b7523d2009-07-29 20:29:231164 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]d43002e2010-04-07 21:29:491165 pool_->CloseIdleSockets();
[email protected]2b7523d2009-07-29 20:29:231166}
1167
[email protected]4d3b05d2010-01-27 21:27:291168TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531169 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571170
1171 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061172 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]9e743cd2010-03-16 07:03:531173 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]a796bcec2010-03-22 17:17:261174 int rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_, log.bound());
[email protected]5fc08e32009-07-15 17:09:571175 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331176 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:571177 EXPECT_EQ(OK, req.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331178 EXPECT_TRUE(req.handle()->is_initialized());
1179 EXPECT_TRUE(req.handle()->socket());
1180 req.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:301181
[email protected]7c28e9a2010-03-20 01:16:131182 EXPECT_EQ(5u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:461183 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:531184 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
1185 EXPECT_TRUE(LogContainsBeginEvent(
1186 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]e9002a92010-01-29 07:10:461187 EXPECT_TRUE(LogContainsEndEvent(
[email protected]9e743cd2010-03-16 07:03:531188 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]e9002a92010-01-29 07:10:461189 EXPECT_TRUE(LogContainsEndEvent(
[email protected]7c28e9a2010-03-20 01:16:131190 log.entries(), 4, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571191}
1192
[email protected]4d3b05d2010-01-27 21:27:291193TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571194 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531195 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571196
1197 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]a512f5982009-08-18 16:01:061198 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]9e743cd2010-03-16 07:03:531199 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]5fc08e32009-07-15 17:09:571200 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a796bcec2010-03-22 17:17:261201 InitHandle(req.handle(), "a", kDefaultPriority, &req, pool_,
1202 log.bound()));
[email protected]a6c59f62009-07-29 16:33:331203 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:571204 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:301205
[email protected]7c28e9a2010-03-20 01:16:131206 EXPECT_EQ(5u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:461207 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:531208 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
1209 EXPECT_TRUE(LogContainsBeginEvent(
1210 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]e9002a92010-01-29 07:10:461211 EXPECT_TRUE(LogContainsEndEvent(
[email protected]9e743cd2010-03-16 07:03:531212 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]6b624c62010-03-14 08:37:321213 EXPECT_TRUE(LogContainsEndEvent(
[email protected]7c28e9a2010-03-20 01:16:131214 log.entries(), 4, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571215}
1216
[email protected]4d3b05d2010-01-27 21:27:291217TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101218 // TODO(eroman): Add back the log expectations! Removed them because the
1219 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531220 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571221
1222 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061223 TestSocketRequest req(&request_order_, &completion_count_);
1224 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]5fc08e32009-07-15 17:09:571225
1226 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a796bcec2010-03-22 17:17:261227 InitHandle(req.handle(), "a", kDefaultPriority, &req, pool_,
1228 BoundNetLog()));
[email protected]9e743cd2010-03-16 07:03:531229 CapturingBoundNetLog log2(CapturingNetLog::kUnbounded);
[email protected]5fc08e32009-07-15 17:09:571230 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a796bcec2010-03-22 17:17:261231 InitHandle(req2.handle(), "a", kDefaultPriority, &req2, pool_,
1232 BoundNetLog()));
[email protected]5fc08e32009-07-15 17:09:571233
[email protected]a6c59f62009-07-29 16:33:331234 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571235
[email protected]fd7b7c92009-08-20 19:38:301236
1237 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301238
[email protected]5fc08e32009-07-15 17:09:571239 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331240 req2.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:301241
1242 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531243 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571244}
1245
[email protected]4d3b05d2010-01-27 21:27:291246TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341247 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1248
[email protected]17a0c6c2009-08-04 00:07:041249 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1250
[email protected]ac790b42009-12-02 04:31:311251 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1252 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1253 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1254 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341255
1256 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1257 requests_[2]->handle()->Reset();
1258 requests_[3]->handle()->Reset();
1259 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1260
1261 requests_[1]->handle()->Reset();
1262 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1263
1264 requests_[0]->handle()->Reset();
1265 EXPECT_EQ(kDefaultMaxSocketsPerGroup - 1, pool_->NumConnectJobsInGroup("a"));
1266}
1267
[email protected]5fc08e32009-07-15 17:09:571268// When requests and ConnectJobs are not coupled, the request will get serviced
1269// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291270TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531271 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571272
1273 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321274 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571275
[email protected]a512f5982009-08-18 16:01:061276 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261277 int rv = InitHandle(req1.handle(), "a", kDefaultPriority, &req1, pool_, NULL);
[email protected]5fc08e32009-07-15 17:09:571278 EXPECT_EQ(ERR_IO_PENDING, rv);
1279 EXPECT_EQ(OK, req1.WaitForResult());
1280
1281 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1282 // without a job.
1283 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1284
[email protected]a512f5982009-08-18 16:01:061285 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261286 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2, pool_, NULL);
[email protected]5fc08e32009-07-15 17:09:571287 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a512f5982009-08-18 16:01:061288 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261289 rv = InitHandle(req3.handle(), "a", kDefaultPriority, &req3, pool_, NULL);
[email protected]5fc08e32009-07-15 17:09:571290 EXPECT_EQ(ERR_IO_PENDING, rv);
1291
1292 // Both Requests 2 and 3 are pending. We release socket 1 which should
1293 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331294 req1.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571295 MessageLoop::current()->RunAllPending(); // Run the DoReleaseSocket()
[email protected]a6c59f62009-07-29 16:33:331296 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571297 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331298 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571299
1300 // Signal job 2, which should service request 3.
1301
1302 client_socket_factory_.SignalJobs();
1303 EXPECT_EQ(OK, req3.WaitForResult());
1304
1305 ASSERT_EQ(3U, request_order_.size());
1306 EXPECT_EQ(&req1, request_order_[0]);
1307 EXPECT_EQ(&req2, request_order_[1]);
1308 EXPECT_EQ(&req3, request_order_[2]);
1309 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1310}
1311
1312// The requests are not coupled to the jobs. So, the requests should finish in
1313// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:291314TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531315 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571316 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321317 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571318
[email protected]a512f5982009-08-18 16:01:061319 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261320 int rv = InitHandle(req1.handle(), "a", kDefaultPriority, &req1, pool_, NULL);
[email protected]5fc08e32009-07-15 17:09:571321 EXPECT_EQ(ERR_IO_PENDING, rv);
1322
[email protected]a512f5982009-08-18 16:01:061323 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261324 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2, pool_, NULL);
[email protected]5fc08e32009-07-15 17:09:571325 EXPECT_EQ(ERR_IO_PENDING, rv);
1326
1327 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321328 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571329
[email protected]a512f5982009-08-18 16:01:061330 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261331 rv = InitHandle(req3.handle(), "a", kDefaultPriority, &req3, pool_, NULL);
[email protected]5fc08e32009-07-15 17:09:571332 EXPECT_EQ(ERR_IO_PENDING, rv);
1333
1334 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1335 EXPECT_EQ(OK, req2.WaitForResult());
1336 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1337
1338 ASSERT_EQ(3U, request_order_.size());
1339 EXPECT_EQ(&req1, request_order_[0]);
1340 EXPECT_EQ(&req2, request_order_[1]);
1341 EXPECT_EQ(&req3, request_order_[2]);
1342}
1343
[email protected]4d3b05d2010-01-27 21:27:291344TEST_F(ClientSocketPoolBaseTest, DISABLED_LoadState) {
[email protected]211d21722009-07-22 15:48:531345 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571346 connect_job_factory_->set_job_type(
[email protected]b59ff372009-07-15 22:04:321347 TestConnectJob::kMockAdvancingLoadStateJob);
[email protected]5fc08e32009-07-15 17:09:571348
[email protected]a512f5982009-08-18 16:01:061349 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261350 int rv = InitHandle(req1.handle(), "a", kDefaultPriority, &req1, pool_, NULL);
[email protected]5fc08e32009-07-15 17:09:571351 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331352 EXPECT_EQ(LOAD_STATE_IDLE, req1.handle()->GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571353
1354 MessageLoop::current()->RunAllPending();
1355
[email protected]a512f5982009-08-18 16:01:061356 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261357 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2, pool_, NULL);
[email protected]5fc08e32009-07-15 17:09:571358 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331359 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, req1.handle()->GetLoadState());
1360 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, req2.handle()->GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571361}
1362
[email protected]4d3b05d2010-01-27 21:27:291363TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
[email protected]9bf28db2009-08-29 01:35:161364 CreatePoolWithIdleTimeouts(
1365 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1366 base::TimeDelta(), // Time out unused sockets immediately.
1367 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1368
1369 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1370
1371 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
1372
1373 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261374 int rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_, NULL);
[email protected]9bf28db2009-08-29 01:35:161375 EXPECT_EQ(ERR_IO_PENDING, rv);
1376 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
1377
1378 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261379 rv = InitHandle(req2.handle(), "a", LOWEST, &req2, pool_, NULL);
[email protected]9bf28db2009-08-29 01:35:161380 EXPECT_EQ(ERR_IO_PENDING, rv);
1381 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req2.handle()));
1382
1383 // Cancel one of the requests. Wait for the other, which will get the first
1384 // job. Release the socket. Run the loop again to make sure the second
1385 // socket is sitting idle and the first one is released (since ReleaseSocket()
1386 // just posts a DoReleaseSocket() task).
1387
1388 req.handle()->Reset();
1389 EXPECT_EQ(OK, req2.WaitForResult());
1390 req2.handle()->Reset();
[email protected]6b175382009-10-13 06:47:471391
1392 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1393 // actually become pending until 2ms after they have been created. In order
1394 // to flush all tasks, we need to wait so that we know there are no
1395 // soon-to-be-pending tasks waiting.
1396 PlatformThread::Sleep(10);
[email protected]9bf28db2009-08-29 01:35:161397 MessageLoop::current()->RunAllPending();
1398
1399 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:041400
[email protected]9bf28db2009-08-29 01:35:161401 // Invoke the idle socket cleanup check. Only one socket should be left, the
1402 // used socket. Request it to make sure that it's used.
1403
1404 pool_->CleanupTimedOutIdleSockets();
[email protected]9e743cd2010-03-16 07:03:531405 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]a796bcec2010-03-22 17:17:261406 rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_, log.bound());
[email protected]9bf28db2009-08-29 01:35:161407 EXPECT_EQ(OK, rv);
1408 EXPECT_TRUE(req.handle()->is_reused());
[email protected]fd4fe0b2010-02-08 23:02:151409 EXPECT_TRUE(LogContainsEntryWithType(
[email protected]9e743cd2010-03-16 07:03:531410 log.entries(), 1, NetLog::Entry::TYPE_STRING_LITERAL));
[email protected]9bf28db2009-08-29 01:35:161411}
1412
[email protected]2041cf342010-02-19 03:15:591413// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:161414// because of multiple releasing disconnected sockets.
1415TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
1416 CreatePoolWithIdleTimeouts(
1417 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1418 base::TimeDelta(), // Time out unused sockets immediately.
1419 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1420
1421 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1422
1423 // Startup 4 connect jobs. Two of them will be pending.
1424
1425 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261426 int rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_, NULL);
[email protected]4f2abec2010-02-03 18:10:161427 EXPECT_EQ(OK, rv);
1428
1429 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261430 rv = InitHandle(req2.handle(), "a", LOWEST, &req2, pool_, NULL);
[email protected]4f2abec2010-02-03 18:10:161431 EXPECT_EQ(OK, rv);
1432
1433 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261434 rv = InitHandle(req3.handle(), "a", LOWEST, &req3, pool_, NULL);
[email protected]4f2abec2010-02-03 18:10:161435 EXPECT_EQ(ERR_IO_PENDING, rv);
1436
1437 TestSocketRequest req4(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261438 rv = InitHandle(req4.handle(), "a", LOWEST, &req4, pool_, NULL);
[email protected]4f2abec2010-02-03 18:10:161439 EXPECT_EQ(ERR_IO_PENDING, rv);
1440
1441 // Release two disconnected sockets.
1442
1443 req.handle()->socket()->Disconnect();
1444 req.handle()->Reset();
1445 req2.handle()->socket()->Disconnect();
1446 req2.handle()->Reset();
1447
1448 EXPECT_EQ(OK, req3.WaitForResult());
1449 EXPECT_FALSE(req3.handle()->is_reused());
1450 EXPECT_EQ(OK, req4.WaitForResult());
1451 EXPECT_FALSE(req4.handle()->is_reused());
1452}
1453
[email protected]fd4fe0b2010-02-08 23:02:151454TEST_F(ClientSocketPoolBaseTest,
1455 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
1456 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1457
1458 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1459
1460 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1461 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1462 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1463 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1464
1465 EXPECT_EQ(OK, requests_[0]->WaitForResult());
1466 EXPECT_EQ(OK, requests_[1]->WaitForResult());
1467 EXPECT_EQ(2u, completion_count_);
1468
1469 // Releases one connection.
1470 EXPECT_TRUE(ReleaseOneConnection(NO_KEEP_ALIVE));
1471 EXPECT_EQ(OK, requests_[2]->WaitForResult());
1472
1473 EXPECT_TRUE(ReleaseOneConnection(NO_KEEP_ALIVE));
1474 EXPECT_EQ(OK, requests_[3]->WaitForResult());
1475 EXPECT_EQ(4u, completion_count_);
1476
1477 EXPECT_EQ(1, GetOrderOfRequest(1));
1478 EXPECT_EQ(2, GetOrderOfRequest(2));
1479 EXPECT_EQ(3, GetOrderOfRequest(3));
1480 EXPECT_EQ(4, GetOrderOfRequest(4));
1481
1482 // Make sure we test order of all requests made.
1483 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(5));
1484}
1485
[email protected]4f1e4982010-03-02 18:31:041486class TestReleasingSocketRequest : public CallbackRunner< Tuple1<int> > {
1487 public:
1488 explicit TestReleasingSocketRequest(TestClientSocketPool* pool)
1489 : pool_(pool) {}
1490
1491 ClientSocketHandle* handle() { return &handle_; }
1492
1493 int WaitForResult() {
1494 return callback_.WaitForResult();
1495 }
1496
1497 virtual void RunWithParams(const Tuple1<int>& params) {
1498 callback_.RunWithParams(params);
1499 handle_.Reset();
[email protected]a796bcec2010-03-22 17:17:261500 EXPECT_EQ(ERR_IO_PENDING, InitHandle(&handle2_, "a", kDefaultPriority,
1501 &callback2_, pool_, NULL));
[email protected]4f1e4982010-03-02 18:31:041502 }
1503
1504 private:
1505 TestClientSocketPool* const pool_;
1506 ClientSocketHandle handle_;
1507 ClientSocketHandle handle2_;
1508 TestCompletionCallback callback_;
1509 TestCompletionCallback callback2_;
1510};
1511
1512// This test covers the case where, within the same DoReleaseSocket() callback,
1513// we release the just acquired socket and start up a new request. See bug
1514// 36871 for details.
1515TEST_F(ClientSocketPoolBaseTest, ReleasedSocketReleasesToo) {
1516 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1517
1518 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1519
1520 // Complete one request and release the socket.
1521 ClientSocketHandle handle;
1522 TestCompletionCallback callback;
[email protected]a796bcec2010-03-22 17:17:261523 EXPECT_EQ(OK, InitHandle(&handle, "a", kDefaultPriority, &callback, pool_,
1524 NULL));
[email protected]4f1e4982010-03-02 18:31:041525 handle.Reset();
[email protected]6b624c62010-03-14 08:37:321526
[email protected]4f1e4982010-03-02 18:31:041527 // Before the DoReleaseSocket() task has run, start up a
1528 // TestReleasingSocketRequest. This one will be ERR_IO_PENDING since
1529 // num_releasing_sockets > 0 and there was no idle socket to use yet.
1530 TestReleasingSocketRequest request(pool_.get());
[email protected]a796bcec2010-03-22 17:17:261531 EXPECT_EQ(ERR_IO_PENDING, InitHandle(request.handle(), "a", kDefaultPriority,
1532 &request, pool_, NULL));
[email protected]4f1e4982010-03-02 18:31:041533
1534 EXPECT_EQ(OK, request.WaitForResult());
1535}
1536
[email protected]f6d1d6eb2009-06-24 20:16:091537} // namespace
1538
1539} // namespace net