blob: 5f0695a3a2ec5630abc0b1dc3f39c3638574ab7d [file] [log] [blame]
[email protected]9b6fee12009-09-29 18:13:071// Copyright (c) 2009 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
7#include "base/compiler_specific.h"
8#include "base/message_loop.h"
[email protected]974ebd62009-08-03 23:14:349#include "base/platform_thread.h"
[email protected]c9d6a1d2009-07-14 16:15:2010#include "base/scoped_vector.h"
[email protected]fd7b7c92009-08-20 19:38:3011#include "net/base/load_log.h"
12#include "net/base/load_log_unittest.h"
[email protected]f6d1d6eb2009-06-24 20:16:0913#include "net/base/net_errors.h"
14#include "net/base/test_completion_callback.h"
15#include "net/socket/client_socket.h"
16#include "net/socket/client_socket_factory.h"
17#include "net/socket/client_socket_handle.h"
[email protected]75439d3b2009-07-23 22:11:1718#include "net/socket/socket_test_util.h"
[email protected]f6d1d6eb2009-06-24 20:16:0919#include "testing/gtest/include/gtest/gtest.h"
20
21namespace net {
22
23namespace {
24
[email protected]211d21722009-07-22 15:48:5325const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2026const int kDefaultMaxSocketsPerGroup = 2;
[email protected]0b7648c2009-07-06 20:14:0127const int kDefaultPriority = 5;
28
[email protected]d80a4322009-08-14 07:07:4929typedef ClientSocketPoolBase<const void*> TestClientSocketPoolBase;
30
[email protected]f6d1d6eb2009-06-24 20:16:0931class MockClientSocket : public ClientSocket {
32 public:
33 MockClientSocket() : connected_(false) {}
34
[email protected]ab838892009-06-30 18:49:0535 // Socket methods:
36 virtual int Read(
37 IOBuffer* /* buf */, int /* len */, CompletionCallback* /* callback */) {
38 return ERR_UNEXPECTED;
39 }
40
41 virtual int Write(
42 IOBuffer* /* buf */, int /* len */, CompletionCallback* /* callback */) {
43 return ERR_UNEXPECTED;
44 }
[email protected]d3f66572009-09-09 22:38:0445 virtual bool SetReceiveBufferSize(int32 size) { return true; };
46 virtual bool SetSendBufferSize(int32 size) { return true; };
[email protected]ab838892009-06-30 18:49:0547
[email protected]f6d1d6eb2009-06-24 20:16:0948 // ClientSocket methods:
[email protected]ab838892009-06-30 18:49:0549
[email protected]5a05c47a2009-11-02 23:25:1950 virtual int Connect(CompletionCallback* callback, LoadLog* load_log) {
[email protected]f6d1d6eb2009-06-24 20:16:0951 connected_ = true;
52 return OK;
53 }
[email protected]f6d1d6eb2009-06-24 20:16:0954
[email protected]ab838892009-06-30 18:49:0555 virtual void Disconnect() { connected_ = false; }
56 virtual bool IsConnected() const { return connected_; }
57 virtual bool IsConnectedAndIdle() const { return connected_; }
[email protected]0b7648c2009-07-06 20:14:0158
[email protected]ab838892009-06-30 18:49:0559#if defined(OS_LINUX)
60 virtual int GetPeerName(struct sockaddr* /* name */,
61 socklen_t* /* namelen */) {
62 return 0;
[email protected]f6d1d6eb2009-06-24 20:16:0963 }
[email protected]ab838892009-06-30 18:49:0564#endif
[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,
118 LoadLog* load_log)
119 : ConnectJob(group_name, request.handle(), timeout_duration,
120 delegate, load_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,
253 LoadLog* load_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_,
260 load_log);
[email protected]ab838892009-06-30 18:49:05261 }
262
263 private:
264 TestConnectJob::JobType job_type_;
[email protected]974ebd62009-08-03 23:14:34265 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57266 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05267
268 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
269};
270
271class TestClientSocketPool : public ClientSocketPool {
272 public:
273 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53274 int max_sockets,
[email protected]ab838892009-06-30 18:49:05275 int max_sockets_per_group,
[email protected]9bf28db2009-08-29 01:35:16276 base::TimeDelta unused_idle_socket_timeout,
277 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49278 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
[email protected]9bf28db2009-08-29 01:35:16279 : base_(max_sockets, max_sockets_per_group,
280 unused_idle_socket_timeout, used_idle_socket_timeout,
281 connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05282
283 virtual int RequestSocket(
284 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49285 const void* params,
[email protected]ab838892009-06-30 18:49:05286 int priority,
287 ClientSocketHandle* handle,
[email protected]684970b2009-08-14 04:54:46288 CompletionCallback* callback,
289 LoadLog* load_log) {
[email protected]d80a4322009-08-14 07:07:49290 return base_.RequestSocket(
291 group_name, params, priority, handle, callback, load_log);
[email protected]ab838892009-06-30 18:49:05292 }
293
294 virtual void CancelRequest(
295 const std::string& group_name,
296 const ClientSocketHandle* handle) {
[email protected]d80a4322009-08-14 07:07:49297 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05298 }
299
300 virtual void ReleaseSocket(
301 const std::string& group_name,
302 ClientSocket* socket) {
[email protected]d80a4322009-08-14 07:07:49303 base_.ReleaseSocket(group_name, socket);
[email protected]ab838892009-06-30 18:49:05304 }
305
306 virtual void CloseIdleSockets() {
[email protected]d80a4322009-08-14 07:07:49307 base_.CloseIdleSockets();
[email protected]ab838892009-06-30 18:49:05308 }
309
[email protected]d80a4322009-08-14 07:07:49310 virtual int IdleSocketCount() const { return base_.idle_socket_count(); }
[email protected]ab838892009-06-30 18:49:05311
312 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49313 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05314 }
315
316 virtual LoadState GetLoadState(const std::string& group_name,
317 const ClientSocketHandle* handle) const {
[email protected]d80a4322009-08-14 07:07:49318 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05319 }
320
[email protected]d80a4322009-08-14 07:07:49321 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20322
[email protected]974ebd62009-08-03 23:14:34323 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49324 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34325 }
326
[email protected]9bf28db2009-08-29 01:35:16327 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
328
[email protected]ab838892009-06-30 18:49:05329 private:
[email protected]d80a4322009-08-14 07:07:49330 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05331
332 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
333};
334
[email protected]a937a06d2009-08-19 21:19:24335} // namespace
336
337REGISTER_SOCKET_PARAMS_FOR_POOL(TestClientSocketPool, const void*);
338
339namespace {
340
[email protected]5fc08e32009-07-15 17:09:57341void MockClientSocketFactory::SignalJobs() {
342 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
343 it != waiting_jobs_.end(); ++it) {
344 (*it)->Signal();
345 }
346 waiting_jobs_.clear();
347}
348
[email protected]974ebd62009-08-03 23:14:34349class TestConnectJobDelegate : public ConnectJob::Delegate {
350 public:
351 TestConnectJobDelegate()
352 : have_result_(false), waiting_for_result_(false), result_(OK) {}
353 virtual ~TestConnectJobDelegate() {}
354
355 virtual void OnConnectJobComplete(int result, ConnectJob* job) {
356 result_ = result;
[email protected]6e713f02009-08-06 02:56:40357 scoped_ptr<ClientSocket> socket(job->ReleaseSocket());
[email protected]9b6fee12009-09-29 18:13:07358 // socket.get() should be NULL iff result != OK
359 EXPECT_EQ(socket.get() == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34360 delete job;
361 have_result_ = true;
362 if (waiting_for_result_)
363 MessageLoop::current()->Quit();
364 }
365
366 int WaitForResult() {
367 DCHECK(!waiting_for_result_);
368 while (!have_result_) {
369 waiting_for_result_ = true;
370 MessageLoop::current()->Run();
371 waiting_for_result_ = false;
372 }
373 have_result_ = false; // auto-reset for next callback
374 return result_;
375 }
376
377 private:
378 bool have_result_;
379 bool waiting_for_result_;
380 int result_;
381};
382
[email protected]75439d3b2009-07-23 22:11:17383class ClientSocketPoolBaseTest : public ClientSocketPoolTest {
[email protected]f6d1d6eb2009-06-24 20:16:09384 protected:
[email protected]17a0c6c2009-08-04 00:07:04385 ClientSocketPoolBaseTest() {}
[email protected]c9d6a1d2009-07-14 16:15:20386
[email protected]211d21722009-07-22 15:48:53387 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16388 CreatePoolWithIdleTimeouts(
389 max_sockets,
390 max_sockets_per_group,
391 base::TimeDelta::FromSeconds(kUnusedIdleSocketTimeout),
392 base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout));
393 }
394
395 void CreatePoolWithIdleTimeouts(
396 int max_sockets, int max_sockets_per_group,
397 base::TimeDelta unused_idle_socket_timeout,
398 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20399 DCHECK(!pool_.get());
[email protected]17a0c6c2009-08-04 00:07:04400 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_);
[email protected]211d21722009-07-22 15:48:53401 pool_ = new TestClientSocketPool(max_sockets,
402 max_sockets_per_group,
[email protected]9bf28db2009-08-29 01:35:16403 unused_idle_socket_timeout,
404 used_idle_socket_timeout,
[email protected]c9d6a1d2009-07-14 16:15:20405 connect_job_factory_);
406 }
[email protected]f6d1d6eb2009-06-24 20:16:09407
[email protected]75439d3b2009-07-23 22:11:17408 int StartRequest(const std::string& group_name, int priority) {
[email protected]a937a06d2009-08-19 21:19:24409 return StartRequestUsingPool<TestClientSocketPool, const void*>(
410 pool_.get(), group_name, priority, NULL);
[email protected]f6d1d6eb2009-06-24 20:16:09411 }
412
413 virtual void TearDown() {
[email protected]6b175382009-10-13 06:47:47414 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
415 // actually become pending until 2ms after they have been created. In order
416 // to flush all tasks, we need to wait so that we know there are no
417 // soon-to-be-pending tasks waiting.
418 PlatformThread::Sleep(10);
419 MessageLoop::current()->RunAllPending();
420
[email protected]211d21722009-07-22 15:48:53421 // Need to delete |pool_| before we turn late binding back off. We also need
422 // to delete |requests_| because the pool is reference counted and requests
423 // keep reference to it.
424 // TODO(willchan): Remove this part when late binding becomes the default.
[email protected]5fc08e32009-07-15 17:09:57425 pool_ = NULL;
[email protected]211d21722009-07-22 15:48:53426 requests_.reset();
427
[email protected]d80a4322009-08-14 07:07:49428 EnableLateBindingOfSockets(false);
[email protected]75439d3b2009-07-23 22:11:17429
430 ClientSocketPoolTest::TearDown();
[email protected]f6d1d6eb2009-06-24 20:16:09431 }
432
[email protected]f6d1d6eb2009-06-24 20:16:09433 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04434 TestConnectJobFactory* connect_job_factory_;
[email protected]c9d6a1d2009-07-14 16:15:20435 scoped_refptr<TestClientSocketPool> pool_;
[email protected]f6d1d6eb2009-06-24 20:16:09436};
437
[email protected]a937a06d2009-08-19 21:19:24438// Helper function which explicitly specifies the template parameters, since
439// the compiler will infer (in this case, incorrectly) that NULL is of type int.
440int InitHandle(ClientSocketHandle* handle,
441 const std::string& group_name,
442 int priority,
443 CompletionCallback* callback,
444 TestClientSocketPool* pool,
445 LoadLog* load_log) {
446 return handle->Init<const void*, TestClientSocketPool>(
447 group_name, NULL, priority, callback, pool, load_log);
448}
449
[email protected]974ebd62009-08-03 23:14:34450// Even though a timeout is specified, it doesn't time out on a synchronous
451// completion.
452TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
453 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06454 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49455 TestClientSocketPoolBase::Request request(
456 &ignored, NULL, kDefaultPriority, NULL, NULL);
[email protected]974ebd62009-08-03 23:14:34457 scoped_ptr<TestConnectJob> job(
458 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:12459 "a",
[email protected]974ebd62009-08-03 23:14:34460 request,
461 base::TimeDelta::FromMicroseconds(1),
462 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30463 &client_socket_factory_,
464 NULL));
[email protected]974ebd62009-08-03 23:14:34465 EXPECT_EQ(OK, job->Connect());
466}
467
468TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
469 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06470 ClientSocketHandle ignored;
[email protected]fd7b7c92009-08-20 19:38:30471 scoped_refptr<LoadLog> log(new LoadLog);
[email protected]d80a4322009-08-14 07:07:49472 TestClientSocketPoolBase::Request request(
473 &ignored, NULL, kDefaultPriority, NULL, NULL);
[email protected]974ebd62009-08-03 23:14:34474 // Deleted by TestConnectJobDelegate.
475 TestConnectJob* job =
476 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12477 "a",
[email protected]974ebd62009-08-03 23:14:34478 request,
479 base::TimeDelta::FromMicroseconds(1),
480 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30481 &client_socket_factory_,
482 log);
[email protected]974ebd62009-08-03 23:14:34483 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
484 PlatformThread::Sleep(1);
485 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30486
487 EXPECT_EQ(3u, log->events().size());
488 ExpectLogContains(log, 0, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
489 LoadLog::PHASE_BEGIN);
490 ExpectLogContains(log, 1, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
491 LoadLog::PHASE_NONE);
492 ExpectLogContains(log, 2, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
493 LoadLog::PHASE_END);
[email protected]974ebd62009-08-03 23:14:34494}
495
[email protected]5fc08e32009-07-15 17:09:57496TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53497 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20498
[email protected]f6d1d6eb2009-06-24 20:16:09499 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06500 ClientSocketHandle handle;
[email protected]fd7b7c92009-08-20 19:38:30501 scoped_refptr<LoadLog> log(new LoadLog);
[email protected]a937a06d2009-08-19 21:19:24502 EXPECT_EQ(OK, InitHandle(&handle, "a", kDefaultPriority,
[email protected]fd7b7c92009-08-20 19:38:30503 &callback, pool_.get(), log));
[email protected]f6d1d6eb2009-06-24 20:16:09504 EXPECT_TRUE(handle.is_initialized());
505 EXPECT_TRUE(handle.socket());
[email protected]f6d1d6eb2009-06-24 20:16:09506 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:30507
508 EXPECT_EQ(4u, log->events().size());
509 ExpectLogContains(log, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
510 ExpectLogContains(log, 1, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
511 LoadLog::PHASE_BEGIN);
512 ExpectLogContains(log, 2, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
513 LoadLog::PHASE_END);
514 ExpectLogContains(log, 3, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
[email protected]f6d1d6eb2009-06-24 20:16:09515}
516
[email protected]5fc08e32009-07-15 17:09:57517TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:53518 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:57519
520 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]fd7b7c92009-08-20 19:38:30521 scoped_refptr<LoadLog> log(new LoadLog);
[email protected]a512f5982009-08-18 16:01:06522 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]fd7b7c92009-08-20 19:38:30523 int rv = InitHandle(req.handle(), "a", 0, &req, pool_.get(), log);
[email protected]5fc08e32009-07-15 17:09:57524 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:33525 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:57526 EXPECT_EQ(OK, req.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:33527 EXPECT_TRUE(req.handle()->is_initialized());
528 EXPECT_TRUE(req.handle()->socket());
529 req.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:30530
531 EXPECT_EQ(4u, log->events().size());
532 ExpectLogContains(log, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
533 ExpectLogContains(log, 1, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
534 LoadLog::PHASE_BEGIN);
535 ExpectLogContains(log, 2, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
536 LoadLog::PHASE_END);
537 ExpectLogContains(log, 3, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
[email protected]5fc08e32009-07-15 17:09:57538}
539
[email protected]ab838892009-06-30 18:49:05540TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53541 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20542
[email protected]ab838892009-06-30 18:49:05543 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]fd7b7c92009-08-20 19:38:30544 scoped_refptr<LoadLog> log(new LoadLog);
[email protected]a512f5982009-08-18 16:01:06545 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]3ae82302009-06-26 06:01:21546 EXPECT_EQ(ERR_CONNECTION_FAILED,
[email protected]a937a06d2009-08-19 21:19:24547 InitHandle(req.handle(), "a", kDefaultPriority, &req,
[email protected]fd7b7c92009-08-20 19:38:30548 pool_.get(), log));
549
550 EXPECT_EQ(4u, log->events().size());
551 ExpectLogContains(log, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
552 ExpectLogContains(log, 1, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
553 LoadLog::PHASE_BEGIN);
554 ExpectLogContains(log, 2, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
555 LoadLog::PHASE_END);
556 ExpectLogContains(log, 3, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
[email protected]f6d1d6eb2009-06-24 20:16:09557}
558
[email protected]5fc08e32009-07-15 17:09:57559TEST_F(ClientSocketPoolBaseTest, InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:53560 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:57561
562 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]fd7b7c92009-08-20 19:38:30563 scoped_refptr<LoadLog> log(new LoadLog);
[email protected]a512f5982009-08-18 16:01:06564 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]5fc08e32009-07-15 17:09:57565 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:24566 InitHandle(req.handle(), "a", kDefaultPriority, &req,
[email protected]fd7b7c92009-08-20 19:38:30567 pool_.get(), log));
[email protected]a6c59f62009-07-29 16:33:33568 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:57569 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30570
571 EXPECT_EQ(4u, log->events().size());
572 ExpectLogContains(log, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
573 ExpectLogContains(log, 1, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
574 LoadLog::PHASE_BEGIN);
575 ExpectLogContains(log, 2, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
576 LoadLog::PHASE_END);
577 ExpectLogContains(log, 3, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
[email protected]5fc08e32009-07-15 17:09:57578}
579
[email protected]211d21722009-07-22 15:48:53580TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
581 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
582
[email protected]fd7b7c92009-08-20 19:38:30583 // TODO(eroman): Check that the LoadLog contains this event.
584
[email protected]211d21722009-07-22 15:48:53585 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
586 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
587 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
588 EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
589
590 EXPECT_EQ(static_cast<int>(requests_.size()),
591 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17592 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53593
594 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
595 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
596 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
597
598 ReleaseAllConnections(KEEP_ALIVE);
599
600 EXPECT_EQ(static_cast<int>(requests_.size()),
601 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17602 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53603
604 EXPECT_EQ(1, GetOrderOfRequest(1));
605 EXPECT_EQ(2, GetOrderOfRequest(2));
606 EXPECT_EQ(3, GetOrderOfRequest(3));
607 EXPECT_EQ(4, GetOrderOfRequest(4));
608 EXPECT_EQ(5, GetOrderOfRequest(5));
609 EXPECT_EQ(6, GetOrderOfRequest(6));
610 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17611
612 // Make sure we test order of all requests made.
613 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53614}
615
616TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
617 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
618
[email protected]fd7b7c92009-08-20 19:38:30619 // TODO(eroman): Check that the LoadLog contains this event.
620
[email protected]211d21722009-07-22 15:48:53621 // Reach all limits: max total sockets, and max sockets per group.
622 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
623 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
624 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
625 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
626
627 EXPECT_EQ(static_cast<int>(requests_.size()),
628 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17629 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53630
631 // Now create a new group and verify that we don't starve it.
632 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
633
634 ReleaseAllConnections(KEEP_ALIVE);
635
636 EXPECT_EQ(static_cast<int>(requests_.size()),
637 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17638 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53639
640 EXPECT_EQ(1, GetOrderOfRequest(1));
641 EXPECT_EQ(2, GetOrderOfRequest(2));
642 EXPECT_EQ(3, GetOrderOfRequest(3));
643 EXPECT_EQ(4, GetOrderOfRequest(4));
644 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17645
646 // Make sure we test order of all requests made.
647 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53648}
649
650TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
651 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
652
653 EXPECT_EQ(OK, StartRequest("b", 3));
654 EXPECT_EQ(OK, StartRequest("a", 3));
655 EXPECT_EQ(OK, StartRequest("b", 6));
656 EXPECT_EQ(OK, StartRequest("a", 6));
657
658 EXPECT_EQ(static_cast<int>(requests_.size()),
659 client_socket_factory_.allocation_count());
660
661 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", 4));
662 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 5));
663 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", 7));
664
665 ReleaseAllConnections(KEEP_ALIVE);
666
667 // We're re-using one socket for group "a", and one for "b".
668 EXPECT_EQ(static_cast<int>(requests_.size()) - 2,
669 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17670 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53671
672 // First 4 requests don't have to wait, and finish in order.
673 EXPECT_EQ(1, GetOrderOfRequest(1));
674 EXPECT_EQ(2, GetOrderOfRequest(2));
675 EXPECT_EQ(3, GetOrderOfRequest(3));
676 EXPECT_EQ(4, GetOrderOfRequest(4));
677
678 // Request ("b", 7) has the highest priority, then ("a", 5),
679 // and then ("c", 4).
680 EXPECT_EQ(7, GetOrderOfRequest(5));
681 EXPECT_EQ(6, GetOrderOfRequest(6));
682 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17683
684 // Make sure we test order of all requests made.
685 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53686}
687
688TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
689 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
690
691 EXPECT_EQ(OK, StartRequest("a", 3));
692 EXPECT_EQ(OK, StartRequest("a", 6));
693 EXPECT_EQ(OK, StartRequest("b", 3));
694 EXPECT_EQ(OK, StartRequest("b", 6));
695
696 EXPECT_EQ(static_cast<int>(requests_.size()),
697 client_socket_factory_.allocation_count());
698
699 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", 6));
700 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
701 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", 7));
702
703 ReleaseAllConnections(KEEP_ALIVE);
704
705 // We're re-using one socket for group "a", and one for "b".
706 EXPECT_EQ(static_cast<int>(requests_.size()) - 2,
707 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17708 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53709
710 // First 4 requests don't have to wait, and finish in order.
711 EXPECT_EQ(1, GetOrderOfRequest(1));
712 EXPECT_EQ(2, GetOrderOfRequest(2));
713 EXPECT_EQ(3, GetOrderOfRequest(3));
714 EXPECT_EQ(4, GetOrderOfRequest(4));
715
716 // Request ("b", 7) has the highest priority, but we can't make new socket for
717 // group "b", because it has reached the per-group limit. Then we make
718 // socket for ("c", 6), because it has higher priority than ("a", 4),
719 // and we still can't make a socket for group "b".
720 EXPECT_EQ(5, GetOrderOfRequest(5));
721 EXPECT_EQ(6, GetOrderOfRequest(6));
722 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17723
724 // Make sure we test order of all requests made.
725 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53726}
727
728// Make sure that we count connecting sockets against the total limit.
729TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
730 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
731
732 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
733 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
734 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
735
736 // Create one asynchronous request.
737 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
738 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
739
[email protected]6b175382009-10-13 06:47:47740 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
741 // actually become pending until 2ms after they have been created. In order
742 // to flush all tasks, we need to wait so that we know there are no
743 // soon-to-be-pending tasks waiting.
744 PlatformThread::Sleep(10);
745 MessageLoop::current()->RunAllPending();
746
[email protected]211d21722009-07-22 15:48:53747 // The next synchronous request should wait for its turn.
748 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
749 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
750
751 ReleaseAllConnections(KEEP_ALIVE);
752
753 EXPECT_EQ(static_cast<int>(requests_.size()),
754 client_socket_factory_.allocation_count());
755
756 EXPECT_EQ(1, GetOrderOfRequest(1));
757 EXPECT_EQ(2, GetOrderOfRequest(2));
758 EXPECT_EQ(3, GetOrderOfRequest(3));
759 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:17760 EXPECT_EQ(5, GetOrderOfRequest(5));
761
762 // Make sure we test order of all requests made.
763 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53764}
765
766// Inside ClientSocketPoolBase we have a may_have_stalled_group flag,
767// which tells it to use more expensive, but accurate, group selection
768// algorithm. Make sure it doesn't get stuck in the "on" state.
769TEST_F(ClientSocketPoolBaseTest, MayHaveStalledGroupReset) {
770 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
771
772 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
773
774 // Reach group socket limit.
775 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
776 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
777 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
778
779 // Reach total limit, but don't request more sockets.
780 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
781 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
782 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
783
784 // Request one more socket while we are at the maximum sockets limit.
785 // This should flip the may_have_stalled_group flag.
786 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
787 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
788
789 // After releasing first connection for "a", we're still at the
790 // maximum sockets limit, but every group's pending queue is empty,
791 // so we reset the flag.
792 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
793 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
794
795 // Requesting additional socket while at the total limit should
796 // flip the flag back to "on".
797 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
798 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
799
800 // We'll request one more socket to verify that we don't reset the flag
801 // too eagerly.
802 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
803 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
804
805 // We're at the maximum socket limit, and still have one request pending
806 // for "d". Flag should be "on".
807 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
808 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
809
810 // Now every group's pending queue should be empty again.
811 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
812 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
813
814 ReleaseAllConnections(KEEP_ALIVE);
815 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
816}
817
[email protected]ab838892009-06-30 18:49:05818TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:53819 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09820
[email protected]c9d6a1d2009-07-14 16:15:20821 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
822 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
823 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
824 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 3));
825 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
826 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 2));
827 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
[email protected]f6d1d6eb2009-06-24 20:16:09828
[email protected]c9d6a1d2009-07-14 16:15:20829 ReleaseAllConnections(KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09830
[email protected]c9d6a1d2009-07-14 16:15:20831 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
832 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17833 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09834
[email protected]c9d6a1d2009-07-14 16:15:20835 EXPECT_EQ(1, GetOrderOfRequest(1));
836 EXPECT_EQ(2, GetOrderOfRequest(2));
837 EXPECT_EQ(6, GetOrderOfRequest(3));
838 EXPECT_EQ(4, GetOrderOfRequest(4));
839 EXPECT_EQ(3, GetOrderOfRequest(5));
840 EXPECT_EQ(5, GetOrderOfRequest(6));
841 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17842
843 // Make sure we test order of all requests made.
844 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:09845}
846
[email protected]ab838892009-06-30 18:49:05847TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:53848 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09849
[email protected]c9d6a1d2009-07-14 16:15:20850 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
851 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
852 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
853 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 3));
854 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
855 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 2));
856 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
[email protected]f6d1d6eb2009-06-24 20:16:09857
[email protected]c9d6a1d2009-07-14 16:15:20858 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09859
[email protected]c9d6a1d2009-07-14 16:15:20860 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i)
861 EXPECT_EQ(OK, requests_[i]->WaitForResult());
862
863 EXPECT_EQ(static_cast<int>(requests_.size()),
864 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17865 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09866}
867
868// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:05869// The pending connect job will be cancelled and should not call back into
870// ClientSocketPoolBase.
871TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:53872 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20873
[email protected]ab838892009-06-30 18:49:05874 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:06875 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]ab838892009-06-30 18:49:05876 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:24877 InitHandle(req.handle(), "a", kDefaultPriority, &req,
878 pool_.get(), NULL));
[email protected]a6c59f62009-07-29 16:33:33879 req.handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:09880}
881
[email protected]ab838892009-06-30 18:49:05882TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]211d21722009-07-22 15:48:53883 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20884
[email protected]ab838892009-06-30 18:49:05885 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:06886 TestSocketRequest req(&request_order_, &completion_count_);
887 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09888
[email protected]ab838892009-06-30 18:49:05889 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:24890 InitHandle(req.handle(), "a", kDefaultPriority, &req,
891 pool_.get(), NULL));
[email protected]ab838892009-06-30 18:49:05892 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:24893 InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
894 pool_.get(), NULL));
[email protected]f6d1d6eb2009-06-24 20:16:09895
[email protected]a6c59f62009-07-29 16:33:33896 req.handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:09897
898 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:33899 req2.handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:09900}
901
[email protected]ab838892009-06-30 18:49:05902TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:53903 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20904
[email protected]ab838892009-06-30 18:49:05905 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:06906 ClientSocketHandle handle;
[email protected]f6d1d6eb2009-06-24 20:16:09907 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06908 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09909
[email protected]ab838892009-06-30 18:49:05910 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:24911 InitHandle(&handle, "a", kDefaultPriority, &callback,
912 pool_.get(), NULL));
[email protected]f6d1d6eb2009-06-24 20:16:09913
914 handle.Reset();
915
916 TestCompletionCallback callback2;
[email protected]ab838892009-06-30 18:49:05917 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:24918 InitHandle(&handle, "a", kDefaultPriority, &callback2,
919 pool_.get(), NULL));
[email protected]f6d1d6eb2009-06-24 20:16:09920
921 EXPECT_EQ(OK, callback2.WaitForResult());
922 EXPECT_FALSE(callback.have_result());
923
924 handle.Reset();
925}
926
[email protected]ab838892009-06-30 18:49:05927TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:53928 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09929
[email protected]c9d6a1d2009-07-14 16:15:20930 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
931 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
932 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
933 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 3));
934 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
935 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 2));
936 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
[email protected]f6d1d6eb2009-06-24 20:16:09937
938 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:20939 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]a6c59f62009-07-29 16:33:33940 EXPECT_FALSE(requests_[index_to_cancel]->handle()->is_initialized());
941 requests_[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:09942
[email protected]c9d6a1d2009-07-14 16:15:20943 ReleaseAllConnections(KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09944
[email protected]c9d6a1d2009-07-14 16:15:20945 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
946 client_socket_factory_.allocation_count());
947 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup - 1,
[email protected]75439d3b2009-07-23 22:11:17948 completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09949
[email protected]c9d6a1d2009-07-14 16:15:20950 EXPECT_EQ(1, GetOrderOfRequest(1));
951 EXPECT_EQ(2, GetOrderOfRequest(2));
952 EXPECT_EQ(5, GetOrderOfRequest(3));
953 EXPECT_EQ(3, GetOrderOfRequest(4));
954 EXPECT_EQ(kRequestNotFound, GetOrderOfRequest(5)); // Canceled request.
955 EXPECT_EQ(4, GetOrderOfRequest(6));
956 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17957
958 // Make sure we test order of all requests made.
959 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:09960}
961
962class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
963 public:
[email protected]2ab05b52009-07-01 23:57:58964 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:24965 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:58966 TestConnectJobFactory* test_connect_job_factory,
967 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:09968 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:06969 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:58970 within_callback_(false),
971 test_connect_job_factory_(test_connect_job_factory),
972 next_job_type_(next_job_type) {}
[email protected]f6d1d6eb2009-06-24 20:16:09973
974 virtual void RunWithParams(const Tuple1<int>& params) {
975 callback_.RunWithParams(params);
976 ASSERT_EQ(OK, params.a);
977
978 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:58979 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]f6d1d6eb2009-06-24 20:16:09980 handle_->Reset();
981 within_callback_ = true;
[email protected]6b175382009-10-13 06:47:47982 TestCompletionCallback next_job_callback;
[email protected]a937a06d2009-08-19 21:19:24983 int rv = InitHandle(
[email protected]6b175382009-10-13 06:47:47984 handle_, "a", kDefaultPriority, &next_job_callback, pool_.get(),
985 NULL);
[email protected]2ab05b52009-07-01 23:57:58986 switch (next_job_type_) {
987 case TestConnectJob::kMockJob:
988 EXPECT_EQ(OK, rv);
989 break;
990 case TestConnectJob::kMockPendingJob:
991 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:47992
993 // For pending jobs, wait for new socket to be created. This makes
994 // sure there are no more pending operations nor any unclosed sockets
995 // when the test finishes.
996 // We need to give it a little bit of time to run, so that all the
997 // operations that happen on timers (e.g. cleanup of idle
998 // connections) can execute.
999 MessageLoop::current()->SetNestableTasksAllowed(true);
1000 PlatformThread::Sleep(10);
1001 EXPECT_EQ(OK, next_job_callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581002 break;
1003 default:
1004 FAIL() << "Unexpected job type: " << next_job_type_;
1005 break;
1006 }
[email protected]f6d1d6eb2009-06-24 20:16:091007 }
1008 }
1009
1010 int WaitForResult() {
1011 return callback_.WaitForResult();
1012 }
1013
1014 private:
1015 ClientSocketHandle* const handle_;
[email protected]a937a06d2009-08-19 21:19:241016 const scoped_refptr<TestClientSocketPool> pool_;
[email protected]f6d1d6eb2009-06-24 20:16:091017 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:581018 TestConnectJobFactory* const test_connect_job_factory_;
1019 TestConnectJob::JobType next_job_type_;
[email protected]f6d1d6eb2009-06-24 20:16:091020 TestCompletionCallback callback_;
1021};
1022
[email protected]2ab05b52009-07-01 23:57:581023TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531024 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201025
[email protected]0b7648c2009-07-06 20:14:011026 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061027 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581028 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061029 &handle, pool_.get(), connect_job_factory_,
1030 TestConnectJob::kMockPendingJob);
[email protected]a937a06d2009-08-19 21:19:241031 int rv = InitHandle(&handle, "a", kDefaultPriority, &callback,
1032 pool_.get(), NULL);
[email protected]f6d1d6eb2009-06-24 20:16:091033 ASSERT_EQ(ERR_IO_PENDING, rv);
1034
1035 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581036 handle.Reset();
1037}
[email protected]f6d1d6eb2009-06-24 20:16:091038
[email protected]2ab05b52009-07-01 23:57:581039TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531040 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201041
[email protected]0b7648c2009-07-06 20:14:011042 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061043 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581044 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061045 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]a937a06d2009-08-19 21:19:241046 int rv = InitHandle(&handle, "a", kDefaultPriority, &callback,
1047 pool_.get(), NULL);
[email protected]2ab05b52009-07-01 23:57:581048 ASSERT_EQ(ERR_IO_PENDING, rv);
1049
1050 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091051 handle.Reset();
1052}
1053
1054// Make sure that pending requests get serviced after active requests get
1055// cancelled.
[email protected]ab838892009-06-30 18:49:051056TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531057 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201058
[email protected]0b7648c2009-07-06 20:14:011059 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091060
[email protected]c9d6a1d2009-07-14 16:15:201061 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1062 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1063 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1064 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1065 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1066 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1067 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091068
[email protected]c9d6a1d2009-07-14 16:15:201069 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1070 // Let's cancel them.
1071 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]a6c59f62009-07-29 16:33:331072 ASSERT_FALSE(requests_[i]->handle()->is_initialized());
1073 requests_[i]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091074 }
1075
[email protected]f6d1d6eb2009-06-24 20:16:091076 // Let's wait for the rest to complete now.
[email protected]c9d6a1d2009-07-14 16:15:201077 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i) {
1078 EXPECT_EQ(OK, requests_[i]->WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331079 requests_[i]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091080 }
1081
[email protected]75439d3b2009-07-23 22:11:171082 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091083}
1084
1085// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051086TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531087 const size_t kMaxSockets = 5;
1088 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201089
[email protected]0b7648c2009-07-06 20:14:011090 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091091
[email protected]211d21722009-07-22 15:48:531092 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1093 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091094
1095 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531096 for (size_t i = 0; i < kNumberOfRequests; ++i)
1097 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091098
[email protected]211d21722009-07-22 15:48:531099 for (size_t i = 0; i < kNumberOfRequests; ++i)
1100 EXPECT_EQ(ERR_CONNECTION_FAILED, requests_[i]->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091101}
1102
[email protected]5fc08e32009-07-15 17:09:571103TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531104 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571105
1106 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1107
[email protected]a512f5982009-08-18 16:01:061108 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241109 int rv = InitHandle(req.handle(), "a", kDefaultPriority, &req,
1110 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571111 EXPECT_EQ(ERR_IO_PENDING, rv);
1112
1113 // Cancel the active request.
[email protected]a6c59f62009-07-29 16:33:331114 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571115
[email protected]a937a06d2009-08-19 21:19:241116 rv = InitHandle(req.handle(), "a", kDefaultPriority, &req,
1117 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571118 EXPECT_EQ(ERR_IO_PENDING, rv);
1119 EXPECT_EQ(OK, req.WaitForResult());
1120
[email protected]a6c59f62009-07-29 16:33:331121 EXPECT_FALSE(req.handle()->is_reused());
[email protected]75439d3b2009-07-23 22:11:171122 EXPECT_EQ(1U, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571123 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1124}
1125
[email protected]2ab05b52009-07-01 23:57:581126// A pending asynchronous job completes, which will free up a socket slot. The
1127// next job finishes synchronously. The callback for the asynchronous job
1128// should be first though.
1129TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531130 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201131
[email protected]2ab05b52009-07-01 23:57:581132 // First two jobs are async.
[email protected]0b7648c2009-07-06 20:14:011133 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2ab05b52009-07-01 23:57:581134
1135 // Start job 1 (async error).
[email protected]a512f5982009-08-18 16:01:061136 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241137 int rv = InitHandle(req1.handle(), "a", kDefaultPriority, &req1,
1138 pool_.get(), NULL);
[email protected]2ab05b52009-07-01 23:57:581139 EXPECT_EQ(ERR_IO_PENDING, rv);
1140
1141 // Start job 2 (async error).
[email protected]a512f5982009-08-18 16:01:061142 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241143 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
1144 pool_.get(), NULL);
[email protected]2ab05b52009-07-01 23:57:581145 EXPECT_EQ(ERR_IO_PENDING, rv);
1146
1147 // The pending job is sync.
[email protected]0b7648c2009-07-06 20:14:011148 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]2ab05b52009-07-01 23:57:581149
1150 // Request 3 does not have a ConnectJob yet. It's just pending.
[email protected]a512f5982009-08-18 16:01:061151 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241152 rv = InitHandle(
1153 req3.handle(), "a", kDefaultPriority, &req3, pool_.get(), NULL);
[email protected]2ab05b52009-07-01 23:57:581154 EXPECT_EQ(ERR_IO_PENDING, rv);
1155
1156 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1157 EXPECT_EQ(ERR_CONNECTION_FAILED, req2.WaitForResult());
1158 EXPECT_EQ(OK, req3.WaitForResult());
1159
1160 ASSERT_EQ(3U, request_order_.size());
1161
1162 // After job 1 finishes unsuccessfully, it will try to process the pending
1163 // requests queue, so it starts up job 3 for request 3. This job
1164 // synchronously succeeds, so the request order is 1, 3, 2.
1165 EXPECT_EQ(&req1, request_order_[0]);
1166 EXPECT_EQ(&req2, request_order_[2]);
1167 EXPECT_EQ(&req3, request_order_[1]);
1168}
1169
[email protected]5fc08e32009-07-15 17:09:571170// When a ConnectJob is coupled to a request, even if a free socket becomes
1171// available, the request will be serviced by the ConnectJob.
1172TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531173 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]d80a4322009-08-14 07:07:491174 EnableLateBindingOfSockets(false);
[email protected]5fc08e32009-07-15 17:09:571175
1176 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321177 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571178
[email protected]a512f5982009-08-18 16:01:061179 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241180 int rv = InitHandle(req1.handle(), "a", kDefaultPriority, &req1,
1181 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571182 EXPECT_EQ(ERR_IO_PENDING, rv);
1183 EXPECT_EQ(OK, req1.WaitForResult());
1184
1185 // Job 1 finished OK. Start job 2 (also async OK). Release socket 1.
1186 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1187
[email protected]a512f5982009-08-18 16:01:061188 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241189 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
1190 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571191 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331192 req1.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571193 MessageLoop::current()->RunAllPending(); // Run the DoReleaseSocket()
1194
1195 // Job 2 is pending. Start request 3 (which has no associated job since it
1196 // will use the idle socket).
1197
[email protected]a512f5982009-08-18 16:01:061198 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241199 rv = InitHandle(req3.handle(), "a", kDefaultPriority, &req3,
1200 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571201 EXPECT_EQ(OK, rv);
1202
[email protected]a6c59f62009-07-29 16:33:331203 EXPECT_FALSE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571204 client_socket_factory_.SignalJobs();
1205 EXPECT_EQ(OK, req2.WaitForResult());
1206
1207 ASSERT_EQ(2U, request_order_.size());
1208 EXPECT_EQ(&req1, request_order_[0]);
1209 EXPECT_EQ(&req2, request_order_[1]);
1210 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1211}
1212
[email protected]2b7523d2009-07-29 20:29:231213// Regression test for http://crbug.com/17985.
1214TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1215 const int kMaxSockets = 3;
1216 const int kMaxSocketsPerGroup = 2;
1217 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1218
1219 const int kHighPriority = kDefaultPriority + 100;
1220
1221 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1222 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1223
1224 // This is going to be a pending request in an otherwise empty group.
1225 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1226
1227 // Reach the maximum socket limit.
1228 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1229
1230 // Create a stalled group with high priorities.
1231 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1232 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1233 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
1234
1235 // Release the first two sockets from "a", which will make room
1236 // for requests from "c". After that "a" will have no active sockets
1237 // and one pending request.
1238 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1239 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1240
1241 // Closing idle sockets should not get us into trouble, but in the bug
1242 // we were hitting a CHECK here.
1243 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
1244 pool_->CloseIdleSockets();
1245 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1246}
1247
[email protected]5fc08e32009-07-15 17:09:571248class ClientSocketPoolBaseTest_LateBinding : public ClientSocketPoolBaseTest {
1249 protected:
1250 virtual void SetUp() {
1251 ClientSocketPoolBaseTest::SetUp();
[email protected]d80a4322009-08-14 07:07:491252 EnableLateBindingOfSockets(true);
[email protected]5fc08e32009-07-15 17:09:571253 }
1254};
1255
[email protected]6e713f02009-08-06 02:56:401256// Even though a timeout is specified, it doesn't time out on a synchronous
1257// completion.
1258TEST_F(ClientSocketPoolBaseTest_LateBinding,
1259 ConnectJob_NoTimeoutOnSynchronousCompletion) {
1260 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:061261 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:491262 TestClientSocketPoolBase::Request request(&ignored, NULL, 0, NULL, NULL);
[email protected]6e713f02009-08-06 02:56:401263 scoped_ptr<TestConnectJob> job(
1264 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:121265 "a",
[email protected]6e713f02009-08-06 02:56:401266 request,
1267 base::TimeDelta::FromMicroseconds(1),
1268 &delegate,
[email protected]fd7b7c92009-08-20 19:38:301269 &client_socket_factory_,
1270 NULL));
[email protected]6e713f02009-08-06 02:56:401271 EXPECT_EQ(OK, job->Connect());
1272}
1273
1274TEST_F(ClientSocketPoolBaseTest_LateBinding, ConnectJob_TimedOut) {
1275 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:061276 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:491277 TestClientSocketPoolBase::Request request(&ignored, NULL, 0, NULL, NULL);
[email protected]6e713f02009-08-06 02:56:401278 // Deleted by TestConnectJobDelegate.
1279 TestConnectJob* job =
1280 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:121281 "a",
[email protected]6e713f02009-08-06 02:56:401282 request,
1283 base::TimeDelta::FromMicroseconds(1),
1284 &delegate,
[email protected]fd7b7c92009-08-20 19:38:301285 &client_socket_factory_,
1286 NULL);
[email protected]6e713f02009-08-06 02:56:401287 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
1288 PlatformThread::Sleep(1);
1289 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
1290}
1291
[email protected]5fc08e32009-07-15 17:09:571292TEST_F(ClientSocketPoolBaseTest_LateBinding, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:531293 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571294
1295 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:061296 ClientSocketHandle handle;
[email protected]fd7b7c92009-08-20 19:38:301297 scoped_refptr<LoadLog> log(new LoadLog);
[email protected]a937a06d2009-08-19 21:19:241298 EXPECT_EQ(OK, InitHandle(&handle, "a", kDefaultPriority, &callback,
[email protected]fd7b7c92009-08-20 19:38:301299 pool_.get(), log));
[email protected]5fc08e32009-07-15 17:09:571300 EXPECT_TRUE(handle.is_initialized());
1301 EXPECT_TRUE(handle.socket());
1302 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:301303
1304 EXPECT_EQ(4u, log->events().size());
1305 ExpectLogContains(log, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
1306 ExpectLogContains(log, 1, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1307 LoadLog::PHASE_BEGIN);
1308 ExpectLogContains(log, 2, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1309 LoadLog::PHASE_END);
1310 ExpectLogContains(log, 3, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
[email protected]5fc08e32009-07-15 17:09:571311}
1312
1313TEST_F(ClientSocketPoolBaseTest_LateBinding, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531314 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571315
1316 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061317 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]fd7b7c92009-08-20 19:38:301318 scoped_refptr<LoadLog> log(new LoadLog);
1319 int rv = InitHandle(req.handle(), "a", 0, &req, pool_.get(), log);
[email protected]5fc08e32009-07-15 17:09:571320 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331321 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:571322 EXPECT_EQ(OK, req.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331323 EXPECT_TRUE(req.handle()->is_initialized());
1324 EXPECT_TRUE(req.handle()->socket());
1325 req.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:301326
1327 EXPECT_EQ(6u, log->events().size());
1328 ExpectLogContains(log, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
1329 ExpectLogContains(log, 1, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1330 LoadLog::PHASE_BEGIN);
1331 ExpectLogContains(log, 2, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1332 LoadLog::PHASE_END);
1333 ExpectLogContains(log, 3, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1334 LoadLog::PHASE_BEGIN);
1335 ExpectLogContains(log, 4, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1336 LoadLog::PHASE_END);
1337 ExpectLogContains(log, 5, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
[email protected]5fc08e32009-07-15 17:09:571338}
1339
1340TEST_F(ClientSocketPoolBaseTest_LateBinding, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:531341 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571342
1343 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]a512f5982009-08-18 16:01:061344 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]fd7b7c92009-08-20 19:38:301345 scoped_refptr<LoadLog> log(new LoadLog);
[email protected]5fc08e32009-07-15 17:09:571346 EXPECT_EQ(ERR_CONNECTION_FAILED,
[email protected]a937a06d2009-08-19 21:19:241347 InitHandle(req.handle(), "a", kDefaultPriority, &req,
[email protected]fd7b7c92009-08-20 19:38:301348 pool_.get(), log));
1349
1350 EXPECT_EQ(4u, log->events().size());
1351 ExpectLogContains(log, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
1352 ExpectLogContains(log, 1, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1353 LoadLog::PHASE_BEGIN);
1354 ExpectLogContains(log, 2, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1355 LoadLog::PHASE_END);
1356 ExpectLogContains(log, 3, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
[email protected]5fc08e32009-07-15 17:09:571357}
1358
1359TEST_F(ClientSocketPoolBaseTest_LateBinding,
1360 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531361 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571362
1363 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]a512f5982009-08-18 16:01:061364 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]fd7b7c92009-08-20 19:38:301365 scoped_refptr<LoadLog> log(new LoadLog);
[email protected]5fc08e32009-07-15 17:09:571366 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:241367 InitHandle(req.handle(), "a", kDefaultPriority, &req,
[email protected]fd7b7c92009-08-20 19:38:301368 pool_.get(), log));
[email protected]a6c59f62009-07-29 16:33:331369 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:571370 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:301371
1372 EXPECT_EQ(6u, log->events().size());
1373 ExpectLogContains(log, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
1374 ExpectLogContains(log, 1, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1375 LoadLog::PHASE_BEGIN);
1376 ExpectLogContains(log, 2, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1377 LoadLog::PHASE_END);
1378 ExpectLogContains(log, 3, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1379 LoadLog::PHASE_BEGIN);
1380 ExpectLogContains(log, 4, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1381 LoadLog::PHASE_END);
1382 ExpectLogContains(log, 5, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
[email protected]5fc08e32009-07-15 17:09:571383}
1384
1385TEST_F(ClientSocketPoolBaseTest_LateBinding, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531386 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571387
1388 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1389 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1390 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
1391 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 3));
1392 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
1393 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 2));
1394 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
1395
1396 ReleaseAllConnections(KEEP_ALIVE);
1397
1398 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1399 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:171400 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571401
1402 EXPECT_EQ(1, GetOrderOfRequest(1));
1403 EXPECT_EQ(2, GetOrderOfRequest(2));
1404 EXPECT_EQ(6, GetOrderOfRequest(3));
1405 EXPECT_EQ(4, GetOrderOfRequest(4));
1406 EXPECT_EQ(3, GetOrderOfRequest(5));
1407 EXPECT_EQ(5, GetOrderOfRequest(6));
1408 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171409
1410 // Make sure we test order of all requests made.
1411 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]5fc08e32009-07-15 17:09:571412}
1413
1414TEST_F(ClientSocketPoolBaseTest_LateBinding, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531415 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571416
1417 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1418 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1419 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
1420 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 3));
1421 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
1422 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 2));
1423 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
1424
1425 ReleaseAllConnections(NO_KEEP_ALIVE);
1426
1427 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i)
1428 EXPECT_EQ(OK, requests_[i]->WaitForResult());
1429
1430 EXPECT_EQ(static_cast<int>(requests_.size()),
1431 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:171432 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571433}
1434
1435// This test will start up a RequestSocket() and then immediately Cancel() it.
1436// The pending connect job will be cancelled and should not call back into
1437// ClientSocketPoolBase.
1438TEST_F(ClientSocketPoolBaseTest_LateBinding, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531439 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571440
1441 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061442 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]5fc08e32009-07-15 17:09:571443 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:241444 InitHandle(req.handle(), "a", kDefaultPriority, &req,
1445 pool_.get(), NULL));
[email protected]a6c59f62009-07-29 16:33:331446 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571447}
1448
1449TEST_F(ClientSocketPoolBaseTest_LateBinding, TwoRequestsCancelOne) {
[email protected]211d21722009-07-22 15:48:531450 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571451
1452 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061453 TestSocketRequest req(&request_order_, &completion_count_);
1454 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]5fc08e32009-07-15 17:09:571455
[email protected]fd7b7c92009-08-20 19:38:301456 scoped_refptr<LoadLog> log1(new LoadLog);
[email protected]5fc08e32009-07-15 17:09:571457 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:241458 InitHandle(req.handle(), "a", kDefaultPriority, &req,
[email protected]fd7b7c92009-08-20 19:38:301459 pool_.get(), log1));
1460 scoped_refptr<LoadLog> log2(new LoadLog);
[email protected]5fc08e32009-07-15 17:09:571461 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:241462 InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
[email protected]fd7b7c92009-08-20 19:38:301463 pool_.get(), log2));
[email protected]5fc08e32009-07-15 17:09:571464
[email protected]a6c59f62009-07-29 16:33:331465 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571466
[email protected]fd7b7c92009-08-20 19:38:301467 EXPECT_EQ(5u, log1->events().size());
1468 ExpectLogContains(log1, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
1469 ExpectLogContains(log1, 1, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1470 LoadLog::PHASE_BEGIN);
1471 ExpectLogContains(log1, 2, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1472 LoadLog::PHASE_END);
1473 ExpectLogContains(log1, 3, LoadLog::TYPE_CANCELLED, LoadLog::PHASE_NONE);
1474 ExpectLogContains(log1, 4, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
1475
1476 // At this point, request 2 is just waiting for the connect job to finish.
1477 EXPECT_EQ(2u, log2->events().size());
1478 ExpectLogContains(log2, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
1479 ExpectLogContains(log2, 1, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1480 LoadLog::PHASE_BEGIN);
1481
[email protected]5fc08e32009-07-15 17:09:571482 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331483 req2.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:301484
1485 // Now request 2 has actually finished.
1486 EXPECT_EQ(6u, log2->events().size());
1487 ExpectLogContains(log2, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
1488 ExpectLogContains(log2, 1, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1489 LoadLog::PHASE_BEGIN);
1490 ExpectLogContains(log1, 2, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1491 LoadLog::PHASE_END);
1492 ExpectLogContains(log2, 3, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1493 LoadLog::PHASE_BEGIN);
1494 ExpectLogContains(log2, 4, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1495 LoadLog::PHASE_END);
1496 ExpectLogContains(log2, 5, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
1497
[email protected]5fc08e32009-07-15 17:09:571498}
1499
1500TEST_F(ClientSocketPoolBaseTest_LateBinding, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531501 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571502
1503 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061504 ClientSocketHandle handle;
[email protected]5fc08e32009-07-15 17:09:571505 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:061506 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]5fc08e32009-07-15 17:09:571507
1508 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:241509 InitHandle(&handle, "a", kDefaultPriority, &callback,
1510 pool_.get(), NULL));
[email protected]5fc08e32009-07-15 17:09:571511
1512 handle.Reset();
1513
1514 TestCompletionCallback callback2;
1515 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:241516 InitHandle(&handle, "a", kDefaultPriority, &callback2,
1517 pool_.get(), NULL));
[email protected]5fc08e32009-07-15 17:09:571518
1519 EXPECT_EQ(OK, callback2.WaitForResult());
1520 EXPECT_FALSE(callback.have_result());
1521
1522 handle.Reset();
1523}
1524
1525TEST_F(ClientSocketPoolBaseTest_LateBinding, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531526 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571527
1528 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1529 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1530 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
1531 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 3));
1532 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
1533 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 2));
1534 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
1535
1536 // Cancel a request.
1537 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]a6c59f62009-07-29 16:33:331538 EXPECT_FALSE(requests_[index_to_cancel]->handle()->is_initialized());
1539 requests_[index_to_cancel]->handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571540
1541 ReleaseAllConnections(KEEP_ALIVE);
1542
1543 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1544 client_socket_factory_.allocation_count());
1545 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup - 1,
[email protected]75439d3b2009-07-23 22:11:171546 completion_count_);
[email protected]5fc08e32009-07-15 17:09:571547
1548 EXPECT_EQ(1, GetOrderOfRequest(1));
1549 EXPECT_EQ(2, GetOrderOfRequest(2));
1550 EXPECT_EQ(5, GetOrderOfRequest(3));
1551 EXPECT_EQ(3, GetOrderOfRequest(4));
1552 EXPECT_EQ(kRequestNotFound, GetOrderOfRequest(5)); // Canceled request.
1553 EXPECT_EQ(4, GetOrderOfRequest(6));
1554 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171555
1556 // Make sure we test order of all requests made.
1557 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]5fc08e32009-07-15 17:09:571558}
1559
[email protected]974ebd62009-08-03 23:14:341560TEST_F(ClientSocketPoolBaseTest_LateBinding, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341561 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1562
[email protected]17a0c6c2009-08-04 00:07:041563 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1564
[email protected]974ebd62009-08-03 23:14:341565 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
1566 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 2));
1567 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 3));
1568 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
1569
1570 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1571 requests_[2]->handle()->Reset();
1572 requests_[3]->handle()->Reset();
1573 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1574
1575 requests_[1]->handle()->Reset();
1576 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1577
1578 requests_[0]->handle()->Reset();
1579 EXPECT_EQ(kDefaultMaxSocketsPerGroup - 1, pool_->NumConnectJobsInGroup("a"));
1580}
1581
[email protected]5fc08e32009-07-15 17:09:571582TEST_F(ClientSocketPoolBaseTest_LateBinding, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531583 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571584
1585 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061586 ClientSocketHandle handle;
[email protected]5fc08e32009-07-15 17:09:571587 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061588 &handle, pool_.get(), connect_job_factory_,
1589 TestConnectJob::kMockPendingJob);
[email protected]a937a06d2009-08-19 21:19:241590 int rv = InitHandle(
1591 &handle, "a", kDefaultPriority, &callback, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571592 ASSERT_EQ(ERR_IO_PENDING, rv);
1593
1594 EXPECT_EQ(OK, callback.WaitForResult());
1595 handle.Reset();
1596}
1597
1598TEST_F(ClientSocketPoolBaseTest_LateBinding, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531599 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571600
1601 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061602 ClientSocketHandle handle;
[email protected]5fc08e32009-07-15 17:09:571603 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061604 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]a937a06d2009-08-19 21:19:241605 int rv = InitHandle(
1606 &handle, "a", kDefaultPriority, &callback,
[email protected]a512f5982009-08-18 16:01:061607 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571608 ASSERT_EQ(ERR_IO_PENDING, rv);
1609
1610 EXPECT_EQ(OK, callback.WaitForResult());
1611 handle.Reset();
1612}
1613
1614// Make sure that pending requests get serviced after active requests get
1615// cancelled.
1616TEST_F(ClientSocketPoolBaseTest_LateBinding,
1617 CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531618 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571619
1620 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1621
1622 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1623 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1624 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1625 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1626 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1627 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1628 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1629
1630 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1631 // Let's cancel them.
1632 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]a6c59f62009-07-29 16:33:331633 ASSERT_FALSE(requests_[i]->handle()->is_initialized());
1634 requests_[i]->handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571635 }
1636
1637 // Let's wait for the rest to complete now.
1638 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i) {
1639 EXPECT_EQ(OK, requests_[i]->WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331640 requests_[i]->handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571641 }
1642
[email protected]75439d3b2009-07-23 22:11:171643 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571644}
1645
1646// Make sure that pending requests get serviced after active requests fail.
1647TEST_F(ClientSocketPoolBaseTest_LateBinding,
1648 FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531649 const int kMaxSockets = 5;
1650 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571651
1652 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1653
[email protected]211d21722009-07-22 15:48:531654 const int kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1655 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test hangs.
[email protected]5fc08e32009-07-15 17:09:571656
1657 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531658 for (int i = 0; i < kNumberOfRequests; ++i)
1659 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]5fc08e32009-07-15 17:09:571660
[email protected]211d21722009-07-22 15:48:531661 for (int i = 0; i < kNumberOfRequests; ++i)
1662 EXPECT_EQ(ERR_CONNECTION_FAILED, requests_[i]->WaitForResult());
[email protected]5fc08e32009-07-15 17:09:571663}
1664
1665TEST_F(ClientSocketPoolBaseTest_LateBinding,
1666 CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531667 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571668
1669 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1670
[email protected]a512f5982009-08-18 16:01:061671 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241672 int rv = InitHandle(req.handle(), "a", kDefaultPriority, &req,
1673 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571674 EXPECT_EQ(ERR_IO_PENDING, rv);
1675
1676 // Cancel the active request.
[email protected]a6c59f62009-07-29 16:33:331677 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571678
[email protected]a937a06d2009-08-19 21:19:241679 rv = InitHandle(req.handle(), "a", kDefaultPriority, &req,
1680 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571681 EXPECT_EQ(ERR_IO_PENDING, rv);
1682 EXPECT_EQ(OK, req.WaitForResult());
1683
[email protected]a6c59f62009-07-29 16:33:331684 EXPECT_FALSE(req.handle()->is_reused());
[email protected]75439d3b2009-07-23 22:11:171685 EXPECT_EQ(1U, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571686 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1687}
1688
1689// When requests and ConnectJobs are not coupled, the request will get serviced
1690// by whatever comes first.
1691TEST_F(ClientSocketPoolBaseTest_LateBinding, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531692 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571693
1694 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321695 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571696
[email protected]a512f5982009-08-18 16:01:061697 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241698 int rv = InitHandle(req1.handle(), "a", kDefaultPriority,
1699 &req1, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571700 EXPECT_EQ(ERR_IO_PENDING, rv);
1701 EXPECT_EQ(OK, req1.WaitForResult());
1702
1703 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1704 // without a job.
1705 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1706
[email protected]a512f5982009-08-18 16:01:061707 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241708 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
1709 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571710 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a512f5982009-08-18 16:01:061711 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241712 rv = InitHandle(
1713 req3.handle(), "a", kDefaultPriority, &req3, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571714 EXPECT_EQ(ERR_IO_PENDING, rv);
1715
1716 // Both Requests 2 and 3 are pending. We release socket 1 which should
1717 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331718 req1.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571719 MessageLoop::current()->RunAllPending(); // Run the DoReleaseSocket()
[email protected]a6c59f62009-07-29 16:33:331720 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571721 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331722 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571723
1724 // Signal job 2, which should service request 3.
1725
1726 client_socket_factory_.SignalJobs();
1727 EXPECT_EQ(OK, req3.WaitForResult());
1728
1729 ASSERT_EQ(3U, request_order_.size());
1730 EXPECT_EQ(&req1, request_order_[0]);
1731 EXPECT_EQ(&req2, request_order_[1]);
1732 EXPECT_EQ(&req3, request_order_[2]);
1733 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1734}
1735
1736// The requests are not coupled to the jobs. So, the requests should finish in
1737// their priority / insertion order.
1738TEST_F(ClientSocketPoolBaseTest_LateBinding, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531739 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571740 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321741 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571742
[email protected]a512f5982009-08-18 16:01:061743 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241744 int rv = InitHandle(
1745 req1.handle(), "a", kDefaultPriority, &req1, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571746 EXPECT_EQ(ERR_IO_PENDING, rv);
1747
[email protected]a512f5982009-08-18 16:01:061748 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241749 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
1750 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571751 EXPECT_EQ(ERR_IO_PENDING, rv);
1752
1753 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321754 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571755
[email protected]a512f5982009-08-18 16:01:061756 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241757 rv = InitHandle(
1758 req3.handle(), "a", kDefaultPriority, &req3, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571759 EXPECT_EQ(ERR_IO_PENDING, rv);
1760
1761 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1762 EXPECT_EQ(OK, req2.WaitForResult());
1763 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1764
1765 ASSERT_EQ(3U, request_order_.size());
1766 EXPECT_EQ(&req1, request_order_[0]);
1767 EXPECT_EQ(&req2, request_order_[1]);
1768 EXPECT_EQ(&req3, request_order_[2]);
1769}
1770
[email protected]f0109a7d2009-07-16 00:09:521771TEST_F(ClientSocketPoolBaseTest_LateBinding, DISABLED_LoadState) {
[email protected]211d21722009-07-22 15:48:531772 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571773 connect_job_factory_->set_job_type(
[email protected]b59ff372009-07-15 22:04:321774 TestConnectJob::kMockAdvancingLoadStateJob);
[email protected]5fc08e32009-07-15 17:09:571775
[email protected]a512f5982009-08-18 16:01:061776 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241777 int rv = InitHandle(
1778 req1.handle(), "a", kDefaultPriority, &req1, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571779 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331780 EXPECT_EQ(LOAD_STATE_IDLE, req1.handle()->GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571781
1782 MessageLoop::current()->RunAllPending();
1783
[email protected]a512f5982009-08-18 16:01:061784 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241785 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
1786 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571787 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331788 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, req1.handle()->GetLoadState());
1789 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, req2.handle()->GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571790}
1791
[email protected]2b7523d2009-07-29 20:29:231792// Regression test for http://crbug.com/17985.
1793TEST_F(ClientSocketPoolBaseTest_LateBinding,
1794 GroupWithPendingRequestsIsNotEmpty) {
1795 const int kMaxSockets = 3;
1796 const int kMaxSocketsPerGroup = 2;
1797 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1798
1799 const int kHighPriority = kDefaultPriority + 100;
1800
1801 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1802 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1803
1804 // This is going to be a pending request in an otherwise empty group.
1805 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1806
1807 // Reach the maximum socket limit.
1808 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1809
1810 // Create a stalled group with high priorities.
1811 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1812 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1813 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
1814
1815 // Release the first two sockets from "a", which will make room
1816 // for requests from "c". After that "a" will have no active sockets
1817 // and one pending request.
1818 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1819 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1820
1821 // Closing idle sockets should not get us into trouble, but in the bug
1822 // we were hitting a CHECK here.
1823 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
1824 pool_->CloseIdleSockets();
1825 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1826}
1827
[email protected]9bf28db2009-08-29 01:35:161828TEST_F(ClientSocketPoolBaseTest_LateBinding, CleanupTimedOutIdleSockets) {
1829 CreatePoolWithIdleTimeouts(
1830 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1831 base::TimeDelta(), // Time out unused sockets immediately.
1832 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1833
1834 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1835
1836 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
1837
1838 TestSocketRequest req(&request_order_, &completion_count_);
1839 int rv = InitHandle(req.handle(), "a", 0, &req, pool_.get(), NULL);
1840 EXPECT_EQ(ERR_IO_PENDING, rv);
1841 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
1842
1843 TestSocketRequest req2(&request_order_, &completion_count_);
1844 rv = InitHandle(req2.handle(), "a", 0, &req2, pool_.get(), NULL);
1845 EXPECT_EQ(ERR_IO_PENDING, rv);
1846 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req2.handle()));
1847
1848 // Cancel one of the requests. Wait for the other, which will get the first
1849 // job. Release the socket. Run the loop again to make sure the second
1850 // socket is sitting idle and the first one is released (since ReleaseSocket()
1851 // just posts a DoReleaseSocket() task).
1852
1853 req.handle()->Reset();
1854 EXPECT_EQ(OK, req2.WaitForResult());
1855 req2.handle()->Reset();
[email protected]6b175382009-10-13 06:47:471856
1857 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1858 // actually become pending until 2ms after they have been created. In order
1859 // to flush all tasks, we need to wait so that we know there are no
1860 // soon-to-be-pending tasks waiting.
1861 PlatformThread::Sleep(10);
[email protected]9bf28db2009-08-29 01:35:161862 MessageLoop::current()->RunAllPending();
1863
1864 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:041865
[email protected]9bf28db2009-08-29 01:35:161866 // Invoke the idle socket cleanup check. Only one socket should be left, the
1867 // used socket. Request it to make sure that it's used.
1868
1869 pool_->CleanupTimedOutIdleSockets();
1870 rv = InitHandle(req.handle(), "a", 0, &req, pool_.get(), NULL);
1871 EXPECT_EQ(OK, rv);
1872 EXPECT_TRUE(req.handle()->is_reused());
1873}
1874
[email protected]f6d1d6eb2009-06-24 20:16:091875} // namespace
1876
1877} // namespace net