blob: 6f3f5ef2c07cecb5a43053039d2e2e7c9929968b [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]5edbf8d2010-01-13 18:44:11984
985 // Don't allow reuse of the socket. Disconnect it and then release it and
986 // run through the MessageLoop once to get it completely released.
987 handle_->socket()->Disconnect();
[email protected]f6d1d6eb2009-06-24 20:16:09988 handle_->Reset();
[email protected]5edbf8d2010-01-13 18:44:11989 {
990 MessageLoop::ScopedNestableTaskAllower nestable(
991 MessageLoop::current());
992 MessageLoop::current()->RunAllPending();
993 }
[email protected]f6d1d6eb2009-06-24 20:16:09994 within_callback_ = true;
[email protected]6b175382009-10-13 06:47:47995 TestCompletionCallback next_job_callback;
[email protected]a937a06d2009-08-19 21:19:24996 int rv = InitHandle(
[email protected]6b175382009-10-13 06:47:47997 handle_, "a", kDefaultPriority, &next_job_callback, pool_.get(),
998 NULL);
[email protected]2ab05b52009-07-01 23:57:58999 switch (next_job_type_) {
1000 case TestConnectJob::kMockJob:
1001 EXPECT_EQ(OK, rv);
1002 break;
1003 case TestConnectJob::kMockPendingJob:
1004 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:471005
1006 // For pending jobs, wait for new socket to be created. This makes
1007 // sure there are no more pending operations nor any unclosed sockets
1008 // when the test finishes.
1009 // We need to give it a little bit of time to run, so that all the
1010 // operations that happen on timers (e.g. cleanup of idle
1011 // connections) can execute.
[email protected]5edbf8d2010-01-13 18:44:111012 {
1013 MessageLoop::ScopedNestableTaskAllower nestable(
1014 MessageLoop::current());
1015 PlatformThread::Sleep(10);
1016 EXPECT_EQ(OK, next_job_callback.WaitForResult());
1017 }
[email protected]2ab05b52009-07-01 23:57:581018 break;
1019 default:
1020 FAIL() << "Unexpected job type: " << next_job_type_;
1021 break;
1022 }
[email protected]f6d1d6eb2009-06-24 20:16:091023 }
1024 }
1025
1026 int WaitForResult() {
1027 return callback_.WaitForResult();
1028 }
1029
1030 private:
1031 ClientSocketHandle* const handle_;
[email protected]a937a06d2009-08-19 21:19:241032 const scoped_refptr<TestClientSocketPool> pool_;
[email protected]f6d1d6eb2009-06-24 20:16:091033 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:581034 TestConnectJobFactory* const test_connect_job_factory_;
1035 TestConnectJob::JobType next_job_type_;
[email protected]f6d1d6eb2009-06-24 20:16:091036 TestCompletionCallback callback_;
1037};
1038
[email protected]2ab05b52009-07-01 23:57:581039TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531040 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201041
[email protected]0b7648c2009-07-06 20:14:011042 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061043 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581044 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061045 &handle, pool_.get(), connect_job_factory_,
1046 TestConnectJob::kMockPendingJob);
[email protected]a937a06d2009-08-19 21:19:241047 int rv = InitHandle(&handle, "a", kDefaultPriority, &callback,
1048 pool_.get(), NULL);
[email protected]f6d1d6eb2009-06-24 20:16:091049 ASSERT_EQ(ERR_IO_PENDING, rv);
1050
1051 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581052}
[email protected]f6d1d6eb2009-06-24 20:16:091053
[email protected]2ab05b52009-07-01 23:57:581054TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531055 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201056
[email protected]0b7648c2009-07-06 20:14:011057 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061058 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581059 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061060 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]a937a06d2009-08-19 21:19:241061 int rv = InitHandle(&handle, "a", kDefaultPriority, &callback,
1062 pool_.get(), NULL);
[email protected]2ab05b52009-07-01 23:57:581063 ASSERT_EQ(ERR_IO_PENDING, rv);
1064
1065 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091066}
1067
1068// Make sure that pending requests get serviced after active requests get
1069// cancelled.
[email protected]ab838892009-06-30 18:49:051070TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531071 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201072
[email protected]0b7648c2009-07-06 20:14:011073 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091074
[email protected]c9d6a1d2009-07-14 16:15:201075 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1076 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1077 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1078 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1079 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1080 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1081 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091082
[email protected]c9d6a1d2009-07-14 16:15:201083 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1084 // Let's cancel them.
1085 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]a6c59f62009-07-29 16:33:331086 ASSERT_FALSE(requests_[i]->handle()->is_initialized());
1087 requests_[i]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091088 }
1089
[email protected]f6d1d6eb2009-06-24 20:16:091090 // Let's wait for the rest to complete now.
[email protected]c9d6a1d2009-07-14 16:15:201091 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i) {
1092 EXPECT_EQ(OK, requests_[i]->WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331093 requests_[i]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091094 }
1095
[email protected]75439d3b2009-07-23 22:11:171096 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091097}
1098
1099// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051100TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531101 const size_t kMaxSockets = 5;
1102 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201103
[email protected]0b7648c2009-07-06 20:14:011104 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091105
[email protected]211d21722009-07-22 15:48:531106 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1107 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091108
1109 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531110 for (size_t i = 0; i < kNumberOfRequests; ++i)
1111 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091112
[email protected]211d21722009-07-22 15:48:531113 for (size_t i = 0; i < kNumberOfRequests; ++i)
1114 EXPECT_EQ(ERR_CONNECTION_FAILED, requests_[i]->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091115}
1116
[email protected]5fc08e32009-07-15 17:09:571117TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531118 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571119
1120 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1121
[email protected]a512f5982009-08-18 16:01:061122 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241123 int rv = InitHandle(req.handle(), "a", kDefaultPriority, &req,
1124 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571125 EXPECT_EQ(ERR_IO_PENDING, rv);
1126
1127 // Cancel the active request.
[email protected]a6c59f62009-07-29 16:33:331128 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571129
[email protected]a937a06d2009-08-19 21:19:241130 rv = InitHandle(req.handle(), "a", kDefaultPriority, &req,
1131 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571132 EXPECT_EQ(ERR_IO_PENDING, rv);
1133 EXPECT_EQ(OK, req.WaitForResult());
1134
[email protected]a6c59f62009-07-29 16:33:331135 EXPECT_FALSE(req.handle()->is_reused());
[email protected]75439d3b2009-07-23 22:11:171136 EXPECT_EQ(1U, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571137 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1138}
1139
[email protected]2ab05b52009-07-01 23:57:581140// A pending asynchronous job completes, which will free up a socket slot. The
1141// next job finishes synchronously. The callback for the asynchronous job
1142// should be first though.
1143TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531144 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201145
[email protected]2ab05b52009-07-01 23:57:581146 // First two jobs are async.
[email protected]0b7648c2009-07-06 20:14:011147 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2ab05b52009-07-01 23:57:581148
1149 // Start job 1 (async error).
[email protected]a512f5982009-08-18 16:01:061150 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241151 int rv = InitHandle(req1.handle(), "a", kDefaultPriority, &req1,
1152 pool_.get(), NULL);
[email protected]2ab05b52009-07-01 23:57:581153 EXPECT_EQ(ERR_IO_PENDING, rv);
1154
1155 // Start job 2 (async error).
[email protected]a512f5982009-08-18 16:01:061156 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241157 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
1158 pool_.get(), NULL);
[email protected]2ab05b52009-07-01 23:57:581159 EXPECT_EQ(ERR_IO_PENDING, rv);
1160
1161 // The pending job is sync.
[email protected]0b7648c2009-07-06 20:14:011162 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]2ab05b52009-07-01 23:57:581163
1164 // Request 3 does not have a ConnectJob yet. It's just pending.
[email protected]a512f5982009-08-18 16:01:061165 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241166 rv = InitHandle(
1167 req3.handle(), "a", kDefaultPriority, &req3, pool_.get(), NULL);
[email protected]2ab05b52009-07-01 23:57:581168 EXPECT_EQ(ERR_IO_PENDING, rv);
1169
1170 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1171 EXPECT_EQ(ERR_CONNECTION_FAILED, req2.WaitForResult());
1172 EXPECT_EQ(OK, req3.WaitForResult());
1173
1174 ASSERT_EQ(3U, request_order_.size());
1175
1176 // After job 1 finishes unsuccessfully, it will try to process the pending
1177 // requests queue, so it starts up job 3 for request 3. This job
1178 // synchronously succeeds, so the request order is 1, 3, 2.
1179 EXPECT_EQ(&req1, request_order_[0]);
1180 EXPECT_EQ(&req2, request_order_[2]);
1181 EXPECT_EQ(&req3, request_order_[1]);
1182}
1183
[email protected]5fc08e32009-07-15 17:09:571184// When a ConnectJob is coupled to a request, even if a free socket becomes
1185// available, the request will be serviced by the ConnectJob.
1186TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531187 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]d80a4322009-08-14 07:07:491188 EnableLateBindingOfSockets(false);
[email protected]5fc08e32009-07-15 17:09:571189
1190 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321191 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571192
[email protected]a512f5982009-08-18 16:01:061193 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241194 int rv = InitHandle(req1.handle(), "a", kDefaultPriority, &req1,
1195 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571196 EXPECT_EQ(ERR_IO_PENDING, rv);
1197 EXPECT_EQ(OK, req1.WaitForResult());
1198
1199 // Job 1 finished OK. Start job 2 (also async OK). Release socket 1.
1200 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1201
[email protected]a512f5982009-08-18 16:01:061202 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241203 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
1204 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571205 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331206 req1.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571207 MessageLoop::current()->RunAllPending(); // Run the DoReleaseSocket()
1208
1209 // Job 2 is pending. Start request 3 (which has no associated job since it
1210 // will use the idle socket).
1211
[email protected]a512f5982009-08-18 16:01:061212 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241213 rv = InitHandle(req3.handle(), "a", kDefaultPriority, &req3,
1214 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571215 EXPECT_EQ(OK, rv);
1216
[email protected]a6c59f62009-07-29 16:33:331217 EXPECT_FALSE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571218 client_socket_factory_.SignalJobs();
1219 EXPECT_EQ(OK, req2.WaitForResult());
1220
1221 ASSERT_EQ(2U, request_order_.size());
1222 EXPECT_EQ(&req1, request_order_[0]);
1223 EXPECT_EQ(&req2, request_order_[1]);
1224 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1225}
1226
[email protected]2b7523d2009-07-29 20:29:231227// Regression test for http://crbug.com/17985.
1228TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1229 const int kMaxSockets = 3;
1230 const int kMaxSocketsPerGroup = 2;
1231 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1232
[email protected]ac790b42009-12-02 04:31:311233 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231234
1235 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1236 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1237
1238 // This is going to be a pending request in an otherwise empty group.
1239 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1240
1241 // Reach the maximum socket limit.
1242 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1243
1244 // Create a stalled group with high priorities.
1245 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1246 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1247 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
1248
1249 // Release the first two sockets from "a", which will make room
1250 // for requests from "c". After that "a" will have no active sockets
1251 // and one pending request.
1252 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1253 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1254
1255 // Closing idle sockets should not get us into trouble, but in the bug
1256 // we were hitting a CHECK here.
1257 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
1258 pool_->CloseIdleSockets();
1259 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1260}
1261
[email protected]5fc08e32009-07-15 17:09:571262class ClientSocketPoolBaseTest_LateBinding : public ClientSocketPoolBaseTest {
1263 protected:
1264 virtual void SetUp() {
1265 ClientSocketPoolBaseTest::SetUp();
[email protected]d80a4322009-08-14 07:07:491266 EnableLateBindingOfSockets(true);
[email protected]5fc08e32009-07-15 17:09:571267 }
1268};
1269
[email protected]6e713f02009-08-06 02:56:401270// Even though a timeout is specified, it doesn't time out on a synchronous
1271// completion.
1272TEST_F(ClientSocketPoolBaseTest_LateBinding,
1273 ConnectJob_NoTimeoutOnSynchronousCompletion) {
1274 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:061275 ClientSocketHandle ignored;
[email protected]ac790b42009-12-02 04:31:311276 TestClientSocketPoolBase::Request request(&ignored, NULL, LOWEST, NULL,
1277 NULL);
[email protected]6e713f02009-08-06 02:56:401278 scoped_ptr<TestConnectJob> job(
1279 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:121280 "a",
[email protected]6e713f02009-08-06 02:56:401281 request,
1282 base::TimeDelta::FromMicroseconds(1),
1283 &delegate,
[email protected]fd7b7c92009-08-20 19:38:301284 &client_socket_factory_,
1285 NULL));
[email protected]6e713f02009-08-06 02:56:401286 EXPECT_EQ(OK, job->Connect());
1287}
1288
1289TEST_F(ClientSocketPoolBaseTest_LateBinding, ConnectJob_TimedOut) {
1290 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:061291 ClientSocketHandle ignored;
[email protected]ac790b42009-12-02 04:31:311292 TestClientSocketPoolBase::Request request(&ignored, NULL, LOWEST, NULL,
1293 NULL);
[email protected]6e713f02009-08-06 02:56:401294 // Deleted by TestConnectJobDelegate.
1295 TestConnectJob* job =
1296 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:121297 "a",
[email protected]6e713f02009-08-06 02:56:401298 request,
1299 base::TimeDelta::FromMicroseconds(1),
1300 &delegate,
[email protected]fd7b7c92009-08-20 19:38:301301 &client_socket_factory_,
1302 NULL);
[email protected]6e713f02009-08-06 02:56:401303 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
1304 PlatformThread::Sleep(1);
1305 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
1306}
1307
[email protected]5fc08e32009-07-15 17:09:571308TEST_F(ClientSocketPoolBaseTest_LateBinding, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:531309 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571310
1311 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:061312 ClientSocketHandle handle;
[email protected]60c4c412009-11-06 19:59:361313 scoped_refptr<LoadLog> log(new LoadLog(LoadLog::kUnbounded));
[email protected]a937a06d2009-08-19 21:19:241314 EXPECT_EQ(OK, InitHandle(&handle, "a", kDefaultPriority, &callback,
[email protected]fd7b7c92009-08-20 19:38:301315 pool_.get(), log));
[email protected]5fc08e32009-07-15 17:09:571316 EXPECT_TRUE(handle.is_initialized());
1317 EXPECT_TRUE(handle.socket());
1318 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:301319
[email protected]bf6c087a2009-12-21 20:45:101320 EXPECT_EQ(4u, log->entries().size());
[email protected]fd7b7c92009-08-20 19:38:301321 ExpectLogContains(log, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
1322 ExpectLogContains(log, 1, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1323 LoadLog::PHASE_BEGIN);
1324 ExpectLogContains(log, 2, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1325 LoadLog::PHASE_END);
1326 ExpectLogContains(log, 3, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
[email protected]5fc08e32009-07-15 17:09:571327}
1328
1329TEST_F(ClientSocketPoolBaseTest_LateBinding, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531330 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571331
1332 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061333 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]60c4c412009-11-06 19:59:361334 scoped_refptr<LoadLog> log(new LoadLog(LoadLog::kUnbounded));
[email protected]ac790b42009-12-02 04:31:311335 int rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_.get(), log);
[email protected]5fc08e32009-07-15 17:09:571336 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331337 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:571338 EXPECT_EQ(OK, req.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331339 EXPECT_TRUE(req.handle()->is_initialized());
1340 EXPECT_TRUE(req.handle()->socket());
1341 req.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:301342
[email protected]bf6c087a2009-12-21 20:45:101343 EXPECT_EQ(6u, log->entries().size());
[email protected]fd7b7c92009-08-20 19:38:301344 ExpectLogContains(log, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
1345 ExpectLogContains(log, 1, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1346 LoadLog::PHASE_BEGIN);
1347 ExpectLogContains(log, 2, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1348 LoadLog::PHASE_END);
1349 ExpectLogContains(log, 3, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1350 LoadLog::PHASE_BEGIN);
1351 ExpectLogContains(log, 4, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1352 LoadLog::PHASE_END);
1353 ExpectLogContains(log, 5, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
[email protected]5fc08e32009-07-15 17:09:571354}
1355
1356TEST_F(ClientSocketPoolBaseTest_LateBinding, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:531357 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571358
1359 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]a512f5982009-08-18 16:01:061360 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]60c4c412009-11-06 19:59:361361 scoped_refptr<LoadLog> log(new LoadLog(LoadLog::kUnbounded));
[email protected]5fc08e32009-07-15 17:09:571362 EXPECT_EQ(ERR_CONNECTION_FAILED,
[email protected]a937a06d2009-08-19 21:19:241363 InitHandle(req.handle(), "a", kDefaultPriority, &req,
[email protected]fd7b7c92009-08-20 19:38:301364 pool_.get(), log));
1365
[email protected]bf6c087a2009-12-21 20:45:101366 EXPECT_EQ(4u, log->entries().size());
[email protected]fd7b7c92009-08-20 19:38:301367 ExpectLogContains(log, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
1368 ExpectLogContains(log, 1, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1369 LoadLog::PHASE_BEGIN);
1370 ExpectLogContains(log, 2, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1371 LoadLog::PHASE_END);
1372 ExpectLogContains(log, 3, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
[email protected]5fc08e32009-07-15 17:09:571373}
1374
1375TEST_F(ClientSocketPoolBaseTest_LateBinding,
1376 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531377 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571378
1379 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]a512f5982009-08-18 16:01:061380 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]60c4c412009-11-06 19:59:361381 scoped_refptr<LoadLog> log(new LoadLog(LoadLog::kUnbounded));
[email protected]5fc08e32009-07-15 17:09:571382 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:241383 InitHandle(req.handle(), "a", kDefaultPriority, &req,
[email protected]fd7b7c92009-08-20 19:38:301384 pool_.get(), log));
[email protected]a6c59f62009-07-29 16:33:331385 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:571386 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:301387
[email protected]bf6c087a2009-12-21 20:45:101388 EXPECT_EQ(6u, log->entries().size());
[email protected]fd7b7c92009-08-20 19:38:301389 ExpectLogContains(log, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
1390 ExpectLogContains(log, 1, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1391 LoadLog::PHASE_BEGIN);
1392 ExpectLogContains(log, 2, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1393 LoadLog::PHASE_END);
1394 ExpectLogContains(log, 3, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1395 LoadLog::PHASE_BEGIN);
1396 ExpectLogContains(log, 4, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1397 LoadLog::PHASE_END);
1398 ExpectLogContains(log, 5, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
[email protected]5fc08e32009-07-15 17:09:571399}
1400
1401TEST_F(ClientSocketPoolBaseTest_LateBinding, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531402 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571403
1404 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1405 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311406 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1407 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1408 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1409 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1410 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]5fc08e32009-07-15 17:09:571411
1412 ReleaseAllConnections(KEEP_ALIVE);
1413
1414 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1415 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:171416 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571417
1418 EXPECT_EQ(1, GetOrderOfRequest(1));
1419 EXPECT_EQ(2, GetOrderOfRequest(2));
1420 EXPECT_EQ(6, GetOrderOfRequest(3));
1421 EXPECT_EQ(4, GetOrderOfRequest(4));
1422 EXPECT_EQ(3, GetOrderOfRequest(5));
1423 EXPECT_EQ(5, GetOrderOfRequest(6));
1424 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171425
1426 // Make sure we test order of all requests made.
1427 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]5fc08e32009-07-15 17:09:571428}
1429
1430TEST_F(ClientSocketPoolBaseTest_LateBinding, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531431 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571432
1433 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1434 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311435 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1436 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1437 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1438 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1439 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]5fc08e32009-07-15 17:09:571440
1441 ReleaseAllConnections(NO_KEEP_ALIVE);
1442
1443 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i)
1444 EXPECT_EQ(OK, requests_[i]->WaitForResult());
1445
1446 EXPECT_EQ(static_cast<int>(requests_.size()),
1447 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:171448 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571449}
1450
1451// This test will start up a RequestSocket() and then immediately Cancel() it.
1452// The pending connect job will be cancelled and should not call back into
1453// ClientSocketPoolBase.
1454TEST_F(ClientSocketPoolBaseTest_LateBinding, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531455 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571456
1457 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061458 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]5fc08e32009-07-15 17:09:571459 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:241460 InitHandle(req.handle(), "a", kDefaultPriority, &req,
1461 pool_.get(), NULL));
[email protected]a6c59f62009-07-29 16:33:331462 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571463}
1464
1465TEST_F(ClientSocketPoolBaseTest_LateBinding, TwoRequestsCancelOne) {
[email protected]211d21722009-07-22 15:48:531466 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571467
1468 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061469 TestSocketRequest req(&request_order_, &completion_count_);
1470 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]5fc08e32009-07-15 17:09:571471
[email protected]60c4c412009-11-06 19:59:361472 scoped_refptr<LoadLog> log1(new LoadLog(LoadLog::kUnbounded));
[email protected]5fc08e32009-07-15 17:09:571473 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:241474 InitHandle(req.handle(), "a", kDefaultPriority, &req,
[email protected]fd7b7c92009-08-20 19:38:301475 pool_.get(), log1));
[email protected]60c4c412009-11-06 19:59:361476 scoped_refptr<LoadLog> log2(new LoadLog(LoadLog::kUnbounded));
[email protected]5fc08e32009-07-15 17:09:571477 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:241478 InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
[email protected]fd7b7c92009-08-20 19:38:301479 pool_.get(), log2));
[email protected]5fc08e32009-07-15 17:09:571480
[email protected]a6c59f62009-07-29 16:33:331481 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571482
[email protected]bf6c087a2009-12-21 20:45:101483 EXPECT_EQ(5u, log1->entries().size());
[email protected]fd7b7c92009-08-20 19:38:301484 ExpectLogContains(log1, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
1485 ExpectLogContains(log1, 1, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1486 LoadLog::PHASE_BEGIN);
1487 ExpectLogContains(log1, 2, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1488 LoadLog::PHASE_END);
1489 ExpectLogContains(log1, 3, LoadLog::TYPE_CANCELLED, LoadLog::PHASE_NONE);
1490 ExpectLogContains(log1, 4, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
1491
1492 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]bf6c087a2009-12-21 20:45:101493 EXPECT_EQ(2u, log2->entries().size());
[email protected]fd7b7c92009-08-20 19:38:301494 ExpectLogContains(log2, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
1495 ExpectLogContains(log2, 1, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1496 LoadLog::PHASE_BEGIN);
1497
[email protected]5fc08e32009-07-15 17:09:571498 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331499 req2.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:301500
1501 // Now request 2 has actually finished.
[email protected]bf6c087a2009-12-21 20:45:101502 EXPECT_EQ(6u, log2->entries().size());
[email protected]fd7b7c92009-08-20 19:38:301503 ExpectLogContains(log2, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
1504 ExpectLogContains(log2, 1, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1505 LoadLog::PHASE_BEGIN);
1506 ExpectLogContains(log1, 2, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1507 LoadLog::PHASE_END);
1508 ExpectLogContains(log2, 3, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1509 LoadLog::PHASE_BEGIN);
1510 ExpectLogContains(log2, 4, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1511 LoadLog::PHASE_END);
1512 ExpectLogContains(log2, 5, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
1513
[email protected]5fc08e32009-07-15 17:09:571514}
1515
1516TEST_F(ClientSocketPoolBaseTest_LateBinding, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531517 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571518
1519 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061520 ClientSocketHandle handle;
[email protected]5fc08e32009-07-15 17:09:571521 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:061522 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]5fc08e32009-07-15 17:09:571523
1524 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:241525 InitHandle(&handle, "a", kDefaultPriority, &callback,
1526 pool_.get(), NULL));
[email protected]5fc08e32009-07-15 17:09:571527
1528 handle.Reset();
1529
1530 TestCompletionCallback callback2;
1531 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:241532 InitHandle(&handle, "a", kDefaultPriority, &callback2,
1533 pool_.get(), NULL));
[email protected]5fc08e32009-07-15 17:09:571534
1535 EXPECT_EQ(OK, callback2.WaitForResult());
1536 EXPECT_FALSE(callback.have_result());
1537
1538 handle.Reset();
1539}
1540
1541TEST_F(ClientSocketPoolBaseTest_LateBinding, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531542 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571543
1544 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1545 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311546 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1547 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1548 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1549 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1550 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]5fc08e32009-07-15 17:09:571551
1552 // Cancel a request.
1553 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]a6c59f62009-07-29 16:33:331554 EXPECT_FALSE(requests_[index_to_cancel]->handle()->is_initialized());
1555 requests_[index_to_cancel]->handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571556
1557 ReleaseAllConnections(KEEP_ALIVE);
1558
1559 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1560 client_socket_factory_.allocation_count());
1561 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup - 1,
[email protected]75439d3b2009-07-23 22:11:171562 completion_count_);
[email protected]5fc08e32009-07-15 17:09:571563
1564 EXPECT_EQ(1, GetOrderOfRequest(1));
1565 EXPECT_EQ(2, GetOrderOfRequest(2));
1566 EXPECT_EQ(5, GetOrderOfRequest(3));
1567 EXPECT_EQ(3, GetOrderOfRequest(4));
1568 EXPECT_EQ(kRequestNotFound, GetOrderOfRequest(5)); // Canceled request.
1569 EXPECT_EQ(4, GetOrderOfRequest(6));
1570 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171571
1572 // Make sure we test order of all requests made.
1573 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]5fc08e32009-07-15 17:09:571574}
1575
[email protected]974ebd62009-08-03 23:14:341576TEST_F(ClientSocketPoolBaseTest_LateBinding, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341577 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1578
[email protected]17a0c6c2009-08-04 00:07:041579 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1580
[email protected]ac790b42009-12-02 04:31:311581 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1582 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1583 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1584 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341585
1586 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1587 requests_[2]->handle()->Reset();
1588 requests_[3]->handle()->Reset();
1589 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1590
1591 requests_[1]->handle()->Reset();
1592 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1593
1594 requests_[0]->handle()->Reset();
1595 EXPECT_EQ(kDefaultMaxSocketsPerGroup - 1, pool_->NumConnectJobsInGroup("a"));
1596}
1597
[email protected]5fc08e32009-07-15 17:09:571598TEST_F(ClientSocketPoolBaseTest_LateBinding, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531599 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571600
1601 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061602 ClientSocketHandle handle;
[email protected]5fc08e32009-07-15 17:09:571603 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061604 &handle, pool_.get(), connect_job_factory_,
1605 TestConnectJob::kMockPendingJob);
[email protected]a937a06d2009-08-19 21:19:241606 int rv = InitHandle(
1607 &handle, "a", kDefaultPriority, &callback, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571608 ASSERT_EQ(ERR_IO_PENDING, rv);
1609
1610 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]5fc08e32009-07-15 17:09:571611}
1612
1613TEST_F(ClientSocketPoolBaseTest_LateBinding, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531614 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571615
1616 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061617 ClientSocketHandle handle;
[email protected]5fc08e32009-07-15 17:09:571618 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061619 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]a937a06d2009-08-19 21:19:241620 int rv = InitHandle(
1621 &handle, "a", kDefaultPriority, &callback,
[email protected]a512f5982009-08-18 16:01:061622 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571623 ASSERT_EQ(ERR_IO_PENDING, rv);
1624
1625 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]5fc08e32009-07-15 17:09:571626}
1627
1628// Make sure that pending requests get serviced after active requests get
1629// cancelled.
1630TEST_F(ClientSocketPoolBaseTest_LateBinding,
1631 CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531632 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571633
1634 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1635
1636 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1637 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1638 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1639 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1640 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1641 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1642 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1643
1644 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1645 // Let's cancel them.
1646 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]a6c59f62009-07-29 16:33:331647 ASSERT_FALSE(requests_[i]->handle()->is_initialized());
1648 requests_[i]->handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571649 }
1650
1651 // Let's wait for the rest to complete now.
1652 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i) {
1653 EXPECT_EQ(OK, requests_[i]->WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331654 requests_[i]->handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571655 }
1656
[email protected]75439d3b2009-07-23 22:11:171657 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571658}
1659
1660// Make sure that pending requests get serviced after active requests fail.
1661TEST_F(ClientSocketPoolBaseTest_LateBinding,
1662 FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531663 const int kMaxSockets = 5;
1664 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571665
1666 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1667
[email protected]211d21722009-07-22 15:48:531668 const int kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1669 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test hangs.
[email protected]5fc08e32009-07-15 17:09:571670
1671 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531672 for (int i = 0; i < kNumberOfRequests; ++i)
1673 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]5fc08e32009-07-15 17:09:571674
[email protected]211d21722009-07-22 15:48:531675 for (int i = 0; i < kNumberOfRequests; ++i)
1676 EXPECT_EQ(ERR_CONNECTION_FAILED, requests_[i]->WaitForResult());
[email protected]5fc08e32009-07-15 17:09:571677}
1678
1679TEST_F(ClientSocketPoolBaseTest_LateBinding,
1680 CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531681 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571682
1683 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1684
[email protected]a512f5982009-08-18 16:01:061685 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241686 int rv = InitHandle(req.handle(), "a", kDefaultPriority, &req,
1687 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571688 EXPECT_EQ(ERR_IO_PENDING, rv);
1689
1690 // Cancel the active request.
[email protected]a6c59f62009-07-29 16:33:331691 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571692
[email protected]a937a06d2009-08-19 21:19:241693 rv = InitHandle(req.handle(), "a", kDefaultPriority, &req,
1694 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571695 EXPECT_EQ(ERR_IO_PENDING, rv);
1696 EXPECT_EQ(OK, req.WaitForResult());
1697
[email protected]a6c59f62009-07-29 16:33:331698 EXPECT_FALSE(req.handle()->is_reused());
[email protected]75439d3b2009-07-23 22:11:171699 EXPECT_EQ(1U, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571700 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1701}
1702
1703// When requests and ConnectJobs are not coupled, the request will get serviced
1704// by whatever comes first.
1705TEST_F(ClientSocketPoolBaseTest_LateBinding, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531706 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571707
1708 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321709 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571710
[email protected]a512f5982009-08-18 16:01:061711 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241712 int rv = InitHandle(req1.handle(), "a", kDefaultPriority,
1713 &req1, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571714 EXPECT_EQ(ERR_IO_PENDING, rv);
1715 EXPECT_EQ(OK, req1.WaitForResult());
1716
1717 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1718 // without a job.
1719 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1720
[email protected]a512f5982009-08-18 16:01:061721 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241722 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
1723 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571724 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a512f5982009-08-18 16:01:061725 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241726 rv = InitHandle(
1727 req3.handle(), "a", kDefaultPriority, &req3, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571728 EXPECT_EQ(ERR_IO_PENDING, rv);
1729
1730 // Both Requests 2 and 3 are pending. We release socket 1 which should
1731 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331732 req1.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571733 MessageLoop::current()->RunAllPending(); // Run the DoReleaseSocket()
[email protected]a6c59f62009-07-29 16:33:331734 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571735 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331736 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571737
1738 // Signal job 2, which should service request 3.
1739
1740 client_socket_factory_.SignalJobs();
1741 EXPECT_EQ(OK, req3.WaitForResult());
1742
1743 ASSERT_EQ(3U, request_order_.size());
1744 EXPECT_EQ(&req1, request_order_[0]);
1745 EXPECT_EQ(&req2, request_order_[1]);
1746 EXPECT_EQ(&req3, request_order_[2]);
1747 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1748}
1749
1750// The requests are not coupled to the jobs. So, the requests should finish in
1751// their priority / insertion order.
1752TEST_F(ClientSocketPoolBaseTest_LateBinding, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531753 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571754 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321755 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571756
[email protected]a512f5982009-08-18 16:01:061757 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241758 int rv = InitHandle(
1759 req1.handle(), "a", kDefaultPriority, &req1, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571760 EXPECT_EQ(ERR_IO_PENDING, rv);
1761
[email protected]a512f5982009-08-18 16:01:061762 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241763 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
1764 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571765 EXPECT_EQ(ERR_IO_PENDING, rv);
1766
1767 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321768 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571769
[email protected]a512f5982009-08-18 16:01:061770 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241771 rv = InitHandle(
1772 req3.handle(), "a", kDefaultPriority, &req3, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571773 EXPECT_EQ(ERR_IO_PENDING, rv);
1774
1775 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1776 EXPECT_EQ(OK, req2.WaitForResult());
1777 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1778
1779 ASSERT_EQ(3U, request_order_.size());
1780 EXPECT_EQ(&req1, request_order_[0]);
1781 EXPECT_EQ(&req2, request_order_[1]);
1782 EXPECT_EQ(&req3, request_order_[2]);
1783}
1784
[email protected]f0109a7d2009-07-16 00:09:521785TEST_F(ClientSocketPoolBaseTest_LateBinding, DISABLED_LoadState) {
[email protected]211d21722009-07-22 15:48:531786 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571787 connect_job_factory_->set_job_type(
[email protected]b59ff372009-07-15 22:04:321788 TestConnectJob::kMockAdvancingLoadStateJob);
[email protected]5fc08e32009-07-15 17:09:571789
[email protected]a512f5982009-08-18 16:01:061790 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241791 int rv = InitHandle(
1792 req1.handle(), "a", kDefaultPriority, &req1, 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_IDLE, req1.handle()->GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571795
1796 MessageLoop::current()->RunAllPending();
1797
[email protected]a512f5982009-08-18 16:01:061798 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241799 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
1800 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571801 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331802 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, req1.handle()->GetLoadState());
1803 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, req2.handle()->GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571804}
1805
[email protected]2b7523d2009-07-29 20:29:231806// Regression test for http://crbug.com/17985.
1807TEST_F(ClientSocketPoolBaseTest_LateBinding,
1808 GroupWithPendingRequestsIsNotEmpty) {
1809 const int kMaxSockets = 3;
1810 const int kMaxSocketsPerGroup = 2;
1811 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1812
[email protected]ac790b42009-12-02 04:31:311813 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231814
1815 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1816 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1817
1818 // This is going to be a pending request in an otherwise empty group.
1819 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1820
1821 // Reach the maximum socket limit.
1822 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1823
1824 // Create a stalled group with high priorities.
1825 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1826 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1827 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
1828
1829 // Release the first two sockets from "a", which will make room
1830 // for requests from "c". After that "a" will have no active sockets
1831 // and one pending request.
1832 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1833 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1834
1835 // Closing idle sockets should not get us into trouble, but in the bug
1836 // we were hitting a CHECK here.
1837 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
1838 pool_->CloseIdleSockets();
1839 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1840}
1841
[email protected]9bf28db2009-08-29 01:35:161842TEST_F(ClientSocketPoolBaseTest_LateBinding, CleanupTimedOutIdleSockets) {
1843 CreatePoolWithIdleTimeouts(
1844 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1845 base::TimeDelta(), // Time out unused sockets immediately.
1846 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1847
1848 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1849
1850 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
1851
1852 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]ac790b42009-12-02 04:31:311853 int rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_.get(), NULL);
[email protected]9bf28db2009-08-29 01:35:161854 EXPECT_EQ(ERR_IO_PENDING, rv);
1855 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
1856
1857 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]ac790b42009-12-02 04:31:311858 rv = InitHandle(req2.handle(), "a", LOWEST, &req2, pool_.get(), NULL);
[email protected]9bf28db2009-08-29 01:35:161859 EXPECT_EQ(ERR_IO_PENDING, rv);
1860 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req2.handle()));
1861
1862 // Cancel one of the requests. Wait for the other, which will get the first
1863 // job. Release the socket. Run the loop again to make sure the second
1864 // socket is sitting idle and the first one is released (since ReleaseSocket()
1865 // just posts a DoReleaseSocket() task).
1866
1867 req.handle()->Reset();
1868 EXPECT_EQ(OK, req2.WaitForResult());
1869 req2.handle()->Reset();
[email protected]6b175382009-10-13 06:47:471870
1871 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1872 // actually become pending until 2ms after they have been created. In order
1873 // to flush all tasks, we need to wait so that we know there are no
1874 // soon-to-be-pending tasks waiting.
1875 PlatformThread::Sleep(10);
[email protected]9bf28db2009-08-29 01:35:161876 MessageLoop::current()->RunAllPending();
1877
1878 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:041879
[email protected]9bf28db2009-08-29 01:35:161880 // Invoke the idle socket cleanup check. Only one socket should be left, the
1881 // used socket. Request it to make sure that it's used.
1882
1883 pool_->CleanupTimedOutIdleSockets();
[email protected]ac790b42009-12-02 04:31:311884 rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_.get(), NULL);
[email protected]9bf28db2009-08-29 01:35:161885 EXPECT_EQ(OK, rv);
1886 EXPECT_TRUE(req.handle()->is_reused());
1887}
1888
[email protected]f6d1d6eb2009-06-24 20:16:091889} // namespace
1890
1891} // namespace net