blob: 6688e01244d4bbfefd7da486f332db2173a8738e [file] [log] [blame]
[email protected]e34400c32012-01-24 02:49:331// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]f6d1d6eb2009-06-24 20:16:092// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]ab838892009-06-30 18:49:055#include "net/socket/client_socket_pool_base.h"
[email protected]f6d1d6eb2009-06-24 20:16:096
[email protected]51fdc7c2012-04-10 19:19:487#include <vector>
8
[email protected]6ecf2b92011-12-15 01:14:529#include "base/bind.h"
10#include "base/bind_helpers.h"
[email protected]2041cf342010-02-19 03:15:5911#include "base/callback.h"
[email protected]3b63f8f42011-03-28 01:54:1512#include "base/memory/ref_counted.h"
13#include "base/memory/scoped_vector.h"
[email protected]6ea7b152011-12-21 21:21:1314#include "base/memory/weak_ptr.h"
[email protected]18b577412013-07-18 04:19:1515#include "base/message_loop/message_loop.h"
[email protected]034df0f32013-01-07 23:17:4816#include "base/run_loop.h"
[email protected]fc9be5802013-06-11 10:56:5117#include "base/strings/string_number_conversions.h"
[email protected]18b577412013-07-18 04:19:1518#include "base/strings/stringprintf.h"
[email protected]f214f8792011-01-01 02:17:0819#include "base/threading/platform_thread.h"
[email protected]f3a1c642011-07-12 19:15:0320#include "base/values.h"
[email protected]034df0f32013-01-07 23:17:4821#include "net/base/load_timing_info.h"
[email protected]b258e0792013-01-12 07:11:5922#include "net/base/load_timing_info_test_util.h"
[email protected]d8eb84242010-09-25 02:25:0623#include "net/base/net_errors.h"
[email protected]9e743cd2010-03-16 07:03:5324#include "net/base/net_log.h"
25#include "net/base/net_log_unittest.h"
[email protected]ac790b42009-12-02 04:31:3126#include "net/base/request_priority.h"
[email protected]f6d1d6eb2009-06-24 20:16:0927#include "net/base/test_completion_callback.h"
[email protected]277d5942010-08-11 21:02:3528#include "net/http/http_response_headers.h"
[email protected]f6d1d6eb2009-06-24 20:16:0929#include "net/socket/client_socket_factory.h"
30#include "net/socket/client_socket_handle.h"
[email protected]b89f7e42010-05-20 20:37:0031#include "net/socket/client_socket_pool_histograms.h"
[email protected]75439d3b2009-07-23 22:11:1732#include "net/socket/socket_test_util.h"
[email protected]18ccfdb2013-08-15 00:13:4433#include "net/socket/ssl_client_socket.h"
[email protected]3268023f2011-05-05 00:08:1034#include "net/socket/stream_socket.h"
[email protected]18ccfdb2013-08-15 00:13:4435#include "net/udp/datagram_client_socket.h"
[email protected]51fdc7c2012-04-10 19:19:4836#include "testing/gmock/include/gmock/gmock.h"
[email protected]f6d1d6eb2009-06-24 20:16:0937#include "testing/gtest/include/gtest/gtest.h"
38
[email protected]51fdc7c2012-04-10 19:19:4839using ::testing::Invoke;
40using ::testing::Return;
41
[email protected]f6d1d6eb2009-06-24 20:16:0942namespace net {
43
44namespace {
45
[email protected]211d21722009-07-22 15:48:5346const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2047const int kDefaultMaxSocketsPerGroup = 2;
[email protected]a554a8262010-05-20 00:13:5248const net::RequestPriority kDefaultPriority = MEDIUM;
[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]51fdc7c2012-04-10 19:19:48103 TestSocketParams() : ignore_limits_(false) {}
104
105 void set_ignore_limits(bool ignore_limits) {
106 ignore_limits_ = ignore_limits;
107 }
108 bool ignore_limits() { return ignore_limits_; }
109
[email protected]df4b4ef2010-07-12 18:25:21110 private:
111 friend class base::RefCounted<TestSocketParams>;
112 ~TestSocketParams() {}
[email protected]51fdc7c2012-04-10 19:19:48113
114 bool ignore_limits_;
[email protected]df4b4ef2010-07-12 18:25:21115};
[email protected]7fc5b09a2010-02-27 00:07:38116typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
[email protected]d80a4322009-08-14 07:07:49117
[email protected]3268023f2011-05-05 00:08:10118class MockClientSocket : public StreamSocket {
[email protected]f6d1d6eb2009-06-24 20:16:09119 public:
[email protected]034df0f32013-01-07 23:17:48120 explicit MockClientSocket(net::NetLog* net_log)
121 : connected_(false),
122 net_log_(BoundNetLog::Make(net_log, net::NetLog::SOURCE_SOCKET)),
[email protected]e86df8dc2013-03-30 13:18:28123 was_used_to_convey_data_(false) {
[email protected]034df0f32013-01-07 23:17:48124 }
[email protected]f6d1d6eb2009-06-24 20:16:09125
[email protected]3f55aa12011-12-07 02:03:33126 // Socket implementation.
[email protected]ab838892009-06-30 18:49:05127 virtual int Read(
[email protected]83039bb2011-12-09 18:43:55128 IOBuffer* /* buf */, int len,
129 const CompletionCallback& /* callback */) OVERRIDE {
[email protected]e86df8dc2013-03-30 13:18:28130 return ERR_UNEXPECTED;
[email protected]3f55aa12011-12-07 02:03:33131 }
[email protected]ab838892009-06-30 18:49:05132
133 virtual int Write(
[email protected]83039bb2011-12-09 18:43:55134 IOBuffer* /* buf */, int len,
135 const CompletionCallback& /* callback */) OVERRIDE {
[email protected]0f873e82010-09-02 16:09:01136 was_used_to_convey_data_ = true;
137 return len;
[email protected]ab838892009-06-30 18:49:05138 }
[email protected]46fadfd2013-02-06 09:40:16139 virtual bool SetReceiveBufferSize(int32 size) OVERRIDE { return true; }
140 virtual bool SetSendBufferSize(int32 size) OVERRIDE { return true; }
[email protected]ab838892009-06-30 18:49:05141
[email protected]dbf036f2011-12-06 23:33:24142 // StreamSocket implementation.
[email protected]83039bb2011-12-09 18:43:55143 virtual int Connect(const CompletionCallback& callback) OVERRIDE {
[email protected]dbf036f2011-12-06 23:33:24144 connected_ = true;
145 return OK;
146 }
[email protected]f6d1d6eb2009-06-24 20:16:09147
[email protected]46fadfd2013-02-06 09:40:16148 virtual void Disconnect() OVERRIDE { connected_ = false; }
149 virtual bool IsConnected() const OVERRIDE { return connected_; }
150 virtual bool IsConnectedAndIdle() const OVERRIDE { return connected_; }
[email protected]0b7648c2009-07-06 20:14:01151
[email protected]46fadfd2013-02-06 09:40:16152 virtual int GetPeerAddress(IPEndPoint* /* address */) const OVERRIDE {
[email protected]9f864b32010-01-20 15:01:16153 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:09154 }
[email protected]f6d1d6eb2009-06-24 20:16:09155
[email protected]46fadfd2013-02-06 09:40:16156 virtual int GetLocalAddress(IPEndPoint* /* address */) const OVERRIDE {
[email protected]e7f74da2011-04-19 23:49:35157 return ERR_UNEXPECTED;
158 }
159
[email protected]46fadfd2013-02-06 09:40:16160 virtual const BoundNetLog& NetLog() const OVERRIDE {
[email protected]a2006ece2010-04-23 16:44:02161 return net_log_;
162 }
163
[email protected]46fadfd2013-02-06 09:40:16164 virtual void SetSubresourceSpeculation() OVERRIDE {}
165 virtual void SetOmniboxSpeculation() OVERRIDE {}
166 virtual bool WasEverUsed() const OVERRIDE {
[email protected]e86df8dc2013-03-30 13:18:28167 return was_used_to_convey_data_;
[email protected]5e6efa52011-06-27 17:26:41168 }
[email protected]46fadfd2013-02-06 09:40:16169 virtual bool UsingTCPFastOpen() const OVERRIDE { return false; }
[email protected]46fadfd2013-02-06 09:40:16170 virtual bool WasNpnNegotiated() const OVERRIDE {
[email protected]2d88e7d2012-07-19 17:55:17171 return false;
172 }
[email protected]46fadfd2013-02-06 09:40:16173 virtual NextProto GetNegotiatedProtocol() const OVERRIDE {
[email protected]33661e482012-04-03 16:16:26174 return kProtoUnknown;
175 }
[email protected]46fadfd2013-02-06 09:40:16176 virtual bool GetSSLInfo(SSLInfo* ssl_info) OVERRIDE {
[email protected]2d88e7d2012-07-19 17:55:17177 return false;
178 }
[email protected]9b5614a2010-08-25 20:29:45179
[email protected]f6d1d6eb2009-06-24 20:16:09180 private:
181 bool connected_;
[email protected]a2006ece2010-04-23 16:44:02182 BoundNetLog net_log_;
[email protected]0f873e82010-09-02 16:09:01183 bool was_used_to_convey_data_;
[email protected]f6d1d6eb2009-06-24 20:16:09184
[email protected]ab838892009-06-30 18:49:05185 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:09186};
187
[email protected]5fc08e32009-07-15 17:09:57188class TestConnectJob;
189
[email protected]f6d1d6eb2009-06-24 20:16:09190class MockClientSocketFactory : public ClientSocketFactory {
191 public:
[email protected]ab838892009-06-30 18:49:05192 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:09193
[email protected]18ccfdb2013-08-15 00:13:44194 virtual scoped_ptr<DatagramClientSocket> CreateDatagramClientSocket(
[email protected]5370c012011-06-29 03:47:04195 DatagramSocket::BindType bind_type,
196 const RandIntCallback& rand_int_cb,
[email protected]98b0e582011-06-22 14:31:41197 NetLog* net_log,
[email protected]46fadfd2013-02-06 09:40:16198 const NetLog::Source& source) OVERRIDE {
[email protected]98b0e582011-06-22 14:31:41199 NOTREACHED();
[email protected]18ccfdb2013-08-15 00:13:44200 return scoped_ptr<DatagramClientSocket>();
[email protected]98b0e582011-06-22 14:31:41201 }
202
[email protected]18ccfdb2013-08-15 00:13:44203 virtual scoped_ptr<StreamSocket> CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07204 const AddressList& addresses,
205 NetLog* /* net_log */,
[email protected]46fadfd2013-02-06 09:40:16206 const NetLog::Source& /*source*/) OVERRIDE {
[email protected]f6d1d6eb2009-06-24 20:16:09207 allocation_count_++;
[email protected]18ccfdb2013-08-15 00:13:44208 return scoped_ptr<StreamSocket>();
[email protected]f6d1d6eb2009-06-24 20:16:09209 }
210
[email protected]18ccfdb2013-08-15 00:13:44211 virtual scoped_ptr<SSLClientSocket> CreateSSLClientSocket(
212 scoped_ptr<ClientSocketHandle> transport_socket,
[email protected]4f4de7e62010-11-12 19:55:27213 const HostPortPair& host_and_port,
[email protected]7ab5bbd12010-10-19 13:33:21214 const SSLConfig& ssl_config,
[email protected]46fadfd2013-02-06 09:40:16215 const SSLClientSocketContext& context) OVERRIDE {
[email protected]f6d1d6eb2009-06-24 20:16:09216 NOTIMPLEMENTED();
[email protected]18ccfdb2013-08-15 00:13:44217 return scoped_ptr<SSLClientSocket>();
[email protected]f6d1d6eb2009-06-24 20:16:09218 }
219
[email protected]46fadfd2013-02-06 09:40:16220 virtual void ClearSSLSessionCache() OVERRIDE {
[email protected]25f47352011-02-25 16:31:59221 NOTIMPLEMENTED();
222 }
223
[email protected]5fc08e32009-07-15 17:09:57224 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
[email protected]03b7c8c2013-07-20 04:38:55225
[email protected]5fc08e32009-07-15 17:09:57226 void SignalJobs();
227
[email protected]03b7c8c2013-07-20 04:38:55228 void SignalJob(size_t job);
229
230 void SetJobLoadState(size_t job, LoadState load_state);
231
[email protected]f6d1d6eb2009-06-24 20:16:09232 int allocation_count() const { return allocation_count_; }
233
[email protected]f6d1d6eb2009-06-24 20:16:09234 private:
235 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:57236 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09237};
238
[email protected]ab838892009-06-30 18:49:05239class TestConnectJob : public ConnectJob {
240 public:
241 enum JobType {
242 kMockJob,
243 kMockFailingJob,
244 kMockPendingJob,
245 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57246 kMockWaitingJob,
[email protected]e772db3f2010-07-12 18:11:13247 kMockRecoverableJob,
248 kMockPendingRecoverableJob,
[email protected]e60e47a2010-07-14 03:37:18249 kMockAdditionalErrorStateJob,
250 kMockPendingAdditionalErrorStateJob,
[email protected]ab838892009-06-30 18:49:05251 };
252
[email protected]994d4932010-07-12 17:55:13253 // The kMockPendingJob uses a slight delay before allowing the connect
254 // to complete.
255 static const int kPendingConnectDelay = 2;
256
[email protected]ab838892009-06-30 18:49:05257 TestConnectJob(JobType job_type,
258 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49259 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34260 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05261 ConnectJob::Delegate* delegate,
[email protected]fd7b7c92009-08-20 19:38:30262 MockClientSocketFactory* client_socket_factory,
[email protected]06650c52010-06-03 00:49:17263 NetLog* net_log)
264 : ConnectJob(group_name, timeout_duration, delegate,
265 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
[email protected]2ab05b52009-07-01 23:57:58266 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05267 client_socket_factory_(client_socket_factory),
[email protected]aa249b52013-04-30 01:04:32268 weak_factory_(this),
[email protected]e60e47a2010-07-14 03:37:18269 load_state_(LOAD_STATE_IDLE),
270 store_additional_error_state_(false) {}
[email protected]ab838892009-06-30 18:49:05271
[email protected]974ebd62009-08-03 23:14:34272 void Signal() {
[email protected]e772db3f2010-07-12 18:11:13273 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
[email protected]974ebd62009-08-03 23:14:34274 }
275
[email protected]03b7c8c2013-07-20 04:38:55276 void set_load_state(LoadState load_state) { load_state_ = load_state; }
277
278 // From ConnectJob:
279
[email protected]46fadfd2013-02-06 09:40:16280 virtual LoadState GetLoadState() const OVERRIDE { return load_state_; }
[email protected]46451352009-09-01 14:54:21281
[email protected]46fadfd2013-02-06 09:40:16282 virtual void GetAdditionalErrorState(ClientSocketHandle* handle) OVERRIDE {
[email protected]e60e47a2010-07-14 03:37:18283 if (store_additional_error_state_) {
284 // Set all of the additional error state fields in some way.
285 handle->set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43286 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:45287 info.headers = new HttpResponseHeaders(std::string());
[email protected]8b498692010-07-16 17:11:43288 handle->set_ssl_error_response_info(info);
[email protected]e60e47a2010-07-14 03:37:18289 }
290 }
291
[email protected]974ebd62009-08-03 23:14:34292 private:
[email protected]03b7c8c2013-07-20 04:38:55293 // From ConnectJob:
[email protected]ab838892009-06-30 18:49:05294
[email protected]46fadfd2013-02-06 09:40:16295 virtual int ConnectInternal() OVERRIDE {
[email protected]ab838892009-06-30 18:49:05296 AddressList ignored;
[email protected]ab739042011-04-07 15:22:28297 client_socket_factory_->CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07298 ignored, NULL, net::NetLog::Source());
[email protected]18ccfdb2013-08-15 00:13:44299 SetSocket(
300 scoped_ptr<StreamSocket>(new MockClientSocket(net_log().net_log())));
[email protected]ab838892009-06-30 18:49:05301 switch (job_type_) {
302 case kMockJob:
[email protected]e772db3f2010-07-12 18:11:13303 return DoConnect(true /* successful */, false /* sync */,
304 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05305 case kMockFailingJob:
[email protected]e772db3f2010-07-12 18:11:13306 return DoConnect(false /* error */, false /* sync */,
307 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05308 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57309 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47310
311 // Depending on execution timings, posting a delayed task can result
312 // in the task getting executed the at the earliest possible
313 // opportunity or only after returning once from the message loop and
314 // then a second call into the message loop. In order to make behavior
315 // more deterministic, we change the default delay to 2ms. This should
316 // always require us to wait for the second call into the message loop.
317 //
318 // N.B. The correct fix for this and similar timing problems is to
319 // abstract time for the purpose of unittests. Unfortunately, we have
320 // a lot of third-party components that directly call the various
321 // time functions, so this change would be rather invasive.
[email protected]2da659e2013-05-23 20:51:34322 base::MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05323 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13324 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
325 weak_factory_.GetWeakPtr(),
326 true /* successful */,
327 true /* async */,
328 false /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53329 base::TimeDelta::FromMilliseconds(kPendingConnectDelay));
[email protected]ab838892009-06-30 18:49:05330 return ERR_IO_PENDING;
331 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57332 set_load_state(LOAD_STATE_CONNECTING);
[email protected]2da659e2013-05-23 20:51:34333 base::MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05334 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13335 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
336 weak_factory_.GetWeakPtr(),
337 false /* error */,
338 true /* async */,
339 false /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53340 base::TimeDelta::FromMilliseconds(2));
[email protected]ab838892009-06-30 18:49:05341 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57342 case kMockWaitingJob:
[email protected]03b7c8c2013-07-20 04:38:55343 set_load_state(LOAD_STATE_CONNECTING);
[email protected]5fc08e32009-07-15 17:09:57344 client_socket_factory_->WaitForSignal(this);
345 waiting_success_ = true;
346 return ERR_IO_PENDING;
[email protected]e772db3f2010-07-12 18:11:13347 case kMockRecoverableJob:
348 return DoConnect(false /* error */, false /* sync */,
349 true /* recoverable */);
350 case kMockPendingRecoverableJob:
351 set_load_state(LOAD_STATE_CONNECTING);
[email protected]2da659e2013-05-23 20:51:34352 base::MessageLoop::current()->PostDelayedTask(
[email protected]e772db3f2010-07-12 18:11:13353 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13354 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
355 weak_factory_.GetWeakPtr(),
356 false /* error */,
357 true /* async */,
358 true /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53359 base::TimeDelta::FromMilliseconds(2));
[email protected]e772db3f2010-07-12 18:11:13360 return ERR_IO_PENDING;
[email protected]e60e47a2010-07-14 03:37:18361 case kMockAdditionalErrorStateJob:
362 store_additional_error_state_ = true;
363 return DoConnect(false /* error */, false /* sync */,
364 false /* recoverable */);
365 case kMockPendingAdditionalErrorStateJob:
366 set_load_state(LOAD_STATE_CONNECTING);
367 store_additional_error_state_ = true;
[email protected]2da659e2013-05-23 20:51:34368 base::MessageLoop::current()->PostDelayedTask(
[email protected]e60e47a2010-07-14 03:37:18369 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13370 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
371 weak_factory_.GetWeakPtr(),
372 false /* error */,
373 true /* async */,
374 false /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53375 base::TimeDelta::FromMilliseconds(2));
[email protected]e60e47a2010-07-14 03:37:18376 return ERR_IO_PENDING;
[email protected]ab838892009-06-30 18:49:05377 default:
378 NOTREACHED();
[email protected]18ccfdb2013-08-15 00:13:44379 SetSocket(scoped_ptr<StreamSocket>());
[email protected]ab838892009-06-30 18:49:05380 return ERR_FAILED;
381 }
382 }
383
[email protected]e772db3f2010-07-12 18:11:13384 int DoConnect(bool succeed, bool was_async, bool recoverable) {
385 int result = OK;
[email protected]ab838892009-06-30 18:49:05386 if (succeed) {
[email protected]83039bb2011-12-09 18:43:55387 socket()->Connect(CompletionCallback());
[email protected]e772db3f2010-07-12 18:11:13388 } else if (recoverable) {
389 result = ERR_PROXY_AUTH_REQUESTED;
[email protected]6e713f02009-08-06 02:56:40390 } else {
[email protected]e772db3f2010-07-12 18:11:13391 result = ERR_CONNECTION_FAILED;
[email protected]18ccfdb2013-08-15 00:13:44392 SetSocket(scoped_ptr<StreamSocket>());
[email protected]ab838892009-06-30 18:49:05393 }
[email protected]2ab05b52009-07-01 23:57:58394
395 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30396 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05397 return result;
398 }
399
[email protected]5fc08e32009-07-15 17:09:57400 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05401 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57402 MockClientSocketFactory* const client_socket_factory_;
[email protected]6ea7b152011-12-21 21:21:13403 base::WeakPtrFactory<TestConnectJob> weak_factory_;
[email protected]46451352009-09-01 14:54:21404 LoadState load_state_;
[email protected]e60e47a2010-07-14 03:37:18405 bool store_additional_error_state_;
[email protected]ab838892009-06-30 18:49:05406
407 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
408};
409
[email protected]d80a4322009-08-14 07:07:49410class TestConnectJobFactory
411 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05412 public:
[email protected]034df0f32013-01-07 23:17:48413 TestConnectJobFactory(MockClientSocketFactory* client_socket_factory,
414 NetLog* net_log)
[email protected]ab838892009-06-30 18:49:05415 : job_type_(TestConnectJob::kMockJob),
[email protected]51fdc7c2012-04-10 19:19:48416 job_types_(NULL),
[email protected]034df0f32013-01-07 23:17:48417 client_socket_factory_(client_socket_factory),
418 net_log_(net_log) {
[email protected]b021ece62013-06-11 11:06:33419 }
[email protected]ab838892009-06-30 18:49:05420
421 virtual ~TestConnectJobFactory() {}
422
423 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
424
[email protected]51fdc7c2012-04-10 19:19:48425 void set_job_types(std::list<TestConnectJob::JobType>* job_types) {
426 job_types_ = job_types;
427 CHECK(!job_types_->empty());
428 }
429
[email protected]974ebd62009-08-03 23:14:34430 void set_timeout_duration(base::TimeDelta timeout_duration) {
431 timeout_duration_ = timeout_duration;
432 }
433
[email protected]3f55aa12011-12-07 02:03:33434 // ConnectJobFactory implementation.
[email protected]83039bb2011-12-09 18:43:55435
[email protected]18ccfdb2013-08-15 00:13:44436 virtual scoped_ptr<ConnectJob> NewConnectJob(
[email protected]ab838892009-06-30 18:49:05437 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49438 const TestClientSocketPoolBase::Request& request,
[email protected]46fadfd2013-02-06 09:40:16439 ConnectJob::Delegate* delegate) const OVERRIDE {
[email protected]51fdc7c2012-04-10 19:19:48440 EXPECT_TRUE(!job_types_ || !job_types_->empty());
441 TestConnectJob::JobType job_type = job_type_;
442 if (job_types_ && !job_types_->empty()) {
443 job_type = job_types_->front();
444 job_types_->pop_front();
445 }
[email protected]18ccfdb2013-08-15 00:13:44446 return scoped_ptr<ConnectJob>(new TestConnectJob(job_type,
447 group_name,
448 request,
449 timeout_duration_,
450 delegate,
451 client_socket_factory_,
452 net_log_));
[email protected]ab838892009-06-30 18:49:05453 }
454
[email protected]46fadfd2013-02-06 09:40:16455 virtual base::TimeDelta ConnectionTimeout() const OVERRIDE {
[email protected]a796bcec2010-03-22 17:17:26456 return timeout_duration_;
457 }
458
[email protected]ab838892009-06-30 18:49:05459 private:
460 TestConnectJob::JobType job_type_;
[email protected]51fdc7c2012-04-10 19:19:48461 std::list<TestConnectJob::JobType>* job_types_;
[email protected]974ebd62009-08-03 23:14:34462 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57463 MockClientSocketFactory* const client_socket_factory_;
[email protected]034df0f32013-01-07 23:17:48464 NetLog* net_log_;
[email protected]ab838892009-06-30 18:49:05465
466 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
467};
468
469class TestClientSocketPool : public ClientSocketPool {
470 public:
471 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53472 int max_sockets,
[email protected]ab838892009-06-30 18:49:05473 int max_sockets_per_group,
[email protected]2431756e2010-09-29 20:26:13474 ClientSocketPoolHistograms* histograms,
[email protected]9bf28db2009-08-29 01:35:16475 base::TimeDelta unused_idle_socket_timeout,
476 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49477 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
[email protected]b89f7e42010-05-20 20:37:00478 : base_(max_sockets, max_sockets_per_group, histograms,
[email protected]9bf28db2009-08-29 01:35:16479 unused_idle_socket_timeout, used_idle_socket_timeout,
[email protected]66761b952010-06-25 21:30:38480 connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05481
[email protected]2431756e2010-09-29 20:26:13482 virtual ~TestClientSocketPool() {}
483
[email protected]ab838892009-06-30 18:49:05484 virtual int RequestSocket(
485 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49486 const void* params,
[email protected]ac790b42009-12-02 04:31:31487 net::RequestPriority priority,
[email protected]ab838892009-06-30 18:49:05488 ClientSocketHandle* handle,
[email protected]49639fa2011-12-20 23:22:41489 const CompletionCallback& callback,
[email protected]d4dfdab2011-12-07 16:56:59490 const BoundNetLog& net_log) OVERRIDE {
[email protected]df4b4ef2010-07-12 18:25:21491 const scoped_refptr<TestSocketParams>* casted_socket_params =
492 static_cast<const scoped_refptr<TestSocketParams>*>(params);
493 return base_.RequestSocket(group_name, *casted_socket_params, priority,
494 handle, callback, net_log);
[email protected]ab838892009-06-30 18:49:05495 }
496
[email protected]2c2bef152010-10-13 00:55:03497 virtual void RequestSockets(const std::string& group_name,
498 const void* params,
499 int num_sockets,
[email protected]d4dfdab2011-12-07 16:56:59500 const BoundNetLog& net_log) OVERRIDE {
[email protected]2c2bef152010-10-13 00:55:03501 const scoped_refptr<TestSocketParams>* casted_params =
502 static_cast<const scoped_refptr<TestSocketParams>*>(params);
503
504 base_.RequestSockets(group_name, *casted_params, num_sockets, net_log);
505 }
506
[email protected]ab838892009-06-30 18:49:05507 virtual void CancelRequest(
508 const std::string& group_name,
[email protected]d4dfdab2011-12-07 16:56:59509 ClientSocketHandle* handle) OVERRIDE {
[email protected]d80a4322009-08-14 07:07:49510 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05511 }
512
513 virtual void ReleaseSocket(
514 const std::string& group_name,
[email protected]18ccfdb2013-08-15 00:13:44515 scoped_ptr<StreamSocket> socket,
[email protected]d4dfdab2011-12-07 16:56:59516 int id) OVERRIDE {
[email protected]18ccfdb2013-08-15 00:13:44517 base_.ReleaseSocket(group_name, socket.Pass(), id);
[email protected]a7e38572010-06-07 18:22:24518 }
519
[email protected]7af985a2012-12-14 22:40:42520 virtual void FlushWithError(int error) OVERRIDE {
521 base_.FlushWithError(error);
[email protected]ab838892009-06-30 18:49:05522 }
523
[email protected]51fdc7c2012-04-10 19:19:48524 virtual bool IsStalled() const OVERRIDE {
525 return base_.IsStalled();
526 }
527
[email protected]d4dfdab2011-12-07 16:56:59528 virtual void CloseIdleSockets() OVERRIDE {
[email protected]d80a4322009-08-14 07:07:49529 base_.CloseIdleSockets();
[email protected]ab838892009-06-30 18:49:05530 }
531
[email protected]d4dfdab2011-12-07 16:56:59532 virtual int IdleSocketCount() const OVERRIDE {
533 return base_.idle_socket_count();
534 }
[email protected]ab838892009-06-30 18:49:05535
[email protected]d4dfdab2011-12-07 16:56:59536 virtual int IdleSocketCountInGroup(
537 const std::string& group_name) const OVERRIDE {
[email protected]d80a4322009-08-14 07:07:49538 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05539 }
540
[email protected]d4dfdab2011-12-07 16:56:59541 virtual LoadState GetLoadState(
542 const std::string& group_name,
543 const ClientSocketHandle* handle) const OVERRIDE {
[email protected]d80a4322009-08-14 07:07:49544 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05545 }
546
[email protected]51fdc7c2012-04-10 19:19:48547 virtual void AddLayeredPool(LayeredPool* pool) OVERRIDE {
548 base_.AddLayeredPool(pool);
549 }
550
551 virtual void RemoveLayeredPool(LayeredPool* pool) OVERRIDE {
552 base_.RemoveLayeredPool(pool);
553 }
554
[email protected]ea5ef4c2013-06-13 22:50:27555 virtual base::DictionaryValue* GetInfoAsValue(
[email protected]d4dfdab2011-12-07 16:56:59556 const std::string& name,
557 const std::string& type,
558 bool include_nested_pools) const OVERRIDE {
[email protected]59d7a5a2010-08-30 16:44:27559 return base_.GetInfoAsValue(name, type);
560 }
561
[email protected]d4dfdab2011-12-07 16:56:59562 virtual base::TimeDelta ConnectionTimeout() const OVERRIDE {
[email protected]a796bcec2010-03-22 17:17:26563 return base_.ConnectionTimeout();
564 }
565
[email protected]d4dfdab2011-12-07 16:56:59566 virtual ClientSocketPoolHistograms* histograms() const OVERRIDE {
[email protected]b89f7e42010-05-20 20:37:00567 return base_.histograms();
568 }
[email protected]a796bcec2010-03-22 17:17:26569
[email protected]d80a4322009-08-14 07:07:49570 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20571
[email protected]8159a1c2012-06-07 00:00:10572 int NumUnassignedConnectJobsInGroup(const std::string& group_name) const {
573 return base_.NumUnassignedConnectJobsInGroup(group_name);
574 }
575
[email protected]974ebd62009-08-03 23:14:34576 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49577 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34578 }
579
[email protected]2c2bef152010-10-13 00:55:03580 int NumActiveSocketsInGroup(const std::string& group_name) const {
581 return base_.NumActiveSocketsInGroup(group_name);
582 }
583
[email protected]2abfe90a2010-08-25 17:49:51584 bool HasGroup(const std::string& group_name) const {
585 return base_.HasGroup(group_name);
586 }
587
[email protected]9bf28db2009-08-29 01:35:16588 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
589
[email protected]06d94042010-08-25 01:45:22590 void EnableConnectBackupJobs() { base_.EnableConnectBackupJobs(); }
[email protected]43a21b82010-06-10 21:30:54591
[email protected]51fdc7c2012-04-10 19:19:48592 bool CloseOneIdleConnectionInLayeredPool() {
593 return base_.CloseOneIdleConnectionInLayeredPool();
594 }
595
[email protected]ab838892009-06-30 18:49:05596 private:
[email protected]d80a4322009-08-14 07:07:49597 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05598
599 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
600};
601
[email protected]a937a06d2009-08-19 21:19:24602} // namespace
603
[email protected]7fc5b09a2010-02-27 00:07:38604REGISTER_SOCKET_PARAMS_FOR_POOL(TestClientSocketPool, TestSocketParams);
[email protected]a937a06d2009-08-19 21:19:24605
606namespace {
607
[email protected]5fc08e32009-07-15 17:09:57608void MockClientSocketFactory::SignalJobs() {
609 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
610 it != waiting_jobs_.end(); ++it) {
611 (*it)->Signal();
612 }
613 waiting_jobs_.clear();
614}
615
[email protected]03b7c8c2013-07-20 04:38:55616void MockClientSocketFactory::SignalJob(size_t job) {
617 ASSERT_LT(job, waiting_jobs_.size());
618 waiting_jobs_[job]->Signal();
619 waiting_jobs_.erase(waiting_jobs_.begin() + job);
620}
621
622void MockClientSocketFactory::SetJobLoadState(size_t job,
623 LoadState load_state) {
624 ASSERT_LT(job, waiting_jobs_.size());
625 waiting_jobs_[job]->set_load_state(load_state);
626}
627
[email protected]974ebd62009-08-03 23:14:34628class TestConnectJobDelegate : public ConnectJob::Delegate {
629 public:
630 TestConnectJobDelegate()
631 : have_result_(false), waiting_for_result_(false), result_(OK) {}
632 virtual ~TestConnectJobDelegate() {}
633
[email protected]46fadfd2013-02-06 09:40:16634 virtual void OnConnectJobComplete(int result, ConnectJob* job) OVERRIDE {
[email protected]974ebd62009-08-03 23:14:34635 result_ = result;
[email protected]18ccfdb2013-08-15 00:13:44636 scoped_ptr<ConnectJob> owned_job(job);
637 scoped_ptr<StreamSocket> socket = owned_job->PassSocket();
[email protected]9b6fee12009-09-29 18:13:07638 // socket.get() should be NULL iff result != OK
[email protected]18ccfdb2013-08-15 00:13:44639 EXPECT_EQ(socket == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34640 have_result_ = true;
641 if (waiting_for_result_)
[email protected]2da659e2013-05-23 20:51:34642 base::MessageLoop::current()->Quit();
[email protected]974ebd62009-08-03 23:14:34643 }
644
645 int WaitForResult() {
646 DCHECK(!waiting_for_result_);
647 while (!have_result_) {
648 waiting_for_result_ = true;
[email protected]2da659e2013-05-23 20:51:34649 base::MessageLoop::current()->Run();
[email protected]974ebd62009-08-03 23:14:34650 waiting_for_result_ = false;
651 }
652 have_result_ = false; // auto-reset for next callback
653 return result_;
654 }
655
656 private:
657 bool have_result_;
658 bool waiting_for_result_;
659 int result_;
660};
661
[email protected]2431756e2010-09-29 20:26:13662class ClientSocketPoolBaseTest : public testing::Test {
[email protected]f6d1d6eb2009-06-24 20:16:09663 protected:
[email protected]b89f7e42010-05-20 20:37:00664 ClientSocketPoolBaseTest()
[email protected]df4b4ef2010-07-12 18:25:21665 : params_(new TestSocketParams()),
[email protected]636b8252011-04-08 19:56:54666 histograms_("ClientSocketPoolTest") {
667 connect_backup_jobs_enabled_ =
668 internal::ClientSocketPoolBaseHelper::connect_backup_jobs_enabled();
669 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(true);
[email protected]64770b7d2011-11-16 04:30:41670 cleanup_timer_enabled_ =
671 internal::ClientSocketPoolBaseHelper::cleanup_timer_enabled();
[email protected]636b8252011-04-08 19:56:54672 }
[email protected]2431756e2010-09-29 20:26:13673
[email protected]636b8252011-04-08 19:56:54674 virtual ~ClientSocketPoolBaseTest() {
675 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
676 connect_backup_jobs_enabled_);
[email protected]64770b7d2011-11-16 04:30:41677 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(
678 cleanup_timer_enabled_);
[email protected]636b8252011-04-08 19:56:54679 }
[email protected]c9d6a1d2009-07-14 16:15:20680
[email protected]211d21722009-07-22 15:48:53681 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16682 CreatePoolWithIdleTimeouts(
683 max_sockets,
684 max_sockets_per_group,
[email protected]82b8c962011-10-12 09:17:30685 ClientSocketPool::unused_idle_socket_timeout(),
686 ClientSocketPool::used_idle_socket_timeout());
[email protected]9bf28db2009-08-29 01:35:16687 }
688
689 void CreatePoolWithIdleTimeouts(
690 int max_sockets, int max_sockets_per_group,
691 base::TimeDelta unused_idle_socket_timeout,
692 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20693 DCHECK(!pool_.get());
[email protected]034df0f32013-01-07 23:17:48694 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_,
695 &net_log_);
[email protected]2431756e2010-09-29 20:26:13696 pool_.reset(new TestClientSocketPool(max_sockets,
697 max_sockets_per_group,
698 &histograms_,
699 unused_idle_socket_timeout,
700 used_idle_socket_timeout,
701 connect_job_factory_));
[email protected]c9d6a1d2009-07-14 16:15:20702 }
[email protected]f6d1d6eb2009-06-24 20:16:09703
[email protected]b021ece62013-06-11 11:06:33704 int StartRequestWithParams(
705 const std::string& group_name,
706 RequestPriority priority,
707 const scoped_refptr<TestSocketParams>& params) {
[email protected]2431756e2010-09-29 20:26:13708 return test_base_.StartRequestUsingPool<
709 TestClientSocketPool, TestSocketParams>(
[email protected]b021ece62013-06-11 11:06:33710 pool_.get(), group_name, priority, params);
711 }
712
713 int StartRequest(const std::string& group_name, RequestPriority priority) {
714 return StartRequestWithParams(group_name, priority, params_);
[email protected]f6d1d6eb2009-06-24 20:16:09715 }
716
[email protected]2431756e2010-09-29 20:26:13717 int GetOrderOfRequest(size_t index) const {
718 return test_base_.GetOrderOfRequest(index);
[email protected]f6d1d6eb2009-06-24 20:16:09719 }
720
[email protected]2431756e2010-09-29 20:26:13721 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
722 return test_base_.ReleaseOneConnection(keep_alive);
723 }
724
725 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
726 test_base_.ReleaseAllConnections(keep_alive);
727 }
728
729 TestSocketRequest* request(int i) { return test_base_.request(i); }
730 size_t requests_size() const { return test_base_.requests_size(); }
731 ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); }
732 size_t completion_count() const { return test_base_.completion_count(); }
733
[email protected]034df0f32013-01-07 23:17:48734 CapturingNetLog net_log_;
[email protected]636b8252011-04-08 19:56:54735 bool connect_backup_jobs_enabled_;
[email protected]64770b7d2011-11-16 04:30:41736 bool cleanup_timer_enabled_;
[email protected]f6d1d6eb2009-06-24 20:16:09737 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04738 TestConnectJobFactory* connect_job_factory_;
[email protected]df4b4ef2010-07-12 18:25:21739 scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:13740 ClientSocketPoolHistograms histograms_;
741 scoped_ptr<TestClientSocketPool> pool_;
742 ClientSocketPoolTest test_base_;
[email protected]f6d1d6eb2009-06-24 20:16:09743};
744
[email protected]974ebd62009-08-03 23:14:34745// Even though a timeout is specified, it doesn't time out on a synchronous
746// completion.
747TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
748 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06749 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49750 TestClientSocketPoolBase::Request request(
[email protected]49639fa2011-12-20 23:22:41751 &ignored, CompletionCallback(), kDefaultPriority,
[email protected]2c2bef152010-10-13 00:55:03752 internal::ClientSocketPoolBaseHelper::NORMAL,
[email protected]5acdce12011-03-30 13:00:20753 false, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34754 scoped_ptr<TestConnectJob> job(
755 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:12756 "a",
[email protected]974ebd62009-08-03 23:14:34757 request,
758 base::TimeDelta::FromMicroseconds(1),
759 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30760 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17761 NULL));
[email protected]974ebd62009-08-03 23:14:34762 EXPECT_EQ(OK, job->Connect());
763}
764
765TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
766 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06767 ClientSocketHandle ignored;
[email protected]333bdf62012-06-08 22:57:29768 CapturingNetLog log;
[email protected]9e743cd2010-03-16 07:03:53769
[email protected]d80a4322009-08-14 07:07:49770 TestClientSocketPoolBase::Request request(
[email protected]49639fa2011-12-20 23:22:41771 &ignored, CompletionCallback(), kDefaultPriority,
[email protected]2c2bef152010-10-13 00:55:03772 internal::ClientSocketPoolBaseHelper::NORMAL,
[email protected]5acdce12011-03-30 13:00:20773 false, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34774 // Deleted by TestConnectJobDelegate.
775 TestConnectJob* job =
776 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12777 "a",
[email protected]974ebd62009-08-03 23:14:34778 request,
779 base::TimeDelta::FromMicroseconds(1),
780 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30781 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17782 &log);
[email protected]974ebd62009-08-03 23:14:34783 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
[email protected]26b9973962012-01-28 00:57:00784 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
[email protected]974ebd62009-08-03 23:14:34785 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30786
[email protected]333bdf62012-06-08 22:57:29787 CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:40788 log.GetEntries(&entries);
789
790 EXPECT_EQ(6u, entries.size());
[email protected]e9002a92010-01-29 07:10:46791 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40792 entries, 0, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]06650c52010-06-03 00:49:17793 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40794 entries, 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]e9002a92010-01-29 07:10:46795 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40796 entries, 2, NetLog::TYPE_CONNECT_JOB_SET_SOCKET,
[email protected]06650c52010-06-03 00:49:17797 NetLog::PHASE_NONE));
798 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40799 entries, 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
[email protected]9e743cd2010-03-16 07:03:53800 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:46801 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40802 entries, 4, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]06650c52010-06-03 00:49:17803 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40804 entries, 5, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34805}
806
[email protected]5fc08e32009-07-15 17:09:57807TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53808 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20809
[email protected]6ecf2b92011-12-15 01:14:52810 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06811 ClientSocketHandle handle;
[email protected]333bdf62012-06-08 22:57:29812 CapturingBoundNetLog log;
[email protected]034df0f32013-01-07 23:17:48813 TestLoadTimingInfoNotConnected(handle);
[email protected]9e743cd2010-03-16 07:03:53814
[email protected]2431756e2010-09-29 20:26:13815 EXPECT_EQ(OK,
816 handle.Init("a",
817 params_,
818 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:52819 callback.callback(),
[email protected]2431756e2010-09-29 20:26:13820 pool_.get(),
821 log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09822 EXPECT_TRUE(handle.is_initialized());
823 EXPECT_TRUE(handle.socket());
[email protected]034df0f32013-01-07 23:17:48824 TestLoadTimingInfoConnectedNotReused(handle);
825
[email protected]f6d1d6eb2009-06-24 20:16:09826 handle.Reset();
[email protected]034df0f32013-01-07 23:17:48827 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:30828
[email protected]333bdf62012-06-08 22:57:29829 CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:40830 log.GetEntries(&entries);
831
832 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:46833 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40834 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]9e743cd2010-03-16 07:03:53835 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40836 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:17837 NetLog::PHASE_NONE));
838 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40839 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]9e743cd2010-03-16 07:03:53840 NetLog::PHASE_NONE));
841 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40842 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09843}
844
[email protected]ab838892009-06-30 18:49:05845TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53846 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20847
[email protected]ab838892009-06-30 18:49:05848 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]333bdf62012-06-08 22:57:29849 CapturingBoundNetLog log;
[email protected]9e743cd2010-03-16 07:03:53850
[email protected]2431756e2010-09-29 20:26:13851 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:52852 TestCompletionCallback callback;
[email protected]e60e47a2010-07-14 03:37:18853 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:13854 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43855 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:45856 info.headers = new HttpResponseHeaders(std::string());
[email protected]2431756e2010-09-29 20:26:13857 handle.set_ssl_error_response_info(info);
858 EXPECT_EQ(ERR_CONNECTION_FAILED,
859 handle.Init("a",
860 params_,
861 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:52862 callback.callback(),
[email protected]2431756e2010-09-29 20:26:13863 pool_.get(),
864 log.bound()));
865 EXPECT_FALSE(handle.socket());
866 EXPECT_FALSE(handle.is_ssl_error());
867 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]034df0f32013-01-07 23:17:48868 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:30869
[email protected]333bdf62012-06-08 22:57:29870 CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:40871 log.GetEntries(&entries);
872
873 EXPECT_EQ(3u, entries.size());
[email protected]5a1d7ca2010-04-28 20:12:27874 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40875 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:17876 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40877 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:17878 NetLog::PHASE_NONE));
[email protected]a2006ece2010-04-23 16:44:02879 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40880 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09881}
882
[email protected]211d21722009-07-22 15:48:53883TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
884 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
885
[email protected]9e743cd2010-03-16 07:03:53886 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30887
[email protected]211d21722009-07-22 15:48:53888 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
889 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
890 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
891 EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
892
[email protected]2431756e2010-09-29 20:26:13893 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53894 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13895 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53896
897 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
898 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
899 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
900
[email protected]2431756e2010-09-29 20:26:13901 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53902
[email protected]2431756e2010-09-29 20:26:13903 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53904 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13905 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53906
907 EXPECT_EQ(1, GetOrderOfRequest(1));
908 EXPECT_EQ(2, GetOrderOfRequest(2));
909 EXPECT_EQ(3, GetOrderOfRequest(3));
910 EXPECT_EQ(4, GetOrderOfRequest(4));
911 EXPECT_EQ(5, GetOrderOfRequest(5));
912 EXPECT_EQ(6, GetOrderOfRequest(6));
913 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17914
915 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13916 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53917}
918
919TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
920 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
921
[email protected]9e743cd2010-03-16 07:03:53922 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30923
[email protected]211d21722009-07-22 15:48:53924 // Reach all limits: max total sockets, and max sockets per group.
925 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
926 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
927 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
928 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
929
[email protected]2431756e2010-09-29 20:26:13930 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53931 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13932 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53933
934 // Now create a new group and verify that we don't starve it.
935 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
936
[email protected]2431756e2010-09-29 20:26:13937 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53938
[email protected]2431756e2010-09-29 20:26:13939 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53940 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13941 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53942
943 EXPECT_EQ(1, GetOrderOfRequest(1));
944 EXPECT_EQ(2, GetOrderOfRequest(2));
945 EXPECT_EQ(3, GetOrderOfRequest(3));
946 EXPECT_EQ(4, GetOrderOfRequest(4));
947 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17948
949 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13950 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53951}
952
953TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
954 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
955
[email protected]ac790b42009-12-02 04:31:31956 EXPECT_EQ(OK, StartRequest("b", LOWEST));
957 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
958 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
959 EXPECT_EQ(OK, StartRequest("a", LOWEST));
[email protected]211d21722009-07-22 15:48:53960
[email protected]2431756e2010-09-29 20:26:13961 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53962 client_socket_factory_.allocation_count());
963
[email protected]ac790b42009-12-02 04:31:31964 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
965 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
966 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53967
[email protected]2431756e2010-09-29 20:26:13968 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53969
[email protected]2431756e2010-09-29 20:26:13970 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53971
972 // First 4 requests don't have to wait, and finish in order.
973 EXPECT_EQ(1, GetOrderOfRequest(1));
974 EXPECT_EQ(2, GetOrderOfRequest(2));
975 EXPECT_EQ(3, GetOrderOfRequest(3));
976 EXPECT_EQ(4, GetOrderOfRequest(4));
977
[email protected]ac790b42009-12-02 04:31:31978 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
979 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53980 EXPECT_EQ(7, GetOrderOfRequest(5));
981 EXPECT_EQ(6, GetOrderOfRequest(6));
982 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17983
984 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13985 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]211d21722009-07-22 15:48:53986}
987
988TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
989 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
990
[email protected]ac790b42009-12-02 04:31:31991 EXPECT_EQ(OK, StartRequest("a", LOWEST));
992 EXPECT_EQ(OK, StartRequest("a", LOW));
993 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
994 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
[email protected]211d21722009-07-22 15:48:53995
[email protected]2431756e2010-09-29 20:26:13996 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53997 client_socket_factory_.allocation_count());
998
[email protected]ac790b42009-12-02 04:31:31999 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
1000 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1001 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:531002
[email protected]2431756e2010-09-29 20:26:131003 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531004
[email protected]2431756e2010-09-29 20:26:131005 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531006 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131007 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:531008
1009 // First 4 requests don't have to wait, and finish in order.
1010 EXPECT_EQ(1, GetOrderOfRequest(1));
1011 EXPECT_EQ(2, GetOrderOfRequest(2));
1012 EXPECT_EQ(3, GetOrderOfRequest(3));
1013 EXPECT_EQ(4, GetOrderOfRequest(4));
1014
1015 // Request ("b", 7) has the highest priority, but we can't make new socket for
1016 // group "b", because it has reached the per-group limit. Then we make
1017 // socket for ("c", 6), because it has higher priority than ("a", 4),
1018 // and we still can't make a socket for group "b".
1019 EXPECT_EQ(5, GetOrderOfRequest(5));
1020 EXPECT_EQ(6, GetOrderOfRequest(6));
1021 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171022
1023 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131024 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:531025}
1026
1027// Make sure that we count connecting sockets against the total limit.
1028TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
1029 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1030
1031 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1032 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1033 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
1034
1035 // Create one asynchronous request.
1036 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1037 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
1038
[email protected]6b175382009-10-13 06:47:471039 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1040 // actually become pending until 2ms after they have been created. In order
1041 // to flush all tasks, we need to wait so that we know there are no
1042 // soon-to-be-pending tasks waiting.
[email protected]26b9973962012-01-28 00:57:001043 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
[email protected]2da659e2013-05-23 20:51:341044 base::MessageLoop::current()->RunUntilIdle();
[email protected]6b175382009-10-13 06:47:471045
[email protected]211d21722009-07-22 15:48:531046 // The next synchronous request should wait for its turn.
1047 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1048 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
1049
[email protected]2431756e2010-09-29 20:26:131050 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531051
[email protected]2431756e2010-09-29 20:26:131052 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531053 client_socket_factory_.allocation_count());
1054
1055 EXPECT_EQ(1, GetOrderOfRequest(1));
1056 EXPECT_EQ(2, GetOrderOfRequest(2));
1057 EXPECT_EQ(3, GetOrderOfRequest(3));
1058 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:171059 EXPECT_EQ(5, GetOrderOfRequest(5));
1060
1061 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131062 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:531063}
1064
[email protected]6427fe22010-04-16 22:27:411065TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
1066 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1067 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1068
1069 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1070 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1071 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1072 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1073
1074 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1075
1076 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1077
1078 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", kDefaultPriority));
1079 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
1080
1081 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1082
[email protected]2431756e2010-09-29 20:26:131083 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411084 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131085 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411086 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131087 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1088 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411089 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
1090}
1091
[email protected]d7027bb2010-05-10 18:58:541092TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
1093 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1094 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1095
1096 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521097 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131098 EXPECT_EQ(ERR_IO_PENDING,
1099 handle.Init("a",
1100 params_,
1101 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521102 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131103 pool_.get(),
1104 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541105
1106 ClientSocketHandle handles[4];
1107 for (size_t i = 0; i < arraysize(handles); ++i) {
[email protected]6ecf2b92011-12-15 01:14:521108 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131109 EXPECT_EQ(ERR_IO_PENDING,
1110 handles[i].Init("b",
1111 params_,
1112 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521113 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131114 pool_.get(),
1115 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541116 }
1117
1118 // One will be stalled, cancel all the handles now.
1119 // This should hit the OnAvailableSocketSlot() code where we previously had
1120 // stalled groups, but no longer have any.
1121 for (size_t i = 0; i < arraysize(handles); ++i)
1122 handles[i].Reset();
1123}
1124
[email protected]eb5a99382010-07-11 03:18:261125TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:541126 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1127 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1128
[email protected]eb5a99382010-07-11 03:18:261129 {
1130 ClientSocketHandle handles[kDefaultMaxSockets];
[email protected]6ecf2b92011-12-15 01:14:521131 TestCompletionCallback callbacks[kDefaultMaxSockets];
[email protected]eb5a99382010-07-11 03:18:261132 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]2431756e2010-09-29 20:26:131133 EXPECT_EQ(OK, handles[i].Init(base::IntToString(i),
1134 params_,
[email protected]e83326f2010-07-31 17:29:251135 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521136 callbacks[i].callback(),
[email protected]2431756e2010-09-29 20:26:131137 pool_.get(),
1138 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261139 }
1140
1141 // Force a stalled group.
1142 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521143 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131144 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1145 params_,
1146 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521147 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131148 pool_.get(),
1149 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261150
1151 // Cancel the stalled request.
1152 stalled_handle.Reset();
1153
1154 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1155 EXPECT_EQ(0, pool_->IdleSocketCount());
1156
1157 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541158 }
1159
[email protected]43a21b82010-06-10 21:30:541160 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1161 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:261162}
[email protected]43a21b82010-06-10 21:30:541163
[email protected]eb5a99382010-07-11 03:18:261164TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
1165 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1166 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1167
1168 {
1169 ClientSocketHandle handles[kDefaultMaxSockets];
1170 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521171 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131172 EXPECT_EQ(ERR_IO_PENDING, handles[i].Init(base::IntToString(i),
1173 params_,
1174 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521175 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131176 pool_.get(),
1177 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261178 }
1179
1180 // Force a stalled group.
1181 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1182 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521183 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131184 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1185 params_,
1186 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521187 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131188 pool_.get(),
1189 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261190
1191 // Since it is stalled, it should have no connect jobs.
1192 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101193 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261194
1195 // Cancel the stalled request.
1196 handles[0].Reset();
1197
[email protected]eb5a99382010-07-11 03:18:261198 // Now we should have a connect job.
1199 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101200 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261201
1202 // The stalled socket should connect.
1203 EXPECT_EQ(OK, callback.WaitForResult());
1204
1205 EXPECT_EQ(kDefaultMaxSockets + 1,
1206 client_socket_factory_.allocation_count());
1207 EXPECT_EQ(0, pool_->IdleSocketCount());
1208 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101209 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261210
1211 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541212 }
1213
[email protected]eb5a99382010-07-11 03:18:261214 EXPECT_EQ(1, pool_->IdleSocketCount());
1215}
[email protected]43a21b82010-06-10 21:30:541216
[email protected]eb5a99382010-07-11 03:18:261217TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1218 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1219 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:541220
[email protected]eb5a99382010-07-11 03:18:261221 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521222 TestCompletionCallback callback;
[email protected]eb5a99382010-07-11 03:18:261223 {
[email protected]51fdc7c2012-04-10 19:19:481224 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261225 ClientSocketHandle handles[kDefaultMaxSockets];
1226 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521227 TestCompletionCallback callback;
[email protected]1870d5cf2011-05-12 01:55:401228 EXPECT_EQ(OK, handles[i].Init(base::StringPrintf(
1229 "Take 2: %d", i),
1230 params_,
1231 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521232 callback.callback(),
[email protected]1870d5cf2011-05-12 01:55:401233 pool_.get(),
1234 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261235 }
1236
1237 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1238 EXPECT_EQ(0, pool_->IdleSocketCount());
[email protected]51fdc7c2012-04-10 19:19:481239 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261240
1241 // Now we will hit the socket limit.
[email protected]2431756e2010-09-29 20:26:131242 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1243 params_,
1244 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521245 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131246 pool_.get(),
1247 BoundNetLog()));
[email protected]51fdc7c2012-04-10 19:19:481248 EXPECT_TRUE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261249
1250 // Dropping out of scope will close all handles and return them to idle.
1251 }
[email protected]43a21b82010-06-10 21:30:541252
1253 // But if we wait for it, the released idle sockets will be closed in
1254 // preference of the waiting request.
[email protected]8ae03f42010-07-07 19:08:101255 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]eb5a99382010-07-11 03:18:261256
1257 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1258 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:541259}
1260
1261// Regression test for http://crbug.com/40952.
1262TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1263 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]06d94042010-08-25 01:45:221264 pool_->EnableConnectBackupJobs();
[email protected]43a21b82010-06-10 21:30:541265 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1266
1267 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1268 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521269 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131270 EXPECT_EQ(OK, handle.Init(base::IntToString(i),
1271 params_,
1272 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521273 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131274 pool_.get(),
1275 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541276 }
1277
1278 // Flush all the DoReleaseSocket tasks.
[email protected]2da659e2013-05-23 20:51:341279 base::MessageLoop::current()->RunUntilIdle();
[email protected]43a21b82010-06-10 21:30:541280
1281 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1282 // reuse a socket.
1283 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1284 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521285 TestCompletionCallback callback;
[email protected]43a21b82010-06-10 21:30:541286
1287 // "0" is special here, since it should be the first entry in the sorted map,
1288 // which is the one which we would close an idle socket for. We shouldn't
1289 // close an idle socket though, since we should reuse the idle socket.
[email protected]2431756e2010-09-29 20:26:131290 EXPECT_EQ(OK, handle.Init("0",
1291 params_,
1292 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521293 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131294 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211295 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541296
1297 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1298 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1299}
1300
[email protected]ab838892009-06-30 18:49:051301TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531302 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091303
[email protected]c9d6a1d2009-07-14 16:15:201304 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1305 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]c9c6f5c2010-07-31 01:30:031306 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", IDLE));
[email protected]ac790b42009-12-02 04:31:311307 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1308 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1309 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1310 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1311 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091312
[email protected]2431756e2010-09-29 20:26:131313 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091314
[email protected]c9d6a1d2009-07-14 16:15:201315 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1316 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131317 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1318 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091319
[email protected]c9d6a1d2009-07-14 16:15:201320 EXPECT_EQ(1, GetOrderOfRequest(1));
1321 EXPECT_EQ(2, GetOrderOfRequest(2));
[email protected]c9c6f5c2010-07-31 01:30:031322 EXPECT_EQ(8, GetOrderOfRequest(3));
1323 EXPECT_EQ(6, GetOrderOfRequest(4));
1324 EXPECT_EQ(4, GetOrderOfRequest(5));
1325 EXPECT_EQ(3, GetOrderOfRequest(6));
1326 EXPECT_EQ(5, GetOrderOfRequest(7));
1327 EXPECT_EQ(7, GetOrderOfRequest(8));
[email protected]75439d3b2009-07-23 22:11:171328
1329 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131330 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]f6d1d6eb2009-06-24 20:16:091331}
1332
[email protected]ab838892009-06-30 18:49:051333TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531334 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091335
[email protected]c9d6a1d2009-07-14 16:15:201336 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1337 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311338 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1339 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1340 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1341 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1342 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091343
[email protected]2431756e2010-09-29 20:26:131344 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091345
[email protected]2431756e2010-09-29 20:26:131346 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
1347 EXPECT_EQ(OK, request(i)->WaitForResult());
[email protected]c9d6a1d2009-07-14 16:15:201348
[email protected]2431756e2010-09-29 20:26:131349 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]c9d6a1d2009-07-14 16:15:201350 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131351 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1352 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091353}
1354
1355// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:051356// The pending connect job will be cancelled and should not call back into
1357// ClientSocketPoolBase.
1358TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531359 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201360
[email protected]ab838892009-06-30 18:49:051361 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131362 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521363 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131364 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1365 params_,
1366 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521367 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131368 pool_.get(),
1369 BoundNetLog()));
1370 handle.Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091371}
1372
[email protected]ab838892009-06-30 18:49:051373TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531374 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201375
[email protected]ab838892009-06-30 18:49:051376 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061377 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521378 TestCompletionCallback callback;
[email protected]f6d1d6eb2009-06-24 20:16:091379
[email protected]2431756e2010-09-29 20:26:131380 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1381 params_,
1382 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521383 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131384 pool_.get(),
1385 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091386
1387 handle.Reset();
1388
[email protected]6ecf2b92011-12-15 01:14:521389 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:131390 EXPECT_EQ(ERR_IO_PENDING,
1391 handle.Init("a",
1392 params_,
1393 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521394 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:131395 pool_.get(),
1396 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091397
1398 EXPECT_EQ(OK, callback2.WaitForResult());
1399 EXPECT_FALSE(callback.have_result());
1400
1401 handle.Reset();
1402}
1403
[email protected]ab838892009-06-30 18:49:051404TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531405 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091406
[email protected]c9d6a1d2009-07-14 16:15:201407 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1408 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311409 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1410 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1411 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1412 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1413 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091414
1415 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201416 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]2431756e2010-09-29 20:26:131417 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1418 (*requests())[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091419
[email protected]2431756e2010-09-29 20:26:131420 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091421
[email protected]c9d6a1d2009-07-14 16:15:201422 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1423 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131424 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1425 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091426
[email protected]c9d6a1d2009-07-14 16:15:201427 EXPECT_EQ(1, GetOrderOfRequest(1));
1428 EXPECT_EQ(2, GetOrderOfRequest(2));
1429 EXPECT_EQ(5, GetOrderOfRequest(3));
1430 EXPECT_EQ(3, GetOrderOfRequest(4));
[email protected]2431756e2010-09-29 20:26:131431 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1432 GetOrderOfRequest(5)); // Canceled request.
[email protected]c9d6a1d2009-07-14 16:15:201433 EXPECT_EQ(4, GetOrderOfRequest(6));
1434 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171435
1436 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131437 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091438}
1439
[email protected]6ecf2b92011-12-15 01:14:521440class RequestSocketCallback : public TestCompletionCallbackBase {
[email protected]f6d1d6eb2009-06-24 20:16:091441 public:
[email protected]2ab05b52009-07-01 23:57:581442 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:241443 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:581444 TestConnectJobFactory* test_connect_job_factory,
1445 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:091446 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:061447 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:581448 within_callback_(false),
1449 test_connect_job_factory_(test_connect_job_factory),
[email protected]6ecf2b92011-12-15 01:14:521450 next_job_type_(next_job_type),
[email protected]aa249b52013-04-30 01:04:321451 callback_(base::Bind(&RequestSocketCallback::OnComplete,
1452 base::Unretained(this))) {
[email protected]6ecf2b92011-12-15 01:14:521453 }
[email protected]f6d1d6eb2009-06-24 20:16:091454
[email protected]6ecf2b92011-12-15 01:14:521455 virtual ~RequestSocketCallback() {}
1456
1457 const CompletionCallback& callback() const { return callback_; }
1458
1459 private:
1460 void OnComplete(int result) {
1461 SetResult(result);
1462 ASSERT_EQ(OK, result);
[email protected]f6d1d6eb2009-06-24 20:16:091463
1464 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:581465 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]5edbf8d2010-01-13 18:44:111466
1467 // Don't allow reuse of the socket. Disconnect it and then release it and
1468 // run through the MessageLoop once to get it completely released.
1469 handle_->socket()->Disconnect();
[email protected]f6d1d6eb2009-06-24 20:16:091470 handle_->Reset();
[email protected]5edbf8d2010-01-13 18:44:111471 {
[email protected]b5717a42012-02-14 19:33:521472 // TODO: Resolve conflicting intentions of stopping recursion with the
[email protected]b4c62eb2012-11-14 18:36:511473 // |!within_callback_| test (above) and the call to |RunUntilIdle()|
[email protected]b5717a42012-02-14 19:33:521474 // below. http://crbug.com/114130.
[email protected]2da659e2013-05-23 20:51:341475 base::MessageLoop::ScopedNestableTaskAllower allow(
1476 base::MessageLoop::current());
1477 base::MessageLoop::current()->RunUntilIdle();
[email protected]5edbf8d2010-01-13 18:44:111478 }
[email protected]f6d1d6eb2009-06-24 20:16:091479 within_callback_ = true;
[email protected]6ecf2b92011-12-15 01:14:521480 TestCompletionCallback next_job_callback;
[email protected]ad8e04a2010-11-01 04:16:271481 scoped_refptr<TestSocketParams> params(new TestSocketParams());
[email protected]2431756e2010-09-29 20:26:131482 int rv = handle_->Init("a",
1483 params,
1484 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521485 next_job_callback.callback(),
[email protected]2431756e2010-09-29 20:26:131486 pool_,
1487 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581488 switch (next_job_type_) {
1489 case TestConnectJob::kMockJob:
1490 EXPECT_EQ(OK, rv);
1491 break;
1492 case TestConnectJob::kMockPendingJob:
1493 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:471494
1495 // For pending jobs, wait for new socket to be created. This makes
1496 // sure there are no more pending operations nor any unclosed sockets
1497 // when the test finishes.
1498 // We need to give it a little bit of time to run, so that all the
1499 // operations that happen on timers (e.g. cleanup of idle
1500 // connections) can execute.
[email protected]5edbf8d2010-01-13 18:44:111501 {
[email protected]2da659e2013-05-23 20:51:341502 base::MessageLoop::ScopedNestableTaskAllower allow(
1503 base::MessageLoop::current());
[email protected]26b9973962012-01-28 00:57:001504 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
[email protected]5edbf8d2010-01-13 18:44:111505 EXPECT_EQ(OK, next_job_callback.WaitForResult());
1506 }
[email protected]2ab05b52009-07-01 23:57:581507 break;
1508 default:
1509 FAIL() << "Unexpected job type: " << next_job_type_;
1510 break;
1511 }
[email protected]f6d1d6eb2009-06-24 20:16:091512 }
1513 }
1514
[email protected]f6d1d6eb2009-06-24 20:16:091515 ClientSocketHandle* const handle_;
[email protected]2431756e2010-09-29 20:26:131516 TestClientSocketPool* const pool_;
[email protected]f6d1d6eb2009-06-24 20:16:091517 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:581518 TestConnectJobFactory* const test_connect_job_factory_;
1519 TestConnectJob::JobType next_job_type_;
[email protected]6ecf2b92011-12-15 01:14:521520 CompletionCallback callback_;
[email protected]f6d1d6eb2009-06-24 20:16:091521};
1522
[email protected]2ab05b52009-07-01 23:57:581523TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531524 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201525
[email protected]0b7648c2009-07-06 20:14:011526 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061527 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581528 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061529 &handle, pool_.get(), connect_job_factory_,
1530 TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131531 int rv = handle.Init("a",
1532 params_,
1533 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521534 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131535 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211536 BoundNetLog());
[email protected]f6d1d6eb2009-06-24 20:16:091537 ASSERT_EQ(ERR_IO_PENDING, rv);
1538
1539 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581540}
[email protected]f6d1d6eb2009-06-24 20:16:091541
[email protected]2ab05b52009-07-01 23:57:581542TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531543 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201544
[email protected]0b7648c2009-07-06 20:14:011545 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061546 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581547 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061548 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]2431756e2010-09-29 20:26:131549 int rv = handle.Init("a",
1550 params_,
1551 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521552 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131553 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211554 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581555 ASSERT_EQ(ERR_IO_PENDING, rv);
1556
1557 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091558}
1559
1560// Make sure that pending requests get serviced after active requests get
1561// cancelled.
[email protected]ab838892009-06-30 18:49:051562TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531563 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201564
[email protected]0b7648c2009-07-06 20:14:011565 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091566
[email protected]c9d6a1d2009-07-14 16:15:201567 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1568 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1569 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1570 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1571 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1572 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1573 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091574
[email protected]c9d6a1d2009-07-14 16:15:201575 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1576 // Let's cancel them.
1577 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]2431756e2010-09-29 20:26:131578 ASSERT_FALSE(request(i)->handle()->is_initialized());
1579 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091580 }
1581
[email protected]f6d1d6eb2009-06-24 20:16:091582 // Let's wait for the rest to complete now.
[email protected]2431756e2010-09-29 20:26:131583 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
1584 EXPECT_EQ(OK, request(i)->WaitForResult());
1585 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091586 }
1587
[email protected]2431756e2010-09-29 20:26:131588 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1589 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091590}
1591
1592// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051593TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531594 const size_t kMaxSockets = 5;
1595 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201596
[email protected]0b7648c2009-07-06 20:14:011597 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091598
[email protected]211d21722009-07-22 15:48:531599 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1600 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091601
1602 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531603 for (size_t i = 0; i < kNumberOfRequests; ++i)
1604 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091605
[email protected]211d21722009-07-22 15:48:531606 for (size_t i = 0; i < kNumberOfRequests; ++i)
[email protected]2431756e2010-09-29 20:26:131607 EXPECT_EQ(ERR_CONNECTION_FAILED, request(i)->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091608}
1609
[email protected]5fc08e32009-07-15 17:09:571610TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531611 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571612
1613 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1614
[email protected]2431756e2010-09-29 20:26:131615 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521616 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131617 int rv = handle.Init("a",
1618 params_,
1619 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521620 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131621 pool_.get(),
1622 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571623 EXPECT_EQ(ERR_IO_PENDING, rv);
1624
1625 // Cancel the active request.
[email protected]2431756e2010-09-29 20:26:131626 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571627
[email protected]2431756e2010-09-29 20:26:131628 rv = handle.Init("a",
1629 params_,
1630 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521631 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131632 pool_.get(),
1633 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571634 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131635 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]5fc08e32009-07-15 17:09:571636
[email protected]2431756e2010-09-29 20:26:131637 EXPECT_FALSE(handle.is_reused());
[email protected]034df0f32013-01-07 23:17:481638 TestLoadTimingInfoConnectedNotReused(handle);
[email protected]5fc08e32009-07-15 17:09:571639 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1640}
1641
[email protected]2b7523d2009-07-29 20:29:231642// Regression test for http://crbug.com/17985.
1643TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1644 const int kMaxSockets = 3;
1645 const int kMaxSocketsPerGroup = 2;
1646 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1647
[email protected]ac790b42009-12-02 04:31:311648 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231649
1650 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1651 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1652
1653 // This is going to be a pending request in an otherwise empty group.
1654 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1655
1656 // Reach the maximum socket limit.
1657 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1658
1659 // Create a stalled group with high priorities.
1660 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1661 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
[email protected]2b7523d2009-07-29 20:29:231662
[email protected]eb5a99382010-07-11 03:18:261663 // Release the first two sockets from "a". Because this is a keepalive,
1664 // the first release will unblock the pending request for "a". The
1665 // second release will unblock a request for "c", becaue it is the next
1666 // high priority socket.
[email protected]2431756e2010-09-29 20:26:131667 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1668 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]2b7523d2009-07-29 20:29:231669
1670 // Closing idle sockets should not get us into trouble, but in the bug
1671 // we were hitting a CHECK here.
[email protected]93054cc12010-06-08 06:12:411672 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]43a21b82010-06-10 21:30:541673 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261674
[email protected]2da659e2013-05-23 20:51:341675 // Run the released socket wakeups.
1676 base::MessageLoop::current()->RunUntilIdle();
[email protected]2b7523d2009-07-29 20:29:231677}
1678
[email protected]4d3b05d2010-01-27 21:27:291679TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531680 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571681
1682 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131683 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521684 TestCompletionCallback callback;
[email protected]333bdf62012-06-08 22:57:291685 CapturingBoundNetLog log;
[email protected]2431756e2010-09-29 20:26:131686 int rv = handle.Init("a",
1687 params_,
1688 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:521689 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131690 pool_.get(),
1691 log.bound());
[email protected]5fc08e32009-07-15 17:09:571692 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131693 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
[email protected]034df0f32013-01-07 23:17:481694 TestLoadTimingInfoNotConnected(handle);
1695
[email protected]2431756e2010-09-29 20:26:131696 EXPECT_EQ(OK, callback.WaitForResult());
1697 EXPECT_TRUE(handle.is_initialized());
1698 EXPECT_TRUE(handle.socket());
[email protected]034df0f32013-01-07 23:17:481699 TestLoadTimingInfoConnectedNotReused(handle);
1700
[email protected]2431756e2010-09-29 20:26:131701 handle.Reset();
[email protected]034df0f32013-01-07 23:17:481702 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:301703
[email protected]333bdf62012-06-08 22:57:291704 CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:401705 log.GetEntries(&entries);
1706
1707 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:461708 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401709 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171710 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401711 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171712 NetLog::PHASE_NONE));
1713 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401714 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]06650c52010-06-03 00:49:171715 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:461716 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401717 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571718}
1719
[email protected]4d3b05d2010-01-27 21:27:291720TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571721 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531722 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571723
1724 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2431756e2010-09-29 20:26:131725 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521726 TestCompletionCallback callback;
[email protected]333bdf62012-06-08 22:57:291727 CapturingBoundNetLog log;
[email protected]e60e47a2010-07-14 03:37:181728 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:131729 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:431730 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:451731 info.headers = new HttpResponseHeaders(std::string());
[email protected]2431756e2010-09-29 20:26:131732 handle.set_ssl_error_response_info(info);
1733 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1734 params_,
1735 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521736 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131737 pool_.get(),
1738 log.bound()));
1739 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1740 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1741 EXPECT_FALSE(handle.is_ssl_error());
1742 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:301743
[email protected]333bdf62012-06-08 22:57:291744 CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:401745 log.GetEntries(&entries);
1746
1747 EXPECT_EQ(3u, entries.size());
[email protected]e9002a92010-01-29 07:10:461748 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401749 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171750 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401751 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171752 NetLog::PHASE_NONE));
[email protected]6b624c62010-03-14 08:37:321753 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401754 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571755}
1756
[email protected]4d3b05d2010-01-27 21:27:291757TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101758 // TODO(eroman): Add back the log expectations! Removed them because the
1759 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531760 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571761
1762 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131763 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521764 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131765 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:521766 TestCompletionCallback callback2;
[email protected]5fc08e32009-07-15 17:09:571767
[email protected]2431756e2010-09-29 20:26:131768 EXPECT_EQ(ERR_IO_PENDING,
1769 handle.Init("a",
1770 params_,
1771 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521772 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131773 pool_.get(),
1774 BoundNetLog()));
[email protected]333bdf62012-06-08 22:57:291775 CapturingBoundNetLog log2;
[email protected]2431756e2010-09-29 20:26:131776 EXPECT_EQ(ERR_IO_PENDING,
1777 handle2.Init("a",
1778 params_,
1779 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521780 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:131781 pool_.get(),
1782 BoundNetLog()));
[email protected]5fc08e32009-07-15 17:09:571783
[email protected]2431756e2010-09-29 20:26:131784 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571785
[email protected]fd7b7c92009-08-20 19:38:301786
1787 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301788
[email protected]2431756e2010-09-29 20:26:131789 EXPECT_EQ(OK, callback2.WaitForResult());
1790 handle2.Reset();
[email protected]fd7b7c92009-08-20 19:38:301791
1792 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531793 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571794}
1795
[email protected]4d3b05d2010-01-27 21:27:291796TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341797 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1798
[email protected]17a0c6c2009-08-04 00:07:041799 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1800
[email protected]ac790b42009-12-02 04:31:311801 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1802 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1803 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1804 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341805
1806 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]2431756e2010-09-29 20:26:131807 (*requests())[2]->handle()->Reset();
1808 (*requests())[3]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341809 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1810
[email protected]2431756e2010-09-29 20:26:131811 (*requests())[1]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341812 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1813
[email protected]2431756e2010-09-29 20:26:131814 (*requests())[0]->handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261815 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]974ebd62009-08-03 23:14:341816}
1817
[email protected]5fc08e32009-07-15 17:09:571818// When requests and ConnectJobs are not coupled, the request will get serviced
1819// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291820TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531821 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571822
1823 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321824 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571825
[email protected]2431756e2010-09-29 20:26:131826 std::vector<TestSocketRequest*> request_order;
1827 size_t completion_count; // unused
1828 TestSocketRequest req1(&request_order, &completion_count);
1829 int rv = req1.handle()->Init("a",
1830 params_,
1831 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521832 req1.callback(), pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211833 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571834 EXPECT_EQ(ERR_IO_PENDING, rv);
1835 EXPECT_EQ(OK, req1.WaitForResult());
1836
1837 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1838 // without a job.
1839 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1840
[email protected]2431756e2010-09-29 20:26:131841 TestSocketRequest req2(&request_order, &completion_count);
1842 rv = req2.handle()->Init("a",
1843 params_,
1844 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521845 req2.callback(),
[email protected]2431756e2010-09-29 20:26:131846 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211847 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571848 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131849 TestSocketRequest req3(&request_order, &completion_count);
1850 rv = req3.handle()->Init("a",
1851 params_,
1852 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521853 req3.callback(),
[email protected]2431756e2010-09-29 20:26:131854 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211855 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571856 EXPECT_EQ(ERR_IO_PENDING, rv);
1857
1858 // Both Requests 2 and 3 are pending. We release socket 1 which should
1859 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331860 req1.handle()->Reset();
[email protected]2da659e2013-05-23 20:51:341861 // Run the released socket wakeups.
1862 base::MessageLoop::current()->RunUntilIdle();
[email protected]a6c59f62009-07-29 16:33:331863 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571864 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331865 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571866
1867 // Signal job 2, which should service request 3.
1868
1869 client_socket_factory_.SignalJobs();
1870 EXPECT_EQ(OK, req3.WaitForResult());
1871
[email protected]2431756e2010-09-29 20:26:131872 ASSERT_EQ(3U, request_order.size());
1873 EXPECT_EQ(&req1, request_order[0]);
1874 EXPECT_EQ(&req2, request_order[1]);
1875 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571876 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1877}
1878
1879// The requests are not coupled to the jobs. So, the requests should finish in
1880// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:291881TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531882 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571883 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321884 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571885
[email protected]2431756e2010-09-29 20:26:131886 std::vector<TestSocketRequest*> request_order;
1887 size_t completion_count; // unused
1888 TestSocketRequest req1(&request_order, &completion_count);
1889 int rv = req1.handle()->Init("a",
1890 params_,
1891 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521892 req1.callback(),
[email protected]2431756e2010-09-29 20:26:131893 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211894 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571895 EXPECT_EQ(ERR_IO_PENDING, rv);
1896
[email protected]2431756e2010-09-29 20:26:131897 TestSocketRequest req2(&request_order, &completion_count);
1898 rv = req2.handle()->Init("a",
1899 params_,
1900 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521901 req2.callback(),
[email protected]2431756e2010-09-29 20:26:131902 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211903 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571904 EXPECT_EQ(ERR_IO_PENDING, rv);
1905
1906 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321907 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571908
[email protected]2431756e2010-09-29 20:26:131909 TestSocketRequest req3(&request_order, &completion_count);
1910 rv = req3.handle()->Init("a",
1911 params_,
1912 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521913 req3.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 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1919 EXPECT_EQ(OK, req2.WaitForResult());
1920 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1921
[email protected]2431756e2010-09-29 20:26:131922 ASSERT_EQ(3U, request_order.size());
1923 EXPECT_EQ(&req1, request_order[0]);
1924 EXPECT_EQ(&req2, request_order[1]);
1925 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571926}
1927
[email protected]03b7c8c2013-07-20 04:38:551928// Test GetLoadState in the case there's only one socket request.
1929TEST_F(ClientSocketPoolBaseTest, LoadStateOneRequest) {
[email protected]211d21722009-07-22 15:48:531930 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]03b7c8c2013-07-20 04:38:551931 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]5fc08e32009-07-15 17:09:571932
[email protected]2431756e2010-09-29 20:26:131933 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521934 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131935 int rv = handle.Init("a",
1936 params_,
1937 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521938 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131939 pool_.get(),
1940 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571941 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]03b7c8c2013-07-20 04:38:551942 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571943
[email protected]03b7c8c2013-07-20 04:38:551944 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
1945 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
1946
1947 // No point in completing the connection, since ClientSocketHandles only
1948 // expect the LoadState to be checked while connecting.
1949}
1950
1951// Test GetLoadState in the case there are two socket requests.
1952TEST_F(ClientSocketPoolBaseTest, LoadStateTwoRequests) {
1953 CreatePool(2, 2);
1954 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1955
1956 ClientSocketHandle handle;
1957 TestCompletionCallback callback;
1958 int rv = handle.Init("a",
1959 params_,
1960 kDefaultPriority,
1961 callback.callback(),
1962 pool_.get(),
1963 BoundNetLog());
1964 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]5fc08e32009-07-15 17:09:571965
[email protected]2431756e2010-09-29 20:26:131966 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:521967 TestCompletionCallback callback2;
[email protected]03b7c8c2013-07-20 04:38:551968 rv = handle2.Init("a",
1969 params_,
1970 kDefaultPriority,
1971 callback2.callback(),
1972 pool_.get(),
1973 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571974 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]03b7c8c2013-07-20 04:38:551975
1976 // If the first Job is in an earlier state than the second, the state of
1977 // the second job should be used for both handles.
1978 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
1979 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
1980 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
1981
1982 // If the second Job is in an earlier state than the second, the state of
1983 // the first job should be used for both handles.
1984 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
1985 // One request is farther
1986 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
1987 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle2.GetLoadState());
1988
1989 // Farthest along job connects and the first request gets the socket. The
1990 // second handle switches to the state of the remaining ConnectJob.
1991 client_socket_factory_.SignalJob(0);
1992 EXPECT_EQ(OK, callback.WaitForResult());
1993 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
1994}
1995
1996// Test GetLoadState in the case the per-group limit is reached.
1997TEST_F(ClientSocketPoolBaseTest, LoadStateGroupLimit) {
1998 CreatePool(2, 1);
1999 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2000
2001 ClientSocketHandle handle;
2002 TestCompletionCallback callback;
2003 int rv = handle.Init("a",
2004 params_,
2005 MEDIUM,
2006 callback.callback(),
2007 pool_.get(),
2008 BoundNetLog());
2009 EXPECT_EQ(ERR_IO_PENDING, rv);
2010 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2011
2012 // Request another socket from the same pool, buth with a higher priority.
2013 // The first request should now be stalled at the socket group limit.
2014 ClientSocketHandle handle2;
2015 TestCompletionCallback callback2;
2016 rv = handle2.Init("a",
2017 params_,
2018 HIGHEST,
2019 callback2.callback(),
2020 pool_.get(),
2021 BoundNetLog());
2022 EXPECT_EQ(ERR_IO_PENDING, rv);
2023 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2024 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
2025
2026 // The first handle should remain stalled as the other socket goes through
2027 // the connect process.
2028
2029 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2030 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2031 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle2.GetLoadState());
2032
2033 client_socket_factory_.SignalJob(0);
2034 EXPECT_EQ(OK, callback2.WaitForResult());
2035 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2036
2037 // Closing the second socket should cause the stalled handle to finally get a
2038 // ConnectJob.
2039 handle2.socket()->Disconnect();
2040 handle2.Reset();
2041 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2042}
2043
2044// Test GetLoadState in the case the per-pool limit is reached.
2045TEST_F(ClientSocketPoolBaseTest, LoadStatePoolLimit) {
2046 CreatePool(2, 2);
2047 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2048
2049 ClientSocketHandle handle;
2050 TestCompletionCallback callback;
2051 int rv = handle.Init("a",
2052 params_,
2053 kDefaultPriority,
2054 callback.callback(),
2055 pool_.get(),
2056 BoundNetLog());
2057 EXPECT_EQ(ERR_IO_PENDING, rv);
2058
2059 // Request for socket from another pool.
2060 ClientSocketHandle handle2;
2061 TestCompletionCallback callback2;
2062 rv = handle2.Init("b",
2063 params_,
2064 kDefaultPriority,
2065 callback2.callback(),
2066 pool_.get(),
2067 BoundNetLog());
2068 EXPECT_EQ(ERR_IO_PENDING, rv);
2069
2070 // Request another socket from the first pool. Request should stall at the
2071 // socket pool limit.
2072 ClientSocketHandle handle3;
2073 TestCompletionCallback callback3;
2074 rv = handle3.Init("a",
2075 params_,
2076 kDefaultPriority,
2077 callback2.callback(),
2078 pool_.get(),
2079 BoundNetLog());
2080 EXPECT_EQ(ERR_IO_PENDING, rv);
2081
2082 // The third handle should remain stalled as the other sockets in its group
2083 // goes through the connect process.
2084
2085 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2086 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2087
2088 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2089 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
2090 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2091
2092 client_socket_factory_.SignalJob(0);
2093 EXPECT_EQ(OK, callback.WaitForResult());
2094 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2095
2096 // Closing a socket should allow the stalled handle to finally get a new
2097 // ConnectJob.
2098 handle.socket()->Disconnect();
2099 handle.Reset();
2100 EXPECT_EQ(LOAD_STATE_CONNECTING, handle3.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:572101}
2102
[email protected]e772db3f2010-07-12 18:11:132103TEST_F(ClientSocketPoolBaseTest, Recoverable) {
2104 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2105 connect_job_factory_->set_job_type(TestConnectJob::kMockRecoverableJob);
2106
[email protected]2431756e2010-09-29 20:26:132107 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522108 TestCompletionCallback callback;
2109 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED,
2110 handle.Init("a", params_, kDefaultPriority, callback.callback(),
2111 pool_.get(), BoundNetLog()));
[email protected]2431756e2010-09-29 20:26:132112 EXPECT_TRUE(handle.is_initialized());
2113 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:132114}
2115
2116TEST_F(ClientSocketPoolBaseTest, AsyncRecoverable) {
2117 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2118
2119 connect_job_factory_->set_job_type(
2120 TestConnectJob::kMockPendingRecoverableJob);
[email protected]2431756e2010-09-29 20:26:132121 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522122 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132123 EXPECT_EQ(ERR_IO_PENDING,
2124 handle.Init("a",
2125 params_,
2126 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522127 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132128 pool_.get(),
2129 BoundNetLog()));
2130 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2131 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, callback.WaitForResult());
2132 EXPECT_TRUE(handle.is_initialized());
2133 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:132134}
2135
[email protected]e60e47a2010-07-14 03:37:182136TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
2137 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2138 connect_job_factory_->set_job_type(
2139 TestConnectJob::kMockAdditionalErrorStateJob);
2140
[email protected]2431756e2010-09-29 20:26:132141 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522142 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132143 EXPECT_EQ(ERR_CONNECTION_FAILED,
2144 handle.Init("a",
2145 params_,
2146 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522147 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132148 pool_.get(),
2149 BoundNetLog()));
2150 EXPECT_FALSE(handle.is_initialized());
2151 EXPECT_FALSE(handle.socket());
2152 EXPECT_TRUE(handle.is_ssl_error());
2153 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182154}
2155
2156TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
2157 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2158
2159 connect_job_factory_->set_job_type(
2160 TestConnectJob::kMockPendingAdditionalErrorStateJob);
[email protected]2431756e2010-09-29 20:26:132161 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522162 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132163 EXPECT_EQ(ERR_IO_PENDING,
2164 handle.Init("a",
2165 params_,
2166 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522167 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132168 pool_.get(),
2169 BoundNetLog()));
2170 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2171 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
2172 EXPECT_FALSE(handle.is_initialized());
2173 EXPECT_FALSE(handle.socket());
2174 EXPECT_TRUE(handle.is_ssl_error());
2175 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182176}
2177
[email protected]e7b1c6d2c2012-05-05 00:54:032178// Make sure we can reuse sockets when the cleanup timer is disabled.
2179TEST_F(ClientSocketPoolBaseTest, DisableCleanupTimerReuse) {
[email protected]64770b7d2011-11-16 04:30:412180 // Disable cleanup timer.
2181 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(false);
2182
2183 CreatePoolWithIdleTimeouts(
2184 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
[email protected]e7b1c6d2c2012-05-05 00:54:032185 base::TimeDelta(), // Time out unused sockets immediately.
2186 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2187
2188 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2189
2190 ClientSocketHandle handle;
2191 TestCompletionCallback callback;
2192 int rv = handle.Init("a",
2193 params_,
2194 LOWEST,
2195 callback.callback(),
2196 pool_.get(),
2197 BoundNetLog());
2198 ASSERT_EQ(ERR_IO_PENDING, rv);
2199 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2200 ASSERT_EQ(OK, callback.WaitForResult());
2201
2202 // Use and release the socket.
2203 EXPECT_EQ(1, handle.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]034df0f32013-01-07 23:17:482204 TestLoadTimingInfoConnectedNotReused(handle);
[email protected]e7b1c6d2c2012-05-05 00:54:032205 handle.Reset();
2206
2207 // Should now have one idle socket.
2208 ASSERT_EQ(1, pool_->IdleSocketCount());
2209
2210 // Request a new socket. This should reuse the old socket and complete
2211 // synchronously.
[email protected]333bdf62012-06-08 22:57:292212 CapturingBoundNetLog log;
[email protected]e7b1c6d2c2012-05-05 00:54:032213 rv = handle.Init("a",
2214 params_,
2215 LOWEST,
2216 CompletionCallback(),
2217 pool_.get(),
2218 log.bound());
2219 ASSERT_EQ(OK, rv);
2220 EXPECT_TRUE(handle.is_reused());
[email protected]034df0f32013-01-07 23:17:482221 TestLoadTimingInfoConnectedReused(handle);
[email protected]e7b1c6d2c2012-05-05 00:54:032222
2223 ASSERT_TRUE(pool_->HasGroup("a"));
2224 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2225 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2226
[email protected]333bdf62012-06-08 22:57:292227 CapturingNetLog::CapturedEntryList entries;
[email protected]e7b1c6d2c2012-05-05 00:54:032228 log.GetEntries(&entries);
2229 EXPECT_TRUE(LogContainsEntryWithType(
2230 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
2231}
2232
2233// Make sure we cleanup old unused sockets when the cleanup timer is disabled.
2234TEST_F(ClientSocketPoolBaseTest, DisableCleanupTimerNoReuse) {
2235 // Disable cleanup timer.
2236 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(false);
2237
2238 CreatePoolWithIdleTimeouts(
2239 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2240 base::TimeDelta(), // Time out unused sockets immediately
2241 base::TimeDelta()); // Time out used sockets immediately
[email protected]64770b7d2011-11-16 04:30:412242
2243 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2244
2245 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2246
2247 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522248 TestCompletionCallback callback;
[email protected]64770b7d2011-11-16 04:30:412249 int rv = handle.Init("a",
2250 params_,
2251 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522252 callback.callback(),
[email protected]64770b7d2011-11-16 04:30:412253 pool_.get(),
2254 BoundNetLog());
[email protected]e7b1c6d2c2012-05-05 00:54:032255 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]64770b7d2011-11-16 04:30:412256 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2257
2258 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522259 TestCompletionCallback callback2;
[email protected]64770b7d2011-11-16 04:30:412260 rv = handle2.Init("a",
2261 params_,
2262 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522263 callback2.callback(),
[email protected]64770b7d2011-11-16 04:30:412264 pool_.get(),
2265 BoundNetLog());
[email protected]e7b1c6d2c2012-05-05 00:54:032266 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]64770b7d2011-11-16 04:30:412267 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
2268
2269 // Cancel one of the requests. Wait for the other, which will get the first
2270 // job. Release the socket. Run the loop again to make sure the second
2271 // socket is sitting idle and the first one is released (since ReleaseSocket()
2272 // just posts a DoReleaseSocket() task).
2273
2274 handle.Reset();
[email protected]e7b1c6d2c2012-05-05 00:54:032275 ASSERT_EQ(OK, callback2.WaitForResult());
[email protected]64770b7d2011-11-16 04:30:412276 // Use the socket.
[email protected]83039bb2011-12-09 18:43:552277 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]64770b7d2011-11-16 04:30:412278 handle2.Reset();
2279
[email protected]e7b1c6d2c2012-05-05 00:54:032280 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2281 // actually become pending until 2ms after they have been created. In order
2282 // to flush all tasks, we need to wait so that we know there are no
2283 // soon-to-be-pending tasks waiting.
2284 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
[email protected]2da659e2013-05-23 20:51:342285 base::MessageLoop::current()->RunUntilIdle();
[email protected]64770b7d2011-11-16 04:30:412286
[email protected]e7b1c6d2c2012-05-05 00:54:032287 // Both sockets should now be idle.
[email protected]64770b7d2011-11-16 04:30:412288 ASSERT_EQ(2, pool_->IdleSocketCount());
2289
2290 // Request a new socket. This should cleanup the unused and timed out ones.
2291 // A new socket will be created rather than reusing the idle one.
[email protected]333bdf62012-06-08 22:57:292292 CapturingBoundNetLog log;
[email protected]6ecf2b92011-12-15 01:14:522293 TestCompletionCallback callback3;
[email protected]64770b7d2011-11-16 04:30:412294 rv = handle.Init("a",
2295 params_,
2296 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522297 callback3.callback(),
[email protected]64770b7d2011-11-16 04:30:412298 pool_.get(),
2299 log.bound());
[email protected]e7b1c6d2c2012-05-05 00:54:032300 ASSERT_EQ(ERR_IO_PENDING, rv);
2301 ASSERT_EQ(OK, callback3.WaitForResult());
[email protected]64770b7d2011-11-16 04:30:412302 EXPECT_FALSE(handle.is_reused());
2303
[email protected]e7b1c6d2c2012-05-05 00:54:032304 // Make sure the idle socket is closed.
[email protected]64770b7d2011-11-16 04:30:412305 ASSERT_TRUE(pool_->HasGroup("a"));
2306 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2307 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2308
[email protected]333bdf62012-06-08 22:57:292309 CapturingNetLog::CapturedEntryList entries;
[email protected]64770b7d2011-11-16 04:30:412310 log.GetEntries(&entries);
2311 EXPECT_FALSE(LogContainsEntryWithType(
2312 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
2313}
2314
[email protected]4d3b05d2010-01-27 21:27:292315TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
[email protected]9bf28db2009-08-29 01:35:162316 CreatePoolWithIdleTimeouts(
2317 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2318 base::TimeDelta(), // Time out unused sockets immediately.
2319 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2320
2321 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2322
2323 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2324
[email protected]2431756e2010-09-29 20:26:132325 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522326 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132327 int rv = handle.Init("a",
2328 params_,
2329 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522330 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132331 pool_.get(),
2332 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:162333 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:132334 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
[email protected]9bf28db2009-08-29 01:35:162335
[email protected]2431756e2010-09-29 20:26:132336 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522337 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132338 rv = handle2.Init("a",
2339 params_,
2340 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522341 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132342 pool_.get(),
2343 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:162344 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:132345 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
[email protected]9bf28db2009-08-29 01:35:162346
2347 // Cancel one of the requests. Wait for the other, which will get the first
2348 // job. Release the socket. Run the loop again to make sure the second
2349 // socket is sitting idle and the first one is released (since ReleaseSocket()
2350 // just posts a DoReleaseSocket() task).
2351
[email protected]2431756e2010-09-29 20:26:132352 handle.Reset();
2353 EXPECT_EQ(OK, callback2.WaitForResult());
[email protected]0f873e82010-09-02 16:09:012354 // Use the socket.
[email protected]83039bb2011-12-09 18:43:552355 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]2431756e2010-09-29 20:26:132356 handle2.Reset();
[email protected]6b175382009-10-13 06:47:472357
2358 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2359 // actually become pending until 2ms after they have been created. In order
2360 // to flush all tasks, we need to wait so that we know there are no
2361 // soon-to-be-pending tasks waiting.
[email protected]26b9973962012-01-28 00:57:002362 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
[email protected]2da659e2013-05-23 20:51:342363 base::MessageLoop::current()->RunUntilIdle();
[email protected]9bf28db2009-08-29 01:35:162364
2365 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:042366
[email protected]9bf28db2009-08-29 01:35:162367 // Invoke the idle socket cleanup check. Only one socket should be left, the
2368 // used socket. Request it to make sure that it's used.
2369
2370 pool_->CleanupTimedOutIdleSockets();
[email protected]333bdf62012-06-08 22:57:292371 CapturingBoundNetLog log;
[email protected]2431756e2010-09-29 20:26:132372 rv = handle.Init("a",
2373 params_,
2374 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522375 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132376 pool_.get(),
2377 log.bound());
[email protected]9bf28db2009-08-29 01:35:162378 EXPECT_EQ(OK, rv);
[email protected]2431756e2010-09-29 20:26:132379 EXPECT_TRUE(handle.is_reused());
[email protected]b2fcd0e2010-12-01 15:19:402380
[email protected]333bdf62012-06-08 22:57:292381 CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402382 log.GetEntries(&entries);
[email protected]fd4fe0b2010-02-08 23:02:152383 EXPECT_TRUE(LogContainsEntryWithType(
[email protected]b2fcd0e2010-12-01 15:19:402384 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]9bf28db2009-08-29 01:35:162385}
2386
[email protected]2041cf342010-02-19 03:15:592387// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:162388// because of multiple releasing disconnected sockets.
2389TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
2390 CreatePoolWithIdleTimeouts(
2391 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2392 base::TimeDelta(), // Time out unused sockets immediately.
2393 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2394
2395 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2396
2397 // Startup 4 connect jobs. Two of them will be pending.
2398
[email protected]2431756e2010-09-29 20:26:132399 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522400 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132401 int rv = handle.Init("a",
2402 params_,
2403 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522404 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132405 pool_.get(),
2406 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162407 EXPECT_EQ(OK, rv);
2408
[email protected]2431756e2010-09-29 20:26:132409 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522410 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132411 rv = handle2.Init("a",
2412 params_,
2413 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522414 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132415 pool_.get(),
2416 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162417 EXPECT_EQ(OK, rv);
2418
[email protected]2431756e2010-09-29 20:26:132419 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:522420 TestCompletionCallback callback3;
[email protected]2431756e2010-09-29 20:26:132421 rv = handle3.Init("a",
2422 params_,
2423 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522424 callback3.callback(),
[email protected]2431756e2010-09-29 20:26:132425 pool_.get(),
2426 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162427 EXPECT_EQ(ERR_IO_PENDING, rv);
2428
[email protected]2431756e2010-09-29 20:26:132429 ClientSocketHandle handle4;
[email protected]6ecf2b92011-12-15 01:14:522430 TestCompletionCallback callback4;
[email protected]2431756e2010-09-29 20:26:132431 rv = handle4.Init("a",
2432 params_,
2433 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522434 callback4.callback(),
[email protected]2431756e2010-09-29 20:26:132435 pool_.get(),
2436 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162437 EXPECT_EQ(ERR_IO_PENDING, rv);
2438
2439 // Release two disconnected sockets.
2440
[email protected]2431756e2010-09-29 20:26:132441 handle.socket()->Disconnect();
2442 handle.Reset();
2443 handle2.socket()->Disconnect();
2444 handle2.Reset();
[email protected]4f2abec2010-02-03 18:10:162445
[email protected]2431756e2010-09-29 20:26:132446 EXPECT_EQ(OK, callback3.WaitForResult());
2447 EXPECT_FALSE(handle3.is_reused());
2448 EXPECT_EQ(OK, callback4.WaitForResult());
2449 EXPECT_FALSE(handle4.is_reused());
[email protected]4f2abec2010-02-03 18:10:162450}
2451
[email protected]d7027bb2010-05-10 18:58:542452// Regression test for http://crbug.com/42267.
2453// When DoReleaseSocket() is processed for one socket, it is blocked because the
2454// other stalled groups all have releasing sockets, so no progress can be made.
2455TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
2456 CreatePoolWithIdleTimeouts(
2457 4 /* socket limit */, 4 /* socket limit per group */,
2458 base::TimeDelta(), // Time out unused sockets immediately.
2459 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2460
2461 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2462
2463 // Max out the socket limit with 2 per group.
2464
[email protected]2431756e2010-09-29 20:26:132465 ClientSocketHandle handle_a[4];
[email protected]6ecf2b92011-12-15 01:14:522466 TestCompletionCallback callback_a[4];
[email protected]2431756e2010-09-29 20:26:132467 ClientSocketHandle handle_b[4];
[email protected]6ecf2b92011-12-15 01:14:522468 TestCompletionCallback callback_b[4];
[email protected]d7027bb2010-05-10 18:58:542469
2470 for (int i = 0; i < 2; ++i) {
[email protected]2431756e2010-09-29 20:26:132471 EXPECT_EQ(OK, handle_a[i].Init("a",
2472 params_,
2473 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522474 callback_a[i].callback(),
[email protected]2431756e2010-09-29 20:26:132475 pool_.get(),
2476 BoundNetLog()));
2477 EXPECT_EQ(OK, handle_b[i].Init("b",
2478 params_,
2479 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522480 callback_b[i].callback(),
[email protected]2431756e2010-09-29 20:26:132481 pool_.get(),
2482 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542483 }
[email protected]b89f7e42010-05-20 20:37:002484
[email protected]d7027bb2010-05-10 18:58:542485 // Make 4 pending requests, 2 per group.
2486
2487 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132488 EXPECT_EQ(ERR_IO_PENDING,
2489 handle_a[i].Init("a",
2490 params_,
2491 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522492 callback_a[i].callback(),
[email protected]2431756e2010-09-29 20:26:132493 pool_.get(),
2494 BoundNetLog()));
2495 EXPECT_EQ(ERR_IO_PENDING,
2496 handle_b[i].Init("b",
2497 params_,
2498 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522499 callback_b[i].callback(),
[email protected]2431756e2010-09-29 20:26:132500 pool_.get(),
2501 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542502 }
2503
2504 // Release b's socket first. The order is important, because in
2505 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2506 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2507 // first, which has a releasing socket, so it refuses to start up another
2508 // ConnectJob. So, we used to infinite loop on this.
[email protected]2431756e2010-09-29 20:26:132509 handle_b[0].socket()->Disconnect();
2510 handle_b[0].Reset();
2511 handle_a[0].socket()->Disconnect();
2512 handle_a[0].Reset();
[email protected]d7027bb2010-05-10 18:58:542513
2514 // Used to get stuck here.
[email protected]2da659e2013-05-23 20:51:342515 base::MessageLoop::current()->RunUntilIdle();
[email protected]d7027bb2010-05-10 18:58:542516
[email protected]2431756e2010-09-29 20:26:132517 handle_b[1].socket()->Disconnect();
2518 handle_b[1].Reset();
2519 handle_a[1].socket()->Disconnect();
2520 handle_a[1].Reset();
[email protected]d7027bb2010-05-10 18:58:542521
2522 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132523 EXPECT_EQ(OK, callback_b[i].WaitForResult());
2524 EXPECT_EQ(OK, callback_a[i].WaitForResult());
[email protected]d7027bb2010-05-10 18:58:542525 }
2526}
2527
[email protected]fd4fe0b2010-02-08 23:02:152528TEST_F(ClientSocketPoolBaseTest,
2529 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2530 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2531
2532 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2533
2534 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2535 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2536 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2537 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2538
[email protected]2431756e2010-09-29 20:26:132539 EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
2540 EXPECT_EQ(OK, (*requests())[1]->WaitForResult());
2541 EXPECT_EQ(2u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152542
2543 // Releases one connection.
[email protected]2431756e2010-09-29 20:26:132544 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2545 EXPECT_EQ(OK, (*requests())[2]->WaitForResult());
[email protected]fd4fe0b2010-02-08 23:02:152546
[email protected]2431756e2010-09-29 20:26:132547 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2548 EXPECT_EQ(OK, (*requests())[3]->WaitForResult());
2549 EXPECT_EQ(4u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152550
2551 EXPECT_EQ(1, GetOrderOfRequest(1));
2552 EXPECT_EQ(2, GetOrderOfRequest(2));
2553 EXPECT_EQ(3, GetOrderOfRequest(3));
2554 EXPECT_EQ(4, GetOrderOfRequest(4));
2555
2556 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:132557 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
[email protected]fd4fe0b2010-02-08 23:02:152558}
2559
[email protected]6ecf2b92011-12-15 01:14:522560class TestReleasingSocketRequest : public TestCompletionCallbackBase {
[email protected]4f1e4982010-03-02 18:31:042561 public:
[email protected]2431756e2010-09-29 20:26:132562 TestReleasingSocketRequest(TestClientSocketPool* pool,
2563 int expected_result,
[email protected]e60e47a2010-07-14 03:37:182564 bool reset_releasing_handle)
2565 : pool_(pool),
2566 expected_result_(expected_result),
[email protected]6ecf2b92011-12-15 01:14:522567 reset_releasing_handle_(reset_releasing_handle),
[email protected]aa249b52013-04-30 01:04:322568 callback_(base::Bind(&TestReleasingSocketRequest::OnComplete,
2569 base::Unretained(this))) {
[email protected]6ecf2b92011-12-15 01:14:522570 }
2571
2572 virtual ~TestReleasingSocketRequest() {}
[email protected]4f1e4982010-03-02 18:31:042573
2574 ClientSocketHandle* handle() { return &handle_; }
2575
[email protected]6ecf2b92011-12-15 01:14:522576 const CompletionCallback& callback() const { return callback_; }
[email protected]4f1e4982010-03-02 18:31:042577
2578 private:
[email protected]6ecf2b92011-12-15 01:14:522579 void OnComplete(int result) {
2580 SetResult(result);
2581 if (reset_releasing_handle_)
2582 handle_.Reset();
2583
2584 scoped_refptr<TestSocketParams> con_params(new TestSocketParams());
2585 EXPECT_EQ(expected_result_,
2586 handle2_.Init("a", con_params, kDefaultPriority,
2587 callback2_.callback(), pool_, BoundNetLog()));
2588 }
2589
[email protected]2431756e2010-09-29 20:26:132590 TestClientSocketPool* const pool_;
[email protected]e60e47a2010-07-14 03:37:182591 int expected_result_;
2592 bool reset_releasing_handle_;
[email protected]4f1e4982010-03-02 18:31:042593 ClientSocketHandle handle_;
2594 ClientSocketHandle handle2_;
[email protected]6ecf2b92011-12-15 01:14:522595 CompletionCallback callback_;
2596 TestCompletionCallback callback2_;
[email protected]4f1e4982010-03-02 18:31:042597};
2598
[email protected]e60e47a2010-07-14 03:37:182599
2600TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2601 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2602
2603 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2604 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
2605 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2606
[email protected]2431756e2010-09-29 20:26:132607 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]e60e47a2010-07-14 03:37:182608 client_socket_factory_.allocation_count());
2609
2610 connect_job_factory_->set_job_type(
2611 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2612 TestReleasingSocketRequest req(pool_.get(), OK, false);
[email protected]2431756e2010-09-29 20:26:132613 EXPECT_EQ(ERR_IO_PENDING,
[email protected]6ecf2b92011-12-15 01:14:522614 req.handle()->Init("a", params_, kDefaultPriority, req.callback(),
2615 pool_.get(), BoundNetLog()));
[email protected]e60e47a2010-07-14 03:37:182616 // The next job should complete synchronously
2617 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2618
2619 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
2620 EXPECT_FALSE(req.handle()->is_initialized());
2621 EXPECT_FALSE(req.handle()->socket());
2622 EXPECT_TRUE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:432623 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182624}
2625
[email protected]b6501d3d2010-06-03 23:53:342626// http://crbug.com/44724 regression test.
2627// We start releasing the pool when we flush on network change. When that
2628// happens, the only active references are in the ClientSocketHandles. When a
2629// ConnectJob completes and calls back into the last ClientSocketHandle, that
2630// callback can release the last reference and delete the pool. After the
2631// callback finishes, we go back to the stack frame within the now-deleted pool.
2632// Executing any code that refers to members of the now-deleted pool can cause
2633// crashes.
2634TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2635 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2636 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2637
2638 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522639 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132640 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2641 params_,
2642 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522643 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132644 pool_.get(),
2645 BoundNetLog()));
[email protected]b6501d3d2010-06-03 23:53:342646
[email protected]7af985a2012-12-14 22:40:422647 pool_->FlushWithError(ERR_NETWORK_CHANGED);
[email protected]b6501d3d2010-06-03 23:53:342648
2649 // We'll call back into this now.
2650 callback.WaitForResult();
2651}
2652
[email protected]a7e38572010-06-07 18:22:242653TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2654 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2655 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2656
2657 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522658 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132659 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2660 params_,
2661 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522662 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132663 pool_.get(),
2664 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242665 EXPECT_EQ(OK, callback.WaitForResult());
2666 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2667
[email protected]7af985a2012-12-14 22:40:422668 pool_->FlushWithError(ERR_NETWORK_CHANGED);
[email protected]a7e38572010-06-07 18:22:242669
2670 handle.Reset();
[email protected]2da659e2013-05-23 20:51:342671 base::MessageLoop::current()->RunUntilIdle();
[email protected]a7e38572010-06-07 18:22:242672
[email protected]2431756e2010-09-29 20:26:132673 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2674 params_,
2675 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522676 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132677 pool_.get(),
2678 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242679 EXPECT_EQ(OK, callback.WaitForResult());
2680 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2681}
2682
[email protected]6ecf2b92011-12-15 01:14:522683class ConnectWithinCallback : public TestCompletionCallbackBase {
[email protected]06f92462010-08-31 19:24:142684 public:
2685 ConnectWithinCallback(
2686 const std::string& group_name,
2687 const scoped_refptr<TestSocketParams>& params,
[email protected]2431756e2010-09-29 20:26:132688 TestClientSocketPool* pool)
[email protected]6ecf2b92011-12-15 01:14:522689 : group_name_(group_name),
2690 params_(params),
2691 pool_(pool),
[email protected]aa249b52013-04-30 01:04:322692 callback_(base::Bind(&ConnectWithinCallback::OnComplete,
2693 base::Unretained(this))) {
[email protected]06f92462010-08-31 19:24:142694 }
2695
[email protected]6ecf2b92011-12-15 01:14:522696 virtual ~ConnectWithinCallback() {}
[email protected]06f92462010-08-31 19:24:142697
2698 int WaitForNestedResult() {
2699 return nested_callback_.WaitForResult();
2700 }
2701
[email protected]6ecf2b92011-12-15 01:14:522702 const CompletionCallback& callback() const { return callback_; }
2703
[email protected]06f92462010-08-31 19:24:142704 private:
[email protected]6ecf2b92011-12-15 01:14:522705 void OnComplete(int result) {
2706 SetResult(result);
2707 EXPECT_EQ(ERR_IO_PENDING,
2708 handle_.Init(group_name_,
2709 params_,
2710 kDefaultPriority,
2711 nested_callback_.callback(),
2712 pool_,
2713 BoundNetLog()));
2714 }
2715
[email protected]06f92462010-08-31 19:24:142716 const std::string group_name_;
2717 const scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:132718 TestClientSocketPool* const pool_;
[email protected]06f92462010-08-31 19:24:142719 ClientSocketHandle handle_;
[email protected]6ecf2b92011-12-15 01:14:522720 CompletionCallback callback_;
2721 TestCompletionCallback nested_callback_;
2722
2723 DISALLOW_COPY_AND_ASSIGN(ConnectWithinCallback);
[email protected]06f92462010-08-31 19:24:142724};
2725
2726TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
2727 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2728
2729 // First job will be waiting until it gets aborted.
2730 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2731
2732 ClientSocketHandle handle;
[email protected]2431756e2010-09-29 20:26:132733 ConnectWithinCallback callback("a", params_, pool_.get());
2734 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2735 params_,
2736 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522737 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132738 pool_.get(),
2739 BoundNetLog()));
[email protected]06f92462010-08-31 19:24:142740
2741 // Second job will be started during the first callback, and will
2742 // asynchronously complete with OK.
2743 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]7af985a2012-12-14 22:40:422744 pool_->FlushWithError(ERR_NETWORK_CHANGED);
2745 EXPECT_EQ(ERR_NETWORK_CHANGED, callback.WaitForResult());
[email protected]06f92462010-08-31 19:24:142746 EXPECT_EQ(OK, callback.WaitForNestedResult());
2747}
2748
[email protected]25eea382010-07-10 23:55:262749// Cancel a pending socket request while we're at max sockets,
2750// and verify that the backup socket firing doesn't cause a crash.
2751TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
2752 // Max 4 sockets globally, max 4 sockets per group.
2753 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
[email protected]06d94042010-08-25 01:45:222754 pool_->EnableConnectBackupJobs();
[email protected]25eea382010-07-10 23:55:262755
[email protected]4baaf9d2010-08-31 15:15:442756 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2757 // timer.
[email protected]25eea382010-07-10 23:55:262758 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2759 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522760 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132761 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2762 params_,
2763 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522764 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132765 pool_.get(),
2766 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262767
2768 // Start (MaxSockets - 1) connected sockets to reach max sockets.
2769 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2770 ClientSocketHandle handles[kDefaultMaxSockets];
2771 for (int i = 1; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:522772 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132773 EXPECT_EQ(OK, handles[i].Init("bar",
2774 params_,
2775 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522776 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132777 pool_.get(),
2778 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262779 }
2780
[email protected]2da659e2013-05-23 20:51:342781 base::MessageLoop::current()->RunUntilIdle();
[email protected]25eea382010-07-10 23:55:262782
2783 // Cancel the pending request.
2784 handle.Reset();
2785
2786 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]26b9973962012-01-28 00:57:002787 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2788 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]25eea382010-07-10 23:55:262789
[email protected]2da659e2013-05-23 20:51:342790 base::MessageLoop::current()->RunUntilIdle();
[email protected]25eea382010-07-10 23:55:262791 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
2792}
2793
[email protected]3f00be82010-09-27 19:50:022794TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
[email protected]4baaf9d2010-08-31 15:15:442795 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2796 pool_->EnableConnectBackupJobs();
2797
2798 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2799 // timer.
2800 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2801 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522802 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132803 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2804 params_,
2805 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522806 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132807 pool_.get(),
2808 BoundNetLog()));
[email protected]4baaf9d2010-08-31 15:15:442809 ASSERT_TRUE(pool_->HasGroup("bar"));
2810 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
[email protected]8159a1c2012-06-07 00:00:102811 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("bar"));
[email protected]4baaf9d2010-08-31 15:15:442812
2813 // Cancel the socket request. This should cancel the backup timer. Wait for
2814 // the backup time to see if it indeed got canceled.
2815 handle.Reset();
2816 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]26b9973962012-01-28 00:57:002817 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2818 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]2da659e2013-05-23 20:51:342819 base::MessageLoop::current()->RunUntilIdle();
[email protected]4baaf9d2010-08-31 15:15:442820 ASSERT_TRUE(pool_->HasGroup("bar"));
2821 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2822}
2823
[email protected]3f00be82010-09-27 19:50:022824TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
2825 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2826 pool_->EnableConnectBackupJobs();
2827
2828 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2829 // timer.
2830 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2831 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522832 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132833 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2834 params_,
2835 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522836 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132837 pool_.get(),
2838 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022839 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2840 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522841 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132842 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("bar",
2843 params_,
2844 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522845 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132846 pool_.get(),
2847 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022848 ASSERT_TRUE(pool_->HasGroup("bar"));
2849 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("bar"));
2850
2851 // Cancel request 1 and then complete request 2. With the requests finished,
2852 // the backup timer should be cancelled.
2853 handle.Reset();
2854 EXPECT_EQ(OK, callback2.WaitForResult());
2855 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]26b9973962012-01-28 00:57:002856 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2857 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]2da659e2013-05-23 20:51:342858 base::MessageLoop::current()->RunUntilIdle();
[email protected]3f00be82010-09-27 19:50:022859}
2860
[email protected]eb5a99382010-07-11 03:18:262861// Test delayed socket binding for the case where we have two connects,
2862// and while one is waiting on a connect, the other frees up.
2863// The socket waiting on a connect should switch immediately to the freed
2864// up socket.
2865TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
2866 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2867 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2868
2869 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522870 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132871 EXPECT_EQ(ERR_IO_PENDING,
2872 handle1.Init("a",
2873 params_,
2874 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522875 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132876 pool_.get(),
2877 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262878 EXPECT_EQ(OK, callback.WaitForResult());
2879
2880 // No idle sockets, no pending jobs.
2881 EXPECT_EQ(0, pool_->IdleSocketCount());
2882 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2883
2884 // Create a second socket to the same host, but this one will wait.
2885 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2886 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132887 EXPECT_EQ(ERR_IO_PENDING,
2888 handle2.Init("a",
2889 params_,
2890 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522891 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132892 pool_.get(),
2893 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262894 // No idle sockets, and one connecting job.
2895 EXPECT_EQ(0, pool_->IdleSocketCount());
2896 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2897
2898 // Return the first handle to the pool. This will initiate the delayed
2899 // binding.
2900 handle1.Reset();
2901
[email protected]2da659e2013-05-23 20:51:342902 base::MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262903
2904 // Still no idle sockets, still one pending connect job.
2905 EXPECT_EQ(0, pool_->IdleSocketCount());
2906 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2907
2908 // The second socket connected, even though it was a Waiting Job.
2909 EXPECT_EQ(OK, callback.WaitForResult());
2910
2911 // And we can see there is still one job waiting.
2912 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2913
2914 // Finally, signal the waiting Connect.
2915 client_socket_factory_.SignalJobs();
2916 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2917
[email protected]2da659e2013-05-23 20:51:342918 base::MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262919}
2920
2921// Test delayed socket binding when a group is at capacity and one
2922// of the group's sockets frees up.
2923TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
2924 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2925 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2926
2927 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522928 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132929 EXPECT_EQ(ERR_IO_PENDING,
2930 handle1.Init("a",
2931 params_,
2932 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522933 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132934 pool_.get(),
2935 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262936 EXPECT_EQ(OK, callback.WaitForResult());
2937
2938 // No idle sockets, no pending jobs.
2939 EXPECT_EQ(0, pool_->IdleSocketCount());
2940 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2941
2942 // Create a second socket to the same host, but this one will wait.
2943 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2944 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132945 EXPECT_EQ(ERR_IO_PENDING,
2946 handle2.Init("a",
2947 params_,
2948 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522949 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132950 pool_.get(),
2951 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262952 // No idle sockets, and one connecting job.
2953 EXPECT_EQ(0, pool_->IdleSocketCount());
2954 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2955
2956 // Return the first handle to the pool. This will initiate the delayed
2957 // binding.
2958 handle1.Reset();
2959
[email protected]2da659e2013-05-23 20:51:342960 base::MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262961
2962 // Still no idle sockets, still one pending connect job.
2963 EXPECT_EQ(0, pool_->IdleSocketCount());
2964 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2965
2966 // The second socket connected, even though it was a Waiting Job.
2967 EXPECT_EQ(OK, callback.WaitForResult());
2968
2969 // And we can see there is still one job waiting.
2970 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2971
2972 // Finally, signal the waiting Connect.
2973 client_socket_factory_.SignalJobs();
2974 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2975
[email protected]2da659e2013-05-23 20:51:342976 base::MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262977}
2978
2979// Test out the case where we have one socket connected, one
2980// connecting, when the first socket finishes and goes idle.
[email protected]2abfe90a2010-08-25 17:49:512981// Although the second connection is pending, the second request
[email protected]eb5a99382010-07-11 03:18:262982// should complete, by taking the first socket's idle socket.
2983TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
2984 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2985 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2986
2987 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522988 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132989 EXPECT_EQ(ERR_IO_PENDING,
2990 handle1.Init("a",
2991 params_,
2992 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522993 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132994 pool_.get(),
2995 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262996 EXPECT_EQ(OK, callback.WaitForResult());
2997
2998 // No idle sockets, no pending jobs.
2999 EXPECT_EQ(0, pool_->IdleSocketCount());
3000 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3001
3002 // Create a second socket to the same host, but this one will wait.
3003 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3004 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:133005 EXPECT_EQ(ERR_IO_PENDING,
3006 handle2.Init("a",
3007 params_,
3008 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523009 callback.callback(),
[email protected]2431756e2010-09-29 20:26:133010 pool_.get(),
3011 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:263012 // No idle sockets, and one connecting job.
3013 EXPECT_EQ(0, pool_->IdleSocketCount());
3014 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3015
3016 // Return the first handle to the pool. This will initiate the delayed
3017 // binding.
3018 handle1.Reset();
3019
[email protected]2da659e2013-05-23 20:51:343020 base::MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263021
3022 // Still no idle sockets, still one pending connect job.
3023 EXPECT_EQ(0, pool_->IdleSocketCount());
3024 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3025
3026 // The second socket connected, even though it was a Waiting Job.
3027 EXPECT_EQ(OK, callback.WaitForResult());
3028
3029 // And we can see there is still one job waiting.
3030 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3031
3032 // Finally, signal the waiting Connect.
3033 client_socket_factory_.SignalJobs();
3034 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3035
[email protected]2da659e2013-05-23 20:51:343036 base::MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263037}
3038
[email protected]2abfe90a2010-08-25 17:49:513039// Cover the case where on an available socket slot, we have one pending
3040// request that completes synchronously, thereby making the Group empty.
3041TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
3042 const int kUnlimitedSockets = 100;
3043 const int kOneSocketPerGroup = 1;
3044 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
3045
3046 // Make the first request asynchronous fail.
3047 // This will free up a socket slot later.
3048 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
3049
3050 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523051 TestCompletionCallback callback1;
[email protected]2431756e2010-09-29 20:26:133052 EXPECT_EQ(ERR_IO_PENDING,
3053 handle1.Init("a",
3054 params_,
3055 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523056 callback1.callback(),
[email protected]2431756e2010-09-29 20:26:133057 pool_.get(),
3058 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:513059 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3060
3061 // Make the second request synchronously fail. This should make the Group
3062 // empty.
3063 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3064 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523065 TestCompletionCallback callback2;
[email protected]2abfe90a2010-08-25 17:49:513066 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
3067 // when created.
[email protected]2431756e2010-09-29 20:26:133068 EXPECT_EQ(ERR_IO_PENDING,
3069 handle2.Init("a",
3070 params_,
3071 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523072 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:133073 pool_.get(),
3074 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:513075
3076 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3077
3078 EXPECT_EQ(ERR_CONNECTION_FAILED, callback1.WaitForResult());
3079 EXPECT_EQ(ERR_CONNECTION_FAILED, callback2.WaitForResult());
3080 EXPECT_FALSE(pool_->HasGroup("a"));
3081}
3082
[email protected]e1b54dc2010-10-06 21:27:223083TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
3084 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3085
3086 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3087
3088 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523089 TestCompletionCallback callback1;
[email protected]e1b54dc2010-10-06 21:27:223090 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3091 params_,
3092 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523093 callback1.callback(),
[email protected]e1b54dc2010-10-06 21:27:223094 pool_.get(),
3095 BoundNetLog()));
3096
3097 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523098 TestCompletionCallback callback2;
[email protected]e1b54dc2010-10-06 21:27:223099 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3100 params_,
3101 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523102 callback2.callback(),
[email protected]e1b54dc2010-10-06 21:27:223103 pool_.get(),
3104 BoundNetLog()));
3105 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:523106 TestCompletionCallback callback3;
[email protected]e1b54dc2010-10-06 21:27:223107 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
3108 params_,
3109 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523110 callback3.callback(),
[email protected]e1b54dc2010-10-06 21:27:223111 pool_.get(),
3112 BoundNetLog()));
3113
3114 EXPECT_EQ(OK, callback1.WaitForResult());
3115 EXPECT_EQ(OK, callback2.WaitForResult());
3116 EXPECT_EQ(OK, callback3.WaitForResult());
3117
3118 // Use the socket.
[email protected]83039bb2011-12-09 18:43:553119 EXPECT_EQ(1, handle1.socket()->Write(NULL, 1, CompletionCallback()));
3120 EXPECT_EQ(1, handle3.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]e1b54dc2010-10-06 21:27:223121
3122 handle1.Reset();
3123 handle2.Reset();
3124 handle3.Reset();
3125
3126 EXPECT_EQ(OK, handle1.Init("a",
3127 params_,
3128 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523129 callback1.callback(),
[email protected]e1b54dc2010-10-06 21:27:223130 pool_.get(),
3131 BoundNetLog()));
3132 EXPECT_EQ(OK, handle2.Init("a",
3133 params_,
3134 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523135 callback2.callback(),
[email protected]e1b54dc2010-10-06 21:27:223136 pool_.get(),
3137 BoundNetLog()));
3138 EXPECT_EQ(OK, handle3.Init("a",
3139 params_,
3140 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523141 callback3.callback(),
[email protected]e1b54dc2010-10-06 21:27:223142 pool_.get(),
3143 BoundNetLog()));
3144
3145 EXPECT_TRUE(handle1.socket()->WasEverUsed());
3146 EXPECT_TRUE(handle2.socket()->WasEverUsed());
3147 EXPECT_FALSE(handle3.socket()->WasEverUsed());
3148}
3149
[email protected]2c2bef152010-10-13 00:55:033150TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
3151 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3152 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3153
3154 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3155
3156 ASSERT_TRUE(pool_->HasGroup("a"));
3157 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103158 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033159 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3160
3161 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523162 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033163 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3164 params_,
3165 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523166 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033167 pool_.get(),
3168 BoundNetLog()));
3169
3170 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523171 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033172 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3173 params_,
3174 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523175 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033176 pool_.get(),
3177 BoundNetLog()));
3178
3179 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103180 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033181 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3182
3183 EXPECT_EQ(OK, callback1.WaitForResult());
3184 EXPECT_EQ(OK, callback2.WaitForResult());
3185 handle1.Reset();
3186 handle2.Reset();
3187
3188 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103189 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033190 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3191}
3192
3193TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
3194 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3195 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3196
3197 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523198 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033199 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3200 params_,
3201 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523202 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033203 pool_.get(),
3204 BoundNetLog()));
3205
3206 ASSERT_TRUE(pool_->HasGroup("a"));
3207 EXPECT_EQ(1, 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 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3212
3213 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103214 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033215 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3216
3217 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523218 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033219 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3220 params_,
3221 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523222 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033223 pool_.get(),
3224 BoundNetLog()));
3225
3226 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103227 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033228 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3229
3230 EXPECT_EQ(OK, callback1.WaitForResult());
3231 EXPECT_EQ(OK, callback2.WaitForResult());
3232 handle1.Reset();
3233 handle2.Reset();
3234
3235 EXPECT_EQ(0, 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(2, pool_->IdleSocketCountInGroup("a"));
3238}
3239
3240TEST_F(ClientSocketPoolBaseTest,
3241 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
3242 CreatePool(4, 4);
3243 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3244
3245 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523246 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033247 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3248 params_,
3249 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523250 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033251 pool_.get(),
3252 BoundNetLog()));
3253
3254 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523255 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033256 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3257 params_,
3258 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523259 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033260 pool_.get(),
3261 BoundNetLog()));
3262
3263 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:523264 TestCompletionCallback callback3;
[email protected]2c2bef152010-10-13 00:55:033265 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
3266 params_,
3267 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523268 callback3.callback(),
[email protected]2c2bef152010-10-13 00:55:033269 pool_.get(),
3270 BoundNetLog()));
3271
3272 ASSERT_TRUE(pool_->HasGroup("a"));
3273 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103274 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033275 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3276
3277 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3278
3279 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103280 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033281 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3282
3283 EXPECT_EQ(OK, callback1.WaitForResult());
3284 EXPECT_EQ(OK, callback2.WaitForResult());
3285 EXPECT_EQ(OK, callback3.WaitForResult());
3286 handle1.Reset();
3287 handle2.Reset();
3288 handle3.Reset();
3289
3290 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103291 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033292 EXPECT_EQ(3, pool_->IdleSocketCountInGroup("a"));
3293}
3294
3295TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
3296 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3297 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3298
3299 ASSERT_FALSE(pool_->HasGroup("a"));
3300
3301 pool_->RequestSockets("a", &params_, kDefaultMaxSockets,
3302 BoundNetLog());
3303
3304 ASSERT_TRUE(pool_->HasGroup("a"));
3305 EXPECT_EQ(kDefaultMaxSockets, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103306 EXPECT_EQ(kDefaultMaxSockets, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033307
3308 ASSERT_FALSE(pool_->HasGroup("b"));
3309
3310 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
3311 BoundNetLog());
3312
3313 ASSERT_FALSE(pool_->HasGroup("b"));
3314}
3315
3316TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
3317 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3318 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3319
3320 ASSERT_FALSE(pool_->HasGroup("a"));
3321
3322 pool_->RequestSockets("a", &params_, kDefaultMaxSockets - 1,
3323 BoundNetLog());
3324
3325 ASSERT_TRUE(pool_->HasGroup("a"));
3326 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103327 EXPECT_EQ(kDefaultMaxSockets - 1,
3328 pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]51fdc7c2012-04-10 19:19:483329 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033330
3331 ASSERT_FALSE(pool_->HasGroup("b"));
3332
3333 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
3334 BoundNetLog());
3335
3336 ASSERT_TRUE(pool_->HasGroup("b"));
3337 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("b"));
[email protected]51fdc7c2012-04-10 19:19:483338 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033339}
3340
3341TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
3342 CreatePool(4, 4);
3343 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3344
3345 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523346 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033347 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3348 params_,
3349 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523350 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033351 pool_.get(),
3352 BoundNetLog()));
3353 ASSERT_EQ(OK, callback1.WaitForResult());
3354 handle1.Reset();
3355
3356 ASSERT_TRUE(pool_->HasGroup("a"));
3357 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103358 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033359 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3360
3361 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3362
3363 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103364 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033365 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3366}
3367
3368TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
3369 CreatePool(4, 4);
3370 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3371
3372 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523373 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033374 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3375 params_,
3376 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523377 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033378 pool_.get(),
3379 BoundNetLog()));
3380 ASSERT_EQ(OK, callback1.WaitForResult());
3381
3382 ASSERT_TRUE(pool_->HasGroup("a"));
3383 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103384 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033385 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3386 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3387
3388 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3389
3390 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103391 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033392 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3393 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3394}
3395
3396TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
3397 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3398 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3399
3400 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3401 BoundNetLog());
3402
3403 ASSERT_TRUE(pool_->HasGroup("a"));
3404 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103405 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033406 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("a"));
3407
3408 pool_->RequestSockets("b", &params_, kDefaultMaxSocketsPerGroup,
3409 BoundNetLog());
3410
3411 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103412 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]2c2bef152010-10-13 00:55:033413 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("b"));
3414}
3415
[email protected]3c819f522010-12-02 02:03:123416TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
3417 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3418 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3419
3420 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3421 BoundNetLog());
3422
3423 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]fd2e53e2011-01-14 20:40:523424
3425 connect_job_factory_->set_job_type(
3426 TestConnectJob::kMockAdditionalErrorStateJob);
3427 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3428 BoundNetLog());
3429
3430 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]3c819f522010-12-02 02:03:123431}
3432
[email protected]8159a1c2012-06-07 00:00:103433TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
[email protected]2c2bef152010-10-13 00:55:033434 CreatePool(4, 4);
3435 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3436
3437 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3438
3439 ASSERT_TRUE(pool_->HasGroup("a"));
3440 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103441 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033442 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3443
3444 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3445 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103446 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033447 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3448
3449 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523450 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033451 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3452 params_,
3453 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523454 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033455 pool_.get(),
3456 BoundNetLog()));
3457 ASSERT_EQ(OK, callback1.WaitForResult());
3458
3459 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523460 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033461 int rv = handle2.Init("a",
3462 params_,
3463 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523464 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033465 pool_.get(),
3466 BoundNetLog());
3467 if (rv != OK) {
3468 EXPECT_EQ(ERR_IO_PENDING, rv);
3469 EXPECT_EQ(OK, callback2.WaitForResult());
3470 }
3471
[email protected]8159a1c2012-06-07 00:00:103472 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3473 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3474 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("a"));
3475 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3476
[email protected]2c2bef152010-10-13 00:55:033477 handle1.Reset();
3478 handle2.Reset();
3479
[email protected]8159a1c2012-06-07 00:00:103480 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3481 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033482 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3483
3484 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3485 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103486 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033487 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3488}
3489
3490TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
3491 CreatePool(4, 4);
3492 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3493
3494 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3495
3496 ASSERT_TRUE(pool_->HasGroup("a"));
3497 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103498 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033499 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3500
3501 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3502 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103503 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033504 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3505
3506 pool_->RequestSockets("a", &params_, 3, BoundNetLog());
3507 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103508 EXPECT_EQ(3, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033509 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3510
3511 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3512 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103513 EXPECT_EQ(3, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033514 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3515}
3516
3517TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
3518 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3519 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3520
3521 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3522
3523 ASSERT_TRUE(pool_->HasGroup("a"));
3524 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103525 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033526 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3527
3528 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523529 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033530 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3531 params_,
3532 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523533 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033534 pool_.get(),
3535 BoundNetLog()));
3536
3537 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103538 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033539 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3540
3541 ASSERT_EQ(OK, callback1.WaitForResult());
3542
[email protected]034df0f32013-01-07 23:17:483543 // Make sure if a preconneced socket is not fully connected when a request
3544 // starts, it has a connect start time.
3545 TestLoadTimingInfoConnectedNotReused(handle1);
[email protected]2c2bef152010-10-13 00:55:033546 handle1.Reset();
3547
3548 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3549}
3550
[email protected]034df0f32013-01-07 23:17:483551// Checks that fully connected preconnect jobs have no connect times, and are
3552// marked as reused.
3553TEST_F(ClientSocketPoolBaseTest, ConnectedPreconnectJobsHaveNoConnectTimes) {
3554 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3555 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3556 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3557
3558 ASSERT_TRUE(pool_->HasGroup("a"));
3559 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3560 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3561 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3562
3563 ClientSocketHandle handle;
3564 TestCompletionCallback callback;
3565 EXPECT_EQ(OK, handle.Init("a",
3566 params_,
3567 kDefaultPriority,
3568 callback.callback(),
3569 pool_.get(),
3570 BoundNetLog()));
3571
3572 // Make sure the idle socket was used.
3573 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3574
3575 TestLoadTimingInfoConnectedReused(handle);
3576 handle.Reset();
3577 TestLoadTimingInfoNotConnected(handle);
3578}
3579
[email protected]dcbe168a2010-12-02 03:14:463580// http://crbug.com/64940 regression test.
3581TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
3582 const int kMaxTotalSockets = 3;
3583 const int kMaxSocketsPerGroup = 2;
3584 CreatePool(kMaxTotalSockets, kMaxSocketsPerGroup);
3585 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3586
3587 // Note that group name ordering matters here. "a" comes before "b", so
3588 // CloseOneIdleSocket() will try to close "a"'s idle socket.
3589
3590 // Set up one idle socket in "a".
3591 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523592 TestCompletionCallback callback1;
[email protected]dcbe168a2010-12-02 03:14:463593 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3594 params_,
3595 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523596 callback1.callback(),
[email protected]dcbe168a2010-12-02 03:14:463597 pool_.get(),
3598 BoundNetLog()));
3599
3600 ASSERT_EQ(OK, callback1.WaitForResult());
3601 handle1.Reset();
3602 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3603
3604 // Set up two active sockets in "b".
3605 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523606 TestCompletionCallback callback2;
[email protected]dcbe168a2010-12-02 03:14:463607 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("b",
3608 params_,
3609 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523610 callback1.callback(),
[email protected]dcbe168a2010-12-02 03:14:463611 pool_.get(),
3612 BoundNetLog()));
3613 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("b",
3614 params_,
3615 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523616 callback2.callback(),
[email protected]dcbe168a2010-12-02 03:14:463617 pool_.get(),
3618 BoundNetLog()));
3619
3620 ASSERT_EQ(OK, callback1.WaitForResult());
3621 ASSERT_EQ(OK, callback2.WaitForResult());
3622 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103623 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463624 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3625
3626 // Now we have 1 idle socket in "a" and 2 active sockets in "b". This means
3627 // we've maxed out on sockets, since we set |kMaxTotalSockets| to 3.
3628 // Requesting 2 preconnected sockets for "a" should fail to allocate any more
3629 // sockets for "a", and "b" should still have 2 active sockets.
3630
3631 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3632 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103633 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]dcbe168a2010-12-02 03:14:463634 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3635 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3636 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103637 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463638 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3639 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3640
3641 // Now release the 2 active sockets for "b". This will give us 1 idle socket
3642 // in "a" and 2 idle sockets in "b". Requesting 2 preconnected sockets for
3643 // "a" should result in closing 1 for "b".
3644 handle1.Reset();
3645 handle2.Reset();
3646 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("b"));
3647 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3648
3649 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3650 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103651 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]dcbe168a2010-12-02 03:14:463652 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3653 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3654 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103655 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463656 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("b"));
3657 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3658}
3659
[email protected]b7b8be42011-07-12 12:46:413660TEST_F(ClientSocketPoolBaseTest, PreconnectWithoutBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073661 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3662 pool_->EnableConnectBackupJobs();
3663
3664 // Make the ConnectJob hang until it times out, shorten the timeout.
3665 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3666 connect_job_factory_->set_timeout_duration(
3667 base::TimeDelta::FromMilliseconds(500));
3668 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3669 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103670 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073671 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073672
[email protected]b7b8be42011-07-12 12:46:413673 // Verify the backup timer doesn't create a backup job, by making
3674 // the backup job a pending job instead of a waiting job, so it
3675 // *would* complete if it were created.
[email protected]a9fc8fc2011-05-10 02:41:073676 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2da659e2013-05-23 20:51:343677 base::MessageLoop::current()->PostDelayedTask(
3678 FROM_HERE,
3679 base::MessageLoop::QuitClosure(),
3680 base::TimeDelta::FromSeconds(1));
3681 base::MessageLoop::current()->Run();
[email protected]a9fc8fc2011-05-10 02:41:073682 EXPECT_FALSE(pool_->HasGroup("a"));
3683}
3684
[email protected]b7b8be42011-07-12 12:46:413685TEST_F(ClientSocketPoolBaseTest, PreconnectWithBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073686 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3687 pool_->EnableConnectBackupJobs();
3688
3689 // Make the ConnectJob hang forever.
3690 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3691 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3692 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103693 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073694 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]2da659e2013-05-23 20:51:343695 base::MessageLoop::current()->RunUntilIdle();
[email protected]a9fc8fc2011-05-10 02:41:073696
3697 // Make the backup job be a pending job, so it completes normally.
3698 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3699 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:523700 TestCompletionCallback callback;
[email protected]a9fc8fc2011-05-10 02:41:073701 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
3702 params_,
3703 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523704 callback.callback(),
[email protected]a9fc8fc2011-05-10 02:41:073705 pool_.get(),
3706 BoundNetLog()));
[email protected]b7b8be42011-07-12 12:46:413707 // Timer has started, but the backup connect job shouldn't be created yet.
[email protected]a9fc8fc2011-05-10 02:41:073708 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103709 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073710 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3711 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3712 ASSERT_EQ(OK, callback.WaitForResult());
3713
3714 // The hung connect job should still be there, but everything else should be
3715 // complete.
3716 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103717 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073718 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3719 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3720}
3721
[email protected]58e562f2013-04-22 17:32:203722class MockLayeredPool : public LayeredPool {
3723 public:
3724 MockLayeredPool(TestClientSocketPool* pool,
3725 const std::string& group_name)
3726 : pool_(pool),
3727 params_(new TestSocketParams),
3728 group_name_(group_name),
3729 can_release_connection_(true) {
3730 pool_->AddLayeredPool(this);
3731 }
3732
3733 ~MockLayeredPool() {
3734 pool_->RemoveLayeredPool(this);
3735 }
3736
3737 int RequestSocket(TestClientSocketPool* pool) {
3738 return handle_.Init(group_name_, params_, kDefaultPriority,
3739 callback_.callback(), pool, BoundNetLog());
3740 }
3741
3742 int RequestSocketWithoutLimits(TestClientSocketPool* pool) {
3743 params_->set_ignore_limits(true);
3744 return handle_.Init(group_name_, params_, kDefaultPriority,
3745 callback_.callback(), pool, BoundNetLog());
3746 }
3747
3748 bool ReleaseOneConnection() {
3749 if (!handle_.is_initialized() || !can_release_connection_) {
3750 return false;
3751 }
3752 handle_.socket()->Disconnect();
3753 handle_.Reset();
3754 return true;
3755 }
3756
3757 void set_can_release_connection(bool can_release_connection) {
3758 can_release_connection_ = can_release_connection;
3759 }
3760
3761 MOCK_METHOD0(CloseOneIdleConnection, bool());
3762
3763 private:
3764 TestClientSocketPool* const pool_;
3765 scoped_refptr<TestSocketParams> params_;
3766 ClientSocketHandle handle_;
3767 TestCompletionCallback callback_;
3768 const std::string group_name_;
3769 bool can_release_connection_;
3770};
3771
3772TEST_F(ClientSocketPoolBaseTest, FailToCloseIdleSocketsNotHeldByLayeredPool) {
3773 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3774 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3775
3776 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
3777 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3778 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3779 .WillOnce(Return(false));
3780 EXPECT_FALSE(pool_->CloseOneIdleConnectionInLayeredPool());
3781}
3782
3783TEST_F(ClientSocketPoolBaseTest, ForciblyCloseIdleSocketsHeldByLayeredPool) {
3784 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3785 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3786
3787 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
3788 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3789 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3790 .WillOnce(Invoke(&mock_layered_pool,
3791 &MockLayeredPool::ReleaseOneConnection));
3792 EXPECT_TRUE(pool_->CloseOneIdleConnectionInLayeredPool());
3793}
3794
3795// Tests the basic case of closing an idle socket in a higher layered pool when
3796// a new request is issued and the lower layer pool is stalled.
3797TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsHeldByLayeredPoolWhenNeeded) {
3798 CreatePool(1, 1);
3799 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3800
3801 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
3802 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3803 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3804 .WillOnce(Invoke(&mock_layered_pool,
3805 &MockLayeredPool::ReleaseOneConnection));
3806 ClientSocketHandle handle;
3807 TestCompletionCallback callback;
3808 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
3809 params_,
3810 kDefaultPriority,
3811 callback.callback(),
3812 pool_.get(),
3813 BoundNetLog()));
3814 EXPECT_EQ(OK, callback.WaitForResult());
3815}
3816
3817// Same as above, but the idle socket is in the same group as the stalled
3818// socket, and closes the only other request in its group when closing requests
3819// in higher layered pools. This generally shouldn't happen, but it may be
3820// possible if a higher level pool issues a request and the request is
3821// subsequently cancelled. Even if it's not possible, best not to crash.
3822TEST_F(ClientSocketPoolBaseTest,
3823 CloseIdleSocketsHeldByLayeredPoolWhenNeededSameGroup) {
3824 CreatePool(2, 2);
3825 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3826
3827 // Need a socket in another group for the pool to be stalled (If a group
3828 // has the maximum number of connections already, it's not stalled).
3829 ClientSocketHandle handle1;
3830 TestCompletionCallback callback1;
3831 EXPECT_EQ(OK, handle1.Init("group1",
3832 params_,
3833 kDefaultPriority,
3834 callback1.callback(),
3835 pool_.get(),
3836 BoundNetLog()));
3837
3838 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
3839 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3840 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3841 .WillOnce(Invoke(&mock_layered_pool,
3842 &MockLayeredPool::ReleaseOneConnection));
3843 ClientSocketHandle handle;
3844 TestCompletionCallback callback2;
3845 EXPECT_EQ(ERR_IO_PENDING, handle.Init("group2",
3846 params_,
3847 kDefaultPriority,
3848 callback2.callback(),
3849 pool_.get(),
3850 BoundNetLog()));
3851 EXPECT_EQ(OK, callback2.WaitForResult());
3852}
3853
3854// Tests the case when an idle socket can be closed when a new request is
3855// issued, and the new request belongs to a group that was previously stalled.
3856TEST_F(ClientSocketPoolBaseTest,
3857 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded) {
3858 CreatePool(2, 2);
3859 std::list<TestConnectJob::JobType> job_types;
3860 job_types.push_back(TestConnectJob::kMockJob);
3861 job_types.push_back(TestConnectJob::kMockJob);
3862 job_types.push_back(TestConnectJob::kMockJob);
3863 job_types.push_back(TestConnectJob::kMockJob);
3864 connect_job_factory_->set_job_types(&job_types);
3865
3866 ClientSocketHandle handle1;
3867 TestCompletionCallback callback1;
3868 EXPECT_EQ(OK, handle1.Init("group1",
3869 params_,
3870 kDefaultPriority,
3871 callback1.callback(),
3872 pool_.get(),
3873 BoundNetLog()));
3874
3875 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
3876 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3877 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3878 .WillRepeatedly(Invoke(&mock_layered_pool,
3879 &MockLayeredPool::ReleaseOneConnection));
3880 mock_layered_pool.set_can_release_connection(false);
3881
3882 // The third request is made when the socket pool is in a stalled state.
3883 ClientSocketHandle handle3;
3884 TestCompletionCallback callback3;
3885 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("group3",
3886 params_,
3887 kDefaultPriority,
3888 callback3.callback(),
3889 pool_.get(),
3890 BoundNetLog()));
3891
3892 base::RunLoop().RunUntilIdle();
3893 EXPECT_FALSE(callback3.have_result());
3894
3895 // The fourth request is made when the pool is no longer stalled. The third
3896 // request should be serviced first, since it was issued first and has the
3897 // same priority.
3898 mock_layered_pool.set_can_release_connection(true);
3899 ClientSocketHandle handle4;
3900 TestCompletionCallback callback4;
3901 EXPECT_EQ(ERR_IO_PENDING, handle4.Init("group3",
3902 params_,
3903 kDefaultPriority,
3904 callback4.callback(),
3905 pool_.get(),
3906 BoundNetLog()));
3907 EXPECT_EQ(OK, callback3.WaitForResult());
3908 EXPECT_FALSE(callback4.have_result());
3909
3910 // Closing a handle should free up another socket slot.
3911 handle1.Reset();
3912 EXPECT_EQ(OK, callback4.WaitForResult());
3913}
3914
3915// Tests the case when an idle socket can be closed when a new request is
3916// issued, and the new request belongs to a group that was previously stalled.
3917//
3918// The two differences from the above test are that the stalled requests are not
3919// in the same group as the layered pool's request, and the the fourth request
3920// has a higher priority than the third one, so gets a socket first.
3921TEST_F(ClientSocketPoolBaseTest,
3922 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded2) {
3923 CreatePool(2, 2);
3924 std::list<TestConnectJob::JobType> job_types;
3925 job_types.push_back(TestConnectJob::kMockJob);
3926 job_types.push_back(TestConnectJob::kMockJob);
3927 job_types.push_back(TestConnectJob::kMockJob);
3928 job_types.push_back(TestConnectJob::kMockJob);
3929 connect_job_factory_->set_job_types(&job_types);
3930
3931 ClientSocketHandle handle1;
3932 TestCompletionCallback callback1;
3933 EXPECT_EQ(OK, handle1.Init("group1",
3934 params_,
3935 kDefaultPriority,
3936 callback1.callback(),
3937 pool_.get(),
3938 BoundNetLog()));
3939
3940 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
3941 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3942 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3943 .WillRepeatedly(Invoke(&mock_layered_pool,
3944 &MockLayeredPool::ReleaseOneConnection));
3945 mock_layered_pool.set_can_release_connection(false);
3946
3947 // The third request is made when the socket pool is in a stalled state.
3948 ClientSocketHandle handle3;
3949 TestCompletionCallback callback3;
3950 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("group3",
3951 params_,
3952 MEDIUM,
3953 callback3.callback(),
3954 pool_.get(),
3955 BoundNetLog()));
3956
3957 base::RunLoop().RunUntilIdle();
3958 EXPECT_FALSE(callback3.have_result());
3959
3960 // The fourth request is made when the pool is no longer stalled. This
3961 // request has a higher priority than the third request, so is serviced first.
3962 mock_layered_pool.set_can_release_connection(true);
3963 ClientSocketHandle handle4;
3964 TestCompletionCallback callback4;
3965 EXPECT_EQ(ERR_IO_PENDING, handle4.Init("group3",
3966 params_,
3967 HIGHEST,
3968 callback4.callback(),
3969 pool_.get(),
3970 BoundNetLog()));
3971 EXPECT_EQ(OK, callback4.WaitForResult());
3972 EXPECT_FALSE(callback3.have_result());
3973
3974 // Closing a handle should free up another socket slot.
3975 handle1.Reset();
3976 EXPECT_EQ(OK, callback3.WaitForResult());
3977}
3978
3979TEST_F(ClientSocketPoolBaseTest,
3980 CloseMultipleIdleSocketsHeldByLayeredPoolWhenNeeded) {
3981 CreatePool(1, 1);
3982 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3983
3984 MockLayeredPool mock_layered_pool1(pool_.get(), "foo");
3985 EXPECT_EQ(OK, mock_layered_pool1.RequestSocket(pool_.get()));
3986 EXPECT_CALL(mock_layered_pool1, CloseOneIdleConnection())
3987 .WillRepeatedly(Invoke(&mock_layered_pool1,
3988 &MockLayeredPool::ReleaseOneConnection));
3989 MockLayeredPool mock_layered_pool2(pool_.get(), "bar");
3990 EXPECT_EQ(OK, mock_layered_pool2.RequestSocketWithoutLimits(pool_.get()));
3991 EXPECT_CALL(mock_layered_pool2, CloseOneIdleConnection())
3992 .WillRepeatedly(Invoke(&mock_layered_pool2,
3993 &MockLayeredPool::ReleaseOneConnection));
3994 ClientSocketHandle handle;
3995 TestCompletionCallback callback;
3996 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
3997 params_,
3998 kDefaultPriority,
3999 callback.callback(),
4000 pool_.get(),
4001 BoundNetLog()));
4002 EXPECT_EQ(OK, callback.WaitForResult());
4003}
4004
[email protected]b021ece62013-06-11 11:06:334005// Test that when a socket pool and group are at their limits, a request
4006// with |ignore_limits| triggers creation of a new socket, and gets the socket
4007// instead of a request with the same priority that was issued earlier, but
4008// that does not have |ignore_limits| set.
4009TEST_F(ClientSocketPoolBaseTest, IgnoreLimits) {
4010 scoped_refptr<TestSocketParams> params_ignore_limits(new TestSocketParams());
4011 params_ignore_limits->set_ignore_limits(true);
4012 CreatePool(1, 1);
4013
4014 // Issue a request to reach the socket pool limit.
4015 EXPECT_EQ(OK, StartRequestWithParams("a", kDefaultPriority, params_));
4016 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4017
4018 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4019
4020 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithParams("a", kDefaultPriority,
4021 params_));
4022 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4023
4024 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithParams("a", kDefaultPriority,
4025 params_ignore_limits));
4026 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4027
4028 EXPECT_EQ(OK, request(2)->WaitForResult());
4029 EXPECT_FALSE(request(1)->have_result());
4030}
4031
4032// Test that when a socket pool and group are at their limits, a request with
4033// |ignore_limits| set triggers creation of a new socket, and gets the socket
4034// instead of a request with a higher priority that was issued earlier, but
4035// that does not have |ignore_limits| set.
4036TEST_F(ClientSocketPoolBaseTest, IgnoreLimitsLowPriority) {
4037 scoped_refptr<TestSocketParams> params_ignore_limits(new TestSocketParams());
4038 params_ignore_limits->set_ignore_limits(true);
4039 CreatePool(1, 1);
4040
4041 // Issue a request to reach the socket pool limit.
4042 EXPECT_EQ(OK, StartRequestWithParams("a", HIGHEST, params_));
4043 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4044
4045 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4046
4047 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithParams("a", HIGHEST, params_));
4048 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4049
4050 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithParams("a", LOW,
4051 params_ignore_limits));
4052 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4053
4054 EXPECT_EQ(OK, request(2)->WaitForResult());
4055 EXPECT_FALSE(request(1)->have_result());
4056}
4057
4058// Test that when a socket pool and group are at their limits, a request with
4059// |ignore_limits| set triggers creation of a new socket, and gets the socket
4060// instead of a request with a higher priority that was issued later and
4061// does not have |ignore_limits| set.
4062TEST_F(ClientSocketPoolBaseTest, IgnoreLimitsLowPriority2) {
4063 scoped_refptr<TestSocketParams> params_ignore_limits(new TestSocketParams());
4064 params_ignore_limits->set_ignore_limits(true);
4065 CreatePool(1, 1);
4066
4067 // Issue a request to reach the socket pool limit.
4068 EXPECT_EQ(OK, StartRequestWithParams("a", HIGHEST, params_));
4069 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4070
4071 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4072
4073 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithParams("a", LOW,
4074 params_ignore_limits));
4075 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4076
4077 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithParams("a", HIGHEST, params_));
4078 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4079
4080 EXPECT_EQ(OK, request(1)->WaitForResult());
4081 EXPECT_FALSE(request(2)->have_result());
4082}
4083
4084// Test that when a socket pool and group are at their limits, a ConnectJob
4085// issued for a request with |ignore_limits| set is not cancelled when a request
4086// without |ignore_limits| issued to the same group is cancelled.
4087TEST_F(ClientSocketPoolBaseTest, IgnoreLimitsCancelOtherJob) {
4088 scoped_refptr<TestSocketParams> params_ignore_limits(new TestSocketParams());
4089 params_ignore_limits->set_ignore_limits(true);
4090 CreatePool(1, 1);
4091
4092 // Issue a request to reach the socket pool limit.
4093 EXPECT_EQ(OK, StartRequestWithParams("a", HIGHEST, params_));
4094 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4095
4096 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4097
4098 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithParams("a", HIGHEST, params_));
4099 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4100
4101 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithParams("a", HIGHEST,
4102 params_ignore_limits));
4103 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4104
4105 // Cancel the pending request without ignore_limits set. The ConnectJob
4106 // should not be cancelled.
4107 request(1)->handle()->Reset();
4108 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4109
4110 EXPECT_EQ(OK, request(2)->WaitForResult());
4111 EXPECT_FALSE(request(1)->have_result());
4112}
4113
4114// More involved test of ignore limits. Issues a bunch of requests and later
4115// checks the order in which they receive sockets.
4116TEST_F(ClientSocketPoolBaseTest, IgnoreLimitsOrder) {
4117 scoped_refptr<TestSocketParams> params_ignore_limits(new TestSocketParams());
4118 params_ignore_limits->set_ignore_limits(true);
4119 CreatePool(1, 1);
4120
4121 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4122
4123 // Requests 0 and 1 do not have ignore_limits set, so they finish last. Since
4124 // the maximum number of sockets per pool is 1, the second requests does not
4125 // trigger a ConnectJob.
4126 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithParams("a", HIGHEST, params_));
4127 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithParams("a", HIGHEST, params_));
4128
4129 // Requests 2 and 3 have ignore_limits set, but have a low priority, so they
4130 // finish just before the first two.
4131 EXPECT_EQ(ERR_IO_PENDING,
4132 StartRequestWithParams("a", LOW, params_ignore_limits));
4133 EXPECT_EQ(ERR_IO_PENDING,
4134 StartRequestWithParams("a", LOW, params_ignore_limits));
4135
4136 // Request 4 finishes first, since it is high priority and ignores limits.
4137 EXPECT_EQ(ERR_IO_PENDING,
4138 StartRequestWithParams("a", HIGHEST, params_ignore_limits));
4139
4140 // Request 5 and 6 are cancelled right after starting. This should result in
4141 // creating two ConnectJobs. Since only one request (Request 1) did not
4142 // result in creating a ConnectJob, only one of the ConnectJobs should be
4143 // cancelled when the requests are.
4144 EXPECT_EQ(ERR_IO_PENDING,
4145 StartRequestWithParams("a", HIGHEST, params_ignore_limits));
4146 EXPECT_EQ(ERR_IO_PENDING,
4147 StartRequestWithParams("a", HIGHEST, params_ignore_limits));
4148 EXPECT_EQ(6, pool_->NumConnectJobsInGroup("a"));
4149 request(5)->handle()->Reset();
4150 EXPECT_EQ(6, pool_->NumConnectJobsInGroup("a"));
4151 request(6)->handle()->Reset();
4152 ASSERT_EQ(5, pool_->NumConnectJobsInGroup("a"));
4153
4154 // Wait for the last request to get a socket.
4155 EXPECT_EQ(OK, request(1)->WaitForResult());
4156
4157 // Check order in which requests received sockets.
4158 // These are 1-based indices, while request(x) uses 0-based indices.
4159 EXPECT_EQ(1, GetOrderOfRequest(5));
4160 EXPECT_EQ(2, GetOrderOfRequest(3));
4161 EXPECT_EQ(3, GetOrderOfRequest(4));
4162 EXPECT_EQ(4, GetOrderOfRequest(1));
4163 EXPECT_EQ(5, GetOrderOfRequest(2));
4164}
[email protected]58e562f2013-04-22 17:32:204165
[email protected]f6d1d6eb2009-06-24 20:16:094166} // namespace
4167
4168} // namespace net