blob: db61140101242a8d7dca9422e29132021fc3fe94 [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"
[email protected]ac790b42009-12-02 04:31:3114#include "net/base/request_priority.h"
[email protected]f6d1d6eb2009-06-24 20:16:0915#include "net/base/test_completion_callback.h"
16#include "net/socket/client_socket.h"
17#include "net/socket/client_socket_factory.h"
18#include "net/socket/client_socket_handle.h"
[email protected]75439d3b2009-07-23 22:11:1719#include "net/socket/socket_test_util.h"
[email protected]f6d1d6eb2009-06-24 20:16:0920#include "testing/gtest/include/gtest/gtest.h"
21
22namespace net {
23
24namespace {
25
[email protected]211d21722009-07-22 15:48:5326const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2027const int kDefaultMaxSocketsPerGroup = 2;
[email protected]ac790b42009-12-02 04:31:3128const net::RequestPriority kDefaultPriority = MEDIUM;
[email protected]0b7648c2009-07-06 20:14:0129
[email protected]d80a4322009-08-14 07:07:4930typedef ClientSocketPoolBase<const void*> TestClientSocketPoolBase;
31
[email protected]f6d1d6eb2009-06-24 20:16:0932class MockClientSocket : public ClientSocket {
33 public:
34 MockClientSocket() : connected_(false) {}
35
[email protected]ab838892009-06-30 18:49:0536 // Socket methods:
37 virtual int Read(
38 IOBuffer* /* buf */, int /* len */, CompletionCallback* /* callback */) {
39 return ERR_UNEXPECTED;
40 }
41
42 virtual int Write(
43 IOBuffer* /* buf */, int /* len */, CompletionCallback* /* callback */) {
44 return ERR_UNEXPECTED;
45 }
[email protected]d3f66572009-09-09 22:38:0446 virtual bool SetReceiveBufferSize(int32 size) { return true; };
47 virtual bool SetSendBufferSize(int32 size) { return true; };
[email protected]ab838892009-06-30 18:49:0548
[email protected]f6d1d6eb2009-06-24 20:16:0949 // ClientSocket methods:
[email protected]ab838892009-06-30 18:49:0550
[email protected]5a05c47a2009-11-02 23:25:1951 virtual int Connect(CompletionCallback* callback, LoadLog* load_log) {
[email protected]f6d1d6eb2009-06-24 20:16:0952 connected_ = true;
53 return OK;
54 }
[email protected]f6d1d6eb2009-06-24 20:16:0955
[email protected]ab838892009-06-30 18:49:0556 virtual void Disconnect() { connected_ = false; }
57 virtual bool IsConnected() const { return connected_; }
58 virtual bool IsConnectedAndIdle() const { return connected_; }
[email protected]0b7648c2009-07-06 20:14:0159
[email protected]ab838892009-06-30 18:49:0560#if defined(OS_LINUX)
61 virtual int GetPeerName(struct sockaddr* /* name */,
62 socklen_t* /* namelen */) {
63 return 0;
[email protected]f6d1d6eb2009-06-24 20:16:0964 }
[email protected]ab838892009-06-30 18:49:0565#endif
[email protected]f6d1d6eb2009-06-24 20:16:0966
67 private:
68 bool connected_;
[email protected]f6d1d6eb2009-06-24 20:16:0969
[email protected]ab838892009-06-30 18:49:0570 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:0971};
72
[email protected]5fc08e32009-07-15 17:09:5773class TestConnectJob;
74
[email protected]f6d1d6eb2009-06-24 20:16:0975class MockClientSocketFactory : public ClientSocketFactory {
76 public:
[email protected]ab838892009-06-30 18:49:0577 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:0978
79 virtual ClientSocket* CreateTCPClientSocket(const AddressList& addresses) {
80 allocation_count_++;
[email protected]ab838892009-06-30 18:49:0581 return NULL;
[email protected]f6d1d6eb2009-06-24 20:16:0982 }
83
84 virtual SSLClientSocket* CreateSSLClientSocket(
85 ClientSocket* transport_socket,
86 const std::string& hostname,
87 const SSLConfig& ssl_config) {
88 NOTIMPLEMENTED();
89 return NULL;
90 }
91
[email protected]5fc08e32009-07-15 17:09:5792 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
93 void SignalJobs();
94
[email protected]f6d1d6eb2009-06-24 20:16:0995 int allocation_count() const { return allocation_count_; }
96
[email protected]f6d1d6eb2009-06-24 20:16:0997 private:
98 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:5799 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09100};
101
[email protected]ab838892009-06-30 18:49:05102class TestConnectJob : public ConnectJob {
103 public:
104 enum JobType {
105 kMockJob,
106 kMockFailingJob,
107 kMockPendingJob,
108 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57109 kMockWaitingJob,
110 kMockAdvancingLoadStateJob,
[email protected]ab838892009-06-30 18:49:05111 };
112
113 TestConnectJob(JobType job_type,
114 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49115 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34116 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05117 ConnectJob::Delegate* delegate,
[email protected]fd7b7c92009-08-20 19:38:30118 MockClientSocketFactory* client_socket_factory,
119 LoadLog* load_log)
120 : ConnectJob(group_name, request.handle(), timeout_duration,
121 delegate, load_log),
[email protected]2ab05b52009-07-01 23:57:58122 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05123 client_socket_factory_(client_socket_factory),
[email protected]46451352009-09-01 14:54:21124 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
125 load_state_(LOAD_STATE_IDLE) {}
[email protected]ab838892009-06-30 18:49:05126
[email protected]974ebd62009-08-03 23:14:34127 void Signal() {
128 DoConnect(waiting_success_, true /* async */);
129 }
130
[email protected]46451352009-09-01 14:54:21131 virtual LoadState GetLoadState() const { return load_state_; }
132
[email protected]974ebd62009-08-03 23:14:34133 private:
[email protected]ab838892009-06-30 18:49:05134 // ConnectJob methods:
135
[email protected]974ebd62009-08-03 23:14:34136 virtual int ConnectInternal() {
[email protected]ab838892009-06-30 18:49:05137 AddressList ignored;
138 client_socket_factory_->CreateTCPClientSocket(ignored);
[email protected]6e713f02009-08-06 02:56:40139 set_socket(new MockClientSocket());
[email protected]ab838892009-06-30 18:49:05140 switch (job_type_) {
141 case kMockJob:
142 return DoConnect(true /* successful */, false /* sync */);
143 case kMockFailingJob:
144 return DoConnect(false /* error */, false /* sync */);
145 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57146 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47147
148 // Depending on execution timings, posting a delayed task can result
149 // in the task getting executed the at the earliest possible
150 // opportunity or only after returning once from the message loop and
151 // then a second call into the message loop. In order to make behavior
152 // more deterministic, we change the default delay to 2ms. This should
153 // always require us to wait for the second call into the message loop.
154 //
155 // N.B. The correct fix for this and similar timing problems is to
156 // abstract time for the purpose of unittests. Unfortunately, we have
157 // a lot of third-party components that directly call the various
158 // time functions, so this change would be rather invasive.
159 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05160 FROM_HERE,
161 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47162 &TestConnectJob::DoConnect,
163 true /* successful */,
164 true /* async */),
165 2);
[email protected]ab838892009-06-30 18:49:05166 return ERR_IO_PENDING;
167 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57168 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47169 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05170 FROM_HERE,
171 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47172 &TestConnectJob::DoConnect,
173 false /* error */,
174 true /* async */),
175 2);
[email protected]ab838892009-06-30 18:49:05176 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57177 case kMockWaitingJob:
178 client_socket_factory_->WaitForSignal(this);
179 waiting_success_ = true;
180 return ERR_IO_PENDING;
181 case kMockAdvancingLoadStateJob:
[email protected]6b175382009-10-13 06:47:47182 MessageLoop::current()->PostDelayedTask(
[email protected]5fc08e32009-07-15 17:09:57183 FROM_HERE,
184 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47185 &TestConnectJob::AdvanceLoadState, load_state_),
186 2);
[email protected]5fc08e32009-07-15 17:09:57187 return ERR_IO_PENDING;
[email protected]ab838892009-06-30 18:49:05188 default:
189 NOTREACHED();
[email protected]6e713f02009-08-06 02:56:40190 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05191 return ERR_FAILED;
192 }
193 }
194
[email protected]46451352009-09-01 14:54:21195 void set_load_state(LoadState load_state) { load_state_ = load_state; }
196
[email protected]ab838892009-06-30 18:49:05197 int DoConnect(bool succeed, bool was_async) {
198 int result = ERR_CONNECTION_FAILED;
[email protected]ab838892009-06-30 18:49:05199 if (succeed) {
200 result = OK;
[email protected]5a05c47a2009-11-02 23:25:19201 socket()->Connect(NULL, NULL);
[email protected]6e713f02009-08-06 02:56:40202 } else {
203 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05204 }
[email protected]2ab05b52009-07-01 23:57:58205
206 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30207 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05208 return result;
209 }
210
[email protected]5fc08e32009-07-15 17:09:57211 void AdvanceLoadState(LoadState state) {
212 int tmp = state;
213 tmp++;
214 state = static_cast<LoadState>(tmp);
215 set_load_state(state);
216 // Post a delayed task so RunAllPending() won't run it.
217 MessageLoop::current()->PostDelayedTask(
218 FROM_HERE,
219 method_factory_.NewRunnableMethod(&TestConnectJob::AdvanceLoadState,
220 state),
221 1 /* 1ms delay */);
222 }
223
224 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05225 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57226 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05227 ScopedRunnableMethodFactory<TestConnectJob> method_factory_;
[email protected]46451352009-09-01 14:54:21228 LoadState load_state_;
[email protected]ab838892009-06-30 18:49:05229
230 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
231};
232
[email protected]d80a4322009-08-14 07:07:49233class TestConnectJobFactory
234 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05235 public:
[email protected]5fc08e32009-07-15 17:09:57236 explicit TestConnectJobFactory(MockClientSocketFactory* client_socket_factory)
[email protected]ab838892009-06-30 18:49:05237 : job_type_(TestConnectJob::kMockJob),
238 client_socket_factory_(client_socket_factory) {}
239
240 virtual ~TestConnectJobFactory() {}
241
242 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
243
[email protected]974ebd62009-08-03 23:14:34244 void set_timeout_duration(base::TimeDelta timeout_duration) {
245 timeout_duration_ = timeout_duration;
246 }
247
[email protected]ab838892009-06-30 18:49:05248 // ConnectJobFactory methods:
249
250 virtual ConnectJob* NewConnectJob(
251 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49252 const TestClientSocketPoolBase::Request& request,
[email protected]fd7b7c92009-08-20 19:38:30253 ConnectJob::Delegate* delegate,
254 LoadLog* load_log) const {
[email protected]ab838892009-06-30 18:49:05255 return new TestConnectJob(job_type_,
256 group_name,
257 request,
[email protected]974ebd62009-08-03 23:14:34258 timeout_duration_,
[email protected]ab838892009-06-30 18:49:05259 delegate,
[email protected]fd7b7c92009-08-20 19:38:30260 client_socket_factory_,
261 load_log);
[email protected]ab838892009-06-30 18:49:05262 }
263
264 private:
265 TestConnectJob::JobType job_type_;
[email protected]974ebd62009-08-03 23:14:34266 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57267 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05268
269 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
270};
271
272class TestClientSocketPool : public ClientSocketPool {
273 public:
274 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53275 int max_sockets,
[email protected]ab838892009-06-30 18:49:05276 int max_sockets_per_group,
[email protected]9bf28db2009-08-29 01:35:16277 base::TimeDelta unused_idle_socket_timeout,
278 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49279 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
[email protected]9bf28db2009-08-29 01:35:16280 : base_(max_sockets, max_sockets_per_group,
281 unused_idle_socket_timeout, used_idle_socket_timeout,
[email protected]100d5fb92009-12-21 21:08:35282 connect_job_factory, NULL) {}
[email protected]ab838892009-06-30 18:49:05283
284 virtual int RequestSocket(
285 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49286 const void* params,
[email protected]ac790b42009-12-02 04:31:31287 net::RequestPriority priority,
[email protected]ab838892009-06-30 18:49:05288 ClientSocketHandle* handle,
[email protected]684970b2009-08-14 04:54:46289 CompletionCallback* callback,
290 LoadLog* load_log) {
[email protected]d80a4322009-08-14 07:07:49291 return base_.RequestSocket(
292 group_name, params, priority, handle, callback, load_log);
[email protected]ab838892009-06-30 18:49:05293 }
294
295 virtual void CancelRequest(
296 const std::string& group_name,
297 const ClientSocketHandle* handle) {
[email protected]d80a4322009-08-14 07:07:49298 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05299 }
300
301 virtual void ReleaseSocket(
302 const std::string& group_name,
303 ClientSocket* socket) {
[email protected]d80a4322009-08-14 07:07:49304 base_.ReleaseSocket(group_name, socket);
[email protected]ab838892009-06-30 18:49:05305 }
306
307 virtual void CloseIdleSockets() {
[email protected]d80a4322009-08-14 07:07:49308 base_.CloseIdleSockets();
[email protected]ab838892009-06-30 18:49:05309 }
310
[email protected]d80a4322009-08-14 07:07:49311 virtual int IdleSocketCount() const { return base_.idle_socket_count(); }
[email protected]ab838892009-06-30 18:49:05312
313 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49314 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05315 }
316
317 virtual LoadState GetLoadState(const std::string& group_name,
318 const ClientSocketHandle* handle) const {
[email protected]d80a4322009-08-14 07:07:49319 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05320 }
321
[email protected]d80a4322009-08-14 07:07:49322 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20323
[email protected]974ebd62009-08-03 23:14:34324 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49325 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34326 }
327
[email protected]9bf28db2009-08-29 01:35:16328 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
329
[email protected]ab838892009-06-30 18:49:05330 private:
[email protected]5389bc72009-11-05 23:34:24331 ~TestClientSocketPool() {}
332
[email protected]d80a4322009-08-14 07:07:49333 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05334
335 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
336};
337
[email protected]a937a06d2009-08-19 21:19:24338} // namespace
339
340REGISTER_SOCKET_PARAMS_FOR_POOL(TestClientSocketPool, const void*);
341
342namespace {
343
[email protected]5fc08e32009-07-15 17:09:57344void MockClientSocketFactory::SignalJobs() {
345 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
346 it != waiting_jobs_.end(); ++it) {
347 (*it)->Signal();
348 }
349 waiting_jobs_.clear();
350}
351
[email protected]974ebd62009-08-03 23:14:34352class TestConnectJobDelegate : public ConnectJob::Delegate {
353 public:
354 TestConnectJobDelegate()
355 : have_result_(false), waiting_for_result_(false), result_(OK) {}
356 virtual ~TestConnectJobDelegate() {}
357
358 virtual void OnConnectJobComplete(int result, ConnectJob* job) {
359 result_ = result;
[email protected]6e713f02009-08-06 02:56:40360 scoped_ptr<ClientSocket> socket(job->ReleaseSocket());
[email protected]9b6fee12009-09-29 18:13:07361 // socket.get() should be NULL iff result != OK
362 EXPECT_EQ(socket.get() == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34363 delete job;
364 have_result_ = true;
365 if (waiting_for_result_)
366 MessageLoop::current()->Quit();
367 }
368
369 int WaitForResult() {
370 DCHECK(!waiting_for_result_);
371 while (!have_result_) {
372 waiting_for_result_ = true;
373 MessageLoop::current()->Run();
374 waiting_for_result_ = false;
375 }
376 have_result_ = false; // auto-reset for next callback
377 return result_;
378 }
379
380 private:
381 bool have_result_;
382 bool waiting_for_result_;
383 int result_;
384};
385
[email protected]75439d3b2009-07-23 22:11:17386class ClientSocketPoolBaseTest : public ClientSocketPoolTest {
[email protected]f6d1d6eb2009-06-24 20:16:09387 protected:
[email protected]17a0c6c2009-08-04 00:07:04388 ClientSocketPoolBaseTest() {}
[email protected]c9d6a1d2009-07-14 16:15:20389
[email protected]211d21722009-07-22 15:48:53390 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16391 CreatePoolWithIdleTimeouts(
392 max_sockets,
393 max_sockets_per_group,
394 base::TimeDelta::FromSeconds(kUnusedIdleSocketTimeout),
395 base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout));
396 }
397
398 void CreatePoolWithIdleTimeouts(
399 int max_sockets, int max_sockets_per_group,
400 base::TimeDelta unused_idle_socket_timeout,
401 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20402 DCHECK(!pool_.get());
[email protected]17a0c6c2009-08-04 00:07:04403 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_);
[email protected]211d21722009-07-22 15:48:53404 pool_ = new TestClientSocketPool(max_sockets,
405 max_sockets_per_group,
[email protected]9bf28db2009-08-29 01:35:16406 unused_idle_socket_timeout,
407 used_idle_socket_timeout,
[email protected]c9d6a1d2009-07-14 16:15:20408 connect_job_factory_);
409 }
[email protected]f6d1d6eb2009-06-24 20:16:09410
[email protected]ac790b42009-12-02 04:31:31411 int StartRequest(const std::string& group_name,
412 net::RequestPriority priority) {
[email protected]a937a06d2009-08-19 21:19:24413 return StartRequestUsingPool<TestClientSocketPool, const void*>(
414 pool_.get(), group_name, priority, NULL);
[email protected]f6d1d6eb2009-06-24 20:16:09415 }
416
417 virtual void TearDown() {
[email protected]6b175382009-10-13 06:47:47418 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
419 // actually become pending until 2ms after they have been created. In order
420 // to flush all tasks, we need to wait so that we know there are no
421 // soon-to-be-pending tasks waiting.
422 PlatformThread::Sleep(10);
423 MessageLoop::current()->RunAllPending();
424
[email protected]211d21722009-07-22 15:48:53425 // Need to delete |pool_| before we turn late binding back off. We also need
426 // to delete |requests_| because the pool is reference counted and requests
427 // keep reference to it.
428 // TODO(willchan): Remove this part when late binding becomes the default.
[email protected]5fc08e32009-07-15 17:09:57429 pool_ = NULL;
[email protected]211d21722009-07-22 15:48:53430 requests_.reset();
431
[email protected]d80a4322009-08-14 07:07:49432 EnableLateBindingOfSockets(false);
[email protected]75439d3b2009-07-23 22:11:17433
434 ClientSocketPoolTest::TearDown();
[email protected]f6d1d6eb2009-06-24 20:16:09435 }
436
[email protected]f6d1d6eb2009-06-24 20:16:09437 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04438 TestConnectJobFactory* connect_job_factory_;
[email protected]c9d6a1d2009-07-14 16:15:20439 scoped_refptr<TestClientSocketPool> pool_;
[email protected]f6d1d6eb2009-06-24 20:16:09440};
441
[email protected]a937a06d2009-08-19 21:19:24442// Helper function which explicitly specifies the template parameters, since
443// the compiler will infer (in this case, incorrectly) that NULL is of type int.
444int InitHandle(ClientSocketHandle* handle,
445 const std::string& group_name,
[email protected]ac790b42009-12-02 04:31:31446 net::RequestPriority priority,
[email protected]a937a06d2009-08-19 21:19:24447 CompletionCallback* callback,
448 TestClientSocketPool* pool,
449 LoadLog* load_log) {
450 return handle->Init<const void*, TestClientSocketPool>(
451 group_name, NULL, priority, callback, pool, load_log);
452}
453
[email protected]974ebd62009-08-03 23:14:34454// Even though a timeout is specified, it doesn't time out on a synchronous
455// completion.
456TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
457 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06458 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49459 TestClientSocketPoolBase::Request request(
460 &ignored, NULL, kDefaultPriority, NULL, NULL);
[email protected]974ebd62009-08-03 23:14:34461 scoped_ptr<TestConnectJob> job(
462 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:12463 "a",
[email protected]974ebd62009-08-03 23:14:34464 request,
465 base::TimeDelta::FromMicroseconds(1),
466 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30467 &client_socket_factory_,
468 NULL));
[email protected]974ebd62009-08-03 23:14:34469 EXPECT_EQ(OK, job->Connect());
470}
471
472TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
473 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06474 ClientSocketHandle ignored;
[email protected]60c4c412009-11-06 19:59:36475 scoped_refptr<LoadLog> log(new LoadLog(LoadLog::kUnbounded));
[email protected]d80a4322009-08-14 07:07:49476 TestClientSocketPoolBase::Request request(
477 &ignored, NULL, kDefaultPriority, NULL, NULL);
[email protected]974ebd62009-08-03 23:14:34478 // Deleted by TestConnectJobDelegate.
479 TestConnectJob* job =
480 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12481 "a",
[email protected]974ebd62009-08-03 23:14:34482 request,
483 base::TimeDelta::FromMicroseconds(1),
484 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30485 &client_socket_factory_,
486 log);
[email protected]974ebd62009-08-03 23:14:34487 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
488 PlatformThread::Sleep(1);
489 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30490
[email protected]bf6c087a2009-12-21 20:45:10491 EXPECT_EQ(3u, log->entries().size());
[email protected]fd7b7c92009-08-20 19:38:30492 ExpectLogContains(log, 0, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
493 LoadLog::PHASE_BEGIN);
494 ExpectLogContains(log, 1, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
495 LoadLog::PHASE_NONE);
496 ExpectLogContains(log, 2, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
497 LoadLog::PHASE_END);
[email protected]974ebd62009-08-03 23:14:34498}
499
[email protected]5fc08e32009-07-15 17:09:57500TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53501 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20502
[email protected]f6d1d6eb2009-06-24 20:16:09503 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06504 ClientSocketHandle handle;
[email protected]60c4c412009-11-06 19:59:36505 scoped_refptr<LoadLog> log(new LoadLog(LoadLog::kUnbounded));
[email protected]a937a06d2009-08-19 21:19:24506 EXPECT_EQ(OK, InitHandle(&handle, "a", kDefaultPriority,
[email protected]fd7b7c92009-08-20 19:38:30507 &callback, pool_.get(), log));
[email protected]f6d1d6eb2009-06-24 20:16:09508 EXPECT_TRUE(handle.is_initialized());
509 EXPECT_TRUE(handle.socket());
[email protected]f6d1d6eb2009-06-24 20:16:09510 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:30511
[email protected]bf6c087a2009-12-21 20:45:10512 EXPECT_EQ(4u, log->entries().size());
[email protected]fd7b7c92009-08-20 19:38:30513 ExpectLogContains(log, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
514 ExpectLogContains(log, 1, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
515 LoadLog::PHASE_BEGIN);
516 ExpectLogContains(log, 2, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
517 LoadLog::PHASE_END);
518 ExpectLogContains(log, 3, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
[email protected]f6d1d6eb2009-06-24 20:16:09519}
520
[email protected]5fc08e32009-07-15 17:09:57521TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:53522 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:57523
524 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]60c4c412009-11-06 19:59:36525 scoped_refptr<LoadLog> log(new LoadLog(LoadLog::kUnbounded));
[email protected]a512f5982009-08-18 16:01:06526 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]ac790b42009-12-02 04:31:31527 int rv = InitHandle(req.handle(), "a", LOW, &req, pool_.get(), log);
[email protected]5fc08e32009-07-15 17:09:57528 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:33529 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:57530 EXPECT_EQ(OK, req.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:33531 EXPECT_TRUE(req.handle()->is_initialized());
532 EXPECT_TRUE(req.handle()->socket());
533 req.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:30534
[email protected]bf6c087a2009-12-21 20:45:10535 EXPECT_EQ(4u, log->entries().size());
[email protected]fd7b7c92009-08-20 19:38:30536 ExpectLogContains(log, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
537 ExpectLogContains(log, 1, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
538 LoadLog::PHASE_BEGIN);
539 ExpectLogContains(log, 2, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
540 LoadLog::PHASE_END);
541 ExpectLogContains(log, 3, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
[email protected]5fc08e32009-07-15 17:09:57542}
543
[email protected]ab838892009-06-30 18:49:05544TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53545 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20546
[email protected]ab838892009-06-30 18:49:05547 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]60c4c412009-11-06 19:59:36548 scoped_refptr<LoadLog> log(new LoadLog(LoadLog::kUnbounded));
[email protected]a512f5982009-08-18 16:01:06549 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]3ae82302009-06-26 06:01:21550 EXPECT_EQ(ERR_CONNECTION_FAILED,
[email protected]a937a06d2009-08-19 21:19:24551 InitHandle(req.handle(), "a", kDefaultPriority, &req,
[email protected]fd7b7c92009-08-20 19:38:30552 pool_.get(), log));
553
[email protected]bf6c087a2009-12-21 20:45:10554 EXPECT_EQ(4u, log->entries().size());
[email protected]fd7b7c92009-08-20 19:38:30555 ExpectLogContains(log, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
556 ExpectLogContains(log, 1, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
557 LoadLog::PHASE_BEGIN);
558 ExpectLogContains(log, 2, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
559 LoadLog::PHASE_END);
560 ExpectLogContains(log, 3, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
[email protected]f6d1d6eb2009-06-24 20:16:09561}
562
[email protected]5fc08e32009-07-15 17:09:57563TEST_F(ClientSocketPoolBaseTest, InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:53564 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:57565
566 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]60c4c412009-11-06 19:59:36567 scoped_refptr<LoadLog> log(new LoadLog(LoadLog::kUnbounded));
[email protected]a512f5982009-08-18 16:01:06568 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]5fc08e32009-07-15 17:09:57569 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:24570 InitHandle(req.handle(), "a", kDefaultPriority, &req,
[email protected]fd7b7c92009-08-20 19:38:30571 pool_.get(), log));
[email protected]a6c59f62009-07-29 16:33:33572 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:57573 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30574
[email protected]bf6c087a2009-12-21 20:45:10575 EXPECT_EQ(4u, log->entries().size());
[email protected]fd7b7c92009-08-20 19:38:30576 ExpectLogContains(log, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
577 ExpectLogContains(log, 1, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
578 LoadLog::PHASE_BEGIN);
579 ExpectLogContains(log, 2, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
580 LoadLog::PHASE_END);
581 ExpectLogContains(log, 3, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
[email protected]5fc08e32009-07-15 17:09:57582}
583
[email protected]211d21722009-07-22 15:48:53584TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
585 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
586
[email protected]fd7b7c92009-08-20 19:38:30587 // TODO(eroman): Check that the LoadLog contains this event.
588
[email protected]211d21722009-07-22 15:48:53589 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
590 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
591 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
592 EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
593
594 EXPECT_EQ(static_cast<int>(requests_.size()),
595 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17596 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53597
598 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
599 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
600 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
601
602 ReleaseAllConnections(KEEP_ALIVE);
603
604 EXPECT_EQ(static_cast<int>(requests_.size()),
605 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17606 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53607
608 EXPECT_EQ(1, GetOrderOfRequest(1));
609 EXPECT_EQ(2, GetOrderOfRequest(2));
610 EXPECT_EQ(3, GetOrderOfRequest(3));
611 EXPECT_EQ(4, GetOrderOfRequest(4));
612 EXPECT_EQ(5, GetOrderOfRequest(5));
613 EXPECT_EQ(6, GetOrderOfRequest(6));
614 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17615
616 // Make sure we test order of all requests made.
617 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53618}
619
620TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
621 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
622
[email protected]fd7b7c92009-08-20 19:38:30623 // TODO(eroman): Check that the LoadLog contains this event.
624
[email protected]211d21722009-07-22 15:48:53625 // Reach all limits: max total sockets, and max sockets per group.
626 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
627 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
628 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
629 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
630
631 EXPECT_EQ(static_cast<int>(requests_.size()),
632 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17633 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53634
635 // Now create a new group and verify that we don't starve it.
636 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
637
638 ReleaseAllConnections(KEEP_ALIVE);
639
640 EXPECT_EQ(static_cast<int>(requests_.size()),
641 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17642 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53643
644 EXPECT_EQ(1, GetOrderOfRequest(1));
645 EXPECT_EQ(2, GetOrderOfRequest(2));
646 EXPECT_EQ(3, GetOrderOfRequest(3));
647 EXPECT_EQ(4, GetOrderOfRequest(4));
648 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17649
650 // Make sure we test order of all requests made.
651 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53652}
653
654TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
655 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
656
[email protected]ac790b42009-12-02 04:31:31657 EXPECT_EQ(OK, StartRequest("b", LOWEST));
658 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
659 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
660 EXPECT_EQ(OK, StartRequest("a", LOWEST));
[email protected]211d21722009-07-22 15:48:53661
662 EXPECT_EQ(static_cast<int>(requests_.size()),
663 client_socket_factory_.allocation_count());
664
[email protected]ac790b42009-12-02 04:31:31665 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
666 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
667 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53668
669 ReleaseAllConnections(KEEP_ALIVE);
670
671 // We're re-using one socket for group "a", and one for "b".
672 EXPECT_EQ(static_cast<int>(requests_.size()) - 2,
673 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17674 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53675
676 // First 4 requests don't have to wait, and finish in order.
677 EXPECT_EQ(1, GetOrderOfRequest(1));
678 EXPECT_EQ(2, GetOrderOfRequest(2));
679 EXPECT_EQ(3, GetOrderOfRequest(3));
680 EXPECT_EQ(4, GetOrderOfRequest(4));
681
[email protected]ac790b42009-12-02 04:31:31682 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
683 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53684 EXPECT_EQ(7, GetOrderOfRequest(5));
685 EXPECT_EQ(6, GetOrderOfRequest(6));
686 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17687
688 // Make sure we test order of all requests made.
689 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53690}
691
692TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
693 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
694
[email protected]ac790b42009-12-02 04:31:31695 EXPECT_EQ(OK, StartRequest("a", LOWEST));
696 EXPECT_EQ(OK, StartRequest("a", LOW));
697 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
698 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
[email protected]211d21722009-07-22 15:48:53699
700 EXPECT_EQ(static_cast<int>(requests_.size()),
701 client_socket_factory_.allocation_count());
702
[email protected]ac790b42009-12-02 04:31:31703 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
704 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
705 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53706
707 ReleaseAllConnections(KEEP_ALIVE);
708
709 // We're re-using one socket for group "a", and one for "b".
710 EXPECT_EQ(static_cast<int>(requests_.size()) - 2,
711 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17712 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53713
714 // First 4 requests don't have to wait, and finish in order.
715 EXPECT_EQ(1, GetOrderOfRequest(1));
716 EXPECT_EQ(2, GetOrderOfRequest(2));
717 EXPECT_EQ(3, GetOrderOfRequest(3));
718 EXPECT_EQ(4, GetOrderOfRequest(4));
719
720 // Request ("b", 7) has the highest priority, but we can't make new socket for
721 // group "b", because it has reached the per-group limit. Then we make
722 // socket for ("c", 6), because it has higher priority than ("a", 4),
723 // and we still can't make a socket for group "b".
724 EXPECT_EQ(5, GetOrderOfRequest(5));
725 EXPECT_EQ(6, GetOrderOfRequest(6));
726 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17727
728 // Make sure we test order of all requests made.
729 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53730}
731
732// Make sure that we count connecting sockets against the total limit.
733TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
734 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
735
736 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
737 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
738 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
739
740 // Create one asynchronous request.
741 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
742 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
743
[email protected]6b175382009-10-13 06:47:47744 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
745 // actually become pending until 2ms after they have been created. In order
746 // to flush all tasks, we need to wait so that we know there are no
747 // soon-to-be-pending tasks waiting.
748 PlatformThread::Sleep(10);
749 MessageLoop::current()->RunAllPending();
750
[email protected]211d21722009-07-22 15:48:53751 // The next synchronous request should wait for its turn.
752 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
753 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
754
755 ReleaseAllConnections(KEEP_ALIVE);
756
757 EXPECT_EQ(static_cast<int>(requests_.size()),
758 client_socket_factory_.allocation_count());
759
760 EXPECT_EQ(1, GetOrderOfRequest(1));
761 EXPECT_EQ(2, GetOrderOfRequest(2));
762 EXPECT_EQ(3, GetOrderOfRequest(3));
763 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:17764 EXPECT_EQ(5, GetOrderOfRequest(5));
765
766 // Make sure we test order of all requests made.
767 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53768}
769
770// Inside ClientSocketPoolBase we have a may_have_stalled_group flag,
771// which tells it to use more expensive, but accurate, group selection
772// algorithm. Make sure it doesn't get stuck in the "on" state.
773TEST_F(ClientSocketPoolBaseTest, MayHaveStalledGroupReset) {
774 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
775
776 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
777
778 // Reach group socket limit.
779 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
780 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
781 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
782
783 // Reach total limit, but don't request more sockets.
784 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
785 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
786 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
787
788 // Request one more socket while we are at the maximum sockets limit.
789 // This should flip the may_have_stalled_group flag.
790 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
791 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
792
793 // After releasing first connection for "a", we're still at the
794 // maximum sockets limit, but every group's pending queue is empty,
795 // so we reset the flag.
796 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
797 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
798
799 // Requesting additional socket while at the total limit should
800 // flip the flag back to "on".
801 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
802 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
803
804 // We'll request one more socket to verify that we don't reset the flag
805 // too eagerly.
806 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
807 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
808
809 // We're at the maximum socket limit, and still have one request pending
810 // for "d". Flag should be "on".
811 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
812 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
813
814 // Now every group's pending queue should be empty again.
815 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
816 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
817
818 ReleaseAllConnections(KEEP_ALIVE);
819 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
820}
821
[email protected]ab838892009-06-30 18:49:05822TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:53823 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09824
[email protected]c9d6a1d2009-07-14 16:15:20825 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
826 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:31827 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
828 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
829 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
830 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
831 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:09832
[email protected]c9d6a1d2009-07-14 16:15:20833 ReleaseAllConnections(KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09834
[email protected]c9d6a1d2009-07-14 16:15:20835 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
836 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17837 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09838
[email protected]c9d6a1d2009-07-14 16:15:20839 EXPECT_EQ(1, GetOrderOfRequest(1));
840 EXPECT_EQ(2, GetOrderOfRequest(2));
841 EXPECT_EQ(6, GetOrderOfRequest(3));
842 EXPECT_EQ(4, GetOrderOfRequest(4));
843 EXPECT_EQ(3, GetOrderOfRequest(5));
844 EXPECT_EQ(5, GetOrderOfRequest(6));
845 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17846
847 // Make sure we test order of all requests made.
848 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:09849}
850
[email protected]ab838892009-06-30 18:49:05851TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:53852 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09853
[email protected]c9d6a1d2009-07-14 16:15:20854 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
855 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:31856 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
857 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
858 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
859 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
860 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:09861
[email protected]c9d6a1d2009-07-14 16:15:20862 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09863
[email protected]c9d6a1d2009-07-14 16:15:20864 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i)
865 EXPECT_EQ(OK, requests_[i]->WaitForResult());
866
867 EXPECT_EQ(static_cast<int>(requests_.size()),
868 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17869 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09870}
871
872// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:05873// The pending connect job will be cancelled and should not call back into
874// ClientSocketPoolBase.
875TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:53876 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20877
[email protected]ab838892009-06-30 18:49:05878 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:06879 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]ab838892009-06-30 18:49:05880 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:24881 InitHandle(req.handle(), "a", kDefaultPriority, &req,
882 pool_.get(), NULL));
[email protected]a6c59f62009-07-29 16:33:33883 req.handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:09884}
885
[email protected]ab838892009-06-30 18:49:05886TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]211d21722009-07-22 15:48:53887 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20888
[email protected]ab838892009-06-30 18:49:05889 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:06890 TestSocketRequest req(&request_order_, &completion_count_);
891 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09892
[email protected]ab838892009-06-30 18:49:05893 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:24894 InitHandle(req.handle(), "a", kDefaultPriority, &req,
895 pool_.get(), NULL));
[email protected]ab838892009-06-30 18:49:05896 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:24897 InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
898 pool_.get(), NULL));
[email protected]f6d1d6eb2009-06-24 20:16:09899
[email protected]a6c59f62009-07-29 16:33:33900 req.handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:09901
902 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:33903 req2.handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:09904}
905
[email protected]ab838892009-06-30 18:49:05906TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:53907 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20908
[email protected]ab838892009-06-30 18:49:05909 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:06910 ClientSocketHandle handle;
[email protected]f6d1d6eb2009-06-24 20:16:09911 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06912 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09913
[email protected]ab838892009-06-30 18:49:05914 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:24915 InitHandle(&handle, "a", kDefaultPriority, &callback,
916 pool_.get(), NULL));
[email protected]f6d1d6eb2009-06-24 20:16:09917
918 handle.Reset();
919
920 TestCompletionCallback callback2;
[email protected]ab838892009-06-30 18:49:05921 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:24922 InitHandle(&handle, "a", kDefaultPriority, &callback2,
923 pool_.get(), NULL));
[email protected]f6d1d6eb2009-06-24 20:16:09924
925 EXPECT_EQ(OK, callback2.WaitForResult());
926 EXPECT_FALSE(callback.have_result());
927
928 handle.Reset();
929}
930
[email protected]ab838892009-06-30 18:49:05931TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:53932 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09933
[email protected]c9d6a1d2009-07-14 16:15:20934 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
935 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:31936 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
937 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
938 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
939 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
940 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:09941
942 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:20943 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]a6c59f62009-07-29 16:33:33944 EXPECT_FALSE(requests_[index_to_cancel]->handle()->is_initialized());
945 requests_[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:09946
[email protected]c9d6a1d2009-07-14 16:15:20947 ReleaseAllConnections(KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09948
[email protected]c9d6a1d2009-07-14 16:15:20949 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
950 client_socket_factory_.allocation_count());
951 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup - 1,
[email protected]75439d3b2009-07-23 22:11:17952 completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09953
[email protected]c9d6a1d2009-07-14 16:15:20954 EXPECT_EQ(1, GetOrderOfRequest(1));
955 EXPECT_EQ(2, GetOrderOfRequest(2));
956 EXPECT_EQ(5, GetOrderOfRequest(3));
957 EXPECT_EQ(3, GetOrderOfRequest(4));
958 EXPECT_EQ(kRequestNotFound, GetOrderOfRequest(5)); // Canceled request.
959 EXPECT_EQ(4, GetOrderOfRequest(6));
960 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17961
962 // Make sure we test order of all requests made.
963 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:09964}
965
966class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
967 public:
[email protected]2ab05b52009-07-01 23:57:58968 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:24969 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:58970 TestConnectJobFactory* test_connect_job_factory,
971 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:09972 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:06973 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:58974 within_callback_(false),
975 test_connect_job_factory_(test_connect_job_factory),
976 next_job_type_(next_job_type) {}
[email protected]f6d1d6eb2009-06-24 20:16:09977
978 virtual void RunWithParams(const Tuple1<int>& params) {
979 callback_.RunWithParams(params);
980 ASSERT_EQ(OK, params.a);
981
982 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:58983 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]f6d1d6eb2009-06-24 20:16:09984 handle_->Reset();
985 within_callback_ = true;
[email protected]6b175382009-10-13 06:47:47986 TestCompletionCallback next_job_callback;
[email protected]a937a06d2009-08-19 21:19:24987 int rv = InitHandle(
[email protected]6b175382009-10-13 06:47:47988 handle_, "a", kDefaultPriority, &next_job_callback, pool_.get(),
989 NULL);
[email protected]2ab05b52009-07-01 23:57:58990 switch (next_job_type_) {
991 case TestConnectJob::kMockJob:
992 EXPECT_EQ(OK, rv);
993 break;
994 case TestConnectJob::kMockPendingJob:
995 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:47996
997 // For pending jobs, wait for new socket to be created. This makes
998 // sure there are no more pending operations nor any unclosed sockets
999 // when the test finishes.
1000 // We need to give it a little bit of time to run, so that all the
1001 // operations that happen on timers (e.g. cleanup of idle
1002 // connections) can execute.
1003 MessageLoop::current()->SetNestableTasksAllowed(true);
1004 PlatformThread::Sleep(10);
1005 EXPECT_EQ(OK, next_job_callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581006 break;
1007 default:
1008 FAIL() << "Unexpected job type: " << next_job_type_;
1009 break;
1010 }
[email protected]f6d1d6eb2009-06-24 20:16:091011 }
1012 }
1013
1014 int WaitForResult() {
1015 return callback_.WaitForResult();
1016 }
1017
1018 private:
1019 ClientSocketHandle* const handle_;
[email protected]a937a06d2009-08-19 21:19:241020 const scoped_refptr<TestClientSocketPool> pool_;
[email protected]f6d1d6eb2009-06-24 20:16:091021 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:581022 TestConnectJobFactory* const test_connect_job_factory_;
1023 TestConnectJob::JobType next_job_type_;
[email protected]f6d1d6eb2009-06-24 20:16:091024 TestCompletionCallback callback_;
1025};
1026
[email protected]2ab05b52009-07-01 23:57:581027TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531028 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201029
[email protected]0b7648c2009-07-06 20:14:011030 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061031 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581032 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061033 &handle, pool_.get(), connect_job_factory_,
1034 TestConnectJob::kMockPendingJob);
[email protected]a937a06d2009-08-19 21:19:241035 int rv = InitHandle(&handle, "a", kDefaultPriority, &callback,
1036 pool_.get(), NULL);
[email protected]f6d1d6eb2009-06-24 20:16:091037 ASSERT_EQ(ERR_IO_PENDING, rv);
1038
1039 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581040 handle.Reset();
1041}
[email protected]f6d1d6eb2009-06-24 20:16:091042
[email protected]2ab05b52009-07-01 23:57:581043TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531044 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201045
[email protected]0b7648c2009-07-06 20:14:011046 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061047 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581048 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061049 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]a937a06d2009-08-19 21:19:241050 int rv = InitHandle(&handle, "a", kDefaultPriority, &callback,
1051 pool_.get(), NULL);
[email protected]2ab05b52009-07-01 23:57:581052 ASSERT_EQ(ERR_IO_PENDING, rv);
1053
1054 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091055 handle.Reset();
1056}
1057
1058// Make sure that pending requests get serviced after active requests get
1059// cancelled.
[email protected]ab838892009-06-30 18:49:051060TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531061 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201062
[email protected]0b7648c2009-07-06 20:14:011063 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091064
[email protected]c9d6a1d2009-07-14 16:15:201065 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));
1068 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1069 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1070 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1071 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091072
[email protected]c9d6a1d2009-07-14 16:15:201073 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1074 // Let's cancel them.
1075 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]a6c59f62009-07-29 16:33:331076 ASSERT_FALSE(requests_[i]->handle()->is_initialized());
1077 requests_[i]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091078 }
1079
[email protected]f6d1d6eb2009-06-24 20:16:091080 // Let's wait for the rest to complete now.
[email protected]c9d6a1d2009-07-14 16:15:201081 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i) {
1082 EXPECT_EQ(OK, requests_[i]->WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331083 requests_[i]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091084 }
1085
[email protected]75439d3b2009-07-23 22:11:171086 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091087}
1088
1089// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051090TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531091 const size_t kMaxSockets = 5;
1092 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201093
[email protected]0b7648c2009-07-06 20:14:011094 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091095
[email protected]211d21722009-07-22 15:48:531096 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1097 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091098
1099 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531100 for (size_t i = 0; i < kNumberOfRequests; ++i)
1101 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091102
[email protected]211d21722009-07-22 15:48:531103 for (size_t i = 0; i < kNumberOfRequests; ++i)
1104 EXPECT_EQ(ERR_CONNECTION_FAILED, requests_[i]->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091105}
1106
[email protected]5fc08e32009-07-15 17:09:571107TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531108 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571109
1110 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1111
[email protected]a512f5982009-08-18 16:01:061112 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241113 int rv = InitHandle(req.handle(), "a", kDefaultPriority, &req,
1114 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571115 EXPECT_EQ(ERR_IO_PENDING, rv);
1116
1117 // Cancel the active request.
[email protected]a6c59f62009-07-29 16:33:331118 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571119
[email protected]a937a06d2009-08-19 21:19:241120 rv = InitHandle(req.handle(), "a", kDefaultPriority, &req,
1121 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571122 EXPECT_EQ(ERR_IO_PENDING, rv);
1123 EXPECT_EQ(OK, req.WaitForResult());
1124
[email protected]a6c59f62009-07-29 16:33:331125 EXPECT_FALSE(req.handle()->is_reused());
[email protected]75439d3b2009-07-23 22:11:171126 EXPECT_EQ(1U, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571127 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1128}
1129
[email protected]2ab05b52009-07-01 23:57:581130// A pending asynchronous job completes, which will free up a socket slot. The
1131// next job finishes synchronously. The callback for the asynchronous job
1132// should be first though.
1133TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531134 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201135
[email protected]2ab05b52009-07-01 23:57:581136 // First two jobs are async.
[email protected]0b7648c2009-07-06 20:14:011137 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2ab05b52009-07-01 23:57:581138
1139 // Start job 1 (async error).
[email protected]a512f5982009-08-18 16:01:061140 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241141 int rv = InitHandle(req1.handle(), "a", kDefaultPriority, &req1,
1142 pool_.get(), NULL);
[email protected]2ab05b52009-07-01 23:57:581143 EXPECT_EQ(ERR_IO_PENDING, rv);
1144
1145 // Start job 2 (async error).
[email protected]a512f5982009-08-18 16:01:061146 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241147 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
1148 pool_.get(), NULL);
[email protected]2ab05b52009-07-01 23:57:581149 EXPECT_EQ(ERR_IO_PENDING, rv);
1150
1151 // The pending job is sync.
[email protected]0b7648c2009-07-06 20:14:011152 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]2ab05b52009-07-01 23:57:581153
1154 // Request 3 does not have a ConnectJob yet. It's just pending.
[email protected]a512f5982009-08-18 16:01:061155 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241156 rv = InitHandle(
1157 req3.handle(), "a", kDefaultPriority, &req3, pool_.get(), NULL);
[email protected]2ab05b52009-07-01 23:57:581158 EXPECT_EQ(ERR_IO_PENDING, rv);
1159
1160 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1161 EXPECT_EQ(ERR_CONNECTION_FAILED, req2.WaitForResult());
1162 EXPECT_EQ(OK, req3.WaitForResult());
1163
1164 ASSERT_EQ(3U, request_order_.size());
1165
1166 // After job 1 finishes unsuccessfully, it will try to process the pending
1167 // requests queue, so it starts up job 3 for request 3. This job
1168 // synchronously succeeds, so the request order is 1, 3, 2.
1169 EXPECT_EQ(&req1, request_order_[0]);
1170 EXPECT_EQ(&req2, request_order_[2]);
1171 EXPECT_EQ(&req3, request_order_[1]);
1172}
1173
[email protected]5fc08e32009-07-15 17:09:571174// When a ConnectJob is coupled to a request, even if a free socket becomes
1175// available, the request will be serviced by the ConnectJob.
1176TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531177 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]d80a4322009-08-14 07:07:491178 EnableLateBindingOfSockets(false);
[email protected]5fc08e32009-07-15 17:09:571179
1180 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321181 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571182
[email protected]a512f5982009-08-18 16:01:061183 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241184 int rv = InitHandle(req1.handle(), "a", kDefaultPriority, &req1,
1185 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571186 EXPECT_EQ(ERR_IO_PENDING, rv);
1187 EXPECT_EQ(OK, req1.WaitForResult());
1188
1189 // Job 1 finished OK. Start job 2 (also async OK). Release socket 1.
1190 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1191
[email protected]a512f5982009-08-18 16:01:061192 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241193 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
1194 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571195 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331196 req1.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571197 MessageLoop::current()->RunAllPending(); // Run the DoReleaseSocket()
1198
1199 // Job 2 is pending. Start request 3 (which has no associated job since it
1200 // will use the idle socket).
1201
[email protected]a512f5982009-08-18 16:01:061202 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241203 rv = InitHandle(req3.handle(), "a", kDefaultPriority, &req3,
1204 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571205 EXPECT_EQ(OK, rv);
1206
[email protected]a6c59f62009-07-29 16:33:331207 EXPECT_FALSE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571208 client_socket_factory_.SignalJobs();
1209 EXPECT_EQ(OK, req2.WaitForResult());
1210
1211 ASSERT_EQ(2U, request_order_.size());
1212 EXPECT_EQ(&req1, request_order_[0]);
1213 EXPECT_EQ(&req2, request_order_[1]);
1214 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1215}
1216
[email protected]2b7523d2009-07-29 20:29:231217// Regression test for http://crbug.com/17985.
1218TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1219 const int kMaxSockets = 3;
1220 const int kMaxSocketsPerGroup = 2;
1221 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1222
[email protected]ac790b42009-12-02 04:31:311223 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231224
1225 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1226 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1227
1228 // This is going to be a pending request in an otherwise empty group.
1229 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1230
1231 // Reach the maximum socket limit.
1232 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1233
1234 // Create a stalled group with high priorities.
1235 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1236 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1237 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
1238
1239 // Release the first two sockets from "a", which will make room
1240 // for requests from "c". After that "a" will have no active sockets
1241 // and one pending request.
1242 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1243 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1244
1245 // Closing idle sockets should not get us into trouble, but in the bug
1246 // we were hitting a CHECK here.
1247 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
1248 pool_->CloseIdleSockets();
1249 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1250}
1251
[email protected]5fc08e32009-07-15 17:09:571252class ClientSocketPoolBaseTest_LateBinding : public ClientSocketPoolBaseTest {
1253 protected:
1254 virtual void SetUp() {
1255 ClientSocketPoolBaseTest::SetUp();
[email protected]d80a4322009-08-14 07:07:491256 EnableLateBindingOfSockets(true);
[email protected]5fc08e32009-07-15 17:09:571257 }
1258};
1259
[email protected]6e713f02009-08-06 02:56:401260// Even though a timeout is specified, it doesn't time out on a synchronous
1261// completion.
1262TEST_F(ClientSocketPoolBaseTest_LateBinding,
1263 ConnectJob_NoTimeoutOnSynchronousCompletion) {
1264 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:061265 ClientSocketHandle ignored;
[email protected]ac790b42009-12-02 04:31:311266 TestClientSocketPoolBase::Request request(&ignored, NULL, LOWEST, NULL,
1267 NULL);
[email protected]6e713f02009-08-06 02:56:401268 scoped_ptr<TestConnectJob> job(
1269 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:121270 "a",
[email protected]6e713f02009-08-06 02:56:401271 request,
1272 base::TimeDelta::FromMicroseconds(1),
1273 &delegate,
[email protected]fd7b7c92009-08-20 19:38:301274 &client_socket_factory_,
1275 NULL));
[email protected]6e713f02009-08-06 02:56:401276 EXPECT_EQ(OK, job->Connect());
1277}
1278
1279TEST_F(ClientSocketPoolBaseTest_LateBinding, ConnectJob_TimedOut) {
1280 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:061281 ClientSocketHandle ignored;
[email protected]ac790b42009-12-02 04:31:311282 TestClientSocketPoolBase::Request request(&ignored, NULL, LOWEST, NULL,
1283 NULL);
[email protected]6e713f02009-08-06 02:56:401284 // Deleted by TestConnectJobDelegate.
1285 TestConnectJob* job =
1286 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:121287 "a",
[email protected]6e713f02009-08-06 02:56:401288 request,
1289 base::TimeDelta::FromMicroseconds(1),
1290 &delegate,
[email protected]fd7b7c92009-08-20 19:38:301291 &client_socket_factory_,
1292 NULL);
[email protected]6e713f02009-08-06 02:56:401293 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
1294 PlatformThread::Sleep(1);
1295 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
1296}
1297
[email protected]5fc08e32009-07-15 17:09:571298TEST_F(ClientSocketPoolBaseTest_LateBinding, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:531299 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571300
1301 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:061302 ClientSocketHandle handle;
[email protected]60c4c412009-11-06 19:59:361303 scoped_refptr<LoadLog> log(new LoadLog(LoadLog::kUnbounded));
[email protected]a937a06d2009-08-19 21:19:241304 EXPECT_EQ(OK, InitHandle(&handle, "a", kDefaultPriority, &callback,
[email protected]fd7b7c92009-08-20 19:38:301305 pool_.get(), log));
[email protected]5fc08e32009-07-15 17:09:571306 EXPECT_TRUE(handle.is_initialized());
1307 EXPECT_TRUE(handle.socket());
1308 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:301309
[email protected]bf6c087a2009-12-21 20:45:101310 EXPECT_EQ(4u, log->entries().size());
[email protected]fd7b7c92009-08-20 19:38:301311 ExpectLogContains(log, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
1312 ExpectLogContains(log, 1, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1313 LoadLog::PHASE_BEGIN);
1314 ExpectLogContains(log, 2, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1315 LoadLog::PHASE_END);
1316 ExpectLogContains(log, 3, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
[email protected]5fc08e32009-07-15 17:09:571317}
1318
1319TEST_F(ClientSocketPoolBaseTest_LateBinding, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531320 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571321
1322 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061323 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]60c4c412009-11-06 19:59:361324 scoped_refptr<LoadLog> log(new LoadLog(LoadLog::kUnbounded));
[email protected]ac790b42009-12-02 04:31:311325 int rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_.get(), log);
[email protected]5fc08e32009-07-15 17:09:571326 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331327 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:571328 EXPECT_EQ(OK, req.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331329 EXPECT_TRUE(req.handle()->is_initialized());
1330 EXPECT_TRUE(req.handle()->socket());
1331 req.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:301332
[email protected]bf6c087a2009-12-21 20:45:101333 EXPECT_EQ(6u, log->entries().size());
[email protected]fd7b7c92009-08-20 19:38:301334 ExpectLogContains(log, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
1335 ExpectLogContains(log, 1, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1336 LoadLog::PHASE_BEGIN);
1337 ExpectLogContains(log, 2, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1338 LoadLog::PHASE_END);
1339 ExpectLogContains(log, 3, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1340 LoadLog::PHASE_BEGIN);
1341 ExpectLogContains(log, 4, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1342 LoadLog::PHASE_END);
1343 ExpectLogContains(log, 5, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
[email protected]5fc08e32009-07-15 17:09:571344}
1345
1346TEST_F(ClientSocketPoolBaseTest_LateBinding, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:531347 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571348
1349 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]a512f5982009-08-18 16:01:061350 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]60c4c412009-11-06 19:59:361351 scoped_refptr<LoadLog> log(new LoadLog(LoadLog::kUnbounded));
[email protected]5fc08e32009-07-15 17:09:571352 EXPECT_EQ(ERR_CONNECTION_FAILED,
[email protected]a937a06d2009-08-19 21:19:241353 InitHandle(req.handle(), "a", kDefaultPriority, &req,
[email protected]fd7b7c92009-08-20 19:38:301354 pool_.get(), log));
1355
[email protected]bf6c087a2009-12-21 20:45:101356 EXPECT_EQ(4u, log->entries().size());
[email protected]fd7b7c92009-08-20 19:38:301357 ExpectLogContains(log, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
1358 ExpectLogContains(log, 1, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1359 LoadLog::PHASE_BEGIN);
1360 ExpectLogContains(log, 2, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1361 LoadLog::PHASE_END);
1362 ExpectLogContains(log, 3, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
[email protected]5fc08e32009-07-15 17:09:571363}
1364
1365TEST_F(ClientSocketPoolBaseTest_LateBinding,
1366 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531367 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571368
1369 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]a512f5982009-08-18 16:01:061370 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]60c4c412009-11-06 19:59:361371 scoped_refptr<LoadLog> log(new LoadLog(LoadLog::kUnbounded));
[email protected]5fc08e32009-07-15 17:09:571372 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:241373 InitHandle(req.handle(), "a", kDefaultPriority, &req,
[email protected]fd7b7c92009-08-20 19:38:301374 pool_.get(), log));
[email protected]a6c59f62009-07-29 16:33:331375 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:571376 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:301377
[email protected]bf6c087a2009-12-21 20:45:101378 EXPECT_EQ(6u, log->entries().size());
[email protected]fd7b7c92009-08-20 19:38:301379 ExpectLogContains(log, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
1380 ExpectLogContains(log, 1, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1381 LoadLog::PHASE_BEGIN);
1382 ExpectLogContains(log, 2, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1383 LoadLog::PHASE_END);
1384 ExpectLogContains(log, 3, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1385 LoadLog::PHASE_BEGIN);
1386 ExpectLogContains(log, 4, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1387 LoadLog::PHASE_END);
1388 ExpectLogContains(log, 5, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
[email protected]5fc08e32009-07-15 17:09:571389}
1390
1391TEST_F(ClientSocketPoolBaseTest_LateBinding, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531392 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571393
1394 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1395 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311396 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1397 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1398 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1399 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1400 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]5fc08e32009-07-15 17:09:571401
1402 ReleaseAllConnections(KEEP_ALIVE);
1403
1404 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1405 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:171406 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571407
1408 EXPECT_EQ(1, GetOrderOfRequest(1));
1409 EXPECT_EQ(2, GetOrderOfRequest(2));
1410 EXPECT_EQ(6, GetOrderOfRequest(3));
1411 EXPECT_EQ(4, GetOrderOfRequest(4));
1412 EXPECT_EQ(3, GetOrderOfRequest(5));
1413 EXPECT_EQ(5, GetOrderOfRequest(6));
1414 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171415
1416 // Make sure we test order of all requests made.
1417 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]5fc08e32009-07-15 17:09:571418}
1419
1420TEST_F(ClientSocketPoolBaseTest_LateBinding, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531421 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571422
1423 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1424 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311425 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1426 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1427 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1428 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1429 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]5fc08e32009-07-15 17:09:571430
1431 ReleaseAllConnections(NO_KEEP_ALIVE);
1432
1433 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i)
1434 EXPECT_EQ(OK, requests_[i]->WaitForResult());
1435
1436 EXPECT_EQ(static_cast<int>(requests_.size()),
1437 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:171438 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571439}
1440
1441// This test will start up a RequestSocket() and then immediately Cancel() it.
1442// The pending connect job will be cancelled and should not call back into
1443// ClientSocketPoolBase.
1444TEST_F(ClientSocketPoolBaseTest_LateBinding, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531445 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571446
1447 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061448 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]5fc08e32009-07-15 17:09:571449 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:241450 InitHandle(req.handle(), "a", kDefaultPriority, &req,
1451 pool_.get(), NULL));
[email protected]a6c59f62009-07-29 16:33:331452 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571453}
1454
1455TEST_F(ClientSocketPoolBaseTest_LateBinding, TwoRequestsCancelOne) {
[email protected]211d21722009-07-22 15:48:531456 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571457
1458 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061459 TestSocketRequest req(&request_order_, &completion_count_);
1460 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]5fc08e32009-07-15 17:09:571461
[email protected]60c4c412009-11-06 19:59:361462 scoped_refptr<LoadLog> log1(new LoadLog(LoadLog::kUnbounded));
[email protected]5fc08e32009-07-15 17:09:571463 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:241464 InitHandle(req.handle(), "a", kDefaultPriority, &req,
[email protected]fd7b7c92009-08-20 19:38:301465 pool_.get(), log1));
[email protected]60c4c412009-11-06 19:59:361466 scoped_refptr<LoadLog> log2(new LoadLog(LoadLog::kUnbounded));
[email protected]5fc08e32009-07-15 17:09:571467 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:241468 InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
[email protected]fd7b7c92009-08-20 19:38:301469 pool_.get(), log2));
[email protected]5fc08e32009-07-15 17:09:571470
[email protected]a6c59f62009-07-29 16:33:331471 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571472
[email protected]bf6c087a2009-12-21 20:45:101473 EXPECT_EQ(5u, log1->entries().size());
[email protected]fd7b7c92009-08-20 19:38:301474 ExpectLogContains(log1, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
1475 ExpectLogContains(log1, 1, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1476 LoadLog::PHASE_BEGIN);
1477 ExpectLogContains(log1, 2, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1478 LoadLog::PHASE_END);
1479 ExpectLogContains(log1, 3, LoadLog::TYPE_CANCELLED, LoadLog::PHASE_NONE);
1480 ExpectLogContains(log1, 4, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
1481
1482 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]bf6c087a2009-12-21 20:45:101483 EXPECT_EQ(2u, log2->entries().size());
[email protected]fd7b7c92009-08-20 19:38:301484 ExpectLogContains(log2, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
1485 ExpectLogContains(log2, 1, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1486 LoadLog::PHASE_BEGIN);
1487
[email protected]5fc08e32009-07-15 17:09:571488 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331489 req2.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:301490
1491 // Now request 2 has actually finished.
[email protected]bf6c087a2009-12-21 20:45:101492 EXPECT_EQ(6u, log2->entries().size());
[email protected]fd7b7c92009-08-20 19:38:301493 ExpectLogContains(log2, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
1494 ExpectLogContains(log2, 1, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1495 LoadLog::PHASE_BEGIN);
1496 ExpectLogContains(log1, 2, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1497 LoadLog::PHASE_END);
1498 ExpectLogContains(log2, 3, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1499 LoadLog::PHASE_BEGIN);
1500 ExpectLogContains(log2, 4, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1501 LoadLog::PHASE_END);
1502 ExpectLogContains(log2, 5, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
1503
[email protected]5fc08e32009-07-15 17:09:571504}
1505
1506TEST_F(ClientSocketPoolBaseTest_LateBinding, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531507 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571508
1509 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061510 ClientSocketHandle handle;
[email protected]5fc08e32009-07-15 17:09:571511 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:061512 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]5fc08e32009-07-15 17:09:571513
1514 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:241515 InitHandle(&handle, "a", kDefaultPriority, &callback,
1516 pool_.get(), NULL));
[email protected]5fc08e32009-07-15 17:09:571517
1518 handle.Reset();
1519
1520 TestCompletionCallback callback2;
1521 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:241522 InitHandle(&handle, "a", kDefaultPriority, &callback2,
1523 pool_.get(), NULL));
[email protected]5fc08e32009-07-15 17:09:571524
1525 EXPECT_EQ(OK, callback2.WaitForResult());
1526 EXPECT_FALSE(callback.have_result());
1527
1528 handle.Reset();
1529}
1530
1531TEST_F(ClientSocketPoolBaseTest_LateBinding, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531532 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571533
1534 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1535 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311536 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1537 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1538 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1539 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1540 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]5fc08e32009-07-15 17:09:571541
1542 // Cancel a request.
1543 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]a6c59f62009-07-29 16:33:331544 EXPECT_FALSE(requests_[index_to_cancel]->handle()->is_initialized());
1545 requests_[index_to_cancel]->handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571546
1547 ReleaseAllConnections(KEEP_ALIVE);
1548
1549 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1550 client_socket_factory_.allocation_count());
1551 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup - 1,
[email protected]75439d3b2009-07-23 22:11:171552 completion_count_);
[email protected]5fc08e32009-07-15 17:09:571553
1554 EXPECT_EQ(1, GetOrderOfRequest(1));
1555 EXPECT_EQ(2, GetOrderOfRequest(2));
1556 EXPECT_EQ(5, GetOrderOfRequest(3));
1557 EXPECT_EQ(3, GetOrderOfRequest(4));
1558 EXPECT_EQ(kRequestNotFound, GetOrderOfRequest(5)); // Canceled request.
1559 EXPECT_EQ(4, GetOrderOfRequest(6));
1560 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171561
1562 // Make sure we test order of all requests made.
1563 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]5fc08e32009-07-15 17:09:571564}
1565
[email protected]974ebd62009-08-03 23:14:341566TEST_F(ClientSocketPoolBaseTest_LateBinding, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341567 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1568
[email protected]17a0c6c2009-08-04 00:07:041569 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1570
[email protected]ac790b42009-12-02 04:31:311571 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1572 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1573 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1574 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341575
1576 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1577 requests_[2]->handle()->Reset();
1578 requests_[3]->handle()->Reset();
1579 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1580
1581 requests_[1]->handle()->Reset();
1582 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1583
1584 requests_[0]->handle()->Reset();
1585 EXPECT_EQ(kDefaultMaxSocketsPerGroup - 1, pool_->NumConnectJobsInGroup("a"));
1586}
1587
[email protected]5fc08e32009-07-15 17:09:571588TEST_F(ClientSocketPoolBaseTest_LateBinding, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531589 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571590
1591 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061592 ClientSocketHandle handle;
[email protected]5fc08e32009-07-15 17:09:571593 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061594 &handle, pool_.get(), connect_job_factory_,
1595 TestConnectJob::kMockPendingJob);
[email protected]a937a06d2009-08-19 21:19:241596 int rv = InitHandle(
1597 &handle, "a", kDefaultPriority, &callback, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571598 ASSERT_EQ(ERR_IO_PENDING, rv);
1599
1600 EXPECT_EQ(OK, callback.WaitForResult());
1601 handle.Reset();
1602}
1603
1604TEST_F(ClientSocketPoolBaseTest_LateBinding, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531605 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571606
1607 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061608 ClientSocketHandle handle;
[email protected]5fc08e32009-07-15 17:09:571609 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061610 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]a937a06d2009-08-19 21:19:241611 int rv = InitHandle(
1612 &handle, "a", kDefaultPriority, &callback,
[email protected]a512f5982009-08-18 16:01:061613 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571614 ASSERT_EQ(ERR_IO_PENDING, rv);
1615
1616 EXPECT_EQ(OK, callback.WaitForResult());
1617 handle.Reset();
1618}
1619
1620// Make sure that pending requests get serviced after active requests get
1621// cancelled.
1622TEST_F(ClientSocketPoolBaseTest_LateBinding,
1623 CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531624 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571625
1626 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1627
1628 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1629 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1630 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1631 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1632 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1633 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1634 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1635
1636 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1637 // Let's cancel them.
1638 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]a6c59f62009-07-29 16:33:331639 ASSERT_FALSE(requests_[i]->handle()->is_initialized());
1640 requests_[i]->handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571641 }
1642
1643 // Let's wait for the rest to complete now.
1644 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i) {
1645 EXPECT_EQ(OK, requests_[i]->WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331646 requests_[i]->handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571647 }
1648
[email protected]75439d3b2009-07-23 22:11:171649 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571650}
1651
1652// Make sure that pending requests get serviced after active requests fail.
1653TEST_F(ClientSocketPoolBaseTest_LateBinding,
1654 FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531655 const int kMaxSockets = 5;
1656 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571657
1658 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1659
[email protected]211d21722009-07-22 15:48:531660 const int kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1661 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test hangs.
[email protected]5fc08e32009-07-15 17:09:571662
1663 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531664 for (int i = 0; i < kNumberOfRequests; ++i)
1665 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]5fc08e32009-07-15 17:09:571666
[email protected]211d21722009-07-22 15:48:531667 for (int i = 0; i < kNumberOfRequests; ++i)
1668 EXPECT_EQ(ERR_CONNECTION_FAILED, requests_[i]->WaitForResult());
[email protected]5fc08e32009-07-15 17:09:571669}
1670
1671TEST_F(ClientSocketPoolBaseTest_LateBinding,
1672 CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531673 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571674
1675 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1676
[email protected]a512f5982009-08-18 16:01:061677 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241678 int rv = InitHandle(req.handle(), "a", kDefaultPriority, &req,
1679 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571680 EXPECT_EQ(ERR_IO_PENDING, rv);
1681
1682 // Cancel the active request.
[email protected]a6c59f62009-07-29 16:33:331683 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571684
[email protected]a937a06d2009-08-19 21:19:241685 rv = InitHandle(req.handle(), "a", kDefaultPriority, &req,
1686 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571687 EXPECT_EQ(ERR_IO_PENDING, rv);
1688 EXPECT_EQ(OK, req.WaitForResult());
1689
[email protected]a6c59f62009-07-29 16:33:331690 EXPECT_FALSE(req.handle()->is_reused());
[email protected]75439d3b2009-07-23 22:11:171691 EXPECT_EQ(1U, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571692 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1693}
1694
1695// When requests and ConnectJobs are not coupled, the request will get serviced
1696// by whatever comes first.
1697TEST_F(ClientSocketPoolBaseTest_LateBinding, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531698 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571699
1700 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321701 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571702
[email protected]a512f5982009-08-18 16:01:061703 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241704 int rv = InitHandle(req1.handle(), "a", kDefaultPriority,
1705 &req1, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571706 EXPECT_EQ(ERR_IO_PENDING, rv);
1707 EXPECT_EQ(OK, req1.WaitForResult());
1708
1709 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1710 // without a job.
1711 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1712
[email protected]a512f5982009-08-18 16:01:061713 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241714 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
1715 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571716 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a512f5982009-08-18 16:01:061717 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241718 rv = InitHandle(
1719 req3.handle(), "a", kDefaultPriority, &req3, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571720 EXPECT_EQ(ERR_IO_PENDING, rv);
1721
1722 // Both Requests 2 and 3 are pending. We release socket 1 which should
1723 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331724 req1.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571725 MessageLoop::current()->RunAllPending(); // Run the DoReleaseSocket()
[email protected]a6c59f62009-07-29 16:33:331726 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571727 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331728 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571729
1730 // Signal job 2, which should service request 3.
1731
1732 client_socket_factory_.SignalJobs();
1733 EXPECT_EQ(OK, req3.WaitForResult());
1734
1735 ASSERT_EQ(3U, request_order_.size());
1736 EXPECT_EQ(&req1, request_order_[0]);
1737 EXPECT_EQ(&req2, request_order_[1]);
1738 EXPECT_EQ(&req3, request_order_[2]);
1739 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1740}
1741
1742// The requests are not coupled to the jobs. So, the requests should finish in
1743// their priority / insertion order.
1744TEST_F(ClientSocketPoolBaseTest_LateBinding, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531745 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571746 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321747 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571748
[email protected]a512f5982009-08-18 16:01:061749 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241750 int rv = InitHandle(
1751 req1.handle(), "a", kDefaultPriority, &req1, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571752 EXPECT_EQ(ERR_IO_PENDING, rv);
1753
[email protected]a512f5982009-08-18 16:01:061754 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241755 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
1756 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571757 EXPECT_EQ(ERR_IO_PENDING, rv);
1758
1759 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321760 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571761
[email protected]a512f5982009-08-18 16:01:061762 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241763 rv = InitHandle(
1764 req3.handle(), "a", kDefaultPriority, &req3, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571765 EXPECT_EQ(ERR_IO_PENDING, rv);
1766
1767 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1768 EXPECT_EQ(OK, req2.WaitForResult());
1769 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1770
1771 ASSERT_EQ(3U, request_order_.size());
1772 EXPECT_EQ(&req1, request_order_[0]);
1773 EXPECT_EQ(&req2, request_order_[1]);
1774 EXPECT_EQ(&req3, request_order_[2]);
1775}
1776
[email protected]f0109a7d2009-07-16 00:09:521777TEST_F(ClientSocketPoolBaseTest_LateBinding, DISABLED_LoadState) {
[email protected]211d21722009-07-22 15:48:531778 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571779 connect_job_factory_->set_job_type(
[email protected]b59ff372009-07-15 22:04:321780 TestConnectJob::kMockAdvancingLoadStateJob);
[email protected]5fc08e32009-07-15 17:09:571781
[email protected]a512f5982009-08-18 16:01:061782 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241783 int rv = InitHandle(
1784 req1.handle(), "a", kDefaultPriority, &req1, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571785 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331786 EXPECT_EQ(LOAD_STATE_IDLE, req1.handle()->GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571787
1788 MessageLoop::current()->RunAllPending();
1789
[email protected]a512f5982009-08-18 16:01:061790 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241791 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
1792 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571793 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331794 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, req1.handle()->GetLoadState());
1795 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, req2.handle()->GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571796}
1797
[email protected]2b7523d2009-07-29 20:29:231798// Regression test for http://crbug.com/17985.
1799TEST_F(ClientSocketPoolBaseTest_LateBinding,
1800 GroupWithPendingRequestsIsNotEmpty) {
1801 const int kMaxSockets = 3;
1802 const int kMaxSocketsPerGroup = 2;
1803 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1804
[email protected]ac790b42009-12-02 04:31:311805 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231806
1807 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1808 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1809
1810 // This is going to be a pending request in an otherwise empty group.
1811 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1812
1813 // Reach the maximum socket limit.
1814 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1815
1816 // Create a stalled group with high priorities.
1817 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1818 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1819 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
1820
1821 // Release the first two sockets from "a", which will make room
1822 // for requests from "c". After that "a" will have no active sockets
1823 // and one pending request.
1824 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1825 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1826
1827 // Closing idle sockets should not get us into trouble, but in the bug
1828 // we were hitting a CHECK here.
1829 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
1830 pool_->CloseIdleSockets();
1831 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1832}
1833
[email protected]9bf28db2009-08-29 01:35:161834TEST_F(ClientSocketPoolBaseTest_LateBinding, CleanupTimedOutIdleSockets) {
1835 CreatePoolWithIdleTimeouts(
1836 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1837 base::TimeDelta(), // Time out unused sockets immediately.
1838 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1839
1840 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1841
1842 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
1843
1844 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]ac790b42009-12-02 04:31:311845 int rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_.get(), NULL);
[email protected]9bf28db2009-08-29 01:35:161846 EXPECT_EQ(ERR_IO_PENDING, rv);
1847 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
1848
1849 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]ac790b42009-12-02 04:31:311850 rv = InitHandle(req2.handle(), "a", LOWEST, &req2, pool_.get(), NULL);
[email protected]9bf28db2009-08-29 01:35:161851 EXPECT_EQ(ERR_IO_PENDING, rv);
1852 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req2.handle()));
1853
1854 // Cancel one of the requests. Wait for the other, which will get the first
1855 // job. Release the socket. Run the loop again to make sure the second
1856 // socket is sitting idle and the first one is released (since ReleaseSocket()
1857 // just posts a DoReleaseSocket() task).
1858
1859 req.handle()->Reset();
1860 EXPECT_EQ(OK, req2.WaitForResult());
1861 req2.handle()->Reset();
[email protected]6b175382009-10-13 06:47:471862
1863 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1864 // actually become pending until 2ms after they have been created. In order
1865 // to flush all tasks, we need to wait so that we know there are no
1866 // soon-to-be-pending tasks waiting.
1867 PlatformThread::Sleep(10);
[email protected]9bf28db2009-08-29 01:35:161868 MessageLoop::current()->RunAllPending();
1869
1870 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:041871
[email protected]9bf28db2009-08-29 01:35:161872 // Invoke the idle socket cleanup check. Only one socket should be left, the
1873 // used socket. Request it to make sure that it's used.
1874
1875 pool_->CleanupTimedOutIdleSockets();
[email protected]ac790b42009-12-02 04:31:311876 rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_.get(), NULL);
[email protected]9bf28db2009-08-29 01:35:161877 EXPECT_EQ(OK, rv);
1878 EXPECT_TRUE(req.handle()->is_reused());
1879}
1880
[email protected]f6d1d6eb2009-06-24 20:16:091881} // namespace
1882
1883} // namespace net