blob: cfa9c6e115f70f14d3b4dbd7eb00d13a8f3086f8 [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]ac790b42009-12-02 04:31:3124#include "net/base/request_priority.h"
[email protected]f6d1d6eb2009-06-24 20:16:0925#include "net/base/test_completion_callback.h"
[email protected]277d5942010-08-11 21:02:3526#include "net/http/http_response_headers.h"
eroman87c53d62015-04-02 06:51:0727#include "net/log/net_log.h"
mmenke16a7cbdd2015-04-24 23:00:5628#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4629#include "net/log/test_net_log_entry.h"
30#include "net/log/test_net_log_util.h"
[email protected]f6d1d6eb2009-06-24 20:16:0931#include "net/socket/client_socket_factory.h"
32#include "net/socket/client_socket_handle.h"
[email protected]75439d3b2009-07-23 22:11:1733#include "net/socket/socket_test_util.h"
[email protected]18ccfdb2013-08-15 00:13:4434#include "net/socket/ssl_client_socket.h"
[email protected]3268023f2011-05-05 00:08:1035#include "net/socket/stream_socket.h"
[email protected]18ccfdb2013-08-15 00:13:4436#include "net/udp/datagram_client_socket.h"
[email protected]51fdc7c2012-04-10 19:19:4837#include "testing/gmock/include/gmock/gmock.h"
[email protected]f6d1d6eb2009-06-24 20:16:0938#include "testing/gtest/include/gtest/gtest.h"
39
[email protected]51fdc7c2012-04-10 19:19:4840using ::testing::Invoke;
41using ::testing::Return;
42
[email protected]f6d1d6eb2009-06-24 20:16:0943namespace net {
44
45namespace {
46
[email protected]211d21722009-07-22 15:48:5347const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2048const int kDefaultMaxSocketsPerGroup = 2;
[email protected]0b7648c2009-07-06 20:14:0149
[email protected]034df0f32013-01-07 23:17:4850// Make sure |handle| sets load times correctly when it has been assigned a
51// reused socket.
52void TestLoadTimingInfoConnectedReused(const ClientSocketHandle& handle) {
53 LoadTimingInfo load_timing_info;
54 // Only pass true in as |is_reused|, as in general, HttpStream types should
55 // have stricter concepts of reuse than socket pools.
56 EXPECT_TRUE(handle.GetLoadTimingInfo(true, &load_timing_info));
57
58 EXPECT_EQ(true, load_timing_info.socket_reused);
59 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
60
[email protected]b258e0792013-01-12 07:11:5961 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
62 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:4863}
64
65// Make sure |handle| sets load times correctly when it has been assigned a
[email protected]b021ece62013-06-11 11:06:3366// fresh socket. Also runs TestLoadTimingInfoConnectedReused, since the owner
[email protected]034df0f32013-01-07 23:17:4867// of a connection where |is_reused| is false may consider the connection
68// reused.
69void TestLoadTimingInfoConnectedNotReused(const ClientSocketHandle& handle) {
70 EXPECT_FALSE(handle.is_reused());
71
72 LoadTimingInfo load_timing_info;
73 EXPECT_TRUE(handle.GetLoadTimingInfo(false, &load_timing_info));
74
75 EXPECT_FALSE(load_timing_info.socket_reused);
76 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
77
[email protected]b258e0792013-01-12 07:11:5978 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
79 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
80 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:4881
82 TestLoadTimingInfoConnectedReused(handle);
83}
84
85// Make sure |handle| sets load times correctly, in the case that it does not
86// currently have a socket.
87void TestLoadTimingInfoNotConnected(const ClientSocketHandle& handle) {
88 // Should only be set to true once a socket is assigned, if at all.
89 EXPECT_FALSE(handle.is_reused());
90
91 LoadTimingInfo load_timing_info;
92 EXPECT_FALSE(handle.GetLoadTimingInfo(false, &load_timing_info));
93
94 EXPECT_FALSE(load_timing_info.socket_reused);
95 EXPECT_EQ(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
96
[email protected]b258e0792013-01-12 07:11:5997 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
98 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:4899}
100
[email protected]df4b4ef2010-07-12 18:25:21101class TestSocketParams : public base::RefCounted<TestSocketParams> {
[email protected]5acdce12011-03-30 13:00:20102 public:
[email protected]bb1c4662013-11-14 00:00:07103 explicit TestSocketParams(bool ignore_limits)
104 : ignore_limits_(ignore_limits) {}
[email protected]51fdc7c2012-04-10 19:19:48105
[email protected]51fdc7c2012-04-10 19:19:48106 bool ignore_limits() { return ignore_limits_; }
107
[email protected]df4b4ef2010-07-12 18:25:21108 private:
109 friend class base::RefCounted<TestSocketParams>;
110 ~TestSocketParams() {}
[email protected]51fdc7c2012-04-10 19:19:48111
[email protected]bb1c4662013-11-14 00:00:07112 const bool ignore_limits_;
[email protected]df4b4ef2010-07-12 18:25:21113};
[email protected]7fc5b09a2010-02-27 00:07:38114typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
[email protected]d80a4322009-08-14 07:07:49115
[email protected]3268023f2011-05-05 00:08:10116class MockClientSocket : public StreamSocket {
[email protected]f6d1d6eb2009-06-24 20:16:09117 public:
[email protected]034df0f32013-01-07 23:17:48118 explicit MockClientSocket(net::NetLog* net_log)
119 : connected_(false),
[email protected]0dc88b32014-03-26 20:12:28120 has_unread_data_(false),
ttuttle859dc7a2015-04-23 19:42:29121 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)),
122 was_used_to_convey_data_(false) {}
[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.
dchengb03027d2014-10-21 12:00:20131 int Read(IOBuffer* /* buf */,
132 int len,
133 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
dchengb03027d2014-10-21 12:00:20142 int Write(IOBuffer* /* buf */,
143 int len,
144 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 }
dchengb03027d2014-10-21 12:00:20148 int SetReceiveBufferSize(int32 size) override { return OK; }
149 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.
dchengb03027d2014-10-21 12:00:20152 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
dchengb03027d2014-10-21 12:00:20157 void Disconnect() override { connected_ = false; }
158 bool IsConnected() const override { return connected_; }
159 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
dchengb03027d2014-10-21 12:00:20163 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
dchengb03027d2014-10-21 12:00:20167 int GetLocalAddress(IPEndPoint* /* address */) const override {
[email protected]e7f74da2011-04-19 23:49:35168 return ERR_UNEXPECTED;
169 }
170
dchengb03027d2014-10-21 12:00:20171 const BoundNetLog& NetLog() const override { return net_log_; }
[email protected]a2006ece2010-04-23 16:44:02172
dchengb03027d2014-10-21 12:00:20173 void SetSubresourceSpeculation() override {}
174 void SetOmniboxSpeculation() override {}
175 bool WasEverUsed() const override { return was_used_to_convey_data_; }
176 bool UsingTCPFastOpen() const override { return false; }
177 bool WasNpnNegotiated() const override { return false; }
178 NextProto GetNegotiatedProtocol() const override { return kProtoUnknown; }
179 bool GetSSLInfo(SSLInfo* ssl_info) override { return false; }
ttuttle23fdb7b2015-05-15 01:28:03180 void GetConnectionAttempts(ConnectionAttempts* out) const override {
181 out->clear();
182 }
183 void ClearConnectionAttempts() override {}
184 void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
[email protected]9b5614a2010-08-25 20:29:45185
[email protected]f6d1d6eb2009-06-24 20:16:09186 private:
187 bool connected_;
[email protected]0dc88b32014-03-26 20:12:28188 bool has_unread_data_;
[email protected]a2006ece2010-04-23 16:44:02189 BoundNetLog net_log_;
[email protected]0f873e82010-09-02 16:09:01190 bool was_used_to_convey_data_;
[email protected]f6d1d6eb2009-06-24 20:16:09191
[email protected]ab838892009-06-30 18:49:05192 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:09193};
194
[email protected]5fc08e32009-07-15 17:09:57195class TestConnectJob;
196
[email protected]f6d1d6eb2009-06-24 20:16:09197class MockClientSocketFactory : public ClientSocketFactory {
198 public:
[email protected]ab838892009-06-30 18:49:05199 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:09200
dchengb03027d2014-10-21 12:00:20201 scoped_ptr<DatagramClientSocket> CreateDatagramClientSocket(
[email protected]5370c012011-06-29 03:47:04202 DatagramSocket::BindType bind_type,
203 const RandIntCallback& rand_int_cb,
[email protected]98b0e582011-06-22 14:31:41204 NetLog* net_log,
mostynbba063d6032014-10-09 11:01:13205 const NetLog::Source& source) override {
[email protected]98b0e582011-06-22 14:31:41206 NOTREACHED();
[email protected]18ccfdb2013-08-15 00:13:44207 return scoped_ptr<DatagramClientSocket>();
[email protected]98b0e582011-06-22 14:31:41208 }
209
dchengb03027d2014-10-21 12:00:20210 scoped_ptr<StreamSocket> CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07211 const AddressList& addresses,
212 NetLog* /* net_log */,
mostynbba063d6032014-10-09 11:01:13213 const NetLog::Source& /*source*/) override {
[email protected]f6d1d6eb2009-06-24 20:16:09214 allocation_count_++;
[email protected]18ccfdb2013-08-15 00:13:44215 return scoped_ptr<StreamSocket>();
[email protected]f6d1d6eb2009-06-24 20:16:09216 }
217
dchengb03027d2014-10-21 12:00:20218 scoped_ptr<SSLClientSocket> CreateSSLClientSocket(
[email protected]18ccfdb2013-08-15 00:13:44219 scoped_ptr<ClientSocketHandle> transport_socket,
[email protected]4f4de7e62010-11-12 19:55:27220 const HostPortPair& host_and_port,
[email protected]7ab5bbd12010-10-19 13:33:21221 const SSLConfig& ssl_config,
mostynbba063d6032014-10-09 11:01:13222 const SSLClientSocketContext& context) override {
[email protected]f6d1d6eb2009-06-24 20:16:09223 NOTIMPLEMENTED();
[email protected]18ccfdb2013-08-15 00:13:44224 return scoped_ptr<SSLClientSocket>();
[email protected]f6d1d6eb2009-06-24 20:16:09225 }
226
dchengb03027d2014-10-21 12:00:20227 void ClearSSLSessionCache() override { NOTIMPLEMENTED(); }
[email protected]25f47352011-02-25 16:31:59228
[email protected]5fc08e32009-07-15 17:09:57229 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
[email protected]03b7c8c2013-07-20 04:38:55230
[email protected]5fc08e32009-07-15 17:09:57231 void SignalJobs();
232
[email protected]03b7c8c2013-07-20 04:38:55233 void SignalJob(size_t job);
234
235 void SetJobLoadState(size_t job, LoadState load_state);
236
[email protected]f6d1d6eb2009-06-24 20:16:09237 int allocation_count() const { return allocation_count_; }
238
[email protected]f6d1d6eb2009-06-24 20:16:09239 private:
240 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:57241 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09242};
243
[email protected]ab838892009-06-30 18:49:05244class TestConnectJob : public ConnectJob {
245 public:
246 enum JobType {
247 kMockJob,
248 kMockFailingJob,
249 kMockPendingJob,
250 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57251 kMockWaitingJob,
[email protected]e772db3f2010-07-12 18:11:13252 kMockRecoverableJob,
253 kMockPendingRecoverableJob,
[email protected]e60e47a2010-07-14 03:37:18254 kMockAdditionalErrorStateJob,
255 kMockPendingAdditionalErrorStateJob,
[email protected]0dc88b32014-03-26 20:12:28256 kMockUnreadDataJob,
[email protected]ab838892009-06-30 18:49:05257 };
258
[email protected]994d4932010-07-12 17:55:13259 // The kMockPendingJob uses a slight delay before allowing the connect
260 // to complete.
261 static const int kPendingConnectDelay = 2;
262
[email protected]ab838892009-06-30 18:49:05263 TestConnectJob(JobType job_type,
264 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49265 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34266 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05267 ConnectJob::Delegate* delegate,
[email protected]fd7b7c92009-08-20 19:38:30268 MockClientSocketFactory* client_socket_factory,
[email protected]06650c52010-06-03 00:49:17269 NetLog* net_log)
[email protected]3f6007ab2013-08-22 19:45:39270 : ConnectJob(group_name, timeout_duration, request.priority(), delegate,
[email protected]06650c52010-06-03 00:49:17271 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
[email protected]2ab05b52009-07-01 23:57:58272 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05273 client_socket_factory_(client_socket_factory),
[email protected]e60e47a2010-07-14 03:37:18274 load_state_(LOAD_STATE_IDLE),
[email protected]d5492c52013-11-10 20:44:39275 store_additional_error_state_(false),
276 weak_factory_(this) {
277 }
[email protected]ab838892009-06-30 18:49:05278
[email protected]974ebd62009-08-03 23:14:34279 void Signal() {
[email protected]e772db3f2010-07-12 18:11:13280 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
[email protected]974ebd62009-08-03 23:14:34281 }
282
[email protected]03b7c8c2013-07-20 04:38:55283 void set_load_state(LoadState load_state) { load_state_ = load_state; }
284
285 // From ConnectJob:
286
dchengb03027d2014-10-21 12:00:20287 LoadState GetLoadState() const override { return load_state_; }
[email protected]46451352009-09-01 14:54:21288
dchengb03027d2014-10-21 12:00:20289 void GetAdditionalErrorState(ClientSocketHandle* handle) override {
[email protected]e60e47a2010-07-14 03:37:18290 if (store_additional_error_state_) {
291 // Set all of the additional error state fields in some way.
292 handle->set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43293 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:45294 info.headers = new HttpResponseHeaders(std::string());
[email protected]8b498692010-07-16 17:11:43295 handle->set_ssl_error_response_info(info);
[email protected]e60e47a2010-07-14 03:37:18296 }
297 }
298
[email protected]974ebd62009-08-03 23:14:34299 private:
[email protected]03b7c8c2013-07-20 04:38:55300 // From ConnectJob:
[email protected]ab838892009-06-30 18:49:05301
dchengb03027d2014-10-21 12:00:20302 int ConnectInternal() override {
[email protected]ab838892009-06-30 18:49:05303 AddressList ignored;
ttuttle859dc7a2015-04-23 19:42:29304 client_socket_factory_->CreateTransportClientSocket(ignored, NULL,
305 NetLog::Source());
[email protected]18ccfdb2013-08-15 00:13:44306 SetSocket(
307 scoped_ptr<StreamSocket>(new MockClientSocket(net_log().net_log())));
[email protected]ab838892009-06-30 18:49:05308 switch (job_type_) {
309 case kMockJob:
[email protected]e772db3f2010-07-12 18:11:13310 return DoConnect(true /* successful */, false /* sync */,
311 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05312 case kMockFailingJob:
[email protected]e772db3f2010-07-12 18:11:13313 return DoConnect(false /* error */, false /* sync */,
314 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05315 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57316 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47317
318 // Depending on execution timings, posting a delayed task can result
319 // in the task getting executed the at the earliest possible
320 // opportunity or only after returning once from the message loop and
321 // then a second call into the message loop. In order to make behavior
322 // more deterministic, we change the default delay to 2ms. This should
323 // always require us to wait for the second call into the message loop.
324 //
325 // N.B. The correct fix for this and similar timing problems is to
326 // abstract time for the purpose of unittests. Unfortunately, we have
327 // a lot of third-party components that directly call the various
328 // time functions, so this change would be rather invasive.
[email protected]2da659e2013-05-23 20:51:34329 base::MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05330 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13331 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
332 weak_factory_.GetWeakPtr(),
333 true /* successful */,
334 true /* async */,
335 false /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53336 base::TimeDelta::FromMilliseconds(kPendingConnectDelay));
[email protected]ab838892009-06-30 18:49:05337 return ERR_IO_PENDING;
338 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57339 set_load_state(LOAD_STATE_CONNECTING);
[email protected]2da659e2013-05-23 20:51:34340 base::MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05341 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13342 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
343 weak_factory_.GetWeakPtr(),
344 false /* error */,
345 true /* async */,
346 false /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53347 base::TimeDelta::FromMilliseconds(2));
[email protected]ab838892009-06-30 18:49:05348 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57349 case kMockWaitingJob:
[email protected]03b7c8c2013-07-20 04:38:55350 set_load_state(LOAD_STATE_CONNECTING);
[email protected]5fc08e32009-07-15 17:09:57351 client_socket_factory_->WaitForSignal(this);
352 waiting_success_ = true;
353 return ERR_IO_PENDING;
[email protected]e772db3f2010-07-12 18:11:13354 case kMockRecoverableJob:
355 return DoConnect(false /* error */, false /* sync */,
356 true /* recoverable */);
357 case kMockPendingRecoverableJob:
358 set_load_state(LOAD_STATE_CONNECTING);
[email protected]2da659e2013-05-23 20:51:34359 base::MessageLoop::current()->PostDelayedTask(
[email protected]e772db3f2010-07-12 18:11:13360 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13361 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
362 weak_factory_.GetWeakPtr(),
363 false /* error */,
364 true /* async */,
365 true /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53366 base::TimeDelta::FromMilliseconds(2));
[email protected]e772db3f2010-07-12 18:11:13367 return ERR_IO_PENDING;
[email protected]e60e47a2010-07-14 03:37:18368 case kMockAdditionalErrorStateJob:
369 store_additional_error_state_ = true;
370 return DoConnect(false /* error */, false /* sync */,
371 false /* recoverable */);
372 case kMockPendingAdditionalErrorStateJob:
373 set_load_state(LOAD_STATE_CONNECTING);
374 store_additional_error_state_ = true;
[email protected]2da659e2013-05-23 20:51:34375 base::MessageLoop::current()->PostDelayedTask(
[email protected]e60e47a2010-07-14 03:37:18376 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13377 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
378 weak_factory_.GetWeakPtr(),
379 false /* error */,
380 true /* async */,
381 false /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53382 base::TimeDelta::FromMilliseconds(2));
[email protected]e60e47a2010-07-14 03:37:18383 return ERR_IO_PENDING;
[email protected]0dc88b32014-03-26 20:12:28384 case kMockUnreadDataJob: {
385 int ret = DoConnect(true /* successful */, false /* sync */,
386 false /* recoverable */);
387 static_cast<MockClientSocket*>(socket())->set_has_unread_data(true);
388 return ret;
389 }
[email protected]ab838892009-06-30 18:49:05390 default:
391 NOTREACHED();
[email protected]18ccfdb2013-08-15 00:13:44392 SetSocket(scoped_ptr<StreamSocket>());
[email protected]ab838892009-06-30 18:49:05393 return ERR_FAILED;
394 }
395 }
396
[email protected]e772db3f2010-07-12 18:11:13397 int DoConnect(bool succeed, bool was_async, bool recoverable) {
398 int result = OK;
[email protected]ab838892009-06-30 18:49:05399 if (succeed) {
[email protected]83039bb2011-12-09 18:43:55400 socket()->Connect(CompletionCallback());
[email protected]e772db3f2010-07-12 18:11:13401 } else if (recoverable) {
402 result = ERR_PROXY_AUTH_REQUESTED;
[email protected]6e713f02009-08-06 02:56:40403 } else {
[email protected]e772db3f2010-07-12 18:11:13404 result = ERR_CONNECTION_FAILED;
[email protected]18ccfdb2013-08-15 00:13:44405 SetSocket(scoped_ptr<StreamSocket>());
[email protected]ab838892009-06-30 18:49:05406 }
[email protected]2ab05b52009-07-01 23:57:58407
408 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30409 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05410 return result;
411 }
412
[email protected]5fc08e32009-07-15 17:09:57413 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05414 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57415 MockClientSocketFactory* const client_socket_factory_;
[email protected]46451352009-09-01 14:54:21416 LoadState load_state_;
[email protected]e60e47a2010-07-14 03:37:18417 bool store_additional_error_state_;
[email protected]ab838892009-06-30 18:49:05418
[email protected]d5492c52013-11-10 20:44:39419 base::WeakPtrFactory<TestConnectJob> weak_factory_;
420
[email protected]ab838892009-06-30 18:49:05421 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
422};
423
[email protected]d80a4322009-08-14 07:07:49424class TestConnectJobFactory
425 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05426 public:
[email protected]034df0f32013-01-07 23:17:48427 TestConnectJobFactory(MockClientSocketFactory* client_socket_factory,
428 NetLog* net_log)
[email protected]ab838892009-06-30 18:49:05429 : job_type_(TestConnectJob::kMockJob),
[email protected]51fdc7c2012-04-10 19:19:48430 job_types_(NULL),
[email protected]034df0f32013-01-07 23:17:48431 client_socket_factory_(client_socket_factory),
432 net_log_(net_log) {
[email protected]b021ece62013-06-11 11:06:33433 }
[email protected]ab838892009-06-30 18:49:05434
dchengb03027d2014-10-21 12:00:20435 ~TestConnectJobFactory() override {}
[email protected]ab838892009-06-30 18:49:05436
437 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
438
[email protected]51fdc7c2012-04-10 19:19:48439 void set_job_types(std::list<TestConnectJob::JobType>* job_types) {
440 job_types_ = job_types;
441 CHECK(!job_types_->empty());
442 }
443
[email protected]974ebd62009-08-03 23:14:34444 void set_timeout_duration(base::TimeDelta timeout_duration) {
445 timeout_duration_ = timeout_duration;
446 }
447
[email protected]3f55aa12011-12-07 02:03:33448 // ConnectJobFactory implementation.
[email protected]83039bb2011-12-09 18:43:55449
dchengb03027d2014-10-21 12:00:20450 scoped_ptr<ConnectJob> NewConnectJob(
[email protected]ab838892009-06-30 18:49:05451 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49452 const TestClientSocketPoolBase::Request& request,
mostynbba063d6032014-10-09 11:01:13453 ConnectJob::Delegate* delegate) const override {
[email protected]51fdc7c2012-04-10 19:19:48454 EXPECT_TRUE(!job_types_ || !job_types_->empty());
455 TestConnectJob::JobType job_type = job_type_;
456 if (job_types_ && !job_types_->empty()) {
457 job_type = job_types_->front();
458 job_types_->pop_front();
459 }
[email protected]18ccfdb2013-08-15 00:13:44460 return scoped_ptr<ConnectJob>(new TestConnectJob(job_type,
461 group_name,
462 request,
463 timeout_duration_,
464 delegate,
465 client_socket_factory_,
466 net_log_));
[email protected]ab838892009-06-30 18:49:05467 }
468
dchengb03027d2014-10-21 12:00:20469 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26470 return timeout_duration_;
471 }
472
[email protected]ab838892009-06-30 18:49:05473 private:
474 TestConnectJob::JobType job_type_;
[email protected]51fdc7c2012-04-10 19:19:48475 std::list<TestConnectJob::JobType>* job_types_;
[email protected]974ebd62009-08-03 23:14:34476 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57477 MockClientSocketFactory* const client_socket_factory_;
[email protected]034df0f32013-01-07 23:17:48478 NetLog* net_log_;
[email protected]ab838892009-06-30 18:49:05479
480 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
481};
482
483class TestClientSocketPool : public ClientSocketPool {
484 public:
[email protected]12322e7e2013-08-15 17:49:26485 typedef TestSocketParams SocketParams;
486
[email protected]ab838892009-06-30 18:49:05487 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53488 int max_sockets,
[email protected]ab838892009-06-30 18:49:05489 int max_sockets_per_group,
[email protected]9bf28db2009-08-29 01:35:16490 base::TimeDelta unused_idle_socket_timeout,
491 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49492 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
rkaplowd90695c2015-03-25 22:12:41493 : base_(NULL,
494 max_sockets,
495 max_sockets_per_group,
496 unused_idle_socket_timeout,
497 used_idle_socket_timeout,
[email protected]66761b952010-06-25 21:30:38498 connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05499
dchengb03027d2014-10-21 12:00:20500 ~TestClientSocketPool() override {}
[email protected]2431756e2010-09-29 20:26:13501
dchengb03027d2014-10-21 12:00:20502 int RequestSocket(const std::string& group_name,
503 const void* params,
ttuttle859dc7a2015-04-23 19:42:29504 RequestPriority priority,
dchengb03027d2014-10-21 12:00:20505 ClientSocketHandle* handle,
506 const CompletionCallback& callback,
507 const BoundNetLog& net_log) override {
[email protected]df4b4ef2010-07-12 18:25:21508 const scoped_refptr<TestSocketParams>* casted_socket_params =
509 static_cast<const scoped_refptr<TestSocketParams>*>(params);
510 return base_.RequestSocket(group_name, *casted_socket_params, priority,
511 handle, callback, net_log);
[email protected]ab838892009-06-30 18:49:05512 }
513
dchengb03027d2014-10-21 12:00:20514 void RequestSockets(const std::string& group_name,
515 const void* params,
516 int num_sockets,
517 const BoundNetLog& net_log) override {
[email protected]2c2bef152010-10-13 00:55:03518 const scoped_refptr<TestSocketParams>* casted_params =
519 static_cast<const scoped_refptr<TestSocketParams>*>(params);
520
521 base_.RequestSockets(group_name, *casted_params, num_sockets, net_log);
522 }
523
dchengb03027d2014-10-21 12:00:20524 void CancelRequest(const std::string& group_name,
525 ClientSocketHandle* handle) override {
[email protected]d80a4322009-08-14 07:07:49526 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05527 }
528
dchengb03027d2014-10-21 12:00:20529 void ReleaseSocket(const std::string& group_name,
530 scoped_ptr<StreamSocket> socket,
531 int id) override {
[email protected]18ccfdb2013-08-15 00:13:44532 base_.ReleaseSocket(group_name, socket.Pass(), id);
[email protected]a7e38572010-06-07 18:22:24533 }
534
dchengb03027d2014-10-21 12:00:20535 void FlushWithError(int error) override { base_.FlushWithError(error); }
[email protected]ab838892009-06-30 18:49:05536
dchengb03027d2014-10-21 12:00:20537 bool IsStalled() const override { return base_.IsStalled(); }
[email protected]51fdc7c2012-04-10 19:19:48538
dchengb03027d2014-10-21 12:00:20539 void CloseIdleSockets() override { base_.CloseIdleSockets(); }
[email protected]ab838892009-06-30 18:49:05540
dchengb03027d2014-10-21 12:00:20541 int IdleSocketCount() const override { return base_.idle_socket_count(); }
[email protected]ab838892009-06-30 18:49:05542
dchengb03027d2014-10-21 12:00:20543 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]d80a4322009-08-14 07:07:49544 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05545 }
546
dchengb03027d2014-10-21 12:00:20547 LoadState GetLoadState(const std::string& group_name,
548 const ClientSocketHandle* handle) const override {
[email protected]d80a4322009-08-14 07:07:49549 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05550 }
551
dchengb03027d2014-10-21 12:00:20552 void AddHigherLayeredPool(HigherLayeredPool* higher_pool) override {
[email protected]043b68c82013-08-22 23:41:52553 base_.AddHigherLayeredPool(higher_pool);
[email protected]51fdc7c2012-04-10 19:19:48554 }
555
dchengb03027d2014-10-21 12:00:20556 void RemoveHigherLayeredPool(HigherLayeredPool* higher_pool) override {
[email protected]043b68c82013-08-22 23:41:52557 base_.RemoveHigherLayeredPool(higher_pool);
[email protected]51fdc7c2012-04-10 19:19:48558 }
559
dchengb03027d2014-10-21 12:00:20560 base::DictionaryValue* GetInfoAsValue(
[email protected]d4dfdab2011-12-07 16:56:59561 const std::string& name,
562 const std::string& type,
mostynbba063d6032014-10-09 11:01:13563 bool include_nested_pools) const override {
[email protected]59d7a5a2010-08-30 16:44:27564 return base_.GetInfoAsValue(name, type);
565 }
566
dchengb03027d2014-10-21 12:00:20567 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26568 return base_.ConnectionTimeout();
569 }
570
[email protected]d80a4322009-08-14 07:07:49571 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20572
[email protected]8159a1c2012-06-07 00:00:10573 int NumUnassignedConnectJobsInGroup(const std::string& group_name) const {
574 return base_.NumUnassignedConnectJobsInGroup(group_name);
575 }
576
[email protected]974ebd62009-08-03 23:14:34577 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49578 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34579 }
580
[email protected]2c2bef152010-10-13 00:55:03581 int NumActiveSocketsInGroup(const std::string& group_name) const {
582 return base_.NumActiveSocketsInGroup(group_name);
583 }
584
[email protected]2abfe90a2010-08-25 17:49:51585 bool HasGroup(const std::string& group_name) const {
586 return base_.HasGroup(group_name);
587 }
588
[email protected]9bf28db2009-08-29 01:35:16589 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
590
[email protected]06d94042010-08-25 01:45:22591 void EnableConnectBackupJobs() { base_.EnableConnectBackupJobs(); }
[email protected]43a21b82010-06-10 21:30:54592
[email protected]043b68c82013-08-22 23:41:52593 bool CloseOneIdleConnectionInHigherLayeredPool() {
594 return base_.CloseOneIdleConnectionInHigherLayeredPool();
[email protected]51fdc7c2012-04-10 19:19:48595 }
596
[email protected]ab838892009-06-30 18:49:05597 private:
[email protected]d80a4322009-08-14 07:07:49598 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05599
600 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
601};
602
[email protected]a937a06d2009-08-19 21:19:24603} // namespace
604
[email protected]a937a06d2009-08-19 21:19:24605namespace {
606
[email protected]5fc08e32009-07-15 17:09:57607void MockClientSocketFactory::SignalJobs() {
608 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
609 it != waiting_jobs_.end(); ++it) {
610 (*it)->Signal();
611 }
612 waiting_jobs_.clear();
613}
614
[email protected]03b7c8c2013-07-20 04:38:55615void MockClientSocketFactory::SignalJob(size_t job) {
616 ASSERT_LT(job, waiting_jobs_.size());
617 waiting_jobs_[job]->Signal();
618 waiting_jobs_.erase(waiting_jobs_.begin() + job);
619}
620
621void MockClientSocketFactory::SetJobLoadState(size_t job,
622 LoadState load_state) {
623 ASSERT_LT(job, waiting_jobs_.size());
624 waiting_jobs_[job]->set_load_state(load_state);
625}
626
[email protected]974ebd62009-08-03 23:14:34627class TestConnectJobDelegate : public ConnectJob::Delegate {
628 public:
629 TestConnectJobDelegate()
630 : have_result_(false), waiting_for_result_(false), result_(OK) {}
dchengb03027d2014-10-21 12:00:20631 ~TestConnectJobDelegate() override {}
[email protected]974ebd62009-08-03 23:14:34632
dchengb03027d2014-10-21 12:00:20633 void OnConnectJobComplete(int result, ConnectJob* job) override {
[email protected]974ebd62009-08-03 23:14:34634 result_ = result;
[email protected]18ccfdb2013-08-15 00:13:44635 scoped_ptr<ConnectJob> owned_job(job);
636 scoped_ptr<StreamSocket> socket = owned_job->PassSocket();
[email protected]9b6fee12009-09-29 18:13:07637 // socket.get() should be NULL iff result != OK
[email protected]18ccfdb2013-08-15 00:13:44638 EXPECT_EQ(socket == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34639 have_result_ = true;
640 if (waiting_for_result_)
[email protected]2da659e2013-05-23 20:51:34641 base::MessageLoop::current()->Quit();
[email protected]974ebd62009-08-03 23:14:34642 }
643
644 int WaitForResult() {
645 DCHECK(!waiting_for_result_);
646 while (!have_result_) {
647 waiting_for_result_ = true;
[email protected]2da659e2013-05-23 20:51:34648 base::MessageLoop::current()->Run();
[email protected]974ebd62009-08-03 23:14:34649 waiting_for_result_ = false;
650 }
651 have_result_ = false; // auto-reset for next callback
652 return result_;
653 }
654
655 private:
656 bool have_result_;
657 bool waiting_for_result_;
658 int result_;
659};
660
[email protected]2431756e2010-09-29 20:26:13661class ClientSocketPoolBaseTest : public testing::Test {
[email protected]f6d1d6eb2009-06-24 20:16:09662 protected:
[email protected]b89f7e42010-05-20 20:37:00663 ClientSocketPoolBaseTest()
rkaplowd90695c2015-03-25 22:12:41664 : params_(new TestSocketParams(false /* ignore_limits */)) {
[email protected]636b8252011-04-08 19:56:54665 connect_backup_jobs_enabled_ =
666 internal::ClientSocketPoolBaseHelper::connect_backup_jobs_enabled();
667 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(true);
[email protected]64770b7d2011-11-16 04:30:41668 cleanup_timer_enabled_ =
669 internal::ClientSocketPoolBaseHelper::cleanup_timer_enabled();
[email protected]636b8252011-04-08 19:56:54670 }
[email protected]2431756e2010-09-29 20:26:13671
dcheng67be2b1f2014-10-27 21:47:29672 ~ClientSocketPoolBaseTest() override {
[email protected]636b8252011-04-08 19:56:54673 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
674 connect_backup_jobs_enabled_);
[email protected]64770b7d2011-11-16 04:30:41675 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(
676 cleanup_timer_enabled_);
[email protected]636b8252011-04-08 19:56:54677 }
[email protected]c9d6a1d2009-07-14 16:15:20678
[email protected]211d21722009-07-22 15:48:53679 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16680 CreatePoolWithIdleTimeouts(
681 max_sockets,
682 max_sockets_per_group,
[email protected]82b8c962011-10-12 09:17:30683 ClientSocketPool::unused_idle_socket_timeout(),
684 ClientSocketPool::used_idle_socket_timeout());
[email protected]9bf28db2009-08-29 01:35:16685 }
686
687 void CreatePoolWithIdleTimeouts(
688 int max_sockets, int max_sockets_per_group,
689 base::TimeDelta unused_idle_socket_timeout,
690 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20691 DCHECK(!pool_.get());
[email protected]034df0f32013-01-07 23:17:48692 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_,
693 &net_log_);
[email protected]2431756e2010-09-29 20:26:13694 pool_.reset(new TestClientSocketPool(max_sockets,
695 max_sockets_per_group,
[email protected]2431756e2010-09-29 20:26:13696 unused_idle_socket_timeout,
697 used_idle_socket_timeout,
698 connect_job_factory_));
[email protected]c9d6a1d2009-07-14 16:15:20699 }
[email protected]f6d1d6eb2009-06-24 20:16:09700
[email protected]b021ece62013-06-11 11:06:33701 int StartRequestWithParams(
702 const std::string& group_name,
703 RequestPriority priority,
704 const scoped_refptr<TestSocketParams>& params) {
[email protected]12322e7e2013-08-15 17:49:26705 return test_base_.StartRequestUsingPool(
706 pool_.get(), group_name, priority, params);
[email protected]b021ece62013-06-11 11:06:33707 }
708
709 int StartRequest(const std::string& group_name, RequestPriority priority) {
710 return StartRequestWithParams(group_name, priority, params_);
[email protected]f6d1d6eb2009-06-24 20:16:09711 }
712
[email protected]2431756e2010-09-29 20:26:13713 int GetOrderOfRequest(size_t index) const {
714 return test_base_.GetOrderOfRequest(index);
[email protected]f6d1d6eb2009-06-24 20:16:09715 }
716
[email protected]2431756e2010-09-29 20:26:13717 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
718 return test_base_.ReleaseOneConnection(keep_alive);
719 }
720
721 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
722 test_base_.ReleaseAllConnections(keep_alive);
723 }
724
725 TestSocketRequest* request(int i) { return test_base_.request(i); }
726 size_t requests_size() const { return test_base_.requests_size(); }
727 ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); }
728 size_t completion_count() const { return test_base_.completion_count(); }
729
vishal.b62985ca92015-04-17 08:45:51730 TestNetLog net_log_;
[email protected]636b8252011-04-08 19:56:54731 bool connect_backup_jobs_enabled_;
[email protected]64770b7d2011-11-16 04:30:41732 bool cleanup_timer_enabled_;
[email protected]f6d1d6eb2009-06-24 20:16:09733 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04734 TestConnectJobFactory* connect_job_factory_;
[email protected]df4b4ef2010-07-12 18:25:21735 scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:13736 scoped_ptr<TestClientSocketPool> pool_;
737 ClientSocketPoolTest test_base_;
[email protected]f6d1d6eb2009-06-24 20:16:09738};
739
[email protected]974ebd62009-08-03 23:14:34740// Even though a timeout is specified, it doesn't time out on a synchronous
741// completion.
742TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
743 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06744 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49745 TestClientSocketPoolBase::Request request(
[email protected]bb1c4662013-11-14 00:00:07746 &ignored, CompletionCallback(), DEFAULT_PRIORITY,
[email protected]2c2bef152010-10-13 00:55:03747 internal::ClientSocketPoolBaseHelper::NORMAL,
[email protected]5acdce12011-03-30 13:00:20748 false, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34749 scoped_ptr<TestConnectJob> job(
750 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:12751 "a",
[email protected]974ebd62009-08-03 23:14:34752 request,
753 base::TimeDelta::FromMicroseconds(1),
754 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30755 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17756 NULL));
[email protected]974ebd62009-08-03 23:14:34757 EXPECT_EQ(OK, job->Connect());
758}
759
760TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
761 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06762 ClientSocketHandle ignored;
vishal.b62985ca92015-04-17 08:45:51763 TestNetLog log;
[email protected]9e743cd2010-03-16 07:03:53764
[email protected]d80a4322009-08-14 07:07:49765 TestClientSocketPoolBase::Request request(
[email protected]bb1c4662013-11-14 00:00:07766 &ignored, CompletionCallback(), DEFAULT_PRIORITY,
[email protected]2c2bef152010-10-13 00:55:03767 internal::ClientSocketPoolBaseHelper::NORMAL,
[email protected]5acdce12011-03-30 13:00:20768 false, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34769 // Deleted by TestConnectJobDelegate.
770 TestConnectJob* job =
771 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12772 "a",
[email protected]974ebd62009-08-03 23:14:34773 request,
774 base::TimeDelta::FromMicroseconds(1),
775 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30776 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17777 &log);
[email protected]974ebd62009-08-03 23:14:34778 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
[email protected]26b9973962012-01-28 00:57:00779 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
[email protected]974ebd62009-08-03 23:14:34780 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30781
mmenke43758e62015-05-04 21:09:46782 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40783 log.GetEntries(&entries);
784
785 EXPECT_EQ(6u, entries.size());
[email protected]e9002a92010-01-29 07:10:46786 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40787 entries, 0, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]06650c52010-06-03 00:49:17788 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40789 entries, 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]e9002a92010-01-29 07:10:46790 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40791 entries, 2, NetLog::TYPE_CONNECT_JOB_SET_SOCKET,
[email protected]06650c52010-06-03 00:49:17792 NetLog::PHASE_NONE));
793 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40794 entries, 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
[email protected]9e743cd2010-03-16 07:03:53795 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:46796 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40797 entries, 4, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]06650c52010-06-03 00:49:17798 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40799 entries, 5, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34800}
801
[email protected]5fc08e32009-07-15 17:09:57802TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53803 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20804
[email protected]6ecf2b92011-12-15 01:14:52805 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06806 ClientSocketHandle handle;
vishal.b62985ca92015-04-17 08:45:51807 BoundTestNetLog log;
[email protected]034df0f32013-01-07 23:17:48808 TestLoadTimingInfoNotConnected(handle);
[email protected]9e743cd2010-03-16 07:03:53809
[email protected]2431756e2010-09-29 20:26:13810 EXPECT_EQ(OK,
811 handle.Init("a",
812 params_,
[email protected]bb1c4662013-11-14 00:00:07813 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:52814 callback.callback(),
[email protected]2431756e2010-09-29 20:26:13815 pool_.get(),
816 log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09817 EXPECT_TRUE(handle.is_initialized());
818 EXPECT_TRUE(handle.socket());
[email protected]034df0f32013-01-07 23:17:48819 TestLoadTimingInfoConnectedNotReused(handle);
820
[email protected]f6d1d6eb2009-06-24 20:16:09821 handle.Reset();
[email protected]034df0f32013-01-07 23:17:48822 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:30823
mmenke43758e62015-05-04 21:09:46824 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40825 log.GetEntries(&entries);
826
827 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:46828 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40829 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]9e743cd2010-03-16 07:03:53830 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40831 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:17832 NetLog::PHASE_NONE));
833 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40834 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]9e743cd2010-03-16 07:03:53835 NetLog::PHASE_NONE));
836 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40837 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09838}
839
[email protected]ab838892009-06-30 18:49:05840TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53841 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20842
[email protected]ab838892009-06-30 18:49:05843 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
vishal.b62985ca92015-04-17 08:45:51844 BoundTestNetLog log;
[email protected]9e743cd2010-03-16 07:03:53845
[email protected]2431756e2010-09-29 20:26:13846 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:52847 TestCompletionCallback callback;
[email protected]e60e47a2010-07-14 03:37:18848 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:13849 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43850 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:45851 info.headers = new HttpResponseHeaders(std::string());
[email protected]2431756e2010-09-29 20:26:13852 handle.set_ssl_error_response_info(info);
853 EXPECT_EQ(ERR_CONNECTION_FAILED,
854 handle.Init("a",
855 params_,
[email protected]bb1c4662013-11-14 00:00:07856 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:52857 callback.callback(),
[email protected]2431756e2010-09-29 20:26:13858 pool_.get(),
859 log.bound()));
860 EXPECT_FALSE(handle.socket());
861 EXPECT_FALSE(handle.is_ssl_error());
862 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]034df0f32013-01-07 23:17:48863 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:30864
mmenke43758e62015-05-04 21:09:46865 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40866 log.GetEntries(&entries);
867
868 EXPECT_EQ(3u, entries.size());
[email protected]5a1d7ca2010-04-28 20:12:27869 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40870 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:17871 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40872 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:17873 NetLog::PHASE_NONE));
[email protected]a2006ece2010-04-23 16:44:02874 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40875 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09876}
877
[email protected]211d21722009-07-22 15:48:53878TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
879 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
880
[email protected]9e743cd2010-03-16 07:03:53881 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30882
[email protected]bb1c4662013-11-14 00:00:07883 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
884 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
885 EXPECT_EQ(OK, StartRequest("c", DEFAULT_PRIORITY));
886 EXPECT_EQ(OK, StartRequest("d", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:53887
[email protected]2431756e2010-09-29 20:26:13888 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53889 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13890 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53891
[email protected]bb1c4662013-11-14 00:00:07892 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", DEFAULT_PRIORITY));
893 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", DEFAULT_PRIORITY));
894 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:53895
[email protected]2431756e2010-09-29 20:26:13896 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53897
[email protected]2431756e2010-09-29 20:26:13898 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53899 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13900 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53901
902 EXPECT_EQ(1, GetOrderOfRequest(1));
903 EXPECT_EQ(2, GetOrderOfRequest(2));
904 EXPECT_EQ(3, GetOrderOfRequest(3));
905 EXPECT_EQ(4, GetOrderOfRequest(4));
906 EXPECT_EQ(5, GetOrderOfRequest(5));
907 EXPECT_EQ(6, GetOrderOfRequest(6));
908 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17909
910 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13911 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53912}
913
914TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
915 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
916
[email protected]9e743cd2010-03-16 07:03:53917 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30918
[email protected]211d21722009-07-22 15:48:53919 // Reach all limits: max total sockets, and max sockets per group.
[email protected]bb1c4662013-11-14 00:00:07920 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
921 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
922 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
923 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:53924
[email protected]2431756e2010-09-29 20:26:13925 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53926 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13927 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53928
929 // Now create a new group and verify that we don't starve it.
[email protected]bb1c4662013-11-14 00:00:07930 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:53931
[email protected]2431756e2010-09-29 20:26:13932 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53933
[email protected]2431756e2010-09-29 20:26:13934 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53935 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13936 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53937
938 EXPECT_EQ(1, GetOrderOfRequest(1));
939 EXPECT_EQ(2, GetOrderOfRequest(2));
940 EXPECT_EQ(3, GetOrderOfRequest(3));
941 EXPECT_EQ(4, GetOrderOfRequest(4));
942 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17943
944 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13945 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53946}
947
948TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
949 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
950
[email protected]ac790b42009-12-02 04:31:31951 EXPECT_EQ(OK, StartRequest("b", LOWEST));
952 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
953 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
954 EXPECT_EQ(OK, StartRequest("a", LOWEST));
[email protected]211d21722009-07-22 15:48:53955
[email protected]2431756e2010-09-29 20:26:13956 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53957 client_socket_factory_.allocation_count());
958
[email protected]ac790b42009-12-02 04:31:31959 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
960 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
961 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53962
[email protected]2431756e2010-09-29 20:26:13963 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53964
[email protected]2431756e2010-09-29 20:26:13965 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53966
967 // First 4 requests don't have to wait, and finish in order.
968 EXPECT_EQ(1, GetOrderOfRequest(1));
969 EXPECT_EQ(2, GetOrderOfRequest(2));
970 EXPECT_EQ(3, GetOrderOfRequest(3));
971 EXPECT_EQ(4, GetOrderOfRequest(4));
972
[email protected]ac790b42009-12-02 04:31:31973 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
974 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53975 EXPECT_EQ(7, GetOrderOfRequest(5));
976 EXPECT_EQ(6, GetOrderOfRequest(6));
977 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17978
979 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13980 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]211d21722009-07-22 15:48:53981}
982
983TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
984 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
985
[email protected]ac790b42009-12-02 04:31:31986 EXPECT_EQ(OK, StartRequest("a", LOWEST));
987 EXPECT_EQ(OK, StartRequest("a", LOW));
988 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
989 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
[email protected]211d21722009-07-22 15:48:53990
[email protected]2431756e2010-09-29 20:26:13991 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53992 client_socket_factory_.allocation_count());
993
[email protected]ac790b42009-12-02 04:31:31994 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
995 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
996 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53997
[email protected]2431756e2010-09-29 20:26:13998 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53999
[email protected]2431756e2010-09-29 20:26:131000 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531001 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131002 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:531003
1004 // First 4 requests don't have to wait, and finish in order.
1005 EXPECT_EQ(1, GetOrderOfRequest(1));
1006 EXPECT_EQ(2, GetOrderOfRequest(2));
1007 EXPECT_EQ(3, GetOrderOfRequest(3));
1008 EXPECT_EQ(4, GetOrderOfRequest(4));
1009
1010 // Request ("b", 7) has the highest priority, but we can't make new socket for
1011 // group "b", because it has reached the per-group limit. Then we make
1012 // socket for ("c", 6), because it has higher priority than ("a", 4),
1013 // and we still can't make a socket for group "b".
1014 EXPECT_EQ(5, GetOrderOfRequest(5));
1015 EXPECT_EQ(6, GetOrderOfRequest(6));
1016 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171017
1018 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131019 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:531020}
1021
1022// Make sure that we count connecting sockets against the total limit.
1023TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
1024 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1025
[email protected]bb1c4662013-11-14 00:00:071026 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1027 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
1028 EXPECT_EQ(OK, StartRequest("c", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:531029
1030 // Create one asynchronous request.
1031 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]bb1c4662013-11-14 00:00:071032 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:531033
[email protected]6b175382009-10-13 06:47:471034 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1035 // actually become pending until 2ms after they have been created. In order
1036 // to flush all tasks, we need to wait so that we know there are no
1037 // soon-to-be-pending tasks waiting.
[email protected]26b9973962012-01-28 00:57:001038 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
[email protected]2da659e2013-05-23 20:51:341039 base::MessageLoop::current()->RunUntilIdle();
[email protected]6b175382009-10-13 06:47:471040
[email protected]211d21722009-07-22 15:48:531041 // The next synchronous request should wait for its turn.
1042 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]bb1c4662013-11-14 00:00:071043 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:531044
[email protected]2431756e2010-09-29 20:26:131045 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531046
[email protected]2431756e2010-09-29 20:26:131047 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531048 client_socket_factory_.allocation_count());
1049
1050 EXPECT_EQ(1, GetOrderOfRequest(1));
1051 EXPECT_EQ(2, GetOrderOfRequest(2));
1052 EXPECT_EQ(3, GetOrderOfRequest(3));
1053 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:171054 EXPECT_EQ(5, GetOrderOfRequest(5));
1055
1056 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131057 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:531058}
1059
[email protected]6427fe22010-04-16 22:27:411060TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
1061 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1062 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1063
[email protected]bb1c4662013-11-14 00:00:071064 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1065 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1066 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1067 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
[email protected]6427fe22010-04-16 22:27:411068
1069 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1070
1071 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1072
[email protected]bb1c4662013-11-14 00:00:071073 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", DEFAULT_PRIORITY));
1074 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", DEFAULT_PRIORITY));
[email protected]6427fe22010-04-16 22:27:411075
1076 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1077
[email protected]2431756e2010-09-29 20:26:131078 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411079 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131080 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411081 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131082 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1083 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411084 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
1085}
1086
[email protected]d7027bb2010-05-10 18:58:541087TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
1088 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1089 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1090
1091 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521092 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131093 EXPECT_EQ(ERR_IO_PENDING,
1094 handle.Init("a",
1095 params_,
[email protected]bb1c4662013-11-14 00:00:071096 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521097 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131098 pool_.get(),
1099 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541100
1101 ClientSocketHandle handles[4];
1102 for (size_t i = 0; i < arraysize(handles); ++i) {
[email protected]6ecf2b92011-12-15 01:14:521103 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131104 EXPECT_EQ(ERR_IO_PENDING,
1105 handles[i].Init("b",
1106 params_,
[email protected]bb1c4662013-11-14 00:00:071107 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521108 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131109 pool_.get(),
1110 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541111 }
1112
1113 // One will be stalled, cancel all the handles now.
1114 // This should hit the OnAvailableSocketSlot() code where we previously had
1115 // stalled groups, but no longer have any.
1116 for (size_t i = 0; i < arraysize(handles); ++i)
1117 handles[i].Reset();
1118}
1119
[email protected]eb5a99382010-07-11 03:18:261120TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:541121 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1122 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1123
[email protected]eb5a99382010-07-11 03:18:261124 {
1125 ClientSocketHandle handles[kDefaultMaxSockets];
[email protected]6ecf2b92011-12-15 01:14:521126 TestCompletionCallback callbacks[kDefaultMaxSockets];
[email protected]eb5a99382010-07-11 03:18:261127 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]2431756e2010-09-29 20:26:131128 EXPECT_EQ(OK, handles[i].Init(base::IntToString(i),
1129 params_,
[email protected]bb1c4662013-11-14 00:00:071130 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521131 callbacks[i].callback(),
[email protected]2431756e2010-09-29 20:26:131132 pool_.get(),
1133 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261134 }
1135
1136 // Force a stalled group.
1137 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521138 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131139 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1140 params_,
[email protected]bb1c4662013-11-14 00:00:071141 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521142 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131143 pool_.get(),
1144 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261145
1146 // Cancel the stalled request.
1147 stalled_handle.Reset();
1148
1149 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1150 EXPECT_EQ(0, pool_->IdleSocketCount());
1151
1152 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541153 }
1154
[email protected]43a21b82010-06-10 21:30:541155 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1156 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:261157}
[email protected]43a21b82010-06-10 21:30:541158
[email protected]eb5a99382010-07-11 03:18:261159TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
1160 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1161 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1162
1163 {
1164 ClientSocketHandle handles[kDefaultMaxSockets];
1165 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521166 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131167 EXPECT_EQ(ERR_IO_PENDING, handles[i].Init(base::IntToString(i),
1168 params_,
[email protected]bb1c4662013-11-14 00:00:071169 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521170 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131171 pool_.get(),
1172 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261173 }
1174
1175 // Force a stalled group.
1176 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1177 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521178 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131179 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1180 params_,
[email protected]bb1c4662013-11-14 00:00:071181 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521182 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131183 pool_.get(),
1184 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261185
1186 // Since it is stalled, it should have no connect jobs.
1187 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101188 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261189
1190 // Cancel the stalled request.
1191 handles[0].Reset();
1192
[email protected]eb5a99382010-07-11 03:18:261193 // Now we should have a connect job.
1194 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101195 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261196
1197 // The stalled socket should connect.
1198 EXPECT_EQ(OK, callback.WaitForResult());
1199
1200 EXPECT_EQ(kDefaultMaxSockets + 1,
1201 client_socket_factory_.allocation_count());
1202 EXPECT_EQ(0, pool_->IdleSocketCount());
1203 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101204 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261205
1206 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541207 }
1208
[email protected]eb5a99382010-07-11 03:18:261209 EXPECT_EQ(1, pool_->IdleSocketCount());
1210}
[email protected]43a21b82010-06-10 21:30:541211
[email protected]eb5a99382010-07-11 03:18:261212TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1213 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1214 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:541215
[email protected]eb5a99382010-07-11 03:18:261216 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521217 TestCompletionCallback callback;
[email protected]eb5a99382010-07-11 03:18:261218 {
[email protected]51fdc7c2012-04-10 19:19:481219 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261220 ClientSocketHandle handles[kDefaultMaxSockets];
1221 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521222 TestCompletionCallback callback;
[email protected]1870d5cf2011-05-12 01:55:401223 EXPECT_EQ(OK, handles[i].Init(base::StringPrintf(
1224 "Take 2: %d", i),
1225 params_,
[email protected]bb1c4662013-11-14 00:00:071226 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521227 callback.callback(),
[email protected]1870d5cf2011-05-12 01:55:401228 pool_.get(),
1229 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261230 }
1231
1232 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1233 EXPECT_EQ(0, pool_->IdleSocketCount());
[email protected]51fdc7c2012-04-10 19:19:481234 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261235
1236 // Now we will hit the socket limit.
[email protected]2431756e2010-09-29 20:26:131237 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1238 params_,
[email protected]bb1c4662013-11-14 00:00:071239 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521240 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131241 pool_.get(),
1242 BoundNetLog()));
[email protected]51fdc7c2012-04-10 19:19:481243 EXPECT_TRUE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261244
1245 // Dropping out of scope will close all handles and return them to idle.
1246 }
[email protected]43a21b82010-06-10 21:30:541247
1248 // But if we wait for it, the released idle sockets will be closed in
1249 // preference of the waiting request.
[email protected]8ae03f42010-07-07 19:08:101250 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]eb5a99382010-07-11 03:18:261251
1252 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1253 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:541254}
1255
1256// Regression test for http://crbug.com/40952.
1257TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1258 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]06d94042010-08-25 01:45:221259 pool_->EnableConnectBackupJobs();
[email protected]43a21b82010-06-10 21:30:541260 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1261
1262 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1263 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521264 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131265 EXPECT_EQ(OK, handle.Init(base::IntToString(i),
1266 params_,
[email protected]bb1c4662013-11-14 00:00:071267 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521268 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131269 pool_.get(),
1270 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541271 }
1272
1273 // Flush all the DoReleaseSocket tasks.
[email protected]2da659e2013-05-23 20:51:341274 base::MessageLoop::current()->RunUntilIdle();
[email protected]43a21b82010-06-10 21:30:541275
1276 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1277 // reuse a socket.
1278 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1279 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521280 TestCompletionCallback callback;
[email protected]43a21b82010-06-10 21:30:541281
1282 // "0" is special here, since it should be the first entry in the sorted map,
1283 // which is the one which we would close an idle socket for. We shouldn't
1284 // close an idle socket though, since we should reuse the idle socket.
[email protected]2431756e2010-09-29 20:26:131285 EXPECT_EQ(OK, handle.Init("0",
1286 params_,
[email protected]bb1c4662013-11-14 00:00:071287 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521288 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131289 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211290 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541291
1292 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1293 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1294}
1295
[email protected]ab838892009-06-30 18:49:051296TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531297 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091298
[email protected]bb1c4662013-11-14 00:00:071299 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1300 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
[email protected]c9c6f5c2010-07-31 01:30:031301 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", IDLE));
[email protected]ac790b42009-12-02 04:31:311302 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1303 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1304 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1305 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1306 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091307
[email protected]2431756e2010-09-29 20:26:131308 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091309
[email protected]c9d6a1d2009-07-14 16:15:201310 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1311 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131312 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1313 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091314
[email protected]c9d6a1d2009-07-14 16:15:201315 EXPECT_EQ(1, GetOrderOfRequest(1));
1316 EXPECT_EQ(2, GetOrderOfRequest(2));
[email protected]c9c6f5c2010-07-31 01:30:031317 EXPECT_EQ(8, GetOrderOfRequest(3));
1318 EXPECT_EQ(6, GetOrderOfRequest(4));
1319 EXPECT_EQ(4, GetOrderOfRequest(5));
1320 EXPECT_EQ(3, GetOrderOfRequest(6));
1321 EXPECT_EQ(5, GetOrderOfRequest(7));
1322 EXPECT_EQ(7, GetOrderOfRequest(8));
[email protected]75439d3b2009-07-23 22:11:171323
1324 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131325 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]f6d1d6eb2009-06-24 20:16:091326}
1327
[email protected]ab838892009-06-30 18:49:051328TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531329 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091330
[email protected]bb1c4662013-11-14 00:00:071331 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1332 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
[email protected]ac790b42009-12-02 04:31:311333 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1334 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1335 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1336 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1337 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091338
[email protected]2431756e2010-09-29 20:26:131339 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091340
[email protected]2431756e2010-09-29 20:26:131341 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
1342 EXPECT_EQ(OK, request(i)->WaitForResult());
[email protected]c9d6a1d2009-07-14 16:15:201343
[email protected]2431756e2010-09-29 20:26:131344 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]c9d6a1d2009-07-14 16:15:201345 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131346 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1347 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091348}
1349
1350// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:051351// The pending connect job will be cancelled and should not call back into
1352// ClientSocketPoolBase.
1353TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531354 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201355
[email protected]ab838892009-06-30 18:49:051356 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131357 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521358 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131359 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1360 params_,
[email protected]bb1c4662013-11-14 00:00:071361 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521362 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131363 pool_.get(),
1364 BoundNetLog()));
1365 handle.Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091366}
1367
[email protected]ab838892009-06-30 18:49:051368TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531369 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201370
[email protected]ab838892009-06-30 18:49:051371 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061372 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521373 TestCompletionCallback callback;
[email protected]f6d1d6eb2009-06-24 20:16:091374
[email protected]2431756e2010-09-29 20:26:131375 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1376 params_,
[email protected]bb1c4662013-11-14 00:00:071377 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521378 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131379 pool_.get(),
1380 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091381
1382 handle.Reset();
1383
[email protected]6ecf2b92011-12-15 01:14:521384 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:131385 EXPECT_EQ(ERR_IO_PENDING,
1386 handle.Init("a",
1387 params_,
[email protected]bb1c4662013-11-14 00:00:071388 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521389 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:131390 pool_.get(),
1391 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091392
1393 EXPECT_EQ(OK, callback2.WaitForResult());
1394 EXPECT_FALSE(callback.have_result());
1395
1396 handle.Reset();
1397}
1398
[email protected]ab838892009-06-30 18:49:051399TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531400 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091401
[email protected]bb1c4662013-11-14 00:00:071402 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1403 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
[email protected]ac790b42009-12-02 04:31:311404 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1405 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1406 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1407 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1408 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091409
1410 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201411 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]2431756e2010-09-29 20:26:131412 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1413 (*requests())[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091414
[email protected]2431756e2010-09-29 20:26:131415 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091416
[email protected]c9d6a1d2009-07-14 16:15:201417 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1418 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131419 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1420 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091421
[email protected]c9d6a1d2009-07-14 16:15:201422 EXPECT_EQ(1, GetOrderOfRequest(1));
1423 EXPECT_EQ(2, GetOrderOfRequest(2));
1424 EXPECT_EQ(5, GetOrderOfRequest(3));
1425 EXPECT_EQ(3, GetOrderOfRequest(4));
[email protected]2431756e2010-09-29 20:26:131426 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1427 GetOrderOfRequest(5)); // Canceled request.
[email protected]c9d6a1d2009-07-14 16:15:201428 EXPECT_EQ(4, GetOrderOfRequest(6));
1429 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171430
1431 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131432 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091433}
1434
[email protected]6ecf2b92011-12-15 01:14:521435class RequestSocketCallback : public TestCompletionCallbackBase {
[email protected]f6d1d6eb2009-06-24 20:16:091436 public:
[email protected]2ab05b52009-07-01 23:57:581437 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:241438 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:581439 TestConnectJobFactory* test_connect_job_factory,
1440 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:091441 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:061442 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:581443 within_callback_(false),
1444 test_connect_job_factory_(test_connect_job_factory),
[email protected]6ecf2b92011-12-15 01:14:521445 next_job_type_(next_job_type),
[email protected]aa249b52013-04-30 01:04:321446 callback_(base::Bind(&RequestSocketCallback::OnComplete,
1447 base::Unretained(this))) {
[email protected]6ecf2b92011-12-15 01:14:521448 }
[email protected]f6d1d6eb2009-06-24 20:16:091449
dchengb03027d2014-10-21 12:00:201450 ~RequestSocketCallback() override {}
[email protected]6ecf2b92011-12-15 01:14:521451
1452 const CompletionCallback& callback() const { return callback_; }
1453
1454 private:
1455 void OnComplete(int result) {
1456 SetResult(result);
1457 ASSERT_EQ(OK, result);
[email protected]f6d1d6eb2009-06-24 20:16:091458
1459 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:581460 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]5edbf8d2010-01-13 18:44:111461
1462 // Don't allow reuse of the socket. Disconnect it and then release it and
1463 // run through the MessageLoop once to get it completely released.
1464 handle_->socket()->Disconnect();
[email protected]f6d1d6eb2009-06-24 20:16:091465 handle_->Reset();
[email protected]5edbf8d2010-01-13 18:44:111466 {
[email protected]b5717a42012-02-14 19:33:521467 // TODO: Resolve conflicting intentions of stopping recursion with the
[email protected]b4c62eb2012-11-14 18:36:511468 // |!within_callback_| test (above) and the call to |RunUntilIdle()|
[email protected]b5717a42012-02-14 19:33:521469 // below. http://crbug.com/114130.
[email protected]2da659e2013-05-23 20:51:341470 base::MessageLoop::ScopedNestableTaskAllower allow(
1471 base::MessageLoop::current());
1472 base::MessageLoop::current()->RunUntilIdle();
[email protected]5edbf8d2010-01-13 18:44:111473 }
[email protected]f6d1d6eb2009-06-24 20:16:091474 within_callback_ = true;
[email protected]6ecf2b92011-12-15 01:14:521475 TestCompletionCallback next_job_callback;
[email protected]bb1c4662013-11-14 00:00:071476 scoped_refptr<TestSocketParams> params(
1477 new TestSocketParams(false /* ignore_limits */));
[email protected]2431756e2010-09-29 20:26:131478 int rv = handle_->Init("a",
1479 params,
[email protected]bb1c4662013-11-14 00:00:071480 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521481 next_job_callback.callback(),
[email protected]2431756e2010-09-29 20:26:131482 pool_,
1483 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581484 switch (next_job_type_) {
1485 case TestConnectJob::kMockJob:
1486 EXPECT_EQ(OK, rv);
1487 break;
1488 case TestConnectJob::kMockPendingJob:
1489 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:471490
1491 // For pending jobs, wait for new socket to be created. This makes
1492 // sure there are no more pending operations nor any unclosed sockets
1493 // when the test finishes.
1494 // We need to give it a little bit of time to run, so that all the
1495 // operations that happen on timers (e.g. cleanup of idle
1496 // connections) can execute.
[email protected]5edbf8d2010-01-13 18:44:111497 {
[email protected]2da659e2013-05-23 20:51:341498 base::MessageLoop::ScopedNestableTaskAllower allow(
1499 base::MessageLoop::current());
[email protected]26b9973962012-01-28 00:57:001500 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
[email protected]5edbf8d2010-01-13 18:44:111501 EXPECT_EQ(OK, next_job_callback.WaitForResult());
1502 }
[email protected]2ab05b52009-07-01 23:57:581503 break;
1504 default:
1505 FAIL() << "Unexpected job type: " << next_job_type_;
1506 break;
1507 }
[email protected]f6d1d6eb2009-06-24 20:16:091508 }
1509 }
1510
[email protected]f6d1d6eb2009-06-24 20:16:091511 ClientSocketHandle* const handle_;
[email protected]2431756e2010-09-29 20:26:131512 TestClientSocketPool* const pool_;
[email protected]f6d1d6eb2009-06-24 20:16:091513 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:581514 TestConnectJobFactory* const test_connect_job_factory_;
1515 TestConnectJob::JobType next_job_type_;
[email protected]6ecf2b92011-12-15 01:14:521516 CompletionCallback callback_;
[email protected]f6d1d6eb2009-06-24 20:16:091517};
1518
[email protected]2ab05b52009-07-01 23:57:581519TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531520 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201521
[email protected]0b7648c2009-07-06 20:14:011522 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061523 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581524 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061525 &handle, pool_.get(), connect_job_factory_,
1526 TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131527 int rv = handle.Init("a",
1528 params_,
[email protected]bb1c4662013-11-14 00:00:071529 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521530 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131531 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211532 BoundNetLog());
[email protected]f6d1d6eb2009-06-24 20:16:091533 ASSERT_EQ(ERR_IO_PENDING, rv);
1534
1535 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581536}
[email protected]f6d1d6eb2009-06-24 20:16:091537
[email protected]2ab05b52009-07-01 23:57:581538TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531539 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201540
[email protected]0b7648c2009-07-06 20:14:011541 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061542 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581543 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061544 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]2431756e2010-09-29 20:26:131545 int rv = handle.Init("a",
1546 params_,
[email protected]bb1c4662013-11-14 00:00:071547 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521548 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131549 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211550 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581551 ASSERT_EQ(ERR_IO_PENDING, rv);
1552
1553 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091554}
1555
1556// Make sure that pending requests get serviced after active requests get
1557// cancelled.
[email protected]ab838892009-06-30 18:49:051558TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531559 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201560
[email protected]0b7648c2009-07-06 20:14:011561 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091562
[email protected]bb1c4662013-11-14 00:00:071563 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1564 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1565 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1566 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1567 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1568 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1569 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
[email protected]f6d1d6eb2009-06-24 20:16:091570
[email protected]c9d6a1d2009-07-14 16:15:201571 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1572 // Let's cancel them.
1573 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]2431756e2010-09-29 20:26:131574 ASSERT_FALSE(request(i)->handle()->is_initialized());
1575 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091576 }
1577
[email protected]f6d1d6eb2009-06-24 20:16:091578 // Let's wait for the rest to complete now.
[email protected]2431756e2010-09-29 20:26:131579 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
1580 EXPECT_EQ(OK, request(i)->WaitForResult());
1581 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091582 }
1583
[email protected]2431756e2010-09-29 20:26:131584 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1585 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091586}
1587
1588// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051589TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531590 const size_t kMaxSockets = 5;
1591 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201592
[email protected]0b7648c2009-07-06 20:14:011593 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091594
[email protected]211d21722009-07-22 15:48:531595 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1596 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091597
1598 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531599 for (size_t i = 0; i < kNumberOfRequests; ++i)
[email protected]bb1c4662013-11-14 00:00:071600 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
[email protected]f6d1d6eb2009-06-24 20:16:091601
[email protected]211d21722009-07-22 15:48:531602 for (size_t i = 0; i < kNumberOfRequests; ++i)
[email protected]2431756e2010-09-29 20:26:131603 EXPECT_EQ(ERR_CONNECTION_FAILED, request(i)->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091604}
1605
[email protected]5fc08e32009-07-15 17:09:571606TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531607 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571608
1609 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1610
[email protected]2431756e2010-09-29 20:26:131611 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521612 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131613 int rv = handle.Init("a",
1614 params_,
[email protected]bb1c4662013-11-14 00:00:071615 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521616 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131617 pool_.get(),
1618 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571619 EXPECT_EQ(ERR_IO_PENDING, rv);
1620
1621 // Cancel the active request.
[email protected]2431756e2010-09-29 20:26:131622 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571623
[email protected]2431756e2010-09-29 20:26:131624 rv = handle.Init("a",
1625 params_,
[email protected]bb1c4662013-11-14 00:00:071626 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521627 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131628 pool_.get(),
1629 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571630 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131631 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]5fc08e32009-07-15 17:09:571632
[email protected]2431756e2010-09-29 20:26:131633 EXPECT_FALSE(handle.is_reused());
[email protected]034df0f32013-01-07 23:17:481634 TestLoadTimingInfoConnectedNotReused(handle);
[email protected]5fc08e32009-07-15 17:09:571635 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1636}
1637
[email protected]2b7523d2009-07-29 20:29:231638// Regression test for http://crbug.com/17985.
1639TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1640 const int kMaxSockets = 3;
1641 const int kMaxSocketsPerGroup = 2;
1642 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1643
[email protected]ac790b42009-12-02 04:31:311644 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231645
[email protected]bb1c4662013-11-14 00:00:071646 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1647 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
[email protected]2b7523d2009-07-29 20:29:231648
1649 // This is going to be a pending request in an otherwise empty group.
[email protected]bb1c4662013-11-14 00:00:071650 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
[email protected]2b7523d2009-07-29 20:29:231651
1652 // Reach the maximum socket limit.
[email protected]bb1c4662013-11-14 00:00:071653 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
[email protected]2b7523d2009-07-29 20:29:231654
1655 // Create a stalled group with high priorities.
1656 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1657 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
[email protected]2b7523d2009-07-29 20:29:231658
[email protected]eb5a99382010-07-11 03:18:261659 // Release the first two sockets from "a". Because this is a keepalive,
1660 // the first release will unblock the pending request for "a". The
1661 // second release will unblock a request for "c", becaue it is the next
1662 // high priority socket.
[email protected]2431756e2010-09-29 20:26:131663 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1664 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]2b7523d2009-07-29 20:29:231665
1666 // Closing idle sockets should not get us into trouble, but in the bug
1667 // we were hitting a CHECK here.
[email protected]93054cc12010-06-08 06:12:411668 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]43a21b82010-06-10 21:30:541669 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261670
[email protected]2da659e2013-05-23 20:51:341671 // Run the released socket wakeups.
1672 base::MessageLoop::current()->RunUntilIdle();
[email protected]2b7523d2009-07-29 20:29:231673}
1674
[email protected]4d3b05d2010-01-27 21:27:291675TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531676 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571677
1678 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131679 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521680 TestCompletionCallback callback;
vishal.b62985ca92015-04-17 08:45:511681 BoundTestNetLog log;
[email protected]2431756e2010-09-29 20:26:131682 int rv = handle.Init("a",
1683 params_,
1684 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:521685 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131686 pool_.get(),
1687 log.bound());
[email protected]5fc08e32009-07-15 17:09:571688 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131689 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
[email protected]034df0f32013-01-07 23:17:481690 TestLoadTimingInfoNotConnected(handle);
1691
[email protected]2431756e2010-09-29 20:26:131692 EXPECT_EQ(OK, callback.WaitForResult());
1693 EXPECT_TRUE(handle.is_initialized());
1694 EXPECT_TRUE(handle.socket());
[email protected]034df0f32013-01-07 23:17:481695 TestLoadTimingInfoConnectedNotReused(handle);
1696
[email protected]2431756e2010-09-29 20:26:131697 handle.Reset();
[email protected]034df0f32013-01-07 23:17:481698 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:301699
mmenke43758e62015-05-04 21:09:461700 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:401701 log.GetEntries(&entries);
1702
1703 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:461704 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401705 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171706 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401707 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171708 NetLog::PHASE_NONE));
1709 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401710 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]06650c52010-06-03 00:49:171711 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:461712 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401713 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571714}
1715
[email protected]4d3b05d2010-01-27 21:27:291716TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571717 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531718 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571719
1720 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2431756e2010-09-29 20:26:131721 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521722 TestCompletionCallback callback;
vishal.b62985ca92015-04-17 08:45:511723 BoundTestNetLog log;
[email protected]e60e47a2010-07-14 03:37:181724 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:131725 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:431726 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:451727 info.headers = new HttpResponseHeaders(std::string());
[email protected]2431756e2010-09-29 20:26:131728 handle.set_ssl_error_response_info(info);
1729 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1730 params_,
[email protected]bb1c4662013-11-14 00:00:071731 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521732 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131733 pool_.get(),
1734 log.bound()));
1735 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1736 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1737 EXPECT_FALSE(handle.is_ssl_error());
1738 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:301739
mmenke43758e62015-05-04 21:09:461740 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:401741 log.GetEntries(&entries);
1742
1743 EXPECT_EQ(3u, entries.size());
[email protected]e9002a92010-01-29 07:10:461744 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401745 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171746 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401747 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171748 NetLog::PHASE_NONE));
[email protected]6b624c62010-03-14 08:37:321749 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401750 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571751}
1752
mmenke6be122f2015-03-09 22:22:471753// Check that an async ConnectJob failure does not result in creation of a new
1754// ConnectJob when there's another pending request also waiting on its own
1755// ConnectJob. See http://crbug.com/463960.
1756TEST_F(ClientSocketPoolBaseTest, AsyncFailureWithPendingRequestWithJob) {
1757 CreatePool(2, 2);
1758 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1759
1760 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1761 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1762
1763 EXPECT_EQ(ERR_CONNECTION_FAILED, request(0)->WaitForResult());
1764 EXPECT_EQ(ERR_CONNECTION_FAILED, request(1)->WaitForResult());
1765
1766 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1767}
1768
[email protected]4d3b05d2010-01-27 21:27:291769TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101770 // TODO(eroman): Add back the log expectations! Removed them because the
1771 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531772 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571773
1774 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131775 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521776 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131777 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:521778 TestCompletionCallback callback2;
[email protected]5fc08e32009-07-15 17:09:571779
[email protected]2431756e2010-09-29 20:26:131780 EXPECT_EQ(ERR_IO_PENDING,
1781 handle.Init("a",
1782 params_,
[email protected]bb1c4662013-11-14 00:00:071783 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521784 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131785 pool_.get(),
1786 BoundNetLog()));
vishal.b62985ca92015-04-17 08:45:511787 BoundTestNetLog log2;
[email protected]2431756e2010-09-29 20:26:131788 EXPECT_EQ(ERR_IO_PENDING,
1789 handle2.Init("a",
1790 params_,
[email protected]bb1c4662013-11-14 00:00:071791 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521792 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:131793 pool_.get(),
1794 BoundNetLog()));
[email protected]5fc08e32009-07-15 17:09:571795
[email protected]2431756e2010-09-29 20:26:131796 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571797
[email protected]fd7b7c92009-08-20 19:38:301798
1799 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301800
[email protected]2431756e2010-09-29 20:26:131801 EXPECT_EQ(OK, callback2.WaitForResult());
1802 handle2.Reset();
[email protected]fd7b7c92009-08-20 19:38:301803
1804 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531805 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571806}
1807
[email protected]4d3b05d2010-01-27 21:27:291808TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341809 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1810
[email protected]17a0c6c2009-08-04 00:07:041811 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1812
[email protected]ac790b42009-12-02 04:31:311813 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1814 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1815 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1816 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341817
1818 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]2431756e2010-09-29 20:26:131819 (*requests())[2]->handle()->Reset();
1820 (*requests())[3]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341821 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1822
[email protected]2431756e2010-09-29 20:26:131823 (*requests())[1]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341824 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1825
[email protected]2431756e2010-09-29 20:26:131826 (*requests())[0]->handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261827 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]974ebd62009-08-03 23:14:341828}
1829
[email protected]5fc08e32009-07-15 17:09:571830// When requests and ConnectJobs are not coupled, the request will get serviced
1831// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291832TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531833 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571834
1835 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321836 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571837
[email protected]2431756e2010-09-29 20:26:131838 std::vector<TestSocketRequest*> request_order;
1839 size_t completion_count; // unused
1840 TestSocketRequest req1(&request_order, &completion_count);
1841 int rv = req1.handle()->Init("a",
1842 params_,
[email protected]bb1c4662013-11-14 00:00:071843 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521844 req1.callback(), pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211845 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571846 EXPECT_EQ(ERR_IO_PENDING, rv);
1847 EXPECT_EQ(OK, req1.WaitForResult());
1848
1849 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1850 // without a job.
1851 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1852
[email protected]2431756e2010-09-29 20:26:131853 TestSocketRequest req2(&request_order, &completion_count);
1854 rv = req2.handle()->Init("a",
1855 params_,
[email protected]bb1c4662013-11-14 00:00:071856 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521857 req2.callback(),
[email protected]2431756e2010-09-29 20:26:131858 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211859 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571860 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131861 TestSocketRequest req3(&request_order, &completion_count);
1862 rv = req3.handle()->Init("a",
1863 params_,
[email protected]bb1c4662013-11-14 00:00:071864 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521865 req3.callback(),
[email protected]2431756e2010-09-29 20:26:131866 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211867 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571868 EXPECT_EQ(ERR_IO_PENDING, rv);
1869
1870 // Both Requests 2 and 3 are pending. We release socket 1 which should
1871 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331872 req1.handle()->Reset();
[email protected]2da659e2013-05-23 20:51:341873 // Run the released socket wakeups.
1874 base::MessageLoop::current()->RunUntilIdle();
[email protected]a6c59f62009-07-29 16:33:331875 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571876 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331877 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571878
1879 // Signal job 2, which should service request 3.
1880
1881 client_socket_factory_.SignalJobs();
1882 EXPECT_EQ(OK, req3.WaitForResult());
1883
[email protected]2431756e2010-09-29 20:26:131884 ASSERT_EQ(3U, request_order.size());
1885 EXPECT_EQ(&req1, request_order[0]);
1886 EXPECT_EQ(&req2, request_order[1]);
1887 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571888 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1889}
1890
1891// The requests are not coupled to the jobs. So, the requests should finish in
1892// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:291893TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531894 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571895 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321896 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571897
[email protected]2431756e2010-09-29 20:26:131898 std::vector<TestSocketRequest*> request_order;
1899 size_t completion_count; // unused
1900 TestSocketRequest req1(&request_order, &completion_count);
1901 int rv = req1.handle()->Init("a",
1902 params_,
[email protected]bb1c4662013-11-14 00:00:071903 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521904 req1.callback(),
[email protected]2431756e2010-09-29 20:26:131905 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211906 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571907 EXPECT_EQ(ERR_IO_PENDING, rv);
1908
[email protected]2431756e2010-09-29 20:26:131909 TestSocketRequest req2(&request_order, &completion_count);
1910 rv = req2.handle()->Init("a",
1911 params_,
[email protected]bb1c4662013-11-14 00:00:071912 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521913 req2.callback(),
[email protected]2431756e2010-09-29 20:26:131914 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211915 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571916 EXPECT_EQ(ERR_IO_PENDING, rv);
1917
1918 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321919 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571920
[email protected]2431756e2010-09-29 20:26:131921 TestSocketRequest req3(&request_order, &completion_count);
1922 rv = req3.handle()->Init("a",
1923 params_,
[email protected]bb1c4662013-11-14 00:00:071924 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521925 req3.callback(),
[email protected]2431756e2010-09-29 20:26:131926 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211927 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571928 EXPECT_EQ(ERR_IO_PENDING, rv);
1929
1930 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1931 EXPECT_EQ(OK, req2.WaitForResult());
1932 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1933
[email protected]2431756e2010-09-29 20:26:131934 ASSERT_EQ(3U, request_order.size());
1935 EXPECT_EQ(&req1, request_order[0]);
1936 EXPECT_EQ(&req2, request_order[1]);
1937 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571938}
1939
[email protected]03b7c8c2013-07-20 04:38:551940// Test GetLoadState in the case there's only one socket request.
1941TEST_F(ClientSocketPoolBaseTest, LoadStateOneRequest) {
[email protected]211d21722009-07-22 15:48:531942 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]03b7c8c2013-07-20 04:38:551943 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]5fc08e32009-07-15 17:09:571944
[email protected]2431756e2010-09-29 20:26:131945 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521946 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131947 int rv = handle.Init("a",
1948 params_,
[email protected]bb1c4662013-11-14 00:00:071949 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521950 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131951 pool_.get(),
1952 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571953 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]03b7c8c2013-07-20 04:38:551954 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571955
[email protected]03b7c8c2013-07-20 04:38:551956 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
1957 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
1958
1959 // No point in completing the connection, since ClientSocketHandles only
1960 // expect the LoadState to be checked while connecting.
1961}
1962
1963// Test GetLoadState in the case there are two socket requests.
haavardm835c1d62015-04-22 08:18:001964// Only the first connection in the pool should affect the pool's load status.
[email protected]03b7c8c2013-07-20 04:38:551965TEST_F(ClientSocketPoolBaseTest, LoadStateTwoRequests) {
1966 CreatePool(2, 2);
1967 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1968
1969 ClientSocketHandle handle;
1970 TestCompletionCallback callback;
haavardm835c1d62015-04-22 08:18:001971 int rv = handle.Init("a", params_, DEFAULT_PRIORITY, callback.callback(),
1972 pool_.get(), BoundNetLog());
1973 EXPECT_EQ(ERR_IO_PENDING, rv);
1974 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
1975
1976 ClientSocketHandle handle2;
1977 TestCompletionCallback callback2;
1978 rv = handle2.Init("a", params_, DEFAULT_PRIORITY, callback2.callback(),
1979 pool_.get(), BoundNetLog());
1980 EXPECT_EQ(ERR_IO_PENDING, rv);
1981 client_socket_factory_.SetJobLoadState(1, LOAD_STATE_RESOLVING_HOST);
1982
1983 // Check that both handles report the state of the first job.
1984 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle.GetLoadState());
1985 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle2.GetLoadState());
1986
1987 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_CONNECTING);
1988
1989 // Check that both handles change to LOAD_STATE_CONNECTING.
1990 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
1991 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
1992}
1993
1994// Test that the second connection request does not affect the pool's load
1995// status.
1996TEST_F(ClientSocketPoolBaseTest, LoadStateTwoRequestsChangeSecondRequestState) {
1997 CreatePool(2, 2);
1998 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1999
2000 ClientSocketHandle handle;
2001 TestCompletionCallback callback;
2002 int rv = handle.Init("a", params_, DEFAULT_PRIORITY, callback.callback(),
2003 pool_.get(), BoundNetLog());
[email protected]03b7c8c2013-07-20 04:38:552004 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]5fc08e32009-07-15 17:09:572005
[email protected]2431756e2010-09-29 20:26:132006 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522007 TestCompletionCallback callback2;
haavardm835c1d62015-04-22 08:18:002008 rv = handle2.Init("a", params_, DEFAULT_PRIORITY, callback2.callback(),
2009 pool_.get(), BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:572010 EXPECT_EQ(ERR_IO_PENDING, rv);
haavardm835c1d62015-04-22 08:18:002011 client_socket_factory_.SetJobLoadState(1, LOAD_STATE_RESOLVING_HOST);
[email protected]03b7c8c2013-07-20 04:38:552012
[email protected]03b7c8c2013-07-20 04:38:552013 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2014 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
2015
haavardm835c1d62015-04-22 08:18:002016 // First job connects and the first request gets the socket. The
[email protected]03b7c8c2013-07-20 04:38:552017 // second handle switches to the state of the remaining ConnectJob.
2018 client_socket_factory_.SignalJob(0);
2019 EXPECT_EQ(OK, callback.WaitForResult());
haavardm835c1d62015-04-22 08:18:002020 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle2.GetLoadState());
[email protected]03b7c8c2013-07-20 04:38:552021}
2022
2023// Test GetLoadState in the case the per-group limit is reached.
2024TEST_F(ClientSocketPoolBaseTest, LoadStateGroupLimit) {
2025 CreatePool(2, 1);
2026 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2027
2028 ClientSocketHandle handle;
2029 TestCompletionCallback callback;
2030 int rv = handle.Init("a",
2031 params_,
2032 MEDIUM,
2033 callback.callback(),
2034 pool_.get(),
2035 BoundNetLog());
2036 EXPECT_EQ(ERR_IO_PENDING, rv);
2037 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2038
2039 // Request another socket from the same pool, buth with a higher priority.
2040 // The first request should now be stalled at the socket group limit.
2041 ClientSocketHandle handle2;
2042 TestCompletionCallback callback2;
2043 rv = handle2.Init("a",
2044 params_,
2045 HIGHEST,
2046 callback2.callback(),
2047 pool_.get(),
2048 BoundNetLog());
2049 EXPECT_EQ(ERR_IO_PENDING, rv);
2050 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2051 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
2052
2053 // The first handle should remain stalled as the other socket goes through
2054 // the connect process.
2055
2056 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2057 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2058 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle2.GetLoadState());
2059
2060 client_socket_factory_.SignalJob(0);
2061 EXPECT_EQ(OK, callback2.WaitForResult());
2062 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2063
2064 // Closing the second socket should cause the stalled handle to finally get a
2065 // ConnectJob.
2066 handle2.socket()->Disconnect();
2067 handle2.Reset();
2068 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2069}
2070
2071// Test GetLoadState in the case the per-pool limit is reached.
2072TEST_F(ClientSocketPoolBaseTest, LoadStatePoolLimit) {
2073 CreatePool(2, 2);
2074 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2075
2076 ClientSocketHandle handle;
2077 TestCompletionCallback callback;
2078 int rv = handle.Init("a",
2079 params_,
[email protected]bb1c4662013-11-14 00:00:072080 DEFAULT_PRIORITY,
[email protected]03b7c8c2013-07-20 04:38:552081 callback.callback(),
2082 pool_.get(),
2083 BoundNetLog());
2084 EXPECT_EQ(ERR_IO_PENDING, rv);
2085
2086 // Request for socket from another pool.
2087 ClientSocketHandle handle2;
2088 TestCompletionCallback callback2;
2089 rv = handle2.Init("b",
2090 params_,
[email protected]bb1c4662013-11-14 00:00:072091 DEFAULT_PRIORITY,
[email protected]03b7c8c2013-07-20 04:38:552092 callback2.callback(),
2093 pool_.get(),
2094 BoundNetLog());
2095 EXPECT_EQ(ERR_IO_PENDING, rv);
2096
2097 // Request another socket from the first pool. Request should stall at the
2098 // socket pool limit.
2099 ClientSocketHandle handle3;
2100 TestCompletionCallback callback3;
2101 rv = handle3.Init("a",
2102 params_,
[email protected]bb1c4662013-11-14 00:00:072103 DEFAULT_PRIORITY,
[email protected]03b7c8c2013-07-20 04:38:552104 callback2.callback(),
2105 pool_.get(),
2106 BoundNetLog());
2107 EXPECT_EQ(ERR_IO_PENDING, rv);
2108
2109 // The third handle should remain stalled as the other sockets in its group
2110 // goes through the connect process.
2111
2112 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2113 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2114
2115 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2116 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
2117 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2118
2119 client_socket_factory_.SignalJob(0);
2120 EXPECT_EQ(OK, callback.WaitForResult());
2121 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2122
2123 // Closing a socket should allow the stalled handle to finally get a new
2124 // ConnectJob.
2125 handle.socket()->Disconnect();
2126 handle.Reset();
2127 EXPECT_EQ(LOAD_STATE_CONNECTING, handle3.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:572128}
2129
[email protected]e772db3f2010-07-12 18:11:132130TEST_F(ClientSocketPoolBaseTest, Recoverable) {
2131 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2132 connect_job_factory_->set_job_type(TestConnectJob::kMockRecoverableJob);
2133
[email protected]2431756e2010-09-29 20:26:132134 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522135 TestCompletionCallback callback;
2136 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED,
[email protected]bb1c4662013-11-14 00:00:072137 handle.Init("a", params_, DEFAULT_PRIORITY, callback.callback(),
[email protected]6ecf2b92011-12-15 01:14:522138 pool_.get(), BoundNetLog()));
[email protected]2431756e2010-09-29 20:26:132139 EXPECT_TRUE(handle.is_initialized());
2140 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:132141}
2142
2143TEST_F(ClientSocketPoolBaseTest, AsyncRecoverable) {
2144 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2145
2146 connect_job_factory_->set_job_type(
2147 TestConnectJob::kMockPendingRecoverableJob);
[email protected]2431756e2010-09-29 20:26:132148 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522149 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132150 EXPECT_EQ(ERR_IO_PENDING,
2151 handle.Init("a",
2152 params_,
[email protected]bb1c4662013-11-14 00:00:072153 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522154 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132155 pool_.get(),
2156 BoundNetLog()));
2157 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2158 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, callback.WaitForResult());
2159 EXPECT_TRUE(handle.is_initialized());
2160 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:132161}
2162
[email protected]e60e47a2010-07-14 03:37:182163TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
2164 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2165 connect_job_factory_->set_job_type(
2166 TestConnectJob::kMockAdditionalErrorStateJob);
2167
[email protected]2431756e2010-09-29 20:26:132168 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522169 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132170 EXPECT_EQ(ERR_CONNECTION_FAILED,
2171 handle.Init("a",
2172 params_,
[email protected]bb1c4662013-11-14 00:00:072173 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522174 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132175 pool_.get(),
2176 BoundNetLog()));
2177 EXPECT_FALSE(handle.is_initialized());
2178 EXPECT_FALSE(handle.socket());
2179 EXPECT_TRUE(handle.is_ssl_error());
2180 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182181}
2182
2183TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
2184 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2185
2186 connect_job_factory_->set_job_type(
2187 TestConnectJob::kMockPendingAdditionalErrorStateJob);
[email protected]2431756e2010-09-29 20:26:132188 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522189 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132190 EXPECT_EQ(ERR_IO_PENDING,
2191 handle.Init("a",
2192 params_,
[email protected]bb1c4662013-11-14 00:00:072193 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522194 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132195 pool_.get(),
2196 BoundNetLog()));
2197 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2198 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
2199 EXPECT_FALSE(handle.is_initialized());
2200 EXPECT_FALSE(handle.socket());
2201 EXPECT_TRUE(handle.is_ssl_error());
2202 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182203}
2204
[email protected]e7b1c6d2c2012-05-05 00:54:032205// Make sure we can reuse sockets when the cleanup timer is disabled.
2206TEST_F(ClientSocketPoolBaseTest, DisableCleanupTimerReuse) {
[email protected]64770b7d2011-11-16 04:30:412207 // Disable cleanup timer.
2208 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(false);
2209
2210 CreatePoolWithIdleTimeouts(
2211 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
[email protected]e7b1c6d2c2012-05-05 00:54:032212 base::TimeDelta(), // Time out unused sockets immediately.
2213 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2214
2215 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2216
2217 ClientSocketHandle handle;
2218 TestCompletionCallback callback;
2219 int rv = handle.Init("a",
2220 params_,
2221 LOWEST,
2222 callback.callback(),
2223 pool_.get(),
2224 BoundNetLog());
2225 ASSERT_EQ(ERR_IO_PENDING, rv);
2226 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2227 ASSERT_EQ(OK, callback.WaitForResult());
2228
2229 // Use and release the socket.
2230 EXPECT_EQ(1, handle.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]034df0f32013-01-07 23:17:482231 TestLoadTimingInfoConnectedNotReused(handle);
[email protected]e7b1c6d2c2012-05-05 00:54:032232 handle.Reset();
2233
2234 // Should now have one idle socket.
2235 ASSERT_EQ(1, pool_->IdleSocketCount());
2236
2237 // Request a new socket. This should reuse the old socket and complete
2238 // synchronously.
vishal.b62985ca92015-04-17 08:45:512239 BoundTestNetLog log;
[email protected]e7b1c6d2c2012-05-05 00:54:032240 rv = handle.Init("a",
2241 params_,
2242 LOWEST,
2243 CompletionCallback(),
2244 pool_.get(),
2245 log.bound());
2246 ASSERT_EQ(OK, rv);
2247 EXPECT_TRUE(handle.is_reused());
[email protected]034df0f32013-01-07 23:17:482248 TestLoadTimingInfoConnectedReused(handle);
[email protected]e7b1c6d2c2012-05-05 00:54:032249
2250 ASSERT_TRUE(pool_->HasGroup("a"));
2251 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2252 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2253
mmenke43758e62015-05-04 21:09:462254 TestNetLogEntry::List entries;
[email protected]e7b1c6d2c2012-05-05 00:54:032255 log.GetEntries(&entries);
2256 EXPECT_TRUE(LogContainsEntryWithType(
2257 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
2258}
2259
2260// Make sure we cleanup old unused sockets when the cleanup timer is disabled.
2261TEST_F(ClientSocketPoolBaseTest, DisableCleanupTimerNoReuse) {
2262 // Disable cleanup timer.
2263 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(false);
2264
2265 CreatePoolWithIdleTimeouts(
2266 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2267 base::TimeDelta(), // Time out unused sockets immediately
2268 base::TimeDelta()); // Time out used sockets immediately
[email protected]64770b7d2011-11-16 04:30:412269
2270 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2271
2272 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2273
2274 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522275 TestCompletionCallback callback;
[email protected]64770b7d2011-11-16 04:30:412276 int rv = handle.Init("a",
2277 params_,
2278 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522279 callback.callback(),
[email protected]64770b7d2011-11-16 04:30:412280 pool_.get(),
2281 BoundNetLog());
[email protected]e7b1c6d2c2012-05-05 00:54:032282 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]64770b7d2011-11-16 04:30:412283 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2284
2285 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522286 TestCompletionCallback callback2;
[email protected]64770b7d2011-11-16 04:30:412287 rv = handle2.Init("a",
2288 params_,
2289 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522290 callback2.callback(),
[email protected]64770b7d2011-11-16 04:30:412291 pool_.get(),
2292 BoundNetLog());
[email protected]e7b1c6d2c2012-05-05 00:54:032293 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]64770b7d2011-11-16 04:30:412294 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
2295
2296 // Cancel one of the requests. Wait for the other, which will get the first
2297 // job. Release the socket. Run the loop again to make sure the second
2298 // socket is sitting idle and the first one is released (since ReleaseSocket()
2299 // just posts a DoReleaseSocket() task).
2300
2301 handle.Reset();
[email protected]e7b1c6d2c2012-05-05 00:54:032302 ASSERT_EQ(OK, callback2.WaitForResult());
[email protected]64770b7d2011-11-16 04:30:412303 // Use the socket.
[email protected]83039bb2011-12-09 18:43:552304 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]64770b7d2011-11-16 04:30:412305 handle2.Reset();
2306
[email protected]e7b1c6d2c2012-05-05 00:54:032307 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2308 // actually become pending until 2ms after they have been created. In order
2309 // to flush all tasks, we need to wait so that we know there are no
2310 // soon-to-be-pending tasks waiting.
2311 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
[email protected]2da659e2013-05-23 20:51:342312 base::MessageLoop::current()->RunUntilIdle();
[email protected]64770b7d2011-11-16 04:30:412313
[email protected]e7b1c6d2c2012-05-05 00:54:032314 // Both sockets should now be idle.
[email protected]64770b7d2011-11-16 04:30:412315 ASSERT_EQ(2, pool_->IdleSocketCount());
2316
2317 // Request a new socket. This should cleanup the unused and timed out ones.
2318 // A new socket will be created rather than reusing the idle one.
vishal.b62985ca92015-04-17 08:45:512319 BoundTestNetLog log;
[email protected]6ecf2b92011-12-15 01:14:522320 TestCompletionCallback callback3;
[email protected]64770b7d2011-11-16 04:30:412321 rv = handle.Init("a",
2322 params_,
2323 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522324 callback3.callback(),
[email protected]64770b7d2011-11-16 04:30:412325 pool_.get(),
2326 log.bound());
[email protected]e7b1c6d2c2012-05-05 00:54:032327 ASSERT_EQ(ERR_IO_PENDING, rv);
2328 ASSERT_EQ(OK, callback3.WaitForResult());
[email protected]64770b7d2011-11-16 04:30:412329 EXPECT_FALSE(handle.is_reused());
2330
[email protected]e7b1c6d2c2012-05-05 00:54:032331 // Make sure the idle socket is closed.
[email protected]64770b7d2011-11-16 04:30:412332 ASSERT_TRUE(pool_->HasGroup("a"));
2333 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2334 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2335
mmenke43758e62015-05-04 21:09:462336 TestNetLogEntry::List entries;
[email protected]64770b7d2011-11-16 04:30:412337 log.GetEntries(&entries);
2338 EXPECT_FALSE(LogContainsEntryWithType(
2339 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
2340}
2341
[email protected]4d3b05d2010-01-27 21:27:292342TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
[email protected]9bf28db2009-08-29 01:35:162343 CreatePoolWithIdleTimeouts(
2344 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2345 base::TimeDelta(), // Time out unused sockets immediately.
2346 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2347
2348 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2349
2350 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2351
[email protected]2431756e2010-09-29 20:26:132352 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522353 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132354 int rv = handle.Init("a",
2355 params_,
2356 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522357 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132358 pool_.get(),
2359 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:162360 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:132361 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
[email protected]9bf28db2009-08-29 01:35:162362
[email protected]2431756e2010-09-29 20:26:132363 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522364 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132365 rv = handle2.Init("a",
2366 params_,
2367 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522368 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132369 pool_.get(),
2370 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:162371 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:132372 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
[email protected]9bf28db2009-08-29 01:35:162373
2374 // Cancel one of the requests. Wait for the other, which will get the first
2375 // job. Release the socket. Run the loop again to make sure the second
2376 // socket is sitting idle and the first one is released (since ReleaseSocket()
2377 // just posts a DoReleaseSocket() task).
2378
[email protected]2431756e2010-09-29 20:26:132379 handle.Reset();
2380 EXPECT_EQ(OK, callback2.WaitForResult());
[email protected]0f873e82010-09-02 16:09:012381 // Use the socket.
[email protected]83039bb2011-12-09 18:43:552382 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]2431756e2010-09-29 20:26:132383 handle2.Reset();
[email protected]6b175382009-10-13 06:47:472384
2385 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2386 // actually become pending until 2ms after they have been created. In order
2387 // to flush all tasks, we need to wait so that we know there are no
2388 // soon-to-be-pending tasks waiting.
[email protected]26b9973962012-01-28 00:57:002389 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
[email protected]2da659e2013-05-23 20:51:342390 base::MessageLoop::current()->RunUntilIdle();
[email protected]9bf28db2009-08-29 01:35:162391
2392 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:042393
[email protected]9bf28db2009-08-29 01:35:162394 // Invoke the idle socket cleanup check. Only one socket should be left, the
2395 // used socket. Request it to make sure that it's used.
2396
2397 pool_->CleanupTimedOutIdleSockets();
vishal.b62985ca92015-04-17 08:45:512398 BoundTestNetLog log;
[email protected]2431756e2010-09-29 20:26:132399 rv = handle.Init("a",
2400 params_,
2401 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522402 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132403 pool_.get(),
2404 log.bound());
[email protected]9bf28db2009-08-29 01:35:162405 EXPECT_EQ(OK, rv);
[email protected]2431756e2010-09-29 20:26:132406 EXPECT_TRUE(handle.is_reused());
[email protected]b2fcd0e2010-12-01 15:19:402407
mmenke43758e62015-05-04 21:09:462408 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:402409 log.GetEntries(&entries);
[email protected]fd4fe0b2010-02-08 23:02:152410 EXPECT_TRUE(LogContainsEntryWithType(
[email protected]b2fcd0e2010-12-01 15:19:402411 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]9bf28db2009-08-29 01:35:162412}
2413
[email protected]2041cf342010-02-19 03:15:592414// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:162415// because of multiple releasing disconnected sockets.
2416TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
2417 CreatePoolWithIdleTimeouts(
2418 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2419 base::TimeDelta(), // Time out unused sockets immediately.
2420 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2421
2422 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2423
2424 // Startup 4 connect jobs. Two of them will be pending.
2425
[email protected]2431756e2010-09-29 20:26:132426 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522427 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132428 int rv = handle.Init("a",
2429 params_,
2430 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522431 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132432 pool_.get(),
2433 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162434 EXPECT_EQ(OK, rv);
2435
[email protected]2431756e2010-09-29 20:26:132436 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522437 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132438 rv = handle2.Init("a",
2439 params_,
2440 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522441 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132442 pool_.get(),
2443 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162444 EXPECT_EQ(OK, rv);
2445
[email protected]2431756e2010-09-29 20:26:132446 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:522447 TestCompletionCallback callback3;
[email protected]2431756e2010-09-29 20:26:132448 rv = handle3.Init("a",
2449 params_,
2450 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522451 callback3.callback(),
[email protected]2431756e2010-09-29 20:26:132452 pool_.get(),
2453 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162454 EXPECT_EQ(ERR_IO_PENDING, rv);
2455
[email protected]2431756e2010-09-29 20:26:132456 ClientSocketHandle handle4;
[email protected]6ecf2b92011-12-15 01:14:522457 TestCompletionCallback callback4;
[email protected]2431756e2010-09-29 20:26:132458 rv = handle4.Init("a",
2459 params_,
2460 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522461 callback4.callback(),
[email protected]2431756e2010-09-29 20:26:132462 pool_.get(),
2463 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162464 EXPECT_EQ(ERR_IO_PENDING, rv);
2465
2466 // Release two disconnected sockets.
2467
[email protected]2431756e2010-09-29 20:26:132468 handle.socket()->Disconnect();
2469 handle.Reset();
2470 handle2.socket()->Disconnect();
2471 handle2.Reset();
[email protected]4f2abec2010-02-03 18:10:162472
[email protected]2431756e2010-09-29 20:26:132473 EXPECT_EQ(OK, callback3.WaitForResult());
2474 EXPECT_FALSE(handle3.is_reused());
2475 EXPECT_EQ(OK, callback4.WaitForResult());
2476 EXPECT_FALSE(handle4.is_reused());
[email protected]4f2abec2010-02-03 18:10:162477}
2478
[email protected]d7027bb2010-05-10 18:58:542479// Regression test for http://crbug.com/42267.
2480// When DoReleaseSocket() is processed for one socket, it is blocked because the
2481// other stalled groups all have releasing sockets, so no progress can be made.
2482TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
2483 CreatePoolWithIdleTimeouts(
2484 4 /* socket limit */, 4 /* socket limit per group */,
2485 base::TimeDelta(), // Time out unused sockets immediately.
2486 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2487
2488 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2489
2490 // Max out the socket limit with 2 per group.
2491
[email protected]2431756e2010-09-29 20:26:132492 ClientSocketHandle handle_a[4];
[email protected]6ecf2b92011-12-15 01:14:522493 TestCompletionCallback callback_a[4];
[email protected]2431756e2010-09-29 20:26:132494 ClientSocketHandle handle_b[4];
[email protected]6ecf2b92011-12-15 01:14:522495 TestCompletionCallback callback_b[4];
[email protected]d7027bb2010-05-10 18:58:542496
2497 for (int i = 0; i < 2; ++i) {
[email protected]2431756e2010-09-29 20:26:132498 EXPECT_EQ(OK, handle_a[i].Init("a",
2499 params_,
2500 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522501 callback_a[i].callback(),
[email protected]2431756e2010-09-29 20:26:132502 pool_.get(),
2503 BoundNetLog()));
2504 EXPECT_EQ(OK, handle_b[i].Init("b",
2505 params_,
2506 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522507 callback_b[i].callback(),
[email protected]2431756e2010-09-29 20:26:132508 pool_.get(),
2509 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542510 }
[email protected]b89f7e42010-05-20 20:37:002511
[email protected]d7027bb2010-05-10 18:58:542512 // Make 4 pending requests, 2 per group.
2513
2514 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132515 EXPECT_EQ(ERR_IO_PENDING,
2516 handle_a[i].Init("a",
2517 params_,
2518 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522519 callback_a[i].callback(),
[email protected]2431756e2010-09-29 20:26:132520 pool_.get(),
2521 BoundNetLog()));
2522 EXPECT_EQ(ERR_IO_PENDING,
2523 handle_b[i].Init("b",
2524 params_,
2525 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522526 callback_b[i].callback(),
[email protected]2431756e2010-09-29 20:26:132527 pool_.get(),
2528 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542529 }
2530
2531 // Release b's socket first. The order is important, because in
2532 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2533 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2534 // first, which has a releasing socket, so it refuses to start up another
2535 // ConnectJob. So, we used to infinite loop on this.
[email protected]2431756e2010-09-29 20:26:132536 handle_b[0].socket()->Disconnect();
2537 handle_b[0].Reset();
2538 handle_a[0].socket()->Disconnect();
2539 handle_a[0].Reset();
[email protected]d7027bb2010-05-10 18:58:542540
2541 // Used to get stuck here.
[email protected]2da659e2013-05-23 20:51:342542 base::MessageLoop::current()->RunUntilIdle();
[email protected]d7027bb2010-05-10 18:58:542543
[email protected]2431756e2010-09-29 20:26:132544 handle_b[1].socket()->Disconnect();
2545 handle_b[1].Reset();
2546 handle_a[1].socket()->Disconnect();
2547 handle_a[1].Reset();
[email protected]d7027bb2010-05-10 18:58:542548
2549 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132550 EXPECT_EQ(OK, callback_b[i].WaitForResult());
2551 EXPECT_EQ(OK, callback_a[i].WaitForResult());
[email protected]d7027bb2010-05-10 18:58:542552 }
2553}
2554
[email protected]fd4fe0b2010-02-08 23:02:152555TEST_F(ClientSocketPoolBaseTest,
2556 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2557 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2558
2559 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2560
[email protected]bb1c4662013-11-14 00:00:072561 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
2562 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
2563 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
2564 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
[email protected]fd4fe0b2010-02-08 23:02:152565
[email protected]2431756e2010-09-29 20:26:132566 EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
2567 EXPECT_EQ(OK, (*requests())[1]->WaitForResult());
2568 EXPECT_EQ(2u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152569
2570 // Releases one connection.
[email protected]2431756e2010-09-29 20:26:132571 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2572 EXPECT_EQ(OK, (*requests())[2]->WaitForResult());
[email protected]fd4fe0b2010-02-08 23:02:152573
[email protected]2431756e2010-09-29 20:26:132574 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2575 EXPECT_EQ(OK, (*requests())[3]->WaitForResult());
2576 EXPECT_EQ(4u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152577
2578 EXPECT_EQ(1, GetOrderOfRequest(1));
2579 EXPECT_EQ(2, GetOrderOfRequest(2));
2580 EXPECT_EQ(3, GetOrderOfRequest(3));
2581 EXPECT_EQ(4, GetOrderOfRequest(4));
2582
2583 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:132584 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
[email protected]fd4fe0b2010-02-08 23:02:152585}
2586
[email protected]6ecf2b92011-12-15 01:14:522587class TestReleasingSocketRequest : public TestCompletionCallbackBase {
[email protected]4f1e4982010-03-02 18:31:042588 public:
[email protected]2431756e2010-09-29 20:26:132589 TestReleasingSocketRequest(TestClientSocketPool* pool,
2590 int expected_result,
[email protected]e60e47a2010-07-14 03:37:182591 bool reset_releasing_handle)
2592 : pool_(pool),
2593 expected_result_(expected_result),
[email protected]6ecf2b92011-12-15 01:14:522594 reset_releasing_handle_(reset_releasing_handle),
[email protected]aa249b52013-04-30 01:04:322595 callback_(base::Bind(&TestReleasingSocketRequest::OnComplete,
2596 base::Unretained(this))) {
[email protected]6ecf2b92011-12-15 01:14:522597 }
2598
dchengb03027d2014-10-21 12:00:202599 ~TestReleasingSocketRequest() override {}
[email protected]4f1e4982010-03-02 18:31:042600
2601 ClientSocketHandle* handle() { return &handle_; }
2602
[email protected]6ecf2b92011-12-15 01:14:522603 const CompletionCallback& callback() const { return callback_; }
[email protected]4f1e4982010-03-02 18:31:042604
2605 private:
[email protected]6ecf2b92011-12-15 01:14:522606 void OnComplete(int result) {
2607 SetResult(result);
2608 if (reset_releasing_handle_)
2609 handle_.Reset();
2610
[email protected]bb1c4662013-11-14 00:00:072611 scoped_refptr<TestSocketParams> con_params(
2612 new TestSocketParams(false /* ignore_limits */));
[email protected]6ecf2b92011-12-15 01:14:522613 EXPECT_EQ(expected_result_,
[email protected]bb1c4662013-11-14 00:00:072614 handle2_.Init("a", con_params, DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522615 callback2_.callback(), pool_, BoundNetLog()));
2616 }
2617
[email protected]2431756e2010-09-29 20:26:132618 TestClientSocketPool* const pool_;
[email protected]e60e47a2010-07-14 03:37:182619 int expected_result_;
2620 bool reset_releasing_handle_;
[email protected]4f1e4982010-03-02 18:31:042621 ClientSocketHandle handle_;
2622 ClientSocketHandle handle2_;
[email protected]6ecf2b92011-12-15 01:14:522623 CompletionCallback callback_;
2624 TestCompletionCallback callback2_;
[email protected]4f1e4982010-03-02 18:31:042625};
2626
[email protected]e60e47a2010-07-14 03:37:182627
2628TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2629 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2630
[email protected]bb1c4662013-11-14 00:00:072631 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
2632 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
2633 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
[email protected]e60e47a2010-07-14 03:37:182634
[email protected]2431756e2010-09-29 20:26:132635 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]e60e47a2010-07-14 03:37:182636 client_socket_factory_.allocation_count());
2637
2638 connect_job_factory_->set_job_type(
2639 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2640 TestReleasingSocketRequest req(pool_.get(), OK, false);
[email protected]2431756e2010-09-29 20:26:132641 EXPECT_EQ(ERR_IO_PENDING,
[email protected]bb1c4662013-11-14 00:00:072642 req.handle()->Init("a", params_, DEFAULT_PRIORITY, req.callback(),
[email protected]6ecf2b92011-12-15 01:14:522643 pool_.get(), BoundNetLog()));
[email protected]e60e47a2010-07-14 03:37:182644 // The next job should complete synchronously
2645 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2646
2647 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
2648 EXPECT_FALSE(req.handle()->is_initialized());
2649 EXPECT_FALSE(req.handle()->socket());
2650 EXPECT_TRUE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:432651 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182652}
2653
[email protected]b6501d3d2010-06-03 23:53:342654// http://crbug.com/44724 regression test.
2655// We start releasing the pool when we flush on network change. When that
2656// happens, the only active references are in the ClientSocketHandles. When a
2657// ConnectJob completes and calls back into the last ClientSocketHandle, that
2658// callback can release the last reference and delete the pool. After the
2659// callback finishes, we go back to the stack frame within the now-deleted pool.
2660// Executing any code that refers to members of the now-deleted pool can cause
2661// crashes.
2662TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2663 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2664 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2665
2666 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522667 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132668 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2669 params_,
[email protected]bb1c4662013-11-14 00:00:072670 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522671 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132672 pool_.get(),
2673 BoundNetLog()));
[email protected]b6501d3d2010-06-03 23:53:342674
[email protected]7af985a2012-12-14 22:40:422675 pool_->FlushWithError(ERR_NETWORK_CHANGED);
[email protected]b6501d3d2010-06-03 23:53:342676
2677 // We'll call back into this now.
2678 callback.WaitForResult();
2679}
2680
[email protected]a7e38572010-06-07 18:22:242681TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2682 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2683 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2684
2685 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522686 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132687 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2688 params_,
[email protected]bb1c4662013-11-14 00:00:072689 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522690 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132691 pool_.get(),
2692 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242693 EXPECT_EQ(OK, callback.WaitForResult());
2694 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2695
[email protected]7af985a2012-12-14 22:40:422696 pool_->FlushWithError(ERR_NETWORK_CHANGED);
[email protected]a7e38572010-06-07 18:22:242697
2698 handle.Reset();
[email protected]2da659e2013-05-23 20:51:342699 base::MessageLoop::current()->RunUntilIdle();
[email protected]a7e38572010-06-07 18:22:242700
[email protected]2431756e2010-09-29 20:26:132701 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2702 params_,
[email protected]bb1c4662013-11-14 00:00:072703 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522704 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132705 pool_.get(),
2706 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242707 EXPECT_EQ(OK, callback.WaitForResult());
2708 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2709}
2710
[email protected]6ecf2b92011-12-15 01:14:522711class ConnectWithinCallback : public TestCompletionCallbackBase {
[email protected]06f92462010-08-31 19:24:142712 public:
2713 ConnectWithinCallback(
2714 const std::string& group_name,
2715 const scoped_refptr<TestSocketParams>& params,
[email protected]2431756e2010-09-29 20:26:132716 TestClientSocketPool* pool)
[email protected]6ecf2b92011-12-15 01:14:522717 : group_name_(group_name),
2718 params_(params),
2719 pool_(pool),
[email protected]aa249b52013-04-30 01:04:322720 callback_(base::Bind(&ConnectWithinCallback::OnComplete,
2721 base::Unretained(this))) {
[email protected]06f92462010-08-31 19:24:142722 }
2723
dchengb03027d2014-10-21 12:00:202724 ~ConnectWithinCallback() override {}
[email protected]06f92462010-08-31 19:24:142725
2726 int WaitForNestedResult() {
2727 return nested_callback_.WaitForResult();
2728 }
2729
[email protected]6ecf2b92011-12-15 01:14:522730 const CompletionCallback& callback() const { return callback_; }
2731
[email protected]06f92462010-08-31 19:24:142732 private:
[email protected]6ecf2b92011-12-15 01:14:522733 void OnComplete(int result) {
2734 SetResult(result);
2735 EXPECT_EQ(ERR_IO_PENDING,
2736 handle_.Init(group_name_,
2737 params_,
[email protected]bb1c4662013-11-14 00:00:072738 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522739 nested_callback_.callback(),
2740 pool_,
2741 BoundNetLog()));
2742 }
2743
[email protected]06f92462010-08-31 19:24:142744 const std::string group_name_;
2745 const scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:132746 TestClientSocketPool* const pool_;
[email protected]06f92462010-08-31 19:24:142747 ClientSocketHandle handle_;
[email protected]6ecf2b92011-12-15 01:14:522748 CompletionCallback callback_;
2749 TestCompletionCallback nested_callback_;
2750
2751 DISALLOW_COPY_AND_ASSIGN(ConnectWithinCallback);
[email protected]06f92462010-08-31 19:24:142752};
2753
2754TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
2755 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2756
2757 // First job will be waiting until it gets aborted.
2758 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2759
2760 ClientSocketHandle handle;
[email protected]2431756e2010-09-29 20:26:132761 ConnectWithinCallback callback("a", params_, pool_.get());
2762 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2763 params_,
[email protected]bb1c4662013-11-14 00:00:072764 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522765 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132766 pool_.get(),
2767 BoundNetLog()));
[email protected]06f92462010-08-31 19:24:142768
2769 // Second job will be started during the first callback, and will
2770 // asynchronously complete with OK.
2771 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]7af985a2012-12-14 22:40:422772 pool_->FlushWithError(ERR_NETWORK_CHANGED);
2773 EXPECT_EQ(ERR_NETWORK_CHANGED, callback.WaitForResult());
[email protected]06f92462010-08-31 19:24:142774 EXPECT_EQ(OK, callback.WaitForNestedResult());
2775}
2776
[email protected]25eea382010-07-10 23:55:262777// Cancel a pending socket request while we're at max sockets,
2778// and verify that the backup socket firing doesn't cause a crash.
2779TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
2780 // Max 4 sockets globally, max 4 sockets per group.
2781 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
[email protected]06d94042010-08-25 01:45:222782 pool_->EnableConnectBackupJobs();
[email protected]25eea382010-07-10 23:55:262783
[email protected]4baaf9d2010-08-31 15:15:442784 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2785 // timer.
[email protected]25eea382010-07-10 23:55:262786 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2787 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522788 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132789 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2790 params_,
[email protected]bb1c4662013-11-14 00:00:072791 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522792 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132793 pool_.get(),
2794 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262795
2796 // Start (MaxSockets - 1) connected sockets to reach max sockets.
2797 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2798 ClientSocketHandle handles[kDefaultMaxSockets];
2799 for (int i = 1; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:522800 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132801 EXPECT_EQ(OK, handles[i].Init("bar",
2802 params_,
[email protected]bb1c4662013-11-14 00:00:072803 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522804 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132805 pool_.get(),
2806 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262807 }
2808
[email protected]2da659e2013-05-23 20:51:342809 base::MessageLoop::current()->RunUntilIdle();
[email protected]25eea382010-07-10 23:55:262810
2811 // Cancel the pending request.
2812 handle.Reset();
2813
2814 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]26b9973962012-01-28 00:57:002815 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2816 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]25eea382010-07-10 23:55:262817
[email protected]2da659e2013-05-23 20:51:342818 base::MessageLoop::current()->RunUntilIdle();
[email protected]25eea382010-07-10 23:55:262819 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
2820}
2821
[email protected]3f00be82010-09-27 19:50:022822TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
[email protected]4baaf9d2010-08-31 15:15:442823 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2824 pool_->EnableConnectBackupJobs();
2825
2826 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2827 // timer.
2828 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2829 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522830 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132831 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2832 params_,
[email protected]bb1c4662013-11-14 00:00:072833 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522834 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132835 pool_.get(),
2836 BoundNetLog()));
[email protected]4baaf9d2010-08-31 15:15:442837 ASSERT_TRUE(pool_->HasGroup("bar"));
2838 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
[email protected]8159a1c2012-06-07 00:00:102839 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("bar"));
[email protected]4baaf9d2010-08-31 15:15:442840
2841 // Cancel the socket request. This should cancel the backup timer. Wait for
2842 // the backup time to see if it indeed got canceled.
2843 handle.Reset();
2844 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]26b9973962012-01-28 00:57:002845 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2846 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]2da659e2013-05-23 20:51:342847 base::MessageLoop::current()->RunUntilIdle();
[email protected]4baaf9d2010-08-31 15:15:442848 ASSERT_TRUE(pool_->HasGroup("bar"));
2849 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2850}
2851
[email protected]3f00be82010-09-27 19:50:022852TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
2853 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2854 pool_->EnableConnectBackupJobs();
2855
2856 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2857 // timer.
2858 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2859 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522860 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132861 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2862 params_,
[email protected]bb1c4662013-11-14 00:00:072863 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522864 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132865 pool_.get(),
2866 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022867 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2868 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522869 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132870 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("bar",
2871 params_,
[email protected]bb1c4662013-11-14 00:00:072872 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522873 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132874 pool_.get(),
2875 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022876 ASSERT_TRUE(pool_->HasGroup("bar"));
2877 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("bar"));
2878
2879 // Cancel request 1 and then complete request 2. With the requests finished,
2880 // the backup timer should be cancelled.
2881 handle.Reset();
2882 EXPECT_EQ(OK, callback2.WaitForResult());
2883 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]26b9973962012-01-28 00:57:002884 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2885 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]2da659e2013-05-23 20:51:342886 base::MessageLoop::current()->RunUntilIdle();
[email protected]3f00be82010-09-27 19:50:022887}
2888
[email protected]eb5a99382010-07-11 03:18:262889// Test delayed socket binding for the case where we have two connects,
2890// and while one is waiting on a connect, the other frees up.
2891// The socket waiting on a connect should switch immediately to the freed
2892// up socket.
2893TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
2894 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2895 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2896
2897 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522898 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132899 EXPECT_EQ(ERR_IO_PENDING,
2900 handle1.Init("a",
2901 params_,
[email protected]bb1c4662013-11-14 00:00:072902 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522903 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132904 pool_.get(),
2905 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262906 EXPECT_EQ(OK, callback.WaitForResult());
2907
2908 // No idle sockets, no pending jobs.
2909 EXPECT_EQ(0, pool_->IdleSocketCount());
2910 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2911
2912 // Create a second socket to the same host, but this one will wait.
2913 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2914 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132915 EXPECT_EQ(ERR_IO_PENDING,
2916 handle2.Init("a",
2917 params_,
[email protected]bb1c4662013-11-14 00:00:072918 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522919 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132920 pool_.get(),
2921 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262922 // No idle sockets, and one connecting job.
2923 EXPECT_EQ(0, pool_->IdleSocketCount());
2924 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2925
2926 // Return the first handle to the pool. This will initiate the delayed
2927 // binding.
2928 handle1.Reset();
2929
[email protected]2da659e2013-05-23 20:51:342930 base::MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262931
2932 // Still no idle sockets, still one pending connect job.
2933 EXPECT_EQ(0, pool_->IdleSocketCount());
2934 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2935
2936 // The second socket connected, even though it was a Waiting Job.
2937 EXPECT_EQ(OK, callback.WaitForResult());
2938
2939 // And we can see there is still one job waiting.
2940 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2941
2942 // Finally, signal the waiting Connect.
2943 client_socket_factory_.SignalJobs();
2944 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2945
[email protected]2da659e2013-05-23 20:51:342946 base::MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262947}
2948
2949// Test delayed socket binding when a group is at capacity and one
2950// of the group's sockets frees up.
2951TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
2952 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2953 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2954
2955 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522956 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132957 EXPECT_EQ(ERR_IO_PENDING,
2958 handle1.Init("a",
2959 params_,
[email protected]bb1c4662013-11-14 00:00:072960 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522961 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132962 pool_.get(),
2963 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262964 EXPECT_EQ(OK, callback.WaitForResult());
2965
2966 // No idle sockets, no pending jobs.
2967 EXPECT_EQ(0, pool_->IdleSocketCount());
2968 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2969
2970 // Create a second socket to the same host, but this one will wait.
2971 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2972 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132973 EXPECT_EQ(ERR_IO_PENDING,
2974 handle2.Init("a",
2975 params_,
[email protected]bb1c4662013-11-14 00:00:072976 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522977 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132978 pool_.get(),
2979 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262980 // No idle sockets, and one connecting job.
2981 EXPECT_EQ(0, pool_->IdleSocketCount());
2982 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2983
2984 // Return the first handle to the pool. This will initiate the delayed
2985 // binding.
2986 handle1.Reset();
2987
[email protected]2da659e2013-05-23 20:51:342988 base::MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262989
2990 // Still no idle sockets, still one pending connect job.
2991 EXPECT_EQ(0, pool_->IdleSocketCount());
2992 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2993
2994 // The second socket connected, even though it was a Waiting Job.
2995 EXPECT_EQ(OK, callback.WaitForResult());
2996
2997 // And we can see there is still one job waiting.
2998 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2999
3000 // Finally, signal the waiting Connect.
3001 client_socket_factory_.SignalJobs();
3002 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3003
[email protected]2da659e2013-05-23 20:51:343004 base::MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263005}
3006
3007// Test out the case where we have one socket connected, one
3008// connecting, when the first socket finishes and goes idle.
[email protected]2abfe90a2010-08-25 17:49:513009// Although the second connection is pending, the second request
[email protected]eb5a99382010-07-11 03:18:263010// should complete, by taking the first socket's idle socket.
3011TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
3012 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3013 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3014
3015 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523016 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:133017 EXPECT_EQ(ERR_IO_PENDING,
3018 handle1.Init("a",
3019 params_,
[email protected]bb1c4662013-11-14 00:00:073020 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523021 callback.callback(),
[email protected]2431756e2010-09-29 20:26:133022 pool_.get(),
3023 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:263024 EXPECT_EQ(OK, callback.WaitForResult());
3025
3026 // No idle sockets, no pending jobs.
3027 EXPECT_EQ(0, pool_->IdleSocketCount());
3028 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3029
3030 // Create a second socket to the same host, but this one will wait.
3031 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3032 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:133033 EXPECT_EQ(ERR_IO_PENDING,
3034 handle2.Init("a",
3035 params_,
[email protected]bb1c4662013-11-14 00:00:073036 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523037 callback.callback(),
[email protected]2431756e2010-09-29 20:26:133038 pool_.get(),
3039 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:263040 // No idle sockets, and one connecting job.
3041 EXPECT_EQ(0, pool_->IdleSocketCount());
3042 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3043
3044 // Return the first handle to the pool. This will initiate the delayed
3045 // binding.
3046 handle1.Reset();
3047
[email protected]2da659e2013-05-23 20:51:343048 base::MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263049
3050 // Still no idle sockets, still one pending connect job.
3051 EXPECT_EQ(0, pool_->IdleSocketCount());
3052 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3053
3054 // The second socket connected, even though it was a Waiting Job.
3055 EXPECT_EQ(OK, callback.WaitForResult());
3056
3057 // And we can see there is still one job waiting.
3058 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3059
3060 // Finally, signal the waiting Connect.
3061 client_socket_factory_.SignalJobs();
3062 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3063
[email protected]2da659e2013-05-23 20:51:343064 base::MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263065}
3066
[email protected]2abfe90a2010-08-25 17:49:513067// Cover the case where on an available socket slot, we have one pending
3068// request that completes synchronously, thereby making the Group empty.
3069TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
3070 const int kUnlimitedSockets = 100;
3071 const int kOneSocketPerGroup = 1;
3072 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
3073
3074 // Make the first request asynchronous fail.
3075 // This will free up a socket slot later.
3076 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
3077
3078 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523079 TestCompletionCallback callback1;
[email protected]2431756e2010-09-29 20:26:133080 EXPECT_EQ(ERR_IO_PENDING,
3081 handle1.Init("a",
3082 params_,
[email protected]bb1c4662013-11-14 00:00:073083 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523084 callback1.callback(),
[email protected]2431756e2010-09-29 20:26:133085 pool_.get(),
3086 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:513087 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3088
3089 // Make the second request synchronously fail. This should make the Group
3090 // empty.
3091 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3092 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523093 TestCompletionCallback callback2;
[email protected]2abfe90a2010-08-25 17:49:513094 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
3095 // when created.
[email protected]2431756e2010-09-29 20:26:133096 EXPECT_EQ(ERR_IO_PENDING,
3097 handle2.Init("a",
3098 params_,
[email protected]bb1c4662013-11-14 00:00:073099 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523100 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:133101 pool_.get(),
3102 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:513103
3104 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3105
3106 EXPECT_EQ(ERR_CONNECTION_FAILED, callback1.WaitForResult());
3107 EXPECT_EQ(ERR_CONNECTION_FAILED, callback2.WaitForResult());
3108 EXPECT_FALSE(pool_->HasGroup("a"));
3109}
3110
[email protected]e1b54dc2010-10-06 21:27:223111TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
3112 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3113
3114 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3115
3116 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523117 TestCompletionCallback callback1;
[email protected]e1b54dc2010-10-06 21:27:223118 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3119 params_,
[email protected]bb1c4662013-11-14 00:00:073120 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523121 callback1.callback(),
[email protected]e1b54dc2010-10-06 21:27:223122 pool_.get(),
3123 BoundNetLog()));
3124
3125 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523126 TestCompletionCallback callback2;
[email protected]e1b54dc2010-10-06 21:27:223127 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3128 params_,
[email protected]bb1c4662013-11-14 00:00:073129 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523130 callback2.callback(),
[email protected]e1b54dc2010-10-06 21:27:223131 pool_.get(),
3132 BoundNetLog()));
3133 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:523134 TestCompletionCallback callback3;
[email protected]e1b54dc2010-10-06 21:27:223135 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
3136 params_,
[email protected]bb1c4662013-11-14 00:00:073137 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523138 callback3.callback(),
[email protected]e1b54dc2010-10-06 21:27:223139 pool_.get(),
3140 BoundNetLog()));
3141
3142 EXPECT_EQ(OK, callback1.WaitForResult());
3143 EXPECT_EQ(OK, callback2.WaitForResult());
3144 EXPECT_EQ(OK, callback3.WaitForResult());
3145
3146 // Use the socket.
[email protected]83039bb2011-12-09 18:43:553147 EXPECT_EQ(1, handle1.socket()->Write(NULL, 1, CompletionCallback()));
3148 EXPECT_EQ(1, handle3.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]e1b54dc2010-10-06 21:27:223149
3150 handle1.Reset();
3151 handle2.Reset();
3152 handle3.Reset();
3153
3154 EXPECT_EQ(OK, handle1.Init("a",
3155 params_,
[email protected]bb1c4662013-11-14 00:00:073156 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523157 callback1.callback(),
[email protected]e1b54dc2010-10-06 21:27:223158 pool_.get(),
3159 BoundNetLog()));
3160 EXPECT_EQ(OK, handle2.Init("a",
3161 params_,
[email protected]bb1c4662013-11-14 00:00:073162 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523163 callback2.callback(),
[email protected]e1b54dc2010-10-06 21:27:223164 pool_.get(),
3165 BoundNetLog()));
3166 EXPECT_EQ(OK, handle3.Init("a",
3167 params_,
[email protected]bb1c4662013-11-14 00:00:073168 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523169 callback3.callback(),
[email protected]e1b54dc2010-10-06 21:27:223170 pool_.get(),
3171 BoundNetLog()));
3172
3173 EXPECT_TRUE(handle1.socket()->WasEverUsed());
3174 EXPECT_TRUE(handle2.socket()->WasEverUsed());
3175 EXPECT_FALSE(handle3.socket()->WasEverUsed());
3176}
3177
[email protected]2c2bef152010-10-13 00:55:033178TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
3179 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3180 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3181
3182 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3183
3184 ASSERT_TRUE(pool_->HasGroup("a"));
3185 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103186 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033187 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3188
3189 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523190 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033191 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3192 params_,
[email protected]bb1c4662013-11-14 00:00:073193 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523194 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033195 pool_.get(),
3196 BoundNetLog()));
3197
3198 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523199 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033200 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3201 params_,
[email protected]bb1c4662013-11-14 00:00:073202 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523203 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033204 pool_.get(),
3205 BoundNetLog()));
3206
3207 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103208 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033209 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3210
3211 EXPECT_EQ(OK, callback1.WaitForResult());
3212 EXPECT_EQ(OK, callback2.WaitForResult());
3213 handle1.Reset();
3214 handle2.Reset();
3215
3216 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103217 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033218 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3219}
3220
3221TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
3222 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3223 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3224
3225 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523226 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033227 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3228 params_,
[email protected]bb1c4662013-11-14 00:00:073229 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523230 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033231 pool_.get(),
3232 BoundNetLog()));
3233
3234 ASSERT_TRUE(pool_->HasGroup("a"));
3235 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103236 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033237 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3238
3239 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3240
3241 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103242 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033243 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3244
3245 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523246 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033247 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3248 params_,
[email protected]bb1c4662013-11-14 00:00:073249 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523250 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033251 pool_.get(),
3252 BoundNetLog()));
3253
3254 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103255 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033256 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3257
3258 EXPECT_EQ(OK, callback1.WaitForResult());
3259 EXPECT_EQ(OK, callback2.WaitForResult());
3260 handle1.Reset();
3261 handle2.Reset();
3262
3263 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103264 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033265 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3266}
3267
3268TEST_F(ClientSocketPoolBaseTest,
3269 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
3270 CreatePool(4, 4);
3271 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3272
3273 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523274 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033275 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3276 params_,
[email protected]bb1c4662013-11-14 00:00:073277 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523278 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033279 pool_.get(),
3280 BoundNetLog()));
3281
3282 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523283 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033284 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3285 params_,
[email protected]bb1c4662013-11-14 00:00:073286 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523287 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033288 pool_.get(),
3289 BoundNetLog()));
3290
3291 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:523292 TestCompletionCallback callback3;
[email protected]2c2bef152010-10-13 00:55:033293 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
3294 params_,
[email protected]bb1c4662013-11-14 00:00:073295 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523296 callback3.callback(),
[email protected]2c2bef152010-10-13 00:55:033297 pool_.get(),
3298 BoundNetLog()));
3299
3300 ASSERT_TRUE(pool_->HasGroup("a"));
3301 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103302 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033303 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3304
3305 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3306
3307 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103308 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033309 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3310
3311 EXPECT_EQ(OK, callback1.WaitForResult());
3312 EXPECT_EQ(OK, callback2.WaitForResult());
3313 EXPECT_EQ(OK, callback3.WaitForResult());
3314 handle1.Reset();
3315 handle2.Reset();
3316 handle3.Reset();
3317
3318 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103319 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033320 EXPECT_EQ(3, pool_->IdleSocketCountInGroup("a"));
3321}
3322
3323TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
3324 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3325 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3326
3327 ASSERT_FALSE(pool_->HasGroup("a"));
3328
3329 pool_->RequestSockets("a", &params_, kDefaultMaxSockets,
3330 BoundNetLog());
3331
3332 ASSERT_TRUE(pool_->HasGroup("a"));
3333 EXPECT_EQ(kDefaultMaxSockets, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103334 EXPECT_EQ(kDefaultMaxSockets, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033335
3336 ASSERT_FALSE(pool_->HasGroup("b"));
3337
3338 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
3339 BoundNetLog());
3340
3341 ASSERT_FALSE(pool_->HasGroup("b"));
3342}
3343
3344TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
3345 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3346 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3347
3348 ASSERT_FALSE(pool_->HasGroup("a"));
3349
3350 pool_->RequestSockets("a", &params_, kDefaultMaxSockets - 1,
3351 BoundNetLog());
3352
3353 ASSERT_TRUE(pool_->HasGroup("a"));
3354 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103355 EXPECT_EQ(kDefaultMaxSockets - 1,
3356 pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]51fdc7c2012-04-10 19:19:483357 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033358
3359 ASSERT_FALSE(pool_->HasGroup("b"));
3360
3361 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
3362 BoundNetLog());
3363
3364 ASSERT_TRUE(pool_->HasGroup("b"));
3365 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("b"));
[email protected]51fdc7c2012-04-10 19:19:483366 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033367}
3368
3369TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
3370 CreatePool(4, 4);
3371 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3372
3373 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523374 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033375 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3376 params_,
[email protected]bb1c4662013-11-14 00:00:073377 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523378 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033379 pool_.get(),
3380 BoundNetLog()));
3381 ASSERT_EQ(OK, callback1.WaitForResult());
3382 handle1.Reset();
3383
3384 ASSERT_TRUE(pool_->HasGroup("a"));
3385 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103386 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033387 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3388
3389 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3390
3391 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103392 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033393 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3394}
3395
3396TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
3397 CreatePool(4, 4);
3398 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3399
3400 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523401 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033402 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3403 params_,
[email protected]bb1c4662013-11-14 00:00:073404 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523405 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033406 pool_.get(),
3407 BoundNetLog()));
3408 ASSERT_EQ(OK, callback1.WaitForResult());
3409
3410 ASSERT_TRUE(pool_->HasGroup("a"));
3411 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103412 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033413 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3414 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3415
3416 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3417
3418 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103419 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033420 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3421 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3422}
3423
3424TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
3425 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3426 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3427
3428 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3429 BoundNetLog());
3430
3431 ASSERT_TRUE(pool_->HasGroup("a"));
3432 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103433 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033434 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("a"));
3435
3436 pool_->RequestSockets("b", &params_, kDefaultMaxSocketsPerGroup,
3437 BoundNetLog());
3438
3439 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103440 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]2c2bef152010-10-13 00:55:033441 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("b"));
3442}
3443
[email protected]3c819f522010-12-02 02:03:123444TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
3445 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3446 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3447
3448 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3449 BoundNetLog());
3450
3451 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]fd2e53e2011-01-14 20:40:523452
3453 connect_job_factory_->set_job_type(
3454 TestConnectJob::kMockAdditionalErrorStateJob);
3455 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3456 BoundNetLog());
3457
3458 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]3c819f522010-12-02 02:03:123459}
3460
[email protected]8159a1c2012-06-07 00:00:103461TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
[email protected]2c2bef152010-10-13 00:55:033462 CreatePool(4, 4);
3463 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3464
3465 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3466
3467 ASSERT_TRUE(pool_->HasGroup("a"));
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 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3473 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103474 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033475 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3476
3477 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523478 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033479 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3480 params_,
[email protected]bb1c4662013-11-14 00:00:073481 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523482 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033483 pool_.get(),
3484 BoundNetLog()));
3485 ASSERT_EQ(OK, callback1.WaitForResult());
3486
3487 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523488 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033489 int rv = handle2.Init("a",
3490 params_,
[email protected]bb1c4662013-11-14 00:00:073491 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523492 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033493 pool_.get(),
3494 BoundNetLog());
3495 if (rv != OK) {
3496 EXPECT_EQ(ERR_IO_PENDING, rv);
3497 EXPECT_EQ(OK, callback2.WaitForResult());
3498 }
3499
[email protected]8159a1c2012-06-07 00:00:103500 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3501 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3502 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("a"));
3503 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3504
[email protected]2c2bef152010-10-13 00:55:033505 handle1.Reset();
3506 handle2.Reset();
3507
[email protected]8159a1c2012-06-07 00:00:103508 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3509 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033510 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3511
3512 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3513 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103514 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033515 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3516}
3517
3518TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
3519 CreatePool(4, 4);
3520 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3521
3522 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3523
3524 ASSERT_TRUE(pool_->HasGroup("a"));
3525 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103526 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033527 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3528
3529 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3530 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103531 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033532 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3533
3534 pool_->RequestSockets("a", &params_, 3, 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 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3540 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103541 EXPECT_EQ(3, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033542 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3543}
3544
3545TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
3546 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3547 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3548
3549 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3550
3551 ASSERT_TRUE(pool_->HasGroup("a"));
3552 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103553 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033554 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3555
3556 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523557 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033558 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3559 params_,
[email protected]bb1c4662013-11-14 00:00:073560 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523561 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033562 pool_.get(),
3563 BoundNetLog()));
3564
3565 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103566 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033567 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3568
3569 ASSERT_EQ(OK, callback1.WaitForResult());
3570
[email protected]0dc88b32014-03-26 20:12:283571 // Make sure if a preconnected socket is not fully connected when a request
[email protected]034df0f32013-01-07 23:17:483572 // starts, it has a connect start time.
3573 TestLoadTimingInfoConnectedNotReused(handle1);
[email protected]2c2bef152010-10-13 00:55:033574 handle1.Reset();
3575
3576 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3577}
3578
[email protected]034df0f32013-01-07 23:17:483579// Checks that fully connected preconnect jobs have no connect times, and are
3580// marked as reused.
3581TEST_F(ClientSocketPoolBaseTest, ConnectedPreconnectJobsHaveNoConnectTimes) {
3582 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3583 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3584 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3585
3586 ASSERT_TRUE(pool_->HasGroup("a"));
3587 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3588 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3589 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3590
3591 ClientSocketHandle handle;
3592 TestCompletionCallback callback;
3593 EXPECT_EQ(OK, handle.Init("a",
3594 params_,
[email protected]bb1c4662013-11-14 00:00:073595 DEFAULT_PRIORITY,
[email protected]034df0f32013-01-07 23:17:483596 callback.callback(),
3597 pool_.get(),
3598 BoundNetLog()));
3599
3600 // Make sure the idle socket was used.
3601 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3602
3603 TestLoadTimingInfoConnectedReused(handle);
3604 handle.Reset();
3605 TestLoadTimingInfoNotConnected(handle);
3606}
3607
[email protected]dcbe168a2010-12-02 03:14:463608// http://crbug.com/64940 regression test.
3609TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
3610 const int kMaxTotalSockets = 3;
3611 const int kMaxSocketsPerGroup = 2;
3612 CreatePool(kMaxTotalSockets, kMaxSocketsPerGroup);
3613 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3614
3615 // Note that group name ordering matters here. "a" comes before "b", so
3616 // CloseOneIdleSocket() will try to close "a"'s idle socket.
3617
3618 // Set up one idle socket in "a".
3619 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523620 TestCompletionCallback callback1;
[email protected]dcbe168a2010-12-02 03:14:463621 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3622 params_,
[email protected]bb1c4662013-11-14 00:00:073623 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523624 callback1.callback(),
[email protected]dcbe168a2010-12-02 03:14:463625 pool_.get(),
3626 BoundNetLog()));
3627
3628 ASSERT_EQ(OK, callback1.WaitForResult());
3629 handle1.Reset();
3630 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3631
3632 // Set up two active sockets in "b".
3633 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523634 TestCompletionCallback callback2;
[email protected]dcbe168a2010-12-02 03:14:463635 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("b",
3636 params_,
[email protected]bb1c4662013-11-14 00:00:073637 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523638 callback1.callback(),
[email protected]dcbe168a2010-12-02 03:14:463639 pool_.get(),
3640 BoundNetLog()));
3641 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("b",
3642 params_,
[email protected]bb1c4662013-11-14 00:00:073643 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523644 callback2.callback(),
[email protected]dcbe168a2010-12-02 03:14:463645 pool_.get(),
3646 BoundNetLog()));
3647
3648 ASSERT_EQ(OK, callback1.WaitForResult());
3649 ASSERT_EQ(OK, callback2.WaitForResult());
3650 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103651 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463652 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3653
3654 // Now we have 1 idle socket in "a" and 2 active sockets in "b". This means
3655 // we've maxed out on sockets, since we set |kMaxTotalSockets| to 3.
3656 // Requesting 2 preconnected sockets for "a" should fail to allocate any more
3657 // sockets for "a", and "b" should still have 2 active sockets.
3658
3659 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3660 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103661 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]dcbe168a2010-12-02 03:14:463662 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3663 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3664 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103665 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463666 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3667 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3668
3669 // Now release the 2 active sockets for "b". This will give us 1 idle socket
3670 // in "a" and 2 idle sockets in "b". Requesting 2 preconnected sockets for
3671 // "a" should result in closing 1 for "b".
3672 handle1.Reset();
3673 handle2.Reset();
3674 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("b"));
3675 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3676
3677 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3678 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103679 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]dcbe168a2010-12-02 03:14:463680 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3681 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3682 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103683 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463684 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("b"));
3685 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3686}
3687
[email protected]b7b8be42011-07-12 12:46:413688TEST_F(ClientSocketPoolBaseTest, PreconnectWithoutBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073689 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3690 pool_->EnableConnectBackupJobs();
3691
3692 // Make the ConnectJob hang until it times out, shorten the timeout.
3693 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3694 connect_job_factory_->set_timeout_duration(
3695 base::TimeDelta::FromMilliseconds(500));
3696 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3697 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103698 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073699 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073700
[email protected]b7b8be42011-07-12 12:46:413701 // Verify the backup timer doesn't create a backup job, by making
3702 // the backup job a pending job instead of a waiting job, so it
3703 // *would* complete if it were created.
[email protected]a9fc8fc2011-05-10 02:41:073704 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2da659e2013-05-23 20:51:343705 base::MessageLoop::current()->PostDelayedTask(
3706 FROM_HERE,
3707 base::MessageLoop::QuitClosure(),
3708 base::TimeDelta::FromSeconds(1));
3709 base::MessageLoop::current()->Run();
[email protected]a9fc8fc2011-05-10 02:41:073710 EXPECT_FALSE(pool_->HasGroup("a"));
3711}
3712
[email protected]b7b8be42011-07-12 12:46:413713TEST_F(ClientSocketPoolBaseTest, PreconnectWithBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073714 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3715 pool_->EnableConnectBackupJobs();
3716
3717 // Make the ConnectJob hang forever.
3718 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3719 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3720 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103721 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073722 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]2da659e2013-05-23 20:51:343723 base::MessageLoop::current()->RunUntilIdle();
[email protected]a9fc8fc2011-05-10 02:41:073724
3725 // Make the backup job be a pending job, so it completes normally.
3726 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3727 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:523728 TestCompletionCallback callback;
[email protected]a9fc8fc2011-05-10 02:41:073729 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
3730 params_,
[email protected]bb1c4662013-11-14 00:00:073731 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523732 callback.callback(),
[email protected]a9fc8fc2011-05-10 02:41:073733 pool_.get(),
3734 BoundNetLog()));
[email protected]b7b8be42011-07-12 12:46:413735 // Timer has started, but the backup connect job shouldn't be created yet.
[email protected]a9fc8fc2011-05-10 02:41:073736 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103737 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073738 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3739 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3740 ASSERT_EQ(OK, callback.WaitForResult());
3741
3742 // The hung connect job should still be there, but everything else should be
3743 // complete.
3744 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103745 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073746 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3747 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3748}
3749
[email protected]0dc88b32014-03-26 20:12:283750// Tests that a preconnect that starts out with unread data can still be used.
3751// http://crbug.com/334467
3752TEST_F(ClientSocketPoolBaseTest, PreconnectWithUnreadData) {
3753 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3754 connect_job_factory_->set_job_type(TestConnectJob::kMockUnreadDataJob);
3755
3756 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3757
3758 ASSERT_TRUE(pool_->HasGroup("a"));
3759 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3760 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3761 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3762
3763 // Fail future jobs to be sure that handle receives the preconnected socket
3764 // rather than closing it and making a new one.
3765 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3766 ClientSocketHandle handle;
3767 TestCompletionCallback callback;
3768 EXPECT_EQ(OK, handle.Init("a",
3769 params_,
3770 DEFAULT_PRIORITY,
3771 callback.callback(),
3772 pool_.get(),
3773 BoundNetLog()));
3774
3775 ASSERT_TRUE(pool_->HasGroup("a"));
3776 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3777 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3778 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3779
3780 // Drain the pending read.
3781 EXPECT_EQ(1, handle.socket()->Read(NULL, 1, CompletionCallback()));
3782
3783 TestLoadTimingInfoConnectedReused(handle);
3784 handle.Reset();
3785
3786 // The socket should be usable now that it's idle again.
3787 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3788}
3789
[email protected]043b68c82013-08-22 23:41:523790class MockLayeredPool : public HigherLayeredPool {
[email protected]58e562f2013-04-22 17:32:203791 public:
3792 MockLayeredPool(TestClientSocketPool* pool,
3793 const std::string& group_name)
3794 : pool_(pool),
[email protected]58e562f2013-04-22 17:32:203795 group_name_(group_name),
3796 can_release_connection_(true) {
[email protected]043b68c82013-08-22 23:41:523797 pool_->AddHigherLayeredPool(this);
[email protected]58e562f2013-04-22 17:32:203798 }
3799
3800 ~MockLayeredPool() {
[email protected]043b68c82013-08-22 23:41:523801 pool_->RemoveHigherLayeredPool(this);
[email protected]58e562f2013-04-22 17:32:203802 }
3803
3804 int RequestSocket(TestClientSocketPool* pool) {
[email protected]bb1c4662013-11-14 00:00:073805 scoped_refptr<TestSocketParams> params(
3806 new TestSocketParams(false /* ignore_limits */));
3807 return handle_.Init(group_name_, params, DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203808 callback_.callback(), pool, BoundNetLog());
3809 }
3810
3811 int RequestSocketWithoutLimits(TestClientSocketPool* pool) {
[email protected]bb1c4662013-11-14 00:00:073812 scoped_refptr<TestSocketParams> params(
3813 new TestSocketParams(true /* ignore_limits */));
3814 return handle_.Init(group_name_, params, MAXIMUM_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203815 callback_.callback(), pool, BoundNetLog());
3816 }
3817
3818 bool ReleaseOneConnection() {
3819 if (!handle_.is_initialized() || !can_release_connection_) {
3820 return false;
3821 }
3822 handle_.socket()->Disconnect();
3823 handle_.Reset();
3824 return true;
3825 }
3826
3827 void set_can_release_connection(bool can_release_connection) {
3828 can_release_connection_ = can_release_connection;
3829 }
3830
3831 MOCK_METHOD0(CloseOneIdleConnection, bool());
3832
3833 private:
3834 TestClientSocketPool* const pool_;
[email protected]58e562f2013-04-22 17:32:203835 ClientSocketHandle handle_;
3836 TestCompletionCallback callback_;
3837 const std::string group_name_;
3838 bool can_release_connection_;
3839};
3840
3841TEST_F(ClientSocketPoolBaseTest, FailToCloseIdleSocketsNotHeldByLayeredPool) {
3842 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3843 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3844
3845 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
3846 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3847 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3848 .WillOnce(Return(false));
[email protected]043b68c82013-08-22 23:41:523849 EXPECT_FALSE(pool_->CloseOneIdleConnectionInHigherLayeredPool());
[email protected]58e562f2013-04-22 17:32:203850}
3851
3852TEST_F(ClientSocketPoolBaseTest, ForciblyCloseIdleSocketsHeldByLayeredPool) {
3853 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3854 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3855
3856 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
3857 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3858 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3859 .WillOnce(Invoke(&mock_layered_pool,
3860 &MockLayeredPool::ReleaseOneConnection));
[email protected]043b68c82013-08-22 23:41:523861 EXPECT_TRUE(pool_->CloseOneIdleConnectionInHigherLayeredPool());
[email protected]58e562f2013-04-22 17:32:203862}
3863
3864// Tests the basic case of closing an idle socket in a higher layered pool when
3865// a new request is issued and the lower layer pool is stalled.
3866TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsHeldByLayeredPoolWhenNeeded) {
3867 CreatePool(1, 1);
3868 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3869
3870 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
3871 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3872 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3873 .WillOnce(Invoke(&mock_layered_pool,
3874 &MockLayeredPool::ReleaseOneConnection));
3875 ClientSocketHandle handle;
3876 TestCompletionCallback callback;
3877 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
3878 params_,
[email protected]bb1c4662013-11-14 00:00:073879 DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203880 callback.callback(),
3881 pool_.get(),
3882 BoundNetLog()));
3883 EXPECT_EQ(OK, callback.WaitForResult());
3884}
3885
3886// Same as above, but the idle socket is in the same group as the stalled
3887// socket, and closes the only other request in its group when closing requests
3888// in higher layered pools. This generally shouldn't happen, but it may be
3889// possible if a higher level pool issues a request and the request is
3890// subsequently cancelled. Even if it's not possible, best not to crash.
3891TEST_F(ClientSocketPoolBaseTest,
3892 CloseIdleSocketsHeldByLayeredPoolWhenNeededSameGroup) {
3893 CreatePool(2, 2);
3894 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3895
3896 // Need a socket in another group for the pool to be stalled (If a group
3897 // has the maximum number of connections already, it's not stalled).
3898 ClientSocketHandle handle1;
3899 TestCompletionCallback callback1;
3900 EXPECT_EQ(OK, handle1.Init("group1",
3901 params_,
[email protected]bb1c4662013-11-14 00:00:073902 DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203903 callback1.callback(),
3904 pool_.get(),
3905 BoundNetLog()));
3906
3907 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
3908 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3909 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3910 .WillOnce(Invoke(&mock_layered_pool,
3911 &MockLayeredPool::ReleaseOneConnection));
3912 ClientSocketHandle handle;
3913 TestCompletionCallback callback2;
3914 EXPECT_EQ(ERR_IO_PENDING, handle.Init("group2",
3915 params_,
[email protected]bb1c4662013-11-14 00:00:073916 DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203917 callback2.callback(),
3918 pool_.get(),
3919 BoundNetLog()));
3920 EXPECT_EQ(OK, callback2.WaitForResult());
3921}
3922
3923// Tests the case when an idle socket can be closed when a new request is
3924// issued, and the new request belongs to a group that was previously stalled.
3925TEST_F(ClientSocketPoolBaseTest,
3926 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded) {
3927 CreatePool(2, 2);
3928 std::list<TestConnectJob::JobType> job_types;
3929 job_types.push_back(TestConnectJob::kMockJob);
3930 job_types.push_back(TestConnectJob::kMockJob);
3931 job_types.push_back(TestConnectJob::kMockJob);
3932 job_types.push_back(TestConnectJob::kMockJob);
3933 connect_job_factory_->set_job_types(&job_types);
3934
3935 ClientSocketHandle handle1;
3936 TestCompletionCallback callback1;
3937 EXPECT_EQ(OK, handle1.Init("group1",
3938 params_,
[email protected]bb1c4662013-11-14 00:00:073939 DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203940 callback1.callback(),
3941 pool_.get(),
3942 BoundNetLog()));
3943
3944 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
3945 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3946 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3947 .WillRepeatedly(Invoke(&mock_layered_pool,
3948 &MockLayeredPool::ReleaseOneConnection));
3949 mock_layered_pool.set_can_release_connection(false);
3950
3951 // The third request is made when the socket pool is in a stalled state.
3952 ClientSocketHandle handle3;
3953 TestCompletionCallback callback3;
3954 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("group3",
3955 params_,
[email protected]bb1c4662013-11-14 00:00:073956 DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203957 callback3.callback(),
3958 pool_.get(),
3959 BoundNetLog()));
3960
3961 base::RunLoop().RunUntilIdle();
3962 EXPECT_FALSE(callback3.have_result());
3963
3964 // The fourth request is made when the pool is no longer stalled. The third
3965 // request should be serviced first, since it was issued first and has the
3966 // same priority.
3967 mock_layered_pool.set_can_release_connection(true);
3968 ClientSocketHandle handle4;
3969 TestCompletionCallback callback4;
3970 EXPECT_EQ(ERR_IO_PENDING, handle4.Init("group3",
3971 params_,
[email protected]bb1c4662013-11-14 00:00:073972 DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203973 callback4.callback(),
3974 pool_.get(),
3975 BoundNetLog()));
3976 EXPECT_EQ(OK, callback3.WaitForResult());
3977 EXPECT_FALSE(callback4.have_result());
3978
3979 // Closing a handle should free up another socket slot.
3980 handle1.Reset();
3981 EXPECT_EQ(OK, callback4.WaitForResult());
3982}
3983
3984// Tests the case when an idle socket can be closed when a new request is
3985// issued, and the new request belongs to a group that was previously stalled.
3986//
3987// The two differences from the above test are that the stalled requests are not
3988// in the same group as the layered pool's request, and the the fourth request
3989// has a higher priority than the third one, so gets a socket first.
3990TEST_F(ClientSocketPoolBaseTest,
3991 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded2) {
3992 CreatePool(2, 2);
3993 std::list<TestConnectJob::JobType> job_types;
3994 job_types.push_back(TestConnectJob::kMockJob);
3995 job_types.push_back(TestConnectJob::kMockJob);
3996 job_types.push_back(TestConnectJob::kMockJob);
3997 job_types.push_back(TestConnectJob::kMockJob);
3998 connect_job_factory_->set_job_types(&job_types);
3999
4000 ClientSocketHandle handle1;
4001 TestCompletionCallback callback1;
4002 EXPECT_EQ(OK, handle1.Init("group1",
4003 params_,
[email protected]bb1c4662013-11-14 00:00:074004 DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:204005 callback1.callback(),
4006 pool_.get(),
4007 BoundNetLog()));
4008
4009 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
4010 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
4011 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4012 .WillRepeatedly(Invoke(&mock_layered_pool,
4013 &MockLayeredPool::ReleaseOneConnection));
4014 mock_layered_pool.set_can_release_connection(false);
4015
4016 // The third request is made when the socket pool is in a stalled state.
4017 ClientSocketHandle handle3;
4018 TestCompletionCallback callback3;
4019 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("group3",
4020 params_,
4021 MEDIUM,
4022 callback3.callback(),
4023 pool_.get(),
4024 BoundNetLog()));
4025
4026 base::RunLoop().RunUntilIdle();
4027 EXPECT_FALSE(callback3.have_result());
4028
4029 // The fourth request is made when the pool is no longer stalled. This
4030 // request has a higher priority than the third request, so is serviced first.
4031 mock_layered_pool.set_can_release_connection(true);
4032 ClientSocketHandle handle4;
4033 TestCompletionCallback callback4;
4034 EXPECT_EQ(ERR_IO_PENDING, handle4.Init("group3",
4035 params_,
4036 HIGHEST,
4037 callback4.callback(),
4038 pool_.get(),
4039 BoundNetLog()));
4040 EXPECT_EQ(OK, callback4.WaitForResult());
4041 EXPECT_FALSE(callback3.have_result());
4042
4043 // Closing a handle should free up another socket slot.
4044 handle1.Reset();
4045 EXPECT_EQ(OK, callback3.WaitForResult());
4046}
4047
4048TEST_F(ClientSocketPoolBaseTest,
4049 CloseMultipleIdleSocketsHeldByLayeredPoolWhenNeeded) {
4050 CreatePool(1, 1);
4051 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4052
4053 MockLayeredPool mock_layered_pool1(pool_.get(), "foo");
4054 EXPECT_EQ(OK, mock_layered_pool1.RequestSocket(pool_.get()));
4055 EXPECT_CALL(mock_layered_pool1, CloseOneIdleConnection())
4056 .WillRepeatedly(Invoke(&mock_layered_pool1,
4057 &MockLayeredPool::ReleaseOneConnection));
4058 MockLayeredPool mock_layered_pool2(pool_.get(), "bar");
4059 EXPECT_EQ(OK, mock_layered_pool2.RequestSocketWithoutLimits(pool_.get()));
4060 EXPECT_CALL(mock_layered_pool2, CloseOneIdleConnection())
4061 .WillRepeatedly(Invoke(&mock_layered_pool2,
4062 &MockLayeredPool::ReleaseOneConnection));
4063 ClientSocketHandle handle;
4064 TestCompletionCallback callback;
4065 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
4066 params_,
[email protected]bb1c4662013-11-14 00:00:074067 DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:204068 callback.callback(),
4069 pool_.get(),
4070 BoundNetLog()));
4071 EXPECT_EQ(OK, callback.WaitForResult());
4072}
4073
[email protected]b021ece62013-06-11 11:06:334074// Test that when a socket pool and group are at their limits, a request
4075// with |ignore_limits| triggers creation of a new socket, and gets the socket
4076// instead of a request with the same priority that was issued earlier, but
4077// that does not have |ignore_limits| set.
4078TEST_F(ClientSocketPoolBaseTest, IgnoreLimits) {
[email protected]bb1c4662013-11-14 00:00:074079 scoped_refptr<TestSocketParams> params_ignore_limits(
4080 new TestSocketParams(true /* ignore_limits */));
[email protected]b021ece62013-06-11 11:06:334081 CreatePool(1, 1);
4082
4083 // Issue a request to reach the socket pool limit.
[email protected]bb1c4662013-11-14 00:00:074084 EXPECT_EQ(OK, StartRequestWithParams("a", MAXIMUM_PRIORITY, params_));
[email protected]b021ece62013-06-11 11:06:334085 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4086
4087 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4088
[email protected]bb1c4662013-11-14 00:00:074089 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithParams("a", MAXIMUM_PRIORITY,
[email protected]b021ece62013-06-11 11:06:334090 params_));
4091 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4092
[email protected]bb1c4662013-11-14 00:00:074093 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithParams("a", MAXIMUM_PRIORITY,
[email protected]b021ece62013-06-11 11:06:334094 params_ignore_limits));
4095 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4096
4097 EXPECT_EQ(OK, request(2)->WaitForResult());
4098 EXPECT_FALSE(request(1)->have_result());
4099}
4100
[email protected]c55fabd2013-11-04 23:26:564101// Test that when a socket pool and group are at their limits, a ConnectJob
4102// issued for a request with |ignore_limits| set is not cancelled when a request
4103// without |ignore_limits| issued to the same group is cancelled.
4104TEST_F(ClientSocketPoolBaseTest, IgnoreLimitsCancelOtherJob) {
[email protected]bb1c4662013-11-14 00:00:074105 scoped_refptr<TestSocketParams> params_ignore_limits(
4106 new TestSocketParams(true /* ignore_limits */));
[email protected]c55fabd2013-11-04 23:26:564107 CreatePool(1, 1);
4108
4109 // Issue a request to reach the socket pool limit.
[email protected]bb1c4662013-11-14 00:00:074110 EXPECT_EQ(OK, StartRequestWithParams("a", MAXIMUM_PRIORITY, params_));
[email protected]c55fabd2013-11-04 23:26:564111 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4112
4113 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4114
[email protected]bb1c4662013-11-14 00:00:074115 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithParams("a", MAXIMUM_PRIORITY,
4116 params_));
[email protected]c55fabd2013-11-04 23:26:564117 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4118
[email protected]bb1c4662013-11-14 00:00:074119 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithParams("a", MAXIMUM_PRIORITY,
[email protected]b021ece62013-06-11 11:06:334120 params_ignore_limits));
4121 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4122
4123 // Cancel the pending request without ignore_limits set. The ConnectJob
4124 // should not be cancelled.
4125 request(1)->handle()->Reset();
4126 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4127
4128 EXPECT_EQ(OK, request(2)->WaitForResult());
4129 EXPECT_FALSE(request(1)->have_result());
4130}
4131
[email protected]f6d1d6eb2009-06-24 20:16:094132} // namespace
4133
4134} // namespace net