Material throbber: use in tabstrip
[chromium-blink-merge.git] / net / socket / client_socket_pool_base_unittest.cc
blobf989a462ccecf1684ce896d4d7206a2cc37d395b
1 // Copyright (c) 2012 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.
5 #include "net/socket/client_socket_pool_base.h"
7 #include <vector>
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "base/callback.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/memory/scoped_vector.h"
14 #include "base/memory/weak_ptr.h"
15 #include "base/message_loop/message_loop.h"
16 #include "base/run_loop.h"
17 #include "base/strings/string_number_conversions.h"
18 #include "base/strings/stringprintf.h"
19 #include "base/threading/platform_thread.h"
20 #include "base/values.h"
21 #include "net/base/load_timing_info.h"
22 #include "net/base/load_timing_info_test_util.h"
23 #include "net/base/net_errors.h"
24 #include "net/base/request_priority.h"
25 #include "net/base/test_completion_callback.h"
26 #include "net/http/http_response_headers.h"
27 #include "net/log/captured_net_log_entry.h"
28 #include "net/log/net_log.h"
29 #include "net/log/net_log_unittest.h"
30 #include "net/log/test_net_log.h"
31 #include "net/socket/client_socket_factory.h"
32 #include "net/socket/client_socket_handle.h"
33 #include "net/socket/socket_test_util.h"
34 #include "net/socket/ssl_client_socket.h"
35 #include "net/socket/stream_socket.h"
36 #include "net/udp/datagram_client_socket.h"
37 #include "testing/gmock/include/gmock/gmock.h"
38 #include "testing/gtest/include/gtest/gtest.h"
40 using ::testing::Invoke;
41 using ::testing::Return;
43 namespace net {
45 namespace {
47 const int kDefaultMaxSockets = 4;
48 const int kDefaultMaxSocketsPerGroup = 2;
50 // Make sure |handle| sets load times correctly when it has been assigned a
51 // reused socket.
52 void TestLoadTimingInfoConnectedReused(const ClientSocketHandle& handle) {
53 LoadTimingInfo load_timing_info;
54 // Only pass true in as |is_reused|, as in general, HttpStream types should
55 // have stricter concepts of reuse than socket pools.
56 EXPECT_TRUE(handle.GetLoadTimingInfo(true, &load_timing_info));
58 EXPECT_EQ(true, load_timing_info.socket_reused);
59 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
61 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
62 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
65 // Make sure |handle| sets load times correctly when it has been assigned a
66 // fresh socket. Also runs TestLoadTimingInfoConnectedReused, since the owner
67 // of a connection where |is_reused| is false may consider the connection
68 // reused.
69 void TestLoadTimingInfoConnectedNotReused(const ClientSocketHandle& handle) {
70 EXPECT_FALSE(handle.is_reused());
72 LoadTimingInfo load_timing_info;
73 EXPECT_TRUE(handle.GetLoadTimingInfo(false, &load_timing_info));
75 EXPECT_FALSE(load_timing_info.socket_reused);
76 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
78 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
79 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
80 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
82 TestLoadTimingInfoConnectedReused(handle);
85 // Make sure |handle| sets load times correctly, in the case that it does not
86 // currently have a socket.
87 void TestLoadTimingInfoNotConnected(const ClientSocketHandle& handle) {
88 // Should only be set to true once a socket is assigned, if at all.
89 EXPECT_FALSE(handle.is_reused());
91 LoadTimingInfo load_timing_info;
92 EXPECT_FALSE(handle.GetLoadTimingInfo(false, &load_timing_info));
94 EXPECT_FALSE(load_timing_info.socket_reused);
95 EXPECT_EQ(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
97 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
98 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
101 class TestSocketParams : public base::RefCounted<TestSocketParams> {
102 public:
103 explicit TestSocketParams(bool ignore_limits)
104 : ignore_limits_(ignore_limits) {}
106 bool ignore_limits() { return ignore_limits_; }
108 private:
109 friend class base::RefCounted<TestSocketParams>;
110 ~TestSocketParams() {}
112 const bool ignore_limits_;
114 typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
116 class MockClientSocket : public StreamSocket {
117 public:
118 explicit MockClientSocket(net::NetLog* net_log)
119 : connected_(false),
120 has_unread_data_(false),
121 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)),
122 was_used_to_convey_data_(false) {}
124 // Sets whether the socket has unread data. If true, the next call to Read()
125 // will return 1 byte and IsConnectedAndIdle() will return false.
126 void set_has_unread_data(bool has_unread_data) {
127 has_unread_data_ = has_unread_data;
130 // Socket implementation.
131 int Read(IOBuffer* /* buf */,
132 int len,
133 const CompletionCallback& /* callback */) override {
134 if (has_unread_data_ && len > 0) {
135 has_unread_data_ = false;
136 was_used_to_convey_data_ = true;
137 return 1;
139 return ERR_UNEXPECTED;
142 int Write(IOBuffer* /* buf */,
143 int len,
144 const CompletionCallback& /* callback */) override {
145 was_used_to_convey_data_ = true;
146 return len;
148 int SetReceiveBufferSize(int32 size) override { return OK; }
149 int SetSendBufferSize(int32 size) override { return OK; }
151 // StreamSocket implementation.
152 int Connect(const CompletionCallback& callback) override {
153 connected_ = true;
154 return OK;
157 void Disconnect() override { connected_ = false; }
158 bool IsConnected() const override { return connected_; }
159 bool IsConnectedAndIdle() const override {
160 return connected_ && !has_unread_data_;
163 int GetPeerAddress(IPEndPoint* /* address */) const override {
164 return ERR_UNEXPECTED;
167 int GetLocalAddress(IPEndPoint* /* address */) const override {
168 return ERR_UNEXPECTED;
171 const BoundNetLog& NetLog() const override { return net_log_; }
173 void SetSubresourceSpeculation() override {}
174 void SetOmniboxSpeculation() override {}
175 bool WasEverUsed() const override { return was_used_to_convey_data_; }
176 bool UsingTCPFastOpen() const override { return false; }
177 bool WasNpnNegotiated() const override { return false; }
178 NextProto GetNegotiatedProtocol() const override { return kProtoUnknown; }
179 bool GetSSLInfo(SSLInfo* ssl_info) override { return false; }
181 private:
182 bool connected_;
183 bool has_unread_data_;
184 BoundNetLog net_log_;
185 bool was_used_to_convey_data_;
187 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
190 class TestConnectJob;
192 class MockClientSocketFactory : public ClientSocketFactory {
193 public:
194 MockClientSocketFactory() : allocation_count_(0) {}
196 scoped_ptr<DatagramClientSocket> CreateDatagramClientSocket(
197 DatagramSocket::BindType bind_type,
198 const RandIntCallback& rand_int_cb,
199 NetLog* net_log,
200 const NetLog::Source& source) override {
201 NOTREACHED();
202 return scoped_ptr<DatagramClientSocket>();
205 scoped_ptr<StreamSocket> CreateTransportClientSocket(
206 const AddressList& addresses,
207 NetLog* /* net_log */,
208 const NetLog::Source& /*source*/) override {
209 allocation_count_++;
210 return scoped_ptr<StreamSocket>();
213 scoped_ptr<SSLClientSocket> CreateSSLClientSocket(
214 scoped_ptr<ClientSocketHandle> transport_socket,
215 const HostPortPair& host_and_port,
216 const SSLConfig& ssl_config,
217 const SSLClientSocketContext& context) override {
218 NOTIMPLEMENTED();
219 return scoped_ptr<SSLClientSocket>();
222 void ClearSSLSessionCache() override { NOTIMPLEMENTED(); }
224 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
226 void SignalJobs();
228 void SignalJob(size_t job);
230 void SetJobLoadState(size_t job, LoadState load_state);
232 int allocation_count() const { return allocation_count_; }
234 private:
235 int allocation_count_;
236 std::vector<TestConnectJob*> waiting_jobs_;
239 class TestConnectJob : public ConnectJob {
240 public:
241 enum JobType {
242 kMockJob,
243 kMockFailingJob,
244 kMockPendingJob,
245 kMockPendingFailingJob,
246 kMockWaitingJob,
247 kMockRecoverableJob,
248 kMockPendingRecoverableJob,
249 kMockAdditionalErrorStateJob,
250 kMockPendingAdditionalErrorStateJob,
251 kMockUnreadDataJob,
254 // The kMockPendingJob uses a slight delay before allowing the connect
255 // to complete.
256 static const int kPendingConnectDelay = 2;
258 TestConnectJob(JobType job_type,
259 const std::string& group_name,
260 const TestClientSocketPoolBase::Request& request,
261 base::TimeDelta timeout_duration,
262 ConnectJob::Delegate* delegate,
263 MockClientSocketFactory* client_socket_factory,
264 NetLog* net_log)
265 : ConnectJob(group_name, timeout_duration, request.priority(), delegate,
266 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
267 job_type_(job_type),
268 client_socket_factory_(client_socket_factory),
269 load_state_(LOAD_STATE_IDLE),
270 store_additional_error_state_(false),
271 weak_factory_(this) {
274 void Signal() {
275 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
278 void set_load_state(LoadState load_state) { load_state_ = load_state; }
280 // From ConnectJob:
282 LoadState GetLoadState() const override { return load_state_; }
284 void GetAdditionalErrorState(ClientSocketHandle* handle) override {
285 if (store_additional_error_state_) {
286 // Set all of the additional error state fields in some way.
287 handle->set_is_ssl_error(true);
288 HttpResponseInfo info;
289 info.headers = new HttpResponseHeaders(std::string());
290 handle->set_ssl_error_response_info(info);
294 private:
295 // From ConnectJob:
297 int ConnectInternal() override {
298 AddressList ignored;
299 client_socket_factory_->CreateTransportClientSocket(ignored, NULL,
300 NetLog::Source());
301 SetSocket(
302 scoped_ptr<StreamSocket>(new MockClientSocket(net_log().net_log())));
303 switch (job_type_) {
304 case kMockJob:
305 return DoConnect(true /* successful */, false /* sync */,
306 false /* recoverable */);
307 case kMockFailingJob:
308 return DoConnect(false /* error */, false /* sync */,
309 false /* recoverable */);
310 case kMockPendingJob:
311 set_load_state(LOAD_STATE_CONNECTING);
313 // Depending on execution timings, posting a delayed task can result
314 // in the task getting executed the at the earliest possible
315 // opportunity or only after returning once from the message loop and
316 // then a second call into the message loop. In order to make behavior
317 // more deterministic, we change the default delay to 2ms. This should
318 // always require us to wait for the second call into the message loop.
320 // N.B. The correct fix for this and similar timing problems is to
321 // abstract time for the purpose of unittests. Unfortunately, we have
322 // a lot of third-party components that directly call the various
323 // time functions, so this change would be rather invasive.
324 base::MessageLoop::current()->PostDelayedTask(
325 FROM_HERE,
326 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
327 weak_factory_.GetWeakPtr(),
328 true /* successful */,
329 true /* async */,
330 false /* recoverable */),
331 base::TimeDelta::FromMilliseconds(kPendingConnectDelay));
332 return ERR_IO_PENDING;
333 case kMockPendingFailingJob:
334 set_load_state(LOAD_STATE_CONNECTING);
335 base::MessageLoop::current()->PostDelayedTask(
336 FROM_HERE,
337 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
338 weak_factory_.GetWeakPtr(),
339 false /* error */,
340 true /* async */,
341 false /* recoverable */),
342 base::TimeDelta::FromMilliseconds(2));
343 return ERR_IO_PENDING;
344 case kMockWaitingJob:
345 set_load_state(LOAD_STATE_CONNECTING);
346 client_socket_factory_->WaitForSignal(this);
347 waiting_success_ = true;
348 return ERR_IO_PENDING;
349 case kMockRecoverableJob:
350 return DoConnect(false /* error */, false /* sync */,
351 true /* recoverable */);
352 case kMockPendingRecoverableJob:
353 set_load_state(LOAD_STATE_CONNECTING);
354 base::MessageLoop::current()->PostDelayedTask(
355 FROM_HERE,
356 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
357 weak_factory_.GetWeakPtr(),
358 false /* error */,
359 true /* async */,
360 true /* recoverable */),
361 base::TimeDelta::FromMilliseconds(2));
362 return ERR_IO_PENDING;
363 case kMockAdditionalErrorStateJob:
364 store_additional_error_state_ = true;
365 return DoConnect(false /* error */, false /* sync */,
366 false /* recoverable */);
367 case kMockPendingAdditionalErrorStateJob:
368 set_load_state(LOAD_STATE_CONNECTING);
369 store_additional_error_state_ = true;
370 base::MessageLoop::current()->PostDelayedTask(
371 FROM_HERE,
372 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
373 weak_factory_.GetWeakPtr(),
374 false /* error */,
375 true /* async */,
376 false /* recoverable */),
377 base::TimeDelta::FromMilliseconds(2));
378 return ERR_IO_PENDING;
379 case kMockUnreadDataJob: {
380 int ret = DoConnect(true /* successful */, false /* sync */,
381 false /* recoverable */);
382 static_cast<MockClientSocket*>(socket())->set_has_unread_data(true);
383 return ret;
385 default:
386 NOTREACHED();
387 SetSocket(scoped_ptr<StreamSocket>());
388 return ERR_FAILED;
392 int DoConnect(bool succeed, bool was_async, bool recoverable) {
393 int result = OK;
394 if (succeed) {
395 socket()->Connect(CompletionCallback());
396 } else if (recoverable) {
397 result = ERR_PROXY_AUTH_REQUESTED;
398 } else {
399 result = ERR_CONNECTION_FAILED;
400 SetSocket(scoped_ptr<StreamSocket>());
403 if (was_async)
404 NotifyDelegateOfCompletion(result);
405 return result;
408 bool waiting_success_;
409 const JobType job_type_;
410 MockClientSocketFactory* const client_socket_factory_;
411 LoadState load_state_;
412 bool store_additional_error_state_;
414 base::WeakPtrFactory<TestConnectJob> weak_factory_;
416 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
419 class TestConnectJobFactory
420 : public TestClientSocketPoolBase::ConnectJobFactory {
421 public:
422 TestConnectJobFactory(MockClientSocketFactory* client_socket_factory,
423 NetLog* net_log)
424 : job_type_(TestConnectJob::kMockJob),
425 job_types_(NULL),
426 client_socket_factory_(client_socket_factory),
427 net_log_(net_log) {
430 ~TestConnectJobFactory() override {}
432 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
434 void set_job_types(std::list<TestConnectJob::JobType>* job_types) {
435 job_types_ = job_types;
436 CHECK(!job_types_->empty());
439 void set_timeout_duration(base::TimeDelta timeout_duration) {
440 timeout_duration_ = timeout_duration;
443 // ConnectJobFactory implementation.
445 scoped_ptr<ConnectJob> NewConnectJob(
446 const std::string& group_name,
447 const TestClientSocketPoolBase::Request& request,
448 ConnectJob::Delegate* delegate) const override {
449 EXPECT_TRUE(!job_types_ || !job_types_->empty());
450 TestConnectJob::JobType job_type = job_type_;
451 if (job_types_ && !job_types_->empty()) {
452 job_type = job_types_->front();
453 job_types_->pop_front();
455 return scoped_ptr<ConnectJob>(new TestConnectJob(job_type,
456 group_name,
457 request,
458 timeout_duration_,
459 delegate,
460 client_socket_factory_,
461 net_log_));
464 base::TimeDelta ConnectionTimeout() const override {
465 return timeout_duration_;
468 private:
469 TestConnectJob::JobType job_type_;
470 std::list<TestConnectJob::JobType>* job_types_;
471 base::TimeDelta timeout_duration_;
472 MockClientSocketFactory* const client_socket_factory_;
473 NetLog* net_log_;
475 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
478 class TestClientSocketPool : public ClientSocketPool {
479 public:
480 typedef TestSocketParams SocketParams;
482 TestClientSocketPool(
483 int max_sockets,
484 int max_sockets_per_group,
485 base::TimeDelta unused_idle_socket_timeout,
486 base::TimeDelta used_idle_socket_timeout,
487 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
488 : base_(NULL,
489 max_sockets,
490 max_sockets_per_group,
491 unused_idle_socket_timeout,
492 used_idle_socket_timeout,
493 connect_job_factory) {}
495 ~TestClientSocketPool() override {}
497 int RequestSocket(const std::string& group_name,
498 const void* params,
499 RequestPriority priority,
500 ClientSocketHandle* handle,
501 const CompletionCallback& callback,
502 const BoundNetLog& net_log) override {
503 const scoped_refptr<TestSocketParams>* casted_socket_params =
504 static_cast<const scoped_refptr<TestSocketParams>*>(params);
505 return base_.RequestSocket(group_name, *casted_socket_params, priority,
506 handle, callback, net_log);
509 void RequestSockets(const std::string& group_name,
510 const void* params,
511 int num_sockets,
512 const BoundNetLog& net_log) override {
513 const scoped_refptr<TestSocketParams>* casted_params =
514 static_cast<const scoped_refptr<TestSocketParams>*>(params);
516 base_.RequestSockets(group_name, *casted_params, num_sockets, net_log);
519 void CancelRequest(const std::string& group_name,
520 ClientSocketHandle* handle) override {
521 base_.CancelRequest(group_name, handle);
524 void ReleaseSocket(const std::string& group_name,
525 scoped_ptr<StreamSocket> socket,
526 int id) override {
527 base_.ReleaseSocket(group_name, socket.Pass(), id);
530 void FlushWithError(int error) override { base_.FlushWithError(error); }
532 bool IsStalled() const override { return base_.IsStalled(); }
534 void CloseIdleSockets() override { base_.CloseIdleSockets(); }
536 int IdleSocketCount() const override { return base_.idle_socket_count(); }
538 int IdleSocketCountInGroup(const std::string& group_name) const override {
539 return base_.IdleSocketCountInGroup(group_name);
542 LoadState GetLoadState(const std::string& group_name,
543 const ClientSocketHandle* handle) const override {
544 return base_.GetLoadState(group_name, handle);
547 void AddHigherLayeredPool(HigherLayeredPool* higher_pool) override {
548 base_.AddHigherLayeredPool(higher_pool);
551 void RemoveHigherLayeredPool(HigherLayeredPool* higher_pool) override {
552 base_.RemoveHigherLayeredPool(higher_pool);
555 base::DictionaryValue* GetInfoAsValue(
556 const std::string& name,
557 const std::string& type,
558 bool include_nested_pools) const override {
559 return base_.GetInfoAsValue(name, type);
562 base::TimeDelta ConnectionTimeout() const override {
563 return base_.ConnectionTimeout();
566 const TestClientSocketPoolBase* base() const { return &base_; }
568 int NumUnassignedConnectJobsInGroup(const std::string& group_name) const {
569 return base_.NumUnassignedConnectJobsInGroup(group_name);
572 int NumConnectJobsInGroup(const std::string& group_name) const {
573 return base_.NumConnectJobsInGroup(group_name);
576 int NumActiveSocketsInGroup(const std::string& group_name) const {
577 return base_.NumActiveSocketsInGroup(group_name);
580 bool HasGroup(const std::string& group_name) const {
581 return base_.HasGroup(group_name);
584 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
586 void EnableConnectBackupJobs() { base_.EnableConnectBackupJobs(); }
588 bool CloseOneIdleConnectionInHigherLayeredPool() {
589 return base_.CloseOneIdleConnectionInHigherLayeredPool();
592 private:
593 TestClientSocketPoolBase base_;
595 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
598 } // namespace
600 namespace {
602 void MockClientSocketFactory::SignalJobs() {
603 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
604 it != waiting_jobs_.end(); ++it) {
605 (*it)->Signal();
607 waiting_jobs_.clear();
610 void MockClientSocketFactory::SignalJob(size_t job) {
611 ASSERT_LT(job, waiting_jobs_.size());
612 waiting_jobs_[job]->Signal();
613 waiting_jobs_.erase(waiting_jobs_.begin() + job);
616 void MockClientSocketFactory::SetJobLoadState(size_t job,
617 LoadState load_state) {
618 ASSERT_LT(job, waiting_jobs_.size());
619 waiting_jobs_[job]->set_load_state(load_state);
622 class TestConnectJobDelegate : public ConnectJob::Delegate {
623 public:
624 TestConnectJobDelegate()
625 : have_result_(false), waiting_for_result_(false), result_(OK) {}
626 ~TestConnectJobDelegate() override {}
628 void OnConnectJobComplete(int result, ConnectJob* job) override {
629 result_ = result;
630 scoped_ptr<ConnectJob> owned_job(job);
631 scoped_ptr<StreamSocket> socket = owned_job->PassSocket();
632 // socket.get() should be NULL iff result != OK
633 EXPECT_EQ(socket == NULL, result != OK);
634 have_result_ = true;
635 if (waiting_for_result_)
636 base::MessageLoop::current()->Quit();
639 int WaitForResult() {
640 DCHECK(!waiting_for_result_);
641 while (!have_result_) {
642 waiting_for_result_ = true;
643 base::MessageLoop::current()->Run();
644 waiting_for_result_ = false;
646 have_result_ = false; // auto-reset for next callback
647 return result_;
650 private:
651 bool have_result_;
652 bool waiting_for_result_;
653 int result_;
656 class ClientSocketPoolBaseTest : public testing::Test {
657 protected:
658 ClientSocketPoolBaseTest()
659 : params_(new TestSocketParams(false /* ignore_limits */)) {
660 connect_backup_jobs_enabled_ =
661 internal::ClientSocketPoolBaseHelper::connect_backup_jobs_enabled();
662 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(true);
663 cleanup_timer_enabled_ =
664 internal::ClientSocketPoolBaseHelper::cleanup_timer_enabled();
667 ~ClientSocketPoolBaseTest() override {
668 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
669 connect_backup_jobs_enabled_);
670 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(
671 cleanup_timer_enabled_);
674 void CreatePool(int max_sockets, int max_sockets_per_group) {
675 CreatePoolWithIdleTimeouts(
676 max_sockets,
677 max_sockets_per_group,
678 ClientSocketPool::unused_idle_socket_timeout(),
679 ClientSocketPool::used_idle_socket_timeout());
682 void CreatePoolWithIdleTimeouts(
683 int max_sockets, int max_sockets_per_group,
684 base::TimeDelta unused_idle_socket_timeout,
685 base::TimeDelta used_idle_socket_timeout) {
686 DCHECK(!pool_.get());
687 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_,
688 &net_log_);
689 pool_.reset(new TestClientSocketPool(max_sockets,
690 max_sockets_per_group,
691 unused_idle_socket_timeout,
692 used_idle_socket_timeout,
693 connect_job_factory_));
696 int StartRequestWithParams(
697 const std::string& group_name,
698 RequestPriority priority,
699 const scoped_refptr<TestSocketParams>& params) {
700 return test_base_.StartRequestUsingPool(
701 pool_.get(), group_name, priority, params);
704 int StartRequest(const std::string& group_name, RequestPriority priority) {
705 return StartRequestWithParams(group_name, priority, params_);
708 int GetOrderOfRequest(size_t index) const {
709 return test_base_.GetOrderOfRequest(index);
712 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
713 return test_base_.ReleaseOneConnection(keep_alive);
716 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
717 test_base_.ReleaseAllConnections(keep_alive);
720 TestSocketRequest* request(int i) { return test_base_.request(i); }
721 size_t requests_size() const { return test_base_.requests_size(); }
722 ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); }
723 size_t completion_count() const { return test_base_.completion_count(); }
725 TestNetLog net_log_;
726 bool connect_backup_jobs_enabled_;
727 bool cleanup_timer_enabled_;
728 MockClientSocketFactory client_socket_factory_;
729 TestConnectJobFactory* connect_job_factory_;
730 scoped_refptr<TestSocketParams> params_;
731 scoped_ptr<TestClientSocketPool> pool_;
732 ClientSocketPoolTest test_base_;
735 // Even though a timeout is specified, it doesn't time out on a synchronous
736 // completion.
737 TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
738 TestConnectJobDelegate delegate;
739 ClientSocketHandle ignored;
740 TestClientSocketPoolBase::Request request(
741 &ignored, CompletionCallback(), DEFAULT_PRIORITY,
742 internal::ClientSocketPoolBaseHelper::NORMAL,
743 false, params_, BoundNetLog());
744 scoped_ptr<TestConnectJob> job(
745 new TestConnectJob(TestConnectJob::kMockJob,
746 "a",
747 request,
748 base::TimeDelta::FromMicroseconds(1),
749 &delegate,
750 &client_socket_factory_,
751 NULL));
752 EXPECT_EQ(OK, job->Connect());
755 TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
756 TestConnectJobDelegate delegate;
757 ClientSocketHandle ignored;
758 TestNetLog log;
760 TestClientSocketPoolBase::Request request(
761 &ignored, CompletionCallback(), DEFAULT_PRIORITY,
762 internal::ClientSocketPoolBaseHelper::NORMAL,
763 false, params_, BoundNetLog());
764 // Deleted by TestConnectJobDelegate.
765 TestConnectJob* job =
766 new TestConnectJob(TestConnectJob::kMockPendingJob,
767 "a",
768 request,
769 base::TimeDelta::FromMicroseconds(1),
770 &delegate,
771 &client_socket_factory_,
772 &log);
773 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
774 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
775 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
777 CapturedNetLogEntry::List entries;
778 log.GetEntries(&entries);
780 EXPECT_EQ(6u, entries.size());
781 EXPECT_TRUE(LogContainsBeginEvent(
782 entries, 0, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
783 EXPECT_TRUE(LogContainsBeginEvent(
784 entries, 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
785 EXPECT_TRUE(LogContainsEvent(
786 entries, 2, NetLog::TYPE_CONNECT_JOB_SET_SOCKET,
787 NetLog::PHASE_NONE));
788 EXPECT_TRUE(LogContainsEvent(
789 entries, 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
790 NetLog::PHASE_NONE));
791 EXPECT_TRUE(LogContainsEndEvent(
792 entries, 4, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
793 EXPECT_TRUE(LogContainsEndEvent(
794 entries, 5, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
797 TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
798 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
800 TestCompletionCallback callback;
801 ClientSocketHandle handle;
802 BoundTestNetLog log;
803 TestLoadTimingInfoNotConnected(handle);
805 EXPECT_EQ(OK,
806 handle.Init("a",
807 params_,
808 DEFAULT_PRIORITY,
809 callback.callback(),
810 pool_.get(),
811 log.bound()));
812 EXPECT_TRUE(handle.is_initialized());
813 EXPECT_TRUE(handle.socket());
814 TestLoadTimingInfoConnectedNotReused(handle);
816 handle.Reset();
817 TestLoadTimingInfoNotConnected(handle);
819 CapturedNetLogEntry::List entries;
820 log.GetEntries(&entries);
822 EXPECT_EQ(4u, entries.size());
823 EXPECT_TRUE(LogContainsBeginEvent(
824 entries, 0, NetLog::TYPE_SOCKET_POOL));
825 EXPECT_TRUE(LogContainsEvent(
826 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
827 NetLog::PHASE_NONE));
828 EXPECT_TRUE(LogContainsEvent(
829 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
830 NetLog::PHASE_NONE));
831 EXPECT_TRUE(LogContainsEndEvent(
832 entries, 3, NetLog::TYPE_SOCKET_POOL));
835 TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
836 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
838 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
839 BoundTestNetLog log;
841 ClientSocketHandle handle;
842 TestCompletionCallback callback;
843 // Set the additional error state members to ensure that they get cleared.
844 handle.set_is_ssl_error(true);
845 HttpResponseInfo info;
846 info.headers = new HttpResponseHeaders(std::string());
847 handle.set_ssl_error_response_info(info);
848 EXPECT_EQ(ERR_CONNECTION_FAILED,
849 handle.Init("a",
850 params_,
851 DEFAULT_PRIORITY,
852 callback.callback(),
853 pool_.get(),
854 log.bound()));
855 EXPECT_FALSE(handle.socket());
856 EXPECT_FALSE(handle.is_ssl_error());
857 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
858 TestLoadTimingInfoNotConnected(handle);
860 CapturedNetLogEntry::List entries;
861 log.GetEntries(&entries);
863 EXPECT_EQ(3u, entries.size());
864 EXPECT_TRUE(LogContainsBeginEvent(
865 entries, 0, NetLog::TYPE_SOCKET_POOL));
866 EXPECT_TRUE(LogContainsEvent(
867 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
868 NetLog::PHASE_NONE));
869 EXPECT_TRUE(LogContainsEndEvent(
870 entries, 2, NetLog::TYPE_SOCKET_POOL));
873 TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
874 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
876 // TODO(eroman): Check that the NetLog contains this event.
878 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
879 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
880 EXPECT_EQ(OK, StartRequest("c", DEFAULT_PRIORITY));
881 EXPECT_EQ(OK, StartRequest("d", DEFAULT_PRIORITY));
883 EXPECT_EQ(static_cast<int>(requests_size()),
884 client_socket_factory_.allocation_count());
885 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
887 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", DEFAULT_PRIORITY));
888 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", DEFAULT_PRIORITY));
889 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", DEFAULT_PRIORITY));
891 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
893 EXPECT_EQ(static_cast<int>(requests_size()),
894 client_socket_factory_.allocation_count());
895 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
897 EXPECT_EQ(1, GetOrderOfRequest(1));
898 EXPECT_EQ(2, GetOrderOfRequest(2));
899 EXPECT_EQ(3, GetOrderOfRequest(3));
900 EXPECT_EQ(4, GetOrderOfRequest(4));
901 EXPECT_EQ(5, GetOrderOfRequest(5));
902 EXPECT_EQ(6, GetOrderOfRequest(6));
903 EXPECT_EQ(7, GetOrderOfRequest(7));
905 // Make sure we test order of all requests made.
906 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
909 TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
910 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
912 // TODO(eroman): Check that the NetLog contains this event.
914 // Reach all limits: max total sockets, and max sockets per group.
915 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
916 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
917 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
918 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
920 EXPECT_EQ(static_cast<int>(requests_size()),
921 client_socket_factory_.allocation_count());
922 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
924 // Now create a new group and verify that we don't starve it.
925 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", DEFAULT_PRIORITY));
927 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
929 EXPECT_EQ(static_cast<int>(requests_size()),
930 client_socket_factory_.allocation_count());
931 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
933 EXPECT_EQ(1, GetOrderOfRequest(1));
934 EXPECT_EQ(2, GetOrderOfRequest(2));
935 EXPECT_EQ(3, GetOrderOfRequest(3));
936 EXPECT_EQ(4, GetOrderOfRequest(4));
937 EXPECT_EQ(5, GetOrderOfRequest(5));
939 // Make sure we test order of all requests made.
940 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
943 TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
944 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
946 EXPECT_EQ(OK, StartRequest("b", LOWEST));
947 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
948 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
949 EXPECT_EQ(OK, StartRequest("a", LOWEST));
951 EXPECT_EQ(static_cast<int>(requests_size()),
952 client_socket_factory_.allocation_count());
954 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
955 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
956 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
958 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
960 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
962 // First 4 requests don't have to wait, and finish in order.
963 EXPECT_EQ(1, GetOrderOfRequest(1));
964 EXPECT_EQ(2, GetOrderOfRequest(2));
965 EXPECT_EQ(3, GetOrderOfRequest(3));
966 EXPECT_EQ(4, GetOrderOfRequest(4));
968 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
969 // and then ("c", LOWEST).
970 EXPECT_EQ(7, GetOrderOfRequest(5));
971 EXPECT_EQ(6, GetOrderOfRequest(6));
972 EXPECT_EQ(5, GetOrderOfRequest(7));
974 // Make sure we test order of all requests made.
975 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
978 TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
979 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
981 EXPECT_EQ(OK, StartRequest("a", LOWEST));
982 EXPECT_EQ(OK, StartRequest("a", LOW));
983 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
984 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
986 EXPECT_EQ(static_cast<int>(requests_size()),
987 client_socket_factory_.allocation_count());
989 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
990 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
991 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
993 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
995 EXPECT_EQ(static_cast<int>(requests_size()),
996 client_socket_factory_.allocation_count());
997 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
999 // First 4 requests don't have to wait, and finish in order.
1000 EXPECT_EQ(1, GetOrderOfRequest(1));
1001 EXPECT_EQ(2, GetOrderOfRequest(2));
1002 EXPECT_EQ(3, GetOrderOfRequest(3));
1003 EXPECT_EQ(4, GetOrderOfRequest(4));
1005 // Request ("b", 7) has the highest priority, but we can't make new socket for
1006 // group "b", because it has reached the per-group limit. Then we make
1007 // socket for ("c", 6), because it has higher priority than ("a", 4),
1008 // and we still can't make a socket for group "b".
1009 EXPECT_EQ(5, GetOrderOfRequest(5));
1010 EXPECT_EQ(6, GetOrderOfRequest(6));
1011 EXPECT_EQ(7, GetOrderOfRequest(7));
1013 // Make sure we test order of all requests made.
1014 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
1017 // Make sure that we count connecting sockets against the total limit.
1018 TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
1019 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1021 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1022 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
1023 EXPECT_EQ(OK, StartRequest("c", DEFAULT_PRIORITY));
1025 // Create one asynchronous request.
1026 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1027 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", DEFAULT_PRIORITY));
1029 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1030 // actually become pending until 2ms after they have been created. In order
1031 // to flush all tasks, we need to wait so that we know there are no
1032 // soon-to-be-pending tasks waiting.
1033 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
1034 base::MessageLoop::current()->RunUntilIdle();
1036 // The next synchronous request should wait for its turn.
1037 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1038 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", DEFAULT_PRIORITY));
1040 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1042 EXPECT_EQ(static_cast<int>(requests_size()),
1043 client_socket_factory_.allocation_count());
1045 EXPECT_EQ(1, GetOrderOfRequest(1));
1046 EXPECT_EQ(2, GetOrderOfRequest(2));
1047 EXPECT_EQ(3, GetOrderOfRequest(3));
1048 EXPECT_EQ(4, GetOrderOfRequest(4));
1049 EXPECT_EQ(5, GetOrderOfRequest(5));
1051 // Make sure we test order of all requests made.
1052 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
1055 TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
1056 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1057 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1059 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1060 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1061 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1062 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1064 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1066 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1068 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", DEFAULT_PRIORITY));
1069 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", DEFAULT_PRIORITY));
1071 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1073 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1074 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1075 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1076 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
1077 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1078 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1079 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
1082 TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
1083 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1084 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1086 ClientSocketHandle handle;
1087 TestCompletionCallback callback;
1088 EXPECT_EQ(ERR_IO_PENDING,
1089 handle.Init("a",
1090 params_,
1091 DEFAULT_PRIORITY,
1092 callback.callback(),
1093 pool_.get(),
1094 BoundNetLog()));
1096 ClientSocketHandle handles[4];
1097 for (size_t i = 0; i < arraysize(handles); ++i) {
1098 TestCompletionCallback callback;
1099 EXPECT_EQ(ERR_IO_PENDING,
1100 handles[i].Init("b",
1101 params_,
1102 DEFAULT_PRIORITY,
1103 callback.callback(),
1104 pool_.get(),
1105 BoundNetLog()));
1108 // One will be stalled, cancel all the handles now.
1109 // This should hit the OnAvailableSocketSlot() code where we previously had
1110 // stalled groups, but no longer have any.
1111 for (size_t i = 0; i < arraysize(handles); ++i)
1112 handles[i].Reset();
1115 TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
1116 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1117 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1120 ClientSocketHandle handles[kDefaultMaxSockets];
1121 TestCompletionCallback callbacks[kDefaultMaxSockets];
1122 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1123 EXPECT_EQ(OK, handles[i].Init(base::IntToString(i),
1124 params_,
1125 DEFAULT_PRIORITY,
1126 callbacks[i].callback(),
1127 pool_.get(),
1128 BoundNetLog()));
1131 // Force a stalled group.
1132 ClientSocketHandle stalled_handle;
1133 TestCompletionCallback callback;
1134 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1135 params_,
1136 DEFAULT_PRIORITY,
1137 callback.callback(),
1138 pool_.get(),
1139 BoundNetLog()));
1141 // Cancel the stalled request.
1142 stalled_handle.Reset();
1144 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1145 EXPECT_EQ(0, pool_->IdleSocketCount());
1147 // Dropping out of scope will close all handles and return them to idle.
1150 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1151 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
1154 TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
1155 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1156 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1159 ClientSocketHandle handles[kDefaultMaxSockets];
1160 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1161 TestCompletionCallback callback;
1162 EXPECT_EQ(ERR_IO_PENDING, handles[i].Init(base::IntToString(i),
1163 params_,
1164 DEFAULT_PRIORITY,
1165 callback.callback(),
1166 pool_.get(),
1167 BoundNetLog()));
1170 // Force a stalled group.
1171 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1172 ClientSocketHandle stalled_handle;
1173 TestCompletionCallback callback;
1174 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1175 params_,
1176 DEFAULT_PRIORITY,
1177 callback.callback(),
1178 pool_.get(),
1179 BoundNetLog()));
1181 // Since it is stalled, it should have no connect jobs.
1182 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
1183 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
1185 // Cancel the stalled request.
1186 handles[0].Reset();
1188 // Now we should have a connect job.
1189 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("foo"));
1190 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
1192 // The stalled socket should connect.
1193 EXPECT_EQ(OK, callback.WaitForResult());
1195 EXPECT_EQ(kDefaultMaxSockets + 1,
1196 client_socket_factory_.allocation_count());
1197 EXPECT_EQ(0, pool_->IdleSocketCount());
1198 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
1199 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
1201 // Dropping out of scope will close all handles and return them to idle.
1204 EXPECT_EQ(1, pool_->IdleSocketCount());
1207 TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1208 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1209 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1211 ClientSocketHandle stalled_handle;
1212 TestCompletionCallback callback;
1214 EXPECT_FALSE(pool_->IsStalled());
1215 ClientSocketHandle handles[kDefaultMaxSockets];
1216 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1217 TestCompletionCallback callback;
1218 EXPECT_EQ(OK, handles[i].Init(base::StringPrintf(
1219 "Take 2: %d", i),
1220 params_,
1221 DEFAULT_PRIORITY,
1222 callback.callback(),
1223 pool_.get(),
1224 BoundNetLog()));
1227 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1228 EXPECT_EQ(0, pool_->IdleSocketCount());
1229 EXPECT_FALSE(pool_->IsStalled());
1231 // Now we will hit the socket limit.
1232 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1233 params_,
1234 DEFAULT_PRIORITY,
1235 callback.callback(),
1236 pool_.get(),
1237 BoundNetLog()));
1238 EXPECT_TRUE(pool_->IsStalled());
1240 // Dropping out of scope will close all handles and return them to idle.
1243 // But if we wait for it, the released idle sockets will be closed in
1244 // preference of the waiting request.
1245 EXPECT_EQ(OK, callback.WaitForResult());
1247 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1248 EXPECT_EQ(3, pool_->IdleSocketCount());
1251 // Regression test for http://crbug.com/40952.
1252 TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1253 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1254 pool_->EnableConnectBackupJobs();
1255 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1257 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1258 ClientSocketHandle handle;
1259 TestCompletionCallback callback;
1260 EXPECT_EQ(OK, handle.Init(base::IntToString(i),
1261 params_,
1262 DEFAULT_PRIORITY,
1263 callback.callback(),
1264 pool_.get(),
1265 BoundNetLog()));
1268 // Flush all the DoReleaseSocket tasks.
1269 base::MessageLoop::current()->RunUntilIdle();
1271 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1272 // reuse a socket.
1273 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1274 ClientSocketHandle handle;
1275 TestCompletionCallback callback;
1277 // "0" is special here, since it should be the first entry in the sorted map,
1278 // which is the one which we would close an idle socket for. We shouldn't
1279 // close an idle socket though, since we should reuse the idle socket.
1280 EXPECT_EQ(OK, handle.Init("0",
1281 params_,
1282 DEFAULT_PRIORITY,
1283 callback.callback(),
1284 pool_.get(),
1285 BoundNetLog()));
1287 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1288 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1291 TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
1292 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1294 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1295 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1296 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", IDLE));
1297 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1298 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1299 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1300 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1301 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1303 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
1305 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1306 client_socket_factory_.allocation_count());
1307 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1308 completion_count());
1310 EXPECT_EQ(1, GetOrderOfRequest(1));
1311 EXPECT_EQ(2, GetOrderOfRequest(2));
1312 EXPECT_EQ(8, GetOrderOfRequest(3));
1313 EXPECT_EQ(6, GetOrderOfRequest(4));
1314 EXPECT_EQ(4, GetOrderOfRequest(5));
1315 EXPECT_EQ(3, GetOrderOfRequest(6));
1316 EXPECT_EQ(5, GetOrderOfRequest(7));
1317 EXPECT_EQ(7, GetOrderOfRequest(8));
1319 // Make sure we test order of all requests made.
1320 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
1323 TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
1324 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1326 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1327 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1328 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1329 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1330 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1331 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1332 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1334 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1336 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
1337 EXPECT_EQ(OK, request(i)->WaitForResult());
1339 EXPECT_EQ(static_cast<int>(requests_size()),
1340 client_socket_factory_.allocation_count());
1341 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1342 completion_count());
1345 // This test will start up a RequestSocket() and then immediately Cancel() it.
1346 // The pending connect job will be cancelled and should not call back into
1347 // ClientSocketPoolBase.
1348 TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
1349 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1351 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1352 ClientSocketHandle handle;
1353 TestCompletionCallback callback;
1354 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1355 params_,
1356 DEFAULT_PRIORITY,
1357 callback.callback(),
1358 pool_.get(),
1359 BoundNetLog()));
1360 handle.Reset();
1363 TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
1364 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1366 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1367 ClientSocketHandle handle;
1368 TestCompletionCallback callback;
1370 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1371 params_,
1372 DEFAULT_PRIORITY,
1373 callback.callback(),
1374 pool_.get(),
1375 BoundNetLog()));
1377 handle.Reset();
1379 TestCompletionCallback callback2;
1380 EXPECT_EQ(ERR_IO_PENDING,
1381 handle.Init("a",
1382 params_,
1383 DEFAULT_PRIORITY,
1384 callback2.callback(),
1385 pool_.get(),
1386 BoundNetLog()));
1388 EXPECT_EQ(OK, callback2.WaitForResult());
1389 EXPECT_FALSE(callback.have_result());
1391 handle.Reset();
1394 TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
1395 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1397 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1398 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1399 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1400 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1401 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1402 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1403 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1405 // Cancel a request.
1406 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
1407 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1408 (*requests())[index_to_cancel]->handle()->Reset();
1410 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
1412 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1413 client_socket_factory_.allocation_count());
1414 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1415 completion_count());
1417 EXPECT_EQ(1, GetOrderOfRequest(1));
1418 EXPECT_EQ(2, GetOrderOfRequest(2));
1419 EXPECT_EQ(5, GetOrderOfRequest(3));
1420 EXPECT_EQ(3, GetOrderOfRequest(4));
1421 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1422 GetOrderOfRequest(5)); // Canceled request.
1423 EXPECT_EQ(4, GetOrderOfRequest(6));
1424 EXPECT_EQ(6, GetOrderOfRequest(7));
1426 // Make sure we test order of all requests made.
1427 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
1430 class RequestSocketCallback : public TestCompletionCallbackBase {
1431 public:
1432 RequestSocketCallback(ClientSocketHandle* handle,
1433 TestClientSocketPool* pool,
1434 TestConnectJobFactory* test_connect_job_factory,
1435 TestConnectJob::JobType next_job_type)
1436 : handle_(handle),
1437 pool_(pool),
1438 within_callback_(false),
1439 test_connect_job_factory_(test_connect_job_factory),
1440 next_job_type_(next_job_type),
1441 callback_(base::Bind(&RequestSocketCallback::OnComplete,
1442 base::Unretained(this))) {
1445 ~RequestSocketCallback() override {}
1447 const CompletionCallback& callback() const { return callback_; }
1449 private:
1450 void OnComplete(int result) {
1451 SetResult(result);
1452 ASSERT_EQ(OK, result);
1454 if (!within_callback_) {
1455 test_connect_job_factory_->set_job_type(next_job_type_);
1457 // Don't allow reuse of the socket. Disconnect it and then release it and
1458 // run through the MessageLoop once to get it completely released.
1459 handle_->socket()->Disconnect();
1460 handle_->Reset();
1462 // TODO: Resolve conflicting intentions of stopping recursion with the
1463 // |!within_callback_| test (above) and the call to |RunUntilIdle()|
1464 // below. http://crbug.com/114130.
1465 base::MessageLoop::ScopedNestableTaskAllower allow(
1466 base::MessageLoop::current());
1467 base::MessageLoop::current()->RunUntilIdle();
1469 within_callback_ = true;
1470 TestCompletionCallback next_job_callback;
1471 scoped_refptr<TestSocketParams> params(
1472 new TestSocketParams(false /* ignore_limits */));
1473 int rv = handle_->Init("a",
1474 params,
1475 DEFAULT_PRIORITY,
1476 next_job_callback.callback(),
1477 pool_,
1478 BoundNetLog());
1479 switch (next_job_type_) {
1480 case TestConnectJob::kMockJob:
1481 EXPECT_EQ(OK, rv);
1482 break;
1483 case TestConnectJob::kMockPendingJob:
1484 EXPECT_EQ(ERR_IO_PENDING, rv);
1486 // For pending jobs, wait for new socket to be created. This makes
1487 // sure there are no more pending operations nor any unclosed sockets
1488 // when the test finishes.
1489 // We need to give it a little bit of time to run, so that all the
1490 // operations that happen on timers (e.g. cleanup of idle
1491 // connections) can execute.
1493 base::MessageLoop::ScopedNestableTaskAllower allow(
1494 base::MessageLoop::current());
1495 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
1496 EXPECT_EQ(OK, next_job_callback.WaitForResult());
1498 break;
1499 default:
1500 FAIL() << "Unexpected job type: " << next_job_type_;
1501 break;
1506 ClientSocketHandle* const handle_;
1507 TestClientSocketPool* const pool_;
1508 bool within_callback_;
1509 TestConnectJobFactory* const test_connect_job_factory_;
1510 TestConnectJob::JobType next_job_type_;
1511 CompletionCallback callback_;
1514 TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
1515 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1517 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1518 ClientSocketHandle handle;
1519 RequestSocketCallback callback(
1520 &handle, pool_.get(), connect_job_factory_,
1521 TestConnectJob::kMockPendingJob);
1522 int rv = handle.Init("a",
1523 params_,
1524 DEFAULT_PRIORITY,
1525 callback.callback(),
1526 pool_.get(),
1527 BoundNetLog());
1528 ASSERT_EQ(ERR_IO_PENDING, rv);
1530 EXPECT_EQ(OK, callback.WaitForResult());
1533 TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
1534 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1536 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1537 ClientSocketHandle handle;
1538 RequestSocketCallback callback(
1539 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
1540 int rv = handle.Init("a",
1541 params_,
1542 DEFAULT_PRIORITY,
1543 callback.callback(),
1544 pool_.get(),
1545 BoundNetLog());
1546 ASSERT_EQ(ERR_IO_PENDING, rv);
1548 EXPECT_EQ(OK, callback.WaitForResult());
1551 // Make sure that pending requests get serviced after active requests get
1552 // cancelled.
1553 TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
1554 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1556 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1558 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1559 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1560 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1561 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1562 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1563 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1564 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1566 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1567 // Let's cancel them.
1568 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
1569 ASSERT_FALSE(request(i)->handle()->is_initialized());
1570 request(i)->handle()->Reset();
1573 // Let's wait for the rest to complete now.
1574 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
1575 EXPECT_EQ(OK, request(i)->WaitForResult());
1576 request(i)->handle()->Reset();
1579 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1580 completion_count());
1583 // Make sure that pending requests get serviced after active requests fail.
1584 TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
1585 const size_t kMaxSockets = 5;
1586 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
1588 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1590 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1591 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
1593 // Queue up all the requests
1594 for (size_t i = 0; i < kNumberOfRequests; ++i)
1595 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1597 for (size_t i = 0; i < kNumberOfRequests; ++i)
1598 EXPECT_EQ(ERR_CONNECTION_FAILED, request(i)->WaitForResult());
1601 TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
1602 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1604 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1606 ClientSocketHandle handle;
1607 TestCompletionCallback callback;
1608 int rv = handle.Init("a",
1609 params_,
1610 DEFAULT_PRIORITY,
1611 callback.callback(),
1612 pool_.get(),
1613 BoundNetLog());
1614 EXPECT_EQ(ERR_IO_PENDING, rv);
1616 // Cancel the active request.
1617 handle.Reset();
1619 rv = handle.Init("a",
1620 params_,
1621 DEFAULT_PRIORITY,
1622 callback.callback(),
1623 pool_.get(),
1624 BoundNetLog());
1625 EXPECT_EQ(ERR_IO_PENDING, rv);
1626 EXPECT_EQ(OK, callback.WaitForResult());
1628 EXPECT_FALSE(handle.is_reused());
1629 TestLoadTimingInfoConnectedNotReused(handle);
1630 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1633 // Regression test for http://crbug.com/17985.
1634 TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1635 const int kMaxSockets = 3;
1636 const int kMaxSocketsPerGroup = 2;
1637 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1639 const RequestPriority kHighPriority = HIGHEST;
1641 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1642 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1644 // This is going to be a pending request in an otherwise empty group.
1645 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1647 // Reach the maximum socket limit.
1648 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
1650 // Create a stalled group with high priorities.
1651 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1652 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1654 // Release the first two sockets from "a". Because this is a keepalive,
1655 // the first release will unblock the pending request for "a". The
1656 // second release will unblock a request for "c", becaue it is the next
1657 // high priority socket.
1658 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1659 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1661 // Closing idle sockets should not get us into trouble, but in the bug
1662 // we were hitting a CHECK here.
1663 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1664 pool_->CloseIdleSockets();
1666 // Run the released socket wakeups.
1667 base::MessageLoop::current()->RunUntilIdle();
1670 TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
1671 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1673 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1674 ClientSocketHandle handle;
1675 TestCompletionCallback callback;
1676 BoundTestNetLog log;
1677 int rv = handle.Init("a",
1678 params_,
1679 LOWEST,
1680 callback.callback(),
1681 pool_.get(),
1682 log.bound());
1683 EXPECT_EQ(ERR_IO_PENDING, rv);
1684 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1685 TestLoadTimingInfoNotConnected(handle);
1687 EXPECT_EQ(OK, callback.WaitForResult());
1688 EXPECT_TRUE(handle.is_initialized());
1689 EXPECT_TRUE(handle.socket());
1690 TestLoadTimingInfoConnectedNotReused(handle);
1692 handle.Reset();
1693 TestLoadTimingInfoNotConnected(handle);
1695 CapturedNetLogEntry::List entries;
1696 log.GetEntries(&entries);
1698 EXPECT_EQ(4u, entries.size());
1699 EXPECT_TRUE(LogContainsBeginEvent(
1700 entries, 0, NetLog::TYPE_SOCKET_POOL));
1701 EXPECT_TRUE(LogContainsEvent(
1702 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1703 NetLog::PHASE_NONE));
1704 EXPECT_TRUE(LogContainsEvent(
1705 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
1706 NetLog::PHASE_NONE));
1707 EXPECT_TRUE(LogContainsEndEvent(
1708 entries, 3, NetLog::TYPE_SOCKET_POOL));
1711 TEST_F(ClientSocketPoolBaseTest,
1712 InitConnectionAsynchronousFailure) {
1713 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1715 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1716 ClientSocketHandle handle;
1717 TestCompletionCallback callback;
1718 BoundTestNetLog log;
1719 // Set the additional error state members to ensure that they get cleared.
1720 handle.set_is_ssl_error(true);
1721 HttpResponseInfo info;
1722 info.headers = new HttpResponseHeaders(std::string());
1723 handle.set_ssl_error_response_info(info);
1724 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1725 params_,
1726 DEFAULT_PRIORITY,
1727 callback.callback(),
1728 pool_.get(),
1729 log.bound()));
1730 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1731 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1732 EXPECT_FALSE(handle.is_ssl_error());
1733 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
1735 CapturedNetLogEntry::List entries;
1736 log.GetEntries(&entries);
1738 EXPECT_EQ(3u, entries.size());
1739 EXPECT_TRUE(LogContainsBeginEvent(
1740 entries, 0, NetLog::TYPE_SOCKET_POOL));
1741 EXPECT_TRUE(LogContainsEvent(
1742 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1743 NetLog::PHASE_NONE));
1744 EXPECT_TRUE(LogContainsEndEvent(
1745 entries, 2, NetLog::TYPE_SOCKET_POOL));
1748 // Check that an async ConnectJob failure does not result in creation of a new
1749 // ConnectJob when there's another pending request also waiting on its own
1750 // ConnectJob. See http://crbug.com/463960.
1751 TEST_F(ClientSocketPoolBaseTest, AsyncFailureWithPendingRequestWithJob) {
1752 CreatePool(2, 2);
1753 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1755 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1756 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1758 EXPECT_EQ(ERR_CONNECTION_FAILED, request(0)->WaitForResult());
1759 EXPECT_EQ(ERR_CONNECTION_FAILED, request(1)->WaitForResult());
1761 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1764 TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
1765 // TODO(eroman): Add back the log expectations! Removed them because the
1766 // ordering is difficult, and some may fire during destructor.
1767 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1769 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1770 ClientSocketHandle handle;
1771 TestCompletionCallback callback;
1772 ClientSocketHandle handle2;
1773 TestCompletionCallback callback2;
1775 EXPECT_EQ(ERR_IO_PENDING,
1776 handle.Init("a",
1777 params_,
1778 DEFAULT_PRIORITY,
1779 callback.callback(),
1780 pool_.get(),
1781 BoundNetLog()));
1782 BoundTestNetLog log2;
1783 EXPECT_EQ(ERR_IO_PENDING,
1784 handle2.Init("a",
1785 params_,
1786 DEFAULT_PRIORITY,
1787 callback2.callback(),
1788 pool_.get(),
1789 BoundNetLog()));
1791 handle.Reset();
1794 // At this point, request 2 is just waiting for the connect job to finish.
1796 EXPECT_EQ(OK, callback2.WaitForResult());
1797 handle2.Reset();
1799 // Now request 2 has actually finished.
1800 // TODO(eroman): Add back log expectations.
1803 TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
1804 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1806 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1808 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1809 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1810 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1811 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1813 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1814 (*requests())[2]->handle()->Reset();
1815 (*requests())[3]->handle()->Reset();
1816 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1818 (*requests())[1]->handle()->Reset();
1819 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1821 (*requests())[0]->handle()->Reset();
1822 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1825 // When requests and ConnectJobs are not coupled, the request will get serviced
1826 // by whatever comes first.
1827 TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
1828 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1830 // Start job 1 (async OK)
1831 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1833 std::vector<TestSocketRequest*> request_order;
1834 size_t completion_count; // unused
1835 TestSocketRequest req1(&request_order, &completion_count);
1836 int rv = req1.handle()->Init("a",
1837 params_,
1838 DEFAULT_PRIORITY,
1839 req1.callback(), pool_.get(),
1840 BoundNetLog());
1841 EXPECT_EQ(ERR_IO_PENDING, rv);
1842 EXPECT_EQ(OK, req1.WaitForResult());
1844 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1845 // without a job.
1846 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1848 TestSocketRequest req2(&request_order, &completion_count);
1849 rv = req2.handle()->Init("a",
1850 params_,
1851 DEFAULT_PRIORITY,
1852 req2.callback(),
1853 pool_.get(),
1854 BoundNetLog());
1855 EXPECT_EQ(ERR_IO_PENDING, rv);
1856 TestSocketRequest req3(&request_order, &completion_count);
1857 rv = req3.handle()->Init("a",
1858 params_,
1859 DEFAULT_PRIORITY,
1860 req3.callback(),
1861 pool_.get(),
1862 BoundNetLog());
1863 EXPECT_EQ(ERR_IO_PENDING, rv);
1865 // Both Requests 2 and 3 are pending. We release socket 1 which should
1866 // service request 2. Request 3 should still be waiting.
1867 req1.handle()->Reset();
1868 // Run the released socket wakeups.
1869 base::MessageLoop::current()->RunUntilIdle();
1870 ASSERT_TRUE(req2.handle()->socket());
1871 EXPECT_EQ(OK, req2.WaitForResult());
1872 EXPECT_FALSE(req3.handle()->socket());
1874 // Signal job 2, which should service request 3.
1876 client_socket_factory_.SignalJobs();
1877 EXPECT_EQ(OK, req3.WaitForResult());
1879 ASSERT_EQ(3U, request_order.size());
1880 EXPECT_EQ(&req1, request_order[0]);
1881 EXPECT_EQ(&req2, request_order[1]);
1882 EXPECT_EQ(&req3, request_order[2]);
1883 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1886 // The requests are not coupled to the jobs. So, the requests should finish in
1887 // their priority / insertion order.
1888 TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
1889 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1890 // First two jobs are async.
1891 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1893 std::vector<TestSocketRequest*> request_order;
1894 size_t completion_count; // unused
1895 TestSocketRequest req1(&request_order, &completion_count);
1896 int rv = req1.handle()->Init("a",
1897 params_,
1898 DEFAULT_PRIORITY,
1899 req1.callback(),
1900 pool_.get(),
1901 BoundNetLog());
1902 EXPECT_EQ(ERR_IO_PENDING, rv);
1904 TestSocketRequest req2(&request_order, &completion_count);
1905 rv = req2.handle()->Init("a",
1906 params_,
1907 DEFAULT_PRIORITY,
1908 req2.callback(),
1909 pool_.get(),
1910 BoundNetLog());
1911 EXPECT_EQ(ERR_IO_PENDING, rv);
1913 // The pending job is sync.
1914 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1916 TestSocketRequest req3(&request_order, &completion_count);
1917 rv = req3.handle()->Init("a",
1918 params_,
1919 DEFAULT_PRIORITY,
1920 req3.callback(),
1921 pool_.get(),
1922 BoundNetLog());
1923 EXPECT_EQ(ERR_IO_PENDING, rv);
1925 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1926 EXPECT_EQ(OK, req2.WaitForResult());
1927 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1929 ASSERT_EQ(3U, request_order.size());
1930 EXPECT_EQ(&req1, request_order[0]);
1931 EXPECT_EQ(&req2, request_order[1]);
1932 EXPECT_EQ(&req3, request_order[2]);
1935 // Test GetLoadState in the case there's only one socket request.
1936 TEST_F(ClientSocketPoolBaseTest, LoadStateOneRequest) {
1937 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1938 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1940 ClientSocketHandle handle;
1941 TestCompletionCallback callback;
1942 int rv = handle.Init("a",
1943 params_,
1944 DEFAULT_PRIORITY,
1945 callback.callback(),
1946 pool_.get(),
1947 BoundNetLog());
1948 EXPECT_EQ(ERR_IO_PENDING, rv);
1949 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
1951 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
1952 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
1954 // No point in completing the connection, since ClientSocketHandles only
1955 // expect the LoadState to be checked while connecting.
1958 // Test GetLoadState in the case there are two socket requests.
1959 // Only the first connection in the pool should affect the pool's load status.
1960 TEST_F(ClientSocketPoolBaseTest, LoadStateTwoRequests) {
1961 CreatePool(2, 2);
1962 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1964 ClientSocketHandle handle;
1965 TestCompletionCallback callback;
1966 int rv = handle.Init("a", params_, DEFAULT_PRIORITY, callback.callback(),
1967 pool_.get(), BoundNetLog());
1968 EXPECT_EQ(ERR_IO_PENDING, rv);
1969 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
1971 ClientSocketHandle handle2;
1972 TestCompletionCallback callback2;
1973 rv = handle2.Init("a", params_, DEFAULT_PRIORITY, callback2.callback(),
1974 pool_.get(), BoundNetLog());
1975 EXPECT_EQ(ERR_IO_PENDING, rv);
1976 client_socket_factory_.SetJobLoadState(1, LOAD_STATE_RESOLVING_HOST);
1978 // Check that both handles report the state of the first job.
1979 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle.GetLoadState());
1980 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle2.GetLoadState());
1982 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_CONNECTING);
1984 // Check that both handles change to LOAD_STATE_CONNECTING.
1985 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
1986 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
1989 // Test that the second connection request does not affect the pool's load
1990 // status.
1991 TEST_F(ClientSocketPoolBaseTest, LoadStateTwoRequestsChangeSecondRequestState) {
1992 CreatePool(2, 2);
1993 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1995 ClientSocketHandle handle;
1996 TestCompletionCallback callback;
1997 int rv = handle.Init("a", params_, DEFAULT_PRIORITY, callback.callback(),
1998 pool_.get(), BoundNetLog());
1999 EXPECT_EQ(ERR_IO_PENDING, rv);
2001 ClientSocketHandle handle2;
2002 TestCompletionCallback callback2;
2003 rv = handle2.Init("a", params_, DEFAULT_PRIORITY, callback2.callback(),
2004 pool_.get(), BoundNetLog());
2005 EXPECT_EQ(ERR_IO_PENDING, rv);
2006 client_socket_factory_.SetJobLoadState(1, LOAD_STATE_RESOLVING_HOST);
2008 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2009 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
2011 // First job connects and the first request gets the socket. The
2012 // second handle switches to the state of the remaining ConnectJob.
2013 client_socket_factory_.SignalJob(0);
2014 EXPECT_EQ(OK, callback.WaitForResult());
2015 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle2.GetLoadState());
2018 // Test GetLoadState in the case the per-group limit is reached.
2019 TEST_F(ClientSocketPoolBaseTest, LoadStateGroupLimit) {
2020 CreatePool(2, 1);
2021 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2023 ClientSocketHandle handle;
2024 TestCompletionCallback callback;
2025 int rv = handle.Init("a",
2026 params_,
2027 MEDIUM,
2028 callback.callback(),
2029 pool_.get(),
2030 BoundNetLog());
2031 EXPECT_EQ(ERR_IO_PENDING, rv);
2032 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2034 // Request another socket from the same pool, buth with a higher priority.
2035 // The first request should now be stalled at the socket group limit.
2036 ClientSocketHandle handle2;
2037 TestCompletionCallback callback2;
2038 rv = handle2.Init("a",
2039 params_,
2040 HIGHEST,
2041 callback2.callback(),
2042 pool_.get(),
2043 BoundNetLog());
2044 EXPECT_EQ(ERR_IO_PENDING, rv);
2045 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2046 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
2048 // The first handle should remain stalled as the other socket goes through
2049 // the connect process.
2051 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2052 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2053 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle2.GetLoadState());
2055 client_socket_factory_.SignalJob(0);
2056 EXPECT_EQ(OK, callback2.WaitForResult());
2057 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2059 // Closing the second socket should cause the stalled handle to finally get a
2060 // ConnectJob.
2061 handle2.socket()->Disconnect();
2062 handle2.Reset();
2063 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2066 // Test GetLoadState in the case the per-pool limit is reached.
2067 TEST_F(ClientSocketPoolBaseTest, LoadStatePoolLimit) {
2068 CreatePool(2, 2);
2069 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2071 ClientSocketHandle handle;
2072 TestCompletionCallback callback;
2073 int rv = handle.Init("a",
2074 params_,
2075 DEFAULT_PRIORITY,
2076 callback.callback(),
2077 pool_.get(),
2078 BoundNetLog());
2079 EXPECT_EQ(ERR_IO_PENDING, rv);
2081 // Request for socket from another pool.
2082 ClientSocketHandle handle2;
2083 TestCompletionCallback callback2;
2084 rv = handle2.Init("b",
2085 params_,
2086 DEFAULT_PRIORITY,
2087 callback2.callback(),
2088 pool_.get(),
2089 BoundNetLog());
2090 EXPECT_EQ(ERR_IO_PENDING, rv);
2092 // Request another socket from the first pool. Request should stall at the
2093 // socket pool limit.
2094 ClientSocketHandle handle3;
2095 TestCompletionCallback callback3;
2096 rv = handle3.Init("a",
2097 params_,
2098 DEFAULT_PRIORITY,
2099 callback2.callback(),
2100 pool_.get(),
2101 BoundNetLog());
2102 EXPECT_EQ(ERR_IO_PENDING, rv);
2104 // The third handle should remain stalled as the other sockets in its group
2105 // goes through the connect process.
2107 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2108 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2110 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2111 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
2112 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2114 client_socket_factory_.SignalJob(0);
2115 EXPECT_EQ(OK, callback.WaitForResult());
2116 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2118 // Closing a socket should allow the stalled handle to finally get a new
2119 // ConnectJob.
2120 handle.socket()->Disconnect();
2121 handle.Reset();
2122 EXPECT_EQ(LOAD_STATE_CONNECTING, handle3.GetLoadState());
2125 TEST_F(ClientSocketPoolBaseTest, Recoverable) {
2126 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2127 connect_job_factory_->set_job_type(TestConnectJob::kMockRecoverableJob);
2129 ClientSocketHandle handle;
2130 TestCompletionCallback callback;
2131 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED,
2132 handle.Init("a", params_, DEFAULT_PRIORITY, callback.callback(),
2133 pool_.get(), BoundNetLog()));
2134 EXPECT_TRUE(handle.is_initialized());
2135 EXPECT_TRUE(handle.socket());
2138 TEST_F(ClientSocketPoolBaseTest, AsyncRecoverable) {
2139 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2141 connect_job_factory_->set_job_type(
2142 TestConnectJob::kMockPendingRecoverableJob);
2143 ClientSocketHandle handle;
2144 TestCompletionCallback callback;
2145 EXPECT_EQ(ERR_IO_PENDING,
2146 handle.Init("a",
2147 params_,
2148 DEFAULT_PRIORITY,
2149 callback.callback(),
2150 pool_.get(),
2151 BoundNetLog()));
2152 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2153 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, callback.WaitForResult());
2154 EXPECT_TRUE(handle.is_initialized());
2155 EXPECT_TRUE(handle.socket());
2158 TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
2159 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2160 connect_job_factory_->set_job_type(
2161 TestConnectJob::kMockAdditionalErrorStateJob);
2163 ClientSocketHandle handle;
2164 TestCompletionCallback callback;
2165 EXPECT_EQ(ERR_CONNECTION_FAILED,
2166 handle.Init("a",
2167 params_,
2168 DEFAULT_PRIORITY,
2169 callback.callback(),
2170 pool_.get(),
2171 BoundNetLog()));
2172 EXPECT_FALSE(handle.is_initialized());
2173 EXPECT_FALSE(handle.socket());
2174 EXPECT_TRUE(handle.is_ssl_error());
2175 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
2178 TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
2179 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2181 connect_job_factory_->set_job_type(
2182 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2183 ClientSocketHandle handle;
2184 TestCompletionCallback callback;
2185 EXPECT_EQ(ERR_IO_PENDING,
2186 handle.Init("a",
2187 params_,
2188 DEFAULT_PRIORITY,
2189 callback.callback(),
2190 pool_.get(),
2191 BoundNetLog()));
2192 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2193 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
2194 EXPECT_FALSE(handle.is_initialized());
2195 EXPECT_FALSE(handle.socket());
2196 EXPECT_TRUE(handle.is_ssl_error());
2197 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
2200 // Make sure we can reuse sockets when the cleanup timer is disabled.
2201 TEST_F(ClientSocketPoolBaseTest, DisableCleanupTimerReuse) {
2202 // Disable cleanup timer.
2203 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(false);
2205 CreatePoolWithIdleTimeouts(
2206 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2207 base::TimeDelta(), // Time out unused sockets immediately.
2208 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2210 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2212 ClientSocketHandle handle;
2213 TestCompletionCallback callback;
2214 int rv = handle.Init("a",
2215 params_,
2216 LOWEST,
2217 callback.callback(),
2218 pool_.get(),
2219 BoundNetLog());
2220 ASSERT_EQ(ERR_IO_PENDING, rv);
2221 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2222 ASSERT_EQ(OK, callback.WaitForResult());
2224 // Use and release the socket.
2225 EXPECT_EQ(1, handle.socket()->Write(NULL, 1, CompletionCallback()));
2226 TestLoadTimingInfoConnectedNotReused(handle);
2227 handle.Reset();
2229 // Should now have one idle socket.
2230 ASSERT_EQ(1, pool_->IdleSocketCount());
2232 // Request a new socket. This should reuse the old socket and complete
2233 // synchronously.
2234 BoundTestNetLog log;
2235 rv = handle.Init("a",
2236 params_,
2237 LOWEST,
2238 CompletionCallback(),
2239 pool_.get(),
2240 log.bound());
2241 ASSERT_EQ(OK, rv);
2242 EXPECT_TRUE(handle.is_reused());
2243 TestLoadTimingInfoConnectedReused(handle);
2245 ASSERT_TRUE(pool_->HasGroup("a"));
2246 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2247 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2249 CapturedNetLogEntry::List entries;
2250 log.GetEntries(&entries);
2251 EXPECT_TRUE(LogContainsEntryWithType(
2252 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
2255 // Make sure we cleanup old unused sockets when the cleanup timer is disabled.
2256 TEST_F(ClientSocketPoolBaseTest, DisableCleanupTimerNoReuse) {
2257 // Disable cleanup timer.
2258 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(false);
2260 CreatePoolWithIdleTimeouts(
2261 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2262 base::TimeDelta(), // Time out unused sockets immediately
2263 base::TimeDelta()); // Time out used sockets immediately
2265 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2267 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2269 ClientSocketHandle handle;
2270 TestCompletionCallback callback;
2271 int rv = handle.Init("a",
2272 params_,
2273 LOWEST,
2274 callback.callback(),
2275 pool_.get(),
2276 BoundNetLog());
2277 ASSERT_EQ(ERR_IO_PENDING, rv);
2278 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2280 ClientSocketHandle handle2;
2281 TestCompletionCallback callback2;
2282 rv = handle2.Init("a",
2283 params_,
2284 LOWEST,
2285 callback2.callback(),
2286 pool_.get(),
2287 BoundNetLog());
2288 ASSERT_EQ(ERR_IO_PENDING, rv);
2289 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
2291 // Cancel one of the requests. Wait for the other, which will get the first
2292 // job. Release the socket. Run the loop again to make sure the second
2293 // socket is sitting idle and the first one is released (since ReleaseSocket()
2294 // just posts a DoReleaseSocket() task).
2296 handle.Reset();
2297 ASSERT_EQ(OK, callback2.WaitForResult());
2298 // Use the socket.
2299 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, CompletionCallback()));
2300 handle2.Reset();
2302 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2303 // actually become pending until 2ms after they have been created. In order
2304 // to flush all tasks, we need to wait so that we know there are no
2305 // soon-to-be-pending tasks waiting.
2306 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
2307 base::MessageLoop::current()->RunUntilIdle();
2309 // Both sockets should now be idle.
2310 ASSERT_EQ(2, pool_->IdleSocketCount());
2312 // Request a new socket. This should cleanup the unused and timed out ones.
2313 // A new socket will be created rather than reusing the idle one.
2314 BoundTestNetLog log;
2315 TestCompletionCallback callback3;
2316 rv = handle.Init("a",
2317 params_,
2318 LOWEST,
2319 callback3.callback(),
2320 pool_.get(),
2321 log.bound());
2322 ASSERT_EQ(ERR_IO_PENDING, rv);
2323 ASSERT_EQ(OK, callback3.WaitForResult());
2324 EXPECT_FALSE(handle.is_reused());
2326 // Make sure the idle socket is closed.
2327 ASSERT_TRUE(pool_->HasGroup("a"));
2328 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2329 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2331 CapturedNetLogEntry::List entries;
2332 log.GetEntries(&entries);
2333 EXPECT_FALSE(LogContainsEntryWithType(
2334 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
2337 TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
2338 CreatePoolWithIdleTimeouts(
2339 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2340 base::TimeDelta(), // Time out unused sockets immediately.
2341 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2343 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2345 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2347 ClientSocketHandle handle;
2348 TestCompletionCallback callback;
2349 int rv = handle.Init("a",
2350 params_,
2351 LOWEST,
2352 callback.callback(),
2353 pool_.get(),
2354 BoundNetLog());
2355 EXPECT_EQ(ERR_IO_PENDING, rv);
2356 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2358 ClientSocketHandle handle2;
2359 TestCompletionCallback callback2;
2360 rv = handle2.Init("a",
2361 params_,
2362 LOWEST,
2363 callback2.callback(),
2364 pool_.get(),
2365 BoundNetLog());
2366 EXPECT_EQ(ERR_IO_PENDING, rv);
2367 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
2369 // Cancel one of the requests. Wait for the other, which will get the first
2370 // job. Release the socket. Run the loop again to make sure the second
2371 // socket is sitting idle and the first one is released (since ReleaseSocket()
2372 // just posts a DoReleaseSocket() task).
2374 handle.Reset();
2375 EXPECT_EQ(OK, callback2.WaitForResult());
2376 // Use the socket.
2377 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, CompletionCallback()));
2378 handle2.Reset();
2380 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2381 // actually become pending until 2ms after they have been created. In order
2382 // to flush all tasks, we need to wait so that we know there are no
2383 // soon-to-be-pending tasks waiting.
2384 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
2385 base::MessageLoop::current()->RunUntilIdle();
2387 ASSERT_EQ(2, pool_->IdleSocketCount());
2389 // Invoke the idle socket cleanup check. Only one socket should be left, the
2390 // used socket. Request it to make sure that it's used.
2392 pool_->CleanupTimedOutIdleSockets();
2393 BoundTestNetLog log;
2394 rv = handle.Init("a",
2395 params_,
2396 LOWEST,
2397 callback.callback(),
2398 pool_.get(),
2399 log.bound());
2400 EXPECT_EQ(OK, rv);
2401 EXPECT_TRUE(handle.is_reused());
2403 CapturedNetLogEntry::List entries;
2404 log.GetEntries(&entries);
2405 EXPECT_TRUE(LogContainsEntryWithType(
2406 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
2409 // Make sure that we process all pending requests even when we're stalling
2410 // because of multiple releasing disconnected sockets.
2411 TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
2412 CreatePoolWithIdleTimeouts(
2413 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2414 base::TimeDelta(), // Time out unused sockets immediately.
2415 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2417 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2419 // Startup 4 connect jobs. Two of them will be pending.
2421 ClientSocketHandle handle;
2422 TestCompletionCallback callback;
2423 int rv = handle.Init("a",
2424 params_,
2425 LOWEST,
2426 callback.callback(),
2427 pool_.get(),
2428 BoundNetLog());
2429 EXPECT_EQ(OK, rv);
2431 ClientSocketHandle handle2;
2432 TestCompletionCallback callback2;
2433 rv = handle2.Init("a",
2434 params_,
2435 LOWEST,
2436 callback2.callback(),
2437 pool_.get(),
2438 BoundNetLog());
2439 EXPECT_EQ(OK, rv);
2441 ClientSocketHandle handle3;
2442 TestCompletionCallback callback3;
2443 rv = handle3.Init("a",
2444 params_,
2445 LOWEST,
2446 callback3.callback(),
2447 pool_.get(),
2448 BoundNetLog());
2449 EXPECT_EQ(ERR_IO_PENDING, rv);
2451 ClientSocketHandle handle4;
2452 TestCompletionCallback callback4;
2453 rv = handle4.Init("a",
2454 params_,
2455 LOWEST,
2456 callback4.callback(),
2457 pool_.get(),
2458 BoundNetLog());
2459 EXPECT_EQ(ERR_IO_PENDING, rv);
2461 // Release two disconnected sockets.
2463 handle.socket()->Disconnect();
2464 handle.Reset();
2465 handle2.socket()->Disconnect();
2466 handle2.Reset();
2468 EXPECT_EQ(OK, callback3.WaitForResult());
2469 EXPECT_FALSE(handle3.is_reused());
2470 EXPECT_EQ(OK, callback4.WaitForResult());
2471 EXPECT_FALSE(handle4.is_reused());
2474 // Regression test for http://crbug.com/42267.
2475 // When DoReleaseSocket() is processed for one socket, it is blocked because the
2476 // other stalled groups all have releasing sockets, so no progress can be made.
2477 TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
2478 CreatePoolWithIdleTimeouts(
2479 4 /* socket limit */, 4 /* socket limit per group */,
2480 base::TimeDelta(), // Time out unused sockets immediately.
2481 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2483 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2485 // Max out the socket limit with 2 per group.
2487 ClientSocketHandle handle_a[4];
2488 TestCompletionCallback callback_a[4];
2489 ClientSocketHandle handle_b[4];
2490 TestCompletionCallback callback_b[4];
2492 for (int i = 0; i < 2; ++i) {
2493 EXPECT_EQ(OK, handle_a[i].Init("a",
2494 params_,
2495 LOWEST,
2496 callback_a[i].callback(),
2497 pool_.get(),
2498 BoundNetLog()));
2499 EXPECT_EQ(OK, handle_b[i].Init("b",
2500 params_,
2501 LOWEST,
2502 callback_b[i].callback(),
2503 pool_.get(),
2504 BoundNetLog()));
2507 // Make 4 pending requests, 2 per group.
2509 for (int i = 2; i < 4; ++i) {
2510 EXPECT_EQ(ERR_IO_PENDING,
2511 handle_a[i].Init("a",
2512 params_,
2513 LOWEST,
2514 callback_a[i].callback(),
2515 pool_.get(),
2516 BoundNetLog()));
2517 EXPECT_EQ(ERR_IO_PENDING,
2518 handle_b[i].Init("b",
2519 params_,
2520 LOWEST,
2521 callback_b[i].callback(),
2522 pool_.get(),
2523 BoundNetLog()));
2526 // Release b's socket first. The order is important, because in
2527 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2528 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2529 // first, which has a releasing socket, so it refuses to start up another
2530 // ConnectJob. So, we used to infinite loop on this.
2531 handle_b[0].socket()->Disconnect();
2532 handle_b[0].Reset();
2533 handle_a[0].socket()->Disconnect();
2534 handle_a[0].Reset();
2536 // Used to get stuck here.
2537 base::MessageLoop::current()->RunUntilIdle();
2539 handle_b[1].socket()->Disconnect();
2540 handle_b[1].Reset();
2541 handle_a[1].socket()->Disconnect();
2542 handle_a[1].Reset();
2544 for (int i = 2; i < 4; ++i) {
2545 EXPECT_EQ(OK, callback_b[i].WaitForResult());
2546 EXPECT_EQ(OK, callback_a[i].WaitForResult());
2550 TEST_F(ClientSocketPoolBaseTest,
2551 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2552 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2554 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2556 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
2557 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
2558 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
2559 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
2561 EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
2562 EXPECT_EQ(OK, (*requests())[1]->WaitForResult());
2563 EXPECT_EQ(2u, completion_count());
2565 // Releases one connection.
2566 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2567 EXPECT_EQ(OK, (*requests())[2]->WaitForResult());
2569 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2570 EXPECT_EQ(OK, (*requests())[3]->WaitForResult());
2571 EXPECT_EQ(4u, completion_count());
2573 EXPECT_EQ(1, GetOrderOfRequest(1));
2574 EXPECT_EQ(2, GetOrderOfRequest(2));
2575 EXPECT_EQ(3, GetOrderOfRequest(3));
2576 EXPECT_EQ(4, GetOrderOfRequest(4));
2578 // Make sure we test order of all requests made.
2579 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
2582 class TestReleasingSocketRequest : public TestCompletionCallbackBase {
2583 public:
2584 TestReleasingSocketRequest(TestClientSocketPool* pool,
2585 int expected_result,
2586 bool reset_releasing_handle)
2587 : pool_(pool),
2588 expected_result_(expected_result),
2589 reset_releasing_handle_(reset_releasing_handle),
2590 callback_(base::Bind(&TestReleasingSocketRequest::OnComplete,
2591 base::Unretained(this))) {
2594 ~TestReleasingSocketRequest() override {}
2596 ClientSocketHandle* handle() { return &handle_; }
2598 const CompletionCallback& callback() const { return callback_; }
2600 private:
2601 void OnComplete(int result) {
2602 SetResult(result);
2603 if (reset_releasing_handle_)
2604 handle_.Reset();
2606 scoped_refptr<TestSocketParams> con_params(
2607 new TestSocketParams(false /* ignore_limits */));
2608 EXPECT_EQ(expected_result_,
2609 handle2_.Init("a", con_params, DEFAULT_PRIORITY,
2610 callback2_.callback(), pool_, BoundNetLog()));
2613 TestClientSocketPool* const pool_;
2614 int expected_result_;
2615 bool reset_releasing_handle_;
2616 ClientSocketHandle handle_;
2617 ClientSocketHandle handle2_;
2618 CompletionCallback callback_;
2619 TestCompletionCallback callback2_;
2623 TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2624 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2626 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
2627 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
2628 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
2630 EXPECT_EQ(static_cast<int>(requests_size()),
2631 client_socket_factory_.allocation_count());
2633 connect_job_factory_->set_job_type(
2634 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2635 TestReleasingSocketRequest req(pool_.get(), OK, false);
2636 EXPECT_EQ(ERR_IO_PENDING,
2637 req.handle()->Init("a", params_, DEFAULT_PRIORITY, req.callback(),
2638 pool_.get(), BoundNetLog()));
2639 // The next job should complete synchronously
2640 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2642 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
2643 EXPECT_FALSE(req.handle()->is_initialized());
2644 EXPECT_FALSE(req.handle()->socket());
2645 EXPECT_TRUE(req.handle()->is_ssl_error());
2646 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
2649 // http://crbug.com/44724 regression test.
2650 // We start releasing the pool when we flush on network change. When that
2651 // happens, the only active references are in the ClientSocketHandles. When a
2652 // ConnectJob completes and calls back into the last ClientSocketHandle, that
2653 // callback can release the last reference and delete the pool. After the
2654 // callback finishes, we go back to the stack frame within the now-deleted pool.
2655 // Executing any code that refers to members of the now-deleted pool can cause
2656 // crashes.
2657 TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2658 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2659 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2661 ClientSocketHandle handle;
2662 TestCompletionCallback callback;
2663 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2664 params_,
2665 DEFAULT_PRIORITY,
2666 callback.callback(),
2667 pool_.get(),
2668 BoundNetLog()));
2670 pool_->FlushWithError(ERR_NETWORK_CHANGED);
2672 // We'll call back into this now.
2673 callback.WaitForResult();
2676 TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2677 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2678 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2680 ClientSocketHandle handle;
2681 TestCompletionCallback callback;
2682 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2683 params_,
2684 DEFAULT_PRIORITY,
2685 callback.callback(),
2686 pool_.get(),
2687 BoundNetLog()));
2688 EXPECT_EQ(OK, callback.WaitForResult());
2689 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2691 pool_->FlushWithError(ERR_NETWORK_CHANGED);
2693 handle.Reset();
2694 base::MessageLoop::current()->RunUntilIdle();
2696 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2697 params_,
2698 DEFAULT_PRIORITY,
2699 callback.callback(),
2700 pool_.get(),
2701 BoundNetLog()));
2702 EXPECT_EQ(OK, callback.WaitForResult());
2703 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2706 class ConnectWithinCallback : public TestCompletionCallbackBase {
2707 public:
2708 ConnectWithinCallback(
2709 const std::string& group_name,
2710 const scoped_refptr<TestSocketParams>& params,
2711 TestClientSocketPool* pool)
2712 : group_name_(group_name),
2713 params_(params),
2714 pool_(pool),
2715 callback_(base::Bind(&ConnectWithinCallback::OnComplete,
2716 base::Unretained(this))) {
2719 ~ConnectWithinCallback() override {}
2721 int WaitForNestedResult() {
2722 return nested_callback_.WaitForResult();
2725 const CompletionCallback& callback() const { return callback_; }
2727 private:
2728 void OnComplete(int result) {
2729 SetResult(result);
2730 EXPECT_EQ(ERR_IO_PENDING,
2731 handle_.Init(group_name_,
2732 params_,
2733 DEFAULT_PRIORITY,
2734 nested_callback_.callback(),
2735 pool_,
2736 BoundNetLog()));
2739 const std::string group_name_;
2740 const scoped_refptr<TestSocketParams> params_;
2741 TestClientSocketPool* const pool_;
2742 ClientSocketHandle handle_;
2743 CompletionCallback callback_;
2744 TestCompletionCallback nested_callback_;
2746 DISALLOW_COPY_AND_ASSIGN(ConnectWithinCallback);
2749 TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
2750 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2752 // First job will be waiting until it gets aborted.
2753 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2755 ClientSocketHandle handle;
2756 ConnectWithinCallback callback("a", params_, pool_.get());
2757 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2758 params_,
2759 DEFAULT_PRIORITY,
2760 callback.callback(),
2761 pool_.get(),
2762 BoundNetLog()));
2764 // Second job will be started during the first callback, and will
2765 // asynchronously complete with OK.
2766 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2767 pool_->FlushWithError(ERR_NETWORK_CHANGED);
2768 EXPECT_EQ(ERR_NETWORK_CHANGED, callback.WaitForResult());
2769 EXPECT_EQ(OK, callback.WaitForNestedResult());
2772 // Cancel a pending socket request while we're at max sockets,
2773 // and verify that the backup socket firing doesn't cause a crash.
2774 TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
2775 // Max 4 sockets globally, max 4 sockets per group.
2776 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2777 pool_->EnableConnectBackupJobs();
2779 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2780 // timer.
2781 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2782 ClientSocketHandle handle;
2783 TestCompletionCallback callback;
2784 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2785 params_,
2786 DEFAULT_PRIORITY,
2787 callback.callback(),
2788 pool_.get(),
2789 BoundNetLog()));
2791 // Start (MaxSockets - 1) connected sockets to reach max sockets.
2792 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2793 ClientSocketHandle handles[kDefaultMaxSockets];
2794 for (int i = 1; i < kDefaultMaxSockets; ++i) {
2795 TestCompletionCallback callback;
2796 EXPECT_EQ(OK, handles[i].Init("bar",
2797 params_,
2798 DEFAULT_PRIORITY,
2799 callback.callback(),
2800 pool_.get(),
2801 BoundNetLog()));
2804 base::MessageLoop::current()->RunUntilIdle();
2806 // Cancel the pending request.
2807 handle.Reset();
2809 // Wait for the backup timer to fire (add some slop to ensure it fires)
2810 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2811 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
2813 base::MessageLoop::current()->RunUntilIdle();
2814 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
2817 TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
2818 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2819 pool_->EnableConnectBackupJobs();
2821 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2822 // timer.
2823 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2824 ClientSocketHandle handle;
2825 TestCompletionCallback callback;
2826 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2827 params_,
2828 DEFAULT_PRIORITY,
2829 callback.callback(),
2830 pool_.get(),
2831 BoundNetLog()));
2832 ASSERT_TRUE(pool_->HasGroup("bar"));
2833 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2834 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("bar"));
2836 // Cancel the socket request. This should cancel the backup timer. Wait for
2837 // the backup time to see if it indeed got canceled.
2838 handle.Reset();
2839 // Wait for the backup timer to fire (add some slop to ensure it fires)
2840 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2841 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
2842 base::MessageLoop::current()->RunUntilIdle();
2843 ASSERT_TRUE(pool_->HasGroup("bar"));
2844 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2847 TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
2848 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2849 pool_->EnableConnectBackupJobs();
2851 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2852 // timer.
2853 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2854 ClientSocketHandle handle;
2855 TestCompletionCallback callback;
2856 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2857 params_,
2858 DEFAULT_PRIORITY,
2859 callback.callback(),
2860 pool_.get(),
2861 BoundNetLog()));
2862 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2863 ClientSocketHandle handle2;
2864 TestCompletionCallback callback2;
2865 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("bar",
2866 params_,
2867 DEFAULT_PRIORITY,
2868 callback2.callback(),
2869 pool_.get(),
2870 BoundNetLog()));
2871 ASSERT_TRUE(pool_->HasGroup("bar"));
2872 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("bar"));
2874 // Cancel request 1 and then complete request 2. With the requests finished,
2875 // the backup timer should be cancelled.
2876 handle.Reset();
2877 EXPECT_EQ(OK, callback2.WaitForResult());
2878 // Wait for the backup timer to fire (add some slop to ensure it fires)
2879 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2880 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
2881 base::MessageLoop::current()->RunUntilIdle();
2884 // Test delayed socket binding for the case where we have two connects,
2885 // and while one is waiting on a connect, the other frees up.
2886 // The socket waiting on a connect should switch immediately to the freed
2887 // up socket.
2888 TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
2889 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2890 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2892 ClientSocketHandle handle1;
2893 TestCompletionCallback callback;
2894 EXPECT_EQ(ERR_IO_PENDING,
2895 handle1.Init("a",
2896 params_,
2897 DEFAULT_PRIORITY,
2898 callback.callback(),
2899 pool_.get(),
2900 BoundNetLog()));
2901 EXPECT_EQ(OK, callback.WaitForResult());
2903 // No idle sockets, no pending jobs.
2904 EXPECT_EQ(0, pool_->IdleSocketCount());
2905 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2907 // Create a second socket to the same host, but this one will wait.
2908 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2909 ClientSocketHandle handle2;
2910 EXPECT_EQ(ERR_IO_PENDING,
2911 handle2.Init("a",
2912 params_,
2913 DEFAULT_PRIORITY,
2914 callback.callback(),
2915 pool_.get(),
2916 BoundNetLog()));
2917 // No idle sockets, and one connecting job.
2918 EXPECT_EQ(0, pool_->IdleSocketCount());
2919 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2921 // Return the first handle to the pool. This will initiate the delayed
2922 // binding.
2923 handle1.Reset();
2925 base::MessageLoop::current()->RunUntilIdle();
2927 // Still no idle sockets, still one pending connect job.
2928 EXPECT_EQ(0, pool_->IdleSocketCount());
2929 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2931 // The second socket connected, even though it was a Waiting Job.
2932 EXPECT_EQ(OK, callback.WaitForResult());
2934 // And we can see there is still one job waiting.
2935 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2937 // Finally, signal the waiting Connect.
2938 client_socket_factory_.SignalJobs();
2939 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2941 base::MessageLoop::current()->RunUntilIdle();
2944 // Test delayed socket binding when a group is at capacity and one
2945 // of the group's sockets frees up.
2946 TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
2947 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2948 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2950 ClientSocketHandle handle1;
2951 TestCompletionCallback callback;
2952 EXPECT_EQ(ERR_IO_PENDING,
2953 handle1.Init("a",
2954 params_,
2955 DEFAULT_PRIORITY,
2956 callback.callback(),
2957 pool_.get(),
2958 BoundNetLog()));
2959 EXPECT_EQ(OK, callback.WaitForResult());
2961 // No idle sockets, no pending jobs.
2962 EXPECT_EQ(0, pool_->IdleSocketCount());
2963 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2965 // Create a second socket to the same host, but this one will wait.
2966 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2967 ClientSocketHandle handle2;
2968 EXPECT_EQ(ERR_IO_PENDING,
2969 handle2.Init("a",
2970 params_,
2971 DEFAULT_PRIORITY,
2972 callback.callback(),
2973 pool_.get(),
2974 BoundNetLog()));
2975 // No idle sockets, and one connecting job.
2976 EXPECT_EQ(0, pool_->IdleSocketCount());
2977 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2979 // Return the first handle to the pool. This will initiate the delayed
2980 // binding.
2981 handle1.Reset();
2983 base::MessageLoop::current()->RunUntilIdle();
2985 // Still no idle sockets, still one pending connect job.
2986 EXPECT_EQ(0, pool_->IdleSocketCount());
2987 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2989 // The second socket connected, even though it was a Waiting Job.
2990 EXPECT_EQ(OK, callback.WaitForResult());
2992 // And we can see there is still one job waiting.
2993 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2995 // Finally, signal the waiting Connect.
2996 client_socket_factory_.SignalJobs();
2997 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2999 base::MessageLoop::current()->RunUntilIdle();
3002 // Test out the case where we have one socket connected, one
3003 // connecting, when the first socket finishes and goes idle.
3004 // Although the second connection is pending, the second request
3005 // should complete, by taking the first socket's idle socket.
3006 TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
3007 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3008 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3010 ClientSocketHandle handle1;
3011 TestCompletionCallback callback;
3012 EXPECT_EQ(ERR_IO_PENDING,
3013 handle1.Init("a",
3014 params_,
3015 DEFAULT_PRIORITY,
3016 callback.callback(),
3017 pool_.get(),
3018 BoundNetLog()));
3019 EXPECT_EQ(OK, callback.WaitForResult());
3021 // No idle sockets, no pending jobs.
3022 EXPECT_EQ(0, pool_->IdleSocketCount());
3023 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3025 // Create a second socket to the same host, but this one will wait.
3026 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3027 ClientSocketHandle handle2;
3028 EXPECT_EQ(ERR_IO_PENDING,
3029 handle2.Init("a",
3030 params_,
3031 DEFAULT_PRIORITY,
3032 callback.callback(),
3033 pool_.get(),
3034 BoundNetLog()));
3035 // No idle sockets, and one connecting job.
3036 EXPECT_EQ(0, pool_->IdleSocketCount());
3037 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3039 // Return the first handle to the pool. This will initiate the delayed
3040 // binding.
3041 handle1.Reset();
3043 base::MessageLoop::current()->RunUntilIdle();
3045 // Still no idle sockets, still one pending connect job.
3046 EXPECT_EQ(0, pool_->IdleSocketCount());
3047 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3049 // The second socket connected, even though it was a Waiting Job.
3050 EXPECT_EQ(OK, callback.WaitForResult());
3052 // And we can see there is still one job waiting.
3053 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3055 // Finally, signal the waiting Connect.
3056 client_socket_factory_.SignalJobs();
3057 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3059 base::MessageLoop::current()->RunUntilIdle();
3062 // Cover the case where on an available socket slot, we have one pending
3063 // request that completes synchronously, thereby making the Group empty.
3064 TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
3065 const int kUnlimitedSockets = 100;
3066 const int kOneSocketPerGroup = 1;
3067 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
3069 // Make the first request asynchronous fail.
3070 // This will free up a socket slot later.
3071 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
3073 ClientSocketHandle handle1;
3074 TestCompletionCallback callback1;
3075 EXPECT_EQ(ERR_IO_PENDING,
3076 handle1.Init("a",
3077 params_,
3078 DEFAULT_PRIORITY,
3079 callback1.callback(),
3080 pool_.get(),
3081 BoundNetLog()));
3082 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3084 // Make the second request synchronously fail. This should make the Group
3085 // empty.
3086 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3087 ClientSocketHandle handle2;
3088 TestCompletionCallback callback2;
3089 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
3090 // when created.
3091 EXPECT_EQ(ERR_IO_PENDING,
3092 handle2.Init("a",
3093 params_,
3094 DEFAULT_PRIORITY,
3095 callback2.callback(),
3096 pool_.get(),
3097 BoundNetLog()));
3099 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3101 EXPECT_EQ(ERR_CONNECTION_FAILED, callback1.WaitForResult());
3102 EXPECT_EQ(ERR_CONNECTION_FAILED, callback2.WaitForResult());
3103 EXPECT_FALSE(pool_->HasGroup("a"));
3106 TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
3107 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3109 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3111 ClientSocketHandle handle1;
3112 TestCompletionCallback callback1;
3113 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3114 params_,
3115 DEFAULT_PRIORITY,
3116 callback1.callback(),
3117 pool_.get(),
3118 BoundNetLog()));
3120 ClientSocketHandle handle2;
3121 TestCompletionCallback callback2;
3122 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3123 params_,
3124 DEFAULT_PRIORITY,
3125 callback2.callback(),
3126 pool_.get(),
3127 BoundNetLog()));
3128 ClientSocketHandle handle3;
3129 TestCompletionCallback callback3;
3130 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
3131 params_,
3132 DEFAULT_PRIORITY,
3133 callback3.callback(),
3134 pool_.get(),
3135 BoundNetLog()));
3137 EXPECT_EQ(OK, callback1.WaitForResult());
3138 EXPECT_EQ(OK, callback2.WaitForResult());
3139 EXPECT_EQ(OK, callback3.WaitForResult());
3141 // Use the socket.
3142 EXPECT_EQ(1, handle1.socket()->Write(NULL, 1, CompletionCallback()));
3143 EXPECT_EQ(1, handle3.socket()->Write(NULL, 1, CompletionCallback()));
3145 handle1.Reset();
3146 handle2.Reset();
3147 handle3.Reset();
3149 EXPECT_EQ(OK, handle1.Init("a",
3150 params_,
3151 DEFAULT_PRIORITY,
3152 callback1.callback(),
3153 pool_.get(),
3154 BoundNetLog()));
3155 EXPECT_EQ(OK, handle2.Init("a",
3156 params_,
3157 DEFAULT_PRIORITY,
3158 callback2.callback(),
3159 pool_.get(),
3160 BoundNetLog()));
3161 EXPECT_EQ(OK, handle3.Init("a",
3162 params_,
3163 DEFAULT_PRIORITY,
3164 callback3.callback(),
3165 pool_.get(),
3166 BoundNetLog()));
3168 EXPECT_TRUE(handle1.socket()->WasEverUsed());
3169 EXPECT_TRUE(handle2.socket()->WasEverUsed());
3170 EXPECT_FALSE(handle3.socket()->WasEverUsed());
3173 TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
3174 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3175 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3177 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3179 ASSERT_TRUE(pool_->HasGroup("a"));
3180 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3181 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
3182 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3184 ClientSocketHandle handle1;
3185 TestCompletionCallback callback1;
3186 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3187 params_,
3188 DEFAULT_PRIORITY,
3189 callback1.callback(),
3190 pool_.get(),
3191 BoundNetLog()));
3193 ClientSocketHandle handle2;
3194 TestCompletionCallback callback2;
3195 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3196 params_,
3197 DEFAULT_PRIORITY,
3198 callback2.callback(),
3199 pool_.get(),
3200 BoundNetLog()));
3202 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3203 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3204 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3206 EXPECT_EQ(OK, callback1.WaitForResult());
3207 EXPECT_EQ(OK, callback2.WaitForResult());
3208 handle1.Reset();
3209 handle2.Reset();
3211 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3212 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3213 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3216 TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
3217 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3218 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3220 ClientSocketHandle handle1;
3221 TestCompletionCallback callback1;
3222 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3223 params_,
3224 DEFAULT_PRIORITY,
3225 callback1.callback(),
3226 pool_.get(),
3227 BoundNetLog()));
3229 ASSERT_TRUE(pool_->HasGroup("a"));
3230 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3231 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3232 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3234 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3236 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3237 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
3238 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3240 ClientSocketHandle handle2;
3241 TestCompletionCallback callback2;
3242 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3243 params_,
3244 DEFAULT_PRIORITY,
3245 callback2.callback(),
3246 pool_.get(),
3247 BoundNetLog()));
3249 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3250 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3251 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3253 EXPECT_EQ(OK, callback1.WaitForResult());
3254 EXPECT_EQ(OK, callback2.WaitForResult());
3255 handle1.Reset();
3256 handle2.Reset();
3258 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3259 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3260 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3263 TEST_F(ClientSocketPoolBaseTest,
3264 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
3265 CreatePool(4, 4);
3266 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3268 ClientSocketHandle handle1;
3269 TestCompletionCallback callback1;
3270 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3271 params_,
3272 DEFAULT_PRIORITY,
3273 callback1.callback(),
3274 pool_.get(),
3275 BoundNetLog()));
3277 ClientSocketHandle handle2;
3278 TestCompletionCallback callback2;
3279 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3280 params_,
3281 DEFAULT_PRIORITY,
3282 callback2.callback(),
3283 pool_.get(),
3284 BoundNetLog()));
3286 ClientSocketHandle handle3;
3287 TestCompletionCallback callback3;
3288 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
3289 params_,
3290 DEFAULT_PRIORITY,
3291 callback3.callback(),
3292 pool_.get(),
3293 BoundNetLog()));
3295 ASSERT_TRUE(pool_->HasGroup("a"));
3296 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
3297 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3298 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3300 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3302 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
3303 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3304 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3306 EXPECT_EQ(OK, callback1.WaitForResult());
3307 EXPECT_EQ(OK, callback2.WaitForResult());
3308 EXPECT_EQ(OK, callback3.WaitForResult());
3309 handle1.Reset();
3310 handle2.Reset();
3311 handle3.Reset();
3313 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3314 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3315 EXPECT_EQ(3, pool_->IdleSocketCountInGroup("a"));
3318 TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
3319 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3320 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3322 ASSERT_FALSE(pool_->HasGroup("a"));
3324 pool_->RequestSockets("a", &params_, kDefaultMaxSockets,
3325 BoundNetLog());
3327 ASSERT_TRUE(pool_->HasGroup("a"));
3328 EXPECT_EQ(kDefaultMaxSockets, pool_->NumConnectJobsInGroup("a"));
3329 EXPECT_EQ(kDefaultMaxSockets, pool_->NumUnassignedConnectJobsInGroup("a"));
3331 ASSERT_FALSE(pool_->HasGroup("b"));
3333 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
3334 BoundNetLog());
3336 ASSERT_FALSE(pool_->HasGroup("b"));
3339 TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
3340 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3341 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3343 ASSERT_FALSE(pool_->HasGroup("a"));
3345 pool_->RequestSockets("a", &params_, kDefaultMaxSockets - 1,
3346 BoundNetLog());
3348 ASSERT_TRUE(pool_->HasGroup("a"));
3349 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->NumConnectJobsInGroup("a"));
3350 EXPECT_EQ(kDefaultMaxSockets - 1,
3351 pool_->NumUnassignedConnectJobsInGroup("a"));
3352 EXPECT_FALSE(pool_->IsStalled());
3354 ASSERT_FALSE(pool_->HasGroup("b"));
3356 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
3357 BoundNetLog());
3359 ASSERT_TRUE(pool_->HasGroup("b"));
3360 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("b"));
3361 EXPECT_FALSE(pool_->IsStalled());
3364 TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
3365 CreatePool(4, 4);
3366 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3368 ClientSocketHandle handle1;
3369 TestCompletionCallback callback1;
3370 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3371 params_,
3372 DEFAULT_PRIORITY,
3373 callback1.callback(),
3374 pool_.get(),
3375 BoundNetLog()));
3376 ASSERT_EQ(OK, callback1.WaitForResult());
3377 handle1.Reset();
3379 ASSERT_TRUE(pool_->HasGroup("a"));
3380 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3381 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3382 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3384 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3386 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3387 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
3388 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3391 TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
3392 CreatePool(4, 4);
3393 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3395 ClientSocketHandle handle1;
3396 TestCompletionCallback callback1;
3397 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3398 params_,
3399 DEFAULT_PRIORITY,
3400 callback1.callback(),
3401 pool_.get(),
3402 BoundNetLog()));
3403 ASSERT_EQ(OK, callback1.WaitForResult());
3405 ASSERT_TRUE(pool_->HasGroup("a"));
3406 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3407 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3408 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3409 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3411 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3413 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3414 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
3415 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3416 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3419 TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
3420 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3421 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3423 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3424 BoundNetLog());
3426 ASSERT_TRUE(pool_->HasGroup("a"));
3427 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3428 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3429 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("a"));
3431 pool_->RequestSockets("b", &params_, kDefaultMaxSocketsPerGroup,
3432 BoundNetLog());
3434 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3435 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
3436 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("b"));
3439 TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
3440 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3441 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3443 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3444 BoundNetLog());
3446 ASSERT_FALSE(pool_->HasGroup("a"));
3448 connect_job_factory_->set_job_type(
3449 TestConnectJob::kMockAdditionalErrorStateJob);
3450 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3451 BoundNetLog());
3453 ASSERT_FALSE(pool_->HasGroup("a"));
3456 TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
3457 CreatePool(4, 4);
3458 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3460 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3462 ASSERT_TRUE(pool_->HasGroup("a"));
3463 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3464 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
3465 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3467 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3468 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3469 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
3470 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3472 ClientSocketHandle handle1;
3473 TestCompletionCallback callback1;
3474 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3475 params_,
3476 DEFAULT_PRIORITY,
3477 callback1.callback(),
3478 pool_.get(),
3479 BoundNetLog()));
3480 ASSERT_EQ(OK, callback1.WaitForResult());
3482 ClientSocketHandle handle2;
3483 TestCompletionCallback callback2;
3484 int rv = handle2.Init("a",
3485 params_,
3486 DEFAULT_PRIORITY,
3487 callback2.callback(),
3488 pool_.get(),
3489 BoundNetLog());
3490 if (rv != OK) {
3491 EXPECT_EQ(ERR_IO_PENDING, rv);
3492 EXPECT_EQ(OK, callback2.WaitForResult());
3495 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3496 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3497 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("a"));
3498 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3500 handle1.Reset();
3501 handle2.Reset();
3503 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3504 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3505 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3507 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3508 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3509 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3510 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3513 TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
3514 CreatePool(4, 4);
3515 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3517 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3519 ASSERT_TRUE(pool_->HasGroup("a"));
3520 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3521 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
3522 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3524 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3525 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3526 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
3527 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3529 pool_->RequestSockets("a", &params_, 3, BoundNetLog());
3530 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
3531 EXPECT_EQ(3, pool_->NumUnassignedConnectJobsInGroup("a"));
3532 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3534 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3535 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
3536 EXPECT_EQ(3, pool_->NumUnassignedConnectJobsInGroup("a"));
3537 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3540 TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
3541 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3542 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3544 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3546 ASSERT_TRUE(pool_->HasGroup("a"));
3547 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3548 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
3549 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3551 ClientSocketHandle handle1;
3552 TestCompletionCallback callback1;
3553 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3554 params_,
3555 DEFAULT_PRIORITY,
3556 callback1.callback(),
3557 pool_.get(),
3558 BoundNetLog()));
3560 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3561 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3562 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3564 ASSERT_EQ(OK, callback1.WaitForResult());
3566 // Make sure if a preconnected socket is not fully connected when a request
3567 // starts, it has a connect start time.
3568 TestLoadTimingInfoConnectedNotReused(handle1);
3569 handle1.Reset();
3571 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3574 // Checks that fully connected preconnect jobs have no connect times, and are
3575 // marked as reused.
3576 TEST_F(ClientSocketPoolBaseTest, ConnectedPreconnectJobsHaveNoConnectTimes) {
3577 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3578 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3579 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3581 ASSERT_TRUE(pool_->HasGroup("a"));
3582 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3583 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3584 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3586 ClientSocketHandle handle;
3587 TestCompletionCallback callback;
3588 EXPECT_EQ(OK, handle.Init("a",
3589 params_,
3590 DEFAULT_PRIORITY,
3591 callback.callback(),
3592 pool_.get(),
3593 BoundNetLog()));
3595 // Make sure the idle socket was used.
3596 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3598 TestLoadTimingInfoConnectedReused(handle);
3599 handle.Reset();
3600 TestLoadTimingInfoNotConnected(handle);
3603 // http://crbug.com/64940 regression test.
3604 TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
3605 const int kMaxTotalSockets = 3;
3606 const int kMaxSocketsPerGroup = 2;
3607 CreatePool(kMaxTotalSockets, kMaxSocketsPerGroup);
3608 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3610 // Note that group name ordering matters here. "a" comes before "b", so
3611 // CloseOneIdleSocket() will try to close "a"'s idle socket.
3613 // Set up one idle socket in "a".
3614 ClientSocketHandle handle1;
3615 TestCompletionCallback callback1;
3616 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3617 params_,
3618 DEFAULT_PRIORITY,
3619 callback1.callback(),
3620 pool_.get(),
3621 BoundNetLog()));
3623 ASSERT_EQ(OK, callback1.WaitForResult());
3624 handle1.Reset();
3625 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3627 // Set up two active sockets in "b".
3628 ClientSocketHandle handle2;
3629 TestCompletionCallback callback2;
3630 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("b",
3631 params_,
3632 DEFAULT_PRIORITY,
3633 callback1.callback(),
3634 pool_.get(),
3635 BoundNetLog()));
3636 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("b",
3637 params_,
3638 DEFAULT_PRIORITY,
3639 callback2.callback(),
3640 pool_.get(),
3641 BoundNetLog()));
3643 ASSERT_EQ(OK, callback1.WaitForResult());
3644 ASSERT_EQ(OK, callback2.WaitForResult());
3645 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3646 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
3647 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3649 // Now we have 1 idle socket in "a" and 2 active sockets in "b". This means
3650 // we've maxed out on sockets, since we set |kMaxTotalSockets| to 3.
3651 // Requesting 2 preconnected sockets for "a" should fail to allocate any more
3652 // sockets for "a", and "b" should still have 2 active sockets.
3654 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3655 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3656 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3657 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3658 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3659 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3660 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
3661 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3662 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3664 // Now release the 2 active sockets for "b". This will give us 1 idle socket
3665 // in "a" and 2 idle sockets in "b". Requesting 2 preconnected sockets for
3666 // "a" should result in closing 1 for "b".
3667 handle1.Reset();
3668 handle2.Reset();
3669 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("b"));
3670 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3672 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3673 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3674 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
3675 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3676 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3677 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3678 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
3679 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("b"));
3680 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3683 TEST_F(ClientSocketPoolBaseTest, PreconnectWithoutBackupJob) {
3684 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3685 pool_->EnableConnectBackupJobs();
3687 // Make the ConnectJob hang until it times out, shorten the timeout.
3688 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3689 connect_job_factory_->set_timeout_duration(
3690 base::TimeDelta::FromMilliseconds(500));
3691 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3692 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3693 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
3694 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3696 // Verify the backup timer doesn't create a backup job, by making
3697 // the backup job a pending job instead of a waiting job, so it
3698 // *would* complete if it were created.
3699 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3700 base::MessageLoop::current()->PostDelayedTask(
3701 FROM_HERE,
3702 base::MessageLoop::QuitClosure(),
3703 base::TimeDelta::FromSeconds(1));
3704 base::MessageLoop::current()->Run();
3705 EXPECT_FALSE(pool_->HasGroup("a"));
3708 TEST_F(ClientSocketPoolBaseTest, PreconnectWithBackupJob) {
3709 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3710 pool_->EnableConnectBackupJobs();
3712 // Make the ConnectJob hang forever.
3713 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3714 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3715 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3716 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
3717 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3718 base::MessageLoop::current()->RunUntilIdle();
3720 // Make the backup job be a pending job, so it completes normally.
3721 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3722 ClientSocketHandle handle;
3723 TestCompletionCallback callback;
3724 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
3725 params_,
3726 DEFAULT_PRIORITY,
3727 callback.callback(),
3728 pool_.get(),
3729 BoundNetLog()));
3730 // Timer has started, but the backup connect job shouldn't be created yet.
3731 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3732 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3733 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3734 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3735 ASSERT_EQ(OK, callback.WaitForResult());
3737 // The hung connect job should still be there, but everything else should be
3738 // complete.
3739 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3740 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3741 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3742 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3745 // Tests that a preconnect that starts out with unread data can still be used.
3746 // http://crbug.com/334467
3747 TEST_F(ClientSocketPoolBaseTest, PreconnectWithUnreadData) {
3748 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3749 connect_job_factory_->set_job_type(TestConnectJob::kMockUnreadDataJob);
3751 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3753 ASSERT_TRUE(pool_->HasGroup("a"));
3754 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3755 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3756 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3758 // Fail future jobs to be sure that handle receives the preconnected socket
3759 // rather than closing it and making a new one.
3760 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3761 ClientSocketHandle handle;
3762 TestCompletionCallback callback;
3763 EXPECT_EQ(OK, handle.Init("a",
3764 params_,
3765 DEFAULT_PRIORITY,
3766 callback.callback(),
3767 pool_.get(),
3768 BoundNetLog()));
3770 ASSERT_TRUE(pool_->HasGroup("a"));
3771 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3772 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3773 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3775 // Drain the pending read.
3776 EXPECT_EQ(1, handle.socket()->Read(NULL, 1, CompletionCallback()));
3778 TestLoadTimingInfoConnectedReused(handle);
3779 handle.Reset();
3781 // The socket should be usable now that it's idle again.
3782 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3785 class MockLayeredPool : public HigherLayeredPool {
3786 public:
3787 MockLayeredPool(TestClientSocketPool* pool,
3788 const std::string& group_name)
3789 : pool_(pool),
3790 group_name_(group_name),
3791 can_release_connection_(true) {
3792 pool_->AddHigherLayeredPool(this);
3795 ~MockLayeredPool() {
3796 pool_->RemoveHigherLayeredPool(this);
3799 int RequestSocket(TestClientSocketPool* pool) {
3800 scoped_refptr<TestSocketParams> params(
3801 new TestSocketParams(false /* ignore_limits */));
3802 return handle_.Init(group_name_, params, DEFAULT_PRIORITY,
3803 callback_.callback(), pool, BoundNetLog());
3806 int RequestSocketWithoutLimits(TestClientSocketPool* pool) {
3807 scoped_refptr<TestSocketParams> params(
3808 new TestSocketParams(true /* ignore_limits */));
3809 return handle_.Init(group_name_, params, MAXIMUM_PRIORITY,
3810 callback_.callback(), pool, BoundNetLog());
3813 bool ReleaseOneConnection() {
3814 if (!handle_.is_initialized() || !can_release_connection_) {
3815 return false;
3817 handle_.socket()->Disconnect();
3818 handle_.Reset();
3819 return true;
3822 void set_can_release_connection(bool can_release_connection) {
3823 can_release_connection_ = can_release_connection;
3826 MOCK_METHOD0(CloseOneIdleConnection, bool());
3828 private:
3829 TestClientSocketPool* const pool_;
3830 ClientSocketHandle handle_;
3831 TestCompletionCallback callback_;
3832 const std::string group_name_;
3833 bool can_release_connection_;
3836 TEST_F(ClientSocketPoolBaseTest, FailToCloseIdleSocketsNotHeldByLayeredPool) {
3837 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3838 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3840 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
3841 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3842 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3843 .WillOnce(Return(false));
3844 EXPECT_FALSE(pool_->CloseOneIdleConnectionInHigherLayeredPool());
3847 TEST_F(ClientSocketPoolBaseTest, ForciblyCloseIdleSocketsHeldByLayeredPool) {
3848 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3849 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3851 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
3852 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3853 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3854 .WillOnce(Invoke(&mock_layered_pool,
3855 &MockLayeredPool::ReleaseOneConnection));
3856 EXPECT_TRUE(pool_->CloseOneIdleConnectionInHigherLayeredPool());
3859 // Tests the basic case of closing an idle socket in a higher layered pool when
3860 // a new request is issued and the lower layer pool is stalled.
3861 TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsHeldByLayeredPoolWhenNeeded) {
3862 CreatePool(1, 1);
3863 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3865 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
3866 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3867 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3868 .WillOnce(Invoke(&mock_layered_pool,
3869 &MockLayeredPool::ReleaseOneConnection));
3870 ClientSocketHandle handle;
3871 TestCompletionCallback callback;
3872 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
3873 params_,
3874 DEFAULT_PRIORITY,
3875 callback.callback(),
3876 pool_.get(),
3877 BoundNetLog()));
3878 EXPECT_EQ(OK, callback.WaitForResult());
3881 // Same as above, but the idle socket is in the same group as the stalled
3882 // socket, and closes the only other request in its group when closing requests
3883 // in higher layered pools. This generally shouldn't happen, but it may be
3884 // possible if a higher level pool issues a request and the request is
3885 // subsequently cancelled. Even if it's not possible, best not to crash.
3886 TEST_F(ClientSocketPoolBaseTest,
3887 CloseIdleSocketsHeldByLayeredPoolWhenNeededSameGroup) {
3888 CreatePool(2, 2);
3889 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3891 // Need a socket in another group for the pool to be stalled (If a group
3892 // has the maximum number of connections already, it's not stalled).
3893 ClientSocketHandle handle1;
3894 TestCompletionCallback callback1;
3895 EXPECT_EQ(OK, handle1.Init("group1",
3896 params_,
3897 DEFAULT_PRIORITY,
3898 callback1.callback(),
3899 pool_.get(),
3900 BoundNetLog()));
3902 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
3903 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3904 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3905 .WillOnce(Invoke(&mock_layered_pool,
3906 &MockLayeredPool::ReleaseOneConnection));
3907 ClientSocketHandle handle;
3908 TestCompletionCallback callback2;
3909 EXPECT_EQ(ERR_IO_PENDING, handle.Init("group2",
3910 params_,
3911 DEFAULT_PRIORITY,
3912 callback2.callback(),
3913 pool_.get(),
3914 BoundNetLog()));
3915 EXPECT_EQ(OK, callback2.WaitForResult());
3918 // Tests the case when an idle socket can be closed when a new request is
3919 // issued, and the new request belongs to a group that was previously stalled.
3920 TEST_F(ClientSocketPoolBaseTest,
3921 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded) {
3922 CreatePool(2, 2);
3923 std::list<TestConnectJob::JobType> job_types;
3924 job_types.push_back(TestConnectJob::kMockJob);
3925 job_types.push_back(TestConnectJob::kMockJob);
3926 job_types.push_back(TestConnectJob::kMockJob);
3927 job_types.push_back(TestConnectJob::kMockJob);
3928 connect_job_factory_->set_job_types(&job_types);
3930 ClientSocketHandle handle1;
3931 TestCompletionCallback callback1;
3932 EXPECT_EQ(OK, handle1.Init("group1",
3933 params_,
3934 DEFAULT_PRIORITY,
3935 callback1.callback(),
3936 pool_.get(),
3937 BoundNetLog()));
3939 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
3940 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3941 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3942 .WillRepeatedly(Invoke(&mock_layered_pool,
3943 &MockLayeredPool::ReleaseOneConnection));
3944 mock_layered_pool.set_can_release_connection(false);
3946 // The third request is made when the socket pool is in a stalled state.
3947 ClientSocketHandle handle3;
3948 TestCompletionCallback callback3;
3949 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("group3",
3950 params_,
3951 DEFAULT_PRIORITY,
3952 callback3.callback(),
3953 pool_.get(),
3954 BoundNetLog()));
3956 base::RunLoop().RunUntilIdle();
3957 EXPECT_FALSE(callback3.have_result());
3959 // The fourth request is made when the pool is no longer stalled. The third
3960 // request should be serviced first, since it was issued first and has the
3961 // same priority.
3962 mock_layered_pool.set_can_release_connection(true);
3963 ClientSocketHandle handle4;
3964 TestCompletionCallback callback4;
3965 EXPECT_EQ(ERR_IO_PENDING, handle4.Init("group3",
3966 params_,
3967 DEFAULT_PRIORITY,
3968 callback4.callback(),
3969 pool_.get(),
3970 BoundNetLog()));
3971 EXPECT_EQ(OK, callback3.WaitForResult());
3972 EXPECT_FALSE(callback4.have_result());
3974 // Closing a handle should free up another socket slot.
3975 handle1.Reset();
3976 EXPECT_EQ(OK, callback4.WaitForResult());
3979 // Tests the case when an idle socket can be closed when a new request is
3980 // issued, and the new request belongs to a group that was previously stalled.
3982 // The two differences from the above test are that the stalled requests are not
3983 // in the same group as the layered pool's request, and the the fourth request
3984 // has a higher priority than the third one, so gets a socket first.
3985 TEST_F(ClientSocketPoolBaseTest,
3986 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded2) {
3987 CreatePool(2, 2);
3988 std::list<TestConnectJob::JobType> job_types;
3989 job_types.push_back(TestConnectJob::kMockJob);
3990 job_types.push_back(TestConnectJob::kMockJob);
3991 job_types.push_back(TestConnectJob::kMockJob);
3992 job_types.push_back(TestConnectJob::kMockJob);
3993 connect_job_factory_->set_job_types(&job_types);
3995 ClientSocketHandle handle1;
3996 TestCompletionCallback callback1;
3997 EXPECT_EQ(OK, handle1.Init("group1",
3998 params_,
3999 DEFAULT_PRIORITY,
4000 callback1.callback(),
4001 pool_.get(),
4002 BoundNetLog()));
4004 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
4005 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
4006 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4007 .WillRepeatedly(Invoke(&mock_layered_pool,
4008 &MockLayeredPool::ReleaseOneConnection));
4009 mock_layered_pool.set_can_release_connection(false);
4011 // The third request is made when the socket pool is in a stalled state.
4012 ClientSocketHandle handle3;
4013 TestCompletionCallback callback3;
4014 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("group3",
4015 params_,
4016 MEDIUM,
4017 callback3.callback(),
4018 pool_.get(),
4019 BoundNetLog()));
4021 base::RunLoop().RunUntilIdle();
4022 EXPECT_FALSE(callback3.have_result());
4024 // The fourth request is made when the pool is no longer stalled. This
4025 // request has a higher priority than the third request, so is serviced first.
4026 mock_layered_pool.set_can_release_connection(true);
4027 ClientSocketHandle handle4;
4028 TestCompletionCallback callback4;
4029 EXPECT_EQ(ERR_IO_PENDING, handle4.Init("group3",
4030 params_,
4031 HIGHEST,
4032 callback4.callback(),
4033 pool_.get(),
4034 BoundNetLog()));
4035 EXPECT_EQ(OK, callback4.WaitForResult());
4036 EXPECT_FALSE(callback3.have_result());
4038 // Closing a handle should free up another socket slot.
4039 handle1.Reset();
4040 EXPECT_EQ(OK, callback3.WaitForResult());
4043 TEST_F(ClientSocketPoolBaseTest,
4044 CloseMultipleIdleSocketsHeldByLayeredPoolWhenNeeded) {
4045 CreatePool(1, 1);
4046 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4048 MockLayeredPool mock_layered_pool1(pool_.get(), "foo");
4049 EXPECT_EQ(OK, mock_layered_pool1.RequestSocket(pool_.get()));
4050 EXPECT_CALL(mock_layered_pool1, CloseOneIdleConnection())
4051 .WillRepeatedly(Invoke(&mock_layered_pool1,
4052 &MockLayeredPool::ReleaseOneConnection));
4053 MockLayeredPool mock_layered_pool2(pool_.get(), "bar");
4054 EXPECT_EQ(OK, mock_layered_pool2.RequestSocketWithoutLimits(pool_.get()));
4055 EXPECT_CALL(mock_layered_pool2, CloseOneIdleConnection())
4056 .WillRepeatedly(Invoke(&mock_layered_pool2,
4057 &MockLayeredPool::ReleaseOneConnection));
4058 ClientSocketHandle handle;
4059 TestCompletionCallback callback;
4060 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
4061 params_,
4062 DEFAULT_PRIORITY,
4063 callback.callback(),
4064 pool_.get(),
4065 BoundNetLog()));
4066 EXPECT_EQ(OK, callback.WaitForResult());
4069 // Test that when a socket pool and group are at their limits, a request
4070 // with |ignore_limits| triggers creation of a new socket, and gets the socket
4071 // instead of a request with the same priority that was issued earlier, but
4072 // that does not have |ignore_limits| set.
4073 TEST_F(ClientSocketPoolBaseTest, IgnoreLimits) {
4074 scoped_refptr<TestSocketParams> params_ignore_limits(
4075 new TestSocketParams(true /* ignore_limits */));
4076 CreatePool(1, 1);
4078 // Issue a request to reach the socket pool limit.
4079 EXPECT_EQ(OK, StartRequestWithParams("a", MAXIMUM_PRIORITY, params_));
4080 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4082 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4084 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithParams("a", MAXIMUM_PRIORITY,
4085 params_));
4086 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4088 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithParams("a", MAXIMUM_PRIORITY,
4089 params_ignore_limits));
4090 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4092 EXPECT_EQ(OK, request(2)->WaitForResult());
4093 EXPECT_FALSE(request(1)->have_result());
4096 // Test that when a socket pool and group are at their limits, a ConnectJob
4097 // issued for a request with |ignore_limits| set is not cancelled when a request
4098 // without |ignore_limits| issued to the same group is cancelled.
4099 TEST_F(ClientSocketPoolBaseTest, IgnoreLimitsCancelOtherJob) {
4100 scoped_refptr<TestSocketParams> params_ignore_limits(
4101 new TestSocketParams(true /* ignore_limits */));
4102 CreatePool(1, 1);
4104 // Issue a request to reach the socket pool limit.
4105 EXPECT_EQ(OK, StartRequestWithParams("a", MAXIMUM_PRIORITY, params_));
4106 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4108 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4110 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithParams("a", MAXIMUM_PRIORITY,
4111 params_));
4112 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4114 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithParams("a", MAXIMUM_PRIORITY,
4115 params_ignore_limits));
4116 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4118 // Cancel the pending request without ignore_limits set. The ConnectJob
4119 // should not be cancelled.
4120 request(1)->handle()->Reset();
4121 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4123 EXPECT_EQ(OK, request(2)->WaitForResult());
4124 EXPECT_FALSE(request(1)->have_result());
4127 } // namespace
4129 } // namespace net