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 }
538
~ClientSocketPoolBaseTest()539 virtual ~ClientSocketPoolBaseTest() {
540 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
541 connect_backup_jobs_enabled_);
542 }
543
CreatePool(int max_sockets,int max_sockets_per_group)544 void CreatePool(int max_sockets, int max_sockets_per_group) {
545 CreatePoolWithIdleTimeouts(
546 max_sockets,
547 max_sockets_per_group,
548 base::TimeDelta::FromSeconds(
549 ClientSocketPool::unused_idle_socket_timeout()),
550 base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout));
551 }
552
CreatePoolWithIdleTimeouts(int max_sockets,int max_sockets_per_group,base::TimeDelta unused_idle_socket_timeout,base::TimeDelta used_idle_socket_timeout)553 void CreatePoolWithIdleTimeouts(
554 int max_sockets, int max_sockets_per_group,
555 base::TimeDelta unused_idle_socket_timeout,
556 base::TimeDelta used_idle_socket_timeout) {
557 DCHECK(!pool_.get());
558 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_);
559 pool_.reset(new TestClientSocketPool(max_sockets,
560 max_sockets_per_group,
561 &histograms_,
562 unused_idle_socket_timeout,
563 used_idle_socket_timeout,
564 connect_job_factory_));
565 }
566
StartRequest(const std::string & group_name,net::RequestPriority priority)567 int StartRequest(const std::string& group_name,
568 net::RequestPriority priority) {
569 return test_base_.StartRequestUsingPool<
570 TestClientSocketPool, TestSocketParams>(
571 pool_.get(), group_name, priority, params_);
572 }
573
GetOrderOfRequest(size_t index) const574 int GetOrderOfRequest(size_t index) const {
575 return test_base_.GetOrderOfRequest(index);
576 }
577
ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive)578 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
579 return test_base_.ReleaseOneConnection(keep_alive);
580 }
581
ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive)582 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
583 test_base_.ReleaseAllConnections(keep_alive);
584 }
585
request(int i)586 TestSocketRequest* request(int i) { return test_base_.request(i); }
requests_size() const587 size_t requests_size() const { return test_base_.requests_size(); }
requests()588 ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); }
completion_count() const589 size_t completion_count() const { return test_base_.completion_count(); }
590
591 bool connect_backup_jobs_enabled_;
592 MockClientSocketFactory client_socket_factory_;
593 TestConnectJobFactory* connect_job_factory_;
594 scoped_refptr<TestSocketParams> params_;
595 ClientSocketPoolHistograms histograms_;
596 scoped_ptr<TestClientSocketPool> pool_;
597 ClientSocketPoolTest test_base_;
598 };
599
600 // Even though a timeout is specified, it doesn't time out on a synchronous
601 // completion.
TEST_F(ClientSocketPoolBaseTest,ConnectJob_NoTimeoutOnSynchronousCompletion)602 TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
603 TestConnectJobDelegate delegate;
604 ClientSocketHandle ignored;
605 TestClientSocketPoolBase::Request request(
606 &ignored, NULL, kDefaultPriority,
607 internal::ClientSocketPoolBaseHelper::NORMAL,
608 false, params_, BoundNetLog());
609 scoped_ptr<TestConnectJob> job(
610 new TestConnectJob(TestConnectJob::kMockJob,
611 "a",
612 request,
613 base::TimeDelta::FromMicroseconds(1),
614 &delegate,
615 &client_socket_factory_,
616 NULL));
617 EXPECT_EQ(OK, job->Connect());
618 }
619
TEST_F(ClientSocketPoolBaseTest,ConnectJob_TimedOut)620 TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
621 TestConnectJobDelegate delegate;
622 ClientSocketHandle ignored;
623 CapturingNetLog log(CapturingNetLog::kUnbounded);
624
625 TestClientSocketPoolBase::Request request(
626 &ignored, NULL, kDefaultPriority,
627 internal::ClientSocketPoolBaseHelper::NORMAL,
628 false, params_, BoundNetLog());
629 // Deleted by TestConnectJobDelegate.
630 TestConnectJob* job =
631 new TestConnectJob(TestConnectJob::kMockPendingJob,
632 "a",
633 request,
634 base::TimeDelta::FromMicroseconds(1),
635 &delegate,
636 &client_socket_factory_,
637 &log);
638 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
639 base::PlatformThread::Sleep(1);
640 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
641
642 net::CapturingNetLog::EntryList entries;
643 log.GetEntries(&entries);
644
645 EXPECT_EQ(6u, entries.size());
646 EXPECT_TRUE(LogContainsBeginEvent(
647 entries, 0, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
648 EXPECT_TRUE(LogContainsBeginEvent(
649 entries, 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
650 EXPECT_TRUE(LogContainsEvent(
651 entries, 2, NetLog::TYPE_CONNECT_JOB_SET_SOCKET,
652 NetLog::PHASE_NONE));
653 EXPECT_TRUE(LogContainsEvent(
654 entries, 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
655 NetLog::PHASE_NONE));
656 EXPECT_TRUE(LogContainsEndEvent(
657 entries, 4, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
658 EXPECT_TRUE(LogContainsEndEvent(
659 entries, 5, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
660 }
661
TEST_F(ClientSocketPoolBaseTest,BasicSynchronous)662 TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
663 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
664
665 TestCompletionCallback callback;
666 ClientSocketHandle handle;
667 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
668
669 EXPECT_EQ(OK,
670 handle.Init("a",
671 params_,
672 kDefaultPriority,
673 &callback,
674 pool_.get(),
675 log.bound()));
676 EXPECT_TRUE(handle.is_initialized());
677 EXPECT_TRUE(handle.socket());
678 handle.Reset();
679
680 net::CapturingNetLog::EntryList entries;
681 log.GetEntries(&entries);
682
683 EXPECT_EQ(4u, entries.size());
684 EXPECT_TRUE(LogContainsBeginEvent(
685 entries, 0, NetLog::TYPE_SOCKET_POOL));
686 EXPECT_TRUE(LogContainsEvent(
687 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
688 NetLog::PHASE_NONE));
689 EXPECT_TRUE(LogContainsEvent(
690 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
691 NetLog::PHASE_NONE));
692 EXPECT_TRUE(LogContainsEndEvent(
693 entries, 3, NetLog::TYPE_SOCKET_POOL));
694 }
695
TEST_F(ClientSocketPoolBaseTest,InitConnectionFailure)696 TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
697 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
698
699 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
700 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
701
702 ClientSocketHandle handle;
703 TestCompletionCallback callback;
704 // Set the additional error state members to ensure that they get cleared.
705 handle.set_is_ssl_error(true);
706 HttpResponseInfo info;
707 info.headers = new HttpResponseHeaders("");
708 handle.set_ssl_error_response_info(info);
709 EXPECT_EQ(ERR_CONNECTION_FAILED,
710 handle.Init("a",
711 params_,
712 kDefaultPriority,
713 &callback,
714 pool_.get(),
715 log.bound()));
716 EXPECT_FALSE(handle.socket());
717 EXPECT_FALSE(handle.is_ssl_error());
718 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
719
720 net::CapturingNetLog::EntryList entries;
721 log.GetEntries(&entries);
722
723 EXPECT_EQ(3u, entries.size());
724 EXPECT_TRUE(LogContainsBeginEvent(
725 entries, 0, NetLog::TYPE_SOCKET_POOL));
726 EXPECT_TRUE(LogContainsEvent(
727 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
728 NetLog::PHASE_NONE));
729 EXPECT_TRUE(LogContainsEndEvent(
730 entries, 2, NetLog::TYPE_SOCKET_POOL));
731 }
732
TEST_F(ClientSocketPoolBaseTest,TotalLimit)733 TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
734 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
735
736 // TODO(eroman): Check that the NetLog contains this event.
737
738 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
739 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
740 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
741 EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
742
743 EXPECT_EQ(static_cast<int>(requests_size()),
744 client_socket_factory_.allocation_count());
745 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
746
747 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
748 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
749 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
750
751 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
752
753 EXPECT_EQ(static_cast<int>(requests_size()),
754 client_socket_factory_.allocation_count());
755 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
756
757 EXPECT_EQ(1, GetOrderOfRequest(1));
758 EXPECT_EQ(2, GetOrderOfRequest(2));
759 EXPECT_EQ(3, GetOrderOfRequest(3));
760 EXPECT_EQ(4, GetOrderOfRequest(4));
761 EXPECT_EQ(5, GetOrderOfRequest(5));
762 EXPECT_EQ(6, GetOrderOfRequest(6));
763 EXPECT_EQ(7, GetOrderOfRequest(7));
764
765 // Make sure we test order of all requests made.
766 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
767 }
768
TEST_F(ClientSocketPoolBaseTest,TotalLimitReachedNewGroup)769 TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
770 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
771
772 // TODO(eroman): Check that the NetLog contains this event.
773
774 // Reach all limits: max total sockets, and max sockets per group.
775 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
776 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
777 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
778 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
779
780 EXPECT_EQ(static_cast<int>(requests_size()),
781 client_socket_factory_.allocation_count());
782 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
783
784 // Now create a new group and verify that we don't starve it.
785 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
786
787 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
788
789 EXPECT_EQ(static_cast<int>(requests_size()),
790 client_socket_factory_.allocation_count());
791 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
792
793 EXPECT_EQ(1, GetOrderOfRequest(1));
794 EXPECT_EQ(2, GetOrderOfRequest(2));
795 EXPECT_EQ(3, GetOrderOfRequest(3));
796 EXPECT_EQ(4, GetOrderOfRequest(4));
797 EXPECT_EQ(5, GetOrderOfRequest(5));
798
799 // Make sure we test order of all requests made.
800 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
801 }
802
TEST_F(ClientSocketPoolBaseTest,TotalLimitRespectsPriority)803 TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
804 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
805
806 EXPECT_EQ(OK, StartRequest("b", LOWEST));
807 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
808 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
809 EXPECT_EQ(OK, StartRequest("a", LOWEST));
810
811 EXPECT_EQ(static_cast<int>(requests_size()),
812 client_socket_factory_.allocation_count());
813
814 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
815 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
816 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
817
818 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
819
820 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
821
822 // First 4 requests don't have to wait, and finish in order.
823 EXPECT_EQ(1, GetOrderOfRequest(1));
824 EXPECT_EQ(2, GetOrderOfRequest(2));
825 EXPECT_EQ(3, GetOrderOfRequest(3));
826 EXPECT_EQ(4, GetOrderOfRequest(4));
827
828 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
829 // and then ("c", LOWEST).
830 EXPECT_EQ(7, GetOrderOfRequest(5));
831 EXPECT_EQ(6, GetOrderOfRequest(6));
832 EXPECT_EQ(5, GetOrderOfRequest(7));
833
834 // Make sure we test order of all requests made.
835 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
836 }
837
TEST_F(ClientSocketPoolBaseTest,TotalLimitRespectsGroupLimit)838 TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
839 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
840
841 EXPECT_EQ(OK, StartRequest("a", LOWEST));
842 EXPECT_EQ(OK, StartRequest("a", LOW));
843 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
844 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
845
846 EXPECT_EQ(static_cast<int>(requests_size()),
847 client_socket_factory_.allocation_count());
848
849 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
850 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
851 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
852
853 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
854
855 EXPECT_EQ(static_cast<int>(requests_size()),
856 client_socket_factory_.allocation_count());
857 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
858
859 // First 4 requests don't have to wait, and finish in order.
860 EXPECT_EQ(1, GetOrderOfRequest(1));
861 EXPECT_EQ(2, GetOrderOfRequest(2));
862 EXPECT_EQ(3, GetOrderOfRequest(3));
863 EXPECT_EQ(4, GetOrderOfRequest(4));
864
865 // Request ("b", 7) has the highest priority, but we can't make new socket for
866 // group "b", because it has reached the per-group limit. Then we make
867 // socket for ("c", 6), because it has higher priority than ("a", 4),
868 // and we still can't make a socket for group "b".
869 EXPECT_EQ(5, GetOrderOfRequest(5));
870 EXPECT_EQ(6, GetOrderOfRequest(6));
871 EXPECT_EQ(7, GetOrderOfRequest(7));
872
873 // Make sure we test order of all requests made.
874 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
875 }
876
877 // Make sure that we count connecting sockets against the total limit.
TEST_F(ClientSocketPoolBaseTest,TotalLimitCountsConnectingSockets)878 TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
879 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
880
881 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
882 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
883 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
884
885 // Create one asynchronous request.
886 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
887 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
888
889 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
890 // actually become pending until 2ms after they have been created. In order
891 // to flush all tasks, we need to wait so that we know there are no
892 // soon-to-be-pending tasks waiting.
893 base::PlatformThread::Sleep(10);
894 MessageLoop::current()->RunAllPending();
895
896 // The next synchronous request should wait for its turn.
897 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
898 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
899
900 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
901
902 EXPECT_EQ(static_cast<int>(requests_size()),
903 client_socket_factory_.allocation_count());
904
905 EXPECT_EQ(1, GetOrderOfRequest(1));
906 EXPECT_EQ(2, GetOrderOfRequest(2));
907 EXPECT_EQ(3, GetOrderOfRequest(3));
908 EXPECT_EQ(4, GetOrderOfRequest(4));
909 EXPECT_EQ(5, GetOrderOfRequest(5));
910
911 // Make sure we test order of all requests made.
912 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
913 }
914
TEST_F(ClientSocketPoolBaseTest,CorrectlyCountStalledGroups)915 TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
916 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
917 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
918
919 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
920 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
921 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
922 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
923
924 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
925
926 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
927
928 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", kDefaultPriority));
929 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
930
931 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
932
933 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
934 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
935 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
936 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
937 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
938 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
939 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
940 }
941
TEST_F(ClientSocketPoolBaseTest,StallAndThenCancelAndTriggerAvailableSocket)942 TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
943 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
944 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
945
946 ClientSocketHandle handle;
947 TestCompletionCallback callback;
948 EXPECT_EQ(ERR_IO_PENDING,
949 handle.Init("a",
950 params_,
951 kDefaultPriority,
952 &callback,
953 pool_.get(),
954 BoundNetLog()));
955
956 ClientSocketHandle handles[4];
957 for (size_t i = 0; i < arraysize(handles); ++i) {
958 TestCompletionCallback callback;
959 EXPECT_EQ(ERR_IO_PENDING,
960 handles[i].Init("b",
961 params_,
962 kDefaultPriority,
963 &callback,
964 pool_.get(),
965 BoundNetLog()));
966 }
967
968 // One will be stalled, cancel all the handles now.
969 // This should hit the OnAvailableSocketSlot() code where we previously had
970 // stalled groups, but no longer have any.
971 for (size_t i = 0; i < arraysize(handles); ++i)
972 handles[i].Reset();
973 }
974
TEST_F(ClientSocketPoolBaseTest,CancelStalledSocketAtSocketLimit)975 TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
976 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
977 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
978
979 {
980 ClientSocketHandle handles[kDefaultMaxSockets];
981 TestCompletionCallback callbacks[kDefaultMaxSockets];
982 for (int i = 0; i < kDefaultMaxSockets; ++i) {
983 EXPECT_EQ(OK, handles[i].Init(base::IntToString(i),
984 params_,
985 kDefaultPriority,
986 &callbacks[i],
987 pool_.get(),
988 BoundNetLog()));
989 }
990
991 // Force a stalled group.
992 ClientSocketHandle stalled_handle;
993 TestCompletionCallback callback;
994 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
995 params_,
996 kDefaultPriority,
997 &callback,
998 pool_.get(),
999 BoundNetLog()));
1000
1001 // Cancel the stalled request.
1002 stalled_handle.Reset();
1003
1004 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1005 EXPECT_EQ(0, pool_->IdleSocketCount());
1006
1007 // Dropping out of scope will close all handles and return them to idle.
1008 }
1009
1010 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1011 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
1012 }
1013
TEST_F(ClientSocketPoolBaseTest,CancelPendingSocketAtSocketLimit)1014 TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
1015 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1016 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1017
1018 {
1019 ClientSocketHandle handles[kDefaultMaxSockets];
1020 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1021 TestCompletionCallback callback;
1022 EXPECT_EQ(ERR_IO_PENDING, handles[i].Init(base::IntToString(i),
1023 params_,
1024 kDefaultPriority,
1025 &callback,
1026 pool_.get(),
1027 BoundNetLog()));
1028 }
1029
1030 // Force a stalled group.
1031 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1032 ClientSocketHandle stalled_handle;
1033 TestCompletionCallback callback;
1034 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1035 params_,
1036 kDefaultPriority,
1037 &callback,
1038 pool_.get(),
1039 BoundNetLog()));
1040
1041 // Since it is stalled, it should have no connect jobs.
1042 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
1043
1044 // Cancel the stalled request.
1045 handles[0].Reset();
1046
1047 // Now we should have a connect job.
1048 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("foo"));
1049
1050 // The stalled socket should connect.
1051 EXPECT_EQ(OK, callback.WaitForResult());
1052
1053 EXPECT_EQ(kDefaultMaxSockets + 1,
1054 client_socket_factory_.allocation_count());
1055 EXPECT_EQ(0, pool_->IdleSocketCount());
1056 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
1057
1058 // Dropping out of scope will close all handles and return them to idle.
1059 }
1060
1061 EXPECT_EQ(1, pool_->IdleSocketCount());
1062 }
1063
TEST_F(ClientSocketPoolBaseTest,WaitForStalledSocketAtSocketLimit)1064 TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1065 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1066 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1067
1068 ClientSocketHandle stalled_handle;
1069 TestCompletionCallback callback;
1070 {
1071 ClientSocketHandle handles[kDefaultMaxSockets];
1072 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1073 TestCompletionCallback callback;
1074 EXPECT_EQ(OK, handles[i].Init(base::StringPrintf("Take 2: %d", i),
1075 params_,
1076 kDefaultPriority,
1077 &callback,
1078 pool_.get(),
1079 BoundNetLog()));
1080 }
1081
1082 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1083 EXPECT_EQ(0, pool_->IdleSocketCount());
1084
1085 // Now we will hit the socket limit.
1086 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1087 params_,
1088 kDefaultPriority,
1089 &callback,
1090 pool_.get(),
1091 BoundNetLog()));
1092
1093 // Dropping out of scope will close all handles and return them to idle.
1094 }
1095
1096 // But if we wait for it, the released idle sockets will be closed in
1097 // preference of the waiting request.
1098 EXPECT_EQ(OK, callback.WaitForResult());
1099
1100 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1101 EXPECT_EQ(3, pool_->IdleSocketCount());
1102 }
1103
1104 // Regression test for http://crbug.com/40952.
TEST_F(ClientSocketPoolBaseTest,CloseIdleSocketAtSocketLimitDeleteGroup)1105 TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1106 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1107 pool_->EnableConnectBackupJobs();
1108 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1109
1110 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1111 ClientSocketHandle handle;
1112 TestCompletionCallback callback;
1113 EXPECT_EQ(OK, handle.Init(base::IntToString(i),
1114 params_,
1115 kDefaultPriority,
1116 &callback,
1117 pool_.get(),
1118 BoundNetLog()));
1119 }
1120
1121 // Flush all the DoReleaseSocket tasks.
1122 MessageLoop::current()->RunAllPending();
1123
1124 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1125 // reuse a socket.
1126 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1127 ClientSocketHandle handle;
1128 TestCompletionCallback callback;
1129
1130 // "0" is special here, since it should be the first entry in the sorted map,
1131 // which is the one which we would close an idle socket for. We shouldn't
1132 // close an idle socket though, since we should reuse the idle socket.
1133 EXPECT_EQ(OK, handle.Init("0",
1134 params_,
1135 kDefaultPriority,
1136 &callback,
1137 pool_.get(),
1138 BoundNetLog()));
1139
1140 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1141 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1142 }
1143
TEST_F(ClientSocketPoolBaseTest,PendingRequests)1144 TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
1145 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1146
1147 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1148 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1149 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", IDLE));
1150 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1151 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1152 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1153 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1154 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1155
1156 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
1157
1158 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1159 client_socket_factory_.allocation_count());
1160 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1161 completion_count());
1162
1163 EXPECT_EQ(1, GetOrderOfRequest(1));
1164 EXPECT_EQ(2, GetOrderOfRequest(2));
1165 EXPECT_EQ(8, GetOrderOfRequest(3));
1166 EXPECT_EQ(6, GetOrderOfRequest(4));
1167 EXPECT_EQ(4, GetOrderOfRequest(5));
1168 EXPECT_EQ(3, GetOrderOfRequest(6));
1169 EXPECT_EQ(5, GetOrderOfRequest(7));
1170 EXPECT_EQ(7, GetOrderOfRequest(8));
1171
1172 // Make sure we test order of all requests made.
1173 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
1174 }
1175
TEST_F(ClientSocketPoolBaseTest,PendingRequests_NoKeepAlive)1176 TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
1177 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1178
1179 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1180 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1181 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1182 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1183 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1184 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1185 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1186
1187 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1188
1189 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
1190 EXPECT_EQ(OK, request(i)->WaitForResult());
1191
1192 EXPECT_EQ(static_cast<int>(requests_size()),
1193 client_socket_factory_.allocation_count());
1194 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1195 completion_count());
1196 }
1197
1198 // This test will start up a RequestSocket() and then immediately Cancel() it.
1199 // The pending connect job will be cancelled and should not call back into
1200 // ClientSocketPoolBase.
TEST_F(ClientSocketPoolBaseTest,CancelRequestClearGroup)1201 TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
1202 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1203
1204 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1205 ClientSocketHandle handle;
1206 TestCompletionCallback callback;
1207 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1208 params_,
1209 kDefaultPriority,
1210 &callback,
1211 pool_.get(),
1212 BoundNetLog()));
1213 handle.Reset();
1214 }
1215
TEST_F(ClientSocketPoolBaseTest,ConnectCancelConnect)1216 TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
1217 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1218
1219 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1220 ClientSocketHandle handle;
1221 TestCompletionCallback callback;
1222
1223 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1224 params_,
1225 kDefaultPriority,
1226 &callback,
1227 pool_.get(),
1228 BoundNetLog()));
1229
1230 handle.Reset();
1231
1232 TestCompletionCallback callback2;
1233 EXPECT_EQ(ERR_IO_PENDING,
1234 handle.Init("a",
1235 params_,
1236 kDefaultPriority,
1237 &callback2,
1238 pool_.get(),
1239 BoundNetLog()));
1240
1241 EXPECT_EQ(OK, callback2.WaitForResult());
1242 EXPECT_FALSE(callback.have_result());
1243
1244 handle.Reset();
1245 }
1246
TEST_F(ClientSocketPoolBaseTest,CancelRequest)1247 TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
1248 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1249
1250 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1251 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1252 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1253 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1254 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1255 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1256 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1257
1258 // Cancel a request.
1259 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
1260 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1261 (*requests())[index_to_cancel]->handle()->Reset();
1262
1263 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
1264
1265 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1266 client_socket_factory_.allocation_count());
1267 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1268 completion_count());
1269
1270 EXPECT_EQ(1, GetOrderOfRequest(1));
1271 EXPECT_EQ(2, GetOrderOfRequest(2));
1272 EXPECT_EQ(5, GetOrderOfRequest(3));
1273 EXPECT_EQ(3, GetOrderOfRequest(4));
1274 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1275 GetOrderOfRequest(5)); // Canceled request.
1276 EXPECT_EQ(4, GetOrderOfRequest(6));
1277 EXPECT_EQ(6, GetOrderOfRequest(7));
1278
1279 // Make sure we test order of all requests made.
1280 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
1281 }
1282
1283 class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
1284 public:
RequestSocketCallback(ClientSocketHandle * handle,TestClientSocketPool * pool,TestConnectJobFactory * test_connect_job_factory,TestConnectJob::JobType next_job_type)1285 RequestSocketCallback(ClientSocketHandle* handle,
1286 TestClientSocketPool* pool,
1287 TestConnectJobFactory* test_connect_job_factory,
1288 TestConnectJob::JobType next_job_type)
1289 : handle_(handle),
1290 pool_(pool),
1291 within_callback_(false),
1292 test_connect_job_factory_(test_connect_job_factory),
1293 next_job_type_(next_job_type) {}
1294
RunWithParams(const Tuple1<int> & params)1295 virtual void RunWithParams(const Tuple1<int>& params) {
1296 callback_.RunWithParams(params);
1297 ASSERT_EQ(OK, params.a);
1298
1299 if (!within_callback_) {
1300 test_connect_job_factory_->set_job_type(next_job_type_);
1301
1302 // Don't allow reuse of the socket. Disconnect it and then release it and
1303 // run through the MessageLoop once to get it completely released.
1304 handle_->socket()->Disconnect();
1305 handle_->Reset();
1306 {
1307 MessageLoop::ScopedNestableTaskAllower nestable(
1308 MessageLoop::current());
1309 MessageLoop::current()->RunAllPending();
1310 }
1311 within_callback_ = true;
1312 TestCompletionCallback next_job_callback;
1313 scoped_refptr<TestSocketParams> params(new TestSocketParams());
1314 int rv = handle_->Init("a",
1315 params,
1316 kDefaultPriority,
1317 &next_job_callback,
1318 pool_,
1319 BoundNetLog());
1320 switch (next_job_type_) {
1321 case TestConnectJob::kMockJob:
1322 EXPECT_EQ(OK, rv);
1323 break;
1324 case TestConnectJob::kMockPendingJob:
1325 EXPECT_EQ(ERR_IO_PENDING, rv);
1326
1327 // For pending jobs, wait for new socket to be created. This makes
1328 // sure there are no more pending operations nor any unclosed sockets
1329 // when the test finishes.
1330 // We need to give it a little bit of time to run, so that all the
1331 // operations that happen on timers (e.g. cleanup of idle
1332 // connections) can execute.
1333 {
1334 MessageLoop::ScopedNestableTaskAllower nestable(
1335 MessageLoop::current());
1336 base::PlatformThread::Sleep(10);
1337 EXPECT_EQ(OK, next_job_callback.WaitForResult());
1338 }
1339 break;
1340 default:
1341 FAIL() << "Unexpected job type: " << next_job_type_;
1342 break;
1343 }
1344 }
1345 }
1346
WaitForResult()1347 int WaitForResult() {
1348 return callback_.WaitForResult();
1349 }
1350
1351 private:
1352 ClientSocketHandle* const handle_;
1353 TestClientSocketPool* const pool_;
1354 bool within_callback_;
1355 TestConnectJobFactory* const test_connect_job_factory_;
1356 TestConnectJob::JobType next_job_type_;
1357 TestCompletionCallback callback_;
1358 };
1359
TEST_F(ClientSocketPoolBaseTest,RequestPendingJobTwice)1360 TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
1361 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1362
1363 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1364 ClientSocketHandle handle;
1365 RequestSocketCallback callback(
1366 &handle, pool_.get(), connect_job_factory_,
1367 TestConnectJob::kMockPendingJob);
1368 int rv = handle.Init("a",
1369 params_,
1370 kDefaultPriority,
1371 &callback,
1372 pool_.get(),
1373 BoundNetLog());
1374 ASSERT_EQ(ERR_IO_PENDING, rv);
1375
1376 EXPECT_EQ(OK, callback.WaitForResult());
1377 }
1378
TEST_F(ClientSocketPoolBaseTest,RequestPendingJobThenSynchronous)1379 TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
1380 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1381
1382 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1383 ClientSocketHandle handle;
1384 RequestSocketCallback callback(
1385 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
1386 int rv = handle.Init("a",
1387 params_,
1388 kDefaultPriority,
1389 &callback,
1390 pool_.get(),
1391 BoundNetLog());
1392 ASSERT_EQ(ERR_IO_PENDING, rv);
1393
1394 EXPECT_EQ(OK, callback.WaitForResult());
1395 }
1396
1397 // Make sure that pending requests get serviced after active requests get
1398 // cancelled.
TEST_F(ClientSocketPoolBaseTest,CancelActiveRequestWithPendingRequests)1399 TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
1400 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1401
1402 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1403
1404 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1405 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1406 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1407 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1408 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1409 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1410 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1411
1412 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1413 // Let's cancel them.
1414 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
1415 ASSERT_FALSE(request(i)->handle()->is_initialized());
1416 request(i)->handle()->Reset();
1417 }
1418
1419 // Let's wait for the rest to complete now.
1420 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
1421 EXPECT_EQ(OK, request(i)->WaitForResult());
1422 request(i)->handle()->Reset();
1423 }
1424
1425 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1426 completion_count());
1427 }
1428
1429 // Make sure that pending requests get serviced after active requests fail.
TEST_F(ClientSocketPoolBaseTest,FailingActiveRequestWithPendingRequests)1430 TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
1431 const size_t kMaxSockets = 5;
1432 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
1433
1434 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1435
1436 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1437 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
1438
1439 // Queue up all the requests
1440 for (size_t i = 0; i < kNumberOfRequests; ++i)
1441 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1442
1443 for (size_t i = 0; i < kNumberOfRequests; ++i)
1444 EXPECT_EQ(ERR_CONNECTION_FAILED, request(i)->WaitForResult());
1445 }
1446
TEST_F(ClientSocketPoolBaseTest,CancelActiveRequestThenRequestSocket)1447 TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
1448 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1449
1450 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1451
1452 ClientSocketHandle handle;
1453 TestCompletionCallback callback;
1454 int rv = handle.Init("a",
1455 params_,
1456 kDefaultPriority,
1457 &callback,
1458 pool_.get(),
1459 BoundNetLog());
1460 EXPECT_EQ(ERR_IO_PENDING, rv);
1461
1462 // Cancel the active request.
1463 handle.Reset();
1464
1465 rv = handle.Init("a",
1466 params_,
1467 kDefaultPriority,
1468 &callback,
1469 pool_.get(),
1470 BoundNetLog());
1471 EXPECT_EQ(ERR_IO_PENDING, rv);
1472 EXPECT_EQ(OK, callback.WaitForResult());
1473
1474 EXPECT_FALSE(handle.is_reused());
1475 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1476 }
1477
1478 // Regression test for http://crbug.com/17985.
TEST_F(ClientSocketPoolBaseTest,GroupWithPendingRequestsIsNotEmpty)1479 TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1480 const int kMaxSockets = 3;
1481 const int kMaxSocketsPerGroup = 2;
1482 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1483
1484 const RequestPriority kHighPriority = HIGHEST;
1485
1486 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1487 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1488
1489 // This is going to be a pending request in an otherwise empty group.
1490 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1491
1492 // Reach the maximum socket limit.
1493 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1494
1495 // Create a stalled group with high priorities.
1496 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1497 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1498
1499 // Release the first two sockets from "a". Because this is a keepalive,
1500 // the first release will unblock the pending request for "a". The
1501 // second release will unblock a request for "c", becaue it is the next
1502 // high priority socket.
1503 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1504 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1505
1506 // Closing idle sockets should not get us into trouble, but in the bug
1507 // we were hitting a CHECK here.
1508 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1509 pool_->CloseIdleSockets();
1510
1511 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
1512 }
1513
TEST_F(ClientSocketPoolBaseTest,BasicAsynchronous)1514 TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
1515 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1516
1517 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1518 ClientSocketHandle handle;
1519 TestCompletionCallback callback;
1520 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
1521 int rv = handle.Init("a",
1522 params_,
1523 LOWEST,
1524 &callback,
1525 pool_.get(),
1526 log.bound());
1527 EXPECT_EQ(ERR_IO_PENDING, rv);
1528 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1529 EXPECT_EQ(OK, callback.WaitForResult());
1530 EXPECT_TRUE(handle.is_initialized());
1531 EXPECT_TRUE(handle.socket());
1532 handle.Reset();
1533
1534 net::CapturingNetLog::EntryList entries;
1535 log.GetEntries(&entries);
1536
1537 EXPECT_EQ(4u, entries.size());
1538 EXPECT_TRUE(LogContainsBeginEvent(
1539 entries, 0, NetLog::TYPE_SOCKET_POOL));
1540 EXPECT_TRUE(LogContainsEvent(
1541 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1542 NetLog::PHASE_NONE));
1543 EXPECT_TRUE(LogContainsEvent(
1544 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
1545 NetLog::PHASE_NONE));
1546 EXPECT_TRUE(LogContainsEndEvent(
1547 entries, 3, NetLog::TYPE_SOCKET_POOL));
1548 }
1549
TEST_F(ClientSocketPoolBaseTest,InitConnectionAsynchronousFailure)1550 TEST_F(ClientSocketPoolBaseTest,
1551 InitConnectionAsynchronousFailure) {
1552 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1553
1554 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1555 ClientSocketHandle handle;
1556 TestCompletionCallback callback;
1557 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
1558 // Set the additional error state members to ensure that they get cleared.
1559 handle.set_is_ssl_error(true);
1560 HttpResponseInfo info;
1561 info.headers = new HttpResponseHeaders("");
1562 handle.set_ssl_error_response_info(info);
1563 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1564 params_,
1565 kDefaultPriority,
1566 &callback,
1567 pool_.get(),
1568 log.bound()));
1569 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1570 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1571 EXPECT_FALSE(handle.is_ssl_error());
1572 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
1573
1574 net::CapturingNetLog::EntryList entries;
1575 log.GetEntries(&entries);
1576
1577 EXPECT_EQ(3u, entries.size());
1578 EXPECT_TRUE(LogContainsBeginEvent(
1579 entries, 0, NetLog::TYPE_SOCKET_POOL));
1580 EXPECT_TRUE(LogContainsEvent(
1581 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1582 NetLog::PHASE_NONE));
1583 EXPECT_TRUE(LogContainsEndEvent(
1584 entries, 2, NetLog::TYPE_SOCKET_POOL));
1585 }
1586
TEST_F(ClientSocketPoolBaseTest,TwoRequestsCancelOne)1587 TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
1588 // TODO(eroman): Add back the log expectations! Removed them because the
1589 // ordering is difficult, and some may fire during destructor.
1590 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1591
1592 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1593 ClientSocketHandle handle;
1594 TestCompletionCallback callback;
1595 ClientSocketHandle handle2;
1596 TestCompletionCallback callback2;
1597
1598 EXPECT_EQ(ERR_IO_PENDING,
1599 handle.Init("a",
1600 params_,
1601 kDefaultPriority,
1602 &callback,
1603 pool_.get(),
1604 BoundNetLog()));
1605 CapturingBoundNetLog log2(CapturingNetLog::kUnbounded);
1606 EXPECT_EQ(ERR_IO_PENDING,
1607 handle2.Init("a",
1608 params_,
1609 kDefaultPriority,
1610 &callback2,
1611 pool_.get(),
1612 BoundNetLog()));
1613
1614 handle.Reset();
1615
1616
1617 // At this point, request 2 is just waiting for the connect job to finish.
1618
1619 EXPECT_EQ(OK, callback2.WaitForResult());
1620 handle2.Reset();
1621
1622 // Now request 2 has actually finished.
1623 // TODO(eroman): Add back log expectations.
1624 }
1625
TEST_F(ClientSocketPoolBaseTest,CancelRequestLimitsJobs)1626 TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
1627 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1628
1629 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1630
1631 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1632 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1633 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1634 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1635
1636 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1637 (*requests())[2]->handle()->Reset();
1638 (*requests())[3]->handle()->Reset();
1639 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1640
1641 (*requests())[1]->handle()->Reset();
1642 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1643
1644 (*requests())[0]->handle()->Reset();
1645 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1646 }
1647
1648 // When requests and ConnectJobs are not coupled, the request will get serviced
1649 // by whatever comes first.
TEST_F(ClientSocketPoolBaseTest,ReleaseSockets)1650 TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
1651 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1652
1653 // Start job 1 (async OK)
1654 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1655
1656 std::vector<TestSocketRequest*> request_order;
1657 size_t completion_count; // unused
1658 TestSocketRequest req1(&request_order, &completion_count);
1659 int rv = req1.handle()->Init("a",
1660 params_,
1661 kDefaultPriority,
1662 &req1, pool_.get(),
1663 BoundNetLog());
1664 EXPECT_EQ(ERR_IO_PENDING, rv);
1665 EXPECT_EQ(OK, req1.WaitForResult());
1666
1667 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1668 // without a job.
1669 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1670
1671 TestSocketRequest req2(&request_order, &completion_count);
1672 rv = req2.handle()->Init("a",
1673 params_,
1674 kDefaultPriority,
1675 &req2,
1676 pool_.get(),
1677 BoundNetLog());
1678 EXPECT_EQ(ERR_IO_PENDING, rv);
1679 TestSocketRequest req3(&request_order, &completion_count);
1680 rv = req3.handle()->Init("a",
1681 params_,
1682 kDefaultPriority,
1683 &req3,
1684 pool_.get(),
1685 BoundNetLog());
1686 EXPECT_EQ(ERR_IO_PENDING, rv);
1687
1688 // Both Requests 2 and 3 are pending. We release socket 1 which should
1689 // service request 2. Request 3 should still be waiting.
1690 req1.handle()->Reset();
1691 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
1692 ASSERT_TRUE(req2.handle()->socket());
1693 EXPECT_EQ(OK, req2.WaitForResult());
1694 EXPECT_FALSE(req3.handle()->socket());
1695
1696 // Signal job 2, which should service request 3.
1697
1698 client_socket_factory_.SignalJobs();
1699 EXPECT_EQ(OK, req3.WaitForResult());
1700
1701 ASSERT_EQ(3U, request_order.size());
1702 EXPECT_EQ(&req1, request_order[0]);
1703 EXPECT_EQ(&req2, request_order[1]);
1704 EXPECT_EQ(&req3, request_order[2]);
1705 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1706 }
1707
1708 // The requests are not coupled to the jobs. So, the requests should finish in
1709 // their priority / insertion order.
TEST_F(ClientSocketPoolBaseTest,PendingJobCompletionOrder)1710 TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
1711 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1712 // First two jobs are async.
1713 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1714
1715 std::vector<TestSocketRequest*> request_order;
1716 size_t completion_count; // unused
1717 TestSocketRequest req1(&request_order, &completion_count);
1718 int rv = req1.handle()->Init("a",
1719 params_,
1720 kDefaultPriority,
1721 &req1,
1722 pool_.get(),
1723 BoundNetLog());
1724 EXPECT_EQ(ERR_IO_PENDING, rv);
1725
1726 TestSocketRequest req2(&request_order, &completion_count);
1727 rv = req2.handle()->Init("a",
1728 params_,
1729 kDefaultPriority,
1730 &req2,
1731 pool_.get(),
1732 BoundNetLog());
1733 EXPECT_EQ(ERR_IO_PENDING, rv);
1734
1735 // The pending job is sync.
1736 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1737
1738 TestSocketRequest req3(&request_order, &completion_count);
1739 rv = req3.handle()->Init("a",
1740 params_,
1741 kDefaultPriority,
1742 &req3,
1743 pool_.get(),
1744 BoundNetLog());
1745 EXPECT_EQ(ERR_IO_PENDING, rv);
1746
1747 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1748 EXPECT_EQ(OK, req2.WaitForResult());
1749 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1750
1751 ASSERT_EQ(3U, request_order.size());
1752 EXPECT_EQ(&req1, request_order[0]);
1753 EXPECT_EQ(&req2, request_order[1]);
1754 EXPECT_EQ(&req3, request_order[2]);
1755 }
1756
TEST_F(ClientSocketPoolBaseTest,LoadState)1757 TEST_F(ClientSocketPoolBaseTest, LoadState) {
1758 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1759 connect_job_factory_->set_job_type(
1760 TestConnectJob::kMockAdvancingLoadStateJob);
1761
1762 ClientSocketHandle handle;
1763 TestCompletionCallback callback;
1764 int rv = handle.Init("a",
1765 params_,
1766 kDefaultPriority,
1767 &callback,
1768 pool_.get(),
1769 BoundNetLog());
1770 EXPECT_EQ(ERR_IO_PENDING, rv);
1771 EXPECT_EQ(LOAD_STATE_IDLE, handle.GetLoadState());
1772
1773 MessageLoop::current()->RunAllPending();
1774
1775 ClientSocketHandle handle2;
1776 TestCompletionCallback callback2;
1777 rv = handle2.Init("a",
1778 params_,
1779 kDefaultPriority,
1780 &callback2, pool_.get(),
1781 BoundNetLog());
1782 EXPECT_EQ(ERR_IO_PENDING, rv);
1783 EXPECT_NE(LOAD_STATE_IDLE, handle.GetLoadState());
1784 EXPECT_NE(LOAD_STATE_IDLE, handle2.GetLoadState());
1785 }
1786
TEST_F(ClientSocketPoolBaseTest,Recoverable)1787 TEST_F(ClientSocketPoolBaseTest, Recoverable) {
1788 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1789 connect_job_factory_->set_job_type(TestConnectJob::kMockRecoverableJob);
1790
1791 ClientSocketHandle handle;
1792 TestCompletionCallback callback;
1793 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, handle.Init("a",
1794 params_,
1795 kDefaultPriority,
1796 &callback, pool_.get(),
1797 BoundNetLog()));
1798 EXPECT_TRUE(handle.is_initialized());
1799 EXPECT_TRUE(handle.socket());
1800 }
1801
TEST_F(ClientSocketPoolBaseTest,AsyncRecoverable)1802 TEST_F(ClientSocketPoolBaseTest, AsyncRecoverable) {
1803 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1804
1805 connect_job_factory_->set_job_type(
1806 TestConnectJob::kMockPendingRecoverableJob);
1807 ClientSocketHandle handle;
1808 TestCompletionCallback callback;
1809 EXPECT_EQ(ERR_IO_PENDING,
1810 handle.Init("a",
1811 params_,
1812 kDefaultPriority,
1813 &callback,
1814 pool_.get(),
1815 BoundNetLog()));
1816 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1817 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, callback.WaitForResult());
1818 EXPECT_TRUE(handle.is_initialized());
1819 EXPECT_TRUE(handle.socket());
1820 }
1821
TEST_F(ClientSocketPoolBaseTest,AdditionalErrorStateSynchronous)1822 TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
1823 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1824 connect_job_factory_->set_job_type(
1825 TestConnectJob::kMockAdditionalErrorStateJob);
1826
1827 ClientSocketHandle handle;
1828 TestCompletionCallback callback;
1829 EXPECT_EQ(ERR_CONNECTION_FAILED,
1830 handle.Init("a",
1831 params_,
1832 kDefaultPriority,
1833 &callback,
1834 pool_.get(),
1835 BoundNetLog()));
1836 EXPECT_FALSE(handle.is_initialized());
1837 EXPECT_FALSE(handle.socket());
1838 EXPECT_TRUE(handle.is_ssl_error());
1839 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
1840 }
1841
TEST_F(ClientSocketPoolBaseTest,AdditionalErrorStateAsynchronous)1842 TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
1843 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1844
1845 connect_job_factory_->set_job_type(
1846 TestConnectJob::kMockPendingAdditionalErrorStateJob);
1847 ClientSocketHandle handle;
1848 TestCompletionCallback callback;
1849 EXPECT_EQ(ERR_IO_PENDING,
1850 handle.Init("a",
1851 params_,
1852 kDefaultPriority,
1853 &callback,
1854 pool_.get(),
1855 BoundNetLog()));
1856 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1857 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1858 EXPECT_FALSE(handle.is_initialized());
1859 EXPECT_FALSE(handle.socket());
1860 EXPECT_TRUE(handle.is_ssl_error());
1861 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
1862 }
1863
TEST_F(ClientSocketPoolBaseTest,CleanupTimedOutIdleSockets)1864 TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
1865 CreatePoolWithIdleTimeouts(
1866 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1867 base::TimeDelta(), // Time out unused sockets immediately.
1868 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1869
1870 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1871
1872 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
1873
1874 ClientSocketHandle handle;
1875 TestCompletionCallback callback;
1876 int rv = handle.Init("a",
1877 params_,
1878 LOWEST,
1879 &callback,
1880 pool_.get(),
1881 BoundNetLog());
1882 EXPECT_EQ(ERR_IO_PENDING, rv);
1883 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1884
1885 ClientSocketHandle handle2;
1886 TestCompletionCallback callback2;
1887 rv = handle2.Init("a",
1888 params_,
1889 LOWEST,
1890 &callback2,
1891 pool_.get(),
1892 BoundNetLog());
1893 EXPECT_EQ(ERR_IO_PENDING, rv);
1894 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
1895
1896 // Cancel one of the requests. Wait for the other, which will get the first
1897 // job. Release the socket. Run the loop again to make sure the second
1898 // socket is sitting idle and the first one is released (since ReleaseSocket()
1899 // just posts a DoReleaseSocket() task).
1900
1901 handle.Reset();
1902 EXPECT_EQ(OK, callback2.WaitForResult());
1903 // Use the socket.
1904 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, NULL));
1905 handle2.Reset();
1906
1907 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1908 // actually become pending until 2ms after they have been created. In order
1909 // to flush all tasks, we need to wait so that we know there are no
1910 // soon-to-be-pending tasks waiting.
1911 base::PlatformThread::Sleep(10);
1912 MessageLoop::current()->RunAllPending();
1913
1914 ASSERT_EQ(2, pool_->IdleSocketCount());
1915
1916 // Invoke the idle socket cleanup check. Only one socket should be left, the
1917 // used socket. Request it to make sure that it's used.
1918
1919 pool_->CleanupTimedOutIdleSockets();
1920 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
1921 rv = handle.Init("a",
1922 params_,
1923 LOWEST,
1924 &callback,
1925 pool_.get(),
1926 log.bound());
1927 EXPECT_EQ(OK, rv);
1928 EXPECT_TRUE(handle.is_reused());
1929
1930 net::CapturingNetLog::EntryList entries;
1931 log.GetEntries(&entries);
1932 EXPECT_TRUE(LogContainsEntryWithType(
1933 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
1934 }
1935
1936 // Make sure that we process all pending requests even when we're stalling
1937 // because of multiple releasing disconnected sockets.
TEST_F(ClientSocketPoolBaseTest,MultipleReleasingDisconnectedSockets)1938 TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
1939 CreatePoolWithIdleTimeouts(
1940 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1941 base::TimeDelta(), // Time out unused sockets immediately.
1942 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1943
1944 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1945
1946 // Startup 4 connect jobs. Two of them will be pending.
1947
1948 ClientSocketHandle handle;
1949 TestCompletionCallback callback;
1950 int rv = handle.Init("a",
1951 params_,
1952 LOWEST,
1953 &callback,
1954 pool_.get(),
1955 BoundNetLog());
1956 EXPECT_EQ(OK, rv);
1957
1958 ClientSocketHandle handle2;
1959 TestCompletionCallback callback2;
1960 rv = handle2.Init("a",
1961 params_,
1962 LOWEST,
1963 &callback2,
1964 pool_.get(),
1965 BoundNetLog());
1966 EXPECT_EQ(OK, rv);
1967
1968 ClientSocketHandle handle3;
1969 TestCompletionCallback callback3;
1970 rv = handle3.Init("a",
1971 params_,
1972 LOWEST,
1973 &callback3,
1974 pool_.get(),
1975 BoundNetLog());
1976 EXPECT_EQ(ERR_IO_PENDING, rv);
1977
1978 ClientSocketHandle handle4;
1979 TestCompletionCallback callback4;
1980 rv = handle4.Init("a",
1981 params_,
1982 LOWEST,
1983 &callback4,
1984 pool_.get(),
1985 BoundNetLog());
1986 EXPECT_EQ(ERR_IO_PENDING, rv);
1987
1988 // Release two disconnected sockets.
1989
1990 handle.socket()->Disconnect();
1991 handle.Reset();
1992 handle2.socket()->Disconnect();
1993 handle2.Reset();
1994
1995 EXPECT_EQ(OK, callback3.WaitForResult());
1996 EXPECT_FALSE(handle3.is_reused());
1997 EXPECT_EQ(OK, callback4.WaitForResult());
1998 EXPECT_FALSE(handle4.is_reused());
1999 }
2000
2001 // Regression test for http://crbug.com/42267.
2002 // When DoReleaseSocket() is processed for one socket, it is blocked because the
2003 // other stalled groups all have releasing sockets, so no progress can be made.
TEST_F(ClientSocketPoolBaseTest,SocketLimitReleasingSockets)2004 TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
2005 CreatePoolWithIdleTimeouts(
2006 4 /* socket limit */, 4 /* socket limit per group */,
2007 base::TimeDelta(), // Time out unused sockets immediately.
2008 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2009
2010 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2011
2012 // Max out the socket limit with 2 per group.
2013
2014 ClientSocketHandle handle_a[4];
2015 TestCompletionCallback callback_a[4];
2016 ClientSocketHandle handle_b[4];
2017 TestCompletionCallback callback_b[4];
2018
2019 for (int i = 0; i < 2; ++i) {
2020 EXPECT_EQ(OK, handle_a[i].Init("a",
2021 params_,
2022 LOWEST,
2023 &callback_a[i],
2024 pool_.get(),
2025 BoundNetLog()));
2026 EXPECT_EQ(OK, handle_b[i].Init("b",
2027 params_,
2028 LOWEST,
2029 &callback_b[i],
2030 pool_.get(),
2031 BoundNetLog()));
2032 }
2033
2034 // Make 4 pending requests, 2 per group.
2035
2036 for (int i = 2; i < 4; ++i) {
2037 EXPECT_EQ(ERR_IO_PENDING,
2038 handle_a[i].Init("a",
2039 params_,
2040 LOWEST,
2041 &callback_a[i],
2042 pool_.get(),
2043 BoundNetLog()));
2044 EXPECT_EQ(ERR_IO_PENDING,
2045 handle_b[i].Init("b",
2046 params_,
2047 LOWEST,
2048 &callback_b[i],
2049 pool_.get(),
2050 BoundNetLog()));
2051 }
2052
2053 // Release b's socket first. The order is important, because in
2054 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2055 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2056 // first, which has a releasing socket, so it refuses to start up another
2057 // ConnectJob. So, we used to infinite loop on this.
2058 handle_b[0].socket()->Disconnect();
2059 handle_b[0].Reset();
2060 handle_a[0].socket()->Disconnect();
2061 handle_a[0].Reset();
2062
2063 // Used to get stuck here.
2064 MessageLoop::current()->RunAllPending();
2065
2066 handle_b[1].socket()->Disconnect();
2067 handle_b[1].Reset();
2068 handle_a[1].socket()->Disconnect();
2069 handle_a[1].Reset();
2070
2071 for (int i = 2; i < 4; ++i) {
2072 EXPECT_EQ(OK, callback_b[i].WaitForResult());
2073 EXPECT_EQ(OK, callback_a[i].WaitForResult());
2074 }
2075 }
2076
TEST_F(ClientSocketPoolBaseTest,ReleasingDisconnectedSocketsMaintainsPriorityOrder)2077 TEST_F(ClientSocketPoolBaseTest,
2078 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2079 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2080
2081 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2082
2083 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2084 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2085 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2086 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2087
2088 EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
2089 EXPECT_EQ(OK, (*requests())[1]->WaitForResult());
2090 EXPECT_EQ(2u, completion_count());
2091
2092 // Releases one connection.
2093 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2094 EXPECT_EQ(OK, (*requests())[2]->WaitForResult());
2095
2096 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2097 EXPECT_EQ(OK, (*requests())[3]->WaitForResult());
2098 EXPECT_EQ(4u, completion_count());
2099
2100 EXPECT_EQ(1, GetOrderOfRequest(1));
2101 EXPECT_EQ(2, GetOrderOfRequest(2));
2102 EXPECT_EQ(3, GetOrderOfRequest(3));
2103 EXPECT_EQ(4, GetOrderOfRequest(4));
2104
2105 // Make sure we test order of all requests made.
2106 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
2107 }
2108
2109 class TestReleasingSocketRequest : public CallbackRunner< Tuple1<int> > {
2110 public:
TestReleasingSocketRequest(TestClientSocketPool * pool,int expected_result,bool reset_releasing_handle)2111 TestReleasingSocketRequest(TestClientSocketPool* pool,
2112 int expected_result,
2113 bool reset_releasing_handle)
2114 : pool_(pool),
2115 expected_result_(expected_result),
2116 reset_releasing_handle_(reset_releasing_handle) {}
2117
handle()2118 ClientSocketHandle* handle() { return &handle_; }
2119
WaitForResult()2120 int WaitForResult() {
2121 return callback_.WaitForResult();
2122 }
2123
RunWithParams(const Tuple1<int> & params)2124 virtual void RunWithParams(const Tuple1<int>& params) {
2125 callback_.RunWithParams(params);
2126 if (reset_releasing_handle_)
2127 handle_.Reset();
2128 scoped_refptr<TestSocketParams> con_params(new TestSocketParams());
2129 EXPECT_EQ(expected_result_, handle2_.Init("a",
2130 con_params,
2131 kDefaultPriority,
2132 &callback2_,
2133 pool_,
2134 BoundNetLog()));
2135 }
2136
2137 private:
2138 TestClientSocketPool* const pool_;
2139 int expected_result_;
2140 bool reset_releasing_handle_;
2141 ClientSocketHandle handle_;
2142 ClientSocketHandle handle2_;
2143 TestCompletionCallback callback_;
2144 TestCompletionCallback callback2_;
2145 };
2146
2147
TEST_F(ClientSocketPoolBaseTest,AdditionalErrorSocketsDontUseSlot)2148 TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2149 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2150
2151 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2152 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
2153 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2154
2155 EXPECT_EQ(static_cast<int>(requests_size()),
2156 client_socket_factory_.allocation_count());
2157
2158 connect_job_factory_->set_job_type(
2159 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2160 TestReleasingSocketRequest req(pool_.get(), OK, false);
2161 EXPECT_EQ(ERR_IO_PENDING,
2162 req.handle()->Init("a",
2163 params_,
2164 kDefaultPriority,
2165 &req,
2166 pool_.get(),
2167 BoundNetLog()));
2168 // The next job should complete synchronously
2169 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2170
2171 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
2172 EXPECT_FALSE(req.handle()->is_initialized());
2173 EXPECT_FALSE(req.handle()->socket());
2174 EXPECT_TRUE(req.handle()->is_ssl_error());
2175 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
2176 }
2177
2178 // http://crbug.com/44724 regression test.
2179 // We start releasing the pool when we flush on network change. When that
2180 // happens, the only active references are in the ClientSocketHandles. When a
2181 // ConnectJob completes and calls back into the last ClientSocketHandle, that
2182 // callback can release the last reference and delete the pool. After the
2183 // callback finishes, we go back to the stack frame within the now-deleted pool.
2184 // Executing any code that refers to members of the now-deleted pool can cause
2185 // crashes.
TEST_F(ClientSocketPoolBaseTest,CallbackThatReleasesPool)2186 TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2187 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2188 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2189
2190 ClientSocketHandle handle;
2191 TestCompletionCallback callback;
2192 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2193 params_,
2194 kDefaultPriority,
2195 &callback,
2196 pool_.get(),
2197 BoundNetLog()));
2198
2199 pool_->Flush();
2200
2201 // We'll call back into this now.
2202 callback.WaitForResult();
2203 }
2204
TEST_F(ClientSocketPoolBaseTest,DoNotReuseSocketAfterFlush)2205 TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2206 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2207 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2208
2209 ClientSocketHandle handle;
2210 TestCompletionCallback callback;
2211 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2212 params_,
2213 kDefaultPriority,
2214 &callback,
2215 pool_.get(),
2216 BoundNetLog()));
2217 EXPECT_EQ(OK, callback.WaitForResult());
2218 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2219
2220 pool_->Flush();
2221
2222 handle.Reset();
2223 MessageLoop::current()->RunAllPending();
2224
2225 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2226 params_,
2227 kDefaultPriority,
2228 &callback,
2229 pool_.get(),
2230 BoundNetLog()));
2231 EXPECT_EQ(OK, callback.WaitForResult());
2232 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2233 }
2234
2235 class ConnectWithinCallback : public CallbackRunner< Tuple1<int> > {
2236 public:
ConnectWithinCallback(const std::string & group_name,const scoped_refptr<TestSocketParams> & params,TestClientSocketPool * pool)2237 ConnectWithinCallback(
2238 const std::string& group_name,
2239 const scoped_refptr<TestSocketParams>& params,
2240 TestClientSocketPool* pool)
2241 : group_name_(group_name), params_(params), pool_(pool) {}
2242
~ConnectWithinCallback()2243 ~ConnectWithinCallback() {}
2244
RunWithParams(const Tuple1<int> & params)2245 virtual void RunWithParams(const Tuple1<int>& params) {
2246 callback_.RunWithParams(params);
2247 EXPECT_EQ(ERR_IO_PENDING,
2248 handle_.Init(group_name_,
2249 params_,
2250 kDefaultPriority,
2251 &nested_callback_,
2252 pool_,
2253 BoundNetLog()));
2254 }
2255
WaitForResult()2256 int WaitForResult() {
2257 return callback_.WaitForResult();
2258 }
2259
WaitForNestedResult()2260 int WaitForNestedResult() {
2261 return nested_callback_.WaitForResult();
2262 }
2263
2264 private:
2265 const std::string group_name_;
2266 const scoped_refptr<TestSocketParams> params_;
2267 TestClientSocketPool* const pool_;
2268 ClientSocketHandle handle_;
2269 TestCompletionCallback callback_;
2270 TestCompletionCallback nested_callback_;
2271 };
2272
TEST_F(ClientSocketPoolBaseTest,AbortAllRequestsOnFlush)2273 TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
2274 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2275
2276 // First job will be waiting until it gets aborted.
2277 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2278
2279 ClientSocketHandle handle;
2280 ConnectWithinCallback callback("a", params_, pool_.get());
2281 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2282 params_,
2283 kDefaultPriority,
2284 &callback,
2285 pool_.get(),
2286 BoundNetLog()));
2287
2288 // Second job will be started during the first callback, and will
2289 // asynchronously complete with OK.
2290 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2291 pool_->Flush();
2292 EXPECT_EQ(ERR_ABORTED, callback.WaitForResult());
2293 EXPECT_EQ(OK, callback.WaitForNestedResult());
2294 }
2295
2296 // Cancel a pending socket request while we're at max sockets,
2297 // and verify that the backup socket firing doesn't cause a crash.
TEST_F(ClientSocketPoolBaseTest,BackupSocketCancelAtMaxSockets)2298 TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
2299 // Max 4 sockets globally, max 4 sockets per group.
2300 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2301 pool_->EnableConnectBackupJobs();
2302
2303 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2304 // timer.
2305 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2306 ClientSocketHandle handle;
2307 TestCompletionCallback callback;
2308 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2309 params_,
2310 kDefaultPriority,
2311 &callback,
2312 pool_.get(),
2313 BoundNetLog()));
2314
2315 // Start (MaxSockets - 1) connected sockets to reach max sockets.
2316 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2317 ClientSocketHandle handles[kDefaultMaxSockets];
2318 for (int i = 1; i < kDefaultMaxSockets; ++i) {
2319 TestCompletionCallback callback;
2320 EXPECT_EQ(OK, handles[i].Init("bar",
2321 params_,
2322 kDefaultPriority,
2323 &callback,
2324 pool_.get(),
2325 BoundNetLog()));
2326 }
2327
2328 MessageLoop::current()->RunAllPending();
2329
2330 // Cancel the pending request.
2331 handle.Reset();
2332
2333 // Wait for the backup timer to fire (add some slop to ensure it fires)
2334 base::PlatformThread::Sleep(
2335 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
2336
2337 MessageLoop::current()->RunAllPending();
2338 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
2339 }
2340
TEST_F(ClientSocketPoolBaseTest,CancelBackupSocketAfterCancelingAllRequests)2341 TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
2342 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2343 pool_->EnableConnectBackupJobs();
2344
2345 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2346 // timer.
2347 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2348 ClientSocketHandle handle;
2349 TestCompletionCallback callback;
2350 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2351 params_,
2352 kDefaultPriority,
2353 &callback,
2354 pool_.get(),
2355 BoundNetLog()));
2356 ASSERT_TRUE(pool_->HasGroup("bar"));
2357 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2358
2359 // Cancel the socket request. This should cancel the backup timer. Wait for
2360 // the backup time to see if it indeed got canceled.
2361 handle.Reset();
2362 // Wait for the backup timer to fire (add some slop to ensure it fires)
2363 base::PlatformThread::Sleep(
2364 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
2365 MessageLoop::current()->RunAllPending();
2366 ASSERT_TRUE(pool_->HasGroup("bar"));
2367 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2368 }
2369
TEST_F(ClientSocketPoolBaseTest,CancelBackupSocketAfterFinishingAllRequests)2370 TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
2371 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2372 pool_->EnableConnectBackupJobs();
2373
2374 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2375 // timer.
2376 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2377 ClientSocketHandle handle;
2378 TestCompletionCallback callback;
2379 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2380 params_,
2381 kDefaultPriority,
2382 &callback,
2383 pool_.get(),
2384 BoundNetLog()));
2385 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2386 ClientSocketHandle handle2;
2387 TestCompletionCallback callback2;
2388 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("bar",
2389 params_,
2390 kDefaultPriority,
2391 &callback2,
2392 pool_.get(),
2393 BoundNetLog()));
2394 ASSERT_TRUE(pool_->HasGroup("bar"));
2395 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("bar"));
2396
2397 // Cancel request 1 and then complete request 2. With the requests finished,
2398 // the backup timer should be cancelled.
2399 handle.Reset();
2400 EXPECT_EQ(OK, callback2.WaitForResult());
2401 // Wait for the backup timer to fire (add some slop to ensure it fires)
2402 base::PlatformThread::Sleep(
2403 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
2404 MessageLoop::current()->RunAllPending();
2405 }
2406
2407 // Test delayed socket binding for the case where we have two connects,
2408 // and while one is waiting on a connect, the other frees up.
2409 // The socket waiting on a connect should switch immediately to the freed
2410 // up socket.
TEST_F(ClientSocketPoolBaseTest,DelayedSocketBindingWaitingForConnect)2411 TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
2412 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2413 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2414
2415 ClientSocketHandle handle1;
2416 TestCompletionCallback callback;
2417 EXPECT_EQ(ERR_IO_PENDING,
2418 handle1.Init("a",
2419 params_,
2420 kDefaultPriority,
2421 &callback,
2422 pool_.get(),
2423 BoundNetLog()));
2424 EXPECT_EQ(OK, callback.WaitForResult());
2425
2426 // No idle sockets, no pending jobs.
2427 EXPECT_EQ(0, pool_->IdleSocketCount());
2428 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2429
2430 // Create a second socket to the same host, but this one will wait.
2431 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2432 ClientSocketHandle handle2;
2433 EXPECT_EQ(ERR_IO_PENDING,
2434 handle2.Init("a",
2435 params_,
2436 kDefaultPriority,
2437 &callback,
2438 pool_.get(),
2439 BoundNetLog()));
2440 // No idle sockets, and one connecting job.
2441 EXPECT_EQ(0, pool_->IdleSocketCount());
2442 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2443
2444 // Return the first handle to the pool. This will initiate the delayed
2445 // binding.
2446 handle1.Reset();
2447
2448 MessageLoop::current()->RunAllPending();
2449
2450 // Still no idle sockets, still one pending connect job.
2451 EXPECT_EQ(0, pool_->IdleSocketCount());
2452 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2453
2454 // The second socket connected, even though it was a Waiting Job.
2455 EXPECT_EQ(OK, callback.WaitForResult());
2456
2457 // And we can see there is still one job waiting.
2458 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2459
2460 // Finally, signal the waiting Connect.
2461 client_socket_factory_.SignalJobs();
2462 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2463
2464 MessageLoop::current()->RunAllPending();
2465 }
2466
2467 // Test delayed socket binding when a group is at capacity and one
2468 // of the group's sockets frees up.
TEST_F(ClientSocketPoolBaseTest,DelayedSocketBindingAtGroupCapacity)2469 TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
2470 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2471 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2472
2473 ClientSocketHandle handle1;
2474 TestCompletionCallback callback;
2475 EXPECT_EQ(ERR_IO_PENDING,
2476 handle1.Init("a",
2477 params_,
2478 kDefaultPriority,
2479 &callback,
2480 pool_.get(),
2481 BoundNetLog()));
2482 EXPECT_EQ(OK, callback.WaitForResult());
2483
2484 // No idle sockets, no pending jobs.
2485 EXPECT_EQ(0, pool_->IdleSocketCount());
2486 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2487
2488 // Create a second socket to the same host, but this one will wait.
2489 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2490 ClientSocketHandle handle2;
2491 EXPECT_EQ(ERR_IO_PENDING,
2492 handle2.Init("a",
2493 params_,
2494 kDefaultPriority,
2495 &callback,
2496 pool_.get(),
2497 BoundNetLog()));
2498 // No idle sockets, and one connecting job.
2499 EXPECT_EQ(0, pool_->IdleSocketCount());
2500 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2501
2502 // Return the first handle to the pool. This will initiate the delayed
2503 // binding.
2504 handle1.Reset();
2505
2506 MessageLoop::current()->RunAllPending();
2507
2508 // Still no idle sockets, still one pending connect job.
2509 EXPECT_EQ(0, pool_->IdleSocketCount());
2510 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2511
2512 // The second socket connected, even though it was a Waiting Job.
2513 EXPECT_EQ(OK, callback.WaitForResult());
2514
2515 // And we can see there is still one job waiting.
2516 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2517
2518 // Finally, signal the waiting Connect.
2519 client_socket_factory_.SignalJobs();
2520 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2521
2522 MessageLoop::current()->RunAllPending();
2523 }
2524
2525 // Test out the case where we have one socket connected, one
2526 // connecting, when the first socket finishes and goes idle.
2527 // Although the second connection is pending, the second request
2528 // should complete, by taking the first socket's idle socket.
TEST_F(ClientSocketPoolBaseTest,DelayedSocketBindingAtStall)2529 TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
2530 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2531 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2532
2533 ClientSocketHandle handle1;
2534 TestCompletionCallback callback;
2535 EXPECT_EQ(ERR_IO_PENDING,
2536 handle1.Init("a",
2537 params_,
2538 kDefaultPriority,
2539 &callback,
2540 pool_.get(),
2541 BoundNetLog()));
2542 EXPECT_EQ(OK, callback.WaitForResult());
2543
2544 // No idle sockets, no pending jobs.
2545 EXPECT_EQ(0, pool_->IdleSocketCount());
2546 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2547
2548 // Create a second socket to the same host, but this one will wait.
2549 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2550 ClientSocketHandle handle2;
2551 EXPECT_EQ(ERR_IO_PENDING,
2552 handle2.Init("a",
2553 params_,
2554 kDefaultPriority,
2555 &callback,
2556 pool_.get(),
2557 BoundNetLog()));
2558 // No idle sockets, and one connecting job.
2559 EXPECT_EQ(0, pool_->IdleSocketCount());
2560 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2561
2562 // Return the first handle to the pool. This will initiate the delayed
2563 // binding.
2564 handle1.Reset();
2565
2566 MessageLoop::current()->RunAllPending();
2567
2568 // Still no idle sockets, still one pending connect job.
2569 EXPECT_EQ(0, pool_->IdleSocketCount());
2570 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2571
2572 // The second socket connected, even though it was a Waiting Job.
2573 EXPECT_EQ(OK, callback.WaitForResult());
2574
2575 // And we can see there is still one job waiting.
2576 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2577
2578 // Finally, signal the waiting Connect.
2579 client_socket_factory_.SignalJobs();
2580 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2581
2582 MessageLoop::current()->RunAllPending();
2583 }
2584
2585 // Cover the case where on an available socket slot, we have one pending
2586 // request that completes synchronously, thereby making the Group empty.
TEST_F(ClientSocketPoolBaseTest,SynchronouslyProcessOnePendingRequest)2587 TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
2588 const int kUnlimitedSockets = 100;
2589 const int kOneSocketPerGroup = 1;
2590 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
2591
2592 // Make the first request asynchronous fail.
2593 // This will free up a socket slot later.
2594 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2595
2596 ClientSocketHandle handle1;
2597 TestCompletionCallback callback1;
2598 EXPECT_EQ(ERR_IO_PENDING,
2599 handle1.Init("a",
2600 params_,
2601 kDefaultPriority,
2602 &callback1,
2603 pool_.get(),
2604 BoundNetLog()));
2605 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2606
2607 // Make the second request synchronously fail. This should make the Group
2608 // empty.
2609 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
2610 ClientSocketHandle handle2;
2611 TestCompletionCallback callback2;
2612 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
2613 // when created.
2614 EXPECT_EQ(ERR_IO_PENDING,
2615 handle2.Init("a",
2616 params_,
2617 kDefaultPriority,
2618 &callback2,
2619 pool_.get(),
2620 BoundNetLog()));
2621
2622 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2623
2624 EXPECT_EQ(ERR_CONNECTION_FAILED, callback1.WaitForResult());
2625 EXPECT_EQ(ERR_CONNECTION_FAILED, callback2.WaitForResult());
2626 EXPECT_FALSE(pool_->HasGroup("a"));
2627 }
2628
TEST_F(ClientSocketPoolBaseTest,PreferUsedSocketToUnusedSocket)2629 TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
2630 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2631
2632 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2633
2634 ClientSocketHandle handle1;
2635 TestCompletionCallback callback1;
2636 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2637 params_,
2638 kDefaultPriority,
2639 &callback1,
2640 pool_.get(),
2641 BoundNetLog()));
2642
2643 ClientSocketHandle handle2;
2644 TestCompletionCallback callback2;
2645 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2646 params_,
2647 kDefaultPriority,
2648 &callback2,
2649 pool_.get(),
2650 BoundNetLog()));
2651 ClientSocketHandle handle3;
2652 TestCompletionCallback callback3;
2653 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
2654 params_,
2655 kDefaultPriority,
2656 &callback3,
2657 pool_.get(),
2658 BoundNetLog()));
2659
2660 EXPECT_EQ(OK, callback1.WaitForResult());
2661 EXPECT_EQ(OK, callback2.WaitForResult());
2662 EXPECT_EQ(OK, callback3.WaitForResult());
2663
2664 // Use the socket.
2665 EXPECT_EQ(1, handle1.socket()->Write(NULL, 1, NULL));
2666 EXPECT_EQ(1, handle3.socket()->Write(NULL, 1, NULL));
2667
2668 handle1.Reset();
2669 handle2.Reset();
2670 handle3.Reset();
2671
2672 EXPECT_EQ(OK, handle1.Init("a",
2673 params_,
2674 kDefaultPriority,
2675 &callback1,
2676 pool_.get(),
2677 BoundNetLog()));
2678 EXPECT_EQ(OK, handle2.Init("a",
2679 params_,
2680 kDefaultPriority,
2681 &callback2,
2682 pool_.get(),
2683 BoundNetLog()));
2684 EXPECT_EQ(OK, handle3.Init("a",
2685 params_,
2686 kDefaultPriority,
2687 &callback3,
2688 pool_.get(),
2689 BoundNetLog()));
2690
2691 EXPECT_TRUE(handle1.socket()->WasEverUsed());
2692 EXPECT_TRUE(handle2.socket()->WasEverUsed());
2693 EXPECT_FALSE(handle3.socket()->WasEverUsed());
2694 }
2695
TEST_F(ClientSocketPoolBaseTest,RequestSockets)2696 TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
2697 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2698 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2699
2700 pool_->RequestSockets("a", ¶ms_, 2, BoundNetLog());
2701
2702 ASSERT_TRUE(pool_->HasGroup("a"));
2703 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2704 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2705
2706 ClientSocketHandle handle1;
2707 TestCompletionCallback callback1;
2708 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2709 params_,
2710 kDefaultPriority,
2711 &callback1,
2712 pool_.get(),
2713 BoundNetLog()));
2714
2715 ClientSocketHandle handle2;
2716 TestCompletionCallback callback2;
2717 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2718 params_,
2719 kDefaultPriority,
2720 &callback2,
2721 pool_.get(),
2722 BoundNetLog()));
2723
2724 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2725 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2726
2727 EXPECT_EQ(OK, callback1.WaitForResult());
2728 EXPECT_EQ(OK, callback2.WaitForResult());
2729 handle1.Reset();
2730 handle2.Reset();
2731
2732 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2733 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2734 }
2735
TEST_F(ClientSocketPoolBaseTest,RequestSocketsWhenAlreadyHaveAConnectJob)2736 TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
2737 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2738 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2739
2740 ClientSocketHandle handle1;
2741 TestCompletionCallback callback1;
2742 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2743 params_,
2744 kDefaultPriority,
2745 &callback1,
2746 pool_.get(),
2747 BoundNetLog()));
2748
2749 ASSERT_TRUE(pool_->HasGroup("a"));
2750 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2751 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2752
2753 pool_->RequestSockets("a", ¶ms_, 2, BoundNetLog());
2754
2755 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2756 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2757
2758 ClientSocketHandle handle2;
2759 TestCompletionCallback callback2;
2760 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2761 params_,
2762 kDefaultPriority,
2763 &callback2,
2764 pool_.get(),
2765 BoundNetLog()));
2766
2767 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2768 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2769
2770 EXPECT_EQ(OK, callback1.WaitForResult());
2771 EXPECT_EQ(OK, callback2.WaitForResult());
2772 handle1.Reset();
2773 handle2.Reset();
2774
2775 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2776 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2777 }
2778
TEST_F(ClientSocketPoolBaseTest,RequestSocketsWhenAlreadyHaveMultipleConnectJob)2779 TEST_F(ClientSocketPoolBaseTest,
2780 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
2781 CreatePool(4, 4);
2782 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2783
2784 ClientSocketHandle handle1;
2785 TestCompletionCallback callback1;
2786 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2787 params_,
2788 kDefaultPriority,
2789 &callback1,
2790 pool_.get(),
2791 BoundNetLog()));
2792
2793 ClientSocketHandle handle2;
2794 TestCompletionCallback callback2;
2795 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2796 params_,
2797 kDefaultPriority,
2798 &callback2,
2799 pool_.get(),
2800 BoundNetLog()));
2801
2802 ClientSocketHandle handle3;
2803 TestCompletionCallback callback3;
2804 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
2805 params_,
2806 kDefaultPriority,
2807 &callback3,
2808 pool_.get(),
2809 BoundNetLog()));
2810
2811 ASSERT_TRUE(pool_->HasGroup("a"));
2812 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2813 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2814
2815 pool_->RequestSockets("a", ¶ms_, 2, BoundNetLog());
2816
2817 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2818 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2819
2820 EXPECT_EQ(OK, callback1.WaitForResult());
2821 EXPECT_EQ(OK, callback2.WaitForResult());
2822 EXPECT_EQ(OK, callback3.WaitForResult());
2823 handle1.Reset();
2824 handle2.Reset();
2825 handle3.Reset();
2826
2827 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2828 EXPECT_EQ(3, pool_->IdleSocketCountInGroup("a"));
2829 }
2830
TEST_F(ClientSocketPoolBaseTest,RequestSocketsAtMaxSocketLimit)2831 TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
2832 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2833 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2834
2835 ASSERT_FALSE(pool_->HasGroup("a"));
2836
2837 pool_->RequestSockets("a", ¶ms_, kDefaultMaxSockets,
2838 BoundNetLog());
2839
2840 ASSERT_TRUE(pool_->HasGroup("a"));
2841 EXPECT_EQ(kDefaultMaxSockets, pool_->NumConnectJobsInGroup("a"));
2842
2843 ASSERT_FALSE(pool_->HasGroup("b"));
2844
2845 pool_->RequestSockets("b", ¶ms_, kDefaultMaxSockets,
2846 BoundNetLog());
2847
2848 ASSERT_FALSE(pool_->HasGroup("b"));
2849 }
2850
TEST_F(ClientSocketPoolBaseTest,RequestSocketsHitMaxSocketLimit)2851 TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
2852 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2853 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2854
2855 ASSERT_FALSE(pool_->HasGroup("a"));
2856
2857 pool_->RequestSockets("a", ¶ms_, kDefaultMaxSockets - 1,
2858 BoundNetLog());
2859
2860 ASSERT_TRUE(pool_->HasGroup("a"));
2861 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->NumConnectJobsInGroup("a"));
2862
2863 ASSERT_FALSE(pool_->HasGroup("b"));
2864
2865 pool_->RequestSockets("b", ¶ms_, kDefaultMaxSockets,
2866 BoundNetLog());
2867
2868 ASSERT_TRUE(pool_->HasGroup("b"));
2869 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("b"));
2870 }
2871
TEST_F(ClientSocketPoolBaseTest,RequestSocketsCountIdleSockets)2872 TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
2873 CreatePool(4, 4);
2874 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2875
2876 ClientSocketHandle handle1;
2877 TestCompletionCallback callback1;
2878 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2879 params_,
2880 kDefaultPriority,
2881 &callback1,
2882 pool_.get(),
2883 BoundNetLog()));
2884 ASSERT_EQ(OK, callback1.WaitForResult());
2885 handle1.Reset();
2886
2887 ASSERT_TRUE(pool_->HasGroup("a"));
2888 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2889 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
2890
2891 pool_->RequestSockets("a", ¶ms_, 2, BoundNetLog());
2892
2893 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2894 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
2895 }
2896
TEST_F(ClientSocketPoolBaseTest,RequestSocketsCountActiveSockets)2897 TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
2898 CreatePool(4, 4);
2899 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2900
2901 ClientSocketHandle handle1;
2902 TestCompletionCallback callback1;
2903 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2904 params_,
2905 kDefaultPriority,
2906 &callback1,
2907 pool_.get(),
2908 BoundNetLog()));
2909 ASSERT_EQ(OK, callback1.WaitForResult());
2910
2911 ASSERT_TRUE(pool_->HasGroup("a"));
2912 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2913 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2914 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2915
2916 pool_->RequestSockets("a", ¶ms_, 2, BoundNetLog());
2917
2918 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2919 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2920 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2921 }
2922
TEST_F(ClientSocketPoolBaseTest,RequestSocketsSynchronous)2923 TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
2924 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2925 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2926
2927 pool_->RequestSockets("a", ¶ms_, kDefaultMaxSocketsPerGroup,
2928 BoundNetLog());
2929
2930 ASSERT_TRUE(pool_->HasGroup("a"));
2931 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2932 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("a"));
2933
2934 pool_->RequestSockets("b", ¶ms_, kDefaultMaxSocketsPerGroup,
2935 BoundNetLog());
2936
2937 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
2938 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("b"));
2939 }
2940
TEST_F(ClientSocketPoolBaseTest,RequestSocketsSynchronousError)2941 TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
2942 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2943 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
2944
2945 pool_->RequestSockets("a", ¶ms_, kDefaultMaxSocketsPerGroup,
2946 BoundNetLog());
2947
2948 ASSERT_FALSE(pool_->HasGroup("a"));
2949
2950 connect_job_factory_->set_job_type(
2951 TestConnectJob::kMockAdditionalErrorStateJob);
2952 pool_->RequestSockets("a", ¶ms_, kDefaultMaxSocketsPerGroup,
2953 BoundNetLog());
2954
2955 ASSERT_FALSE(pool_->HasGroup("a"));
2956 }
2957
TEST_F(ClientSocketPoolBaseTest,RequestSocketsMultipleTimesDoesNothing)2958 TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
2959 CreatePool(4, 4);
2960 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2961
2962 pool_->RequestSockets("a", ¶ms_, 2, BoundNetLog());
2963
2964 ASSERT_TRUE(pool_->HasGroup("a"));
2965 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2966 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2967
2968 pool_->RequestSockets("a", ¶ms_, 2, BoundNetLog());
2969 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2970 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2971
2972 ClientSocketHandle handle1;
2973 TestCompletionCallback callback1;
2974 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2975 params_,
2976 kDefaultPriority,
2977 &callback1,
2978 pool_.get(),
2979 BoundNetLog()));
2980 ASSERT_EQ(OK, callback1.WaitForResult());
2981
2982 ClientSocketHandle handle2;
2983 TestCompletionCallback callback2;
2984 int rv = handle2.Init("a",
2985 params_,
2986 kDefaultPriority,
2987 &callback2,
2988 pool_.get(),
2989 BoundNetLog());
2990 if (rv != OK) {
2991 EXPECT_EQ(ERR_IO_PENDING, rv);
2992 EXPECT_EQ(OK, callback2.WaitForResult());
2993 }
2994
2995 handle1.Reset();
2996 handle2.Reset();
2997
2998 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2999
3000 pool_->RequestSockets("a", ¶ms_, 2, BoundNetLog());
3001 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3002 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3003 }
3004
TEST_F(ClientSocketPoolBaseTest,RequestSocketsDifferentNumSockets)3005 TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
3006 CreatePool(4, 4);
3007 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3008
3009 pool_->RequestSockets("a", ¶ms_, 1, BoundNetLog());
3010
3011 ASSERT_TRUE(pool_->HasGroup("a"));
3012 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3013 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3014
3015 pool_->RequestSockets("a", ¶ms_, 2, BoundNetLog());
3016 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3017 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3018
3019 pool_->RequestSockets("a", ¶ms_, 3, BoundNetLog());
3020 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
3021 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3022
3023 pool_->RequestSockets("a", ¶ms_, 1, BoundNetLog());
3024 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
3025 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3026 }
3027
TEST_F(ClientSocketPoolBaseTest,PreconnectJobsTakenByNormalRequests)3028 TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
3029 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3030 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3031
3032 pool_->RequestSockets("a", ¶ms_, 1, BoundNetLog());
3033
3034 ASSERT_TRUE(pool_->HasGroup("a"));
3035 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3036 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3037
3038 ClientSocketHandle handle1;
3039 TestCompletionCallback callback1;
3040 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3041 params_,
3042 kDefaultPriority,
3043 &callback1,
3044 pool_.get(),
3045 BoundNetLog()));
3046
3047 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3048 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3049
3050 ASSERT_EQ(OK, callback1.WaitForResult());
3051
3052 handle1.Reset();
3053
3054 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3055 }
3056
3057 // http://crbug.com/64940 regression test.
TEST_F(ClientSocketPoolBaseTest,PreconnectClosesIdleSocketRemovesGroup)3058 TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
3059 const int kMaxTotalSockets = 3;
3060 const int kMaxSocketsPerGroup = 2;
3061 CreatePool(kMaxTotalSockets, kMaxSocketsPerGroup);
3062 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3063
3064 // Note that group name ordering matters here. "a" comes before "b", so
3065 // CloseOneIdleSocket() will try to close "a"'s idle socket.
3066
3067 // Set up one idle socket in "a".
3068 ClientSocketHandle handle1;
3069 TestCompletionCallback callback1;
3070 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3071 params_,
3072 kDefaultPriority,
3073 &callback1,
3074 pool_.get(),
3075 BoundNetLog()));
3076
3077 ASSERT_EQ(OK, callback1.WaitForResult());
3078 handle1.Reset();
3079 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3080
3081 // Set up two active sockets in "b".
3082 ClientSocketHandle handle2;
3083 TestCompletionCallback callback2;
3084 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("b",
3085 params_,
3086 kDefaultPriority,
3087 &callback1,
3088 pool_.get(),
3089 BoundNetLog()));
3090 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("b",
3091 params_,
3092 kDefaultPriority,
3093 &callback2,
3094 pool_.get(),
3095 BoundNetLog()));
3096
3097 ASSERT_EQ(OK, callback1.WaitForResult());
3098 ASSERT_EQ(OK, callback2.WaitForResult());
3099 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3100 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3101
3102 // Now we have 1 idle socket in "a" and 2 active sockets in "b". This means
3103 // we've maxed out on sockets, since we set |kMaxTotalSockets| to 3.
3104 // Requesting 2 preconnected sockets for "a" should fail to allocate any more
3105 // sockets for "a", and "b" should still have 2 active sockets.
3106
3107 pool_->RequestSockets("a", ¶ms_, 2, BoundNetLog());
3108 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3109 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3110 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3111 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3112 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3113 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3114
3115 // Now release the 2 active sockets for "b". This will give us 1 idle socket
3116 // in "a" and 2 idle sockets in "b". Requesting 2 preconnected sockets for
3117 // "a" should result in closing 1 for "b".
3118 handle1.Reset();
3119 handle2.Reset();
3120 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("b"));
3121 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3122
3123 pool_->RequestSockets("a", ¶ms_, 2, BoundNetLog());
3124 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3125 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3126 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3127 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3128 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("b"));
3129 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3130 }
3131
3132 } // namespace
3133
3134 } // namespace net
3135