1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/socket/client_socket_pool_base.h"
6
7 #include "base/callback.h"
8 #include "base/compiler_specific.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/memory/scoped_vector.h"
11 #include "base/message_loop.h"
12 #include "base/string_number_conversions.h"
13 #include "base/string_util.h"
14 #include "base/threading/platform_thread.h"
15 #include "net/base/net_errors.h"
16 #include "net/base/net_log.h"
17 #include "net/base/net_log_unittest.h"
18 #include "net/base/request_priority.h"
19 #include "net/base/test_completion_callback.h"
20 #include "net/http/http_response_headers.h"
21 #include "net/socket/client_socket.h"
22 #include "net/socket/client_socket_factory.h"
23 #include "net/socket/client_socket_handle.h"
24 #include "net/socket/client_socket_pool_histograms.h"
25 #include "net/socket/socket_test_util.h"
26 #include "net/socket/ssl_host_info.h"
27 #include "testing/gtest/include/gtest/gtest.h"
28
29 namespace net {
30
31 namespace {
32
33 const int kDefaultMaxSockets = 4;
34 const int kDefaultMaxSocketsPerGroup = 2;
35 const net::RequestPriority kDefaultPriority = MEDIUM;
36
37 class TestSocketParams : public base::RefCounted<TestSocketParams> {
38 public:
ignore_limits()39 bool ignore_limits() { return false; }
40 private:
41 friend class base::RefCounted<TestSocketParams>;
~TestSocketParams()42 ~TestSocketParams() {}
43 };
44 typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
45
46 class MockClientSocket : public ClientSocket {
47 public:
MockClientSocket()48 MockClientSocket() : connected_(false), was_used_to_convey_data_(false) {}
49
50 // Socket methods:
Read(IOBuffer *,int,CompletionCallback *)51 virtual int Read(
52 IOBuffer* /* buf */, int /* len */, CompletionCallback* /* callback */) {
53 return ERR_UNEXPECTED;
54 }
55
Write(IOBuffer *,int len,CompletionCallback *)56 virtual int Write(
57 IOBuffer* /* buf */, int len, CompletionCallback* /* callback */) {
58 was_used_to_convey_data_ = true;
59 return len;
60 }
SetReceiveBufferSize(int32 size)61 virtual bool SetReceiveBufferSize(int32 size) { return true; }
SetSendBufferSize(int32 size)62 virtual bool SetSendBufferSize(int32 size) { return true; }
63
64 // ClientSocket methods:
65
Connect(CompletionCallback * callback)66 virtual int Connect(CompletionCallback* callback) {
67 connected_ = true;
68 return OK;
69 }
70
Disconnect()71 virtual void Disconnect() { connected_ = false; }
IsConnected() const72 virtual bool IsConnected() const { return connected_; }
IsConnectedAndIdle() const73 virtual bool IsConnectedAndIdle() const { return connected_; }
74
GetPeerAddress(AddressList *) const75 virtual int GetPeerAddress(AddressList* /* address */) const {
76 return ERR_UNEXPECTED;
77 }
78
GetLocalAddress(IPEndPoint *) const79 virtual int GetLocalAddress(IPEndPoint* /* address */) const {
80 return ERR_UNEXPECTED;
81 }
82
NetLog() const83 virtual const BoundNetLog& NetLog() const {
84 return net_log_;
85 }
86
SetSubresourceSpeculation()87 virtual void SetSubresourceSpeculation() {}
SetOmniboxSpeculation()88 virtual void SetOmniboxSpeculation() {}
WasEverUsed() const89 virtual bool WasEverUsed() const { return was_used_to_convey_data_; }
UsingTCPFastOpen() const90 virtual bool UsingTCPFastOpen() const { return false; }
91
92 private:
93 bool connected_;
94 BoundNetLog net_log_;
95 bool was_used_to_convey_data_;
96
97 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
98 };
99
100 class TestConnectJob;
101
102 class MockClientSocketFactory : public ClientSocketFactory {
103 public:
MockClientSocketFactory()104 MockClientSocketFactory() : allocation_count_(0) {}
105
CreateTransportClientSocket(const AddressList & addresses,NetLog *,const NetLog::Source &)106 virtual ClientSocket* CreateTransportClientSocket(
107 const AddressList& addresses,
108 NetLog* /* net_log */,
109 const NetLog::Source& /*source*/) {
110 allocation_count_++;
111 return NULL;
112 }
113
CreateSSLClientSocket(ClientSocketHandle * transport_socket,const HostPortPair & host_and_port,const SSLConfig & ssl_config,SSLHostInfo * ssl_host_info,CertVerifier * cert_verifier,DnsCertProvenanceChecker * dns_cert_checker)114 virtual SSLClientSocket* CreateSSLClientSocket(
115 ClientSocketHandle* transport_socket,
116 const HostPortPair& host_and_port,
117 const SSLConfig& ssl_config,
118 SSLHostInfo* ssl_host_info,
119 CertVerifier* cert_verifier,
120 DnsCertProvenanceChecker* dns_cert_checker) {
121 NOTIMPLEMENTED();
122 delete ssl_host_info;
123 return NULL;
124 }
125
ClearSSLSessionCache()126 virtual void ClearSSLSessionCache() {
127 NOTIMPLEMENTED();
128 }
129
WaitForSignal(TestConnectJob * job)130 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
131 void SignalJobs();
132
allocation_count() const133 int allocation_count() const { return allocation_count_; }
134
135 private:
136 int allocation_count_;
137 std::vector<TestConnectJob*> waiting_jobs_;
138 };
139
140 class TestConnectJob : public ConnectJob {
141 public:
142 enum JobType {
143 kMockJob,
144 kMockFailingJob,
145 kMockPendingJob,
146 kMockPendingFailingJob,
147 kMockWaitingJob,
148 kMockAdvancingLoadStateJob,
149 kMockRecoverableJob,
150 kMockPendingRecoverableJob,
151 kMockAdditionalErrorStateJob,
152 kMockPendingAdditionalErrorStateJob,
153 };
154
155 // The kMockPendingJob uses a slight delay before allowing the connect
156 // to complete.
157 static const int kPendingConnectDelay = 2;
158
TestConnectJob(JobType job_type,const std::string & group_name,const TestClientSocketPoolBase::Request & request,base::TimeDelta timeout_duration,ConnectJob::Delegate * delegate,MockClientSocketFactory * client_socket_factory,NetLog * net_log)159 TestConnectJob(JobType job_type,
160 const std::string& group_name,
161 const TestClientSocketPoolBase::Request& request,
162 base::TimeDelta timeout_duration,
163 ConnectJob::Delegate* delegate,
164 MockClientSocketFactory* client_socket_factory,
165 NetLog* net_log)
166 : ConnectJob(group_name, timeout_duration, delegate,
167 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
168 job_type_(job_type),
169 client_socket_factory_(client_socket_factory),
170 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
171 load_state_(LOAD_STATE_IDLE),
172 store_additional_error_state_(false) {}
173
Signal()174 void Signal() {
175 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
176 }
177
GetLoadState() const178 virtual LoadState GetLoadState() const { return load_state_; }
179
GetAdditionalErrorState(ClientSocketHandle * handle)180 virtual void GetAdditionalErrorState(ClientSocketHandle* handle) {
181 if (store_additional_error_state_) {
182 // Set all of the additional error state fields in some way.
183 handle->set_is_ssl_error(true);
184 HttpResponseInfo info;
185 info.headers = new HttpResponseHeaders("");
186 handle->set_ssl_error_response_info(info);
187 }
188 }
189
190 private:
191 // ConnectJob methods:
192
ConnectInternal()193 virtual int ConnectInternal() {
194 AddressList ignored;
195 client_socket_factory_->CreateTransportClientSocket(
196 ignored, NULL, net::NetLog::Source());
197 set_socket(new MockClientSocket());
198 switch (job_type_) {
199 case kMockJob:
200 return DoConnect(true /* successful */, false /* sync */,
201 false /* recoverable */);
202 case kMockFailingJob:
203 return DoConnect(false /* error */, false /* sync */,
204 false /* recoverable */);
205 case kMockPendingJob:
206 set_load_state(LOAD_STATE_CONNECTING);
207
208 // Depending on execution timings, posting a delayed task can result
209 // in the task getting executed the at the earliest possible
210 // opportunity or only after returning once from the message loop and
211 // then a second call into the message loop. In order to make behavior
212 // more deterministic, we change the default delay to 2ms. This should
213 // always require us to wait for the second call into the message loop.
214 //
215 // N.B. The correct fix for this and similar timing problems is to
216 // abstract time for the purpose of unittests. Unfortunately, we have
217 // a lot of third-party components that directly call the various
218 // time functions, so this change would be rather invasive.
219 MessageLoop::current()->PostDelayedTask(
220 FROM_HERE,
221 method_factory_.NewRunnableMethod(
222 &TestConnectJob::DoConnect,
223 true /* successful */,
224 true /* async */,
225 false /* recoverable */),
226 kPendingConnectDelay);
227 return ERR_IO_PENDING;
228 case kMockPendingFailingJob:
229 set_load_state(LOAD_STATE_CONNECTING);
230 MessageLoop::current()->PostDelayedTask(
231 FROM_HERE,
232 method_factory_.NewRunnableMethod(
233 &TestConnectJob::DoConnect,
234 false /* error */,
235 true /* async */,
236 false /* recoverable */),
237 2);
238 return ERR_IO_PENDING;
239 case kMockWaitingJob:
240 client_socket_factory_->WaitForSignal(this);
241 waiting_success_ = true;
242 return ERR_IO_PENDING;
243 case kMockAdvancingLoadStateJob:
244 MessageLoop::current()->PostTask(
245 FROM_HERE,
246 method_factory_.NewRunnableMethod(
247 &TestConnectJob::AdvanceLoadState, load_state_));
248 return ERR_IO_PENDING;
249 case kMockRecoverableJob:
250 return DoConnect(false /* error */, false /* sync */,
251 true /* recoverable */);
252 case kMockPendingRecoverableJob:
253 set_load_state(LOAD_STATE_CONNECTING);
254 MessageLoop::current()->PostDelayedTask(
255 FROM_HERE,
256 method_factory_.NewRunnableMethod(
257 &TestConnectJob::DoConnect,
258 false /* error */,
259 true /* async */,
260 true /* recoverable */),
261 2);
262 return ERR_IO_PENDING;
263 case kMockAdditionalErrorStateJob:
264 store_additional_error_state_ = true;
265 return DoConnect(false /* error */, false /* sync */,
266 false /* recoverable */);
267 case kMockPendingAdditionalErrorStateJob:
268 set_load_state(LOAD_STATE_CONNECTING);
269 store_additional_error_state_ = true;
270 MessageLoop::current()->PostDelayedTask(
271 FROM_HERE,
272 method_factory_.NewRunnableMethod(
273 &TestConnectJob::DoConnect,
274 false /* error */,
275 true /* async */,
276 false /* recoverable */),
277 2);
278 return ERR_IO_PENDING;
279 default:
280 NOTREACHED();
281 set_socket(NULL);
282 return ERR_FAILED;
283 }
284 }
285
set_load_state(LoadState load_state)286 void set_load_state(LoadState load_state) { load_state_ = load_state; }
287
DoConnect(bool succeed,bool was_async,bool recoverable)288 int DoConnect(bool succeed, bool was_async, bool recoverable) {
289 int result = OK;
290 if (succeed) {
291 socket()->Connect(NULL);
292 } else if (recoverable) {
293 result = ERR_PROXY_AUTH_REQUESTED;
294 } else {
295 result = ERR_CONNECTION_FAILED;
296 set_socket(NULL);
297 }
298
299 if (was_async)
300 NotifyDelegateOfCompletion(result);
301 return result;
302 }
303
304 // This function helps simulate the progress of load states on a ConnectJob.
305 // Each time it is called it advances the load state and posts a task to be
306 // called again. It stops at the last connecting load state (the one
307 // before LOAD_STATE_SENDING_REQUEST).
AdvanceLoadState(LoadState state)308 void AdvanceLoadState(LoadState state) {
309 int tmp = state;
310 tmp++;
311 if (tmp < LOAD_STATE_SENDING_REQUEST) {
312 state = static_cast<LoadState>(tmp);
313 set_load_state(state);
314 MessageLoop::current()->PostTask(
315 FROM_HERE,
316 method_factory_.NewRunnableMethod(&TestConnectJob::AdvanceLoadState,
317 state));
318 }
319 }
320
321 bool waiting_success_;
322 const JobType job_type_;
323 MockClientSocketFactory* const client_socket_factory_;
324 ScopedRunnableMethodFactory<TestConnectJob> method_factory_;
325 LoadState load_state_;
326 bool store_additional_error_state_;
327
328 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
329 };
330
331 class TestConnectJobFactory
332 : public TestClientSocketPoolBase::ConnectJobFactory {
333 public:
TestConnectJobFactory(MockClientSocketFactory * client_socket_factory)334 explicit TestConnectJobFactory(MockClientSocketFactory* client_socket_factory)
335 : job_type_(TestConnectJob::kMockJob),
336 client_socket_factory_(client_socket_factory) {}
337
~TestConnectJobFactory()338 virtual ~TestConnectJobFactory() {}
339
set_job_type(TestConnectJob::JobType job_type)340 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
341
set_timeout_duration(base::TimeDelta timeout_duration)342 void set_timeout_duration(base::TimeDelta timeout_duration) {
343 timeout_duration_ = timeout_duration;
344 }
345
346 // ConnectJobFactory methods:
347
NewConnectJob(const std::string & group_name,const TestClientSocketPoolBase::Request & request,ConnectJob::Delegate * delegate) const348 virtual ConnectJob* NewConnectJob(
349 const std::string& group_name,
350 const TestClientSocketPoolBase::Request& request,
351 ConnectJob::Delegate* delegate) const {
352 return new TestConnectJob(job_type_,
353 group_name,
354 request,
355 timeout_duration_,
356 delegate,
357 client_socket_factory_,
358 NULL);
359 }
360
ConnectionTimeout() const361 virtual base::TimeDelta ConnectionTimeout() const {
362 return timeout_duration_;
363 }
364
365 private:
366 TestConnectJob::JobType job_type_;
367 base::TimeDelta timeout_duration_;
368 MockClientSocketFactory* const client_socket_factory_;
369
370 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
371 };
372
373 class TestClientSocketPool : public ClientSocketPool {
374 public:
TestClientSocketPool(int max_sockets,int max_sockets_per_group,ClientSocketPoolHistograms * histograms,base::TimeDelta unused_idle_socket_timeout,base::TimeDelta used_idle_socket_timeout,TestClientSocketPoolBase::ConnectJobFactory * connect_job_factory)375 TestClientSocketPool(
376 int max_sockets,
377 int max_sockets_per_group,
378 ClientSocketPoolHistograms* histograms,
379 base::TimeDelta unused_idle_socket_timeout,
380 base::TimeDelta used_idle_socket_timeout,
381 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
382 : base_(max_sockets, max_sockets_per_group, histograms,
383 unused_idle_socket_timeout, used_idle_socket_timeout,
384 connect_job_factory) {}
385
~TestClientSocketPool()386 virtual ~TestClientSocketPool() {}
387
RequestSocket(const std::string & group_name,const void * params,net::RequestPriority priority,ClientSocketHandle * handle,CompletionCallback * callback,const BoundNetLog & net_log)388 virtual int RequestSocket(
389 const std::string& group_name,
390 const void* params,
391 net::RequestPriority priority,
392 ClientSocketHandle* handle,
393 CompletionCallback* callback,
394 const BoundNetLog& net_log) {
395 const scoped_refptr<TestSocketParams>* casted_socket_params =
396 static_cast<const scoped_refptr<TestSocketParams>*>(params);
397 return base_.RequestSocket(group_name, *casted_socket_params, priority,
398 handle, callback, net_log);
399 }
400
RequestSockets(const std::string & group_name,const void * params,int num_sockets,const BoundNetLog & net_log)401 virtual void RequestSockets(const std::string& group_name,
402 const void* params,
403 int num_sockets,
404 const BoundNetLog& net_log) {
405 const scoped_refptr<TestSocketParams>* casted_params =
406 static_cast<const scoped_refptr<TestSocketParams>*>(params);
407
408 base_.RequestSockets(group_name, *casted_params, num_sockets, net_log);
409 }
410
CancelRequest(const std::string & group_name,ClientSocketHandle * handle)411 virtual void CancelRequest(
412 const std::string& group_name,
413 ClientSocketHandle* handle) {
414 base_.CancelRequest(group_name, handle);
415 }
416
ReleaseSocket(const std::string & group_name,ClientSocket * socket,int id)417 virtual void ReleaseSocket(
418 const std::string& group_name,
419 ClientSocket* socket,
420 int id) {
421 base_.ReleaseSocket(group_name, socket, id);
422 }
423
Flush()424 virtual void Flush() {
425 base_.Flush();
426 }
427
CloseIdleSockets()428 virtual void CloseIdleSockets() {
429 base_.CloseIdleSockets();
430 }
431
IdleSocketCount() const432 virtual int IdleSocketCount() const { return base_.idle_socket_count(); }
433
IdleSocketCountInGroup(const std::string & group_name) const434 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
435 return base_.IdleSocketCountInGroup(group_name);
436 }
437
GetLoadState(const std::string & group_name,const ClientSocketHandle * handle) const438 virtual LoadState GetLoadState(const std::string& group_name,
439 const ClientSocketHandle* handle) const {
440 return base_.GetLoadState(group_name, handle);
441 }
442
GetInfoAsValue(const std::string & name,const std::string & type,bool include_nested_pools) const443 virtual DictionaryValue* GetInfoAsValue(const std::string& name,
444 const std::string& type,
445 bool include_nested_pools) const {
446 return base_.GetInfoAsValue(name, type);
447 }
448
ConnectionTimeout() const449 virtual base::TimeDelta ConnectionTimeout() const {
450 return base_.ConnectionTimeout();
451 }
452
histograms() const453 virtual ClientSocketPoolHistograms* histograms() const {
454 return base_.histograms();
455 }
456
base() const457 const TestClientSocketPoolBase* base() const { return &base_; }
458
NumConnectJobsInGroup(const std::string & group_name) const459 int NumConnectJobsInGroup(const std::string& group_name) const {
460 return base_.NumConnectJobsInGroup(group_name);
461 }
462
NumActiveSocketsInGroup(const std::string & group_name) const463 int NumActiveSocketsInGroup(const std::string& group_name) const {
464 return base_.NumActiveSocketsInGroup(group_name);
465 }
466
HasGroup(const std::string & group_name) const467 bool HasGroup(const std::string& group_name) const {
468 return base_.HasGroup(group_name);
469 }
470
CleanupTimedOutIdleSockets()471 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
472
EnableConnectBackupJobs()473 void EnableConnectBackupJobs() { base_.EnableConnectBackupJobs(); }
474
475 private:
476 TestClientSocketPoolBase base_;
477
478 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
479 };
480
481 } // namespace
482
483 REGISTER_SOCKET_PARAMS_FOR_POOL(TestClientSocketPool, TestSocketParams);
484
485 namespace {
486
SignalJobs()487 void MockClientSocketFactory::SignalJobs() {
488 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
489 it != waiting_jobs_.end(); ++it) {
490 (*it)->Signal();
491 }
492 waiting_jobs_.clear();
493 }
494
495 class TestConnectJobDelegate : public ConnectJob::Delegate {
496 public:
TestConnectJobDelegate()497 TestConnectJobDelegate()
498 : have_result_(false), waiting_for_result_(false), result_(OK) {}
~TestConnectJobDelegate()499 virtual ~TestConnectJobDelegate() {}
500
OnConnectJobComplete(int result,ConnectJob * job)501 virtual void OnConnectJobComplete(int result, ConnectJob* job) {
502 result_ = result;
503 scoped_ptr<ClientSocket> socket(job->ReleaseSocket());
504 // socket.get() should be NULL iff result != OK
505 EXPECT_EQ(socket.get() == NULL, result != OK);
506 delete job;
507 have_result_ = true;
508 if (waiting_for_result_)
509 MessageLoop::current()->Quit();
510 }
511
WaitForResult()512 int WaitForResult() {
513 DCHECK(!waiting_for_result_);
514 while (!have_result_) {
515 waiting_for_result_ = true;
516 MessageLoop::current()->Run();
517 waiting_for_result_ = false;
518 }
519 have_result_ = false; // auto-reset for next callback
520 return result_;
521 }
522
523 private:
524 bool have_result_;
525 bool waiting_for_result_;
526 int result_;
527 };
528
529 class ClientSocketPoolBaseTest : public testing::Test {
530 protected:
ClientSocketPoolBaseTest()531 ClientSocketPoolBaseTest()
532 : params_(new TestSocketParams()),
533 histograms_("ClientSocketPoolTest") {
534 connect_backup_jobs_enabled_ =
535 internal::ClientSocketPoolBaseHelper::connect_backup_jobs_enabled();
536 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(true);
537 cleanup_timer_enabled_ =
538 internal::ClientSocketPoolBaseHelper::cleanup_timer_enabled();
539 }
540
~ClientSocketPoolBaseTest()541 virtual ~ClientSocketPoolBaseTest() {
542 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
543 connect_backup_jobs_enabled_);
544 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(
545 cleanup_timer_enabled_);
546 }
547
CreatePool(int max_sockets,int max_sockets_per_group)548 void CreatePool(int max_sockets, int max_sockets_per_group) {
549 CreatePoolWithIdleTimeouts(
550 max_sockets,
551 max_sockets_per_group,
552 base::TimeDelta::FromSeconds(
553 ClientSocketPool::unused_idle_socket_timeout()),
554 base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout));
555 }
556
CreatePoolWithIdleTimeouts(int max_sockets,int max_sockets_per_group,base::TimeDelta unused_idle_socket_timeout,base::TimeDelta used_idle_socket_timeout)557 void CreatePoolWithIdleTimeouts(
558 int max_sockets, int max_sockets_per_group,
559 base::TimeDelta unused_idle_socket_timeout,
560 base::TimeDelta used_idle_socket_timeout) {
561 DCHECK(!pool_.get());
562 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_);
563 pool_.reset(new TestClientSocketPool(max_sockets,
564 max_sockets_per_group,
565 &histograms_,
566 unused_idle_socket_timeout,
567 used_idle_socket_timeout,
568 connect_job_factory_));
569 }
570
StartRequest(const std::string & group_name,net::RequestPriority priority)571 int StartRequest(const std::string& group_name,
572 net::RequestPriority priority) {
573 return test_base_.StartRequestUsingPool<
574 TestClientSocketPool, TestSocketParams>(
575 pool_.get(), group_name, priority, params_);
576 }
577
GetOrderOfRequest(size_t index) const578 int GetOrderOfRequest(size_t index) const {
579 return test_base_.GetOrderOfRequest(index);
580 }
581
ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive)582 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
583 return test_base_.ReleaseOneConnection(keep_alive);
584 }
585
ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive)586 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
587 test_base_.ReleaseAllConnections(keep_alive);
588 }
589
request(int i)590 TestSocketRequest* request(int i) { return test_base_.request(i); }
requests_size() const591 size_t requests_size() const { return test_base_.requests_size(); }
requests()592 ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); }
completion_count() const593 size_t completion_count() const { return test_base_.completion_count(); }
594
595 bool connect_backup_jobs_enabled_;
596 bool cleanup_timer_enabled_;
597 MockClientSocketFactory client_socket_factory_;
598 TestConnectJobFactory* connect_job_factory_;
599 scoped_refptr<TestSocketParams> params_;
600 ClientSocketPoolHistograms histograms_;
601 scoped_ptr<TestClientSocketPool> pool_;
602 ClientSocketPoolTest test_base_;
603 };
604
605 // Even though a timeout is specified, it doesn't time out on a synchronous
606 // completion.
TEST_F(ClientSocketPoolBaseTest,ConnectJob_NoTimeoutOnSynchronousCompletion)607 TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
608 TestConnectJobDelegate delegate;
609 ClientSocketHandle ignored;
610 TestClientSocketPoolBase::Request request(
611 &ignored, NULL, kDefaultPriority,
612 internal::ClientSocketPoolBaseHelper::NORMAL,
613 false, params_, BoundNetLog());
614 scoped_ptr<TestConnectJob> job(
615 new TestConnectJob(TestConnectJob::kMockJob,
616 "a",
617 request,
618 base::TimeDelta::FromMicroseconds(1),
619 &delegate,
620 &client_socket_factory_,
621 NULL));
622 EXPECT_EQ(OK, job->Connect());
623 }
624
TEST_F(ClientSocketPoolBaseTest,ConnectJob_TimedOut)625 TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
626 TestConnectJobDelegate delegate;
627 ClientSocketHandle ignored;
628 CapturingNetLog log(CapturingNetLog::kUnbounded);
629
630 TestClientSocketPoolBase::Request request(
631 &ignored, NULL, kDefaultPriority,
632 internal::ClientSocketPoolBaseHelper::NORMAL,
633 false, params_, BoundNetLog());
634 // Deleted by TestConnectJobDelegate.
635 TestConnectJob* job =
636 new TestConnectJob(TestConnectJob::kMockPendingJob,
637 "a",
638 request,
639 base::TimeDelta::FromMicroseconds(1),
640 &delegate,
641 &client_socket_factory_,
642 &log);
643 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
644 base::PlatformThread::Sleep(1);
645 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
646
647 net::CapturingNetLog::EntryList entries;
648 log.GetEntries(&entries);
649
650 EXPECT_EQ(6u, entries.size());
651 EXPECT_TRUE(LogContainsBeginEvent(
652 entries, 0, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
653 EXPECT_TRUE(LogContainsBeginEvent(
654 entries, 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
655 EXPECT_TRUE(LogContainsEvent(
656 entries, 2, NetLog::TYPE_CONNECT_JOB_SET_SOCKET,
657 NetLog::PHASE_NONE));
658 EXPECT_TRUE(LogContainsEvent(
659 entries, 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
660 NetLog::PHASE_NONE));
661 EXPECT_TRUE(LogContainsEndEvent(
662 entries, 4, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
663 EXPECT_TRUE(LogContainsEndEvent(
664 entries, 5, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
665 }
666
TEST_F(ClientSocketPoolBaseTest,BasicSynchronous)667 TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
668 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
669
670 TestCompletionCallback callback;
671 ClientSocketHandle handle;
672 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
673
674 EXPECT_EQ(OK,
675 handle.Init("a",
676 params_,
677 kDefaultPriority,
678 &callback,
679 pool_.get(),
680 log.bound()));
681 EXPECT_TRUE(handle.is_initialized());
682 EXPECT_TRUE(handle.socket());
683 handle.Reset();
684
685 net::CapturingNetLog::EntryList entries;
686 log.GetEntries(&entries);
687
688 EXPECT_EQ(4u, entries.size());
689 EXPECT_TRUE(LogContainsBeginEvent(
690 entries, 0, NetLog::TYPE_SOCKET_POOL));
691 EXPECT_TRUE(LogContainsEvent(
692 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
693 NetLog::PHASE_NONE));
694 EXPECT_TRUE(LogContainsEvent(
695 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
696 NetLog::PHASE_NONE));
697 EXPECT_TRUE(LogContainsEndEvent(
698 entries, 3, NetLog::TYPE_SOCKET_POOL));
699 }
700
TEST_F(ClientSocketPoolBaseTest,InitConnectionFailure)701 TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
702 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
703
704 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
705 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
706
707 ClientSocketHandle handle;
708 TestCompletionCallback callback;
709 // Set the additional error state members to ensure that they get cleared.
710 handle.set_is_ssl_error(true);
711 HttpResponseInfo info;
712 info.headers = new HttpResponseHeaders("");
713 handle.set_ssl_error_response_info(info);
714 EXPECT_EQ(ERR_CONNECTION_FAILED,
715 handle.Init("a",
716 params_,
717 kDefaultPriority,
718 &callback,
719 pool_.get(),
720 log.bound()));
721 EXPECT_FALSE(handle.socket());
722 EXPECT_FALSE(handle.is_ssl_error());
723 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
724
725 net::CapturingNetLog::EntryList entries;
726 log.GetEntries(&entries);
727
728 EXPECT_EQ(3u, entries.size());
729 EXPECT_TRUE(LogContainsBeginEvent(
730 entries, 0, NetLog::TYPE_SOCKET_POOL));
731 EXPECT_TRUE(LogContainsEvent(
732 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
733 NetLog::PHASE_NONE));
734 EXPECT_TRUE(LogContainsEndEvent(
735 entries, 2, NetLog::TYPE_SOCKET_POOL));
736 }
737
TEST_F(ClientSocketPoolBaseTest,TotalLimit)738 TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
739 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
740
741 // TODO(eroman): Check that the NetLog contains this event.
742
743 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
744 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
745 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
746 EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
747
748 EXPECT_EQ(static_cast<int>(requests_size()),
749 client_socket_factory_.allocation_count());
750 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
751
752 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
753 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
754 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
755
756 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
757
758 EXPECT_EQ(static_cast<int>(requests_size()),
759 client_socket_factory_.allocation_count());
760 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
761
762 EXPECT_EQ(1, GetOrderOfRequest(1));
763 EXPECT_EQ(2, GetOrderOfRequest(2));
764 EXPECT_EQ(3, GetOrderOfRequest(3));
765 EXPECT_EQ(4, GetOrderOfRequest(4));
766 EXPECT_EQ(5, GetOrderOfRequest(5));
767 EXPECT_EQ(6, GetOrderOfRequest(6));
768 EXPECT_EQ(7, GetOrderOfRequest(7));
769
770 // Make sure we test order of all requests made.
771 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
772 }
773
TEST_F(ClientSocketPoolBaseTest,TotalLimitReachedNewGroup)774 TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
775 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
776
777 // TODO(eroman): Check that the NetLog contains this event.
778
779 // Reach all limits: max total sockets, and max sockets per group.
780 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
781 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
782 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
783 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
784
785 EXPECT_EQ(static_cast<int>(requests_size()),
786 client_socket_factory_.allocation_count());
787 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
788
789 // Now create a new group and verify that we don't starve it.
790 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
791
792 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
793
794 EXPECT_EQ(static_cast<int>(requests_size()),
795 client_socket_factory_.allocation_count());
796 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
797
798 EXPECT_EQ(1, GetOrderOfRequest(1));
799 EXPECT_EQ(2, GetOrderOfRequest(2));
800 EXPECT_EQ(3, GetOrderOfRequest(3));
801 EXPECT_EQ(4, GetOrderOfRequest(4));
802 EXPECT_EQ(5, GetOrderOfRequest(5));
803
804 // Make sure we test order of all requests made.
805 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
806 }
807
TEST_F(ClientSocketPoolBaseTest,TotalLimitRespectsPriority)808 TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
809 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
810
811 EXPECT_EQ(OK, StartRequest("b", LOWEST));
812 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
813 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
814 EXPECT_EQ(OK, StartRequest("a", LOWEST));
815
816 EXPECT_EQ(static_cast<int>(requests_size()),
817 client_socket_factory_.allocation_count());
818
819 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
820 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
821 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
822
823 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
824
825 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
826
827 // First 4 requests don't have to wait, and finish in order.
828 EXPECT_EQ(1, GetOrderOfRequest(1));
829 EXPECT_EQ(2, GetOrderOfRequest(2));
830 EXPECT_EQ(3, GetOrderOfRequest(3));
831 EXPECT_EQ(4, GetOrderOfRequest(4));
832
833 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
834 // and then ("c", LOWEST).
835 EXPECT_EQ(7, GetOrderOfRequest(5));
836 EXPECT_EQ(6, GetOrderOfRequest(6));
837 EXPECT_EQ(5, GetOrderOfRequest(7));
838
839 // Make sure we test order of all requests made.
840 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
841 }
842
TEST_F(ClientSocketPoolBaseTest,TotalLimitRespectsGroupLimit)843 TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
844 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
845
846 EXPECT_EQ(OK, StartRequest("a", LOWEST));
847 EXPECT_EQ(OK, StartRequest("a", LOW));
848 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
849 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
850
851 EXPECT_EQ(static_cast<int>(requests_size()),
852 client_socket_factory_.allocation_count());
853
854 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
855 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
856 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
857
858 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
859
860 EXPECT_EQ(static_cast<int>(requests_size()),
861 client_socket_factory_.allocation_count());
862 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
863
864 // First 4 requests don't have to wait, and finish in order.
865 EXPECT_EQ(1, GetOrderOfRequest(1));
866 EXPECT_EQ(2, GetOrderOfRequest(2));
867 EXPECT_EQ(3, GetOrderOfRequest(3));
868 EXPECT_EQ(4, GetOrderOfRequest(4));
869
870 // Request ("b", 7) has the highest priority, but we can't make new socket for
871 // group "b", because it has reached the per-group limit. Then we make
872 // socket for ("c", 6), because it has higher priority than ("a", 4),
873 // and we still can't make a socket for group "b".
874 EXPECT_EQ(5, GetOrderOfRequest(5));
875 EXPECT_EQ(6, GetOrderOfRequest(6));
876 EXPECT_EQ(7, GetOrderOfRequest(7));
877
878 // Make sure we test order of all requests made.
879 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
880 }
881
882 // Make sure that we count connecting sockets against the total limit.
TEST_F(ClientSocketPoolBaseTest,TotalLimitCountsConnectingSockets)883 TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
884 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
885
886 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
887 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
888 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
889
890 // Create one asynchronous request.
891 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
892 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
893
894 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
895 // actually become pending until 2ms after they have been created. In order
896 // to flush all tasks, we need to wait so that we know there are no
897 // soon-to-be-pending tasks waiting.
898 base::PlatformThread::Sleep(10);
899 MessageLoop::current()->RunAllPending();
900
901 // The next synchronous request should wait for its turn.
902 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
903 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
904
905 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
906
907 EXPECT_EQ(static_cast<int>(requests_size()),
908 client_socket_factory_.allocation_count());
909
910 EXPECT_EQ(1, GetOrderOfRequest(1));
911 EXPECT_EQ(2, GetOrderOfRequest(2));
912 EXPECT_EQ(3, GetOrderOfRequest(3));
913 EXPECT_EQ(4, GetOrderOfRequest(4));
914 EXPECT_EQ(5, GetOrderOfRequest(5));
915
916 // Make sure we test order of all requests made.
917 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
918 }
919
TEST_F(ClientSocketPoolBaseTest,CorrectlyCountStalledGroups)920 TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
921 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
922 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
923
924 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
925 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
926 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
927 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
928
929 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
930
931 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
932
933 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", kDefaultPriority));
934 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
935
936 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
937
938 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
939 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
940 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
941 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
942 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
943 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
944 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
945 }
946
TEST_F(ClientSocketPoolBaseTest,StallAndThenCancelAndTriggerAvailableSocket)947 TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
948 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
949 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
950
951 ClientSocketHandle handle;
952 TestCompletionCallback callback;
953 EXPECT_EQ(ERR_IO_PENDING,
954 handle.Init("a",
955 params_,
956 kDefaultPriority,
957 &callback,
958 pool_.get(),
959 BoundNetLog()));
960
961 ClientSocketHandle handles[4];
962 for (size_t i = 0; i < arraysize(handles); ++i) {
963 TestCompletionCallback callback;
964 EXPECT_EQ(ERR_IO_PENDING,
965 handles[i].Init("b",
966 params_,
967 kDefaultPriority,
968 &callback,
969 pool_.get(),
970 BoundNetLog()));
971 }
972
973 // One will be stalled, cancel all the handles now.
974 // This should hit the OnAvailableSocketSlot() code where we previously had
975 // stalled groups, but no longer have any.
976 for (size_t i = 0; i < arraysize(handles); ++i)
977 handles[i].Reset();
978 }
979
TEST_F(ClientSocketPoolBaseTest,CancelStalledSocketAtSocketLimit)980 TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
981 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
982 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
983
984 {
985 ClientSocketHandle handles[kDefaultMaxSockets];
986 TestCompletionCallback callbacks[kDefaultMaxSockets];
987 for (int i = 0; i < kDefaultMaxSockets; ++i) {
988 EXPECT_EQ(OK, handles[i].Init(base::IntToString(i),
989 params_,
990 kDefaultPriority,
991 &callbacks[i],
992 pool_.get(),
993 BoundNetLog()));
994 }
995
996 // Force a stalled group.
997 ClientSocketHandle stalled_handle;
998 TestCompletionCallback callback;
999 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1000 params_,
1001 kDefaultPriority,
1002 &callback,
1003 pool_.get(),
1004 BoundNetLog()));
1005
1006 // Cancel the stalled request.
1007 stalled_handle.Reset();
1008
1009 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1010 EXPECT_EQ(0, pool_->IdleSocketCount());
1011
1012 // Dropping out of scope will close all handles and return them to idle.
1013 }
1014
1015 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1016 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
1017 }
1018
TEST_F(ClientSocketPoolBaseTest,CancelPendingSocketAtSocketLimit)1019 TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
1020 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1021 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1022
1023 {
1024 ClientSocketHandle handles[kDefaultMaxSockets];
1025 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1026 TestCompletionCallback callback;
1027 EXPECT_EQ(ERR_IO_PENDING, handles[i].Init(base::IntToString(i),
1028 params_,
1029 kDefaultPriority,
1030 &callback,
1031 pool_.get(),
1032 BoundNetLog()));
1033 }
1034
1035 // Force a stalled group.
1036 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1037 ClientSocketHandle stalled_handle;
1038 TestCompletionCallback callback;
1039 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1040 params_,
1041 kDefaultPriority,
1042 &callback,
1043 pool_.get(),
1044 BoundNetLog()));
1045
1046 // Since it is stalled, it should have no connect jobs.
1047 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
1048
1049 // Cancel the stalled request.
1050 handles[0].Reset();
1051
1052 // Now we should have a connect job.
1053 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("foo"));
1054
1055 // The stalled socket should connect.
1056 EXPECT_EQ(OK, callback.WaitForResult());
1057
1058 EXPECT_EQ(kDefaultMaxSockets + 1,
1059 client_socket_factory_.allocation_count());
1060 EXPECT_EQ(0, pool_->IdleSocketCount());
1061 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
1062
1063 // Dropping out of scope will close all handles and return them to idle.
1064 }
1065
1066 EXPECT_EQ(1, pool_->IdleSocketCount());
1067 }
1068
TEST_F(ClientSocketPoolBaseTest,WaitForStalledSocketAtSocketLimit)1069 TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1070 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1071 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1072
1073 ClientSocketHandle stalled_handle;
1074 TestCompletionCallback callback;
1075 {
1076 ClientSocketHandle handles[kDefaultMaxSockets];
1077 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1078 TestCompletionCallback callback;
1079 EXPECT_EQ(OK, handles[i].Init(base::StringPrintf("Take 2: %d", i),
1080 params_,
1081 kDefaultPriority,
1082 &callback,
1083 pool_.get(),
1084 BoundNetLog()));
1085 }
1086
1087 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1088 EXPECT_EQ(0, pool_->IdleSocketCount());
1089
1090 // Now we will hit the socket limit.
1091 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1092 params_,
1093 kDefaultPriority,
1094 &callback,
1095 pool_.get(),
1096 BoundNetLog()));
1097
1098 // Dropping out of scope will close all handles and return them to idle.
1099 }
1100
1101 // But if we wait for it, the released idle sockets will be closed in
1102 // preference of the waiting request.
1103 EXPECT_EQ(OK, callback.WaitForResult());
1104
1105 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1106 EXPECT_EQ(3, pool_->IdleSocketCount());
1107 }
1108
1109 // Regression test for http://crbug.com/40952.
TEST_F(ClientSocketPoolBaseTest,CloseIdleSocketAtSocketLimitDeleteGroup)1110 TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1111 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1112 pool_->EnableConnectBackupJobs();
1113 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1114
1115 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1116 ClientSocketHandle handle;
1117 TestCompletionCallback callback;
1118 EXPECT_EQ(OK, handle.Init(base::IntToString(i),
1119 params_,
1120 kDefaultPriority,
1121 &callback,
1122 pool_.get(),
1123 BoundNetLog()));
1124 }
1125
1126 // Flush all the DoReleaseSocket tasks.
1127 MessageLoop::current()->RunAllPending();
1128
1129 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1130 // reuse a socket.
1131 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1132 ClientSocketHandle handle;
1133 TestCompletionCallback callback;
1134
1135 // "0" is special here, since it should be the first entry in the sorted map,
1136 // which is the one which we would close an idle socket for. We shouldn't
1137 // close an idle socket though, since we should reuse the idle socket.
1138 EXPECT_EQ(OK, handle.Init("0",
1139 params_,
1140 kDefaultPriority,
1141 &callback,
1142 pool_.get(),
1143 BoundNetLog()));
1144
1145 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1146 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1147 }
1148
TEST_F(ClientSocketPoolBaseTest,PendingRequests)1149 TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
1150 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1151
1152 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1153 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1154 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", IDLE));
1155 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1156 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1157 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1158 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1159 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1160
1161 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
1162
1163 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1164 client_socket_factory_.allocation_count());
1165 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1166 completion_count());
1167
1168 EXPECT_EQ(1, GetOrderOfRequest(1));
1169 EXPECT_EQ(2, GetOrderOfRequest(2));
1170 EXPECT_EQ(8, GetOrderOfRequest(3));
1171 EXPECT_EQ(6, GetOrderOfRequest(4));
1172 EXPECT_EQ(4, GetOrderOfRequest(5));
1173 EXPECT_EQ(3, GetOrderOfRequest(6));
1174 EXPECT_EQ(5, GetOrderOfRequest(7));
1175 EXPECT_EQ(7, GetOrderOfRequest(8));
1176
1177 // Make sure we test order of all requests made.
1178 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
1179 }
1180
TEST_F(ClientSocketPoolBaseTest,PendingRequests_NoKeepAlive)1181 TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
1182 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1183
1184 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1185 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1186 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1187 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1188 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1189 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1190 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1191
1192 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1193
1194 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
1195 EXPECT_EQ(OK, request(i)->WaitForResult());
1196
1197 EXPECT_EQ(static_cast<int>(requests_size()),
1198 client_socket_factory_.allocation_count());
1199 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1200 completion_count());
1201 }
1202
1203 // This test will start up a RequestSocket() and then immediately Cancel() it.
1204 // The pending connect job will be cancelled and should not call back into
1205 // ClientSocketPoolBase.
TEST_F(ClientSocketPoolBaseTest,CancelRequestClearGroup)1206 TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
1207 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1208
1209 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1210 ClientSocketHandle handle;
1211 TestCompletionCallback callback;
1212 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1213 params_,
1214 kDefaultPriority,
1215 &callback,
1216 pool_.get(),
1217 BoundNetLog()));
1218 handle.Reset();
1219 }
1220
TEST_F(ClientSocketPoolBaseTest,ConnectCancelConnect)1221 TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
1222 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1223
1224 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1225 ClientSocketHandle handle;
1226 TestCompletionCallback callback;
1227
1228 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1229 params_,
1230 kDefaultPriority,
1231 &callback,
1232 pool_.get(),
1233 BoundNetLog()));
1234
1235 handle.Reset();
1236
1237 TestCompletionCallback callback2;
1238 EXPECT_EQ(ERR_IO_PENDING,
1239 handle.Init("a",
1240 params_,
1241 kDefaultPriority,
1242 &callback2,
1243 pool_.get(),
1244 BoundNetLog()));
1245
1246 EXPECT_EQ(OK, callback2.WaitForResult());
1247 EXPECT_FALSE(callback.have_result());
1248
1249 handle.Reset();
1250 }
1251
TEST_F(ClientSocketPoolBaseTest,CancelRequest)1252 TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
1253 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1254
1255 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1256 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1257 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1258 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1259 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1260 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1261 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1262
1263 // Cancel a request.
1264 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
1265 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1266 (*requests())[index_to_cancel]->handle()->Reset();
1267
1268 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
1269
1270 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1271 client_socket_factory_.allocation_count());
1272 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1273 completion_count());
1274
1275 EXPECT_EQ(1, GetOrderOfRequest(1));
1276 EXPECT_EQ(2, GetOrderOfRequest(2));
1277 EXPECT_EQ(5, GetOrderOfRequest(3));
1278 EXPECT_EQ(3, GetOrderOfRequest(4));
1279 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1280 GetOrderOfRequest(5)); // Canceled request.
1281 EXPECT_EQ(4, GetOrderOfRequest(6));
1282 EXPECT_EQ(6, GetOrderOfRequest(7));
1283
1284 // Make sure we test order of all requests made.
1285 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
1286 }
1287
1288 class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
1289 public:
RequestSocketCallback(ClientSocketHandle * handle,TestClientSocketPool * pool,TestConnectJobFactory * test_connect_job_factory,TestConnectJob::JobType next_job_type)1290 RequestSocketCallback(ClientSocketHandle* handle,
1291 TestClientSocketPool* pool,
1292 TestConnectJobFactory* test_connect_job_factory,
1293 TestConnectJob::JobType next_job_type)
1294 : handle_(handle),
1295 pool_(pool),
1296 within_callback_(false),
1297 test_connect_job_factory_(test_connect_job_factory),
1298 next_job_type_(next_job_type) {}
1299
RunWithParams(const Tuple1<int> & params)1300 virtual void RunWithParams(const Tuple1<int>& params) {
1301 callback_.RunWithParams(params);
1302 ASSERT_EQ(OK, params.a);
1303
1304 if (!within_callback_) {
1305 test_connect_job_factory_->set_job_type(next_job_type_);
1306
1307 // Don't allow reuse of the socket. Disconnect it and then release it and
1308 // run through the MessageLoop once to get it completely released.
1309 handle_->socket()->Disconnect();
1310 handle_->Reset();
1311 {
1312 MessageLoop::ScopedNestableTaskAllower nestable(
1313 MessageLoop::current());
1314 MessageLoop::current()->RunAllPending();
1315 }
1316 within_callback_ = true;
1317 TestCompletionCallback next_job_callback;
1318 scoped_refptr<TestSocketParams> params(new TestSocketParams());
1319 int rv = handle_->Init("a",
1320 params,
1321 kDefaultPriority,
1322 &next_job_callback,
1323 pool_,
1324 BoundNetLog());
1325 switch (next_job_type_) {
1326 case TestConnectJob::kMockJob:
1327 EXPECT_EQ(OK, rv);
1328 break;
1329 case TestConnectJob::kMockPendingJob:
1330 EXPECT_EQ(ERR_IO_PENDING, rv);
1331
1332 // For pending jobs, wait for new socket to be created. This makes
1333 // sure there are no more pending operations nor any unclosed sockets
1334 // when the test finishes.
1335 // We need to give it a little bit of time to run, so that all the
1336 // operations that happen on timers (e.g. cleanup of idle
1337 // connections) can execute.
1338 {
1339 MessageLoop::ScopedNestableTaskAllower nestable(
1340 MessageLoop::current());
1341 base::PlatformThread::Sleep(10);
1342 EXPECT_EQ(OK, next_job_callback.WaitForResult());
1343 }
1344 break;
1345 default:
1346 FAIL() << "Unexpected job type: " << next_job_type_;
1347 break;
1348 }
1349 }
1350 }
1351
WaitForResult()1352 int WaitForResult() {
1353 return callback_.WaitForResult();
1354 }
1355
1356 private:
1357 ClientSocketHandle* const handle_;
1358 TestClientSocketPool* const pool_;
1359 bool within_callback_;
1360 TestConnectJobFactory* const test_connect_job_factory_;
1361 TestConnectJob::JobType next_job_type_;
1362 TestCompletionCallback callback_;
1363 };
1364
TEST_F(ClientSocketPoolBaseTest,RequestPendingJobTwice)1365 TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
1366 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1367
1368 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1369 ClientSocketHandle handle;
1370 RequestSocketCallback callback(
1371 &handle, pool_.get(), connect_job_factory_,
1372 TestConnectJob::kMockPendingJob);
1373 int rv = handle.Init("a",
1374 params_,
1375 kDefaultPriority,
1376 &callback,
1377 pool_.get(),
1378 BoundNetLog());
1379 ASSERT_EQ(ERR_IO_PENDING, rv);
1380
1381 EXPECT_EQ(OK, callback.WaitForResult());
1382 }
1383
TEST_F(ClientSocketPoolBaseTest,RequestPendingJobThenSynchronous)1384 TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
1385 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1386
1387 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1388 ClientSocketHandle handle;
1389 RequestSocketCallback callback(
1390 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
1391 int rv = handle.Init("a",
1392 params_,
1393 kDefaultPriority,
1394 &callback,
1395 pool_.get(),
1396 BoundNetLog());
1397 ASSERT_EQ(ERR_IO_PENDING, rv);
1398
1399 EXPECT_EQ(OK, callback.WaitForResult());
1400 }
1401
1402 // Make sure that pending requests get serviced after active requests get
1403 // cancelled.
TEST_F(ClientSocketPoolBaseTest,CancelActiveRequestWithPendingRequests)1404 TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
1405 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1406
1407 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1408
1409 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1410 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1411 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1412 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1413 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1414 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1415 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1416
1417 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1418 // Let's cancel them.
1419 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
1420 ASSERT_FALSE(request(i)->handle()->is_initialized());
1421 request(i)->handle()->Reset();
1422 }
1423
1424 // Let's wait for the rest to complete now.
1425 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
1426 EXPECT_EQ(OK, request(i)->WaitForResult());
1427 request(i)->handle()->Reset();
1428 }
1429
1430 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1431 completion_count());
1432 }
1433
1434 // Make sure that pending requests get serviced after active requests fail.
TEST_F(ClientSocketPoolBaseTest,FailingActiveRequestWithPendingRequests)1435 TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
1436 const size_t kMaxSockets = 5;
1437 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
1438
1439 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1440
1441 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1442 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
1443
1444 // Queue up all the requests
1445 for (size_t i = 0; i < kNumberOfRequests; ++i)
1446 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1447
1448 for (size_t i = 0; i < kNumberOfRequests; ++i)
1449 EXPECT_EQ(ERR_CONNECTION_FAILED, request(i)->WaitForResult());
1450 }
1451
TEST_F(ClientSocketPoolBaseTest,CancelActiveRequestThenRequestSocket)1452 TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
1453 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1454
1455 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1456
1457 ClientSocketHandle handle;
1458 TestCompletionCallback callback;
1459 int rv = handle.Init("a",
1460 params_,
1461 kDefaultPriority,
1462 &callback,
1463 pool_.get(),
1464 BoundNetLog());
1465 EXPECT_EQ(ERR_IO_PENDING, rv);
1466
1467 // Cancel the active request.
1468 handle.Reset();
1469
1470 rv = handle.Init("a",
1471 params_,
1472 kDefaultPriority,
1473 &callback,
1474 pool_.get(),
1475 BoundNetLog());
1476 EXPECT_EQ(ERR_IO_PENDING, rv);
1477 EXPECT_EQ(OK, callback.WaitForResult());
1478
1479 EXPECT_FALSE(handle.is_reused());
1480 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1481 }
1482
1483 // Regression test for http://crbug.com/17985.
TEST_F(ClientSocketPoolBaseTest,GroupWithPendingRequestsIsNotEmpty)1484 TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1485 const int kMaxSockets = 3;
1486 const int kMaxSocketsPerGroup = 2;
1487 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1488
1489 const RequestPriority kHighPriority = HIGHEST;
1490
1491 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1492 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1493
1494 // This is going to be a pending request in an otherwise empty group.
1495 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1496
1497 // Reach the maximum socket limit.
1498 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1499
1500 // Create a stalled group with high priorities.
1501 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1502 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1503
1504 // Release the first two sockets from "a". Because this is a keepalive,
1505 // the first release will unblock the pending request for "a". The
1506 // second release will unblock a request for "c", becaue it is the next
1507 // high priority socket.
1508 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1509 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1510
1511 // Closing idle sockets should not get us into trouble, but in the bug
1512 // we were hitting a CHECK here.
1513 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1514 pool_->CloseIdleSockets();
1515
1516 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
1517 }
1518
TEST_F(ClientSocketPoolBaseTest,BasicAsynchronous)1519 TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
1520 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1521
1522 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1523 ClientSocketHandle handle;
1524 TestCompletionCallback callback;
1525 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
1526 int rv = handle.Init("a",
1527 params_,
1528 LOWEST,
1529 &callback,
1530 pool_.get(),
1531 log.bound());
1532 EXPECT_EQ(ERR_IO_PENDING, rv);
1533 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1534 EXPECT_EQ(OK, callback.WaitForResult());
1535 EXPECT_TRUE(handle.is_initialized());
1536 EXPECT_TRUE(handle.socket());
1537 handle.Reset();
1538
1539 net::CapturingNetLog::EntryList entries;
1540 log.GetEntries(&entries);
1541
1542 EXPECT_EQ(4u, entries.size());
1543 EXPECT_TRUE(LogContainsBeginEvent(
1544 entries, 0, NetLog::TYPE_SOCKET_POOL));
1545 EXPECT_TRUE(LogContainsEvent(
1546 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1547 NetLog::PHASE_NONE));
1548 EXPECT_TRUE(LogContainsEvent(
1549 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
1550 NetLog::PHASE_NONE));
1551 EXPECT_TRUE(LogContainsEndEvent(
1552 entries, 3, NetLog::TYPE_SOCKET_POOL));
1553 }
1554
TEST_F(ClientSocketPoolBaseTest,InitConnectionAsynchronousFailure)1555 TEST_F(ClientSocketPoolBaseTest,
1556 InitConnectionAsynchronousFailure) {
1557 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1558
1559 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1560 ClientSocketHandle handle;
1561 TestCompletionCallback callback;
1562 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
1563 // Set the additional error state members to ensure that they get cleared.
1564 handle.set_is_ssl_error(true);
1565 HttpResponseInfo info;
1566 info.headers = new HttpResponseHeaders("");
1567 handle.set_ssl_error_response_info(info);
1568 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1569 params_,
1570 kDefaultPriority,
1571 &callback,
1572 pool_.get(),
1573 log.bound()));
1574 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1575 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1576 EXPECT_FALSE(handle.is_ssl_error());
1577 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
1578
1579 net::CapturingNetLog::EntryList entries;
1580 log.GetEntries(&entries);
1581
1582 EXPECT_EQ(3u, entries.size());
1583 EXPECT_TRUE(LogContainsBeginEvent(
1584 entries, 0, NetLog::TYPE_SOCKET_POOL));
1585 EXPECT_TRUE(LogContainsEvent(
1586 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1587 NetLog::PHASE_NONE));
1588 EXPECT_TRUE(LogContainsEndEvent(
1589 entries, 2, NetLog::TYPE_SOCKET_POOL));
1590 }
1591
TEST_F(ClientSocketPoolBaseTest,TwoRequestsCancelOne)1592 TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
1593 // TODO(eroman): Add back the log expectations! Removed them because the
1594 // ordering is difficult, and some may fire during destructor.
1595 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1596
1597 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1598 ClientSocketHandle handle;
1599 TestCompletionCallback callback;
1600 ClientSocketHandle handle2;
1601 TestCompletionCallback callback2;
1602
1603 EXPECT_EQ(ERR_IO_PENDING,
1604 handle.Init("a",
1605 params_,
1606 kDefaultPriority,
1607 &callback,
1608 pool_.get(),
1609 BoundNetLog()));
1610 CapturingBoundNetLog log2(CapturingNetLog::kUnbounded);
1611 EXPECT_EQ(ERR_IO_PENDING,
1612 handle2.Init("a",
1613 params_,
1614 kDefaultPriority,
1615 &callback2,
1616 pool_.get(),
1617 BoundNetLog()));
1618
1619 handle.Reset();
1620
1621
1622 // At this point, request 2 is just waiting for the connect job to finish.
1623
1624 EXPECT_EQ(OK, callback2.WaitForResult());
1625 handle2.Reset();
1626
1627 // Now request 2 has actually finished.
1628 // TODO(eroman): Add back log expectations.
1629 }
1630
TEST_F(ClientSocketPoolBaseTest,CancelRequestLimitsJobs)1631 TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
1632 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1633
1634 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1635
1636 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1637 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1638 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1639 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1640
1641 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1642 (*requests())[2]->handle()->Reset();
1643 (*requests())[3]->handle()->Reset();
1644 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1645
1646 (*requests())[1]->handle()->Reset();
1647 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1648
1649 (*requests())[0]->handle()->Reset();
1650 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1651 }
1652
1653 // When requests and ConnectJobs are not coupled, the request will get serviced
1654 // by whatever comes first.
TEST_F(ClientSocketPoolBaseTest,ReleaseSockets)1655 TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
1656 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1657
1658 // Start job 1 (async OK)
1659 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1660
1661 std::vector<TestSocketRequest*> request_order;
1662 size_t completion_count; // unused
1663 TestSocketRequest req1(&request_order, &completion_count);
1664 int rv = req1.handle()->Init("a",
1665 params_,
1666 kDefaultPriority,
1667 &req1, pool_.get(),
1668 BoundNetLog());
1669 EXPECT_EQ(ERR_IO_PENDING, rv);
1670 EXPECT_EQ(OK, req1.WaitForResult());
1671
1672 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1673 // without a job.
1674 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1675
1676 TestSocketRequest req2(&request_order, &completion_count);
1677 rv = req2.handle()->Init("a",
1678 params_,
1679 kDefaultPriority,
1680 &req2,
1681 pool_.get(),
1682 BoundNetLog());
1683 EXPECT_EQ(ERR_IO_PENDING, rv);
1684 TestSocketRequest req3(&request_order, &completion_count);
1685 rv = req3.handle()->Init("a",
1686 params_,
1687 kDefaultPriority,
1688 &req3,
1689 pool_.get(),
1690 BoundNetLog());
1691 EXPECT_EQ(ERR_IO_PENDING, rv);
1692
1693 // Both Requests 2 and 3 are pending. We release socket 1 which should
1694 // service request 2. Request 3 should still be waiting.
1695 req1.handle()->Reset();
1696 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
1697 ASSERT_TRUE(req2.handle()->socket());
1698 EXPECT_EQ(OK, req2.WaitForResult());
1699 EXPECT_FALSE(req3.handle()->socket());
1700
1701 // Signal job 2, which should service request 3.
1702
1703 client_socket_factory_.SignalJobs();
1704 EXPECT_EQ(OK, req3.WaitForResult());
1705
1706 ASSERT_EQ(3U, request_order.size());
1707 EXPECT_EQ(&req1, request_order[0]);
1708 EXPECT_EQ(&req2, request_order[1]);
1709 EXPECT_EQ(&req3, request_order[2]);
1710 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1711 }
1712
1713 // The requests are not coupled to the jobs. So, the requests should finish in
1714 // their priority / insertion order.
TEST_F(ClientSocketPoolBaseTest,PendingJobCompletionOrder)1715 TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
1716 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1717 // First two jobs are async.
1718 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1719
1720 std::vector<TestSocketRequest*> request_order;
1721 size_t completion_count; // unused
1722 TestSocketRequest req1(&request_order, &completion_count);
1723 int rv = req1.handle()->Init("a",
1724 params_,
1725 kDefaultPriority,
1726 &req1,
1727 pool_.get(),
1728 BoundNetLog());
1729 EXPECT_EQ(ERR_IO_PENDING, rv);
1730
1731 TestSocketRequest req2(&request_order, &completion_count);
1732 rv = req2.handle()->Init("a",
1733 params_,
1734 kDefaultPriority,
1735 &req2,
1736 pool_.get(),
1737 BoundNetLog());
1738 EXPECT_EQ(ERR_IO_PENDING, rv);
1739
1740 // The pending job is sync.
1741 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1742
1743 TestSocketRequest req3(&request_order, &completion_count);
1744 rv = req3.handle()->Init("a",
1745 params_,
1746 kDefaultPriority,
1747 &req3,
1748 pool_.get(),
1749 BoundNetLog());
1750 EXPECT_EQ(ERR_IO_PENDING, rv);
1751
1752 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1753 EXPECT_EQ(OK, req2.WaitForResult());
1754 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1755
1756 ASSERT_EQ(3U, request_order.size());
1757 EXPECT_EQ(&req1, request_order[0]);
1758 EXPECT_EQ(&req2, request_order[1]);
1759 EXPECT_EQ(&req3, request_order[2]);
1760 }
1761
TEST_F(ClientSocketPoolBaseTest,LoadState)1762 TEST_F(ClientSocketPoolBaseTest, LoadState) {
1763 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1764 connect_job_factory_->set_job_type(
1765 TestConnectJob::kMockAdvancingLoadStateJob);
1766
1767 ClientSocketHandle handle;
1768 TestCompletionCallback callback;
1769 int rv = handle.Init("a",
1770 params_,
1771 kDefaultPriority,
1772 &callback,
1773 pool_.get(),
1774 BoundNetLog());
1775 EXPECT_EQ(ERR_IO_PENDING, rv);
1776 EXPECT_EQ(LOAD_STATE_IDLE, handle.GetLoadState());
1777
1778 MessageLoop::current()->RunAllPending();
1779
1780 ClientSocketHandle handle2;
1781 TestCompletionCallback callback2;
1782 rv = handle2.Init("a",
1783 params_,
1784 kDefaultPriority,
1785 &callback2, pool_.get(),
1786 BoundNetLog());
1787 EXPECT_EQ(ERR_IO_PENDING, rv);
1788 EXPECT_NE(LOAD_STATE_IDLE, handle.GetLoadState());
1789 EXPECT_NE(LOAD_STATE_IDLE, handle2.GetLoadState());
1790 }
1791
TEST_F(ClientSocketPoolBaseTest,Recoverable)1792 TEST_F(ClientSocketPoolBaseTest, Recoverable) {
1793 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1794 connect_job_factory_->set_job_type(TestConnectJob::kMockRecoverableJob);
1795
1796 ClientSocketHandle handle;
1797 TestCompletionCallback callback;
1798 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, handle.Init("a",
1799 params_,
1800 kDefaultPriority,
1801 &callback, pool_.get(),
1802 BoundNetLog()));
1803 EXPECT_TRUE(handle.is_initialized());
1804 EXPECT_TRUE(handle.socket());
1805 }
1806
TEST_F(ClientSocketPoolBaseTest,AsyncRecoverable)1807 TEST_F(ClientSocketPoolBaseTest, AsyncRecoverable) {
1808 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1809
1810 connect_job_factory_->set_job_type(
1811 TestConnectJob::kMockPendingRecoverableJob);
1812 ClientSocketHandle handle;
1813 TestCompletionCallback callback;
1814 EXPECT_EQ(ERR_IO_PENDING,
1815 handle.Init("a",
1816 params_,
1817 kDefaultPriority,
1818 &callback,
1819 pool_.get(),
1820 BoundNetLog()));
1821 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1822 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, callback.WaitForResult());
1823 EXPECT_TRUE(handle.is_initialized());
1824 EXPECT_TRUE(handle.socket());
1825 }
1826
TEST_F(ClientSocketPoolBaseTest,AdditionalErrorStateSynchronous)1827 TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
1828 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1829 connect_job_factory_->set_job_type(
1830 TestConnectJob::kMockAdditionalErrorStateJob);
1831
1832 ClientSocketHandle handle;
1833 TestCompletionCallback callback;
1834 EXPECT_EQ(ERR_CONNECTION_FAILED,
1835 handle.Init("a",
1836 params_,
1837 kDefaultPriority,
1838 &callback,
1839 pool_.get(),
1840 BoundNetLog()));
1841 EXPECT_FALSE(handle.is_initialized());
1842 EXPECT_FALSE(handle.socket());
1843 EXPECT_TRUE(handle.is_ssl_error());
1844 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
1845 }
1846
TEST_F(ClientSocketPoolBaseTest,AdditionalErrorStateAsynchronous)1847 TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
1848 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1849
1850 connect_job_factory_->set_job_type(
1851 TestConnectJob::kMockPendingAdditionalErrorStateJob);
1852 ClientSocketHandle handle;
1853 TestCompletionCallback callback;
1854 EXPECT_EQ(ERR_IO_PENDING,
1855 handle.Init("a",
1856 params_,
1857 kDefaultPriority,
1858 &callback,
1859 pool_.get(),
1860 BoundNetLog()));
1861 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1862 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1863 EXPECT_FALSE(handle.is_initialized());
1864 EXPECT_FALSE(handle.socket());
1865 EXPECT_TRUE(handle.is_ssl_error());
1866 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
1867 }
1868
TEST_F(ClientSocketPoolBaseTest,DisableCleanupTimer)1869 TEST_F(ClientSocketPoolBaseTest, DisableCleanupTimer) {
1870 // Disable cleanup timer.
1871 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(false);
1872
1873 CreatePoolWithIdleTimeouts(
1874 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1875 base::TimeDelta::FromMilliseconds(10), // Time out unused sockets
1876 base::TimeDelta::FromMilliseconds(10)); // Time out used sockets
1877
1878 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1879
1880 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
1881
1882 ClientSocketHandle handle;
1883 TestOldCompletionCallback callback;
1884 int rv = handle.Init("a",
1885 params_,
1886 LOWEST,
1887 &callback,
1888 pool_.get(),
1889 BoundNetLog());
1890 EXPECT_EQ(ERR_IO_PENDING, rv);
1891 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1892
1893 ClientSocketHandle handle2;
1894 TestOldCompletionCallback callback2;
1895 rv = handle2.Init("a",
1896 params_,
1897 LOWEST,
1898 &callback2,
1899 pool_.get(),
1900 BoundNetLog());
1901 EXPECT_EQ(ERR_IO_PENDING, rv);
1902 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
1903
1904 // Cancel one of the requests. Wait for the other, which will get the first
1905 // job. Release the socket. Run the loop again to make sure the second
1906 // socket is sitting idle and the first one is released (since ReleaseSocket()
1907 // just posts a DoReleaseSocket() task).
1908
1909 handle.Reset();
1910 EXPECT_EQ(OK, callback2.WaitForResult());
1911 // Use the socket.
1912 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, NULL));
1913 handle2.Reset();
1914
1915 // The idle socket timeout value was set to 10 milliseconds. Wait 20
1916 // milliseconds so the sockets timeout.
1917 base::PlatformThread::Sleep(20);
1918 MessageLoop::current()->RunAllPending();
1919
1920 ASSERT_EQ(2, pool_->IdleSocketCount());
1921
1922 // Request a new socket. This should cleanup the unused and timed out ones.
1923 // A new socket will be created rather than reusing the idle one.
1924 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
1925 rv = handle.Init("a",
1926 params_,
1927 LOWEST,
1928 &callback,
1929 pool_.get(),
1930 log.bound());
1931 EXPECT_EQ(ERR_IO_PENDING, rv);
1932 EXPECT_EQ(OK, callback.WaitForResult());
1933 EXPECT_FALSE(handle.is_reused());
1934
1935 // Make sure the idle socket is closed
1936 ASSERT_TRUE(pool_->HasGroup("a"));
1937 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1938 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
1939
1940 net::CapturingNetLog::EntryList entries;
1941 log.GetEntries(&entries);
1942 EXPECT_FALSE(LogContainsEntryWithType(
1943 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
1944 }
1945
TEST_F(ClientSocketPoolBaseTest,CleanupTimedOutIdleSockets)1946 TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
1947 CreatePoolWithIdleTimeouts(
1948 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1949 base::TimeDelta(), // Time out unused sockets immediately.
1950 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1951
1952 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1953
1954 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
1955
1956 ClientSocketHandle handle;
1957 TestCompletionCallback callback;
1958 int rv = handle.Init("a",
1959 params_,
1960 LOWEST,
1961 &callback,
1962 pool_.get(),
1963 BoundNetLog());
1964 EXPECT_EQ(ERR_IO_PENDING, rv);
1965 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1966
1967 ClientSocketHandle handle2;
1968 TestCompletionCallback callback2;
1969 rv = handle2.Init("a",
1970 params_,
1971 LOWEST,
1972 &callback2,
1973 pool_.get(),
1974 BoundNetLog());
1975 EXPECT_EQ(ERR_IO_PENDING, rv);
1976 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
1977
1978 // Cancel one of the requests. Wait for the other, which will get the first
1979 // job. Release the socket. Run the loop again to make sure the second
1980 // socket is sitting idle and the first one is released (since ReleaseSocket()
1981 // just posts a DoReleaseSocket() task).
1982
1983 handle.Reset();
1984 EXPECT_EQ(OK, callback2.WaitForResult());
1985 // Use the socket.
1986 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, NULL));
1987 handle2.Reset();
1988
1989 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1990 // actually become pending until 2ms after they have been created. In order
1991 // to flush all tasks, we need to wait so that we know there are no
1992 // soon-to-be-pending tasks waiting.
1993 base::PlatformThread::Sleep(10);
1994 MessageLoop::current()->RunAllPending();
1995
1996 ASSERT_EQ(2, pool_->IdleSocketCount());
1997
1998 // Invoke the idle socket cleanup check. Only one socket should be left, the
1999 // used socket. Request it to make sure that it's used.
2000
2001 pool_->CleanupTimedOutIdleSockets();
2002 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
2003 rv = handle.Init("a",
2004 params_,
2005 LOWEST,
2006 &callback,
2007 pool_.get(),
2008 log.bound());
2009 EXPECT_EQ(OK, rv);
2010 EXPECT_TRUE(handle.is_reused());
2011
2012 net::CapturingNetLog::EntryList entries;
2013 log.GetEntries(&entries);
2014 EXPECT_TRUE(LogContainsEntryWithType(
2015 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
2016 }
2017
2018 // Make sure that we process all pending requests even when we're stalling
2019 // because of multiple releasing disconnected sockets.
TEST_F(ClientSocketPoolBaseTest,MultipleReleasingDisconnectedSockets)2020 TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
2021 CreatePoolWithIdleTimeouts(
2022 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2023 base::TimeDelta(), // Time out unused sockets immediately.
2024 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2025
2026 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2027
2028 // Startup 4 connect jobs. Two of them will be pending.
2029
2030 ClientSocketHandle handle;
2031 TestCompletionCallback callback;
2032 int rv = handle.Init("a",
2033 params_,
2034 LOWEST,
2035 &callback,
2036 pool_.get(),
2037 BoundNetLog());
2038 EXPECT_EQ(OK, rv);
2039
2040 ClientSocketHandle handle2;
2041 TestCompletionCallback callback2;
2042 rv = handle2.Init("a",
2043 params_,
2044 LOWEST,
2045 &callback2,
2046 pool_.get(),
2047 BoundNetLog());
2048 EXPECT_EQ(OK, rv);
2049
2050 ClientSocketHandle handle3;
2051 TestCompletionCallback callback3;
2052 rv = handle3.Init("a",
2053 params_,
2054 LOWEST,
2055 &callback3,
2056 pool_.get(),
2057 BoundNetLog());
2058 EXPECT_EQ(ERR_IO_PENDING, rv);
2059
2060 ClientSocketHandle handle4;
2061 TestCompletionCallback callback4;
2062 rv = handle4.Init("a",
2063 params_,
2064 LOWEST,
2065 &callback4,
2066 pool_.get(),
2067 BoundNetLog());
2068 EXPECT_EQ(ERR_IO_PENDING, rv);
2069
2070 // Release two disconnected sockets.
2071
2072 handle.socket()->Disconnect();
2073 handle.Reset();
2074 handle2.socket()->Disconnect();
2075 handle2.Reset();
2076
2077 EXPECT_EQ(OK, callback3.WaitForResult());
2078 EXPECT_FALSE(handle3.is_reused());
2079 EXPECT_EQ(OK, callback4.WaitForResult());
2080 EXPECT_FALSE(handle4.is_reused());
2081 }
2082
2083 // Regression test for http://crbug.com/42267.
2084 // When DoReleaseSocket() is processed for one socket, it is blocked because the
2085 // other stalled groups all have releasing sockets, so no progress can be made.
TEST_F(ClientSocketPoolBaseTest,SocketLimitReleasingSockets)2086 TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
2087 CreatePoolWithIdleTimeouts(
2088 4 /* socket limit */, 4 /* socket limit per group */,
2089 base::TimeDelta(), // Time out unused sockets immediately.
2090 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2091
2092 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2093
2094 // Max out the socket limit with 2 per group.
2095
2096 ClientSocketHandle handle_a[4];
2097 TestCompletionCallback callback_a[4];
2098 ClientSocketHandle handle_b[4];
2099 TestCompletionCallback callback_b[4];
2100
2101 for (int i = 0; i < 2; ++i) {
2102 EXPECT_EQ(OK, handle_a[i].Init("a",
2103 params_,
2104 LOWEST,
2105 &callback_a[i],
2106 pool_.get(),
2107 BoundNetLog()));
2108 EXPECT_EQ(OK, handle_b[i].Init("b",
2109 params_,
2110 LOWEST,
2111 &callback_b[i],
2112 pool_.get(),
2113 BoundNetLog()));
2114 }
2115
2116 // Make 4 pending requests, 2 per group.
2117
2118 for (int i = 2; i < 4; ++i) {
2119 EXPECT_EQ(ERR_IO_PENDING,
2120 handle_a[i].Init("a",
2121 params_,
2122 LOWEST,
2123 &callback_a[i],
2124 pool_.get(),
2125 BoundNetLog()));
2126 EXPECT_EQ(ERR_IO_PENDING,
2127 handle_b[i].Init("b",
2128 params_,
2129 LOWEST,
2130 &callback_b[i],
2131 pool_.get(),
2132 BoundNetLog()));
2133 }
2134
2135 // Release b's socket first. The order is important, because in
2136 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2137 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2138 // first, which has a releasing socket, so it refuses to start up another
2139 // ConnectJob. So, we used to infinite loop on this.
2140 handle_b[0].socket()->Disconnect();
2141 handle_b[0].Reset();
2142 handle_a[0].socket()->Disconnect();
2143 handle_a[0].Reset();
2144
2145 // Used to get stuck here.
2146 MessageLoop::current()->RunAllPending();
2147
2148 handle_b[1].socket()->Disconnect();
2149 handle_b[1].Reset();
2150 handle_a[1].socket()->Disconnect();
2151 handle_a[1].Reset();
2152
2153 for (int i = 2; i < 4; ++i) {
2154 EXPECT_EQ(OK, callback_b[i].WaitForResult());
2155 EXPECT_EQ(OK, callback_a[i].WaitForResult());
2156 }
2157 }
2158
TEST_F(ClientSocketPoolBaseTest,ReleasingDisconnectedSocketsMaintainsPriorityOrder)2159 TEST_F(ClientSocketPoolBaseTest,
2160 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2161 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2162
2163 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2164
2165 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2166 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2167 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2168 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2169
2170 EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
2171 EXPECT_EQ(OK, (*requests())[1]->WaitForResult());
2172 EXPECT_EQ(2u, completion_count());
2173
2174 // Releases one connection.
2175 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2176 EXPECT_EQ(OK, (*requests())[2]->WaitForResult());
2177
2178 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2179 EXPECT_EQ(OK, (*requests())[3]->WaitForResult());
2180 EXPECT_EQ(4u, completion_count());
2181
2182 EXPECT_EQ(1, GetOrderOfRequest(1));
2183 EXPECT_EQ(2, GetOrderOfRequest(2));
2184 EXPECT_EQ(3, GetOrderOfRequest(3));
2185 EXPECT_EQ(4, GetOrderOfRequest(4));
2186
2187 // Make sure we test order of all requests made.
2188 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
2189 }
2190
2191 class TestReleasingSocketRequest : public CallbackRunner< Tuple1<int> > {
2192 public:
TestReleasingSocketRequest(TestClientSocketPool * pool,int expected_result,bool reset_releasing_handle)2193 TestReleasingSocketRequest(TestClientSocketPool* pool,
2194 int expected_result,
2195 bool reset_releasing_handle)
2196 : pool_(pool),
2197 expected_result_(expected_result),
2198 reset_releasing_handle_(reset_releasing_handle) {}
2199
handle()2200 ClientSocketHandle* handle() { return &handle_; }
2201
WaitForResult()2202 int WaitForResult() {
2203 return callback_.WaitForResult();
2204 }
2205
RunWithParams(const Tuple1<int> & params)2206 virtual void RunWithParams(const Tuple1<int>& params) {
2207 callback_.RunWithParams(params);
2208 if (reset_releasing_handle_)
2209 handle_.Reset();
2210 scoped_refptr<TestSocketParams> con_params(new TestSocketParams());
2211 EXPECT_EQ(expected_result_, handle2_.Init("a",
2212 con_params,
2213 kDefaultPriority,
2214 &callback2_,
2215 pool_,
2216 BoundNetLog()));
2217 }
2218
2219 private:
2220 TestClientSocketPool* const pool_;
2221 int expected_result_;
2222 bool reset_releasing_handle_;
2223 ClientSocketHandle handle_;
2224 ClientSocketHandle handle2_;
2225 TestCompletionCallback callback_;
2226 TestCompletionCallback callback2_;
2227 };
2228
2229
TEST_F(ClientSocketPoolBaseTest,AdditionalErrorSocketsDontUseSlot)2230 TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2231 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2232
2233 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2234 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
2235 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2236
2237 EXPECT_EQ(static_cast<int>(requests_size()),
2238 client_socket_factory_.allocation_count());
2239
2240 connect_job_factory_->set_job_type(
2241 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2242 TestReleasingSocketRequest req(pool_.get(), OK, false);
2243 EXPECT_EQ(ERR_IO_PENDING,
2244 req.handle()->Init("a",
2245 params_,
2246 kDefaultPriority,
2247 &req,
2248 pool_.get(),
2249 BoundNetLog()));
2250 // The next job should complete synchronously
2251 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2252
2253 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
2254 EXPECT_FALSE(req.handle()->is_initialized());
2255 EXPECT_FALSE(req.handle()->socket());
2256 EXPECT_TRUE(req.handle()->is_ssl_error());
2257 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
2258 }
2259
2260 // http://crbug.com/44724 regression test.
2261 // We start releasing the pool when we flush on network change. When that
2262 // happens, the only active references are in the ClientSocketHandles. When a
2263 // ConnectJob completes and calls back into the last ClientSocketHandle, that
2264 // callback can release the last reference and delete the pool. After the
2265 // callback finishes, we go back to the stack frame within the now-deleted pool.
2266 // Executing any code that refers to members of the now-deleted pool can cause
2267 // crashes.
TEST_F(ClientSocketPoolBaseTest,CallbackThatReleasesPool)2268 TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2269 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2270 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2271
2272 ClientSocketHandle handle;
2273 TestCompletionCallback callback;
2274 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2275 params_,
2276 kDefaultPriority,
2277 &callback,
2278 pool_.get(),
2279 BoundNetLog()));
2280
2281 pool_->Flush();
2282
2283 // We'll call back into this now.
2284 callback.WaitForResult();
2285 }
2286
TEST_F(ClientSocketPoolBaseTest,DoNotReuseSocketAfterFlush)2287 TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2288 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2289 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2290
2291 ClientSocketHandle handle;
2292 TestCompletionCallback callback;
2293 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2294 params_,
2295 kDefaultPriority,
2296 &callback,
2297 pool_.get(),
2298 BoundNetLog()));
2299 EXPECT_EQ(OK, callback.WaitForResult());
2300 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2301
2302 pool_->Flush();
2303
2304 handle.Reset();
2305 MessageLoop::current()->RunAllPending();
2306
2307 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2308 params_,
2309 kDefaultPriority,
2310 &callback,
2311 pool_.get(),
2312 BoundNetLog()));
2313 EXPECT_EQ(OK, callback.WaitForResult());
2314 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2315 }
2316
2317 class ConnectWithinCallback : public CallbackRunner< Tuple1<int> > {
2318 public:
ConnectWithinCallback(const std::string & group_name,const scoped_refptr<TestSocketParams> & params,TestClientSocketPool * pool)2319 ConnectWithinCallback(
2320 const std::string& group_name,
2321 const scoped_refptr<TestSocketParams>& params,
2322 TestClientSocketPool* pool)
2323 : group_name_(group_name), params_(params), pool_(pool) {}
2324
~ConnectWithinCallback()2325 ~ConnectWithinCallback() {}
2326
RunWithParams(const Tuple1<int> & params)2327 virtual void RunWithParams(const Tuple1<int>& params) {
2328 callback_.RunWithParams(params);
2329 EXPECT_EQ(ERR_IO_PENDING,
2330 handle_.Init(group_name_,
2331 params_,
2332 kDefaultPriority,
2333 &nested_callback_,
2334 pool_,
2335 BoundNetLog()));
2336 }
2337
WaitForResult()2338 int WaitForResult() {
2339 return callback_.WaitForResult();
2340 }
2341
WaitForNestedResult()2342 int WaitForNestedResult() {
2343 return nested_callback_.WaitForResult();
2344 }
2345
2346 private:
2347 const std::string group_name_;
2348 const scoped_refptr<TestSocketParams> params_;
2349 TestClientSocketPool* const pool_;
2350 ClientSocketHandle handle_;
2351 TestCompletionCallback callback_;
2352 TestCompletionCallback nested_callback_;
2353 };
2354
TEST_F(ClientSocketPoolBaseTest,AbortAllRequestsOnFlush)2355 TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
2356 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2357
2358 // First job will be waiting until it gets aborted.
2359 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2360
2361 ClientSocketHandle handle;
2362 ConnectWithinCallback callback("a", params_, pool_.get());
2363 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2364 params_,
2365 kDefaultPriority,
2366 &callback,
2367 pool_.get(),
2368 BoundNetLog()));
2369
2370 // Second job will be started during the first callback, and will
2371 // asynchronously complete with OK.
2372 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2373 pool_->Flush();
2374 EXPECT_EQ(ERR_ABORTED, callback.WaitForResult());
2375 EXPECT_EQ(OK, callback.WaitForNestedResult());
2376 }
2377
2378 // Cancel a pending socket request while we're at max sockets,
2379 // and verify that the backup socket firing doesn't cause a crash.
TEST_F(ClientSocketPoolBaseTest,BackupSocketCancelAtMaxSockets)2380 TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
2381 // Max 4 sockets globally, max 4 sockets per group.
2382 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2383 pool_->EnableConnectBackupJobs();
2384
2385 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2386 // timer.
2387 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2388 ClientSocketHandle handle;
2389 TestCompletionCallback callback;
2390 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2391 params_,
2392 kDefaultPriority,
2393 &callback,
2394 pool_.get(),
2395 BoundNetLog()));
2396
2397 // Start (MaxSockets - 1) connected sockets to reach max sockets.
2398 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2399 ClientSocketHandle handles[kDefaultMaxSockets];
2400 for (int i = 1; i < kDefaultMaxSockets; ++i) {
2401 TestCompletionCallback callback;
2402 EXPECT_EQ(OK, handles[i].Init("bar",
2403 params_,
2404 kDefaultPriority,
2405 &callback,
2406 pool_.get(),
2407 BoundNetLog()));
2408 }
2409
2410 MessageLoop::current()->RunAllPending();
2411
2412 // Cancel the pending request.
2413 handle.Reset();
2414
2415 // Wait for the backup timer to fire (add some slop to ensure it fires)
2416 base::PlatformThread::Sleep(
2417 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
2418
2419 MessageLoop::current()->RunAllPending();
2420 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
2421 }
2422
TEST_F(ClientSocketPoolBaseTest,CancelBackupSocketAfterCancelingAllRequests)2423 TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
2424 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2425 pool_->EnableConnectBackupJobs();
2426
2427 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2428 // timer.
2429 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2430 ClientSocketHandle handle;
2431 TestCompletionCallback callback;
2432 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2433 params_,
2434 kDefaultPriority,
2435 &callback,
2436 pool_.get(),
2437 BoundNetLog()));
2438 ASSERT_TRUE(pool_->HasGroup("bar"));
2439 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2440
2441 // Cancel the socket request. This should cancel the backup timer. Wait for
2442 // the backup time to see if it indeed got canceled.
2443 handle.Reset();
2444 // Wait for the backup timer to fire (add some slop to ensure it fires)
2445 base::PlatformThread::Sleep(
2446 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
2447 MessageLoop::current()->RunAllPending();
2448 ASSERT_TRUE(pool_->HasGroup("bar"));
2449 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2450 }
2451
TEST_F(ClientSocketPoolBaseTest,CancelBackupSocketAfterFinishingAllRequests)2452 TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
2453 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2454 pool_->EnableConnectBackupJobs();
2455
2456 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2457 // timer.
2458 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2459 ClientSocketHandle handle;
2460 TestCompletionCallback callback;
2461 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2462 params_,
2463 kDefaultPriority,
2464 &callback,
2465 pool_.get(),
2466 BoundNetLog()));
2467 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2468 ClientSocketHandle handle2;
2469 TestCompletionCallback callback2;
2470 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("bar",
2471 params_,
2472 kDefaultPriority,
2473 &callback2,
2474 pool_.get(),
2475 BoundNetLog()));
2476 ASSERT_TRUE(pool_->HasGroup("bar"));
2477 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("bar"));
2478
2479 // Cancel request 1 and then complete request 2. With the requests finished,
2480 // the backup timer should be cancelled.
2481 handle.Reset();
2482 EXPECT_EQ(OK, callback2.WaitForResult());
2483 // Wait for the backup timer to fire (add some slop to ensure it fires)
2484 base::PlatformThread::Sleep(
2485 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
2486 MessageLoop::current()->RunAllPending();
2487 }
2488
2489 // Test delayed socket binding for the case where we have two connects,
2490 // and while one is waiting on a connect, the other frees up.
2491 // The socket waiting on a connect should switch immediately to the freed
2492 // up socket.
TEST_F(ClientSocketPoolBaseTest,DelayedSocketBindingWaitingForConnect)2493 TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
2494 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2495 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2496
2497 ClientSocketHandle handle1;
2498 TestCompletionCallback callback;
2499 EXPECT_EQ(ERR_IO_PENDING,
2500 handle1.Init("a",
2501 params_,
2502 kDefaultPriority,
2503 &callback,
2504 pool_.get(),
2505 BoundNetLog()));
2506 EXPECT_EQ(OK, callback.WaitForResult());
2507
2508 // No idle sockets, no pending jobs.
2509 EXPECT_EQ(0, pool_->IdleSocketCount());
2510 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2511
2512 // Create a second socket to the same host, but this one will wait.
2513 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2514 ClientSocketHandle handle2;
2515 EXPECT_EQ(ERR_IO_PENDING,
2516 handle2.Init("a",
2517 params_,
2518 kDefaultPriority,
2519 &callback,
2520 pool_.get(),
2521 BoundNetLog()));
2522 // No idle sockets, and one connecting job.
2523 EXPECT_EQ(0, pool_->IdleSocketCount());
2524 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2525
2526 // Return the first handle to the pool. This will initiate the delayed
2527 // binding.
2528 handle1.Reset();
2529
2530 MessageLoop::current()->RunAllPending();
2531
2532 // Still no idle sockets, still one pending connect job.
2533 EXPECT_EQ(0, pool_->IdleSocketCount());
2534 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2535
2536 // The second socket connected, even though it was a Waiting Job.
2537 EXPECT_EQ(OK, callback.WaitForResult());
2538
2539 // And we can see there is still one job waiting.
2540 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2541
2542 // Finally, signal the waiting Connect.
2543 client_socket_factory_.SignalJobs();
2544 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2545
2546 MessageLoop::current()->RunAllPending();
2547 }
2548
2549 // Test delayed socket binding when a group is at capacity and one
2550 // of the group's sockets frees up.
TEST_F(ClientSocketPoolBaseTest,DelayedSocketBindingAtGroupCapacity)2551 TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
2552 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2553 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2554
2555 ClientSocketHandle handle1;
2556 TestCompletionCallback callback;
2557 EXPECT_EQ(ERR_IO_PENDING,
2558 handle1.Init("a",
2559 params_,
2560 kDefaultPriority,
2561 &callback,
2562 pool_.get(),
2563 BoundNetLog()));
2564 EXPECT_EQ(OK, callback.WaitForResult());
2565
2566 // No idle sockets, no pending jobs.
2567 EXPECT_EQ(0, pool_->IdleSocketCount());
2568 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2569
2570 // Create a second socket to the same host, but this one will wait.
2571 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2572 ClientSocketHandle handle2;
2573 EXPECT_EQ(ERR_IO_PENDING,
2574 handle2.Init("a",
2575 params_,
2576 kDefaultPriority,
2577 &callback,
2578 pool_.get(),
2579 BoundNetLog()));
2580 // No idle sockets, and one connecting job.
2581 EXPECT_EQ(0, pool_->IdleSocketCount());
2582 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2583
2584 // Return the first handle to the pool. This will initiate the delayed
2585 // binding.
2586 handle1.Reset();
2587
2588 MessageLoop::current()->RunAllPending();
2589
2590 // Still no idle sockets, still one pending connect job.
2591 EXPECT_EQ(0, pool_->IdleSocketCount());
2592 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2593
2594 // The second socket connected, even though it was a Waiting Job.
2595 EXPECT_EQ(OK, callback.WaitForResult());
2596
2597 // And we can see there is still one job waiting.
2598 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2599
2600 // Finally, signal the waiting Connect.
2601 client_socket_factory_.SignalJobs();
2602 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2603
2604 MessageLoop::current()->RunAllPending();
2605 }
2606
2607 // Test out the case where we have one socket connected, one
2608 // connecting, when the first socket finishes and goes idle.
2609 // Although the second connection is pending, the second request
2610 // should complete, by taking the first socket's idle socket.
TEST_F(ClientSocketPoolBaseTest,DelayedSocketBindingAtStall)2611 TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
2612 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2613 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2614
2615 ClientSocketHandle handle1;
2616 TestCompletionCallback callback;
2617 EXPECT_EQ(ERR_IO_PENDING,
2618 handle1.Init("a",
2619 params_,
2620 kDefaultPriority,
2621 &callback,
2622 pool_.get(),
2623 BoundNetLog()));
2624 EXPECT_EQ(OK, callback.WaitForResult());
2625
2626 // No idle sockets, no pending jobs.
2627 EXPECT_EQ(0, pool_->IdleSocketCount());
2628 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2629
2630 // Create a second socket to the same host, but this one will wait.
2631 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2632 ClientSocketHandle handle2;
2633 EXPECT_EQ(ERR_IO_PENDING,
2634 handle2.Init("a",
2635 params_,
2636 kDefaultPriority,
2637 &callback,
2638 pool_.get(),
2639 BoundNetLog()));
2640 // No idle sockets, and one connecting job.
2641 EXPECT_EQ(0, pool_->IdleSocketCount());
2642 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2643
2644 // Return the first handle to the pool. This will initiate the delayed
2645 // binding.
2646 handle1.Reset();
2647
2648 MessageLoop::current()->RunAllPending();
2649
2650 // Still no idle sockets, still one pending connect job.
2651 EXPECT_EQ(0, pool_->IdleSocketCount());
2652 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2653
2654 // The second socket connected, even though it was a Waiting Job.
2655 EXPECT_EQ(OK, callback.WaitForResult());
2656
2657 // And we can see there is still one job waiting.
2658 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2659
2660 // Finally, signal the waiting Connect.
2661 client_socket_factory_.SignalJobs();
2662 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2663
2664 MessageLoop::current()->RunAllPending();
2665 }
2666
2667 // Cover the case where on an available socket slot, we have one pending
2668 // request that completes synchronously, thereby making the Group empty.
TEST_F(ClientSocketPoolBaseTest,SynchronouslyProcessOnePendingRequest)2669 TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
2670 const int kUnlimitedSockets = 100;
2671 const int kOneSocketPerGroup = 1;
2672 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
2673
2674 // Make the first request asynchronous fail.
2675 // This will free up a socket slot later.
2676 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2677
2678 ClientSocketHandle handle1;
2679 TestCompletionCallback callback1;
2680 EXPECT_EQ(ERR_IO_PENDING,
2681 handle1.Init("a",
2682 params_,
2683 kDefaultPriority,
2684 &callback1,
2685 pool_.get(),
2686 BoundNetLog()));
2687 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2688
2689 // Make the second request synchronously fail. This should make the Group
2690 // empty.
2691 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
2692 ClientSocketHandle handle2;
2693 TestCompletionCallback callback2;
2694 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
2695 // when created.
2696 EXPECT_EQ(ERR_IO_PENDING,
2697 handle2.Init("a",
2698 params_,
2699 kDefaultPriority,
2700 &callback2,
2701 pool_.get(),
2702 BoundNetLog()));
2703
2704 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2705
2706 EXPECT_EQ(ERR_CONNECTION_FAILED, callback1.WaitForResult());
2707 EXPECT_EQ(ERR_CONNECTION_FAILED, callback2.WaitForResult());
2708 EXPECT_FALSE(pool_->HasGroup("a"));
2709 }
2710
TEST_F(ClientSocketPoolBaseTest,PreferUsedSocketToUnusedSocket)2711 TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
2712 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2713
2714 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2715
2716 ClientSocketHandle handle1;
2717 TestCompletionCallback callback1;
2718 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2719 params_,
2720 kDefaultPriority,
2721 &callback1,
2722 pool_.get(),
2723 BoundNetLog()));
2724
2725 ClientSocketHandle handle2;
2726 TestCompletionCallback callback2;
2727 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2728 params_,
2729 kDefaultPriority,
2730 &callback2,
2731 pool_.get(),
2732 BoundNetLog()));
2733 ClientSocketHandle handle3;
2734 TestCompletionCallback callback3;
2735 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
2736 params_,
2737 kDefaultPriority,
2738 &callback3,
2739 pool_.get(),
2740 BoundNetLog()));
2741
2742 EXPECT_EQ(OK, callback1.WaitForResult());
2743 EXPECT_EQ(OK, callback2.WaitForResult());
2744 EXPECT_EQ(OK, callback3.WaitForResult());
2745
2746 // Use the socket.
2747 EXPECT_EQ(1, handle1.socket()->Write(NULL, 1, NULL));
2748 EXPECT_EQ(1, handle3.socket()->Write(NULL, 1, NULL));
2749
2750 handle1.Reset();
2751 handle2.Reset();
2752 handle3.Reset();
2753
2754 EXPECT_EQ(OK, handle1.Init("a",
2755 params_,
2756 kDefaultPriority,
2757 &callback1,
2758 pool_.get(),
2759 BoundNetLog()));
2760 EXPECT_EQ(OK, handle2.Init("a",
2761 params_,
2762 kDefaultPriority,
2763 &callback2,
2764 pool_.get(),
2765 BoundNetLog()));
2766 EXPECT_EQ(OK, handle3.Init("a",
2767 params_,
2768 kDefaultPriority,
2769 &callback3,
2770 pool_.get(),
2771 BoundNetLog()));
2772
2773 EXPECT_TRUE(handle1.socket()->WasEverUsed());
2774 EXPECT_TRUE(handle2.socket()->WasEverUsed());
2775 EXPECT_FALSE(handle3.socket()->WasEverUsed());
2776 }
2777
TEST_F(ClientSocketPoolBaseTest,RequestSockets)2778 TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
2779 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2780 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2781
2782 pool_->RequestSockets("a", ¶ms_, 2, BoundNetLog());
2783
2784 ASSERT_TRUE(pool_->HasGroup("a"));
2785 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2786 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2787
2788 ClientSocketHandle handle1;
2789 TestCompletionCallback callback1;
2790 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2791 params_,
2792 kDefaultPriority,
2793 &callback1,
2794 pool_.get(),
2795 BoundNetLog()));
2796
2797 ClientSocketHandle handle2;
2798 TestCompletionCallback callback2;
2799 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2800 params_,
2801 kDefaultPriority,
2802 &callback2,
2803 pool_.get(),
2804 BoundNetLog()));
2805
2806 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2807 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2808
2809 EXPECT_EQ(OK, callback1.WaitForResult());
2810 EXPECT_EQ(OK, callback2.WaitForResult());
2811 handle1.Reset();
2812 handle2.Reset();
2813
2814 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2815 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2816 }
2817
TEST_F(ClientSocketPoolBaseTest,RequestSocketsWhenAlreadyHaveAConnectJob)2818 TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
2819 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2820 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2821
2822 ClientSocketHandle handle1;
2823 TestCompletionCallback callback1;
2824 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2825 params_,
2826 kDefaultPriority,
2827 &callback1,
2828 pool_.get(),
2829 BoundNetLog()));
2830
2831 ASSERT_TRUE(pool_->HasGroup("a"));
2832 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2833 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2834
2835 pool_->RequestSockets("a", ¶ms_, 2, BoundNetLog());
2836
2837 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2838 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2839
2840 ClientSocketHandle handle2;
2841 TestCompletionCallback callback2;
2842 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2843 params_,
2844 kDefaultPriority,
2845 &callback2,
2846 pool_.get(),
2847 BoundNetLog()));
2848
2849 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2850 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2851
2852 EXPECT_EQ(OK, callback1.WaitForResult());
2853 EXPECT_EQ(OK, callback2.WaitForResult());
2854 handle1.Reset();
2855 handle2.Reset();
2856
2857 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2858 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2859 }
2860
TEST_F(ClientSocketPoolBaseTest,RequestSocketsWhenAlreadyHaveMultipleConnectJob)2861 TEST_F(ClientSocketPoolBaseTest,
2862 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
2863 CreatePool(4, 4);
2864 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2865
2866 ClientSocketHandle handle1;
2867 TestCompletionCallback callback1;
2868 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2869 params_,
2870 kDefaultPriority,
2871 &callback1,
2872 pool_.get(),
2873 BoundNetLog()));
2874
2875 ClientSocketHandle handle2;
2876 TestCompletionCallback callback2;
2877 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2878 params_,
2879 kDefaultPriority,
2880 &callback2,
2881 pool_.get(),
2882 BoundNetLog()));
2883
2884 ClientSocketHandle handle3;
2885 TestCompletionCallback callback3;
2886 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
2887 params_,
2888 kDefaultPriority,
2889 &callback3,
2890 pool_.get(),
2891 BoundNetLog()));
2892
2893 ASSERT_TRUE(pool_->HasGroup("a"));
2894 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2895 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2896
2897 pool_->RequestSockets("a", ¶ms_, 2, BoundNetLog());
2898
2899 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2900 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2901
2902 EXPECT_EQ(OK, callback1.WaitForResult());
2903 EXPECT_EQ(OK, callback2.WaitForResult());
2904 EXPECT_EQ(OK, callback3.WaitForResult());
2905 handle1.Reset();
2906 handle2.Reset();
2907 handle3.Reset();
2908
2909 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2910 EXPECT_EQ(3, pool_->IdleSocketCountInGroup("a"));
2911 }
2912
TEST_F(ClientSocketPoolBaseTest,RequestSocketsAtMaxSocketLimit)2913 TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
2914 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2915 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2916
2917 ASSERT_FALSE(pool_->HasGroup("a"));
2918
2919 pool_->RequestSockets("a", ¶ms_, kDefaultMaxSockets,
2920 BoundNetLog());
2921
2922 ASSERT_TRUE(pool_->HasGroup("a"));
2923 EXPECT_EQ(kDefaultMaxSockets, pool_->NumConnectJobsInGroup("a"));
2924
2925 ASSERT_FALSE(pool_->HasGroup("b"));
2926
2927 pool_->RequestSockets("b", ¶ms_, kDefaultMaxSockets,
2928 BoundNetLog());
2929
2930 ASSERT_FALSE(pool_->HasGroup("b"));
2931 }
2932
TEST_F(ClientSocketPoolBaseTest,RequestSocketsHitMaxSocketLimit)2933 TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
2934 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2935 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2936
2937 ASSERT_FALSE(pool_->HasGroup("a"));
2938
2939 pool_->RequestSockets("a", ¶ms_, kDefaultMaxSockets - 1,
2940 BoundNetLog());
2941
2942 ASSERT_TRUE(pool_->HasGroup("a"));
2943 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->NumConnectJobsInGroup("a"));
2944
2945 ASSERT_FALSE(pool_->HasGroup("b"));
2946
2947 pool_->RequestSockets("b", ¶ms_, kDefaultMaxSockets,
2948 BoundNetLog());
2949
2950 ASSERT_TRUE(pool_->HasGroup("b"));
2951 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("b"));
2952 }
2953
TEST_F(ClientSocketPoolBaseTest,RequestSocketsCountIdleSockets)2954 TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
2955 CreatePool(4, 4);
2956 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2957
2958 ClientSocketHandle handle1;
2959 TestCompletionCallback callback1;
2960 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2961 params_,
2962 kDefaultPriority,
2963 &callback1,
2964 pool_.get(),
2965 BoundNetLog()));
2966 ASSERT_EQ(OK, callback1.WaitForResult());
2967 handle1.Reset();
2968
2969 ASSERT_TRUE(pool_->HasGroup("a"));
2970 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2971 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
2972
2973 pool_->RequestSockets("a", ¶ms_, 2, BoundNetLog());
2974
2975 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2976 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
2977 }
2978
TEST_F(ClientSocketPoolBaseTest,RequestSocketsCountActiveSockets)2979 TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
2980 CreatePool(4, 4);
2981 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2982
2983 ClientSocketHandle handle1;
2984 TestCompletionCallback callback1;
2985 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2986 params_,
2987 kDefaultPriority,
2988 &callback1,
2989 pool_.get(),
2990 BoundNetLog()));
2991 ASSERT_EQ(OK, callback1.WaitForResult());
2992
2993 ASSERT_TRUE(pool_->HasGroup("a"));
2994 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2995 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2996 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2997
2998 pool_->RequestSockets("a", ¶ms_, 2, BoundNetLog());
2999
3000 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3001 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3002 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3003 }
3004
TEST_F(ClientSocketPoolBaseTest,RequestSocketsSynchronous)3005 TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
3006 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3007 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3008
3009 pool_->RequestSockets("a", ¶ms_, kDefaultMaxSocketsPerGroup,
3010 BoundNetLog());
3011
3012 ASSERT_TRUE(pool_->HasGroup("a"));
3013 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3014 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("a"));
3015
3016 pool_->RequestSockets("b", ¶ms_, kDefaultMaxSocketsPerGroup,
3017 BoundNetLog());
3018
3019 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3020 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("b"));
3021 }
3022
TEST_F(ClientSocketPoolBaseTest,RequestSocketsSynchronousError)3023 TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
3024 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3025 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3026
3027 pool_->RequestSockets("a", ¶ms_, kDefaultMaxSocketsPerGroup,
3028 BoundNetLog());
3029
3030 ASSERT_FALSE(pool_->HasGroup("a"));
3031
3032 connect_job_factory_->set_job_type(
3033 TestConnectJob::kMockAdditionalErrorStateJob);
3034 pool_->RequestSockets("a", ¶ms_, kDefaultMaxSocketsPerGroup,
3035 BoundNetLog());
3036
3037 ASSERT_FALSE(pool_->HasGroup("a"));
3038 }
3039
TEST_F(ClientSocketPoolBaseTest,RequestSocketsMultipleTimesDoesNothing)3040 TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
3041 CreatePool(4, 4);
3042 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3043
3044 pool_->RequestSockets("a", ¶ms_, 2, BoundNetLog());
3045
3046 ASSERT_TRUE(pool_->HasGroup("a"));
3047 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3048 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3049
3050 pool_->RequestSockets("a", ¶ms_, 2, BoundNetLog());
3051 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3052 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3053
3054 ClientSocketHandle handle1;
3055 TestCompletionCallback callback1;
3056 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3057 params_,
3058 kDefaultPriority,
3059 &callback1,
3060 pool_.get(),
3061 BoundNetLog()));
3062 ASSERT_EQ(OK, callback1.WaitForResult());
3063
3064 ClientSocketHandle handle2;
3065 TestCompletionCallback callback2;
3066 int rv = handle2.Init("a",
3067 params_,
3068 kDefaultPriority,
3069 &callback2,
3070 pool_.get(),
3071 BoundNetLog());
3072 if (rv != OK) {
3073 EXPECT_EQ(ERR_IO_PENDING, rv);
3074 EXPECT_EQ(OK, callback2.WaitForResult());
3075 }
3076
3077 handle1.Reset();
3078 handle2.Reset();
3079
3080 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3081
3082 pool_->RequestSockets("a", ¶ms_, 2, BoundNetLog());
3083 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3084 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3085 }
3086
TEST_F(ClientSocketPoolBaseTest,RequestSocketsDifferentNumSockets)3087 TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
3088 CreatePool(4, 4);
3089 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3090
3091 pool_->RequestSockets("a", ¶ms_, 1, BoundNetLog());
3092
3093 ASSERT_TRUE(pool_->HasGroup("a"));
3094 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3095 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3096
3097 pool_->RequestSockets("a", ¶ms_, 2, BoundNetLog());
3098 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3099 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3100
3101 pool_->RequestSockets("a", ¶ms_, 3, BoundNetLog());
3102 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
3103 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3104
3105 pool_->RequestSockets("a", ¶ms_, 1, BoundNetLog());
3106 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
3107 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3108 }
3109
TEST_F(ClientSocketPoolBaseTest,PreconnectJobsTakenByNormalRequests)3110 TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
3111 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3112 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3113
3114 pool_->RequestSockets("a", ¶ms_, 1, BoundNetLog());
3115
3116 ASSERT_TRUE(pool_->HasGroup("a"));
3117 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3118 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3119
3120 ClientSocketHandle handle1;
3121 TestCompletionCallback callback1;
3122 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3123 params_,
3124 kDefaultPriority,
3125 &callback1,
3126 pool_.get(),
3127 BoundNetLog()));
3128
3129 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3130 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3131
3132 ASSERT_EQ(OK, callback1.WaitForResult());
3133
3134 handle1.Reset();
3135
3136 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3137 }
3138
3139 // http://crbug.com/64940 regression test.
TEST_F(ClientSocketPoolBaseTest,PreconnectClosesIdleSocketRemovesGroup)3140 TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
3141 const int kMaxTotalSockets = 3;
3142 const int kMaxSocketsPerGroup = 2;
3143 CreatePool(kMaxTotalSockets, kMaxSocketsPerGroup);
3144 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3145
3146 // Note that group name ordering matters here. "a" comes before "b", so
3147 // CloseOneIdleSocket() will try to close "a"'s idle socket.
3148
3149 // Set up one idle socket in "a".
3150 ClientSocketHandle handle1;
3151 TestCompletionCallback callback1;
3152 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3153 params_,
3154 kDefaultPriority,
3155 &callback1,
3156 pool_.get(),
3157 BoundNetLog()));
3158
3159 ASSERT_EQ(OK, callback1.WaitForResult());
3160 handle1.Reset();
3161 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3162
3163 // Set up two active sockets in "b".
3164 ClientSocketHandle handle2;
3165 TestCompletionCallback callback2;
3166 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("b",
3167 params_,
3168 kDefaultPriority,
3169 &callback1,
3170 pool_.get(),
3171 BoundNetLog()));
3172 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("b",
3173 params_,
3174 kDefaultPriority,
3175 &callback2,
3176 pool_.get(),
3177 BoundNetLog()));
3178
3179 ASSERT_EQ(OK, callback1.WaitForResult());
3180 ASSERT_EQ(OK, callback2.WaitForResult());
3181 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3182 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3183
3184 // Now we have 1 idle socket in "a" and 2 active sockets in "b". This means
3185 // we've maxed out on sockets, since we set |kMaxTotalSockets| to 3.
3186 // Requesting 2 preconnected sockets for "a" should fail to allocate any more
3187 // sockets for "a", and "b" should still have 2 active sockets.
3188
3189 pool_->RequestSockets("a", ¶ms_, 2, BoundNetLog());
3190 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3191 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3192 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3193 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3194 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3195 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3196
3197 // Now release the 2 active sockets for "b". This will give us 1 idle socket
3198 // in "a" and 2 idle sockets in "b". Requesting 2 preconnected sockets for
3199 // "a" should result in closing 1 for "b".
3200 handle1.Reset();
3201 handle2.Reset();
3202 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("b"));
3203 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3204
3205 pool_->RequestSockets("a", ¶ms_, 2, BoundNetLog());
3206 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3207 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3208 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3209 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3210 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("b"));
3211 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3212 }
3213
3214 } // namespace
3215
3216 } // namespace net
3217