blob: 3cafc891bee5759500900c7a9e2225c89dee810d [file] [log] [blame]
[email protected]e34400c32012-01-24 02:49:331// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]f6d1d6eb2009-06-24 20:16:092// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]ab838892009-06-30 18:49:055#include "net/socket/client_socket_pool_base.h"
[email protected]f6d1d6eb2009-06-24 20:16:096
[email protected]51fdc7c2012-04-10 19:19:487#include <vector>
8
[email protected]6ecf2b92011-12-15 01:14:529#include "base/bind.h"
10#include "base/bind_helpers.h"
[email protected]2041cf342010-02-19 03:15:5911#include "base/callback.h"
[email protected]3b63f8f42011-03-28 01:54:1512#include "base/memory/ref_counted.h"
13#include "base/memory/scoped_vector.h"
[email protected]6ea7b152011-12-21 21:21:1314#include "base/memory/weak_ptr.h"
[email protected]18b577412013-07-18 04:19:1515#include "base/message_loop/message_loop.h"
[email protected]034df0f32013-01-07 23:17:4816#include "base/run_loop.h"
[email protected]fc9be5802013-06-11 10:56:5117#include "base/strings/string_number_conversions.h"
[email protected]18b577412013-07-18 04:19:1518#include "base/strings/stringprintf.h"
[email protected]f214f8792011-01-01 02:17:0819#include "base/threading/platform_thread.h"
[email protected]f3a1c642011-07-12 19:15:0320#include "base/values.h"
[email protected]034df0f32013-01-07 23:17:4821#include "net/base/load_timing_info.h"
[email protected]b258e0792013-01-12 07:11:5922#include "net/base/load_timing_info_test_util.h"
[email protected]d8eb84242010-09-25 02:25:0623#include "net/base/net_errors.h"
[email protected]9e743cd2010-03-16 07:03:5324#include "net/base/net_log.h"
25#include "net/base/net_log_unittest.h"
[email protected]ac790b42009-12-02 04:31:3126#include "net/base/request_priority.h"
[email protected]f6d1d6eb2009-06-24 20:16:0927#include "net/base/test_completion_callback.h"
[email protected]277d5942010-08-11 21:02:3528#include "net/http/http_response_headers.h"
[email protected]f6d1d6eb2009-06-24 20:16:0929#include "net/socket/client_socket_factory.h"
30#include "net/socket/client_socket_handle.h"
[email protected]b89f7e42010-05-20 20:37:0031#include "net/socket/client_socket_pool_histograms.h"
[email protected]75439d3b2009-07-23 22:11:1732#include "net/socket/socket_test_util.h"
[email protected]18ccfdb2013-08-15 00:13:4433#include "net/socket/ssl_client_socket.h"
[email protected]3268023f2011-05-05 00:08:1034#include "net/socket/stream_socket.h"
[email protected]18ccfdb2013-08-15 00:13:4435#include "net/udp/datagram_client_socket.h"
[email protected]51fdc7c2012-04-10 19:19:4836#include "testing/gmock/include/gmock/gmock.h"
[email protected]f6d1d6eb2009-06-24 20:16:0937#include "testing/gtest/include/gtest/gtest.h"
38
[email protected]51fdc7c2012-04-10 19:19:4839using ::testing::Invoke;
40using ::testing::Return;
41
[email protected]f6d1d6eb2009-06-24 20:16:0942namespace net {
43
44namespace {
45
[email protected]211d21722009-07-22 15:48:5346const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2047const int kDefaultMaxSocketsPerGroup = 2;
[email protected]0b7648c2009-07-06 20:14:0148
[email protected]034df0f32013-01-07 23:17:4849// Make sure |handle| sets load times correctly when it has been assigned a
50// reused socket.
51void TestLoadTimingInfoConnectedReused(const ClientSocketHandle& handle) {
52 LoadTimingInfo load_timing_info;
53 // Only pass true in as |is_reused|, as in general, HttpStream types should
54 // have stricter concepts of reuse than socket pools.
55 EXPECT_TRUE(handle.GetLoadTimingInfo(true, &load_timing_info));
56
57 EXPECT_EQ(true, load_timing_info.socket_reused);
58 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
59
[email protected]b258e0792013-01-12 07:11:5960 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
61 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:4862}
63
64// Make sure |handle| sets load times correctly when it has been assigned a
[email protected]b021ece62013-06-11 11:06:3365// fresh socket. Also runs TestLoadTimingInfoConnectedReused, since the owner
[email protected]034df0f32013-01-07 23:17:4866// of a connection where |is_reused| is false may consider the connection
67// reused.
68void TestLoadTimingInfoConnectedNotReused(const ClientSocketHandle& handle) {
69 EXPECT_FALSE(handle.is_reused());
70
71 LoadTimingInfo load_timing_info;
72 EXPECT_TRUE(handle.GetLoadTimingInfo(false, &load_timing_info));
73
74 EXPECT_FALSE(load_timing_info.socket_reused);
75 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
76
[email protected]b258e0792013-01-12 07:11:5977 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
78 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
79 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:4880
81 TestLoadTimingInfoConnectedReused(handle);
82}
83
84// Make sure |handle| sets load times correctly, in the case that it does not
85// currently have a socket.
86void TestLoadTimingInfoNotConnected(const ClientSocketHandle& handle) {
87 // Should only be set to true once a socket is assigned, if at all.
88 EXPECT_FALSE(handle.is_reused());
89
90 LoadTimingInfo load_timing_info;
91 EXPECT_FALSE(handle.GetLoadTimingInfo(false, &load_timing_info));
92
93 EXPECT_FALSE(load_timing_info.socket_reused);
94 EXPECT_EQ(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
95
[email protected]b258e0792013-01-12 07:11:5996 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
97 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:4898}
99
[email protected]df4b4ef2010-07-12 18:25:21100class TestSocketParams : public base::RefCounted<TestSocketParams> {
[email protected]5acdce12011-03-30 13:00:20101 public:
[email protected]bb1c4662013-11-14 00:00:07102 explicit TestSocketParams(bool ignore_limits)
103 : ignore_limits_(ignore_limits) {}
[email protected]51fdc7c2012-04-10 19:19:48104
[email protected]51fdc7c2012-04-10 19:19:48105 bool ignore_limits() { return ignore_limits_; }
106
[email protected]df4b4ef2010-07-12 18:25:21107 private:
108 friend class base::RefCounted<TestSocketParams>;
109 ~TestSocketParams() {}
[email protected]51fdc7c2012-04-10 19:19:48110
[email protected]bb1c4662013-11-14 00:00:07111 const bool ignore_limits_;
[email protected]df4b4ef2010-07-12 18:25:21112};
[email protected]7fc5b09a2010-02-27 00:07:38113typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
[email protected]d80a4322009-08-14 07:07:49114
[email protected]3268023f2011-05-05 00:08:10115class MockClientSocket : public StreamSocket {
[email protected]f6d1d6eb2009-06-24 20:16:09116 public:
[email protected]034df0f32013-01-07 23:17:48117 explicit MockClientSocket(net::NetLog* net_log)
118 : connected_(false),
[email protected]0dc88b32014-03-26 20:12:28119 has_unread_data_(false),
[email protected]034df0f32013-01-07 23:17:48120 net_log_(BoundNetLog::Make(net_log, net::NetLog::SOURCE_SOCKET)),
[email protected]e86df8dc2013-03-30 13:18:28121 was_used_to_convey_data_(false) {
[email protected]034df0f32013-01-07 23:17:48122 }
[email protected]f6d1d6eb2009-06-24 20:16:09123
[email protected]0dc88b32014-03-26 20:12:28124 // 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;
128 }
129
[email protected]3f55aa12011-12-07 02:03:33130 // Socket implementation.
[email protected]ab838892009-06-30 18:49:05131 virtual int Read(
[email protected]83039bb2011-12-09 18:43:55132 IOBuffer* /* buf */, int len,
mostynbba063d6032014-10-09 11:01:13133 const CompletionCallback& /* callback */) override {
[email protected]0dc88b32014-03-26 20:12:28134 if (has_unread_data_ && len > 0) {
135 has_unread_data_ = false;
136 was_used_to_convey_data_ = true;
137 return 1;
138 }
[email protected]e86df8dc2013-03-30 13:18:28139 return ERR_UNEXPECTED;
[email protected]3f55aa12011-12-07 02:03:33140 }
[email protected]ab838892009-06-30 18:49:05141
142 virtual int Write(
[email protected]83039bb2011-12-09 18:43:55143 IOBuffer* /* buf */, int len,
mostynbba063d6032014-10-09 11:01:13144 const CompletionCallback& /* callback */) override {
[email protected]0f873e82010-09-02 16:09:01145 was_used_to_convey_data_ = true;
146 return len;
[email protected]ab838892009-06-30 18:49:05147 }
mostynbba063d6032014-10-09 11:01:13148 virtual int SetReceiveBufferSize(int32 size) override { return OK; }
149 virtual int SetSendBufferSize(int32 size) override { return OK; }
[email protected]ab838892009-06-30 18:49:05150
[email protected]dbf036f2011-12-06 23:33:24151 // StreamSocket implementation.
mostynbba063d6032014-10-09 11:01:13152 virtual int Connect(const CompletionCallback& callback) override {
[email protected]dbf036f2011-12-06 23:33:24153 connected_ = true;
154 return OK;
155 }
[email protected]f6d1d6eb2009-06-24 20:16:09156
mostynbba063d6032014-10-09 11:01:13157 virtual void Disconnect() override { connected_ = false; }
158 virtual bool IsConnected() const override { return connected_; }
159 virtual bool IsConnectedAndIdle() const override {
[email protected]0dc88b32014-03-26 20:12:28160 return connected_ && !has_unread_data_;
161 }
[email protected]0b7648c2009-07-06 20:14:01162
mostynbba063d6032014-10-09 11:01:13163 virtual int GetPeerAddress(IPEndPoint* /* address */) const override {
[email protected]9f864b32010-01-20 15:01:16164 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:09165 }
[email protected]f6d1d6eb2009-06-24 20:16:09166
mostynbba063d6032014-10-09 11:01:13167 virtual int GetLocalAddress(IPEndPoint* /* address */) const override {
[email protected]e7f74da2011-04-19 23:49:35168 return ERR_UNEXPECTED;
169 }
170
mostynbba063d6032014-10-09 11:01:13171 virtual const BoundNetLog& NetLog() const override {
[email protected]a2006ece2010-04-23 16:44:02172 return net_log_;
173 }
174
mostynbba063d6032014-10-09 11:01:13175 virtual void SetSubresourceSpeculation() override {}
176 virtual void SetOmniboxSpeculation() override {}
177 virtual bool WasEverUsed() const override {
[email protected]e86df8dc2013-03-30 13:18:28178 return was_used_to_convey_data_;
[email protected]5e6efa52011-06-27 17:26:41179 }
mostynbba063d6032014-10-09 11:01:13180 virtual bool UsingTCPFastOpen() const override { return false; }
181 virtual bool WasNpnNegotiated() const override {
[email protected]2d88e7d2012-07-19 17:55:17182 return false;
183 }
mostynbba063d6032014-10-09 11:01:13184 virtual NextProto GetNegotiatedProtocol() const override {
[email protected]33661e482012-04-03 16:16:26185 return kProtoUnknown;
186 }
mostynbba063d6032014-10-09 11:01:13187 virtual bool GetSSLInfo(SSLInfo* ssl_info) override {
[email protected]2d88e7d2012-07-19 17:55:17188 return false;
189 }
[email protected]9b5614a2010-08-25 20:29:45190
[email protected]f6d1d6eb2009-06-24 20:16:09191 private:
192 bool connected_;
[email protected]0dc88b32014-03-26 20:12:28193 bool has_unread_data_;
[email protected]a2006ece2010-04-23 16:44:02194 BoundNetLog net_log_;
[email protected]0f873e82010-09-02 16:09:01195 bool was_used_to_convey_data_;
[email protected]f6d1d6eb2009-06-24 20:16:09196
[email protected]ab838892009-06-30 18:49:05197 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:09198};
199
[email protected]5fc08e32009-07-15 17:09:57200class TestConnectJob;
201
[email protected]f6d1d6eb2009-06-24 20:16:09202class MockClientSocketFactory : public ClientSocketFactory {
203 public:
[email protected]ab838892009-06-30 18:49:05204 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:09205
[email protected]18ccfdb2013-08-15 00:13:44206 virtual scoped_ptr<DatagramClientSocket> CreateDatagramClientSocket(
[email protected]5370c012011-06-29 03:47:04207 DatagramSocket::BindType bind_type,
208 const RandIntCallback& rand_int_cb,
[email protected]98b0e582011-06-22 14:31:41209 NetLog* net_log,
mostynbba063d6032014-10-09 11:01:13210 const NetLog::Source& source) override {
[email protected]98b0e582011-06-22 14:31:41211 NOTREACHED();
[email protected]18ccfdb2013-08-15 00:13:44212 return scoped_ptr<DatagramClientSocket>();
[email protected]98b0e582011-06-22 14:31:41213 }
214
[email protected]18ccfdb2013-08-15 00:13:44215 virtual scoped_ptr<StreamSocket> CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07216 const AddressList& addresses,
217 NetLog* /* net_log */,
mostynbba063d6032014-10-09 11:01:13218 const NetLog::Source& /*source*/) override {
[email protected]f6d1d6eb2009-06-24 20:16:09219 allocation_count_++;
[email protected]18ccfdb2013-08-15 00:13:44220 return scoped_ptr<StreamSocket>();
[email protected]f6d1d6eb2009-06-24 20:16:09221 }
222
[email protected]18ccfdb2013-08-15 00:13:44223 virtual scoped_ptr<SSLClientSocket> CreateSSLClientSocket(
224 scoped_ptr<ClientSocketHandle> transport_socket,
[email protected]4f4de7e62010-11-12 19:55:27225 const HostPortPair& host_and_port,
[email protected]7ab5bbd12010-10-19 13:33:21226 const SSLConfig& ssl_config,
mostynbba063d6032014-10-09 11:01:13227 const SSLClientSocketContext& context) override {
[email protected]f6d1d6eb2009-06-24 20:16:09228 NOTIMPLEMENTED();
[email protected]18ccfdb2013-08-15 00:13:44229 return scoped_ptr<SSLClientSocket>();
[email protected]f6d1d6eb2009-06-24 20:16:09230 }
231
mostynbba063d6032014-10-09 11:01:13232 virtual void ClearSSLSessionCache() override {
[email protected]25f47352011-02-25 16:31:59233 NOTIMPLEMENTED();
234 }
235
[email protected]5fc08e32009-07-15 17:09:57236 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
[email protected]03b7c8c2013-07-20 04:38:55237
[email protected]5fc08e32009-07-15 17:09:57238 void SignalJobs();
239
[email protected]03b7c8c2013-07-20 04:38:55240 void SignalJob(size_t job);
241
242 void SetJobLoadState(size_t job, LoadState load_state);
243
[email protected]f6d1d6eb2009-06-24 20:16:09244 int allocation_count() const { return allocation_count_; }
245
[email protected]f6d1d6eb2009-06-24 20:16:09246 private:
247 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:57248 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09249};
250
[email protected]ab838892009-06-30 18:49:05251class TestConnectJob : public ConnectJob {
252 public:
253 enum JobType {
254 kMockJob,
255 kMockFailingJob,
256 kMockPendingJob,
257 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57258 kMockWaitingJob,
[email protected]e772db3f2010-07-12 18:11:13259 kMockRecoverableJob,
260 kMockPendingRecoverableJob,
[email protected]e60e47a2010-07-14 03:37:18261 kMockAdditionalErrorStateJob,
262 kMockPendingAdditionalErrorStateJob,
[email protected]0dc88b32014-03-26 20:12:28263 kMockUnreadDataJob,
[email protected]ab838892009-06-30 18:49:05264 };
265
[email protected]994d4932010-07-12 17:55:13266 // The kMockPendingJob uses a slight delay before allowing the connect
267 // to complete.
268 static const int kPendingConnectDelay = 2;
269
[email protected]ab838892009-06-30 18:49:05270 TestConnectJob(JobType job_type,
271 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49272 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34273 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05274 ConnectJob::Delegate* delegate,
[email protected]fd7b7c92009-08-20 19:38:30275 MockClientSocketFactory* client_socket_factory,
[email protected]06650c52010-06-03 00:49:17276 NetLog* net_log)
[email protected]3f6007ab2013-08-22 19:45:39277 : ConnectJob(group_name, timeout_duration, request.priority(), delegate,
[email protected]06650c52010-06-03 00:49:17278 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
[email protected]2ab05b52009-07-01 23:57:58279 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05280 client_socket_factory_(client_socket_factory),
[email protected]e60e47a2010-07-14 03:37:18281 load_state_(LOAD_STATE_IDLE),
[email protected]d5492c52013-11-10 20:44:39282 store_additional_error_state_(false),
283 weak_factory_(this) {
284 }
[email protected]ab838892009-06-30 18:49:05285
[email protected]974ebd62009-08-03 23:14:34286 void Signal() {
[email protected]e772db3f2010-07-12 18:11:13287 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
[email protected]974ebd62009-08-03 23:14:34288 }
289
[email protected]03b7c8c2013-07-20 04:38:55290 void set_load_state(LoadState load_state) { load_state_ = load_state; }
291
292 // From ConnectJob:
293
mostynbba063d6032014-10-09 11:01:13294 virtual LoadState GetLoadState() const override { return load_state_; }
[email protected]46451352009-09-01 14:54:21295
mostynbba063d6032014-10-09 11:01:13296 virtual void GetAdditionalErrorState(ClientSocketHandle* handle) override {
[email protected]e60e47a2010-07-14 03:37:18297 if (store_additional_error_state_) {
298 // Set all of the additional error state fields in some way.
299 handle->set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43300 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:45301 info.headers = new HttpResponseHeaders(std::string());
[email protected]8b498692010-07-16 17:11:43302 handle->set_ssl_error_response_info(info);
[email protected]e60e47a2010-07-14 03:37:18303 }
304 }
305
[email protected]974ebd62009-08-03 23:14:34306 private:
[email protected]03b7c8c2013-07-20 04:38:55307 // From ConnectJob:
[email protected]ab838892009-06-30 18:49:05308
mostynbba063d6032014-10-09 11:01:13309 virtual int ConnectInternal() override {
[email protected]ab838892009-06-30 18:49:05310 AddressList ignored;
[email protected]ab739042011-04-07 15:22:28311 client_socket_factory_->CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07312 ignored, NULL, net::NetLog::Source());
[email protected]18ccfdb2013-08-15 00:13:44313 SetSocket(
314 scoped_ptr<StreamSocket>(new MockClientSocket(net_log().net_log())));
[email protected]ab838892009-06-30 18:49:05315 switch (job_type_) {
316 case kMockJob:
[email protected]e772db3f2010-07-12 18:11:13317 return DoConnect(true /* successful */, false /* sync */,
318 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05319 case kMockFailingJob:
[email protected]e772db3f2010-07-12 18:11:13320 return DoConnect(false /* error */, false /* sync */,
321 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05322 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57323 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47324
325 // Depending on execution timings, posting a delayed task can result
326 // in the task getting executed the at the earliest possible
327 // opportunity or only after returning once from the message loop and
328 // then a second call into the message loop. In order to make behavior
329 // more deterministic, we change the default delay to 2ms. This should
330 // always require us to wait for the second call into the message loop.
331 //
332 // N.B. The correct fix for this and similar timing problems is to
333 // abstract time for the purpose of unittests. Unfortunately, we have
334 // a lot of third-party components that directly call the various
335 // time functions, so this change would be rather invasive.
[email protected]2da659e2013-05-23 20:51:34336 base::MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05337 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13338 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
339 weak_factory_.GetWeakPtr(),
340 true /* successful */,
341 true /* async */,
342 false /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53343 base::TimeDelta::FromMilliseconds(kPendingConnectDelay));
[email protected]ab838892009-06-30 18:49:05344 return ERR_IO_PENDING;
345 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57346 set_load_state(LOAD_STATE_CONNECTING);
[email protected]2da659e2013-05-23 20:51:34347 base::MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05348 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13349 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
350 weak_factory_.GetWeakPtr(),
351 false /* error */,
352 true /* async */,
353 false /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53354 base::TimeDelta::FromMilliseconds(2));
[email protected]ab838892009-06-30 18:49:05355 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57356 case kMockWaitingJob:
[email protected]03b7c8c2013-07-20 04:38:55357 set_load_state(LOAD_STATE_CONNECTING);
[email protected]5fc08e32009-07-15 17:09:57358 client_socket_factory_->WaitForSignal(this);
359 waiting_success_ = true;
360 return ERR_IO_PENDING;
[email protected]e772db3f2010-07-12 18:11:13361 case kMockRecoverableJob:
362 return DoConnect(false /* error */, false /* sync */,
363 true /* recoverable */);
364 case kMockPendingRecoverableJob:
365 set_load_state(LOAD_STATE_CONNECTING);
[email protected]2da659e2013-05-23 20:51:34366 base::MessageLoop::current()->PostDelayedTask(
[email protected]e772db3f2010-07-12 18:11:13367 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13368 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
369 weak_factory_.GetWeakPtr(),
370 false /* error */,
371 true /* async */,
372 true /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53373 base::TimeDelta::FromMilliseconds(2));
[email protected]e772db3f2010-07-12 18:11:13374 return ERR_IO_PENDING;
[email protected]e60e47a2010-07-14 03:37:18375 case kMockAdditionalErrorStateJob:
376 store_additional_error_state_ = true;
377 return DoConnect(false /* error */, false /* sync */,
378 false /* recoverable */);
379 case kMockPendingAdditionalErrorStateJob:
380 set_load_state(LOAD_STATE_CONNECTING);
381 store_additional_error_state_ = true;
[email protected]2da659e2013-05-23 20:51:34382 base::MessageLoop::current()->PostDelayedTask(
[email protected]e60e47a2010-07-14 03:37:18383 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13384 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
385 weak_factory_.GetWeakPtr(),
386 false /* error */,
387 true /* async */,
388 false /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53389 base::TimeDelta::FromMilliseconds(2));
[email protected]e60e47a2010-07-14 03:37:18390 return ERR_IO_PENDING;
[email protected]0dc88b32014-03-26 20:12:28391 case kMockUnreadDataJob: {
392 int ret = DoConnect(true /* successful */, false /* sync */,
393 false /* recoverable */);
394 static_cast<MockClientSocket*>(socket())->set_has_unread_data(true);
395 return ret;
396 }
[email protected]ab838892009-06-30 18:49:05397 default:
398 NOTREACHED();
[email protected]18ccfdb2013-08-15 00:13:44399 SetSocket(scoped_ptr<StreamSocket>());
[email protected]ab838892009-06-30 18:49:05400 return ERR_FAILED;
401 }
402 }
403
[email protected]e772db3f2010-07-12 18:11:13404 int DoConnect(bool succeed, bool was_async, bool recoverable) {
405 int result = OK;
[email protected]ab838892009-06-30 18:49:05406 if (succeed) {
[email protected]83039bb2011-12-09 18:43:55407 socket()->Connect(CompletionCallback());
[email protected]e772db3f2010-07-12 18:11:13408 } else if (recoverable) {
409 result = ERR_PROXY_AUTH_REQUESTED;
[email protected]6e713f02009-08-06 02:56:40410 } else {
[email protected]e772db3f2010-07-12 18:11:13411 result = ERR_CONNECTION_FAILED;
[email protected]18ccfdb2013-08-15 00:13:44412 SetSocket(scoped_ptr<StreamSocket>());
[email protected]ab838892009-06-30 18:49:05413 }
[email protected]2ab05b52009-07-01 23:57:58414
415 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30416 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05417 return result;
418 }
419
[email protected]5fc08e32009-07-15 17:09:57420 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05421 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57422 MockClientSocketFactory* const client_socket_factory_;
[email protected]46451352009-09-01 14:54:21423 LoadState load_state_;
[email protected]e60e47a2010-07-14 03:37:18424 bool store_additional_error_state_;
[email protected]ab838892009-06-30 18:49:05425
[email protected]d5492c52013-11-10 20:44:39426 base::WeakPtrFactory<TestConnectJob> weak_factory_;
427
[email protected]ab838892009-06-30 18:49:05428 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
429};
430
[email protected]d80a4322009-08-14 07:07:49431class TestConnectJobFactory
432 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05433 public:
[email protected]034df0f32013-01-07 23:17:48434 TestConnectJobFactory(MockClientSocketFactory* client_socket_factory,
435 NetLog* net_log)
[email protected]ab838892009-06-30 18:49:05436 : job_type_(TestConnectJob::kMockJob),
[email protected]51fdc7c2012-04-10 19:19:48437 job_types_(NULL),
[email protected]034df0f32013-01-07 23:17:48438 client_socket_factory_(client_socket_factory),
439 net_log_(net_log) {
[email protected]b021ece62013-06-11 11:06:33440 }
[email protected]ab838892009-06-30 18:49:05441
442 virtual ~TestConnectJobFactory() {}
443
444 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
445
[email protected]51fdc7c2012-04-10 19:19:48446 void set_job_types(std::list<TestConnectJob::JobType>* job_types) {
447 job_types_ = job_types;
448 CHECK(!job_types_->empty());
449 }
450
[email protected]974ebd62009-08-03 23:14:34451 void set_timeout_duration(base::TimeDelta timeout_duration) {
452 timeout_duration_ = timeout_duration;
453 }
454
[email protected]3f55aa12011-12-07 02:03:33455 // ConnectJobFactory implementation.
[email protected]83039bb2011-12-09 18:43:55456
[email protected]18ccfdb2013-08-15 00:13:44457 virtual scoped_ptr<ConnectJob> NewConnectJob(
[email protected]ab838892009-06-30 18:49:05458 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49459 const TestClientSocketPoolBase::Request& request,
mostynbba063d6032014-10-09 11:01:13460 ConnectJob::Delegate* delegate) const override {
[email protected]51fdc7c2012-04-10 19:19:48461 EXPECT_TRUE(!job_types_ || !job_types_->empty());
462 TestConnectJob::JobType job_type = job_type_;
463 if (job_types_ && !job_types_->empty()) {
464 job_type = job_types_->front();
465 job_types_->pop_front();
466 }
[email protected]18ccfdb2013-08-15 00:13:44467 return scoped_ptr<ConnectJob>(new TestConnectJob(job_type,
468 group_name,
469 request,
470 timeout_duration_,
471 delegate,
472 client_socket_factory_,
473 net_log_));
[email protected]ab838892009-06-30 18:49:05474 }
475
mostynbba063d6032014-10-09 11:01:13476 virtual base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26477 return timeout_duration_;
478 }
479
[email protected]ab838892009-06-30 18:49:05480 private:
481 TestConnectJob::JobType job_type_;
[email protected]51fdc7c2012-04-10 19:19:48482 std::list<TestConnectJob::JobType>* job_types_;
[email protected]974ebd62009-08-03 23:14:34483 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57484 MockClientSocketFactory* const client_socket_factory_;
[email protected]034df0f32013-01-07 23:17:48485 NetLog* net_log_;
[email protected]ab838892009-06-30 18:49:05486
487 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
488};
489
490class TestClientSocketPool : public ClientSocketPool {
491 public:
[email protected]12322e7e2013-08-15 17:49:26492 typedef TestSocketParams SocketParams;
493
[email protected]ab838892009-06-30 18:49:05494 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53495 int max_sockets,
[email protected]ab838892009-06-30 18:49:05496 int max_sockets_per_group,
[email protected]2431756e2010-09-29 20:26:13497 ClientSocketPoolHistograms* histograms,
[email protected]9bf28db2009-08-29 01:35:16498 base::TimeDelta unused_idle_socket_timeout,
499 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49500 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
[email protected]043b68c82013-08-22 23:41:52501 : base_(NULL, max_sockets, max_sockets_per_group, histograms,
[email protected]9bf28db2009-08-29 01:35:16502 unused_idle_socket_timeout, used_idle_socket_timeout,
[email protected]66761b952010-06-25 21:30:38503 connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05504
[email protected]2431756e2010-09-29 20:26:13505 virtual ~TestClientSocketPool() {}
506
[email protected]ab838892009-06-30 18:49:05507 virtual int RequestSocket(
508 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49509 const void* params,
[email protected]ac790b42009-12-02 04:31:31510 net::RequestPriority priority,
[email protected]ab838892009-06-30 18:49:05511 ClientSocketHandle* handle,
[email protected]49639fa2011-12-20 23:22:41512 const CompletionCallback& callback,
mostynbba063d6032014-10-09 11:01:13513 const BoundNetLog& net_log) override {
[email protected]df4b4ef2010-07-12 18:25:21514 const scoped_refptr<TestSocketParams>* casted_socket_params =
515 static_cast<const scoped_refptr<TestSocketParams>*>(params);
516 return base_.RequestSocket(group_name, *casted_socket_params, priority,
517 handle, callback, net_log);
[email protected]ab838892009-06-30 18:49:05518 }
519
[email protected]2c2bef152010-10-13 00:55:03520 virtual void RequestSockets(const std::string& group_name,
521 const void* params,
522 int num_sockets,
mostynbba063d6032014-10-09 11:01:13523 const BoundNetLog& net_log) override {
[email protected]2c2bef152010-10-13 00:55:03524 const scoped_refptr<TestSocketParams>* casted_params =
525 static_cast<const scoped_refptr<TestSocketParams>*>(params);
526
527 base_.RequestSockets(group_name, *casted_params, num_sockets, net_log);
528 }
529
[email protected]ab838892009-06-30 18:49:05530 virtual void CancelRequest(
531 const std::string& group_name,
mostynbba063d6032014-10-09 11:01:13532 ClientSocketHandle* handle) override {
[email protected]d80a4322009-08-14 07:07:49533 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05534 }
535
536 virtual void ReleaseSocket(
537 const std::string& group_name,
[email protected]18ccfdb2013-08-15 00:13:44538 scoped_ptr<StreamSocket> socket,
mostynbba063d6032014-10-09 11:01:13539 int id) override {
[email protected]18ccfdb2013-08-15 00:13:44540 base_.ReleaseSocket(group_name, socket.Pass(), id);
[email protected]a7e38572010-06-07 18:22:24541 }
542
mostynbba063d6032014-10-09 11:01:13543 virtual void FlushWithError(int error) override {
[email protected]7af985a2012-12-14 22:40:42544 base_.FlushWithError(error);
[email protected]ab838892009-06-30 18:49:05545 }
546
mostynbba063d6032014-10-09 11:01:13547 virtual bool IsStalled() const override {
[email protected]51fdc7c2012-04-10 19:19:48548 return base_.IsStalled();
549 }
550
mostynbba063d6032014-10-09 11:01:13551 virtual void CloseIdleSockets() override {
[email protected]d80a4322009-08-14 07:07:49552 base_.CloseIdleSockets();
[email protected]ab838892009-06-30 18:49:05553 }
554
mostynbba063d6032014-10-09 11:01:13555 virtual int IdleSocketCount() const override {
[email protected]d4dfdab2011-12-07 16:56:59556 return base_.idle_socket_count();
557 }
[email protected]ab838892009-06-30 18:49:05558
[email protected]d4dfdab2011-12-07 16:56:59559 virtual int IdleSocketCountInGroup(
mostynbba063d6032014-10-09 11:01:13560 const std::string& group_name) const override {
[email protected]d80a4322009-08-14 07:07:49561 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05562 }
563
[email protected]d4dfdab2011-12-07 16:56:59564 virtual LoadState GetLoadState(
565 const std::string& group_name,
mostynbba063d6032014-10-09 11:01:13566 const ClientSocketHandle* handle) const override {
[email protected]d80a4322009-08-14 07:07:49567 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05568 }
569
mostynbba063d6032014-10-09 11:01:13570 virtual void AddHigherLayeredPool(HigherLayeredPool* higher_pool) override {
[email protected]043b68c82013-08-22 23:41:52571 base_.AddHigherLayeredPool(higher_pool);
[email protected]51fdc7c2012-04-10 19:19:48572 }
573
[email protected]043b68c82013-08-22 23:41:52574 virtual void RemoveHigherLayeredPool(
mostynbba063d6032014-10-09 11:01:13575 HigherLayeredPool* higher_pool) override {
[email protected]043b68c82013-08-22 23:41:52576 base_.RemoveHigherLayeredPool(higher_pool);
[email protected]51fdc7c2012-04-10 19:19:48577 }
578
[email protected]ea5ef4c2013-06-13 22:50:27579 virtual base::DictionaryValue* GetInfoAsValue(
[email protected]d4dfdab2011-12-07 16:56:59580 const std::string& name,
581 const std::string& type,
mostynbba063d6032014-10-09 11:01:13582 bool include_nested_pools) const override {
[email protected]59d7a5a2010-08-30 16:44:27583 return base_.GetInfoAsValue(name, type);
584 }
585
mostynbba063d6032014-10-09 11:01:13586 virtual base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26587 return base_.ConnectionTimeout();
588 }
589
mostynbba063d6032014-10-09 11:01:13590 virtual ClientSocketPoolHistograms* histograms() const override {
[email protected]b89f7e42010-05-20 20:37:00591 return base_.histograms();
592 }
[email protected]a796bcec2010-03-22 17:17:26593
[email protected]d80a4322009-08-14 07:07:49594 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20595
[email protected]8159a1c2012-06-07 00:00:10596 int NumUnassignedConnectJobsInGroup(const std::string& group_name) const {
597 return base_.NumUnassignedConnectJobsInGroup(group_name);
598 }
599
[email protected]974ebd62009-08-03 23:14:34600 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49601 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34602 }
603
[email protected]2c2bef152010-10-13 00:55:03604 int NumActiveSocketsInGroup(const std::string& group_name) const {
605 return base_.NumActiveSocketsInGroup(group_name);
606 }
607
[email protected]2abfe90a2010-08-25 17:49:51608 bool HasGroup(const std::string& group_name) const {
609 return base_.HasGroup(group_name);
610 }
611
[email protected]9bf28db2009-08-29 01:35:16612 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
613
[email protected]06d94042010-08-25 01:45:22614 void EnableConnectBackupJobs() { base_.EnableConnectBackupJobs(); }
[email protected]43a21b82010-06-10 21:30:54615
[email protected]043b68c82013-08-22 23:41:52616 bool CloseOneIdleConnectionInHigherLayeredPool() {
617 return base_.CloseOneIdleConnectionInHigherLayeredPool();
[email protected]51fdc7c2012-04-10 19:19:48618 }
619
[email protected]ab838892009-06-30 18:49:05620 private:
[email protected]d80a4322009-08-14 07:07:49621 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05622
623 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
624};
625
[email protected]a937a06d2009-08-19 21:19:24626} // namespace
627
[email protected]a937a06d2009-08-19 21:19:24628namespace {
629
[email protected]5fc08e32009-07-15 17:09:57630void MockClientSocketFactory::SignalJobs() {
631 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
632 it != waiting_jobs_.end(); ++it) {
633 (*it)->Signal();
634 }
635 waiting_jobs_.clear();
636}
637
[email protected]03b7c8c2013-07-20 04:38:55638void MockClientSocketFactory::SignalJob(size_t job) {
639 ASSERT_LT(job, waiting_jobs_.size());
640 waiting_jobs_[job]->Signal();
641 waiting_jobs_.erase(waiting_jobs_.begin() + job);
642}
643
644void MockClientSocketFactory::SetJobLoadState(size_t job,
645 LoadState load_state) {
646 ASSERT_LT(job, waiting_jobs_.size());
647 waiting_jobs_[job]->set_load_state(load_state);
648}
649
[email protected]974ebd62009-08-03 23:14:34650class TestConnectJobDelegate : public ConnectJob::Delegate {
651 public:
652 TestConnectJobDelegate()
653 : have_result_(false), waiting_for_result_(false), result_(OK) {}
654 virtual ~TestConnectJobDelegate() {}
655
mostynbba063d6032014-10-09 11:01:13656 virtual void OnConnectJobComplete(int result, ConnectJob* job) override {
[email protected]974ebd62009-08-03 23:14:34657 result_ = result;
[email protected]18ccfdb2013-08-15 00:13:44658 scoped_ptr<ConnectJob> owned_job(job);
659 scoped_ptr<StreamSocket> socket = owned_job->PassSocket();
[email protected]9b6fee12009-09-29 18:13:07660 // socket.get() should be NULL iff result != OK
[email protected]18ccfdb2013-08-15 00:13:44661 EXPECT_EQ(socket == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34662 have_result_ = true;
663 if (waiting_for_result_)
[email protected]2da659e2013-05-23 20:51:34664 base::MessageLoop::current()->Quit();
[email protected]974ebd62009-08-03 23:14:34665 }
666
667 int WaitForResult() {
668 DCHECK(!waiting_for_result_);
669 while (!have_result_) {
670 waiting_for_result_ = true;
[email protected]2da659e2013-05-23 20:51:34671 base::MessageLoop::current()->Run();
[email protected]974ebd62009-08-03 23:14:34672 waiting_for_result_ = false;
673 }
674 have_result_ = false; // auto-reset for next callback
675 return result_;
676 }
677
678 private:
679 bool have_result_;
680 bool waiting_for_result_;
681 int result_;
682};
683
[email protected]2431756e2010-09-29 20:26:13684class ClientSocketPoolBaseTest : public testing::Test {
[email protected]f6d1d6eb2009-06-24 20:16:09685 protected:
[email protected]b89f7e42010-05-20 20:37:00686 ClientSocketPoolBaseTest()
[email protected]bb1c4662013-11-14 00:00:07687 : params_(new TestSocketParams(false /* ignore_limits */)),
[email protected]636b8252011-04-08 19:56:54688 histograms_("ClientSocketPoolTest") {
689 connect_backup_jobs_enabled_ =
690 internal::ClientSocketPoolBaseHelper::connect_backup_jobs_enabled();
691 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(true);
[email protected]64770b7d2011-11-16 04:30:41692 cleanup_timer_enabled_ =
693 internal::ClientSocketPoolBaseHelper::cleanup_timer_enabled();
[email protected]636b8252011-04-08 19:56:54694 }
[email protected]2431756e2010-09-29 20:26:13695
[email protected]636b8252011-04-08 19:56:54696 virtual ~ClientSocketPoolBaseTest() {
697 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
698 connect_backup_jobs_enabled_);
[email protected]64770b7d2011-11-16 04:30:41699 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(
700 cleanup_timer_enabled_);
[email protected]636b8252011-04-08 19:56:54701 }
[email protected]c9d6a1d2009-07-14 16:15:20702
[email protected]211d21722009-07-22 15:48:53703 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16704 CreatePoolWithIdleTimeouts(
705 max_sockets,
706 max_sockets_per_group,
[email protected]82b8c962011-10-12 09:17:30707 ClientSocketPool::unused_idle_socket_timeout(),
708 ClientSocketPool::used_idle_socket_timeout());
[email protected]9bf28db2009-08-29 01:35:16709 }
710
711 void CreatePoolWithIdleTimeouts(
712 int max_sockets, int max_sockets_per_group,
713 base::TimeDelta unused_idle_socket_timeout,
714 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20715 DCHECK(!pool_.get());
[email protected]034df0f32013-01-07 23:17:48716 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_,
717 &net_log_);
[email protected]2431756e2010-09-29 20:26:13718 pool_.reset(new TestClientSocketPool(max_sockets,
719 max_sockets_per_group,
720 &histograms_,
721 unused_idle_socket_timeout,
722 used_idle_socket_timeout,
723 connect_job_factory_));
[email protected]c9d6a1d2009-07-14 16:15:20724 }
[email protected]f6d1d6eb2009-06-24 20:16:09725
[email protected]b021ece62013-06-11 11:06:33726 int StartRequestWithParams(
727 const std::string& group_name,
728 RequestPriority priority,
729 const scoped_refptr<TestSocketParams>& params) {
[email protected]12322e7e2013-08-15 17:49:26730 return test_base_.StartRequestUsingPool(
731 pool_.get(), group_name, priority, params);
[email protected]b021ece62013-06-11 11:06:33732 }
733
734 int StartRequest(const std::string& group_name, RequestPriority priority) {
735 return StartRequestWithParams(group_name, priority, params_);
[email protected]f6d1d6eb2009-06-24 20:16:09736 }
737
[email protected]2431756e2010-09-29 20:26:13738 int GetOrderOfRequest(size_t index) const {
739 return test_base_.GetOrderOfRequest(index);
[email protected]f6d1d6eb2009-06-24 20:16:09740 }
741
[email protected]2431756e2010-09-29 20:26:13742 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
743 return test_base_.ReleaseOneConnection(keep_alive);
744 }
745
746 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
747 test_base_.ReleaseAllConnections(keep_alive);
748 }
749
750 TestSocketRequest* request(int i) { return test_base_.request(i); }
751 size_t requests_size() const { return test_base_.requests_size(); }
752 ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); }
753 size_t completion_count() const { return test_base_.completion_count(); }
754
[email protected]034df0f32013-01-07 23:17:48755 CapturingNetLog net_log_;
[email protected]636b8252011-04-08 19:56:54756 bool connect_backup_jobs_enabled_;
[email protected]64770b7d2011-11-16 04:30:41757 bool cleanup_timer_enabled_;
[email protected]f6d1d6eb2009-06-24 20:16:09758 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04759 TestConnectJobFactory* connect_job_factory_;
[email protected]df4b4ef2010-07-12 18:25:21760 scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:13761 ClientSocketPoolHistograms histograms_;
762 scoped_ptr<TestClientSocketPool> pool_;
763 ClientSocketPoolTest test_base_;
[email protected]f6d1d6eb2009-06-24 20:16:09764};
765
[email protected]974ebd62009-08-03 23:14:34766// Even though a timeout is specified, it doesn't time out on a synchronous
767// completion.
768TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
769 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06770 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49771 TestClientSocketPoolBase::Request request(
[email protected]bb1c4662013-11-14 00:00:07772 &ignored, CompletionCallback(), DEFAULT_PRIORITY,
[email protected]2c2bef152010-10-13 00:55:03773 internal::ClientSocketPoolBaseHelper::NORMAL,
[email protected]5acdce12011-03-30 13:00:20774 false, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34775 scoped_ptr<TestConnectJob> job(
776 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:12777 "a",
[email protected]974ebd62009-08-03 23:14:34778 request,
779 base::TimeDelta::FromMicroseconds(1),
780 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30781 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17782 NULL));
[email protected]974ebd62009-08-03 23:14:34783 EXPECT_EQ(OK, job->Connect());
784}
785
786TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
787 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06788 ClientSocketHandle ignored;
[email protected]333bdf62012-06-08 22:57:29789 CapturingNetLog log;
[email protected]9e743cd2010-03-16 07:03:53790
[email protected]d80a4322009-08-14 07:07:49791 TestClientSocketPoolBase::Request request(
[email protected]bb1c4662013-11-14 00:00:07792 &ignored, CompletionCallback(), DEFAULT_PRIORITY,
[email protected]2c2bef152010-10-13 00:55:03793 internal::ClientSocketPoolBaseHelper::NORMAL,
[email protected]5acdce12011-03-30 13:00:20794 false, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34795 // Deleted by TestConnectJobDelegate.
796 TestConnectJob* job =
797 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12798 "a",
[email protected]974ebd62009-08-03 23:14:34799 request,
800 base::TimeDelta::FromMicroseconds(1),
801 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30802 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17803 &log);
[email protected]974ebd62009-08-03 23:14:34804 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
[email protected]26b9973962012-01-28 00:57:00805 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
[email protected]974ebd62009-08-03 23:14:34806 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30807
[email protected]333bdf62012-06-08 22:57:29808 CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:40809 log.GetEntries(&entries);
810
811 EXPECT_EQ(6u, entries.size());
[email protected]e9002a92010-01-29 07:10:46812 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40813 entries, 0, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]06650c52010-06-03 00:49:17814 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40815 entries, 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]e9002a92010-01-29 07:10:46816 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40817 entries, 2, NetLog::TYPE_CONNECT_JOB_SET_SOCKET,
[email protected]06650c52010-06-03 00:49:17818 NetLog::PHASE_NONE));
819 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40820 entries, 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
[email protected]9e743cd2010-03-16 07:03:53821 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:46822 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40823 entries, 4, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]06650c52010-06-03 00:49:17824 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40825 entries, 5, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34826}
827
[email protected]5fc08e32009-07-15 17:09:57828TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53829 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20830
[email protected]6ecf2b92011-12-15 01:14:52831 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06832 ClientSocketHandle handle;
[email protected]333bdf62012-06-08 22:57:29833 CapturingBoundNetLog log;
[email protected]034df0f32013-01-07 23:17:48834 TestLoadTimingInfoNotConnected(handle);
[email protected]9e743cd2010-03-16 07:03:53835
[email protected]2431756e2010-09-29 20:26:13836 EXPECT_EQ(OK,
837 handle.Init("a",
838 params_,
[email protected]bb1c4662013-11-14 00:00:07839 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:52840 callback.callback(),
[email protected]2431756e2010-09-29 20:26:13841 pool_.get(),
842 log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09843 EXPECT_TRUE(handle.is_initialized());
844 EXPECT_TRUE(handle.socket());
[email protected]034df0f32013-01-07 23:17:48845 TestLoadTimingInfoConnectedNotReused(handle);
846
[email protected]f6d1d6eb2009-06-24 20:16:09847 handle.Reset();
[email protected]034df0f32013-01-07 23:17:48848 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:30849
[email protected]333bdf62012-06-08 22:57:29850 CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:40851 log.GetEntries(&entries);
852
853 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:46854 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40855 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]9e743cd2010-03-16 07:03:53856 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40857 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:17858 NetLog::PHASE_NONE));
859 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40860 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]9e743cd2010-03-16 07:03:53861 NetLog::PHASE_NONE));
862 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40863 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09864}
865
[email protected]ab838892009-06-30 18:49:05866TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53867 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20868
[email protected]ab838892009-06-30 18:49:05869 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]333bdf62012-06-08 22:57:29870 CapturingBoundNetLog log;
[email protected]9e743cd2010-03-16 07:03:53871
[email protected]2431756e2010-09-29 20:26:13872 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:52873 TestCompletionCallback callback;
[email protected]e60e47a2010-07-14 03:37:18874 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:13875 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43876 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:45877 info.headers = new HttpResponseHeaders(std::string());
[email protected]2431756e2010-09-29 20:26:13878 handle.set_ssl_error_response_info(info);
879 EXPECT_EQ(ERR_CONNECTION_FAILED,
880 handle.Init("a",
881 params_,
[email protected]bb1c4662013-11-14 00:00:07882 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:52883 callback.callback(),
[email protected]2431756e2010-09-29 20:26:13884 pool_.get(),
885 log.bound()));
886 EXPECT_FALSE(handle.socket());
887 EXPECT_FALSE(handle.is_ssl_error());
888 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]034df0f32013-01-07 23:17:48889 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:30890
[email protected]333bdf62012-06-08 22:57:29891 CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:40892 log.GetEntries(&entries);
893
894 EXPECT_EQ(3u, entries.size());
[email protected]5a1d7ca2010-04-28 20:12:27895 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40896 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:17897 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40898 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:17899 NetLog::PHASE_NONE));
[email protected]a2006ece2010-04-23 16:44:02900 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40901 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09902}
903
[email protected]211d21722009-07-22 15:48:53904TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
905 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
906
[email protected]9e743cd2010-03-16 07:03:53907 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30908
[email protected]bb1c4662013-11-14 00:00:07909 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
910 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
911 EXPECT_EQ(OK, StartRequest("c", DEFAULT_PRIORITY));
912 EXPECT_EQ(OK, StartRequest("d", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:53913
[email protected]2431756e2010-09-29 20:26:13914 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53915 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13916 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53917
[email protected]bb1c4662013-11-14 00:00:07918 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", DEFAULT_PRIORITY));
919 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", DEFAULT_PRIORITY));
920 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:53921
[email protected]2431756e2010-09-29 20:26:13922 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53923
[email protected]2431756e2010-09-29 20:26:13924 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53925 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13926 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53927
928 EXPECT_EQ(1, GetOrderOfRequest(1));
929 EXPECT_EQ(2, GetOrderOfRequest(2));
930 EXPECT_EQ(3, GetOrderOfRequest(3));
931 EXPECT_EQ(4, GetOrderOfRequest(4));
932 EXPECT_EQ(5, GetOrderOfRequest(5));
933 EXPECT_EQ(6, GetOrderOfRequest(6));
934 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17935
936 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13937 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53938}
939
940TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
941 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
942
[email protected]9e743cd2010-03-16 07:03:53943 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30944
[email protected]211d21722009-07-22 15:48:53945 // Reach all limits: max total sockets, and max sockets per group.
[email protected]bb1c4662013-11-14 00:00:07946 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
947 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
948 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
949 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:53950
[email protected]2431756e2010-09-29 20:26:13951 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53952 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13953 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53954
955 // Now create a new group and verify that we don't starve it.
[email protected]bb1c4662013-11-14 00:00:07956 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:53957
[email protected]2431756e2010-09-29 20:26:13958 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53959
[email protected]2431756e2010-09-29 20:26:13960 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53961 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13962 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53963
964 EXPECT_EQ(1, GetOrderOfRequest(1));
965 EXPECT_EQ(2, GetOrderOfRequest(2));
966 EXPECT_EQ(3, GetOrderOfRequest(3));
967 EXPECT_EQ(4, GetOrderOfRequest(4));
968 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17969
970 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13971 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53972}
973
974TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
975 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
976
[email protected]ac790b42009-12-02 04:31:31977 EXPECT_EQ(OK, StartRequest("b", LOWEST));
978 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
979 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
980 EXPECT_EQ(OK, StartRequest("a", LOWEST));
[email protected]211d21722009-07-22 15:48:53981
[email protected]2431756e2010-09-29 20:26:13982 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53983 client_socket_factory_.allocation_count());
984
[email protected]ac790b42009-12-02 04:31:31985 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
986 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
987 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53988
[email protected]2431756e2010-09-29 20:26:13989 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53990
[email protected]2431756e2010-09-29 20:26:13991 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53992
993 // First 4 requests don't have to wait, and finish in order.
994 EXPECT_EQ(1, GetOrderOfRequest(1));
995 EXPECT_EQ(2, GetOrderOfRequest(2));
996 EXPECT_EQ(3, GetOrderOfRequest(3));
997 EXPECT_EQ(4, GetOrderOfRequest(4));
998
[email protected]ac790b42009-12-02 04:31:31999 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
1000 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:531001 EXPECT_EQ(7, GetOrderOfRequest(5));
1002 EXPECT_EQ(6, GetOrderOfRequest(6));
1003 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171004
1005 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131006 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]211d21722009-07-22 15:48:531007}
1008
1009TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
1010 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1011
[email protected]ac790b42009-12-02 04:31:311012 EXPECT_EQ(OK, StartRequest("a", LOWEST));
1013 EXPECT_EQ(OK, StartRequest("a", LOW));
1014 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
1015 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
[email protected]211d21722009-07-22 15:48:531016
[email protected]2431756e2010-09-29 20:26:131017 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531018 client_socket_factory_.allocation_count());
1019
[email protected]ac790b42009-12-02 04:31:311020 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
1021 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1022 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:531023
[email protected]2431756e2010-09-29 20:26:131024 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531025
[email protected]2431756e2010-09-29 20:26:131026 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531027 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131028 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:531029
1030 // First 4 requests don't have to wait, and finish in order.
1031 EXPECT_EQ(1, GetOrderOfRequest(1));
1032 EXPECT_EQ(2, GetOrderOfRequest(2));
1033 EXPECT_EQ(3, GetOrderOfRequest(3));
1034 EXPECT_EQ(4, GetOrderOfRequest(4));
1035
1036 // Request ("b", 7) has the highest priority, but we can't make new socket for
1037 // group "b", because it has reached the per-group limit. Then we make
1038 // socket for ("c", 6), because it has higher priority than ("a", 4),
1039 // and we still can't make a socket for group "b".
1040 EXPECT_EQ(5, GetOrderOfRequest(5));
1041 EXPECT_EQ(6, GetOrderOfRequest(6));
1042 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171043
1044 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131045 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:531046}
1047
1048// Make sure that we count connecting sockets against the total limit.
1049TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
1050 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1051
[email protected]bb1c4662013-11-14 00:00:071052 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1053 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
1054 EXPECT_EQ(OK, StartRequest("c", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:531055
1056 // Create one asynchronous request.
1057 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]bb1c4662013-11-14 00:00:071058 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:531059
[email protected]6b175382009-10-13 06:47:471060 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1061 // actually become pending until 2ms after they have been created. In order
1062 // to flush all tasks, we need to wait so that we know there are no
1063 // soon-to-be-pending tasks waiting.
[email protected]26b9973962012-01-28 00:57:001064 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
[email protected]2da659e2013-05-23 20:51:341065 base::MessageLoop::current()->RunUntilIdle();
[email protected]6b175382009-10-13 06:47:471066
[email protected]211d21722009-07-22 15:48:531067 // The next synchronous request should wait for its turn.
1068 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]bb1c4662013-11-14 00:00:071069 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:531070
[email protected]2431756e2010-09-29 20:26:131071 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531072
[email protected]2431756e2010-09-29 20:26:131073 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531074 client_socket_factory_.allocation_count());
1075
1076 EXPECT_EQ(1, GetOrderOfRequest(1));
1077 EXPECT_EQ(2, GetOrderOfRequest(2));
1078 EXPECT_EQ(3, GetOrderOfRequest(3));
1079 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:171080 EXPECT_EQ(5, GetOrderOfRequest(5));
1081
1082 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131083 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:531084}
1085
[email protected]6427fe22010-04-16 22:27:411086TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
1087 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1088 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1089
[email protected]bb1c4662013-11-14 00:00:071090 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1091 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1092 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1093 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
[email protected]6427fe22010-04-16 22:27:411094
1095 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1096
1097 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1098
[email protected]bb1c4662013-11-14 00:00:071099 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", DEFAULT_PRIORITY));
1100 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", DEFAULT_PRIORITY));
[email protected]6427fe22010-04-16 22:27:411101
1102 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1103
[email protected]2431756e2010-09-29 20:26:131104 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411105 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131106 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411107 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131108 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1109 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411110 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
1111}
1112
[email protected]d7027bb2010-05-10 18:58:541113TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
1114 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1115 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1116
1117 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521118 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131119 EXPECT_EQ(ERR_IO_PENDING,
1120 handle.Init("a",
1121 params_,
[email protected]bb1c4662013-11-14 00:00:071122 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521123 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131124 pool_.get(),
1125 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541126
1127 ClientSocketHandle handles[4];
1128 for (size_t i = 0; i < arraysize(handles); ++i) {
[email protected]6ecf2b92011-12-15 01:14:521129 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131130 EXPECT_EQ(ERR_IO_PENDING,
1131 handles[i].Init("b",
1132 params_,
[email protected]bb1c4662013-11-14 00:00:071133 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521134 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131135 pool_.get(),
1136 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541137 }
1138
1139 // One will be stalled, cancel all the handles now.
1140 // This should hit the OnAvailableSocketSlot() code where we previously had
1141 // stalled groups, but no longer have any.
1142 for (size_t i = 0; i < arraysize(handles); ++i)
1143 handles[i].Reset();
1144}
1145
[email protected]eb5a99382010-07-11 03:18:261146TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:541147 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1148 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1149
[email protected]eb5a99382010-07-11 03:18:261150 {
1151 ClientSocketHandle handles[kDefaultMaxSockets];
[email protected]6ecf2b92011-12-15 01:14:521152 TestCompletionCallback callbacks[kDefaultMaxSockets];
[email protected]eb5a99382010-07-11 03:18:261153 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]2431756e2010-09-29 20:26:131154 EXPECT_EQ(OK, handles[i].Init(base::IntToString(i),
1155 params_,
[email protected]bb1c4662013-11-14 00:00:071156 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521157 callbacks[i].callback(),
[email protected]2431756e2010-09-29 20:26:131158 pool_.get(),
1159 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261160 }
1161
1162 // Force a stalled group.
1163 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521164 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131165 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1166 params_,
[email protected]bb1c4662013-11-14 00:00:071167 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521168 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131169 pool_.get(),
1170 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261171
1172 // Cancel the stalled request.
1173 stalled_handle.Reset();
1174
1175 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1176 EXPECT_EQ(0, pool_->IdleSocketCount());
1177
1178 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541179 }
1180
[email protected]43a21b82010-06-10 21:30:541181 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1182 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:261183}
[email protected]43a21b82010-06-10 21:30:541184
[email protected]eb5a99382010-07-11 03:18:261185TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
1186 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1187 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1188
1189 {
1190 ClientSocketHandle handles[kDefaultMaxSockets];
1191 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521192 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131193 EXPECT_EQ(ERR_IO_PENDING, handles[i].Init(base::IntToString(i),
1194 params_,
[email protected]bb1c4662013-11-14 00:00:071195 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521196 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131197 pool_.get(),
1198 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261199 }
1200
1201 // Force a stalled group.
1202 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1203 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521204 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131205 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1206 params_,
[email protected]bb1c4662013-11-14 00:00:071207 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521208 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131209 pool_.get(),
1210 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261211
1212 // Since it is stalled, it should have no connect jobs.
1213 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101214 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261215
1216 // Cancel the stalled request.
1217 handles[0].Reset();
1218
[email protected]eb5a99382010-07-11 03:18:261219 // Now we should have a connect job.
1220 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101221 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261222
1223 // The stalled socket should connect.
1224 EXPECT_EQ(OK, callback.WaitForResult());
1225
1226 EXPECT_EQ(kDefaultMaxSockets + 1,
1227 client_socket_factory_.allocation_count());
1228 EXPECT_EQ(0, pool_->IdleSocketCount());
1229 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101230 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261231
1232 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541233 }
1234
[email protected]eb5a99382010-07-11 03:18:261235 EXPECT_EQ(1, pool_->IdleSocketCount());
1236}
[email protected]43a21b82010-06-10 21:30:541237
[email protected]eb5a99382010-07-11 03:18:261238TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1239 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1240 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:541241
[email protected]eb5a99382010-07-11 03:18:261242 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521243 TestCompletionCallback callback;
[email protected]eb5a99382010-07-11 03:18:261244 {
[email protected]51fdc7c2012-04-10 19:19:481245 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261246 ClientSocketHandle handles[kDefaultMaxSockets];
1247 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521248 TestCompletionCallback callback;
[email protected]1870d5cf2011-05-12 01:55:401249 EXPECT_EQ(OK, handles[i].Init(base::StringPrintf(
1250 "Take 2: %d", i),
1251 params_,
[email protected]bb1c4662013-11-14 00:00:071252 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521253 callback.callback(),
[email protected]1870d5cf2011-05-12 01:55:401254 pool_.get(),
1255 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261256 }
1257
1258 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1259 EXPECT_EQ(0, pool_->IdleSocketCount());
[email protected]51fdc7c2012-04-10 19:19:481260 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261261
1262 // Now we will hit the socket limit.
[email protected]2431756e2010-09-29 20:26:131263 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1264 params_,
[email protected]bb1c4662013-11-14 00:00:071265 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521266 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131267 pool_.get(),
1268 BoundNetLog()));
[email protected]51fdc7c2012-04-10 19:19:481269 EXPECT_TRUE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261270
1271 // Dropping out of scope will close all handles and return them to idle.
1272 }
[email protected]43a21b82010-06-10 21:30:541273
1274 // But if we wait for it, the released idle sockets will be closed in
1275 // preference of the waiting request.
[email protected]8ae03f42010-07-07 19:08:101276 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]eb5a99382010-07-11 03:18:261277
1278 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1279 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:541280}
1281
1282// Regression test for http://crbug.com/40952.
1283TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1284 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]06d94042010-08-25 01:45:221285 pool_->EnableConnectBackupJobs();
[email protected]43a21b82010-06-10 21:30:541286 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1287
1288 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1289 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521290 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131291 EXPECT_EQ(OK, handle.Init(base::IntToString(i),
1292 params_,
[email protected]bb1c4662013-11-14 00:00:071293 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521294 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131295 pool_.get(),
1296 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541297 }
1298
1299 // Flush all the DoReleaseSocket tasks.
[email protected]2da659e2013-05-23 20:51:341300 base::MessageLoop::current()->RunUntilIdle();
[email protected]43a21b82010-06-10 21:30:541301
1302 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1303 // reuse a socket.
1304 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1305 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521306 TestCompletionCallback callback;
[email protected]43a21b82010-06-10 21:30:541307
1308 // "0" is special here, since it should be the first entry in the sorted map,
1309 // which is the one which we would close an idle socket for. We shouldn't
1310 // close an idle socket though, since we should reuse the idle socket.
[email protected]2431756e2010-09-29 20:26:131311 EXPECT_EQ(OK, handle.Init("0",
1312 params_,
[email protected]bb1c4662013-11-14 00:00:071313 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521314 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131315 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211316 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541317
1318 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1319 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1320}
1321
[email protected]ab838892009-06-30 18:49:051322TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531323 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091324
[email protected]bb1c4662013-11-14 00:00:071325 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1326 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
[email protected]c9c6f5c2010-07-31 01:30:031327 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", IDLE));
[email protected]ac790b42009-12-02 04:31:311328 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));
[email protected]f6d1d6eb2009-06-24 20:16:091333
[email protected]2431756e2010-09-29 20:26:131334 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091335
[email protected]c9d6a1d2009-07-14 16:15:201336 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1337 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131338 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1339 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091340
[email protected]c9d6a1d2009-07-14 16:15:201341 EXPECT_EQ(1, GetOrderOfRequest(1));
1342 EXPECT_EQ(2, GetOrderOfRequest(2));
[email protected]c9c6f5c2010-07-31 01:30:031343 EXPECT_EQ(8, GetOrderOfRequest(3));
1344 EXPECT_EQ(6, GetOrderOfRequest(4));
1345 EXPECT_EQ(4, GetOrderOfRequest(5));
1346 EXPECT_EQ(3, GetOrderOfRequest(6));
1347 EXPECT_EQ(5, GetOrderOfRequest(7));
1348 EXPECT_EQ(7, GetOrderOfRequest(8));
[email protected]75439d3b2009-07-23 22:11:171349
1350 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131351 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]f6d1d6eb2009-06-24 20:16:091352}
1353
[email protected]ab838892009-06-30 18:49:051354TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531355 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091356
[email protected]bb1c4662013-11-14 00:00:071357 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1358 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
[email protected]ac790b42009-12-02 04:31:311359 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1360 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1361 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1362 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1363 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091364
[email protected]2431756e2010-09-29 20:26:131365 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091366
[email protected]2431756e2010-09-29 20:26:131367 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
1368 EXPECT_EQ(OK, request(i)->WaitForResult());
[email protected]c9d6a1d2009-07-14 16:15:201369
[email protected]2431756e2010-09-29 20:26:131370 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]c9d6a1d2009-07-14 16:15:201371 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131372 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1373 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091374}
1375
1376// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:051377// The pending connect job will be cancelled and should not call back into
1378// ClientSocketPoolBase.
1379TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531380 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201381
[email protected]ab838892009-06-30 18:49:051382 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131383 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521384 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131385 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1386 params_,
[email protected]bb1c4662013-11-14 00:00:071387 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521388 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131389 pool_.get(),
1390 BoundNetLog()));
1391 handle.Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091392}
1393
[email protected]ab838892009-06-30 18:49:051394TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531395 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201396
[email protected]ab838892009-06-30 18:49:051397 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061398 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521399 TestCompletionCallback callback;
[email protected]f6d1d6eb2009-06-24 20:16:091400
[email protected]2431756e2010-09-29 20:26:131401 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1402 params_,
[email protected]bb1c4662013-11-14 00:00:071403 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521404 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131405 pool_.get(),
1406 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091407
1408 handle.Reset();
1409
[email protected]6ecf2b92011-12-15 01:14:521410 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:131411 EXPECT_EQ(ERR_IO_PENDING,
1412 handle.Init("a",
1413 params_,
[email protected]bb1c4662013-11-14 00:00:071414 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521415 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:131416 pool_.get(),
1417 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091418
1419 EXPECT_EQ(OK, callback2.WaitForResult());
1420 EXPECT_FALSE(callback.have_result());
1421
1422 handle.Reset();
1423}
1424
[email protected]ab838892009-06-30 18:49:051425TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531426 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091427
[email protected]bb1c4662013-11-14 00:00:071428 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1429 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
[email protected]ac790b42009-12-02 04:31:311430 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1431 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1432 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1433 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1434 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091435
1436 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201437 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]2431756e2010-09-29 20:26:131438 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1439 (*requests())[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091440
[email protected]2431756e2010-09-29 20:26:131441 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091442
[email protected]c9d6a1d2009-07-14 16:15:201443 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1444 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131445 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1446 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091447
[email protected]c9d6a1d2009-07-14 16:15:201448 EXPECT_EQ(1, GetOrderOfRequest(1));
1449 EXPECT_EQ(2, GetOrderOfRequest(2));
1450 EXPECT_EQ(5, GetOrderOfRequest(3));
1451 EXPECT_EQ(3, GetOrderOfRequest(4));
[email protected]2431756e2010-09-29 20:26:131452 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1453 GetOrderOfRequest(5)); // Canceled request.
[email protected]c9d6a1d2009-07-14 16:15:201454 EXPECT_EQ(4, GetOrderOfRequest(6));
1455 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171456
1457 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131458 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091459}
1460
[email protected]6ecf2b92011-12-15 01:14:521461class RequestSocketCallback : public TestCompletionCallbackBase {
[email protected]f6d1d6eb2009-06-24 20:16:091462 public:
[email protected]2ab05b52009-07-01 23:57:581463 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:241464 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:581465 TestConnectJobFactory* test_connect_job_factory,
1466 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:091467 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:061468 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:581469 within_callback_(false),
1470 test_connect_job_factory_(test_connect_job_factory),
[email protected]6ecf2b92011-12-15 01:14:521471 next_job_type_(next_job_type),
[email protected]aa249b52013-04-30 01:04:321472 callback_(base::Bind(&RequestSocketCallback::OnComplete,
1473 base::Unretained(this))) {
[email protected]6ecf2b92011-12-15 01:14:521474 }
[email protected]f6d1d6eb2009-06-24 20:16:091475
[email protected]6ecf2b92011-12-15 01:14:521476 virtual ~RequestSocketCallback() {}
1477
1478 const CompletionCallback& callback() const { return callback_; }
1479
1480 private:
1481 void OnComplete(int result) {
1482 SetResult(result);
1483 ASSERT_EQ(OK, result);
[email protected]f6d1d6eb2009-06-24 20:16:091484
1485 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:581486 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]5edbf8d2010-01-13 18:44:111487
1488 // Don't allow reuse of the socket. Disconnect it and then release it and
1489 // run through the MessageLoop once to get it completely released.
1490 handle_->socket()->Disconnect();
[email protected]f6d1d6eb2009-06-24 20:16:091491 handle_->Reset();
[email protected]5edbf8d2010-01-13 18:44:111492 {
[email protected]b5717a42012-02-14 19:33:521493 // TODO: Resolve conflicting intentions of stopping recursion with the
[email protected]b4c62eb2012-11-14 18:36:511494 // |!within_callback_| test (above) and the call to |RunUntilIdle()|
[email protected]b5717a42012-02-14 19:33:521495 // below. http://crbug.com/114130.
[email protected]2da659e2013-05-23 20:51:341496 base::MessageLoop::ScopedNestableTaskAllower allow(
1497 base::MessageLoop::current());
1498 base::MessageLoop::current()->RunUntilIdle();
[email protected]5edbf8d2010-01-13 18:44:111499 }
[email protected]f6d1d6eb2009-06-24 20:16:091500 within_callback_ = true;
[email protected]6ecf2b92011-12-15 01:14:521501 TestCompletionCallback next_job_callback;
[email protected]bb1c4662013-11-14 00:00:071502 scoped_refptr<TestSocketParams> params(
1503 new TestSocketParams(false /* ignore_limits */));
[email protected]2431756e2010-09-29 20:26:131504 int rv = handle_->Init("a",
1505 params,
[email protected]bb1c4662013-11-14 00:00:071506 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521507 next_job_callback.callback(),
[email protected]2431756e2010-09-29 20:26:131508 pool_,
1509 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581510 switch (next_job_type_) {
1511 case TestConnectJob::kMockJob:
1512 EXPECT_EQ(OK, rv);
1513 break;
1514 case TestConnectJob::kMockPendingJob:
1515 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:471516
1517 // For pending jobs, wait for new socket to be created. This makes
1518 // sure there are no more pending operations nor any unclosed sockets
1519 // when the test finishes.
1520 // We need to give it a little bit of time to run, so that all the
1521 // operations that happen on timers (e.g. cleanup of idle
1522 // connections) can execute.
[email protected]5edbf8d2010-01-13 18:44:111523 {
[email protected]2da659e2013-05-23 20:51:341524 base::MessageLoop::ScopedNestableTaskAllower allow(
1525 base::MessageLoop::current());
[email protected]26b9973962012-01-28 00:57:001526 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
[email protected]5edbf8d2010-01-13 18:44:111527 EXPECT_EQ(OK, next_job_callback.WaitForResult());
1528 }
[email protected]2ab05b52009-07-01 23:57:581529 break;
1530 default:
1531 FAIL() << "Unexpected job type: " << next_job_type_;
1532 break;
1533 }
[email protected]f6d1d6eb2009-06-24 20:16:091534 }
1535 }
1536
[email protected]f6d1d6eb2009-06-24 20:16:091537 ClientSocketHandle* const handle_;
[email protected]2431756e2010-09-29 20:26:131538 TestClientSocketPool* const pool_;
[email protected]f6d1d6eb2009-06-24 20:16:091539 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:581540 TestConnectJobFactory* const test_connect_job_factory_;
1541 TestConnectJob::JobType next_job_type_;
[email protected]6ecf2b92011-12-15 01:14:521542 CompletionCallback callback_;
[email protected]f6d1d6eb2009-06-24 20:16:091543};
1544
[email protected]2ab05b52009-07-01 23:57:581545TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531546 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201547
[email protected]0b7648c2009-07-06 20:14:011548 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061549 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581550 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061551 &handle, pool_.get(), connect_job_factory_,
1552 TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131553 int rv = handle.Init("a",
1554 params_,
[email protected]bb1c4662013-11-14 00:00:071555 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521556 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131557 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211558 BoundNetLog());
[email protected]f6d1d6eb2009-06-24 20:16:091559 ASSERT_EQ(ERR_IO_PENDING, rv);
1560
1561 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581562}
[email protected]f6d1d6eb2009-06-24 20:16:091563
[email protected]2ab05b52009-07-01 23:57:581564TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531565 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201566
[email protected]0b7648c2009-07-06 20:14:011567 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061568 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581569 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061570 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]2431756e2010-09-29 20:26:131571 int rv = handle.Init("a",
1572 params_,
[email protected]bb1c4662013-11-14 00:00:071573 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521574 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131575 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211576 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581577 ASSERT_EQ(ERR_IO_PENDING, rv);
1578
1579 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091580}
1581
1582// Make sure that pending requests get serviced after active requests get
1583// cancelled.
[email protected]ab838892009-06-30 18:49:051584TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531585 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201586
[email protected]0b7648c2009-07-06 20:14:011587 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091588
[email protected]bb1c4662013-11-14 00:00:071589 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1590 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1591 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1592 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1593 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1594 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1595 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
[email protected]f6d1d6eb2009-06-24 20:16:091596
[email protected]c9d6a1d2009-07-14 16:15:201597 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1598 // Let's cancel them.
1599 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]2431756e2010-09-29 20:26:131600 ASSERT_FALSE(request(i)->handle()->is_initialized());
1601 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091602 }
1603
[email protected]f6d1d6eb2009-06-24 20:16:091604 // Let's wait for the rest to complete now.
[email protected]2431756e2010-09-29 20:26:131605 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
1606 EXPECT_EQ(OK, request(i)->WaitForResult());
1607 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091608 }
1609
[email protected]2431756e2010-09-29 20:26:131610 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1611 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091612}
1613
1614// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051615TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531616 const size_t kMaxSockets = 5;
1617 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201618
[email protected]0b7648c2009-07-06 20:14:011619 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091620
[email protected]211d21722009-07-22 15:48:531621 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1622 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091623
1624 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531625 for (size_t i = 0; i < kNumberOfRequests; ++i)
[email protected]bb1c4662013-11-14 00:00:071626 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
[email protected]f6d1d6eb2009-06-24 20:16:091627
[email protected]211d21722009-07-22 15:48:531628 for (size_t i = 0; i < kNumberOfRequests; ++i)
[email protected]2431756e2010-09-29 20:26:131629 EXPECT_EQ(ERR_CONNECTION_FAILED, request(i)->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091630}
1631
[email protected]5fc08e32009-07-15 17:09:571632TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531633 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571634
1635 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1636
[email protected]2431756e2010-09-29 20:26:131637 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521638 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131639 int rv = handle.Init("a",
1640 params_,
[email protected]bb1c4662013-11-14 00:00:071641 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521642 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131643 pool_.get(),
1644 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571645 EXPECT_EQ(ERR_IO_PENDING, rv);
1646
1647 // Cancel the active request.
[email protected]2431756e2010-09-29 20:26:131648 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571649
[email protected]2431756e2010-09-29 20:26:131650 rv = handle.Init("a",
1651 params_,
[email protected]bb1c4662013-11-14 00:00:071652 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521653 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131654 pool_.get(),
1655 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571656 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131657 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]5fc08e32009-07-15 17:09:571658
[email protected]2431756e2010-09-29 20:26:131659 EXPECT_FALSE(handle.is_reused());
[email protected]034df0f32013-01-07 23:17:481660 TestLoadTimingInfoConnectedNotReused(handle);
[email protected]5fc08e32009-07-15 17:09:571661 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1662}
1663
[email protected]2b7523d2009-07-29 20:29:231664// Regression test for http://crbug.com/17985.
1665TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1666 const int kMaxSockets = 3;
1667 const int kMaxSocketsPerGroup = 2;
1668 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1669
[email protected]ac790b42009-12-02 04:31:311670 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231671
[email protected]bb1c4662013-11-14 00:00:071672 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1673 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
[email protected]2b7523d2009-07-29 20:29:231674
1675 // This is going to be a pending request in an otherwise empty group.
[email protected]bb1c4662013-11-14 00:00:071676 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
[email protected]2b7523d2009-07-29 20:29:231677
1678 // Reach the maximum socket limit.
[email protected]bb1c4662013-11-14 00:00:071679 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
[email protected]2b7523d2009-07-29 20:29:231680
1681 // Create a stalled group with high priorities.
1682 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1683 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
[email protected]2b7523d2009-07-29 20:29:231684
[email protected]eb5a99382010-07-11 03:18:261685 // Release the first two sockets from "a". Because this is a keepalive,
1686 // the first release will unblock the pending request for "a". The
1687 // second release will unblock a request for "c", becaue it is the next
1688 // high priority socket.
[email protected]2431756e2010-09-29 20:26:131689 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1690 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]2b7523d2009-07-29 20:29:231691
1692 // Closing idle sockets should not get us into trouble, but in the bug
1693 // we were hitting a CHECK here.
[email protected]93054cc12010-06-08 06:12:411694 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]43a21b82010-06-10 21:30:541695 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261696
[email protected]2da659e2013-05-23 20:51:341697 // Run the released socket wakeups.
1698 base::MessageLoop::current()->RunUntilIdle();
[email protected]2b7523d2009-07-29 20:29:231699}
1700
[email protected]4d3b05d2010-01-27 21:27:291701TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531702 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571703
1704 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131705 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521706 TestCompletionCallback callback;
[email protected]333bdf62012-06-08 22:57:291707 CapturingBoundNetLog log;
[email protected]2431756e2010-09-29 20:26:131708 int rv = handle.Init("a",
1709 params_,
1710 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:521711 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131712 pool_.get(),
1713 log.bound());
[email protected]5fc08e32009-07-15 17:09:571714 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131715 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
[email protected]034df0f32013-01-07 23:17:481716 TestLoadTimingInfoNotConnected(handle);
1717
[email protected]2431756e2010-09-29 20:26:131718 EXPECT_EQ(OK, callback.WaitForResult());
1719 EXPECT_TRUE(handle.is_initialized());
1720 EXPECT_TRUE(handle.socket());
[email protected]034df0f32013-01-07 23:17:481721 TestLoadTimingInfoConnectedNotReused(handle);
1722
[email protected]2431756e2010-09-29 20:26:131723 handle.Reset();
[email protected]034df0f32013-01-07 23:17:481724 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:301725
[email protected]333bdf62012-06-08 22:57:291726 CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:401727 log.GetEntries(&entries);
1728
1729 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:461730 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401731 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171732 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401733 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171734 NetLog::PHASE_NONE));
1735 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401736 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]06650c52010-06-03 00:49:171737 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:461738 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401739 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571740}
1741
[email protected]4d3b05d2010-01-27 21:27:291742TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571743 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531744 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571745
1746 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2431756e2010-09-29 20:26:131747 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521748 TestCompletionCallback callback;
[email protected]333bdf62012-06-08 22:57:291749 CapturingBoundNetLog log;
[email protected]e60e47a2010-07-14 03:37:181750 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:131751 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:431752 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:451753 info.headers = new HttpResponseHeaders(std::string());
[email protected]2431756e2010-09-29 20:26:131754 handle.set_ssl_error_response_info(info);
1755 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1756 params_,
[email protected]bb1c4662013-11-14 00:00:071757 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521758 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131759 pool_.get(),
1760 log.bound()));
1761 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1762 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1763 EXPECT_FALSE(handle.is_ssl_error());
1764 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:301765
[email protected]333bdf62012-06-08 22:57:291766 CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:401767 log.GetEntries(&entries);
1768
1769 EXPECT_EQ(3u, entries.size());
[email protected]e9002a92010-01-29 07:10:461770 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401771 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171772 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401773 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171774 NetLog::PHASE_NONE));
[email protected]6b624c62010-03-14 08:37:321775 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401776 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571777}
1778
[email protected]4d3b05d2010-01-27 21:27:291779TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101780 // TODO(eroman): Add back the log expectations! Removed them because the
1781 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531782 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571783
1784 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131785 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521786 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131787 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:521788 TestCompletionCallback callback2;
[email protected]5fc08e32009-07-15 17:09:571789
[email protected]2431756e2010-09-29 20:26:131790 EXPECT_EQ(ERR_IO_PENDING,
1791 handle.Init("a",
1792 params_,
[email protected]bb1c4662013-11-14 00:00:071793 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521794 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131795 pool_.get(),
1796 BoundNetLog()));
[email protected]333bdf62012-06-08 22:57:291797 CapturingBoundNetLog log2;
[email protected]2431756e2010-09-29 20:26:131798 EXPECT_EQ(ERR_IO_PENDING,
1799 handle2.Init("a",
1800 params_,
[email protected]bb1c4662013-11-14 00:00:071801 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521802 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:131803 pool_.get(),
1804 BoundNetLog()));
[email protected]5fc08e32009-07-15 17:09:571805
[email protected]2431756e2010-09-29 20:26:131806 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571807
[email protected]fd7b7c92009-08-20 19:38:301808
1809 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301810
[email protected]2431756e2010-09-29 20:26:131811 EXPECT_EQ(OK, callback2.WaitForResult());
1812 handle2.Reset();
[email protected]fd7b7c92009-08-20 19:38:301813
1814 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531815 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571816}
1817
[email protected]4d3b05d2010-01-27 21:27:291818TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341819 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1820
[email protected]17a0c6c2009-08-04 00:07:041821 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1822
[email protected]ac790b42009-12-02 04:31:311823 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1824 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1825 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1826 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341827
1828 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]2431756e2010-09-29 20:26:131829 (*requests())[2]->handle()->Reset();
1830 (*requests())[3]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341831 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1832
[email protected]2431756e2010-09-29 20:26:131833 (*requests())[1]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341834 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1835
[email protected]2431756e2010-09-29 20:26:131836 (*requests())[0]->handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261837 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]974ebd62009-08-03 23:14:341838}
1839
[email protected]5fc08e32009-07-15 17:09:571840// When requests and ConnectJobs are not coupled, the request will get serviced
1841// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291842TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531843 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571844
1845 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321846 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571847
[email protected]2431756e2010-09-29 20:26:131848 std::vector<TestSocketRequest*> request_order;
1849 size_t completion_count; // unused
1850 TestSocketRequest req1(&request_order, &completion_count);
1851 int rv = req1.handle()->Init("a",
1852 params_,
[email protected]bb1c4662013-11-14 00:00:071853 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521854 req1.callback(), pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211855 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571856 EXPECT_EQ(ERR_IO_PENDING, rv);
1857 EXPECT_EQ(OK, req1.WaitForResult());
1858
1859 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1860 // without a job.
1861 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1862
[email protected]2431756e2010-09-29 20:26:131863 TestSocketRequest req2(&request_order, &completion_count);
1864 rv = req2.handle()->Init("a",
1865 params_,
[email protected]bb1c4662013-11-14 00:00:071866 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521867 req2.callback(),
[email protected]2431756e2010-09-29 20:26:131868 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211869 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571870 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131871 TestSocketRequest req3(&request_order, &completion_count);
1872 rv = req3.handle()->Init("a",
1873 params_,
[email protected]bb1c4662013-11-14 00:00:071874 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521875 req3.callback(),
[email protected]2431756e2010-09-29 20:26:131876 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211877 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571878 EXPECT_EQ(ERR_IO_PENDING, rv);
1879
1880 // Both Requests 2 and 3 are pending. We release socket 1 which should
1881 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331882 req1.handle()->Reset();
[email protected]2da659e2013-05-23 20:51:341883 // Run the released socket wakeups.
1884 base::MessageLoop::current()->RunUntilIdle();
[email protected]a6c59f62009-07-29 16:33:331885 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571886 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331887 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571888
1889 // Signal job 2, which should service request 3.
1890
1891 client_socket_factory_.SignalJobs();
1892 EXPECT_EQ(OK, req3.WaitForResult());
1893
[email protected]2431756e2010-09-29 20:26:131894 ASSERT_EQ(3U, request_order.size());
1895 EXPECT_EQ(&req1, request_order[0]);
1896 EXPECT_EQ(&req2, request_order[1]);
1897 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571898 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1899}
1900
1901// The requests are not coupled to the jobs. So, the requests should finish in
1902// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:291903TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531904 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571905 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321906 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571907
[email protected]2431756e2010-09-29 20:26:131908 std::vector<TestSocketRequest*> request_order;
1909 size_t completion_count; // unused
1910 TestSocketRequest req1(&request_order, &completion_count);
1911 int rv = req1.handle()->Init("a",
1912 params_,
[email protected]bb1c4662013-11-14 00:00:071913 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521914 req1.callback(),
[email protected]2431756e2010-09-29 20:26:131915 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211916 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571917 EXPECT_EQ(ERR_IO_PENDING, rv);
1918
[email protected]2431756e2010-09-29 20:26:131919 TestSocketRequest req2(&request_order, &completion_count);
1920 rv = req2.handle()->Init("a",
1921 params_,
[email protected]bb1c4662013-11-14 00:00:071922 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521923 req2.callback(),
[email protected]2431756e2010-09-29 20:26:131924 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211925 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571926 EXPECT_EQ(ERR_IO_PENDING, rv);
1927
1928 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321929 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571930
[email protected]2431756e2010-09-29 20:26:131931 TestSocketRequest req3(&request_order, &completion_count);
1932 rv = req3.handle()->Init("a",
1933 params_,
[email protected]bb1c4662013-11-14 00:00:071934 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521935 req3.callback(),
[email protected]2431756e2010-09-29 20:26:131936 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211937 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571938 EXPECT_EQ(ERR_IO_PENDING, rv);
1939
1940 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1941 EXPECT_EQ(OK, req2.WaitForResult());
1942 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1943
[email protected]2431756e2010-09-29 20:26:131944 ASSERT_EQ(3U, request_order.size());
1945 EXPECT_EQ(&req1, request_order[0]);
1946 EXPECT_EQ(&req2, request_order[1]);
1947 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571948}
1949
[email protected]03b7c8c2013-07-20 04:38:551950// Test GetLoadState in the case there's only one socket request.
1951TEST_F(ClientSocketPoolBaseTest, LoadStateOneRequest) {
[email protected]211d21722009-07-22 15:48:531952 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]03b7c8c2013-07-20 04:38:551953 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]5fc08e32009-07-15 17:09:571954
[email protected]2431756e2010-09-29 20:26:131955 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521956 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131957 int rv = handle.Init("a",
1958 params_,
[email protected]bb1c4662013-11-14 00:00:071959 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521960 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131961 pool_.get(),
1962 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571963 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]03b7c8c2013-07-20 04:38:551964 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571965
[email protected]03b7c8c2013-07-20 04:38:551966 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
1967 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
1968
1969 // No point in completing the connection, since ClientSocketHandles only
1970 // expect the LoadState to be checked while connecting.
1971}
1972
1973// Test GetLoadState in the case there are two socket requests.
1974TEST_F(ClientSocketPoolBaseTest, LoadStateTwoRequests) {
1975 CreatePool(2, 2);
1976 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1977
1978 ClientSocketHandle handle;
1979 TestCompletionCallback callback;
1980 int rv = handle.Init("a",
1981 params_,
[email protected]bb1c4662013-11-14 00:00:071982 DEFAULT_PRIORITY,
[email protected]03b7c8c2013-07-20 04:38:551983 callback.callback(),
1984 pool_.get(),
1985 BoundNetLog());
1986 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]5fc08e32009-07-15 17:09:571987
[email protected]2431756e2010-09-29 20:26:131988 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:521989 TestCompletionCallback callback2;
[email protected]03b7c8c2013-07-20 04:38:551990 rv = handle2.Init("a",
1991 params_,
[email protected]bb1c4662013-11-14 00:00:071992 DEFAULT_PRIORITY,
[email protected]03b7c8c2013-07-20 04:38:551993 callback2.callback(),
1994 pool_.get(),
1995 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571996 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]03b7c8c2013-07-20 04:38:551997
1998 // If the first Job is in an earlier state than the second, the state of
1999 // the second job should be used for both handles.
2000 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
2001 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2002 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
2003
2004 // If the second Job is in an earlier state than the second, the state of
2005 // the first job should be used for both handles.
2006 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2007 // One request is farther
2008 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
2009 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle2.GetLoadState());
2010
2011 // Farthest along 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_CONNECTING, handle2.GetLoadState());
2016}
2017
2018// Test GetLoadState in the case the per-group limit is reached.
2019TEST_F(ClientSocketPoolBaseTest, LoadStateGroupLimit) {
2020 CreatePool(2, 1);
2021 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2022
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());
2033
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());
2047
2048 // The first handle should remain stalled as the other socket goes through
2049 // the connect process.
2050
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());
2054
2055 client_socket_factory_.SignalJob(0);
2056 EXPECT_EQ(OK, callback2.WaitForResult());
2057 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2058
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());
2064}
2065
2066// Test GetLoadState in the case the per-pool limit is reached.
2067TEST_F(ClientSocketPoolBaseTest, LoadStatePoolLimit) {
2068 CreatePool(2, 2);
2069 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2070
2071 ClientSocketHandle handle;
2072 TestCompletionCallback callback;
2073 int rv = handle.Init("a",
2074 params_,
[email protected]bb1c4662013-11-14 00:00:072075 DEFAULT_PRIORITY,
[email protected]03b7c8c2013-07-20 04:38:552076 callback.callback(),
2077 pool_.get(),
2078 BoundNetLog());
2079 EXPECT_EQ(ERR_IO_PENDING, rv);
2080
2081 // Request for socket from another pool.
2082 ClientSocketHandle handle2;
2083 TestCompletionCallback callback2;
2084 rv = handle2.Init("b",
2085 params_,
[email protected]bb1c4662013-11-14 00:00:072086 DEFAULT_PRIORITY,
[email protected]03b7c8c2013-07-20 04:38:552087 callback2.callback(),
2088 pool_.get(),
2089 BoundNetLog());
2090 EXPECT_EQ(ERR_IO_PENDING, rv);
2091
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_,
[email protected]bb1c4662013-11-14 00:00:072098 DEFAULT_PRIORITY,
[email protected]03b7c8c2013-07-20 04:38:552099 callback2.callback(),
2100 pool_.get(),
2101 BoundNetLog());
2102 EXPECT_EQ(ERR_IO_PENDING, rv);
2103
2104 // The third handle should remain stalled as the other sockets in its group
2105 // goes through the connect process.
2106
2107 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2108 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2109
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());
2113
2114 client_socket_factory_.SignalJob(0);
2115 EXPECT_EQ(OK, callback.WaitForResult());
2116 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2117
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());
[email protected]5fc08e32009-07-15 17:09:572123}
2124
[email protected]e772db3f2010-07-12 18:11:132125TEST_F(ClientSocketPoolBaseTest, Recoverable) {
2126 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2127 connect_job_factory_->set_job_type(TestConnectJob::kMockRecoverableJob);
2128
[email protected]2431756e2010-09-29 20:26:132129 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522130 TestCompletionCallback callback;
2131 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED,
[email protected]bb1c4662013-11-14 00:00:072132 handle.Init("a", params_, DEFAULT_PRIORITY, callback.callback(),
[email protected]6ecf2b92011-12-15 01:14:522133 pool_.get(), BoundNetLog()));
[email protected]2431756e2010-09-29 20:26:132134 EXPECT_TRUE(handle.is_initialized());
2135 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:132136}
2137
2138TEST_F(ClientSocketPoolBaseTest, AsyncRecoverable) {
2139 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2140
2141 connect_job_factory_->set_job_type(
2142 TestConnectJob::kMockPendingRecoverableJob);
[email protected]2431756e2010-09-29 20:26:132143 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522144 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132145 EXPECT_EQ(ERR_IO_PENDING,
2146 handle.Init("a",
2147 params_,
[email protected]bb1c4662013-11-14 00:00:072148 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522149 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132150 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());
[email protected]e772db3f2010-07-12 18:11:132156}
2157
[email protected]e60e47a2010-07-14 03:37:182158TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
2159 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2160 connect_job_factory_->set_job_type(
2161 TestConnectJob::kMockAdditionalErrorStateJob);
2162
[email protected]2431756e2010-09-29 20:26:132163 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522164 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132165 EXPECT_EQ(ERR_CONNECTION_FAILED,
2166 handle.Init("a",
2167 params_,
[email protected]bb1c4662013-11-14 00:00:072168 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522169 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132170 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);
[email protected]e60e47a2010-07-14 03:37:182176}
2177
2178TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
2179 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2180
2181 connect_job_factory_->set_job_type(
2182 TestConnectJob::kMockPendingAdditionalErrorStateJob);
[email protected]2431756e2010-09-29 20:26:132183 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522184 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132185 EXPECT_EQ(ERR_IO_PENDING,
2186 handle.Init("a",
2187 params_,
[email protected]bb1c4662013-11-14 00:00:072188 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522189 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132190 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);
[email protected]e60e47a2010-07-14 03:37:182198}
2199
[email protected]e7b1c6d2c2012-05-05 00:54:032200// Make sure we can reuse sockets when the cleanup timer is disabled.
2201TEST_F(ClientSocketPoolBaseTest, DisableCleanupTimerReuse) {
[email protected]64770b7d2011-11-16 04:30:412202 // Disable cleanup timer.
2203 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(false);
2204
2205 CreatePoolWithIdleTimeouts(
2206 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
[email protected]e7b1c6d2c2012-05-05 00:54:032207 base::TimeDelta(), // Time out unused sockets immediately.
2208 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2209
2210 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2211
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());
2223
2224 // Use and release the socket.
2225 EXPECT_EQ(1, handle.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]034df0f32013-01-07 23:17:482226 TestLoadTimingInfoConnectedNotReused(handle);
[email protected]e7b1c6d2c2012-05-05 00:54:032227 handle.Reset();
2228
2229 // Should now have one idle socket.
2230 ASSERT_EQ(1, pool_->IdleSocketCount());
2231
2232 // Request a new socket. This should reuse the old socket and complete
2233 // synchronously.
[email protected]333bdf62012-06-08 22:57:292234 CapturingBoundNetLog log;
[email protected]e7b1c6d2c2012-05-05 00:54:032235 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());
[email protected]034df0f32013-01-07 23:17:482243 TestLoadTimingInfoConnectedReused(handle);
[email protected]e7b1c6d2c2012-05-05 00:54:032244
2245 ASSERT_TRUE(pool_->HasGroup("a"));
2246 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2247 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2248
[email protected]333bdf62012-06-08 22:57:292249 CapturingNetLog::CapturedEntryList entries;
[email protected]e7b1c6d2c2012-05-05 00:54:032250 log.GetEntries(&entries);
2251 EXPECT_TRUE(LogContainsEntryWithType(
2252 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
2253}
2254
2255// Make sure we cleanup old unused sockets when the cleanup timer is disabled.
2256TEST_F(ClientSocketPoolBaseTest, DisableCleanupTimerNoReuse) {
2257 // Disable cleanup timer.
2258 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(false);
2259
2260 CreatePoolWithIdleTimeouts(
2261 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2262 base::TimeDelta(), // Time out unused sockets immediately
2263 base::TimeDelta()); // Time out used sockets immediately
[email protected]64770b7d2011-11-16 04:30:412264
2265 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2266
2267 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2268
2269 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522270 TestCompletionCallback callback;
[email protected]64770b7d2011-11-16 04:30:412271 int rv = handle.Init("a",
2272 params_,
2273 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522274 callback.callback(),
[email protected]64770b7d2011-11-16 04:30:412275 pool_.get(),
2276 BoundNetLog());
[email protected]e7b1c6d2c2012-05-05 00:54:032277 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]64770b7d2011-11-16 04:30:412278 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2279
2280 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522281 TestCompletionCallback callback2;
[email protected]64770b7d2011-11-16 04:30:412282 rv = handle2.Init("a",
2283 params_,
2284 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522285 callback2.callback(),
[email protected]64770b7d2011-11-16 04:30:412286 pool_.get(),
2287 BoundNetLog());
[email protected]e7b1c6d2c2012-05-05 00:54:032288 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]64770b7d2011-11-16 04:30:412289 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
2290
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).
2295
2296 handle.Reset();
[email protected]e7b1c6d2c2012-05-05 00:54:032297 ASSERT_EQ(OK, callback2.WaitForResult());
[email protected]64770b7d2011-11-16 04:30:412298 // Use the socket.
[email protected]83039bb2011-12-09 18:43:552299 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]64770b7d2011-11-16 04:30:412300 handle2.Reset();
2301
[email protected]e7b1c6d2c2012-05-05 00:54:032302 // 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));
[email protected]2da659e2013-05-23 20:51:342307 base::MessageLoop::current()->RunUntilIdle();
[email protected]64770b7d2011-11-16 04:30:412308
[email protected]e7b1c6d2c2012-05-05 00:54:032309 // Both sockets should now be idle.
[email protected]64770b7d2011-11-16 04:30:412310 ASSERT_EQ(2, pool_->IdleSocketCount());
2311
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.
[email protected]333bdf62012-06-08 22:57:292314 CapturingBoundNetLog log;
[email protected]6ecf2b92011-12-15 01:14:522315 TestCompletionCallback callback3;
[email protected]64770b7d2011-11-16 04:30:412316 rv = handle.Init("a",
2317 params_,
2318 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522319 callback3.callback(),
[email protected]64770b7d2011-11-16 04:30:412320 pool_.get(),
2321 log.bound());
[email protected]e7b1c6d2c2012-05-05 00:54:032322 ASSERT_EQ(ERR_IO_PENDING, rv);
2323 ASSERT_EQ(OK, callback3.WaitForResult());
[email protected]64770b7d2011-11-16 04:30:412324 EXPECT_FALSE(handle.is_reused());
2325
[email protected]e7b1c6d2c2012-05-05 00:54:032326 // Make sure the idle socket is closed.
[email protected]64770b7d2011-11-16 04:30:412327 ASSERT_TRUE(pool_->HasGroup("a"));
2328 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2329 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2330
[email protected]333bdf62012-06-08 22:57:292331 CapturingNetLog::CapturedEntryList entries;
[email protected]64770b7d2011-11-16 04:30:412332 log.GetEntries(&entries);
2333 EXPECT_FALSE(LogContainsEntryWithType(
2334 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
2335}
2336
[email protected]4d3b05d2010-01-27 21:27:292337TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
[email protected]9bf28db2009-08-29 01:35:162338 CreatePoolWithIdleTimeouts(
2339 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2340 base::TimeDelta(), // Time out unused sockets immediately.
2341 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2342
2343 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2344
2345 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2346
[email protected]2431756e2010-09-29 20:26:132347 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522348 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132349 int rv = handle.Init("a",
2350 params_,
2351 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522352 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132353 pool_.get(),
2354 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:162355 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:132356 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
[email protected]9bf28db2009-08-29 01:35:162357
[email protected]2431756e2010-09-29 20:26:132358 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522359 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132360 rv = handle2.Init("a",
2361 params_,
2362 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522363 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132364 pool_.get(),
2365 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:162366 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:132367 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
[email protected]9bf28db2009-08-29 01:35:162368
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).
2373
[email protected]2431756e2010-09-29 20:26:132374 handle.Reset();
2375 EXPECT_EQ(OK, callback2.WaitForResult());
[email protected]0f873e82010-09-02 16:09:012376 // Use the socket.
[email protected]83039bb2011-12-09 18:43:552377 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]2431756e2010-09-29 20:26:132378 handle2.Reset();
[email protected]6b175382009-10-13 06:47:472379
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.
[email protected]26b9973962012-01-28 00:57:002384 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
[email protected]2da659e2013-05-23 20:51:342385 base::MessageLoop::current()->RunUntilIdle();
[email protected]9bf28db2009-08-29 01:35:162386
2387 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:042388
[email protected]9bf28db2009-08-29 01:35:162389 // 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.
2391
2392 pool_->CleanupTimedOutIdleSockets();
[email protected]333bdf62012-06-08 22:57:292393 CapturingBoundNetLog log;
[email protected]2431756e2010-09-29 20:26:132394 rv = handle.Init("a",
2395 params_,
2396 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522397 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132398 pool_.get(),
2399 log.bound());
[email protected]9bf28db2009-08-29 01:35:162400 EXPECT_EQ(OK, rv);
[email protected]2431756e2010-09-29 20:26:132401 EXPECT_TRUE(handle.is_reused());
[email protected]b2fcd0e2010-12-01 15:19:402402
[email protected]333bdf62012-06-08 22:57:292403 CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402404 log.GetEntries(&entries);
[email protected]fd4fe0b2010-02-08 23:02:152405 EXPECT_TRUE(LogContainsEntryWithType(
[email protected]b2fcd0e2010-12-01 15:19:402406 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]9bf28db2009-08-29 01:35:162407}
2408
[email protected]2041cf342010-02-19 03:15:592409// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:162410// because of multiple releasing disconnected sockets.
2411TEST_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.
2416
2417 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2418
2419 // Startup 4 connect jobs. Two of them will be pending.
2420
[email protected]2431756e2010-09-29 20:26:132421 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522422 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132423 int rv = handle.Init("a",
2424 params_,
2425 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522426 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132427 pool_.get(),
2428 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162429 EXPECT_EQ(OK, rv);
2430
[email protected]2431756e2010-09-29 20:26:132431 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522432 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132433 rv = handle2.Init("a",
2434 params_,
2435 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522436 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132437 pool_.get(),
2438 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162439 EXPECT_EQ(OK, rv);
2440
[email protected]2431756e2010-09-29 20:26:132441 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:522442 TestCompletionCallback callback3;
[email protected]2431756e2010-09-29 20:26:132443 rv = handle3.Init("a",
2444 params_,
2445 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522446 callback3.callback(),
[email protected]2431756e2010-09-29 20:26:132447 pool_.get(),
2448 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162449 EXPECT_EQ(ERR_IO_PENDING, rv);
2450
[email protected]2431756e2010-09-29 20:26:132451 ClientSocketHandle handle4;
[email protected]6ecf2b92011-12-15 01:14:522452 TestCompletionCallback callback4;
[email protected]2431756e2010-09-29 20:26:132453 rv = handle4.Init("a",
2454 params_,
2455 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522456 callback4.callback(),
[email protected]2431756e2010-09-29 20:26:132457 pool_.get(),
2458 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162459 EXPECT_EQ(ERR_IO_PENDING, rv);
2460
2461 // Release two disconnected sockets.
2462
[email protected]2431756e2010-09-29 20:26:132463 handle.socket()->Disconnect();
2464 handle.Reset();
2465 handle2.socket()->Disconnect();
2466 handle2.Reset();
[email protected]4f2abec2010-02-03 18:10:162467
[email protected]2431756e2010-09-29 20:26:132468 EXPECT_EQ(OK, callback3.WaitForResult());
2469 EXPECT_FALSE(handle3.is_reused());
2470 EXPECT_EQ(OK, callback4.WaitForResult());
2471 EXPECT_FALSE(handle4.is_reused());
[email protected]4f2abec2010-02-03 18:10:162472}
2473
[email protected]d7027bb2010-05-10 18:58:542474// 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.
2477TEST_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.
2482
2483 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2484
2485 // Max out the socket limit with 2 per group.
2486
[email protected]2431756e2010-09-29 20:26:132487 ClientSocketHandle handle_a[4];
[email protected]6ecf2b92011-12-15 01:14:522488 TestCompletionCallback callback_a[4];
[email protected]2431756e2010-09-29 20:26:132489 ClientSocketHandle handle_b[4];
[email protected]6ecf2b92011-12-15 01:14:522490 TestCompletionCallback callback_b[4];
[email protected]d7027bb2010-05-10 18:58:542491
2492 for (int i = 0; i < 2; ++i) {
[email protected]2431756e2010-09-29 20:26:132493 EXPECT_EQ(OK, handle_a[i].Init("a",
2494 params_,
2495 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522496 callback_a[i].callback(),
[email protected]2431756e2010-09-29 20:26:132497 pool_.get(),
2498 BoundNetLog()));
2499 EXPECT_EQ(OK, handle_b[i].Init("b",
2500 params_,
2501 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522502 callback_b[i].callback(),
[email protected]2431756e2010-09-29 20:26:132503 pool_.get(),
2504 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542505 }
[email protected]b89f7e42010-05-20 20:37:002506
[email protected]d7027bb2010-05-10 18:58:542507 // Make 4 pending requests, 2 per group.
2508
2509 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132510 EXPECT_EQ(ERR_IO_PENDING,
2511 handle_a[i].Init("a",
2512 params_,
2513 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522514 callback_a[i].callback(),
[email protected]2431756e2010-09-29 20:26:132515 pool_.get(),
2516 BoundNetLog()));
2517 EXPECT_EQ(ERR_IO_PENDING,
2518 handle_b[i].Init("b",
2519 params_,
2520 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522521 callback_b[i].callback(),
[email protected]2431756e2010-09-29 20:26:132522 pool_.get(),
2523 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542524 }
2525
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.
[email protected]2431756e2010-09-29 20:26:132531 handle_b[0].socket()->Disconnect();
2532 handle_b[0].Reset();
2533 handle_a[0].socket()->Disconnect();
2534 handle_a[0].Reset();
[email protected]d7027bb2010-05-10 18:58:542535
2536 // Used to get stuck here.
[email protected]2da659e2013-05-23 20:51:342537 base::MessageLoop::current()->RunUntilIdle();
[email protected]d7027bb2010-05-10 18:58:542538
[email protected]2431756e2010-09-29 20:26:132539 handle_b[1].socket()->Disconnect();
2540 handle_b[1].Reset();
2541 handle_a[1].socket()->Disconnect();
2542 handle_a[1].Reset();
[email protected]d7027bb2010-05-10 18:58:542543
2544 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132545 EXPECT_EQ(OK, callback_b[i].WaitForResult());
2546 EXPECT_EQ(OK, callback_a[i].WaitForResult());
[email protected]d7027bb2010-05-10 18:58:542547 }
2548}
2549
[email protected]fd4fe0b2010-02-08 23:02:152550TEST_F(ClientSocketPoolBaseTest,
2551 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2552 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2553
2554 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2555
[email protected]bb1c4662013-11-14 00:00:072556 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));
[email protected]fd4fe0b2010-02-08 23:02:152560
[email protected]2431756e2010-09-29 20:26:132561 EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
2562 EXPECT_EQ(OK, (*requests())[1]->WaitForResult());
2563 EXPECT_EQ(2u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152564
2565 // Releases one connection.
[email protected]2431756e2010-09-29 20:26:132566 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2567 EXPECT_EQ(OK, (*requests())[2]->WaitForResult());
[email protected]fd4fe0b2010-02-08 23:02:152568
[email protected]2431756e2010-09-29 20:26:132569 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2570 EXPECT_EQ(OK, (*requests())[3]->WaitForResult());
2571 EXPECT_EQ(4u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152572
2573 EXPECT_EQ(1, GetOrderOfRequest(1));
2574 EXPECT_EQ(2, GetOrderOfRequest(2));
2575 EXPECT_EQ(3, GetOrderOfRequest(3));
2576 EXPECT_EQ(4, GetOrderOfRequest(4));
2577
2578 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:132579 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
[email protected]fd4fe0b2010-02-08 23:02:152580}
2581
[email protected]6ecf2b92011-12-15 01:14:522582class TestReleasingSocketRequest : public TestCompletionCallbackBase {
[email protected]4f1e4982010-03-02 18:31:042583 public:
[email protected]2431756e2010-09-29 20:26:132584 TestReleasingSocketRequest(TestClientSocketPool* pool,
2585 int expected_result,
[email protected]e60e47a2010-07-14 03:37:182586 bool reset_releasing_handle)
2587 : pool_(pool),
2588 expected_result_(expected_result),
[email protected]6ecf2b92011-12-15 01:14:522589 reset_releasing_handle_(reset_releasing_handle),
[email protected]aa249b52013-04-30 01:04:322590 callback_(base::Bind(&TestReleasingSocketRequest::OnComplete,
2591 base::Unretained(this))) {
[email protected]6ecf2b92011-12-15 01:14:522592 }
2593
2594 virtual ~TestReleasingSocketRequest() {}
[email protected]4f1e4982010-03-02 18:31:042595
2596 ClientSocketHandle* handle() { return &handle_; }
2597
[email protected]6ecf2b92011-12-15 01:14:522598 const CompletionCallback& callback() const { return callback_; }
[email protected]4f1e4982010-03-02 18:31:042599
2600 private:
[email protected]6ecf2b92011-12-15 01:14:522601 void OnComplete(int result) {
2602 SetResult(result);
2603 if (reset_releasing_handle_)
2604 handle_.Reset();
2605
[email protected]bb1c4662013-11-14 00:00:072606 scoped_refptr<TestSocketParams> con_params(
2607 new TestSocketParams(false /* ignore_limits */));
[email protected]6ecf2b92011-12-15 01:14:522608 EXPECT_EQ(expected_result_,
[email protected]bb1c4662013-11-14 00:00:072609 handle2_.Init("a", con_params, DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522610 callback2_.callback(), pool_, BoundNetLog()));
2611 }
2612
[email protected]2431756e2010-09-29 20:26:132613 TestClientSocketPool* const pool_;
[email protected]e60e47a2010-07-14 03:37:182614 int expected_result_;
2615 bool reset_releasing_handle_;
[email protected]4f1e4982010-03-02 18:31:042616 ClientSocketHandle handle_;
2617 ClientSocketHandle handle2_;
[email protected]6ecf2b92011-12-15 01:14:522618 CompletionCallback callback_;
2619 TestCompletionCallback callback2_;
[email protected]4f1e4982010-03-02 18:31:042620};
2621
[email protected]e60e47a2010-07-14 03:37:182622
2623TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2624 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2625
[email protected]bb1c4662013-11-14 00:00:072626 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
2627 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
2628 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
[email protected]e60e47a2010-07-14 03:37:182629
[email protected]2431756e2010-09-29 20:26:132630 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]e60e47a2010-07-14 03:37:182631 client_socket_factory_.allocation_count());
2632
2633 connect_job_factory_->set_job_type(
2634 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2635 TestReleasingSocketRequest req(pool_.get(), OK, false);
[email protected]2431756e2010-09-29 20:26:132636 EXPECT_EQ(ERR_IO_PENDING,
[email protected]bb1c4662013-11-14 00:00:072637 req.handle()->Init("a", params_, DEFAULT_PRIORITY, req.callback(),
[email protected]6ecf2b92011-12-15 01:14:522638 pool_.get(), BoundNetLog()));
[email protected]e60e47a2010-07-14 03:37:182639 // The next job should complete synchronously
2640 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2641
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());
[email protected]8b498692010-07-16 17:11:432646 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182647}
2648
[email protected]b6501d3d2010-06-03 23:53:342649// 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.
2657TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2658 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2659 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2660
2661 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522662 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132663 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2664 params_,
[email protected]bb1c4662013-11-14 00:00:072665 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522666 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132667 pool_.get(),
2668 BoundNetLog()));
[email protected]b6501d3d2010-06-03 23:53:342669
[email protected]7af985a2012-12-14 22:40:422670 pool_->FlushWithError(ERR_NETWORK_CHANGED);
[email protected]b6501d3d2010-06-03 23:53:342671
2672 // We'll call back into this now.
2673 callback.WaitForResult();
2674}
2675
[email protected]a7e38572010-06-07 18:22:242676TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2677 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2678 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2679
2680 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522681 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132682 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2683 params_,
[email protected]bb1c4662013-11-14 00:00:072684 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522685 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132686 pool_.get(),
2687 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242688 EXPECT_EQ(OK, callback.WaitForResult());
2689 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2690
[email protected]7af985a2012-12-14 22:40:422691 pool_->FlushWithError(ERR_NETWORK_CHANGED);
[email protected]a7e38572010-06-07 18:22:242692
2693 handle.Reset();
[email protected]2da659e2013-05-23 20:51:342694 base::MessageLoop::current()->RunUntilIdle();
[email protected]a7e38572010-06-07 18:22:242695
[email protected]2431756e2010-09-29 20:26:132696 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2697 params_,
[email protected]bb1c4662013-11-14 00:00:072698 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522699 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132700 pool_.get(),
2701 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242702 EXPECT_EQ(OK, callback.WaitForResult());
2703 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2704}
2705
[email protected]6ecf2b92011-12-15 01:14:522706class ConnectWithinCallback : public TestCompletionCallbackBase {
[email protected]06f92462010-08-31 19:24:142707 public:
2708 ConnectWithinCallback(
2709 const std::string& group_name,
2710 const scoped_refptr<TestSocketParams>& params,
[email protected]2431756e2010-09-29 20:26:132711 TestClientSocketPool* pool)
[email protected]6ecf2b92011-12-15 01:14:522712 : group_name_(group_name),
2713 params_(params),
2714 pool_(pool),
[email protected]aa249b52013-04-30 01:04:322715 callback_(base::Bind(&ConnectWithinCallback::OnComplete,
2716 base::Unretained(this))) {
[email protected]06f92462010-08-31 19:24:142717 }
2718
[email protected]6ecf2b92011-12-15 01:14:522719 virtual ~ConnectWithinCallback() {}
[email protected]06f92462010-08-31 19:24:142720
2721 int WaitForNestedResult() {
2722 return nested_callback_.WaitForResult();
2723 }
2724
[email protected]6ecf2b92011-12-15 01:14:522725 const CompletionCallback& callback() const { return callback_; }
2726
[email protected]06f92462010-08-31 19:24:142727 private:
[email protected]6ecf2b92011-12-15 01:14:522728 void OnComplete(int result) {
2729 SetResult(result);
2730 EXPECT_EQ(ERR_IO_PENDING,
2731 handle_.Init(group_name_,
2732 params_,
[email protected]bb1c4662013-11-14 00:00:072733 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522734 nested_callback_.callback(),
2735 pool_,
2736 BoundNetLog()));
2737 }
2738
[email protected]06f92462010-08-31 19:24:142739 const std::string group_name_;
2740 const scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:132741 TestClientSocketPool* const pool_;
[email protected]06f92462010-08-31 19:24:142742 ClientSocketHandle handle_;
[email protected]6ecf2b92011-12-15 01:14:522743 CompletionCallback callback_;
2744 TestCompletionCallback nested_callback_;
2745
2746 DISALLOW_COPY_AND_ASSIGN(ConnectWithinCallback);
[email protected]06f92462010-08-31 19:24:142747};
2748
2749TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
2750 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2751
2752 // First job will be waiting until it gets aborted.
2753 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2754
2755 ClientSocketHandle handle;
[email protected]2431756e2010-09-29 20:26:132756 ConnectWithinCallback callback("a", params_, pool_.get());
2757 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2758 params_,
[email protected]bb1c4662013-11-14 00:00:072759 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522760 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132761 pool_.get(),
2762 BoundNetLog()));
[email protected]06f92462010-08-31 19:24:142763
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);
[email protected]7af985a2012-12-14 22:40:422767 pool_->FlushWithError(ERR_NETWORK_CHANGED);
2768 EXPECT_EQ(ERR_NETWORK_CHANGED, callback.WaitForResult());
[email protected]06f92462010-08-31 19:24:142769 EXPECT_EQ(OK, callback.WaitForNestedResult());
2770}
2771
[email protected]25eea382010-07-10 23:55:262772// Cancel a pending socket request while we're at max sockets,
2773// and verify that the backup socket firing doesn't cause a crash.
2774TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
2775 // Max 4 sockets globally, max 4 sockets per group.
2776 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
[email protected]06d94042010-08-25 01:45:222777 pool_->EnableConnectBackupJobs();
[email protected]25eea382010-07-10 23:55:262778
[email protected]4baaf9d2010-08-31 15:15:442779 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2780 // timer.
[email protected]25eea382010-07-10 23:55:262781 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2782 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522783 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132784 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2785 params_,
[email protected]bb1c4662013-11-14 00:00:072786 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522787 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132788 pool_.get(),
2789 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262790
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) {
[email protected]6ecf2b92011-12-15 01:14:522795 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132796 EXPECT_EQ(OK, handles[i].Init("bar",
2797 params_,
[email protected]bb1c4662013-11-14 00:00:072798 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522799 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132800 pool_.get(),
2801 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262802 }
2803
[email protected]2da659e2013-05-23 20:51:342804 base::MessageLoop::current()->RunUntilIdle();
[email protected]25eea382010-07-10 23:55:262805
2806 // Cancel the pending request.
2807 handle.Reset();
2808
2809 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]26b9973962012-01-28 00:57:002810 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2811 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]25eea382010-07-10 23:55:262812
[email protected]2da659e2013-05-23 20:51:342813 base::MessageLoop::current()->RunUntilIdle();
[email protected]25eea382010-07-10 23:55:262814 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
2815}
2816
[email protected]3f00be82010-09-27 19:50:022817TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
[email protected]4baaf9d2010-08-31 15:15:442818 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2819 pool_->EnableConnectBackupJobs();
2820
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;
[email protected]6ecf2b92011-12-15 01:14:522825 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132826 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2827 params_,
[email protected]bb1c4662013-11-14 00:00:072828 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522829 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132830 pool_.get(),
2831 BoundNetLog()));
[email protected]4baaf9d2010-08-31 15:15:442832 ASSERT_TRUE(pool_->HasGroup("bar"));
2833 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
[email protected]8159a1c2012-06-07 00:00:102834 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("bar"));
[email protected]4baaf9d2010-08-31 15:15:442835
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)
[email protected]26b9973962012-01-28 00:57:002840 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2841 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]2da659e2013-05-23 20:51:342842 base::MessageLoop::current()->RunUntilIdle();
[email protected]4baaf9d2010-08-31 15:15:442843 ASSERT_TRUE(pool_->HasGroup("bar"));
2844 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2845}
2846
[email protected]3f00be82010-09-27 19:50:022847TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
2848 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2849 pool_->EnableConnectBackupJobs();
2850
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;
[email protected]6ecf2b92011-12-15 01:14:522855 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132856 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2857 params_,
[email protected]bb1c4662013-11-14 00:00:072858 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522859 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132860 pool_.get(),
2861 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022862 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2863 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522864 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132865 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("bar",
2866 params_,
[email protected]bb1c4662013-11-14 00:00:072867 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522868 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132869 pool_.get(),
2870 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022871 ASSERT_TRUE(pool_->HasGroup("bar"));
2872 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("bar"));
2873
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)
[email protected]26b9973962012-01-28 00:57:002879 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2880 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]2da659e2013-05-23 20:51:342881 base::MessageLoop::current()->RunUntilIdle();
[email protected]3f00be82010-09-27 19:50:022882}
2883
[email protected]eb5a99382010-07-11 03:18:262884// 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.
2888TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
2889 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2890 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2891
2892 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522893 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132894 EXPECT_EQ(ERR_IO_PENDING,
2895 handle1.Init("a",
2896 params_,
[email protected]bb1c4662013-11-14 00:00:072897 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522898 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132899 pool_.get(),
2900 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262901 EXPECT_EQ(OK, callback.WaitForResult());
2902
2903 // No idle sockets, no pending jobs.
2904 EXPECT_EQ(0, pool_->IdleSocketCount());
2905 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2906
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;
[email protected]2431756e2010-09-29 20:26:132910 EXPECT_EQ(ERR_IO_PENDING,
2911 handle2.Init("a",
2912 params_,
[email protected]bb1c4662013-11-14 00:00:072913 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522914 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132915 pool_.get(),
2916 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262917 // No idle sockets, and one connecting job.
2918 EXPECT_EQ(0, pool_->IdleSocketCount());
2919 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2920
2921 // Return the first handle to the pool. This will initiate the delayed
2922 // binding.
2923 handle1.Reset();
2924
[email protected]2da659e2013-05-23 20:51:342925 base::MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262926
2927 // Still no idle sockets, still one pending connect job.
2928 EXPECT_EQ(0, pool_->IdleSocketCount());
2929 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2930
2931 // The second socket connected, even though it was a Waiting Job.
2932 EXPECT_EQ(OK, callback.WaitForResult());
2933
2934 // And we can see there is still one job waiting.
2935 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2936
2937 // Finally, signal the waiting Connect.
2938 client_socket_factory_.SignalJobs();
2939 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2940
[email protected]2da659e2013-05-23 20:51:342941 base::MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262942}
2943
2944// Test delayed socket binding when a group is at capacity and one
2945// of the group's sockets frees up.
2946TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
2947 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2948 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2949
2950 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522951 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132952 EXPECT_EQ(ERR_IO_PENDING,
2953 handle1.Init("a",
2954 params_,
[email protected]bb1c4662013-11-14 00:00:072955 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522956 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132957 pool_.get(),
2958 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262959 EXPECT_EQ(OK, callback.WaitForResult());
2960
2961 // No idle sockets, no pending jobs.
2962 EXPECT_EQ(0, pool_->IdleSocketCount());
2963 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2964
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;
[email protected]2431756e2010-09-29 20:26:132968 EXPECT_EQ(ERR_IO_PENDING,
2969 handle2.Init("a",
2970 params_,
[email protected]bb1c4662013-11-14 00:00:072971 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522972 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132973 pool_.get(),
2974 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262975 // No idle sockets, and one connecting job.
2976 EXPECT_EQ(0, pool_->IdleSocketCount());
2977 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2978
2979 // Return the first handle to the pool. This will initiate the delayed
2980 // binding.
2981 handle1.Reset();
2982
[email protected]2da659e2013-05-23 20:51:342983 base::MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262984
2985 // Still no idle sockets, still one pending connect job.
2986 EXPECT_EQ(0, pool_->IdleSocketCount());
2987 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2988
2989 // The second socket connected, even though it was a Waiting Job.
2990 EXPECT_EQ(OK, callback.WaitForResult());
2991
2992 // And we can see there is still one job waiting.
2993 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2994
2995 // Finally, signal the waiting Connect.
2996 client_socket_factory_.SignalJobs();
2997 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2998
[email protected]2da659e2013-05-23 20:51:342999 base::MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263000}
3001
3002// Test out the case where we have one socket connected, one
3003// connecting, when the first socket finishes and goes idle.
[email protected]2abfe90a2010-08-25 17:49:513004// Although the second connection is pending, the second request
[email protected]eb5a99382010-07-11 03:18:263005// should complete, by taking the first socket's idle socket.
3006TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
3007 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3008 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3009
3010 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523011 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:133012 EXPECT_EQ(ERR_IO_PENDING,
3013 handle1.Init("a",
3014 params_,
[email protected]bb1c4662013-11-14 00:00:073015 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523016 callback.callback(),
[email protected]2431756e2010-09-29 20:26:133017 pool_.get(),
3018 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:263019 EXPECT_EQ(OK, callback.WaitForResult());
3020
3021 // No idle sockets, no pending jobs.
3022 EXPECT_EQ(0, pool_->IdleSocketCount());
3023 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3024
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;
[email protected]2431756e2010-09-29 20:26:133028 EXPECT_EQ(ERR_IO_PENDING,
3029 handle2.Init("a",
3030 params_,
[email protected]bb1c4662013-11-14 00:00:073031 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523032 callback.callback(),
[email protected]2431756e2010-09-29 20:26:133033 pool_.get(),
3034 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:263035 // No idle sockets, and one connecting job.
3036 EXPECT_EQ(0, pool_->IdleSocketCount());
3037 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3038
3039 // Return the first handle to the pool. This will initiate the delayed
3040 // binding.
3041 handle1.Reset();
3042
[email protected]2da659e2013-05-23 20:51:343043 base::MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263044
3045 // Still no idle sockets, still one pending connect job.
3046 EXPECT_EQ(0, pool_->IdleSocketCount());
3047 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3048
3049 // The second socket connected, even though it was a Waiting Job.
3050 EXPECT_EQ(OK, callback.WaitForResult());
3051
3052 // And we can see there is still one job waiting.
3053 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3054
3055 // Finally, signal the waiting Connect.
3056 client_socket_factory_.SignalJobs();
3057 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3058
[email protected]2da659e2013-05-23 20:51:343059 base::MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263060}
3061
[email protected]2abfe90a2010-08-25 17:49:513062// Cover the case where on an available socket slot, we have one pending
3063// request that completes synchronously, thereby making the Group empty.
3064TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
3065 const int kUnlimitedSockets = 100;
3066 const int kOneSocketPerGroup = 1;
3067 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
3068
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);
3072
3073 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523074 TestCompletionCallback callback1;
[email protected]2431756e2010-09-29 20:26:133075 EXPECT_EQ(ERR_IO_PENDING,
3076 handle1.Init("a",
3077 params_,
[email protected]bb1c4662013-11-14 00:00:073078 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523079 callback1.callback(),
[email protected]2431756e2010-09-29 20:26:133080 pool_.get(),
3081 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:513082 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3083
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;
[email protected]6ecf2b92011-12-15 01:14:523088 TestCompletionCallback callback2;
[email protected]2abfe90a2010-08-25 17:49:513089 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
3090 // when created.
[email protected]2431756e2010-09-29 20:26:133091 EXPECT_EQ(ERR_IO_PENDING,
3092 handle2.Init("a",
3093 params_,
[email protected]bb1c4662013-11-14 00:00:073094 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523095 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:133096 pool_.get(),
3097 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:513098
3099 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3100
3101 EXPECT_EQ(ERR_CONNECTION_FAILED, callback1.WaitForResult());
3102 EXPECT_EQ(ERR_CONNECTION_FAILED, callback2.WaitForResult());
3103 EXPECT_FALSE(pool_->HasGroup("a"));
3104}
3105
[email protected]e1b54dc2010-10-06 21:27:223106TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
3107 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3108
3109 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3110
3111 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523112 TestCompletionCallback callback1;
[email protected]e1b54dc2010-10-06 21:27:223113 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3114 params_,
[email protected]bb1c4662013-11-14 00:00:073115 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523116 callback1.callback(),
[email protected]e1b54dc2010-10-06 21:27:223117 pool_.get(),
3118 BoundNetLog()));
3119
3120 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523121 TestCompletionCallback callback2;
[email protected]e1b54dc2010-10-06 21:27:223122 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3123 params_,
[email protected]bb1c4662013-11-14 00:00:073124 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523125 callback2.callback(),
[email protected]e1b54dc2010-10-06 21:27:223126 pool_.get(),
3127 BoundNetLog()));
3128 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:523129 TestCompletionCallback callback3;
[email protected]e1b54dc2010-10-06 21:27:223130 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
3131 params_,
[email protected]bb1c4662013-11-14 00:00:073132 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523133 callback3.callback(),
[email protected]e1b54dc2010-10-06 21:27:223134 pool_.get(),
3135 BoundNetLog()));
3136
3137 EXPECT_EQ(OK, callback1.WaitForResult());
3138 EXPECT_EQ(OK, callback2.WaitForResult());
3139 EXPECT_EQ(OK, callback3.WaitForResult());
3140
3141 // Use the socket.
[email protected]83039bb2011-12-09 18:43:553142 EXPECT_EQ(1, handle1.socket()->Write(NULL, 1, CompletionCallback()));
3143 EXPECT_EQ(1, handle3.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]e1b54dc2010-10-06 21:27:223144
3145 handle1.Reset();
3146 handle2.Reset();
3147 handle3.Reset();
3148
3149 EXPECT_EQ(OK, handle1.Init("a",
3150 params_,
[email protected]bb1c4662013-11-14 00:00:073151 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523152 callback1.callback(),
[email protected]e1b54dc2010-10-06 21:27:223153 pool_.get(),
3154 BoundNetLog()));
3155 EXPECT_EQ(OK, handle2.Init("a",
3156 params_,
[email protected]bb1c4662013-11-14 00:00:073157 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523158 callback2.callback(),
[email protected]e1b54dc2010-10-06 21:27:223159 pool_.get(),
3160 BoundNetLog()));
3161 EXPECT_EQ(OK, handle3.Init("a",
3162 params_,
[email protected]bb1c4662013-11-14 00:00:073163 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523164 callback3.callback(),
[email protected]e1b54dc2010-10-06 21:27:223165 pool_.get(),
3166 BoundNetLog()));
3167
3168 EXPECT_TRUE(handle1.socket()->WasEverUsed());
3169 EXPECT_TRUE(handle2.socket()->WasEverUsed());
3170 EXPECT_FALSE(handle3.socket()->WasEverUsed());
3171}
3172
[email protected]2c2bef152010-10-13 00:55:033173TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
3174 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3175 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3176
3177 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3178
3179 ASSERT_TRUE(pool_->HasGroup("a"));
3180 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103181 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033182 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3183
3184 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523185 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033186 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3187 params_,
[email protected]bb1c4662013-11-14 00:00:073188 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523189 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033190 pool_.get(),
3191 BoundNetLog()));
3192
3193 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523194 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033195 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3196 params_,
[email protected]bb1c4662013-11-14 00:00:073197 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523198 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033199 pool_.get(),
3200 BoundNetLog()));
3201
3202 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103203 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033204 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3205
3206 EXPECT_EQ(OK, callback1.WaitForResult());
3207 EXPECT_EQ(OK, callback2.WaitForResult());
3208 handle1.Reset();
3209 handle2.Reset();
3210
3211 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103212 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033213 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3214}
3215
3216TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
3217 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3218 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3219
3220 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523221 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033222 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3223 params_,
[email protected]bb1c4662013-11-14 00:00:073224 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523225 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033226 pool_.get(),
3227 BoundNetLog()));
3228
3229 ASSERT_TRUE(pool_->HasGroup("a"));
3230 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103231 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033232 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3233
3234 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3235
3236 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103237 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033238 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3239
3240 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523241 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033242 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3243 params_,
[email protected]bb1c4662013-11-14 00:00:073244 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523245 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033246 pool_.get(),
3247 BoundNetLog()));
3248
3249 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103250 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033251 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3252
3253 EXPECT_EQ(OK, callback1.WaitForResult());
3254 EXPECT_EQ(OK, callback2.WaitForResult());
3255 handle1.Reset();
3256 handle2.Reset();
3257
3258 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103259 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033260 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3261}
3262
3263TEST_F(ClientSocketPoolBaseTest,
3264 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
3265 CreatePool(4, 4);
3266 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3267
3268 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523269 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033270 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3271 params_,
[email protected]bb1c4662013-11-14 00:00:073272 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523273 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033274 pool_.get(),
3275 BoundNetLog()));
3276
3277 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523278 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033279 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3280 params_,
[email protected]bb1c4662013-11-14 00:00:073281 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523282 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033283 pool_.get(),
3284 BoundNetLog()));
3285
3286 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:523287 TestCompletionCallback callback3;
[email protected]2c2bef152010-10-13 00:55:033288 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
3289 params_,
[email protected]bb1c4662013-11-14 00:00:073290 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523291 callback3.callback(),
[email protected]2c2bef152010-10-13 00:55:033292 pool_.get(),
3293 BoundNetLog()));
3294
3295 ASSERT_TRUE(pool_->HasGroup("a"));
3296 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103297 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033298 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3299
3300 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3301
3302 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103303 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033304 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3305
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();
3312
3313 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103314 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033315 EXPECT_EQ(3, pool_->IdleSocketCountInGroup("a"));
3316}
3317
3318TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
3319 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3320 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3321
3322 ASSERT_FALSE(pool_->HasGroup("a"));
3323
3324 pool_->RequestSockets("a", &params_, kDefaultMaxSockets,
3325 BoundNetLog());
3326
3327 ASSERT_TRUE(pool_->HasGroup("a"));
3328 EXPECT_EQ(kDefaultMaxSockets, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103329 EXPECT_EQ(kDefaultMaxSockets, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033330
3331 ASSERT_FALSE(pool_->HasGroup("b"));
3332
3333 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
3334 BoundNetLog());
3335
3336 ASSERT_FALSE(pool_->HasGroup("b"));
3337}
3338
3339TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
3340 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3341 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3342
3343 ASSERT_FALSE(pool_->HasGroup("a"));
3344
3345 pool_->RequestSockets("a", &params_, kDefaultMaxSockets - 1,
3346 BoundNetLog());
3347
3348 ASSERT_TRUE(pool_->HasGroup("a"));
3349 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103350 EXPECT_EQ(kDefaultMaxSockets - 1,
3351 pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]51fdc7c2012-04-10 19:19:483352 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033353
3354 ASSERT_FALSE(pool_->HasGroup("b"));
3355
3356 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
3357 BoundNetLog());
3358
3359 ASSERT_TRUE(pool_->HasGroup("b"));
3360 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("b"));
[email protected]51fdc7c2012-04-10 19:19:483361 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033362}
3363
3364TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
3365 CreatePool(4, 4);
3366 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3367
3368 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523369 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033370 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3371 params_,
[email protected]bb1c4662013-11-14 00:00:073372 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523373 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033374 pool_.get(),
3375 BoundNetLog()));
3376 ASSERT_EQ(OK, callback1.WaitForResult());
3377 handle1.Reset();
3378
3379 ASSERT_TRUE(pool_->HasGroup("a"));
3380 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103381 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033382 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3383
3384 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3385
3386 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103387 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033388 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3389}
3390
3391TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
3392 CreatePool(4, 4);
3393 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3394
3395 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523396 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033397 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3398 params_,
[email protected]bb1c4662013-11-14 00:00:073399 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523400 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033401 pool_.get(),
3402 BoundNetLog()));
3403 ASSERT_EQ(OK, callback1.WaitForResult());
3404
3405 ASSERT_TRUE(pool_->HasGroup("a"));
3406 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103407 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033408 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3409 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3410
3411 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3412
3413 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103414 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033415 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3416 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3417}
3418
3419TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
3420 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3421 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3422
3423 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3424 BoundNetLog());
3425
3426 ASSERT_TRUE(pool_->HasGroup("a"));
3427 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103428 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033429 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("a"));
3430
3431 pool_->RequestSockets("b", &params_, kDefaultMaxSocketsPerGroup,
3432 BoundNetLog());
3433
3434 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103435 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]2c2bef152010-10-13 00:55:033436 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("b"));
3437}
3438
[email protected]3c819f522010-12-02 02:03:123439TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
3440 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3441 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3442
3443 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3444 BoundNetLog());
3445
3446 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]fd2e53e2011-01-14 20:40:523447
3448 connect_job_factory_->set_job_type(
3449 TestConnectJob::kMockAdditionalErrorStateJob);
3450 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3451 BoundNetLog());
3452
3453 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]3c819f522010-12-02 02:03:123454}
3455
[email protected]8159a1c2012-06-07 00:00:103456TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
[email protected]2c2bef152010-10-13 00:55:033457 CreatePool(4, 4);
3458 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3459
3460 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3461
3462 ASSERT_TRUE(pool_->HasGroup("a"));
3463 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103464 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033465 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3466
3467 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3468 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103469 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033470 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3471
3472 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523473 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033474 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3475 params_,
[email protected]bb1c4662013-11-14 00:00:073476 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523477 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033478 pool_.get(),
3479 BoundNetLog()));
3480 ASSERT_EQ(OK, callback1.WaitForResult());
3481
3482 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523483 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033484 int rv = handle2.Init("a",
3485 params_,
[email protected]bb1c4662013-11-14 00:00:073486 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523487 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033488 pool_.get(),
3489 BoundNetLog());
3490 if (rv != OK) {
3491 EXPECT_EQ(ERR_IO_PENDING, rv);
3492 EXPECT_EQ(OK, callback2.WaitForResult());
3493 }
3494
[email protected]8159a1c2012-06-07 00:00:103495 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"));
3499
[email protected]2c2bef152010-10-13 00:55:033500 handle1.Reset();
3501 handle2.Reset();
3502
[email protected]8159a1c2012-06-07 00:00:103503 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3504 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033505 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3506
3507 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3508 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103509 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033510 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3511}
3512
3513TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
3514 CreatePool(4, 4);
3515 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3516
3517 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3518
3519 ASSERT_TRUE(pool_->HasGroup("a"));
3520 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103521 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033522 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3523
3524 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3525 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103526 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033527 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3528
3529 pool_->RequestSockets("a", &params_, 3, BoundNetLog());
3530 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103531 EXPECT_EQ(3, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033532 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3533
3534 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3535 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103536 EXPECT_EQ(3, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033537 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3538}
3539
3540TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
3541 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3542 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3543
3544 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3545
3546 ASSERT_TRUE(pool_->HasGroup("a"));
3547 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103548 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033549 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3550
3551 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523552 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033553 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3554 params_,
[email protected]bb1c4662013-11-14 00:00:073555 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523556 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033557 pool_.get(),
3558 BoundNetLog()));
3559
3560 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103561 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033562 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3563
3564 ASSERT_EQ(OK, callback1.WaitForResult());
3565
[email protected]0dc88b32014-03-26 20:12:283566 // Make sure if a preconnected socket is not fully connected when a request
[email protected]034df0f32013-01-07 23:17:483567 // starts, it has a connect start time.
3568 TestLoadTimingInfoConnectedNotReused(handle1);
[email protected]2c2bef152010-10-13 00:55:033569 handle1.Reset();
3570
3571 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3572}
3573
[email protected]034df0f32013-01-07 23:17:483574// Checks that fully connected preconnect jobs have no connect times, and are
3575// marked as reused.
3576TEST_F(ClientSocketPoolBaseTest, ConnectedPreconnectJobsHaveNoConnectTimes) {
3577 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3578 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3579 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3580
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"));
3585
3586 ClientSocketHandle handle;
3587 TestCompletionCallback callback;
3588 EXPECT_EQ(OK, handle.Init("a",
3589 params_,
[email protected]bb1c4662013-11-14 00:00:073590 DEFAULT_PRIORITY,
[email protected]034df0f32013-01-07 23:17:483591 callback.callback(),
3592 pool_.get(),
3593 BoundNetLog()));
3594
3595 // Make sure the idle socket was used.
3596 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3597
3598 TestLoadTimingInfoConnectedReused(handle);
3599 handle.Reset();
3600 TestLoadTimingInfoNotConnected(handle);
3601}
3602
[email protected]dcbe168a2010-12-02 03:14:463603// http://crbug.com/64940 regression test.
3604TEST_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);
3609
3610 // Note that group name ordering matters here. "a" comes before "b", so
3611 // CloseOneIdleSocket() will try to close "a"'s idle socket.
3612
3613 // Set up one idle socket in "a".
3614 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523615 TestCompletionCallback callback1;
[email protected]dcbe168a2010-12-02 03:14:463616 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3617 params_,
[email protected]bb1c4662013-11-14 00:00:073618 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523619 callback1.callback(),
[email protected]dcbe168a2010-12-02 03:14:463620 pool_.get(),
3621 BoundNetLog()));
3622
3623 ASSERT_EQ(OK, callback1.WaitForResult());
3624 handle1.Reset();
3625 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3626
3627 // Set up two active sockets in "b".
3628 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523629 TestCompletionCallback callback2;
[email protected]dcbe168a2010-12-02 03:14:463630 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("b",
3631 params_,
[email protected]bb1c4662013-11-14 00:00:073632 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523633 callback1.callback(),
[email protected]dcbe168a2010-12-02 03:14:463634 pool_.get(),
3635 BoundNetLog()));
3636 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("b",
3637 params_,
[email protected]bb1c4662013-11-14 00:00:073638 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523639 callback2.callback(),
[email protected]dcbe168a2010-12-02 03:14:463640 pool_.get(),
3641 BoundNetLog()));
3642
3643 ASSERT_EQ(OK, callback1.WaitForResult());
3644 ASSERT_EQ(OK, callback2.WaitForResult());
3645 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103646 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463647 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3648
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.
3653
3654 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3655 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103656 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]dcbe168a2010-12-02 03:14:463657 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3658 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3659 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103660 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463661 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3662 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3663
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"));
3671
3672 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3673 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103674 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]dcbe168a2010-12-02 03:14:463675 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3676 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3677 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103678 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463679 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("b"));
3680 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3681}
3682
[email protected]b7b8be42011-07-12 12:46:413683TEST_F(ClientSocketPoolBaseTest, PreconnectWithoutBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073684 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3685 pool_->EnableConnectBackupJobs();
3686
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"));
[email protected]8159a1c2012-06-07 00:00:103693 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073694 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073695
[email protected]b7b8be42011-07-12 12:46:413696 // 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.
[email protected]a9fc8fc2011-05-10 02:41:073699 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2da659e2013-05-23 20:51:343700 base::MessageLoop::current()->PostDelayedTask(
3701 FROM_HERE,
3702 base::MessageLoop::QuitClosure(),
3703 base::TimeDelta::FromSeconds(1));
3704 base::MessageLoop::current()->Run();
[email protected]a9fc8fc2011-05-10 02:41:073705 EXPECT_FALSE(pool_->HasGroup("a"));
3706}
3707
[email protected]b7b8be42011-07-12 12:46:413708TEST_F(ClientSocketPoolBaseTest, PreconnectWithBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073709 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3710 pool_->EnableConnectBackupJobs();
3711
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"));
[email protected]8159a1c2012-06-07 00:00:103716 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073717 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]2da659e2013-05-23 20:51:343718 base::MessageLoop::current()->RunUntilIdle();
[email protected]a9fc8fc2011-05-10 02:41:073719
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;
[email protected]6ecf2b92011-12-15 01:14:523723 TestCompletionCallback callback;
[email protected]a9fc8fc2011-05-10 02:41:073724 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
3725 params_,
[email protected]bb1c4662013-11-14 00:00:073726 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523727 callback.callback(),
[email protected]a9fc8fc2011-05-10 02:41:073728 pool_.get(),
3729 BoundNetLog()));
[email protected]b7b8be42011-07-12 12:46:413730 // Timer has started, but the backup connect job shouldn't be created yet.
[email protected]a9fc8fc2011-05-10 02:41:073731 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103732 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073733 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3734 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3735 ASSERT_EQ(OK, callback.WaitForResult());
3736
3737 // The hung connect job should still be there, but everything else should be
3738 // complete.
3739 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103740 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073741 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3742 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3743}
3744
[email protected]0dc88b32014-03-26 20:12:283745// Tests that a preconnect that starts out with unread data can still be used.
3746// http://crbug.com/334467
3747TEST_F(ClientSocketPoolBaseTest, PreconnectWithUnreadData) {
3748 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3749 connect_job_factory_->set_job_type(TestConnectJob::kMockUnreadDataJob);
3750
3751 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3752
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"));
3757
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()));
3769
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"));
3774
3775 // Drain the pending read.
3776 EXPECT_EQ(1, handle.socket()->Read(NULL, 1, CompletionCallback()));
3777
3778 TestLoadTimingInfoConnectedReused(handle);
3779 handle.Reset();
3780
3781 // The socket should be usable now that it's idle again.
3782 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3783}
3784
[email protected]043b68c82013-08-22 23:41:523785class MockLayeredPool : public HigherLayeredPool {
[email protected]58e562f2013-04-22 17:32:203786 public:
3787 MockLayeredPool(TestClientSocketPool* pool,
3788 const std::string& group_name)
3789 : pool_(pool),
[email protected]58e562f2013-04-22 17:32:203790 group_name_(group_name),
3791 can_release_connection_(true) {
[email protected]043b68c82013-08-22 23:41:523792 pool_->AddHigherLayeredPool(this);
[email protected]58e562f2013-04-22 17:32:203793 }
3794
3795 ~MockLayeredPool() {
[email protected]043b68c82013-08-22 23:41:523796 pool_->RemoveHigherLayeredPool(this);
[email protected]58e562f2013-04-22 17:32:203797 }
3798
3799 int RequestSocket(TestClientSocketPool* pool) {
[email protected]bb1c4662013-11-14 00:00:073800 scoped_refptr<TestSocketParams> params(
3801 new TestSocketParams(false /* ignore_limits */));
3802 return handle_.Init(group_name_, params, DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203803 callback_.callback(), pool, BoundNetLog());
3804 }
3805
3806 int RequestSocketWithoutLimits(TestClientSocketPool* pool) {
[email protected]bb1c4662013-11-14 00:00:073807 scoped_refptr<TestSocketParams> params(
3808 new TestSocketParams(true /* ignore_limits */));
3809 return handle_.Init(group_name_, params, MAXIMUM_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203810 callback_.callback(), pool, BoundNetLog());
3811 }
3812
3813 bool ReleaseOneConnection() {
3814 if (!handle_.is_initialized() || !can_release_connection_) {
3815 return false;
3816 }
3817 handle_.socket()->Disconnect();
3818 handle_.Reset();
3819 return true;
3820 }
3821
3822 void set_can_release_connection(bool can_release_connection) {
3823 can_release_connection_ = can_release_connection;
3824 }
3825
3826 MOCK_METHOD0(CloseOneIdleConnection, bool());
3827
3828 private:
3829 TestClientSocketPool* const pool_;
[email protected]58e562f2013-04-22 17:32:203830 ClientSocketHandle handle_;
3831 TestCompletionCallback callback_;
3832 const std::string group_name_;
3833 bool can_release_connection_;
3834};
3835
3836TEST_F(ClientSocketPoolBaseTest, FailToCloseIdleSocketsNotHeldByLayeredPool) {
3837 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3838 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3839
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));
[email protected]043b68c82013-08-22 23:41:523844 EXPECT_FALSE(pool_->CloseOneIdleConnectionInHigherLayeredPool());
[email protected]58e562f2013-04-22 17:32:203845}
3846
3847TEST_F(ClientSocketPoolBaseTest, ForciblyCloseIdleSocketsHeldByLayeredPool) {
3848 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3849 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3850
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));
[email protected]043b68c82013-08-22 23:41:523856 EXPECT_TRUE(pool_->CloseOneIdleConnectionInHigherLayeredPool());
[email protected]58e562f2013-04-22 17:32:203857}
3858
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.
3861TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsHeldByLayeredPoolWhenNeeded) {
3862 CreatePool(1, 1);
3863 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3864
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_,
[email protected]bb1c4662013-11-14 00:00:073874 DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203875 callback.callback(),
3876 pool_.get(),
3877 BoundNetLog()));
3878 EXPECT_EQ(OK, callback.WaitForResult());
3879}
3880
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.
3886TEST_F(ClientSocketPoolBaseTest,
3887 CloseIdleSocketsHeldByLayeredPoolWhenNeededSameGroup) {
3888 CreatePool(2, 2);
3889 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3890
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_,
[email protected]bb1c4662013-11-14 00:00:073897 DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203898 callback1.callback(),
3899 pool_.get(),
3900 BoundNetLog()));
3901
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_,
[email protected]bb1c4662013-11-14 00:00:073911 DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203912 callback2.callback(),
3913 pool_.get(),
3914 BoundNetLog()));
3915 EXPECT_EQ(OK, callback2.WaitForResult());
3916}
3917
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.
3920TEST_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);
3929
3930 ClientSocketHandle handle1;
3931 TestCompletionCallback callback1;
3932 EXPECT_EQ(OK, handle1.Init("group1",
3933 params_,
[email protected]bb1c4662013-11-14 00:00:073934 DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203935 callback1.callback(),
3936 pool_.get(),
3937 BoundNetLog()));
3938
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);
3945
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_,
[email protected]bb1c4662013-11-14 00:00:073951 DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203952 callback3.callback(),
3953 pool_.get(),
3954 BoundNetLog()));
3955
3956 base::RunLoop().RunUntilIdle();
3957 EXPECT_FALSE(callback3.have_result());
3958
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_,
[email protected]bb1c4662013-11-14 00:00:073967 DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203968 callback4.callback(),
3969 pool_.get(),
3970 BoundNetLog()));
3971 EXPECT_EQ(OK, callback3.WaitForResult());
3972 EXPECT_FALSE(callback4.have_result());
3973
3974 // Closing a handle should free up another socket slot.
3975 handle1.Reset();
3976 EXPECT_EQ(OK, callback4.WaitForResult());
3977}
3978
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.
3981//
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.
3985TEST_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);
3994
3995 ClientSocketHandle handle1;
3996 TestCompletionCallback callback1;
3997 EXPECT_EQ(OK, handle1.Init("group1",
3998 params_,
[email protected]bb1c4662013-11-14 00:00:073999 DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:204000 callback1.callback(),
4001 pool_.get(),
4002 BoundNetLog()));
4003
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);
4010
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()));
4020
4021 base::RunLoop().RunUntilIdle();
4022 EXPECT_FALSE(callback3.have_result());
4023
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());
4037
4038 // Closing a handle should free up another socket slot.
4039 handle1.Reset();
4040 EXPECT_EQ(OK, callback3.WaitForResult());
4041}
4042
4043TEST_F(ClientSocketPoolBaseTest,
4044 CloseMultipleIdleSocketsHeldByLayeredPoolWhenNeeded) {
4045 CreatePool(1, 1);
4046 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4047
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_,
[email protected]bb1c4662013-11-14 00:00:074062 DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:204063 callback.callback(),
4064 pool_.get(),
4065 BoundNetLog()));
4066 EXPECT_EQ(OK, callback.WaitForResult());
4067}
4068
[email protected]b021ece62013-06-11 11:06:334069// 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.
4073TEST_F(ClientSocketPoolBaseTest, IgnoreLimits) {
[email protected]bb1c4662013-11-14 00:00:074074 scoped_refptr<TestSocketParams> params_ignore_limits(
4075 new TestSocketParams(true /* ignore_limits */));
[email protected]b021ece62013-06-11 11:06:334076 CreatePool(1, 1);
4077
4078 // Issue a request to reach the socket pool limit.
[email protected]bb1c4662013-11-14 00:00:074079 EXPECT_EQ(OK, StartRequestWithParams("a", MAXIMUM_PRIORITY, params_));
[email protected]b021ece62013-06-11 11:06:334080 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4081
4082 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4083
[email protected]bb1c4662013-11-14 00:00:074084 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithParams("a", MAXIMUM_PRIORITY,
[email protected]b021ece62013-06-11 11:06:334085 params_));
4086 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4087
[email protected]bb1c4662013-11-14 00:00:074088 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithParams("a", MAXIMUM_PRIORITY,
[email protected]b021ece62013-06-11 11:06:334089 params_ignore_limits));
4090 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4091
4092 EXPECT_EQ(OK, request(2)->WaitForResult());
4093 EXPECT_FALSE(request(1)->have_result());
4094}
4095
[email protected]c55fabd2013-11-04 23:26:564096// 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.
4099TEST_F(ClientSocketPoolBaseTest, IgnoreLimitsCancelOtherJob) {
[email protected]bb1c4662013-11-14 00:00:074100 scoped_refptr<TestSocketParams> params_ignore_limits(
4101 new TestSocketParams(true /* ignore_limits */));
[email protected]c55fabd2013-11-04 23:26:564102 CreatePool(1, 1);
4103
4104 // Issue a request to reach the socket pool limit.
[email protected]bb1c4662013-11-14 00:00:074105 EXPECT_EQ(OK, StartRequestWithParams("a", MAXIMUM_PRIORITY, params_));
[email protected]c55fabd2013-11-04 23:26:564106 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4107
4108 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4109
[email protected]bb1c4662013-11-14 00:00:074110 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithParams("a", MAXIMUM_PRIORITY,
4111 params_));
[email protected]c55fabd2013-11-04 23:26:564112 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4113
[email protected]bb1c4662013-11-14 00:00:074114 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithParams("a", MAXIMUM_PRIORITY,
[email protected]b021ece62013-06-11 11:06:334115 params_ignore_limits));
4116 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4117
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"));
4122
4123 EXPECT_EQ(OK, request(2)->WaitForResult());
4124 EXPECT_FALSE(request(1)->have_result());
4125}
4126
[email protected]f6d1d6eb2009-06-24 20:16:094127} // namespace
4128
4129} // namespace net