blob: 2ac188159a7dd470f4cdbbff449d9b4bcd2f391b [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"
skyostil4891b25b2015-06-11 11:43:4512#include "base/location.h"
mmenke33d24423d2015-05-19 19:41:0913#include "base/logging.h"
[email protected]3b63f8f42011-03-28 01:54:1514#include "base/memory/ref_counted.h"
15#include "base/memory/scoped_vector.h"
[email protected]6ea7b152011-12-21 21:21:1316#include "base/memory/weak_ptr.h"
[email protected]18b577412013-07-18 04:19:1517#include "base/message_loop/message_loop.h"
[email protected]034df0f32013-01-07 23:17:4818#include "base/run_loop.h"
skyostil4891b25b2015-06-11 11:43:4519#include "base/single_thread_task_runner.h"
[email protected]fc9be5802013-06-11 10:56:5120#include "base/strings/string_number_conversions.h"
[email protected]18b577412013-07-18 04:19:1521#include "base/strings/stringprintf.h"
skyostil4891b25b2015-06-11 11:43:4522#include "base/thread_task_runner_handle.h"
[email protected]f214f8792011-01-01 02:17:0823#include "base/threading/platform_thread.h"
[email protected]f3a1c642011-07-12 19:15:0324#include "base/values.h"
[email protected]034df0f32013-01-07 23:17:4825#include "net/base/load_timing_info.h"
[email protected]b258e0792013-01-12 07:11:5926#include "net/base/load_timing_info_test_util.h"
[email protected]d8eb84242010-09-25 02:25:0627#include "net/base/net_errors.h"
[email protected]ac790b42009-12-02 04:31:3128#include "net/base/request_priority.h"
[email protected]f6d1d6eb2009-06-24 20:16:0929#include "net/base/test_completion_callback.h"
[email protected]277d5942010-08-11 21:02:3530#include "net/http/http_response_headers.h"
eroman87c53d62015-04-02 06:51:0731#include "net/log/net_log.h"
mmenke16a7cbdd2015-04-24 23:00:5632#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4633#include "net/log/test_net_log_entry.h"
34#include "net/log/test_net_log_util.h"
[email protected]f6d1d6eb2009-06-24 20:16:0935#include "net/socket/client_socket_factory.h"
36#include "net/socket/client_socket_handle.h"
[email protected]75439d3b2009-07-23 22:11:1737#include "net/socket/socket_test_util.h"
[email protected]18ccfdb2013-08-15 00:13:4438#include "net/socket/ssl_client_socket.h"
[email protected]3268023f2011-05-05 00:08:1039#include "net/socket/stream_socket.h"
[email protected]18ccfdb2013-08-15 00:13:4440#include "net/udp/datagram_client_socket.h"
[email protected]51fdc7c2012-04-10 19:19:4841#include "testing/gmock/include/gmock/gmock.h"
[email protected]f6d1d6eb2009-06-24 20:16:0942#include "testing/gtest/include/gtest/gtest.h"
43
[email protected]51fdc7c2012-04-10 19:19:4844using ::testing::Invoke;
45using ::testing::Return;
46
[email protected]f6d1d6eb2009-06-24 20:16:0947namespace net {
48
49namespace {
50
[email protected]211d21722009-07-22 15:48:5351const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2052const int kDefaultMaxSocketsPerGroup = 2;
[email protected]0b7648c2009-07-06 20:14:0153
[email protected]034df0f32013-01-07 23:17:4854// Make sure |handle| sets load times correctly when it has been assigned a
55// reused socket.
56void TestLoadTimingInfoConnectedReused(const ClientSocketHandle& handle) {
57 LoadTimingInfo load_timing_info;
58 // Only pass true in as |is_reused|, as in general, HttpStream types should
59 // have stricter concepts of reuse than socket pools.
60 EXPECT_TRUE(handle.GetLoadTimingInfo(true, &load_timing_info));
61
62 EXPECT_EQ(true, load_timing_info.socket_reused);
63 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
64
[email protected]b258e0792013-01-12 07:11:5965 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
66 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:4867}
68
69// Make sure |handle| sets load times correctly when it has been assigned a
[email protected]b021ece62013-06-11 11:06:3370// fresh socket. Also runs TestLoadTimingInfoConnectedReused, since the owner
[email protected]034df0f32013-01-07 23:17:4871// of a connection where |is_reused| is false may consider the connection
72// reused.
73void TestLoadTimingInfoConnectedNotReused(const ClientSocketHandle& handle) {
74 EXPECT_FALSE(handle.is_reused());
75
76 LoadTimingInfo load_timing_info;
77 EXPECT_TRUE(handle.GetLoadTimingInfo(false, &load_timing_info));
78
79 EXPECT_FALSE(load_timing_info.socket_reused);
80 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
81
[email protected]b258e0792013-01-12 07:11:5982 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
83 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
84 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:4885
86 TestLoadTimingInfoConnectedReused(handle);
87}
88
89// Make sure |handle| sets load times correctly, in the case that it does not
90// currently have a socket.
91void TestLoadTimingInfoNotConnected(const ClientSocketHandle& handle) {
92 // Should only be set to true once a socket is assigned, if at all.
93 EXPECT_FALSE(handle.is_reused());
94
95 LoadTimingInfo load_timing_info;
96 EXPECT_FALSE(handle.GetLoadTimingInfo(false, &load_timing_info));
97
98 EXPECT_FALSE(load_timing_info.socket_reused);
99 EXPECT_EQ(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
100
[email protected]b258e0792013-01-12 07:11:59101 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
102 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:48103}
104
[email protected]df4b4ef2010-07-12 18:25:21105class TestSocketParams : public base::RefCounted<TestSocketParams> {
[email protected]5acdce12011-03-30 13:00:20106 public:
[email protected]bb1c4662013-11-14 00:00:07107 explicit TestSocketParams(bool ignore_limits)
108 : ignore_limits_(ignore_limits) {}
[email protected]51fdc7c2012-04-10 19:19:48109
[email protected]51fdc7c2012-04-10 19:19:48110 bool ignore_limits() { return ignore_limits_; }
111
[email protected]df4b4ef2010-07-12 18:25:21112 private:
113 friend class base::RefCounted<TestSocketParams>;
114 ~TestSocketParams() {}
[email protected]51fdc7c2012-04-10 19:19:48115
[email protected]bb1c4662013-11-14 00:00:07116 const bool ignore_limits_;
[email protected]df4b4ef2010-07-12 18:25:21117};
[email protected]7fc5b09a2010-02-27 00:07:38118typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
[email protected]d80a4322009-08-14 07:07:49119
[email protected]3268023f2011-05-05 00:08:10120class MockClientSocket : public StreamSocket {
[email protected]f6d1d6eb2009-06-24 20:16:09121 public:
[email protected]034df0f32013-01-07 23:17:48122 explicit MockClientSocket(net::NetLog* net_log)
123 : connected_(false),
[email protected]0dc88b32014-03-26 20:12:28124 has_unread_data_(false),
ttuttle859dc7a2015-04-23 19:42:29125 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)),
126 was_used_to_convey_data_(false) {}
[email protected]f6d1d6eb2009-06-24 20:16:09127
[email protected]0dc88b32014-03-26 20:12:28128 // Sets whether the socket has unread data. If true, the next call to Read()
129 // will return 1 byte and IsConnectedAndIdle() will return false.
130 void set_has_unread_data(bool has_unread_data) {
131 has_unread_data_ = has_unread_data;
132 }
133
[email protected]3f55aa12011-12-07 02:03:33134 // Socket implementation.
dchengb03027d2014-10-21 12:00:20135 int Read(IOBuffer* /* buf */,
136 int len,
137 const CompletionCallback& /* callback */) override {
[email protected]0dc88b32014-03-26 20:12:28138 if (has_unread_data_ && len > 0) {
139 has_unread_data_ = false;
140 was_used_to_convey_data_ = true;
141 return 1;
142 }
[email protected]e86df8dc2013-03-30 13:18:28143 return ERR_UNEXPECTED;
[email protected]3f55aa12011-12-07 02:03:33144 }
[email protected]ab838892009-06-30 18:49:05145
dchengb03027d2014-10-21 12:00:20146 int Write(IOBuffer* /* buf */,
147 int len,
148 const CompletionCallback& /* callback */) override {
[email protected]0f873e82010-09-02 16:09:01149 was_used_to_convey_data_ = true;
150 return len;
[email protected]ab838892009-06-30 18:49:05151 }
dchengb03027d2014-10-21 12:00:20152 int SetReceiveBufferSize(int32 size) override { return OK; }
153 int SetSendBufferSize(int32 size) override { return OK; }
[email protected]ab838892009-06-30 18:49:05154
[email protected]dbf036f2011-12-06 23:33:24155 // StreamSocket implementation.
dchengb03027d2014-10-21 12:00:20156 int Connect(const CompletionCallback& callback) override {
[email protected]dbf036f2011-12-06 23:33:24157 connected_ = true;
158 return OK;
159 }
[email protected]f6d1d6eb2009-06-24 20:16:09160
dchengb03027d2014-10-21 12:00:20161 void Disconnect() override { connected_ = false; }
162 bool IsConnected() const override { return connected_; }
163 bool IsConnectedAndIdle() const override {
[email protected]0dc88b32014-03-26 20:12:28164 return connected_ && !has_unread_data_;
165 }
[email protected]0b7648c2009-07-06 20:14:01166
dchengb03027d2014-10-21 12:00:20167 int GetPeerAddress(IPEndPoint* /* address */) const override {
[email protected]9f864b32010-01-20 15:01:16168 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:09169 }
[email protected]f6d1d6eb2009-06-24 20:16:09170
dchengb03027d2014-10-21 12:00:20171 int GetLocalAddress(IPEndPoint* /* address */) const override {
[email protected]e7f74da2011-04-19 23:49:35172 return ERR_UNEXPECTED;
173 }
174
dchengb03027d2014-10-21 12:00:20175 const BoundNetLog& NetLog() const override { return net_log_; }
[email protected]a2006ece2010-04-23 16:44:02176
dchengb03027d2014-10-21 12:00:20177 void SetSubresourceSpeculation() override {}
178 void SetOmniboxSpeculation() override {}
179 bool WasEverUsed() const override { return was_used_to_convey_data_; }
180 bool UsingTCPFastOpen() const override { return false; }
181 bool WasNpnNegotiated() const override { return false; }
182 NextProto GetNegotiatedProtocol() const override { return kProtoUnknown; }
183 bool GetSSLInfo(SSLInfo* ssl_info) override { return false; }
ttuttle23fdb7b2015-05-15 01:28:03184 void GetConnectionAttempts(ConnectionAttempts* out) const override {
185 out->clear();
186 }
187 void ClearConnectionAttempts() override {}
188 void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
[email protected]9b5614a2010-08-25 20:29:45189
[email protected]f6d1d6eb2009-06-24 20:16:09190 private:
191 bool connected_;
[email protected]0dc88b32014-03-26 20:12:28192 bool has_unread_data_;
[email protected]a2006ece2010-04-23 16:44:02193 BoundNetLog net_log_;
[email protected]0f873e82010-09-02 16:09:01194 bool was_used_to_convey_data_;
[email protected]f6d1d6eb2009-06-24 20:16:09195
[email protected]ab838892009-06-30 18:49:05196 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:09197};
198
[email protected]5fc08e32009-07-15 17:09:57199class TestConnectJob;
200
[email protected]f6d1d6eb2009-06-24 20:16:09201class MockClientSocketFactory : public ClientSocketFactory {
202 public:
[email protected]ab838892009-06-30 18:49:05203 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:09204
dchengb03027d2014-10-21 12:00:20205 scoped_ptr<DatagramClientSocket> CreateDatagramClientSocket(
[email protected]5370c012011-06-29 03:47:04206 DatagramSocket::BindType bind_type,
207 const RandIntCallback& rand_int_cb,
[email protected]98b0e582011-06-22 14:31:41208 NetLog* net_log,
mostynbba063d6032014-10-09 11:01:13209 const NetLog::Source& source) override {
[email protected]98b0e582011-06-22 14:31:41210 NOTREACHED();
[email protected]18ccfdb2013-08-15 00:13:44211 return scoped_ptr<DatagramClientSocket>();
[email protected]98b0e582011-06-22 14:31:41212 }
213
dchengb03027d2014-10-21 12:00:20214 scoped_ptr<StreamSocket> CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07215 const AddressList& addresses,
216 NetLog* /* net_log */,
mostynbba063d6032014-10-09 11:01:13217 const NetLog::Source& /*source*/) override {
[email protected]f6d1d6eb2009-06-24 20:16:09218 allocation_count_++;
[email protected]18ccfdb2013-08-15 00:13:44219 return scoped_ptr<StreamSocket>();
[email protected]f6d1d6eb2009-06-24 20:16:09220 }
221
dchengb03027d2014-10-21 12:00:20222 scoped_ptr<SSLClientSocket> CreateSSLClientSocket(
[email protected]18ccfdb2013-08-15 00:13:44223 scoped_ptr<ClientSocketHandle> transport_socket,
[email protected]4f4de7e62010-11-12 19:55:27224 const HostPortPair& host_and_port,
[email protected]7ab5bbd12010-10-19 13:33:21225 const SSLConfig& ssl_config,
mostynbba063d6032014-10-09 11:01:13226 const SSLClientSocketContext& context) override {
[email protected]f6d1d6eb2009-06-24 20:16:09227 NOTIMPLEMENTED();
[email protected]18ccfdb2013-08-15 00:13:44228 return scoped_ptr<SSLClientSocket>();
[email protected]f6d1d6eb2009-06-24 20:16:09229 }
230
dchengb03027d2014-10-21 12:00:20231 void ClearSSLSessionCache() override { NOTIMPLEMENTED(); }
[email protected]25f47352011-02-25 16:31:59232
[email protected]5fc08e32009-07-15 17:09:57233 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
[email protected]03b7c8c2013-07-20 04:38:55234
[email protected]5fc08e32009-07-15 17:09:57235 void SignalJobs();
236
[email protected]03b7c8c2013-07-20 04:38:55237 void SignalJob(size_t job);
238
239 void SetJobLoadState(size_t job, LoadState load_state);
240
[email protected]f6d1d6eb2009-06-24 20:16:09241 int allocation_count() const { return allocation_count_; }
242
[email protected]f6d1d6eb2009-06-24 20:16:09243 private:
244 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:57245 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09246};
247
[email protected]ab838892009-06-30 18:49:05248class TestConnectJob : public ConnectJob {
249 public:
250 enum JobType {
251 kMockJob,
252 kMockFailingJob,
253 kMockPendingJob,
254 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57255 kMockWaitingJob,
[email protected]e772db3f2010-07-12 18:11:13256 kMockRecoverableJob,
257 kMockPendingRecoverableJob,
[email protected]e60e47a2010-07-14 03:37:18258 kMockAdditionalErrorStateJob,
259 kMockPendingAdditionalErrorStateJob,
[email protected]0dc88b32014-03-26 20:12:28260 kMockUnreadDataJob,
[email protected]ab838892009-06-30 18:49:05261 };
262
[email protected]994d4932010-07-12 17:55:13263 // The kMockPendingJob uses a slight delay before allowing the connect
264 // to complete.
265 static const int kPendingConnectDelay = 2;
266
[email protected]ab838892009-06-30 18:49:05267 TestConnectJob(JobType job_type,
268 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49269 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34270 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05271 ConnectJob::Delegate* delegate,
[email protected]fd7b7c92009-08-20 19:38:30272 MockClientSocketFactory* client_socket_factory,
[email protected]06650c52010-06-03 00:49:17273 NetLog* net_log)
[email protected]3f6007ab2013-08-22 19:45:39274 : ConnectJob(group_name, timeout_duration, request.priority(), delegate,
[email protected]06650c52010-06-03 00:49:17275 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
[email protected]2ab05b52009-07-01 23:57:58276 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05277 client_socket_factory_(client_socket_factory),
[email protected]e60e47a2010-07-14 03:37:18278 load_state_(LOAD_STATE_IDLE),
[email protected]d5492c52013-11-10 20:44:39279 store_additional_error_state_(false),
280 weak_factory_(this) {
281 }
[email protected]ab838892009-06-30 18:49:05282
[email protected]974ebd62009-08-03 23:14:34283 void Signal() {
[email protected]e772db3f2010-07-12 18:11:13284 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
[email protected]974ebd62009-08-03 23:14:34285 }
286
[email protected]03b7c8c2013-07-20 04:38:55287 void set_load_state(LoadState load_state) { load_state_ = load_state; }
288
289 // From ConnectJob:
290
dchengb03027d2014-10-21 12:00:20291 LoadState GetLoadState() const override { return load_state_; }
[email protected]46451352009-09-01 14:54:21292
dchengb03027d2014-10-21 12:00:20293 void GetAdditionalErrorState(ClientSocketHandle* handle) override {
[email protected]e60e47a2010-07-14 03:37:18294 if (store_additional_error_state_) {
295 // Set all of the additional error state fields in some way.
296 handle->set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43297 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:45298 info.headers = new HttpResponseHeaders(std::string());
[email protected]8b498692010-07-16 17:11:43299 handle->set_ssl_error_response_info(info);
[email protected]e60e47a2010-07-14 03:37:18300 }
301 }
302
[email protected]974ebd62009-08-03 23:14:34303 private:
[email protected]03b7c8c2013-07-20 04:38:55304 // From ConnectJob:
[email protected]ab838892009-06-30 18:49:05305
dchengb03027d2014-10-21 12:00:20306 int ConnectInternal() override {
[email protected]ab838892009-06-30 18:49:05307 AddressList ignored;
ttuttle859dc7a2015-04-23 19:42:29308 client_socket_factory_->CreateTransportClientSocket(ignored, NULL,
309 NetLog::Source());
[email protected]18ccfdb2013-08-15 00:13:44310 SetSocket(
311 scoped_ptr<StreamSocket>(new MockClientSocket(net_log().net_log())));
[email protected]ab838892009-06-30 18:49:05312 switch (job_type_) {
313 case kMockJob:
[email protected]e772db3f2010-07-12 18:11:13314 return DoConnect(true /* successful */, false /* sync */,
315 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05316 case kMockFailingJob:
[email protected]e772db3f2010-07-12 18:11:13317 return DoConnect(false /* error */, false /* sync */,
318 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05319 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57320 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47321
322 // Depending on execution timings, posting a delayed task can result
323 // in the task getting executed the at the earliest possible
324 // opportunity or only after returning once from the message loop and
325 // then a second call into the message loop. In order to make behavior
326 // more deterministic, we change the default delay to 2ms. This should
327 // always require us to wait for the second call into the message loop.
328 //
329 // N.B. The correct fix for this and similar timing problems is to
330 // abstract time for the purpose of unittests. Unfortunately, we have
331 // a lot of third-party components that directly call the various
332 // time functions, so this change would be rather invasive.
skyostil4891b25b2015-06-11 11:43:45333 base::ThreadTaskRunnerHandle::Get()->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),
skyostil4891b25b2015-06-11 11:43:45336 weak_factory_.GetWeakPtr(), true /* successful */,
337 true /* async */, false /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53338 base::TimeDelta::FromMilliseconds(kPendingConnectDelay));
[email protected]ab838892009-06-30 18:49:05339 return ERR_IO_PENDING;
340 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57341 set_load_state(LOAD_STATE_CONNECTING);
skyostil4891b25b2015-06-11 11:43:45342 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05343 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13344 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
skyostil4891b25b2015-06-11 11:43:45345 weak_factory_.GetWeakPtr(), false /* error */,
346 true /* async */, false /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53347 base::TimeDelta::FromMilliseconds(2));
[email protected]ab838892009-06-30 18:49:05348 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57349 case kMockWaitingJob:
[email protected]03b7c8c2013-07-20 04:38:55350 set_load_state(LOAD_STATE_CONNECTING);
[email protected]5fc08e32009-07-15 17:09:57351 client_socket_factory_->WaitForSignal(this);
352 waiting_success_ = true;
353 return ERR_IO_PENDING;
[email protected]e772db3f2010-07-12 18:11:13354 case kMockRecoverableJob:
355 return DoConnect(false /* error */, false /* sync */,
356 true /* recoverable */);
357 case kMockPendingRecoverableJob:
358 set_load_state(LOAD_STATE_CONNECTING);
skyostil4891b25b2015-06-11 11:43:45359 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]e772db3f2010-07-12 18:11:13360 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13361 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
skyostil4891b25b2015-06-11 11:43:45362 weak_factory_.GetWeakPtr(), false /* error */,
363 true /* async */, true /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53364 base::TimeDelta::FromMilliseconds(2));
[email protected]e772db3f2010-07-12 18:11:13365 return ERR_IO_PENDING;
[email protected]e60e47a2010-07-14 03:37:18366 case kMockAdditionalErrorStateJob:
367 store_additional_error_state_ = true;
368 return DoConnect(false /* error */, false /* sync */,
369 false /* recoverable */);
370 case kMockPendingAdditionalErrorStateJob:
371 set_load_state(LOAD_STATE_CONNECTING);
372 store_additional_error_state_ = true;
skyostil4891b25b2015-06-11 11:43:45373 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]e60e47a2010-07-14 03:37:18374 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13375 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
skyostil4891b25b2015-06-11 11:43:45376 weak_factory_.GetWeakPtr(), false /* error */,
377 true /* async */, false /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53378 base::TimeDelta::FromMilliseconds(2));
[email protected]e60e47a2010-07-14 03:37:18379 return ERR_IO_PENDING;
[email protected]0dc88b32014-03-26 20:12:28380 case kMockUnreadDataJob: {
381 int ret = DoConnect(true /* successful */, false /* sync */,
382 false /* recoverable */);
383 static_cast<MockClientSocket*>(socket())->set_has_unread_data(true);
384 return ret;
385 }
[email protected]ab838892009-06-30 18:49:05386 default:
387 NOTREACHED();
[email protected]18ccfdb2013-08-15 00:13:44388 SetSocket(scoped_ptr<StreamSocket>());
[email protected]ab838892009-06-30 18:49:05389 return ERR_FAILED;
390 }
391 }
392
[email protected]e772db3f2010-07-12 18:11:13393 int DoConnect(bool succeed, bool was_async, bool recoverable) {
394 int result = OK;
[email protected]ab838892009-06-30 18:49:05395 if (succeed) {
[email protected]83039bb2011-12-09 18:43:55396 socket()->Connect(CompletionCallback());
[email protected]e772db3f2010-07-12 18:11:13397 } else if (recoverable) {
398 result = ERR_PROXY_AUTH_REQUESTED;
[email protected]6e713f02009-08-06 02:56:40399 } else {
[email protected]e772db3f2010-07-12 18:11:13400 result = ERR_CONNECTION_FAILED;
[email protected]18ccfdb2013-08-15 00:13:44401 SetSocket(scoped_ptr<StreamSocket>());
[email protected]ab838892009-06-30 18:49:05402 }
[email protected]2ab05b52009-07-01 23:57:58403
404 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30405 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05406 return result;
407 }
408
[email protected]5fc08e32009-07-15 17:09:57409 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05410 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57411 MockClientSocketFactory* const client_socket_factory_;
[email protected]46451352009-09-01 14:54:21412 LoadState load_state_;
[email protected]e60e47a2010-07-14 03:37:18413 bool store_additional_error_state_;
[email protected]ab838892009-06-30 18:49:05414
[email protected]d5492c52013-11-10 20:44:39415 base::WeakPtrFactory<TestConnectJob> weak_factory_;
416
[email protected]ab838892009-06-30 18:49:05417 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
418};
419
[email protected]d80a4322009-08-14 07:07:49420class TestConnectJobFactory
421 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05422 public:
[email protected]034df0f32013-01-07 23:17:48423 TestConnectJobFactory(MockClientSocketFactory* client_socket_factory,
424 NetLog* net_log)
[email protected]ab838892009-06-30 18:49:05425 : job_type_(TestConnectJob::kMockJob),
[email protected]51fdc7c2012-04-10 19:19:48426 job_types_(NULL),
[email protected]034df0f32013-01-07 23:17:48427 client_socket_factory_(client_socket_factory),
428 net_log_(net_log) {
[email protected]b021ece62013-06-11 11:06:33429 }
[email protected]ab838892009-06-30 18:49:05430
dchengb03027d2014-10-21 12:00:20431 ~TestConnectJobFactory() override {}
[email protected]ab838892009-06-30 18:49:05432
433 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
434
[email protected]51fdc7c2012-04-10 19:19:48435 void set_job_types(std::list<TestConnectJob::JobType>* job_types) {
436 job_types_ = job_types;
437 CHECK(!job_types_->empty());
438 }
439
[email protected]974ebd62009-08-03 23:14:34440 void set_timeout_duration(base::TimeDelta timeout_duration) {
441 timeout_duration_ = timeout_duration;
442 }
443
[email protected]3f55aa12011-12-07 02:03:33444 // ConnectJobFactory implementation.
[email protected]83039bb2011-12-09 18:43:55445
dchengb03027d2014-10-21 12:00:20446 scoped_ptr<ConnectJob> NewConnectJob(
[email protected]ab838892009-06-30 18:49:05447 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49448 const TestClientSocketPoolBase::Request& request,
mostynbba063d6032014-10-09 11:01:13449 ConnectJob::Delegate* delegate) const override {
[email protected]51fdc7c2012-04-10 19:19:48450 EXPECT_TRUE(!job_types_ || !job_types_->empty());
451 TestConnectJob::JobType job_type = job_type_;
452 if (job_types_ && !job_types_->empty()) {
453 job_type = job_types_->front();
454 job_types_->pop_front();
455 }
[email protected]18ccfdb2013-08-15 00:13:44456 return scoped_ptr<ConnectJob>(new TestConnectJob(job_type,
457 group_name,
458 request,
459 timeout_duration_,
460 delegate,
461 client_socket_factory_,
462 net_log_));
[email protected]ab838892009-06-30 18:49:05463 }
464
dchengb03027d2014-10-21 12:00:20465 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26466 return timeout_duration_;
467 }
468
[email protected]ab838892009-06-30 18:49:05469 private:
470 TestConnectJob::JobType job_type_;
[email protected]51fdc7c2012-04-10 19:19:48471 std::list<TestConnectJob::JobType>* job_types_;
[email protected]974ebd62009-08-03 23:14:34472 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57473 MockClientSocketFactory* const client_socket_factory_;
[email protected]034df0f32013-01-07 23:17:48474 NetLog* net_log_;
[email protected]ab838892009-06-30 18:49:05475
476 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
477};
478
479class TestClientSocketPool : public ClientSocketPool {
480 public:
[email protected]12322e7e2013-08-15 17:49:26481 typedef TestSocketParams SocketParams;
482
[email protected]ab838892009-06-30 18:49:05483 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53484 int max_sockets,
[email protected]ab838892009-06-30 18:49:05485 int max_sockets_per_group,
[email protected]9bf28db2009-08-29 01:35:16486 base::TimeDelta unused_idle_socket_timeout,
487 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49488 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
rkaplowd90695c2015-03-25 22:12:41489 : base_(NULL,
490 max_sockets,
491 max_sockets_per_group,
492 unused_idle_socket_timeout,
493 used_idle_socket_timeout,
[email protected]66761b952010-06-25 21:30:38494 connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05495
dchengb03027d2014-10-21 12:00:20496 ~TestClientSocketPool() override {}
[email protected]2431756e2010-09-29 20:26:13497
dchengb03027d2014-10-21 12:00:20498 int RequestSocket(const std::string& group_name,
499 const void* params,
ttuttle859dc7a2015-04-23 19:42:29500 RequestPriority priority,
dchengb03027d2014-10-21 12:00:20501 ClientSocketHandle* handle,
502 const CompletionCallback& callback,
503 const BoundNetLog& net_log) override {
[email protected]df4b4ef2010-07-12 18:25:21504 const scoped_refptr<TestSocketParams>* casted_socket_params =
505 static_cast<const scoped_refptr<TestSocketParams>*>(params);
506 return base_.RequestSocket(group_name, *casted_socket_params, priority,
507 handle, callback, net_log);
[email protected]ab838892009-06-30 18:49:05508 }
509
dchengb03027d2014-10-21 12:00:20510 void RequestSockets(const std::string& group_name,
511 const void* params,
512 int num_sockets,
513 const BoundNetLog& net_log) override {
[email protected]2c2bef152010-10-13 00:55:03514 const scoped_refptr<TestSocketParams>* casted_params =
515 static_cast<const scoped_refptr<TestSocketParams>*>(params);
516
517 base_.RequestSockets(group_name, *casted_params, num_sockets, net_log);
518 }
519
dchengb03027d2014-10-21 12:00:20520 void CancelRequest(const std::string& group_name,
521 ClientSocketHandle* handle) override {
[email protected]d80a4322009-08-14 07:07:49522 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05523 }
524
dchengb03027d2014-10-21 12:00:20525 void ReleaseSocket(const std::string& group_name,
526 scoped_ptr<StreamSocket> socket,
527 int id) override {
[email protected]18ccfdb2013-08-15 00:13:44528 base_.ReleaseSocket(group_name, socket.Pass(), id);
[email protected]a7e38572010-06-07 18:22:24529 }
530
dchengb03027d2014-10-21 12:00:20531 void FlushWithError(int error) override { base_.FlushWithError(error); }
[email protected]ab838892009-06-30 18:49:05532
dchengb03027d2014-10-21 12:00:20533 bool IsStalled() const override { return base_.IsStalled(); }
[email protected]51fdc7c2012-04-10 19:19:48534
dchengb03027d2014-10-21 12:00:20535 void CloseIdleSockets() override { base_.CloseIdleSockets(); }
[email protected]ab838892009-06-30 18:49:05536
dchengb03027d2014-10-21 12:00:20537 int IdleSocketCount() const override { return base_.idle_socket_count(); }
[email protected]ab838892009-06-30 18:49:05538
dchengb03027d2014-10-21 12:00:20539 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]d80a4322009-08-14 07:07:49540 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05541 }
542
dchengb03027d2014-10-21 12:00:20543 LoadState GetLoadState(const std::string& group_name,
544 const ClientSocketHandle* handle) const override {
[email protected]d80a4322009-08-14 07:07:49545 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05546 }
547
dchengb03027d2014-10-21 12:00:20548 void AddHigherLayeredPool(HigherLayeredPool* higher_pool) override {
[email protected]043b68c82013-08-22 23:41:52549 base_.AddHigherLayeredPool(higher_pool);
[email protected]51fdc7c2012-04-10 19:19:48550 }
551
dchengb03027d2014-10-21 12:00:20552 void RemoveHigherLayeredPool(HigherLayeredPool* higher_pool) override {
[email protected]043b68c82013-08-22 23:41:52553 base_.RemoveHigherLayeredPool(higher_pool);
[email protected]51fdc7c2012-04-10 19:19:48554 }
555
ketan.goyalf84eda92015-06-03 10:53:36556 scoped_ptr<base::DictionaryValue> GetInfoAsValue(
[email protected]d4dfdab2011-12-07 16:56:59557 const std::string& name,
558 const std::string& type,
mostynbba063d6032014-10-09 11:01:13559 bool include_nested_pools) const override {
[email protected]59d7a5a2010-08-30 16:44:27560 return base_.GetInfoAsValue(name, type);
561 }
562
dchengb03027d2014-10-21 12:00:20563 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26564 return base_.ConnectionTimeout();
565 }
566
[email protected]d80a4322009-08-14 07:07:49567 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20568
[email protected]8159a1c2012-06-07 00:00:10569 int NumUnassignedConnectJobsInGroup(const std::string& group_name) const {
570 return base_.NumUnassignedConnectJobsInGroup(group_name);
571 }
572
[email protected]974ebd62009-08-03 23:14:34573 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49574 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34575 }
576
[email protected]2c2bef152010-10-13 00:55:03577 int NumActiveSocketsInGroup(const std::string& group_name) const {
578 return base_.NumActiveSocketsInGroup(group_name);
579 }
580
[email protected]2abfe90a2010-08-25 17:49:51581 bool HasGroup(const std::string& group_name) const {
582 return base_.HasGroup(group_name);
583 }
584
[email protected]9bf28db2009-08-29 01:35:16585 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
586
[email protected]06d94042010-08-25 01:45:22587 void EnableConnectBackupJobs() { base_.EnableConnectBackupJobs(); }
[email protected]43a21b82010-06-10 21:30:54588
[email protected]043b68c82013-08-22 23:41:52589 bool CloseOneIdleConnectionInHigherLayeredPool() {
590 return base_.CloseOneIdleConnectionInHigherLayeredPool();
[email protected]51fdc7c2012-04-10 19:19:48591 }
592
[email protected]ab838892009-06-30 18:49:05593 private:
[email protected]d80a4322009-08-14 07:07:49594 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05595
596 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
597};
598
[email protected]a937a06d2009-08-19 21:19:24599} // namespace
600
[email protected]a937a06d2009-08-19 21:19:24601namespace {
602
[email protected]5fc08e32009-07-15 17:09:57603void MockClientSocketFactory::SignalJobs() {
604 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
605 it != waiting_jobs_.end(); ++it) {
606 (*it)->Signal();
607 }
608 waiting_jobs_.clear();
609}
610
[email protected]03b7c8c2013-07-20 04:38:55611void MockClientSocketFactory::SignalJob(size_t job) {
612 ASSERT_LT(job, waiting_jobs_.size());
613 waiting_jobs_[job]->Signal();
614 waiting_jobs_.erase(waiting_jobs_.begin() + job);
615}
616
617void MockClientSocketFactory::SetJobLoadState(size_t job,
618 LoadState load_state) {
619 ASSERT_LT(job, waiting_jobs_.size());
620 waiting_jobs_[job]->set_load_state(load_state);
621}
622
[email protected]974ebd62009-08-03 23:14:34623class TestConnectJobDelegate : public ConnectJob::Delegate {
624 public:
625 TestConnectJobDelegate()
626 : have_result_(false), waiting_for_result_(false), result_(OK) {}
dchengb03027d2014-10-21 12:00:20627 ~TestConnectJobDelegate() override {}
[email protected]974ebd62009-08-03 23:14:34628
dchengb03027d2014-10-21 12:00:20629 void OnConnectJobComplete(int result, ConnectJob* job) override {
[email protected]974ebd62009-08-03 23:14:34630 result_ = result;
[email protected]18ccfdb2013-08-15 00:13:44631 scoped_ptr<ConnectJob> owned_job(job);
632 scoped_ptr<StreamSocket> socket = owned_job->PassSocket();
[email protected]9b6fee12009-09-29 18:13:07633 // socket.get() should be NULL iff result != OK
[email protected]18ccfdb2013-08-15 00:13:44634 EXPECT_EQ(socket == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34635 have_result_ = true;
636 if (waiting_for_result_)
[email protected]2da659e2013-05-23 20:51:34637 base::MessageLoop::current()->Quit();
[email protected]974ebd62009-08-03 23:14:34638 }
639
640 int WaitForResult() {
641 DCHECK(!waiting_for_result_);
642 while (!have_result_) {
643 waiting_for_result_ = true;
[email protected]2da659e2013-05-23 20:51:34644 base::MessageLoop::current()->Run();
[email protected]974ebd62009-08-03 23:14:34645 waiting_for_result_ = false;
646 }
647 have_result_ = false; // auto-reset for next callback
648 return result_;
649 }
650
651 private:
652 bool have_result_;
653 bool waiting_for_result_;
654 int result_;
655};
656
[email protected]2431756e2010-09-29 20:26:13657class ClientSocketPoolBaseTest : public testing::Test {
[email protected]f6d1d6eb2009-06-24 20:16:09658 protected:
[email protected]b89f7e42010-05-20 20:37:00659 ClientSocketPoolBaseTest()
rkaplowd90695c2015-03-25 22:12:41660 : params_(new TestSocketParams(false /* ignore_limits */)) {
[email protected]636b8252011-04-08 19:56:54661 connect_backup_jobs_enabled_ =
662 internal::ClientSocketPoolBaseHelper::connect_backup_jobs_enabled();
663 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(true);
[email protected]64770b7d2011-11-16 04:30:41664 cleanup_timer_enabled_ =
665 internal::ClientSocketPoolBaseHelper::cleanup_timer_enabled();
[email protected]636b8252011-04-08 19:56:54666 }
[email protected]2431756e2010-09-29 20:26:13667
dcheng67be2b1f2014-10-27 21:47:29668 ~ClientSocketPoolBaseTest() override {
[email protected]636b8252011-04-08 19:56:54669 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
670 connect_backup_jobs_enabled_);
[email protected]64770b7d2011-11-16 04:30:41671 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(
672 cleanup_timer_enabled_);
[email protected]636b8252011-04-08 19:56:54673 }
[email protected]c9d6a1d2009-07-14 16:15:20674
[email protected]211d21722009-07-22 15:48:53675 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16676 CreatePoolWithIdleTimeouts(
677 max_sockets,
678 max_sockets_per_group,
[email protected]82b8c962011-10-12 09:17:30679 ClientSocketPool::unused_idle_socket_timeout(),
680 ClientSocketPool::used_idle_socket_timeout());
[email protected]9bf28db2009-08-29 01:35:16681 }
682
683 void CreatePoolWithIdleTimeouts(
684 int max_sockets, int max_sockets_per_group,
685 base::TimeDelta unused_idle_socket_timeout,
686 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20687 DCHECK(!pool_.get());
[email protected]034df0f32013-01-07 23:17:48688 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_,
689 &net_log_);
[email protected]2431756e2010-09-29 20:26:13690 pool_.reset(new TestClientSocketPool(max_sockets,
691 max_sockets_per_group,
[email protected]2431756e2010-09-29 20:26:13692 unused_idle_socket_timeout,
693 used_idle_socket_timeout,
694 connect_job_factory_));
[email protected]c9d6a1d2009-07-14 16:15:20695 }
[email protected]f6d1d6eb2009-06-24 20:16:09696
[email protected]b021ece62013-06-11 11:06:33697 int StartRequestWithParams(
698 const std::string& group_name,
699 RequestPriority priority,
700 const scoped_refptr<TestSocketParams>& params) {
[email protected]12322e7e2013-08-15 17:49:26701 return test_base_.StartRequestUsingPool(
702 pool_.get(), group_name, priority, params);
[email protected]b021ece62013-06-11 11:06:33703 }
704
705 int StartRequest(const std::string& group_name, RequestPriority priority) {
706 return StartRequestWithParams(group_name, priority, params_);
[email protected]f6d1d6eb2009-06-24 20:16:09707 }
708
[email protected]2431756e2010-09-29 20:26:13709 int GetOrderOfRequest(size_t index) const {
710 return test_base_.GetOrderOfRequest(index);
[email protected]f6d1d6eb2009-06-24 20:16:09711 }
712
[email protected]2431756e2010-09-29 20:26:13713 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
714 return test_base_.ReleaseOneConnection(keep_alive);
715 }
716
717 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
718 test_base_.ReleaseAllConnections(keep_alive);
719 }
720
721 TestSocketRequest* request(int i) { return test_base_.request(i); }
722 size_t requests_size() const { return test_base_.requests_size(); }
723 ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); }
724 size_t completion_count() const { return test_base_.completion_count(); }
725
vishal.b62985ca92015-04-17 08:45:51726 TestNetLog net_log_;
[email protected]636b8252011-04-08 19:56:54727 bool connect_backup_jobs_enabled_;
[email protected]64770b7d2011-11-16 04:30:41728 bool cleanup_timer_enabled_;
[email protected]f6d1d6eb2009-06-24 20:16:09729 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04730 TestConnectJobFactory* connect_job_factory_;
[email protected]df4b4ef2010-07-12 18:25:21731 scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:13732 scoped_ptr<TestClientSocketPool> pool_;
733 ClientSocketPoolTest test_base_;
[email protected]f6d1d6eb2009-06-24 20:16:09734};
735
[email protected]974ebd62009-08-03 23:14:34736// Even though a timeout is specified, it doesn't time out on a synchronous
737// completion.
738TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
739 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06740 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49741 TestClientSocketPoolBase::Request request(
[email protected]bb1c4662013-11-14 00:00:07742 &ignored, CompletionCallback(), DEFAULT_PRIORITY,
[email protected]2c2bef152010-10-13 00:55:03743 internal::ClientSocketPoolBaseHelper::NORMAL,
[email protected]5acdce12011-03-30 13:00:20744 false, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34745 scoped_ptr<TestConnectJob> job(
746 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:12747 "a",
[email protected]974ebd62009-08-03 23:14:34748 request,
749 base::TimeDelta::FromMicroseconds(1),
750 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30751 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17752 NULL));
[email protected]974ebd62009-08-03 23:14:34753 EXPECT_EQ(OK, job->Connect());
754}
755
756TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
757 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06758 ClientSocketHandle ignored;
vishal.b62985ca92015-04-17 08:45:51759 TestNetLog log;
[email protected]9e743cd2010-03-16 07:03:53760
[email protected]d80a4322009-08-14 07:07:49761 TestClientSocketPoolBase::Request request(
[email protected]bb1c4662013-11-14 00:00:07762 &ignored, CompletionCallback(), DEFAULT_PRIORITY,
[email protected]2c2bef152010-10-13 00:55:03763 internal::ClientSocketPoolBaseHelper::NORMAL,
[email protected]5acdce12011-03-30 13:00:20764 false, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34765 // Deleted by TestConnectJobDelegate.
766 TestConnectJob* job =
767 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12768 "a",
[email protected]974ebd62009-08-03 23:14:34769 request,
770 base::TimeDelta::FromMicroseconds(1),
771 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30772 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17773 &log);
[email protected]974ebd62009-08-03 23:14:34774 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
[email protected]26b9973962012-01-28 00:57:00775 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
[email protected]974ebd62009-08-03 23:14:34776 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30777
mmenke43758e62015-05-04 21:09:46778 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40779 log.GetEntries(&entries);
780
781 EXPECT_EQ(6u, entries.size());
[email protected]e9002a92010-01-29 07:10:46782 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40783 entries, 0, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]06650c52010-06-03 00:49:17784 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40785 entries, 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]e9002a92010-01-29 07:10:46786 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40787 entries, 2, NetLog::TYPE_CONNECT_JOB_SET_SOCKET,
[email protected]06650c52010-06-03 00:49:17788 NetLog::PHASE_NONE));
789 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40790 entries, 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
[email protected]9e743cd2010-03-16 07:03:53791 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:46792 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40793 entries, 4, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]06650c52010-06-03 00:49:17794 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40795 entries, 5, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34796}
797
[email protected]5fc08e32009-07-15 17:09:57798TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53799 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20800
[email protected]6ecf2b92011-12-15 01:14:52801 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06802 ClientSocketHandle handle;
vishal.b62985ca92015-04-17 08:45:51803 BoundTestNetLog log;
[email protected]034df0f32013-01-07 23:17:48804 TestLoadTimingInfoNotConnected(handle);
[email protected]9e743cd2010-03-16 07:03:53805
[email protected]2431756e2010-09-29 20:26:13806 EXPECT_EQ(OK,
807 handle.Init("a",
808 params_,
[email protected]bb1c4662013-11-14 00:00:07809 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:52810 callback.callback(),
[email protected]2431756e2010-09-29 20:26:13811 pool_.get(),
812 log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09813 EXPECT_TRUE(handle.is_initialized());
814 EXPECT_TRUE(handle.socket());
[email protected]034df0f32013-01-07 23:17:48815 TestLoadTimingInfoConnectedNotReused(handle);
816
[email protected]f6d1d6eb2009-06-24 20:16:09817 handle.Reset();
[email protected]034df0f32013-01-07 23:17:48818 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:30819
mmenke43758e62015-05-04 21:09:46820 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40821 log.GetEntries(&entries);
822
823 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:46824 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40825 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]9e743cd2010-03-16 07:03:53826 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40827 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:17828 NetLog::PHASE_NONE));
829 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40830 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]9e743cd2010-03-16 07:03:53831 NetLog::PHASE_NONE));
832 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40833 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09834}
835
[email protected]ab838892009-06-30 18:49:05836TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53837 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20838
[email protected]ab838892009-06-30 18:49:05839 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
vishal.b62985ca92015-04-17 08:45:51840 BoundTestNetLog log;
[email protected]9e743cd2010-03-16 07:03:53841
[email protected]2431756e2010-09-29 20:26:13842 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:52843 TestCompletionCallback callback;
[email protected]e60e47a2010-07-14 03:37:18844 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:13845 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43846 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:45847 info.headers = new HttpResponseHeaders(std::string());
[email protected]2431756e2010-09-29 20:26:13848 handle.set_ssl_error_response_info(info);
849 EXPECT_EQ(ERR_CONNECTION_FAILED,
850 handle.Init("a",
851 params_,
[email protected]bb1c4662013-11-14 00:00:07852 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:52853 callback.callback(),
[email protected]2431756e2010-09-29 20:26:13854 pool_.get(),
855 log.bound()));
856 EXPECT_FALSE(handle.socket());
857 EXPECT_FALSE(handle.is_ssl_error());
858 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]034df0f32013-01-07 23:17:48859 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:30860
mmenke43758e62015-05-04 21:09:46861 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40862 log.GetEntries(&entries);
863
864 EXPECT_EQ(3u, entries.size());
[email protected]5a1d7ca2010-04-28 20:12:27865 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40866 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:17867 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40868 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:17869 NetLog::PHASE_NONE));
[email protected]a2006ece2010-04-23 16:44:02870 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40871 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09872}
873
[email protected]211d21722009-07-22 15:48:53874TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
875 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
876
[email protected]9e743cd2010-03-16 07:03:53877 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30878
[email protected]bb1c4662013-11-14 00:00:07879 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
880 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
881 EXPECT_EQ(OK, StartRequest("c", DEFAULT_PRIORITY));
882 EXPECT_EQ(OK, StartRequest("d", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:53883
[email protected]2431756e2010-09-29 20:26:13884 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53885 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13886 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53887
[email protected]bb1c4662013-11-14 00:00:07888 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", DEFAULT_PRIORITY));
889 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", DEFAULT_PRIORITY));
890 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:53891
[email protected]2431756e2010-09-29 20:26:13892 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53893
[email protected]2431756e2010-09-29 20:26:13894 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53895 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13896 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53897
898 EXPECT_EQ(1, GetOrderOfRequest(1));
899 EXPECT_EQ(2, GetOrderOfRequest(2));
900 EXPECT_EQ(3, GetOrderOfRequest(3));
901 EXPECT_EQ(4, GetOrderOfRequest(4));
902 EXPECT_EQ(5, GetOrderOfRequest(5));
903 EXPECT_EQ(6, GetOrderOfRequest(6));
904 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17905
906 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13907 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53908}
909
910TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
911 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
912
[email protected]9e743cd2010-03-16 07:03:53913 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30914
[email protected]211d21722009-07-22 15:48:53915 // Reach all limits: max total sockets, and max sockets per group.
[email protected]bb1c4662013-11-14 00:00:07916 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
917 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
918 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
919 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:53920
[email protected]2431756e2010-09-29 20:26:13921 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53922 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13923 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53924
925 // Now create a new group and verify that we don't starve it.
[email protected]bb1c4662013-11-14 00:00:07926 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:53927
[email protected]2431756e2010-09-29 20:26:13928 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53929
[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 EXPECT_EQ(1, GetOrderOfRequest(1));
935 EXPECT_EQ(2, GetOrderOfRequest(2));
936 EXPECT_EQ(3, GetOrderOfRequest(3));
937 EXPECT_EQ(4, GetOrderOfRequest(4));
938 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17939
940 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13941 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53942}
943
944TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
945 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
946
[email protected]ac790b42009-12-02 04:31:31947 EXPECT_EQ(OK, StartRequest("b", LOWEST));
948 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
949 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
950 EXPECT_EQ(OK, StartRequest("a", LOWEST));
[email protected]211d21722009-07-22 15:48:53951
[email protected]2431756e2010-09-29 20:26:13952 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53953 client_socket_factory_.allocation_count());
954
[email protected]ac790b42009-12-02 04:31:31955 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
956 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
957 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53958
[email protected]2431756e2010-09-29 20:26:13959 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53960
[email protected]2431756e2010-09-29 20:26:13961 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53962
963 // First 4 requests don't have to wait, and finish in order.
964 EXPECT_EQ(1, GetOrderOfRequest(1));
965 EXPECT_EQ(2, GetOrderOfRequest(2));
966 EXPECT_EQ(3, GetOrderOfRequest(3));
967 EXPECT_EQ(4, GetOrderOfRequest(4));
968
[email protected]ac790b42009-12-02 04:31:31969 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
970 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53971 EXPECT_EQ(7, GetOrderOfRequest(5));
972 EXPECT_EQ(6, GetOrderOfRequest(6));
973 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17974
975 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13976 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]211d21722009-07-22 15:48:53977}
978
979TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
980 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
981
[email protected]ac790b42009-12-02 04:31:31982 EXPECT_EQ(OK, StartRequest("a", LOWEST));
983 EXPECT_EQ(OK, StartRequest("a", LOW));
984 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
985 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
[email protected]211d21722009-07-22 15:48:53986
[email protected]2431756e2010-09-29 20:26:13987 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53988 client_socket_factory_.allocation_count());
989
[email protected]ac790b42009-12-02 04:31:31990 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
991 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
992 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53993
[email protected]2431756e2010-09-29 20:26:13994 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[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());
[email protected]2431756e2010-09-29 20:26:13998 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53999
1000 // First 4 requests don't have to wait, and finish in order.
1001 EXPECT_EQ(1, GetOrderOfRequest(1));
1002 EXPECT_EQ(2, GetOrderOfRequest(2));
1003 EXPECT_EQ(3, GetOrderOfRequest(3));
1004 EXPECT_EQ(4, GetOrderOfRequest(4));
1005
1006 // Request ("b", 7) has the highest priority, but we can't make new socket for
1007 // group "b", because it has reached the per-group limit. Then we make
1008 // socket for ("c", 6), because it has higher priority than ("a", 4),
1009 // and we still can't make a socket for group "b".
1010 EXPECT_EQ(5, GetOrderOfRequest(5));
1011 EXPECT_EQ(6, GetOrderOfRequest(6));
1012 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171013
1014 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131015 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:531016}
1017
1018// Make sure that we count connecting sockets against the total limit.
1019TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
1020 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1021
[email protected]bb1c4662013-11-14 00:00:071022 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1023 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
1024 EXPECT_EQ(OK, StartRequest("c", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:531025
1026 // Create one asynchronous request.
1027 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]bb1c4662013-11-14 00:00:071028 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:531029
[email protected]6b175382009-10-13 06:47:471030 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1031 // actually become pending until 2ms after they have been created. In order
1032 // to flush all tasks, we need to wait so that we know there are no
1033 // soon-to-be-pending tasks waiting.
[email protected]26b9973962012-01-28 00:57:001034 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
[email protected]2da659e2013-05-23 20:51:341035 base::MessageLoop::current()->RunUntilIdle();
[email protected]6b175382009-10-13 06:47:471036
[email protected]211d21722009-07-22 15:48:531037 // The next synchronous request should wait for its turn.
1038 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]bb1c4662013-11-14 00:00:071039 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", DEFAULT_PRIORITY));
[email protected]211d21722009-07-22 15:48:531040
[email protected]2431756e2010-09-29 20:26:131041 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531042
[email protected]2431756e2010-09-29 20:26:131043 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531044 client_socket_factory_.allocation_count());
1045
1046 EXPECT_EQ(1, GetOrderOfRequest(1));
1047 EXPECT_EQ(2, GetOrderOfRequest(2));
1048 EXPECT_EQ(3, GetOrderOfRequest(3));
1049 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:171050 EXPECT_EQ(5, GetOrderOfRequest(5));
1051
1052 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131053 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:531054}
1055
[email protected]6427fe22010-04-16 22:27:411056TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
1057 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1058 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1059
[email protected]bb1c4662013-11-14 00:00:071060 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1061 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1062 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1063 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
[email protected]6427fe22010-04-16 22:27:411064
1065 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1066
1067 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1068
[email protected]bb1c4662013-11-14 00:00:071069 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", DEFAULT_PRIORITY));
1070 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", DEFAULT_PRIORITY));
[email protected]6427fe22010-04-16 22:27:411071
1072 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1073
[email protected]2431756e2010-09-29 20:26:131074 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411075 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131076 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411077 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131078 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1079 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411080 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
1081}
1082
[email protected]d7027bb2010-05-10 18:58:541083TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
1084 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1085 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1086
1087 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521088 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131089 EXPECT_EQ(ERR_IO_PENDING,
1090 handle.Init("a",
1091 params_,
[email protected]bb1c4662013-11-14 00:00:071092 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521093 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131094 pool_.get(),
1095 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541096
1097 ClientSocketHandle handles[4];
1098 for (size_t i = 0; i < arraysize(handles); ++i) {
[email protected]6ecf2b92011-12-15 01:14:521099 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131100 EXPECT_EQ(ERR_IO_PENDING,
1101 handles[i].Init("b",
1102 params_,
[email protected]bb1c4662013-11-14 00:00:071103 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521104 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131105 pool_.get(),
1106 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541107 }
1108
1109 // One will be stalled, cancel all the handles now.
1110 // This should hit the OnAvailableSocketSlot() code where we previously had
1111 // stalled groups, but no longer have any.
1112 for (size_t i = 0; i < arraysize(handles); ++i)
1113 handles[i].Reset();
1114}
1115
[email protected]eb5a99382010-07-11 03:18:261116TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:541117 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1118 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1119
[email protected]eb5a99382010-07-11 03:18:261120 {
1121 ClientSocketHandle handles[kDefaultMaxSockets];
[email protected]6ecf2b92011-12-15 01:14:521122 TestCompletionCallback callbacks[kDefaultMaxSockets];
[email protected]eb5a99382010-07-11 03:18:261123 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]2431756e2010-09-29 20:26:131124 EXPECT_EQ(OK, handles[i].Init(base::IntToString(i),
1125 params_,
[email protected]bb1c4662013-11-14 00:00:071126 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521127 callbacks[i].callback(),
[email protected]2431756e2010-09-29 20:26:131128 pool_.get(),
1129 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261130 }
1131
1132 // Force a stalled group.
1133 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521134 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131135 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1136 params_,
[email protected]bb1c4662013-11-14 00:00:071137 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521138 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131139 pool_.get(),
1140 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261141
1142 // Cancel the stalled request.
1143 stalled_handle.Reset();
1144
1145 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1146 EXPECT_EQ(0, pool_->IdleSocketCount());
1147
1148 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541149 }
1150
[email protected]43a21b82010-06-10 21:30:541151 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1152 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:261153}
[email protected]43a21b82010-06-10 21:30:541154
[email protected]eb5a99382010-07-11 03:18:261155TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
1156 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1157 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1158
1159 {
1160 ClientSocketHandle handles[kDefaultMaxSockets];
1161 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521162 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131163 EXPECT_EQ(ERR_IO_PENDING, handles[i].Init(base::IntToString(i),
1164 params_,
[email protected]bb1c4662013-11-14 00:00:071165 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521166 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131167 pool_.get(),
1168 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261169 }
1170
1171 // Force a stalled group.
1172 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1173 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521174 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131175 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1176 params_,
[email protected]bb1c4662013-11-14 00:00:071177 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521178 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131179 pool_.get(),
1180 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261181
1182 // Since it is stalled, it should have no connect jobs.
1183 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101184 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261185
1186 // Cancel the stalled request.
1187 handles[0].Reset();
1188
[email protected]eb5a99382010-07-11 03:18:261189 // Now we should have a connect job.
1190 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101191 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261192
1193 // The stalled socket should connect.
1194 EXPECT_EQ(OK, callback.WaitForResult());
1195
1196 EXPECT_EQ(kDefaultMaxSockets + 1,
1197 client_socket_factory_.allocation_count());
1198 EXPECT_EQ(0, pool_->IdleSocketCount());
1199 EXPECT_EQ(0, 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 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541203 }
1204
[email protected]eb5a99382010-07-11 03:18:261205 EXPECT_EQ(1, pool_->IdleSocketCount());
1206}
[email protected]43a21b82010-06-10 21:30:541207
[email protected]eb5a99382010-07-11 03:18:261208TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1209 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1210 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:541211
[email protected]eb5a99382010-07-11 03:18:261212 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521213 TestCompletionCallback callback;
[email protected]eb5a99382010-07-11 03:18:261214 {
[email protected]51fdc7c2012-04-10 19:19:481215 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261216 ClientSocketHandle handles[kDefaultMaxSockets];
1217 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521218 TestCompletionCallback callback;
[email protected]1870d5cf2011-05-12 01:55:401219 EXPECT_EQ(OK, handles[i].Init(base::StringPrintf(
1220 "Take 2: %d", i),
1221 params_,
[email protected]bb1c4662013-11-14 00:00:071222 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521223 callback.callback(),
[email protected]1870d5cf2011-05-12 01:55:401224 pool_.get(),
1225 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261226 }
1227
1228 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1229 EXPECT_EQ(0, pool_->IdleSocketCount());
[email protected]51fdc7c2012-04-10 19:19:481230 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261231
1232 // Now we will hit the socket limit.
[email protected]2431756e2010-09-29 20:26:131233 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1234 params_,
[email protected]bb1c4662013-11-14 00:00:071235 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521236 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131237 pool_.get(),
1238 BoundNetLog()));
[email protected]51fdc7c2012-04-10 19:19:481239 EXPECT_TRUE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261240
1241 // Dropping out of scope will close all handles and return them to idle.
1242 }
[email protected]43a21b82010-06-10 21:30:541243
1244 // But if we wait for it, the released idle sockets will be closed in
1245 // preference of the waiting request.
[email protected]8ae03f42010-07-07 19:08:101246 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]eb5a99382010-07-11 03:18:261247
1248 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1249 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:541250}
1251
1252// Regression test for http://crbug.com/40952.
1253TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1254 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]06d94042010-08-25 01:45:221255 pool_->EnableConnectBackupJobs();
[email protected]43a21b82010-06-10 21:30:541256 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1257
1258 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1259 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521260 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131261 EXPECT_EQ(OK, handle.Init(base::IntToString(i),
1262 params_,
[email protected]bb1c4662013-11-14 00:00:071263 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521264 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131265 pool_.get(),
1266 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541267 }
1268
1269 // Flush all the DoReleaseSocket tasks.
[email protected]2da659e2013-05-23 20:51:341270 base::MessageLoop::current()->RunUntilIdle();
[email protected]43a21b82010-06-10 21:30:541271
1272 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1273 // reuse a socket.
1274 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1275 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521276 TestCompletionCallback callback;
[email protected]43a21b82010-06-10 21:30:541277
1278 // "0" is special here, since it should be the first entry in the sorted map,
1279 // which is the one which we would close an idle socket for. We shouldn't
1280 // close an idle socket though, since we should reuse the idle socket.
[email protected]2431756e2010-09-29 20:26:131281 EXPECT_EQ(OK, handle.Init("0",
1282 params_,
[email protected]bb1c4662013-11-14 00:00:071283 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521284 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131285 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211286 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541287
1288 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1289 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1290}
1291
[email protected]ab838892009-06-30 18:49:051292TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531293 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091294
[email protected]bb1c4662013-11-14 00:00:071295 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1296 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
[email protected]c9c6f5c2010-07-31 01:30:031297 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", IDLE));
[email protected]ac790b42009-12-02 04:31:311298 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1299 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1300 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1301 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1302 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091303
[email protected]2431756e2010-09-29 20:26:131304 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091305
[email protected]c9d6a1d2009-07-14 16:15:201306 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1307 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131308 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1309 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091310
[email protected]c9d6a1d2009-07-14 16:15:201311 EXPECT_EQ(1, GetOrderOfRequest(1));
1312 EXPECT_EQ(2, GetOrderOfRequest(2));
[email protected]c9c6f5c2010-07-31 01:30:031313 EXPECT_EQ(8, GetOrderOfRequest(3));
1314 EXPECT_EQ(6, GetOrderOfRequest(4));
1315 EXPECT_EQ(4, GetOrderOfRequest(5));
1316 EXPECT_EQ(3, GetOrderOfRequest(6));
1317 EXPECT_EQ(5, GetOrderOfRequest(7));
1318 EXPECT_EQ(7, GetOrderOfRequest(8));
[email protected]75439d3b2009-07-23 22:11:171319
1320 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131321 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]f6d1d6eb2009-06-24 20:16:091322}
1323
[email protected]ab838892009-06-30 18:49:051324TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531325 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091326
[email protected]bb1c4662013-11-14 00:00:071327 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1328 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
[email protected]ac790b42009-12-02 04:31:311329 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1330 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1331 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1332 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1333 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091334
[email protected]2431756e2010-09-29 20:26:131335 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091336
[email protected]2431756e2010-09-29 20:26:131337 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
1338 EXPECT_EQ(OK, request(i)->WaitForResult());
[email protected]c9d6a1d2009-07-14 16:15:201339
[email protected]2431756e2010-09-29 20:26:131340 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]c9d6a1d2009-07-14 16:15:201341 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131342 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1343 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091344}
1345
1346// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:051347// The pending connect job will be cancelled and should not call back into
1348// ClientSocketPoolBase.
1349TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531350 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201351
[email protected]ab838892009-06-30 18:49:051352 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131353 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521354 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131355 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1356 params_,
[email protected]bb1c4662013-11-14 00:00:071357 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521358 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131359 pool_.get(),
1360 BoundNetLog()));
1361 handle.Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091362}
1363
[email protected]ab838892009-06-30 18:49:051364TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531365 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201366
[email protected]ab838892009-06-30 18:49:051367 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061368 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521369 TestCompletionCallback callback;
[email protected]f6d1d6eb2009-06-24 20:16:091370
[email protected]2431756e2010-09-29 20:26:131371 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1372 params_,
[email protected]bb1c4662013-11-14 00:00:071373 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521374 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131375 pool_.get(),
1376 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091377
1378 handle.Reset();
1379
[email protected]6ecf2b92011-12-15 01:14:521380 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:131381 EXPECT_EQ(ERR_IO_PENDING,
1382 handle.Init("a",
1383 params_,
[email protected]bb1c4662013-11-14 00:00:071384 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521385 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:131386 pool_.get(),
1387 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091388
1389 EXPECT_EQ(OK, callback2.WaitForResult());
1390 EXPECT_FALSE(callback.have_result());
1391
1392 handle.Reset();
1393}
1394
[email protected]ab838892009-06-30 18:49:051395TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531396 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091397
[email protected]bb1c4662013-11-14 00:00:071398 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1399 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
[email protected]ac790b42009-12-02 04:31:311400 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1401 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1402 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1403 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1404 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091405
1406 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201407 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]2431756e2010-09-29 20:26:131408 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1409 (*requests())[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091410
[email protected]2431756e2010-09-29 20:26:131411 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091412
[email protected]c9d6a1d2009-07-14 16:15:201413 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1414 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131415 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1416 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091417
[email protected]c9d6a1d2009-07-14 16:15:201418 EXPECT_EQ(1, GetOrderOfRequest(1));
1419 EXPECT_EQ(2, GetOrderOfRequest(2));
1420 EXPECT_EQ(5, GetOrderOfRequest(3));
1421 EXPECT_EQ(3, GetOrderOfRequest(4));
[email protected]2431756e2010-09-29 20:26:131422 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1423 GetOrderOfRequest(5)); // Canceled request.
[email protected]c9d6a1d2009-07-14 16:15:201424 EXPECT_EQ(4, GetOrderOfRequest(6));
1425 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171426
1427 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131428 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091429}
1430
mmenke33d24423d2015-05-19 19:41:091431// Function to be used as a callback on socket request completion. It first
1432// disconnects the successfully connected socket from the first request, and
1433// then reuses the ClientSocketHandle to request another socket.
1434//
1435// |nested_callback| is called with the result of the second socket request.
1436void RequestSocketOnComplete(ClientSocketHandle* handle,
1437 TestClientSocketPool* pool,
1438 TestConnectJobFactory* test_connect_job_factory,
1439 TestConnectJob::JobType next_job_type,
1440 const CompletionCallback& nested_callback,
1441 int first_request_result) {
1442 EXPECT_EQ(OK, first_request_result);
1443
1444 test_connect_job_factory->set_job_type(next_job_type);
1445
1446 // Don't allow reuse of the socket. Disconnect it and then release it.
1447 if (handle->socket())
1448 handle->socket()->Disconnect();
1449 handle->Reset();
1450
1451 scoped_refptr<TestSocketParams> params(
1452 new TestSocketParams(false /* ignore_limits */));
1453 TestCompletionCallback callback;
1454 int rv =
1455 handle->Init("a", params, LOWEST, nested_callback, pool, BoundNetLog());
1456 if (rv != ERR_IO_PENDING) {
1457 DCHECK_EQ(TestConnectJob::kMockJob, next_job_type);
1458 nested_callback.Run(rv);
1459 } else {
1460 DCHECK_EQ(TestConnectJob::kMockPendingJob, next_job_type);
[email protected]6ecf2b92011-12-15 01:14:521461 }
mmenke33d24423d2015-05-19 19:41:091462}
[email protected]f6d1d6eb2009-06-24 20:16:091463
mmenke33d24423d2015-05-19 19:41:091464// Tests the case where a second socket is requested in a completion callback,
1465// and the second socket connects asynchronously. Reuses the same
1466// ClientSocketHandle for the second socket, after disconnecting the first.
[email protected]2ab05b52009-07-01 23:57:581467TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531468 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201469
[email protected]0b7648c2009-07-06 20:14:011470 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061471 ClientSocketHandle handle;
mmenke33d24423d2015-05-19 19:41:091472 TestCompletionCallback second_result_callback;
1473 int rv = handle.Init(
1474 "a", params_, DEFAULT_PRIORITY,
1475 base::Bind(&RequestSocketOnComplete, &handle, pool_.get(),
1476 connect_job_factory_, TestConnectJob::kMockPendingJob,
1477 second_result_callback.callback()),
1478 pool_.get(), BoundNetLog());
[email protected]f6d1d6eb2009-06-24 20:16:091479 ASSERT_EQ(ERR_IO_PENDING, rv);
1480
mmenke33d24423d2015-05-19 19:41:091481 EXPECT_EQ(OK, second_result_callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581482}
[email protected]f6d1d6eb2009-06-24 20:16:091483
mmenke33d24423d2015-05-19 19:41:091484// Tests the case where a second socket is requested in a completion callback,
1485// and the second socket connects synchronously. Reuses the same
1486// ClientSocketHandle for the second socket, after disconnecting the first.
[email protected]2ab05b52009-07-01 23:57:581487TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531488 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201489
[email protected]0b7648c2009-07-06 20:14:011490 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061491 ClientSocketHandle handle;
mmenke33d24423d2015-05-19 19:41:091492 TestCompletionCallback second_result_callback;
1493 int rv = handle.Init(
1494 "a", params_, DEFAULT_PRIORITY,
1495 base::Bind(&RequestSocketOnComplete, &handle, pool_.get(),
1496 connect_job_factory_, TestConnectJob::kMockPendingJob,
1497 second_result_callback.callback()),
1498 pool_.get(), BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581499 ASSERT_EQ(ERR_IO_PENDING, rv);
1500
mmenke33d24423d2015-05-19 19:41:091501 EXPECT_EQ(OK, second_result_callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091502}
1503
1504// Make sure that pending requests get serviced after active requests get
1505// cancelled.
[email protected]ab838892009-06-30 18:49:051506TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531507 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201508
[email protected]0b7648c2009-07-06 20:14:011509 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091510
[email protected]bb1c4662013-11-14 00:00:071511 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1512 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1513 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1514 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1515 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1516 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1517 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
[email protected]f6d1d6eb2009-06-24 20:16:091518
[email protected]c9d6a1d2009-07-14 16:15:201519 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1520 // Let's cancel them.
1521 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]2431756e2010-09-29 20:26:131522 ASSERT_FALSE(request(i)->handle()->is_initialized());
1523 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091524 }
1525
[email protected]f6d1d6eb2009-06-24 20:16:091526 // Let's wait for the rest to complete now.
[email protected]2431756e2010-09-29 20:26:131527 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
1528 EXPECT_EQ(OK, request(i)->WaitForResult());
1529 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091530 }
1531
[email protected]2431756e2010-09-29 20:26:131532 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1533 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091534}
1535
1536// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051537TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531538 const size_t kMaxSockets = 5;
1539 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201540
[email protected]0b7648c2009-07-06 20:14:011541 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091542
[email protected]211d21722009-07-22 15:48:531543 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1544 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091545
1546 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531547 for (size_t i = 0; i < kNumberOfRequests; ++i)
[email protected]bb1c4662013-11-14 00:00:071548 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
[email protected]f6d1d6eb2009-06-24 20:16:091549
[email protected]211d21722009-07-22 15:48:531550 for (size_t i = 0; i < kNumberOfRequests; ++i)
[email protected]2431756e2010-09-29 20:26:131551 EXPECT_EQ(ERR_CONNECTION_FAILED, request(i)->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091552}
1553
[email protected]5fc08e32009-07-15 17:09:571554TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531555 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571556
1557 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1558
[email protected]2431756e2010-09-29 20:26:131559 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521560 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131561 int rv = handle.Init("a",
1562 params_,
[email protected]bb1c4662013-11-14 00:00:071563 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521564 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131565 pool_.get(),
1566 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571567 EXPECT_EQ(ERR_IO_PENDING, rv);
1568
1569 // Cancel the active request.
[email protected]2431756e2010-09-29 20:26:131570 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571571
[email protected]2431756e2010-09-29 20:26:131572 rv = handle.Init("a",
1573 params_,
[email protected]bb1c4662013-11-14 00:00:071574 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521575 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131576 pool_.get(),
1577 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571578 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131579 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]5fc08e32009-07-15 17:09:571580
[email protected]2431756e2010-09-29 20:26:131581 EXPECT_FALSE(handle.is_reused());
[email protected]034df0f32013-01-07 23:17:481582 TestLoadTimingInfoConnectedNotReused(handle);
[email protected]5fc08e32009-07-15 17:09:571583 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1584}
1585
[email protected]2b7523d2009-07-29 20:29:231586// Regression test for http://crbug.com/17985.
1587TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1588 const int kMaxSockets = 3;
1589 const int kMaxSocketsPerGroup = 2;
1590 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1591
[email protected]ac790b42009-12-02 04:31:311592 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231593
[email protected]bb1c4662013-11-14 00:00:071594 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
1595 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
[email protected]2b7523d2009-07-29 20:29:231596
1597 // This is going to be a pending request in an otherwise empty group.
[email protected]bb1c4662013-11-14 00:00:071598 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
[email protected]2b7523d2009-07-29 20:29:231599
1600 // Reach the maximum socket limit.
[email protected]bb1c4662013-11-14 00:00:071601 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
[email protected]2b7523d2009-07-29 20:29:231602
1603 // Create a stalled group with high priorities.
1604 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1605 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
[email protected]2b7523d2009-07-29 20:29:231606
[email protected]eb5a99382010-07-11 03:18:261607 // Release the first two sockets from "a". Because this is a keepalive,
1608 // the first release will unblock the pending request for "a". The
1609 // second release will unblock a request for "c", becaue it is the next
1610 // high priority socket.
[email protected]2431756e2010-09-29 20:26:131611 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1612 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]2b7523d2009-07-29 20:29:231613
1614 // Closing idle sockets should not get us into trouble, but in the bug
1615 // we were hitting a CHECK here.
[email protected]93054cc12010-06-08 06:12:411616 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]43a21b82010-06-10 21:30:541617 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261618
[email protected]2da659e2013-05-23 20:51:341619 // Run the released socket wakeups.
1620 base::MessageLoop::current()->RunUntilIdle();
[email protected]2b7523d2009-07-29 20:29:231621}
1622
[email protected]4d3b05d2010-01-27 21:27:291623TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531624 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571625
1626 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131627 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521628 TestCompletionCallback callback;
vishal.b62985ca92015-04-17 08:45:511629 BoundTestNetLog log;
[email protected]2431756e2010-09-29 20:26:131630 int rv = handle.Init("a",
1631 params_,
1632 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:521633 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131634 pool_.get(),
1635 log.bound());
[email protected]5fc08e32009-07-15 17:09:571636 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131637 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
[email protected]034df0f32013-01-07 23:17:481638 TestLoadTimingInfoNotConnected(handle);
1639
[email protected]2431756e2010-09-29 20:26:131640 EXPECT_EQ(OK, callback.WaitForResult());
1641 EXPECT_TRUE(handle.is_initialized());
1642 EXPECT_TRUE(handle.socket());
[email protected]034df0f32013-01-07 23:17:481643 TestLoadTimingInfoConnectedNotReused(handle);
1644
[email protected]2431756e2010-09-29 20:26:131645 handle.Reset();
[email protected]034df0f32013-01-07 23:17:481646 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:301647
mmenke43758e62015-05-04 21:09:461648 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:401649 log.GetEntries(&entries);
1650
1651 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:461652 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401653 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171654 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401655 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171656 NetLog::PHASE_NONE));
1657 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401658 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]06650c52010-06-03 00:49:171659 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:461660 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401661 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571662}
1663
[email protected]4d3b05d2010-01-27 21:27:291664TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571665 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531666 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571667
1668 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2431756e2010-09-29 20:26:131669 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521670 TestCompletionCallback callback;
vishal.b62985ca92015-04-17 08:45:511671 BoundTestNetLog log;
[email protected]e60e47a2010-07-14 03:37:181672 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:131673 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:431674 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:451675 info.headers = new HttpResponseHeaders(std::string());
[email protected]2431756e2010-09-29 20:26:131676 handle.set_ssl_error_response_info(info);
1677 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1678 params_,
[email protected]bb1c4662013-11-14 00:00:071679 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521680 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131681 pool_.get(),
1682 log.bound()));
1683 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1684 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1685 EXPECT_FALSE(handle.is_ssl_error());
1686 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:301687
mmenke43758e62015-05-04 21:09:461688 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:401689 log.GetEntries(&entries);
1690
1691 EXPECT_EQ(3u, entries.size());
[email protected]e9002a92010-01-29 07:10:461692 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401693 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171694 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401695 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171696 NetLog::PHASE_NONE));
[email protected]6b624c62010-03-14 08:37:321697 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401698 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571699}
1700
mmenke6be122f2015-03-09 22:22:471701// Check that an async ConnectJob failure does not result in creation of a new
1702// ConnectJob when there's another pending request also waiting on its own
1703// ConnectJob. See http://crbug.com/463960.
1704TEST_F(ClientSocketPoolBaseTest, AsyncFailureWithPendingRequestWithJob) {
1705 CreatePool(2, 2);
1706 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1707
1708 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1709 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
1710
1711 EXPECT_EQ(ERR_CONNECTION_FAILED, request(0)->WaitForResult());
1712 EXPECT_EQ(ERR_CONNECTION_FAILED, request(1)->WaitForResult());
1713
1714 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1715}
1716
[email protected]4d3b05d2010-01-27 21:27:291717TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101718 // TODO(eroman): Add back the log expectations! Removed them because the
1719 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531720 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571721
1722 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131723 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521724 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131725 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:521726 TestCompletionCallback callback2;
[email protected]5fc08e32009-07-15 17:09:571727
[email protected]2431756e2010-09-29 20:26:131728 EXPECT_EQ(ERR_IO_PENDING,
1729 handle.Init("a",
1730 params_,
[email protected]bb1c4662013-11-14 00:00:071731 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521732 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131733 pool_.get(),
1734 BoundNetLog()));
vishal.b62985ca92015-04-17 08:45:511735 BoundTestNetLog log2;
[email protected]2431756e2010-09-29 20:26:131736 EXPECT_EQ(ERR_IO_PENDING,
1737 handle2.Init("a",
1738 params_,
[email protected]bb1c4662013-11-14 00:00:071739 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521740 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:131741 pool_.get(),
1742 BoundNetLog()));
[email protected]5fc08e32009-07-15 17:09:571743
[email protected]2431756e2010-09-29 20:26:131744 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571745
[email protected]fd7b7c92009-08-20 19:38:301746
1747 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301748
[email protected]2431756e2010-09-29 20:26:131749 EXPECT_EQ(OK, callback2.WaitForResult());
1750 handle2.Reset();
[email protected]fd7b7c92009-08-20 19:38:301751
1752 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531753 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571754}
1755
[email protected]4d3b05d2010-01-27 21:27:291756TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341757 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1758
[email protected]17a0c6c2009-08-04 00:07:041759 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1760
[email protected]ac790b42009-12-02 04:31:311761 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1762 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1763 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1764 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341765
1766 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]2431756e2010-09-29 20:26:131767 (*requests())[2]->handle()->Reset();
1768 (*requests())[3]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341769 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1770
[email protected]2431756e2010-09-29 20:26:131771 (*requests())[1]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341772 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1773
[email protected]2431756e2010-09-29 20:26:131774 (*requests())[0]->handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261775 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]974ebd62009-08-03 23:14:341776}
1777
[email protected]5fc08e32009-07-15 17:09:571778// When requests and ConnectJobs are not coupled, the request will get serviced
1779// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291780TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531781 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571782
1783 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321784 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571785
[email protected]2431756e2010-09-29 20:26:131786 std::vector<TestSocketRequest*> request_order;
1787 size_t completion_count; // unused
1788 TestSocketRequest req1(&request_order, &completion_count);
1789 int rv = req1.handle()->Init("a",
1790 params_,
[email protected]bb1c4662013-11-14 00:00:071791 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521792 req1.callback(), pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211793 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571794 EXPECT_EQ(ERR_IO_PENDING, rv);
1795 EXPECT_EQ(OK, req1.WaitForResult());
1796
1797 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1798 // without a job.
1799 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1800
[email protected]2431756e2010-09-29 20:26:131801 TestSocketRequest req2(&request_order, &completion_count);
1802 rv = req2.handle()->Init("a",
1803 params_,
[email protected]bb1c4662013-11-14 00:00:071804 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521805 req2.callback(),
[email protected]2431756e2010-09-29 20:26:131806 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211807 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571808 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131809 TestSocketRequest req3(&request_order, &completion_count);
1810 rv = req3.handle()->Init("a",
1811 params_,
[email protected]bb1c4662013-11-14 00:00:071812 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521813 req3.callback(),
[email protected]2431756e2010-09-29 20:26:131814 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211815 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571816 EXPECT_EQ(ERR_IO_PENDING, rv);
1817
1818 // Both Requests 2 and 3 are pending. We release socket 1 which should
1819 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331820 req1.handle()->Reset();
[email protected]2da659e2013-05-23 20:51:341821 // Run the released socket wakeups.
1822 base::MessageLoop::current()->RunUntilIdle();
[email protected]a6c59f62009-07-29 16:33:331823 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571824 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331825 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571826
1827 // Signal job 2, which should service request 3.
1828
1829 client_socket_factory_.SignalJobs();
1830 EXPECT_EQ(OK, req3.WaitForResult());
1831
[email protected]2431756e2010-09-29 20:26:131832 ASSERT_EQ(3U, request_order.size());
1833 EXPECT_EQ(&req1, request_order[0]);
1834 EXPECT_EQ(&req2, request_order[1]);
1835 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571836 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1837}
1838
1839// The requests are not coupled to the jobs. So, the requests should finish in
1840// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:291841TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531842 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571843 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321844 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571845
[email protected]2431756e2010-09-29 20:26:131846 std::vector<TestSocketRequest*> request_order;
1847 size_t completion_count; // unused
1848 TestSocketRequest req1(&request_order, &completion_count);
1849 int rv = req1.handle()->Init("a",
1850 params_,
[email protected]bb1c4662013-11-14 00:00:071851 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521852 req1.callback(),
[email protected]2431756e2010-09-29 20:26:131853 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211854 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571855 EXPECT_EQ(ERR_IO_PENDING, rv);
1856
[email protected]2431756e2010-09-29 20:26:131857 TestSocketRequest req2(&request_order, &completion_count);
1858 rv = req2.handle()->Init("a",
1859 params_,
[email protected]bb1c4662013-11-14 00:00:071860 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521861 req2.callback(),
[email protected]2431756e2010-09-29 20:26:131862 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211863 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571864 EXPECT_EQ(ERR_IO_PENDING, rv);
1865
1866 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321867 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571868
[email protected]2431756e2010-09-29 20:26:131869 TestSocketRequest req3(&request_order, &completion_count);
1870 rv = req3.handle()->Init("a",
1871 params_,
[email protected]bb1c4662013-11-14 00:00:071872 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521873 req3.callback(),
[email protected]2431756e2010-09-29 20:26:131874 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211875 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571876 EXPECT_EQ(ERR_IO_PENDING, rv);
1877
1878 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1879 EXPECT_EQ(OK, req2.WaitForResult());
1880 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1881
[email protected]2431756e2010-09-29 20:26:131882 ASSERT_EQ(3U, request_order.size());
1883 EXPECT_EQ(&req1, request_order[0]);
1884 EXPECT_EQ(&req2, request_order[1]);
1885 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571886}
1887
[email protected]03b7c8c2013-07-20 04:38:551888// Test GetLoadState in the case there's only one socket request.
1889TEST_F(ClientSocketPoolBaseTest, LoadStateOneRequest) {
[email protected]211d21722009-07-22 15:48:531890 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]03b7c8c2013-07-20 04:38:551891 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
[email protected]5fc08e32009-07-15 17:09:571892
[email protected]2431756e2010-09-29 20:26:131893 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521894 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131895 int rv = handle.Init("a",
1896 params_,
[email protected]bb1c4662013-11-14 00:00:071897 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:521898 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131899 pool_.get(),
1900 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571901 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]03b7c8c2013-07-20 04:38:551902 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571903
[email protected]03b7c8c2013-07-20 04:38:551904 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
1905 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
1906
1907 // No point in completing the connection, since ClientSocketHandles only
1908 // expect the LoadState to be checked while connecting.
1909}
1910
1911// Test GetLoadState in the case there are two socket requests.
haavardm835c1d62015-04-22 08:18:001912// Only the first connection in the pool should affect the pool's load status.
[email protected]03b7c8c2013-07-20 04:38:551913TEST_F(ClientSocketPoolBaseTest, LoadStateTwoRequests) {
1914 CreatePool(2, 2);
1915 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1916
1917 ClientSocketHandle handle;
1918 TestCompletionCallback callback;
haavardm835c1d62015-04-22 08:18:001919 int rv = handle.Init("a", params_, DEFAULT_PRIORITY, callback.callback(),
1920 pool_.get(), BoundNetLog());
1921 EXPECT_EQ(ERR_IO_PENDING, rv);
1922 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
1923
1924 ClientSocketHandle handle2;
1925 TestCompletionCallback callback2;
1926 rv = handle2.Init("a", params_, DEFAULT_PRIORITY, callback2.callback(),
1927 pool_.get(), BoundNetLog());
1928 EXPECT_EQ(ERR_IO_PENDING, rv);
1929 client_socket_factory_.SetJobLoadState(1, LOAD_STATE_RESOLVING_HOST);
1930
1931 // Check that both handles report the state of the first job.
1932 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle.GetLoadState());
1933 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle2.GetLoadState());
1934
1935 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_CONNECTING);
1936
1937 // Check that both handles change to LOAD_STATE_CONNECTING.
1938 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
1939 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
1940}
1941
1942// Test that the second connection request does not affect the pool's load
1943// status.
1944TEST_F(ClientSocketPoolBaseTest, LoadStateTwoRequestsChangeSecondRequestState) {
1945 CreatePool(2, 2);
1946 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1947
1948 ClientSocketHandle handle;
1949 TestCompletionCallback callback;
1950 int rv = handle.Init("a", params_, DEFAULT_PRIORITY, callback.callback(),
1951 pool_.get(), BoundNetLog());
[email protected]03b7c8c2013-07-20 04:38:551952 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]5fc08e32009-07-15 17:09:571953
[email protected]2431756e2010-09-29 20:26:131954 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:521955 TestCompletionCallback callback2;
haavardm835c1d62015-04-22 08:18:001956 rv = handle2.Init("a", params_, DEFAULT_PRIORITY, callback2.callback(),
1957 pool_.get(), BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571958 EXPECT_EQ(ERR_IO_PENDING, rv);
haavardm835c1d62015-04-22 08:18:001959 client_socket_factory_.SetJobLoadState(1, LOAD_STATE_RESOLVING_HOST);
[email protected]03b7c8c2013-07-20 04:38:551960
[email protected]03b7c8c2013-07-20 04:38:551961 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
1962 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
1963
haavardm835c1d62015-04-22 08:18:001964 // First job connects and the first request gets the socket. The
[email protected]03b7c8c2013-07-20 04:38:551965 // second handle switches to the state of the remaining ConnectJob.
1966 client_socket_factory_.SignalJob(0);
1967 EXPECT_EQ(OK, callback.WaitForResult());
haavardm835c1d62015-04-22 08:18:001968 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle2.GetLoadState());
[email protected]03b7c8c2013-07-20 04:38:551969}
1970
1971// Test GetLoadState in the case the per-group limit is reached.
1972TEST_F(ClientSocketPoolBaseTest, LoadStateGroupLimit) {
1973 CreatePool(2, 1);
1974 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1975
1976 ClientSocketHandle handle;
1977 TestCompletionCallback callback;
1978 int rv = handle.Init("a",
1979 params_,
1980 MEDIUM,
1981 callback.callback(),
1982 pool_.get(),
1983 BoundNetLog());
1984 EXPECT_EQ(ERR_IO_PENDING, rv);
1985 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
1986
1987 // Request another socket from the same pool, buth with a higher priority.
1988 // The first request should now be stalled at the socket group limit.
1989 ClientSocketHandle handle2;
1990 TestCompletionCallback callback2;
1991 rv = handle2.Init("a",
1992 params_,
1993 HIGHEST,
1994 callback2.callback(),
1995 pool_.get(),
1996 BoundNetLog());
1997 EXPECT_EQ(ERR_IO_PENDING, rv);
1998 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
1999 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
2000
2001 // The first handle should remain stalled as the other socket goes through
2002 // the connect process.
2003
2004 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2005 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2006 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle2.GetLoadState());
2007
2008 client_socket_factory_.SignalJob(0);
2009 EXPECT_EQ(OK, callback2.WaitForResult());
2010 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2011
2012 // Closing the second socket should cause the stalled handle to finally get a
2013 // ConnectJob.
2014 handle2.socket()->Disconnect();
2015 handle2.Reset();
2016 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2017}
2018
2019// Test GetLoadState in the case the per-pool limit is reached.
2020TEST_F(ClientSocketPoolBaseTest, LoadStatePoolLimit) {
2021 CreatePool(2, 2);
2022 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2023
2024 ClientSocketHandle handle;
2025 TestCompletionCallback callback;
2026 int rv = handle.Init("a",
2027 params_,
[email protected]bb1c4662013-11-14 00:00:072028 DEFAULT_PRIORITY,
[email protected]03b7c8c2013-07-20 04:38:552029 callback.callback(),
2030 pool_.get(),
2031 BoundNetLog());
2032 EXPECT_EQ(ERR_IO_PENDING, rv);
2033
2034 // Request for socket from another pool.
2035 ClientSocketHandle handle2;
2036 TestCompletionCallback callback2;
2037 rv = handle2.Init("b",
2038 params_,
[email protected]bb1c4662013-11-14 00:00:072039 DEFAULT_PRIORITY,
[email protected]03b7c8c2013-07-20 04:38:552040 callback2.callback(),
2041 pool_.get(),
2042 BoundNetLog());
2043 EXPECT_EQ(ERR_IO_PENDING, rv);
2044
2045 // Request another socket from the first pool. Request should stall at the
2046 // socket pool limit.
2047 ClientSocketHandle handle3;
2048 TestCompletionCallback callback3;
2049 rv = handle3.Init("a",
2050 params_,
[email protected]bb1c4662013-11-14 00:00:072051 DEFAULT_PRIORITY,
[email protected]03b7c8c2013-07-20 04:38:552052 callback2.callback(),
2053 pool_.get(),
2054 BoundNetLog());
2055 EXPECT_EQ(ERR_IO_PENDING, rv);
2056
2057 // The third handle should remain stalled as the other sockets in its group
2058 // goes through the connect process.
2059
2060 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2061 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2062
2063 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2064 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
2065 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2066
2067 client_socket_factory_.SignalJob(0);
2068 EXPECT_EQ(OK, callback.WaitForResult());
2069 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2070
2071 // Closing a socket should allow the stalled handle to finally get a new
2072 // ConnectJob.
2073 handle.socket()->Disconnect();
2074 handle.Reset();
2075 EXPECT_EQ(LOAD_STATE_CONNECTING, handle3.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:572076}
2077
[email protected]e772db3f2010-07-12 18:11:132078TEST_F(ClientSocketPoolBaseTest, Recoverable) {
2079 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2080 connect_job_factory_->set_job_type(TestConnectJob::kMockRecoverableJob);
2081
[email protected]2431756e2010-09-29 20:26:132082 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522083 TestCompletionCallback callback;
2084 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED,
[email protected]bb1c4662013-11-14 00:00:072085 handle.Init("a", params_, DEFAULT_PRIORITY, callback.callback(),
[email protected]6ecf2b92011-12-15 01:14:522086 pool_.get(), BoundNetLog()));
[email protected]2431756e2010-09-29 20:26:132087 EXPECT_TRUE(handle.is_initialized());
2088 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:132089}
2090
2091TEST_F(ClientSocketPoolBaseTest, AsyncRecoverable) {
2092 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2093
2094 connect_job_factory_->set_job_type(
2095 TestConnectJob::kMockPendingRecoverableJob);
[email protected]2431756e2010-09-29 20:26:132096 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522097 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132098 EXPECT_EQ(ERR_IO_PENDING,
2099 handle.Init("a",
2100 params_,
[email protected]bb1c4662013-11-14 00:00:072101 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522102 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132103 pool_.get(),
2104 BoundNetLog()));
2105 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2106 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, callback.WaitForResult());
2107 EXPECT_TRUE(handle.is_initialized());
2108 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:132109}
2110
[email protected]e60e47a2010-07-14 03:37:182111TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
2112 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2113 connect_job_factory_->set_job_type(
2114 TestConnectJob::kMockAdditionalErrorStateJob);
2115
[email protected]2431756e2010-09-29 20:26:132116 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522117 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132118 EXPECT_EQ(ERR_CONNECTION_FAILED,
2119 handle.Init("a",
2120 params_,
[email protected]bb1c4662013-11-14 00:00:072121 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522122 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132123 pool_.get(),
2124 BoundNetLog()));
2125 EXPECT_FALSE(handle.is_initialized());
2126 EXPECT_FALSE(handle.socket());
2127 EXPECT_TRUE(handle.is_ssl_error());
2128 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182129}
2130
2131TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
2132 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2133
2134 connect_job_factory_->set_job_type(
2135 TestConnectJob::kMockPendingAdditionalErrorStateJob);
[email protected]2431756e2010-09-29 20:26:132136 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522137 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132138 EXPECT_EQ(ERR_IO_PENDING,
2139 handle.Init("a",
2140 params_,
[email protected]bb1c4662013-11-14 00:00:072141 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522142 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132143 pool_.get(),
2144 BoundNetLog()));
2145 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2146 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
2147 EXPECT_FALSE(handle.is_initialized());
2148 EXPECT_FALSE(handle.socket());
2149 EXPECT_TRUE(handle.is_ssl_error());
2150 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182151}
2152
[email protected]e7b1c6d2c2012-05-05 00:54:032153// Make sure we can reuse sockets when the cleanup timer is disabled.
2154TEST_F(ClientSocketPoolBaseTest, DisableCleanupTimerReuse) {
[email protected]64770b7d2011-11-16 04:30:412155 // Disable cleanup timer.
2156 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(false);
2157
2158 CreatePoolWithIdleTimeouts(
2159 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
[email protected]e7b1c6d2c2012-05-05 00:54:032160 base::TimeDelta(), // Time out unused sockets immediately.
2161 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2162
2163 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2164
2165 ClientSocketHandle handle;
2166 TestCompletionCallback callback;
2167 int rv = handle.Init("a",
2168 params_,
2169 LOWEST,
2170 callback.callback(),
2171 pool_.get(),
2172 BoundNetLog());
2173 ASSERT_EQ(ERR_IO_PENDING, rv);
2174 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2175 ASSERT_EQ(OK, callback.WaitForResult());
2176
2177 // Use and release the socket.
2178 EXPECT_EQ(1, handle.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]034df0f32013-01-07 23:17:482179 TestLoadTimingInfoConnectedNotReused(handle);
[email protected]e7b1c6d2c2012-05-05 00:54:032180 handle.Reset();
2181
2182 // Should now have one idle socket.
2183 ASSERT_EQ(1, pool_->IdleSocketCount());
2184
2185 // Request a new socket. This should reuse the old socket and complete
2186 // synchronously.
vishal.b62985ca92015-04-17 08:45:512187 BoundTestNetLog log;
[email protected]e7b1c6d2c2012-05-05 00:54:032188 rv = handle.Init("a",
2189 params_,
2190 LOWEST,
2191 CompletionCallback(),
2192 pool_.get(),
2193 log.bound());
2194 ASSERT_EQ(OK, rv);
2195 EXPECT_TRUE(handle.is_reused());
[email protected]034df0f32013-01-07 23:17:482196 TestLoadTimingInfoConnectedReused(handle);
[email protected]e7b1c6d2c2012-05-05 00:54:032197
2198 ASSERT_TRUE(pool_->HasGroup("a"));
2199 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2200 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2201
mmenke43758e62015-05-04 21:09:462202 TestNetLogEntry::List entries;
[email protected]e7b1c6d2c2012-05-05 00:54:032203 log.GetEntries(&entries);
2204 EXPECT_TRUE(LogContainsEntryWithType(
2205 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
2206}
2207
2208// Make sure we cleanup old unused sockets when the cleanup timer is disabled.
2209TEST_F(ClientSocketPoolBaseTest, DisableCleanupTimerNoReuse) {
2210 // Disable cleanup timer.
2211 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(false);
2212
2213 CreatePoolWithIdleTimeouts(
2214 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2215 base::TimeDelta(), // Time out unused sockets immediately
2216 base::TimeDelta()); // Time out used sockets immediately
[email protected]64770b7d2011-11-16 04:30:412217
2218 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2219
2220 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2221
2222 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522223 TestCompletionCallback callback;
[email protected]64770b7d2011-11-16 04:30:412224 int rv = handle.Init("a",
2225 params_,
2226 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522227 callback.callback(),
[email protected]64770b7d2011-11-16 04:30:412228 pool_.get(),
2229 BoundNetLog());
[email protected]e7b1c6d2c2012-05-05 00:54:032230 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]64770b7d2011-11-16 04:30:412231 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2232
2233 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522234 TestCompletionCallback callback2;
[email protected]64770b7d2011-11-16 04:30:412235 rv = handle2.Init("a",
2236 params_,
2237 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522238 callback2.callback(),
[email protected]64770b7d2011-11-16 04:30:412239 pool_.get(),
2240 BoundNetLog());
[email protected]e7b1c6d2c2012-05-05 00:54:032241 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]64770b7d2011-11-16 04:30:412242 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
2243
2244 // Cancel one of the requests. Wait for the other, which will get the first
2245 // job. Release the socket. Run the loop again to make sure the second
2246 // socket is sitting idle and the first one is released (since ReleaseSocket()
2247 // just posts a DoReleaseSocket() task).
2248
2249 handle.Reset();
[email protected]e7b1c6d2c2012-05-05 00:54:032250 ASSERT_EQ(OK, callback2.WaitForResult());
[email protected]64770b7d2011-11-16 04:30:412251 // Use the socket.
[email protected]83039bb2011-12-09 18:43:552252 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]64770b7d2011-11-16 04:30:412253 handle2.Reset();
2254
[email protected]e7b1c6d2c2012-05-05 00:54:032255 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2256 // actually become pending until 2ms after they have been created. In order
2257 // to flush all tasks, we need to wait so that we know there are no
2258 // soon-to-be-pending tasks waiting.
2259 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
[email protected]2da659e2013-05-23 20:51:342260 base::MessageLoop::current()->RunUntilIdle();
[email protected]64770b7d2011-11-16 04:30:412261
[email protected]e7b1c6d2c2012-05-05 00:54:032262 // Both sockets should now be idle.
[email protected]64770b7d2011-11-16 04:30:412263 ASSERT_EQ(2, pool_->IdleSocketCount());
2264
2265 // Request a new socket. This should cleanup the unused and timed out ones.
2266 // A new socket will be created rather than reusing the idle one.
vishal.b62985ca92015-04-17 08:45:512267 BoundTestNetLog log;
[email protected]6ecf2b92011-12-15 01:14:522268 TestCompletionCallback callback3;
[email protected]64770b7d2011-11-16 04:30:412269 rv = handle.Init("a",
2270 params_,
2271 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522272 callback3.callback(),
[email protected]64770b7d2011-11-16 04:30:412273 pool_.get(),
2274 log.bound());
[email protected]e7b1c6d2c2012-05-05 00:54:032275 ASSERT_EQ(ERR_IO_PENDING, rv);
2276 ASSERT_EQ(OK, callback3.WaitForResult());
[email protected]64770b7d2011-11-16 04:30:412277 EXPECT_FALSE(handle.is_reused());
2278
[email protected]e7b1c6d2c2012-05-05 00:54:032279 // Make sure the idle socket is closed.
[email protected]64770b7d2011-11-16 04:30:412280 ASSERT_TRUE(pool_->HasGroup("a"));
2281 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2282 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2283
mmenke43758e62015-05-04 21:09:462284 TestNetLogEntry::List entries;
[email protected]64770b7d2011-11-16 04:30:412285 log.GetEntries(&entries);
2286 EXPECT_FALSE(LogContainsEntryWithType(
2287 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
2288}
2289
[email protected]4d3b05d2010-01-27 21:27:292290TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
[email protected]9bf28db2009-08-29 01:35:162291 CreatePoolWithIdleTimeouts(
2292 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2293 base::TimeDelta(), // Time out unused sockets immediately.
2294 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2295
2296 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2297
2298 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2299
[email protected]2431756e2010-09-29 20:26:132300 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522301 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132302 int rv = handle.Init("a",
2303 params_,
2304 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522305 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132306 pool_.get(),
2307 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:162308 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:132309 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
[email protected]9bf28db2009-08-29 01:35:162310
[email protected]2431756e2010-09-29 20:26:132311 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522312 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132313 rv = handle2.Init("a",
2314 params_,
2315 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522316 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132317 pool_.get(),
2318 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:162319 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:132320 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
[email protected]9bf28db2009-08-29 01:35:162321
2322 // Cancel one of the requests. Wait for the other, which will get the first
2323 // job. Release the socket. Run the loop again to make sure the second
2324 // socket is sitting idle and the first one is released (since ReleaseSocket()
2325 // just posts a DoReleaseSocket() task).
2326
[email protected]2431756e2010-09-29 20:26:132327 handle.Reset();
2328 EXPECT_EQ(OK, callback2.WaitForResult());
[email protected]0f873e82010-09-02 16:09:012329 // Use the socket.
[email protected]83039bb2011-12-09 18:43:552330 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]2431756e2010-09-29 20:26:132331 handle2.Reset();
[email protected]6b175382009-10-13 06:47:472332
2333 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2334 // actually become pending until 2ms after they have been created. In order
2335 // to flush all tasks, we need to wait so that we know there are no
2336 // soon-to-be-pending tasks waiting.
[email protected]26b9973962012-01-28 00:57:002337 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
[email protected]2da659e2013-05-23 20:51:342338 base::MessageLoop::current()->RunUntilIdle();
[email protected]9bf28db2009-08-29 01:35:162339
2340 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:042341
[email protected]9bf28db2009-08-29 01:35:162342 // Invoke the idle socket cleanup check. Only one socket should be left, the
2343 // used socket. Request it to make sure that it's used.
2344
2345 pool_->CleanupTimedOutIdleSockets();
vishal.b62985ca92015-04-17 08:45:512346 BoundTestNetLog log;
[email protected]2431756e2010-09-29 20:26:132347 rv = handle.Init("a",
2348 params_,
2349 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522350 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132351 pool_.get(),
2352 log.bound());
[email protected]9bf28db2009-08-29 01:35:162353 EXPECT_EQ(OK, rv);
[email protected]2431756e2010-09-29 20:26:132354 EXPECT_TRUE(handle.is_reused());
[email protected]b2fcd0e2010-12-01 15:19:402355
mmenke43758e62015-05-04 21:09:462356 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:402357 log.GetEntries(&entries);
[email protected]fd4fe0b2010-02-08 23:02:152358 EXPECT_TRUE(LogContainsEntryWithType(
[email protected]b2fcd0e2010-12-01 15:19:402359 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]9bf28db2009-08-29 01:35:162360}
2361
[email protected]2041cf342010-02-19 03:15:592362// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:162363// because of multiple releasing disconnected sockets.
2364TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
2365 CreatePoolWithIdleTimeouts(
2366 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2367 base::TimeDelta(), // Time out unused sockets immediately.
2368 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2369
2370 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2371
2372 // Startup 4 connect jobs. Two of them will be pending.
2373
[email protected]2431756e2010-09-29 20:26:132374 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522375 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132376 int rv = handle.Init("a",
2377 params_,
2378 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522379 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132380 pool_.get(),
2381 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162382 EXPECT_EQ(OK, rv);
2383
[email protected]2431756e2010-09-29 20:26:132384 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522385 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132386 rv = handle2.Init("a",
2387 params_,
2388 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522389 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132390 pool_.get(),
2391 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162392 EXPECT_EQ(OK, rv);
2393
[email protected]2431756e2010-09-29 20:26:132394 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:522395 TestCompletionCallback callback3;
[email protected]2431756e2010-09-29 20:26:132396 rv = handle3.Init("a",
2397 params_,
2398 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522399 callback3.callback(),
[email protected]2431756e2010-09-29 20:26:132400 pool_.get(),
2401 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162402 EXPECT_EQ(ERR_IO_PENDING, rv);
2403
[email protected]2431756e2010-09-29 20:26:132404 ClientSocketHandle handle4;
[email protected]6ecf2b92011-12-15 01:14:522405 TestCompletionCallback callback4;
[email protected]2431756e2010-09-29 20:26:132406 rv = handle4.Init("a",
2407 params_,
2408 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522409 callback4.callback(),
[email protected]2431756e2010-09-29 20:26:132410 pool_.get(),
2411 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162412 EXPECT_EQ(ERR_IO_PENDING, rv);
2413
2414 // Release two disconnected sockets.
2415
[email protected]2431756e2010-09-29 20:26:132416 handle.socket()->Disconnect();
2417 handle.Reset();
2418 handle2.socket()->Disconnect();
2419 handle2.Reset();
[email protected]4f2abec2010-02-03 18:10:162420
[email protected]2431756e2010-09-29 20:26:132421 EXPECT_EQ(OK, callback3.WaitForResult());
2422 EXPECT_FALSE(handle3.is_reused());
2423 EXPECT_EQ(OK, callback4.WaitForResult());
2424 EXPECT_FALSE(handle4.is_reused());
[email protected]4f2abec2010-02-03 18:10:162425}
2426
[email protected]d7027bb2010-05-10 18:58:542427// Regression test for http://crbug.com/42267.
2428// When DoReleaseSocket() is processed for one socket, it is blocked because the
2429// other stalled groups all have releasing sockets, so no progress can be made.
2430TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
2431 CreatePoolWithIdleTimeouts(
2432 4 /* socket limit */, 4 /* socket limit per group */,
2433 base::TimeDelta(), // Time out unused sockets immediately.
2434 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2435
2436 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2437
2438 // Max out the socket limit with 2 per group.
2439
[email protected]2431756e2010-09-29 20:26:132440 ClientSocketHandle handle_a[4];
[email protected]6ecf2b92011-12-15 01:14:522441 TestCompletionCallback callback_a[4];
[email protected]2431756e2010-09-29 20:26:132442 ClientSocketHandle handle_b[4];
[email protected]6ecf2b92011-12-15 01:14:522443 TestCompletionCallback callback_b[4];
[email protected]d7027bb2010-05-10 18:58:542444
2445 for (int i = 0; i < 2; ++i) {
[email protected]2431756e2010-09-29 20:26:132446 EXPECT_EQ(OK, handle_a[i].Init("a",
2447 params_,
2448 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522449 callback_a[i].callback(),
[email protected]2431756e2010-09-29 20:26:132450 pool_.get(),
2451 BoundNetLog()));
2452 EXPECT_EQ(OK, handle_b[i].Init("b",
2453 params_,
2454 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522455 callback_b[i].callback(),
[email protected]2431756e2010-09-29 20:26:132456 pool_.get(),
2457 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542458 }
[email protected]b89f7e42010-05-20 20:37:002459
[email protected]d7027bb2010-05-10 18:58:542460 // Make 4 pending requests, 2 per group.
2461
2462 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132463 EXPECT_EQ(ERR_IO_PENDING,
2464 handle_a[i].Init("a",
2465 params_,
2466 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522467 callback_a[i].callback(),
[email protected]2431756e2010-09-29 20:26:132468 pool_.get(),
2469 BoundNetLog()));
2470 EXPECT_EQ(ERR_IO_PENDING,
2471 handle_b[i].Init("b",
2472 params_,
2473 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522474 callback_b[i].callback(),
[email protected]2431756e2010-09-29 20:26:132475 pool_.get(),
2476 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542477 }
2478
2479 // Release b's socket first. The order is important, because in
2480 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2481 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2482 // first, which has a releasing socket, so it refuses to start up another
2483 // ConnectJob. So, we used to infinite loop on this.
[email protected]2431756e2010-09-29 20:26:132484 handle_b[0].socket()->Disconnect();
2485 handle_b[0].Reset();
2486 handle_a[0].socket()->Disconnect();
2487 handle_a[0].Reset();
[email protected]d7027bb2010-05-10 18:58:542488
2489 // Used to get stuck here.
[email protected]2da659e2013-05-23 20:51:342490 base::MessageLoop::current()->RunUntilIdle();
[email protected]d7027bb2010-05-10 18:58:542491
[email protected]2431756e2010-09-29 20:26:132492 handle_b[1].socket()->Disconnect();
2493 handle_b[1].Reset();
2494 handle_a[1].socket()->Disconnect();
2495 handle_a[1].Reset();
[email protected]d7027bb2010-05-10 18:58:542496
2497 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132498 EXPECT_EQ(OK, callback_b[i].WaitForResult());
2499 EXPECT_EQ(OK, callback_a[i].WaitForResult());
[email protected]d7027bb2010-05-10 18:58:542500 }
2501}
2502
[email protected]fd4fe0b2010-02-08 23:02:152503TEST_F(ClientSocketPoolBaseTest,
2504 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2505 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2506
2507 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2508
[email protected]bb1c4662013-11-14 00:00:072509 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
2510 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
2511 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
2512 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", DEFAULT_PRIORITY));
[email protected]fd4fe0b2010-02-08 23:02:152513
[email protected]2431756e2010-09-29 20:26:132514 EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
2515 EXPECT_EQ(OK, (*requests())[1]->WaitForResult());
2516 EXPECT_EQ(2u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152517
2518 // Releases one connection.
[email protected]2431756e2010-09-29 20:26:132519 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2520 EXPECT_EQ(OK, (*requests())[2]->WaitForResult());
[email protected]fd4fe0b2010-02-08 23:02:152521
[email protected]2431756e2010-09-29 20:26:132522 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2523 EXPECT_EQ(OK, (*requests())[3]->WaitForResult());
2524 EXPECT_EQ(4u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152525
2526 EXPECT_EQ(1, GetOrderOfRequest(1));
2527 EXPECT_EQ(2, GetOrderOfRequest(2));
2528 EXPECT_EQ(3, GetOrderOfRequest(3));
2529 EXPECT_EQ(4, GetOrderOfRequest(4));
2530
2531 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:132532 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
[email protected]fd4fe0b2010-02-08 23:02:152533}
2534
[email protected]6ecf2b92011-12-15 01:14:522535class TestReleasingSocketRequest : public TestCompletionCallbackBase {
[email protected]4f1e4982010-03-02 18:31:042536 public:
[email protected]2431756e2010-09-29 20:26:132537 TestReleasingSocketRequest(TestClientSocketPool* pool,
2538 int expected_result,
[email protected]e60e47a2010-07-14 03:37:182539 bool reset_releasing_handle)
2540 : pool_(pool),
2541 expected_result_(expected_result),
[email protected]6ecf2b92011-12-15 01:14:522542 reset_releasing_handle_(reset_releasing_handle),
[email protected]aa249b52013-04-30 01:04:322543 callback_(base::Bind(&TestReleasingSocketRequest::OnComplete,
2544 base::Unretained(this))) {
[email protected]6ecf2b92011-12-15 01:14:522545 }
2546
dchengb03027d2014-10-21 12:00:202547 ~TestReleasingSocketRequest() override {}
[email protected]4f1e4982010-03-02 18:31:042548
2549 ClientSocketHandle* handle() { return &handle_; }
2550
[email protected]6ecf2b92011-12-15 01:14:522551 const CompletionCallback& callback() const { return callback_; }
[email protected]4f1e4982010-03-02 18:31:042552
2553 private:
[email protected]6ecf2b92011-12-15 01:14:522554 void OnComplete(int result) {
2555 SetResult(result);
2556 if (reset_releasing_handle_)
2557 handle_.Reset();
2558
[email protected]bb1c4662013-11-14 00:00:072559 scoped_refptr<TestSocketParams> con_params(
2560 new TestSocketParams(false /* ignore_limits */));
[email protected]6ecf2b92011-12-15 01:14:522561 EXPECT_EQ(expected_result_,
[email protected]bb1c4662013-11-14 00:00:072562 handle2_.Init("a", con_params, DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522563 callback2_.callback(), pool_, BoundNetLog()));
2564 }
2565
[email protected]2431756e2010-09-29 20:26:132566 TestClientSocketPool* const pool_;
[email protected]e60e47a2010-07-14 03:37:182567 int expected_result_;
2568 bool reset_releasing_handle_;
[email protected]4f1e4982010-03-02 18:31:042569 ClientSocketHandle handle_;
2570 ClientSocketHandle handle2_;
[email protected]6ecf2b92011-12-15 01:14:522571 CompletionCallback callback_;
2572 TestCompletionCallback callback2_;
[email protected]4f1e4982010-03-02 18:31:042573};
2574
[email protected]e60e47a2010-07-14 03:37:182575
2576TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2577 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2578
[email protected]bb1c4662013-11-14 00:00:072579 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
2580 EXPECT_EQ(OK, StartRequest("a", DEFAULT_PRIORITY));
2581 EXPECT_EQ(OK, StartRequest("b", DEFAULT_PRIORITY));
[email protected]e60e47a2010-07-14 03:37:182582
[email protected]2431756e2010-09-29 20:26:132583 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]e60e47a2010-07-14 03:37:182584 client_socket_factory_.allocation_count());
2585
2586 connect_job_factory_->set_job_type(
2587 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2588 TestReleasingSocketRequest req(pool_.get(), OK, false);
[email protected]2431756e2010-09-29 20:26:132589 EXPECT_EQ(ERR_IO_PENDING,
[email protected]bb1c4662013-11-14 00:00:072590 req.handle()->Init("a", params_, DEFAULT_PRIORITY, req.callback(),
[email protected]6ecf2b92011-12-15 01:14:522591 pool_.get(), BoundNetLog()));
[email protected]e60e47a2010-07-14 03:37:182592 // The next job should complete synchronously
2593 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2594
2595 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
2596 EXPECT_FALSE(req.handle()->is_initialized());
2597 EXPECT_FALSE(req.handle()->socket());
2598 EXPECT_TRUE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:432599 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182600}
2601
[email protected]b6501d3d2010-06-03 23:53:342602// http://crbug.com/44724 regression test.
2603// We start releasing the pool when we flush on network change. When that
2604// happens, the only active references are in the ClientSocketHandles. When a
2605// ConnectJob completes and calls back into the last ClientSocketHandle, that
2606// callback can release the last reference and delete the pool. After the
2607// callback finishes, we go back to the stack frame within the now-deleted pool.
2608// Executing any code that refers to members of the now-deleted pool can cause
2609// crashes.
2610TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2611 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2612 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2613
2614 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522615 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132616 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2617 params_,
[email protected]bb1c4662013-11-14 00:00:072618 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522619 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132620 pool_.get(),
2621 BoundNetLog()));
[email protected]b6501d3d2010-06-03 23:53:342622
[email protected]7af985a2012-12-14 22:40:422623 pool_->FlushWithError(ERR_NETWORK_CHANGED);
[email protected]b6501d3d2010-06-03 23:53:342624
2625 // We'll call back into this now.
2626 callback.WaitForResult();
2627}
2628
[email protected]a7e38572010-06-07 18:22:242629TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2630 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2631 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2632
2633 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522634 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132635 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2636 params_,
[email protected]bb1c4662013-11-14 00:00:072637 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522638 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132639 pool_.get(),
2640 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242641 EXPECT_EQ(OK, callback.WaitForResult());
2642 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2643
[email protected]7af985a2012-12-14 22:40:422644 pool_->FlushWithError(ERR_NETWORK_CHANGED);
[email protected]a7e38572010-06-07 18:22:242645
2646 handle.Reset();
[email protected]2da659e2013-05-23 20:51:342647 base::MessageLoop::current()->RunUntilIdle();
[email protected]a7e38572010-06-07 18:22:242648
[email protected]2431756e2010-09-29 20:26:132649 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2650 params_,
[email protected]bb1c4662013-11-14 00:00:072651 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522652 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132653 pool_.get(),
2654 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242655 EXPECT_EQ(OK, callback.WaitForResult());
2656 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2657}
2658
[email protected]6ecf2b92011-12-15 01:14:522659class ConnectWithinCallback : public TestCompletionCallbackBase {
[email protected]06f92462010-08-31 19:24:142660 public:
2661 ConnectWithinCallback(
2662 const std::string& group_name,
2663 const scoped_refptr<TestSocketParams>& params,
[email protected]2431756e2010-09-29 20:26:132664 TestClientSocketPool* pool)
[email protected]6ecf2b92011-12-15 01:14:522665 : group_name_(group_name),
2666 params_(params),
2667 pool_(pool),
[email protected]aa249b52013-04-30 01:04:322668 callback_(base::Bind(&ConnectWithinCallback::OnComplete,
2669 base::Unretained(this))) {
[email protected]06f92462010-08-31 19:24:142670 }
2671
dchengb03027d2014-10-21 12:00:202672 ~ConnectWithinCallback() override {}
[email protected]06f92462010-08-31 19:24:142673
2674 int WaitForNestedResult() {
2675 return nested_callback_.WaitForResult();
2676 }
2677
[email protected]6ecf2b92011-12-15 01:14:522678 const CompletionCallback& callback() const { return callback_; }
2679
[email protected]06f92462010-08-31 19:24:142680 private:
[email protected]6ecf2b92011-12-15 01:14:522681 void OnComplete(int result) {
2682 SetResult(result);
2683 EXPECT_EQ(ERR_IO_PENDING,
2684 handle_.Init(group_name_,
2685 params_,
[email protected]bb1c4662013-11-14 00:00:072686 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522687 nested_callback_.callback(),
2688 pool_,
2689 BoundNetLog()));
2690 }
2691
[email protected]06f92462010-08-31 19:24:142692 const std::string group_name_;
2693 const scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:132694 TestClientSocketPool* const pool_;
[email protected]06f92462010-08-31 19:24:142695 ClientSocketHandle handle_;
[email protected]6ecf2b92011-12-15 01:14:522696 CompletionCallback callback_;
2697 TestCompletionCallback nested_callback_;
2698
2699 DISALLOW_COPY_AND_ASSIGN(ConnectWithinCallback);
[email protected]06f92462010-08-31 19:24:142700};
2701
2702TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
2703 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2704
2705 // First job will be waiting until it gets aborted.
2706 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2707
2708 ClientSocketHandle handle;
[email protected]2431756e2010-09-29 20:26:132709 ConnectWithinCallback callback("a", params_, pool_.get());
2710 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2711 params_,
[email protected]bb1c4662013-11-14 00:00:072712 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522713 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132714 pool_.get(),
2715 BoundNetLog()));
[email protected]06f92462010-08-31 19:24:142716
2717 // Second job will be started during the first callback, and will
2718 // asynchronously complete with OK.
2719 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]7af985a2012-12-14 22:40:422720 pool_->FlushWithError(ERR_NETWORK_CHANGED);
2721 EXPECT_EQ(ERR_NETWORK_CHANGED, callback.WaitForResult());
[email protected]06f92462010-08-31 19:24:142722 EXPECT_EQ(OK, callback.WaitForNestedResult());
2723}
2724
[email protected]25eea382010-07-10 23:55:262725// Cancel a pending socket request while we're at max sockets,
2726// and verify that the backup socket firing doesn't cause a crash.
2727TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
2728 // Max 4 sockets globally, max 4 sockets per group.
2729 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
[email protected]06d94042010-08-25 01:45:222730 pool_->EnableConnectBackupJobs();
[email protected]25eea382010-07-10 23:55:262731
[email protected]4baaf9d2010-08-31 15:15:442732 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2733 // timer.
[email protected]25eea382010-07-10 23:55:262734 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2735 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522736 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132737 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2738 params_,
[email protected]bb1c4662013-11-14 00:00:072739 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522740 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132741 pool_.get(),
2742 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262743
2744 // Start (MaxSockets - 1) connected sockets to reach max sockets.
2745 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2746 ClientSocketHandle handles[kDefaultMaxSockets];
2747 for (int i = 1; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:522748 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132749 EXPECT_EQ(OK, handles[i].Init("bar",
2750 params_,
[email protected]bb1c4662013-11-14 00:00:072751 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522752 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132753 pool_.get(),
2754 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262755 }
2756
[email protected]2da659e2013-05-23 20:51:342757 base::MessageLoop::current()->RunUntilIdle();
[email protected]25eea382010-07-10 23:55:262758
2759 // Cancel the pending request.
2760 handle.Reset();
2761
2762 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]26b9973962012-01-28 00:57:002763 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2764 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]25eea382010-07-10 23:55:262765
[email protected]2da659e2013-05-23 20:51:342766 base::MessageLoop::current()->RunUntilIdle();
[email protected]25eea382010-07-10 23:55:262767 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
2768}
2769
[email protected]3f00be82010-09-27 19:50:022770TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
[email protected]4baaf9d2010-08-31 15:15:442771 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2772 pool_->EnableConnectBackupJobs();
2773
2774 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2775 // timer.
2776 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2777 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522778 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132779 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2780 params_,
[email protected]bb1c4662013-11-14 00:00:072781 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522782 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132783 pool_.get(),
2784 BoundNetLog()));
[email protected]4baaf9d2010-08-31 15:15:442785 ASSERT_TRUE(pool_->HasGroup("bar"));
2786 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
[email protected]8159a1c2012-06-07 00:00:102787 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("bar"));
[email protected]4baaf9d2010-08-31 15:15:442788
2789 // Cancel the socket request. This should cancel the backup timer. Wait for
2790 // the backup time to see if it indeed got canceled.
2791 handle.Reset();
2792 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]26b9973962012-01-28 00:57:002793 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2794 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]2da659e2013-05-23 20:51:342795 base::MessageLoop::current()->RunUntilIdle();
[email protected]4baaf9d2010-08-31 15:15:442796 ASSERT_TRUE(pool_->HasGroup("bar"));
2797 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2798}
2799
[email protected]3f00be82010-09-27 19:50:022800TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
2801 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2802 pool_->EnableConnectBackupJobs();
2803
2804 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2805 // timer.
2806 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2807 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522808 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132809 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2810 params_,
[email protected]bb1c4662013-11-14 00:00:072811 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522812 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132813 pool_.get(),
2814 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022815 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2816 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522817 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132818 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("bar",
2819 params_,
[email protected]bb1c4662013-11-14 00:00:072820 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522821 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132822 pool_.get(),
2823 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022824 ASSERT_TRUE(pool_->HasGroup("bar"));
2825 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("bar"));
2826
2827 // Cancel request 1 and then complete request 2. With the requests finished,
2828 // the backup timer should be cancelled.
2829 handle.Reset();
2830 EXPECT_EQ(OK, callback2.WaitForResult());
2831 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]26b9973962012-01-28 00:57:002832 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2833 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]2da659e2013-05-23 20:51:342834 base::MessageLoop::current()->RunUntilIdle();
[email protected]3f00be82010-09-27 19:50:022835}
2836
[email protected]eb5a99382010-07-11 03:18:262837// Test delayed socket binding for the case where we have two connects,
2838// and while one is waiting on a connect, the other frees up.
2839// The socket waiting on a connect should switch immediately to the freed
2840// up socket.
2841TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
2842 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2843 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2844
2845 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522846 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132847 EXPECT_EQ(ERR_IO_PENDING,
2848 handle1.Init("a",
2849 params_,
[email protected]bb1c4662013-11-14 00:00:072850 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522851 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132852 pool_.get(),
2853 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262854 EXPECT_EQ(OK, callback.WaitForResult());
2855
2856 // No idle sockets, no pending jobs.
2857 EXPECT_EQ(0, pool_->IdleSocketCount());
2858 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2859
2860 // Create a second socket to the same host, but this one will wait.
2861 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2862 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132863 EXPECT_EQ(ERR_IO_PENDING,
2864 handle2.Init("a",
2865 params_,
[email protected]bb1c4662013-11-14 00:00:072866 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522867 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132868 pool_.get(),
2869 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262870 // No idle sockets, and one connecting job.
2871 EXPECT_EQ(0, pool_->IdleSocketCount());
2872 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2873
2874 // Return the first handle to the pool. This will initiate the delayed
2875 // binding.
2876 handle1.Reset();
2877
[email protected]2da659e2013-05-23 20:51:342878 base::MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262879
2880 // Still no idle sockets, still one pending connect job.
2881 EXPECT_EQ(0, pool_->IdleSocketCount());
2882 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2883
2884 // The second socket connected, even though it was a Waiting Job.
2885 EXPECT_EQ(OK, callback.WaitForResult());
2886
2887 // And we can see there is still one job waiting.
2888 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2889
2890 // Finally, signal the waiting Connect.
2891 client_socket_factory_.SignalJobs();
2892 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2893
[email protected]2da659e2013-05-23 20:51:342894 base::MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262895}
2896
2897// Test delayed socket binding when a group is at capacity and one
2898// of the group's sockets frees up.
2899TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
2900 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2901 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2902
2903 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522904 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132905 EXPECT_EQ(ERR_IO_PENDING,
2906 handle1.Init("a",
2907 params_,
[email protected]bb1c4662013-11-14 00:00:072908 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522909 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132910 pool_.get(),
2911 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262912 EXPECT_EQ(OK, callback.WaitForResult());
2913
2914 // No idle sockets, no pending jobs.
2915 EXPECT_EQ(0, pool_->IdleSocketCount());
2916 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2917
2918 // Create a second socket to the same host, but this one will wait.
2919 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2920 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132921 EXPECT_EQ(ERR_IO_PENDING,
2922 handle2.Init("a",
2923 params_,
[email protected]bb1c4662013-11-14 00:00:072924 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522925 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132926 pool_.get(),
2927 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262928 // No idle sockets, and one connecting job.
2929 EXPECT_EQ(0, pool_->IdleSocketCount());
2930 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2931
2932 // Return the first handle to the pool. This will initiate the delayed
2933 // binding.
2934 handle1.Reset();
2935
[email protected]2da659e2013-05-23 20:51:342936 base::MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262937
2938 // Still no idle sockets, still one pending connect job.
2939 EXPECT_EQ(0, pool_->IdleSocketCount());
2940 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2941
2942 // The second socket connected, even though it was a Waiting Job.
2943 EXPECT_EQ(OK, callback.WaitForResult());
2944
2945 // And we can see there is still one job waiting.
2946 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2947
2948 // Finally, signal the waiting Connect.
2949 client_socket_factory_.SignalJobs();
2950 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2951
[email protected]2da659e2013-05-23 20:51:342952 base::MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262953}
2954
2955// Test out the case where we have one socket connected, one
2956// connecting, when the first socket finishes and goes idle.
[email protected]2abfe90a2010-08-25 17:49:512957// Although the second connection is pending, the second request
[email protected]eb5a99382010-07-11 03:18:262958// should complete, by taking the first socket's idle socket.
2959TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
2960 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2961 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2962
2963 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522964 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132965 EXPECT_EQ(ERR_IO_PENDING,
2966 handle1.Init("a",
2967 params_,
[email protected]bb1c4662013-11-14 00:00:072968 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522969 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132970 pool_.get(),
2971 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262972 EXPECT_EQ(OK, callback.WaitForResult());
2973
2974 // No idle sockets, no pending jobs.
2975 EXPECT_EQ(0, pool_->IdleSocketCount());
2976 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2977
2978 // Create a second socket to the same host, but this one will wait.
2979 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2980 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132981 EXPECT_EQ(ERR_IO_PENDING,
2982 handle2.Init("a",
2983 params_,
[email protected]bb1c4662013-11-14 00:00:072984 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:522985 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132986 pool_.get(),
2987 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262988 // No idle sockets, and one connecting job.
2989 EXPECT_EQ(0, pool_->IdleSocketCount());
2990 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2991
2992 // Return the first handle to the pool. This will initiate the delayed
2993 // binding.
2994 handle1.Reset();
2995
[email protected]2da659e2013-05-23 20:51:342996 base::MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262997
2998 // Still no idle sockets, still one pending connect job.
2999 EXPECT_EQ(0, pool_->IdleSocketCount());
3000 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3001
3002 // The second socket connected, even though it was a Waiting Job.
3003 EXPECT_EQ(OK, callback.WaitForResult());
3004
3005 // And we can see there is still one job waiting.
3006 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3007
3008 // Finally, signal the waiting Connect.
3009 client_socket_factory_.SignalJobs();
3010 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3011
[email protected]2da659e2013-05-23 20:51:343012 base::MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:263013}
3014
[email protected]2abfe90a2010-08-25 17:49:513015// Cover the case where on an available socket slot, we have one pending
3016// request that completes synchronously, thereby making the Group empty.
3017TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
3018 const int kUnlimitedSockets = 100;
3019 const int kOneSocketPerGroup = 1;
3020 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
3021
3022 // Make the first request asynchronous fail.
3023 // This will free up a socket slot later.
3024 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
3025
3026 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523027 TestCompletionCallback callback1;
[email protected]2431756e2010-09-29 20:26:133028 EXPECT_EQ(ERR_IO_PENDING,
3029 handle1.Init("a",
3030 params_,
[email protected]bb1c4662013-11-14 00:00:073031 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523032 callback1.callback(),
[email protected]2431756e2010-09-29 20:26:133033 pool_.get(),
3034 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:513035 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3036
3037 // Make the second request synchronously fail. This should make the Group
3038 // empty.
3039 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3040 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523041 TestCompletionCallback callback2;
[email protected]2abfe90a2010-08-25 17:49:513042 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
3043 // when created.
[email protected]2431756e2010-09-29 20:26:133044 EXPECT_EQ(ERR_IO_PENDING,
3045 handle2.Init("a",
3046 params_,
[email protected]bb1c4662013-11-14 00:00:073047 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523048 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:133049 pool_.get(),
3050 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:513051
3052 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3053
3054 EXPECT_EQ(ERR_CONNECTION_FAILED, callback1.WaitForResult());
3055 EXPECT_EQ(ERR_CONNECTION_FAILED, callback2.WaitForResult());
3056 EXPECT_FALSE(pool_->HasGroup("a"));
3057}
3058
[email protected]e1b54dc2010-10-06 21:27:223059TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
3060 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3061
3062 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3063
3064 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523065 TestCompletionCallback callback1;
[email protected]e1b54dc2010-10-06 21:27:223066 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3067 params_,
[email protected]bb1c4662013-11-14 00:00:073068 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523069 callback1.callback(),
[email protected]e1b54dc2010-10-06 21:27:223070 pool_.get(),
3071 BoundNetLog()));
3072
3073 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523074 TestCompletionCallback callback2;
[email protected]e1b54dc2010-10-06 21:27:223075 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3076 params_,
[email protected]bb1c4662013-11-14 00:00:073077 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523078 callback2.callback(),
[email protected]e1b54dc2010-10-06 21:27:223079 pool_.get(),
3080 BoundNetLog()));
3081 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:523082 TestCompletionCallback callback3;
[email protected]e1b54dc2010-10-06 21:27:223083 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
3084 params_,
[email protected]bb1c4662013-11-14 00:00:073085 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523086 callback3.callback(),
[email protected]e1b54dc2010-10-06 21:27:223087 pool_.get(),
3088 BoundNetLog()));
3089
3090 EXPECT_EQ(OK, callback1.WaitForResult());
3091 EXPECT_EQ(OK, callback2.WaitForResult());
3092 EXPECT_EQ(OK, callback3.WaitForResult());
3093
3094 // Use the socket.
[email protected]83039bb2011-12-09 18:43:553095 EXPECT_EQ(1, handle1.socket()->Write(NULL, 1, CompletionCallback()));
3096 EXPECT_EQ(1, handle3.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]e1b54dc2010-10-06 21:27:223097
3098 handle1.Reset();
3099 handle2.Reset();
3100 handle3.Reset();
3101
3102 EXPECT_EQ(OK, handle1.Init("a",
3103 params_,
[email protected]bb1c4662013-11-14 00:00:073104 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523105 callback1.callback(),
[email protected]e1b54dc2010-10-06 21:27:223106 pool_.get(),
3107 BoundNetLog()));
3108 EXPECT_EQ(OK, handle2.Init("a",
3109 params_,
[email protected]bb1c4662013-11-14 00:00:073110 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523111 callback2.callback(),
[email protected]e1b54dc2010-10-06 21:27:223112 pool_.get(),
3113 BoundNetLog()));
3114 EXPECT_EQ(OK, handle3.Init("a",
3115 params_,
[email protected]bb1c4662013-11-14 00:00:073116 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523117 callback3.callback(),
[email protected]e1b54dc2010-10-06 21:27:223118 pool_.get(),
3119 BoundNetLog()));
3120
3121 EXPECT_TRUE(handle1.socket()->WasEverUsed());
3122 EXPECT_TRUE(handle2.socket()->WasEverUsed());
3123 EXPECT_FALSE(handle3.socket()->WasEverUsed());
3124}
3125
[email protected]2c2bef152010-10-13 00:55:033126TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
3127 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3128 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3129
3130 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3131
3132 ASSERT_TRUE(pool_->HasGroup("a"));
3133 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103134 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033135 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3136
3137 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523138 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033139 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3140 params_,
[email protected]bb1c4662013-11-14 00:00:073141 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523142 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033143 pool_.get(),
3144 BoundNetLog()));
3145
3146 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523147 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033148 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3149 params_,
[email protected]bb1c4662013-11-14 00:00:073150 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523151 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033152 pool_.get(),
3153 BoundNetLog()));
3154
3155 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103156 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033157 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3158
3159 EXPECT_EQ(OK, callback1.WaitForResult());
3160 EXPECT_EQ(OK, callback2.WaitForResult());
3161 handle1.Reset();
3162 handle2.Reset();
3163
3164 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103165 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033166 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3167}
3168
3169TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
3170 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3171 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3172
3173 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523174 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033175 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3176 params_,
[email protected]bb1c4662013-11-14 00:00:073177 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523178 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033179 pool_.get(),
3180 BoundNetLog()));
3181
3182 ASSERT_TRUE(pool_->HasGroup("a"));
3183 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103184 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033185 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3186
3187 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3188
3189 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103190 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033191 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3192
3193 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523194 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033195 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3196 params_,
[email protected]bb1c4662013-11-14 00:00:073197 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523198 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033199 pool_.get(),
3200 BoundNetLog()));
3201
3202 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103203 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033204 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3205
3206 EXPECT_EQ(OK, callback1.WaitForResult());
3207 EXPECT_EQ(OK, callback2.WaitForResult());
3208 handle1.Reset();
3209 handle2.Reset();
3210
3211 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103212 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033213 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3214}
3215
3216TEST_F(ClientSocketPoolBaseTest,
3217 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
3218 CreatePool(4, 4);
3219 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3220
3221 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523222 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033223 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3224 params_,
[email protected]bb1c4662013-11-14 00:00:073225 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523226 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033227 pool_.get(),
3228 BoundNetLog()));
3229
3230 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523231 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033232 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3233 params_,
[email protected]bb1c4662013-11-14 00:00:073234 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523235 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033236 pool_.get(),
3237 BoundNetLog()));
3238
3239 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:523240 TestCompletionCallback callback3;
[email protected]2c2bef152010-10-13 00:55:033241 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
3242 params_,
[email protected]bb1c4662013-11-14 00:00:073243 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523244 callback3.callback(),
[email protected]2c2bef152010-10-13 00:55:033245 pool_.get(),
3246 BoundNetLog()));
3247
3248 ASSERT_TRUE(pool_->HasGroup("a"));
3249 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103250 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033251 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3252
3253 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3254
3255 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103256 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033257 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3258
3259 EXPECT_EQ(OK, callback1.WaitForResult());
3260 EXPECT_EQ(OK, callback2.WaitForResult());
3261 EXPECT_EQ(OK, callback3.WaitForResult());
3262 handle1.Reset();
3263 handle2.Reset();
3264 handle3.Reset();
3265
3266 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103267 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033268 EXPECT_EQ(3, pool_->IdleSocketCountInGroup("a"));
3269}
3270
3271TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
3272 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3273 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3274
3275 ASSERT_FALSE(pool_->HasGroup("a"));
3276
3277 pool_->RequestSockets("a", &params_, kDefaultMaxSockets,
3278 BoundNetLog());
3279
3280 ASSERT_TRUE(pool_->HasGroup("a"));
3281 EXPECT_EQ(kDefaultMaxSockets, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103282 EXPECT_EQ(kDefaultMaxSockets, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033283
3284 ASSERT_FALSE(pool_->HasGroup("b"));
3285
3286 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
3287 BoundNetLog());
3288
3289 ASSERT_FALSE(pool_->HasGroup("b"));
3290}
3291
3292TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
3293 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3294 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3295
3296 ASSERT_FALSE(pool_->HasGroup("a"));
3297
3298 pool_->RequestSockets("a", &params_, kDefaultMaxSockets - 1,
3299 BoundNetLog());
3300
3301 ASSERT_TRUE(pool_->HasGroup("a"));
3302 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103303 EXPECT_EQ(kDefaultMaxSockets - 1,
3304 pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]51fdc7c2012-04-10 19:19:483305 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033306
3307 ASSERT_FALSE(pool_->HasGroup("b"));
3308
3309 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
3310 BoundNetLog());
3311
3312 ASSERT_TRUE(pool_->HasGroup("b"));
3313 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("b"));
[email protected]51fdc7c2012-04-10 19:19:483314 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033315}
3316
3317TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
3318 CreatePool(4, 4);
3319 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3320
3321 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523322 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033323 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3324 params_,
[email protected]bb1c4662013-11-14 00:00:073325 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523326 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033327 pool_.get(),
3328 BoundNetLog()));
3329 ASSERT_EQ(OK, callback1.WaitForResult());
3330 handle1.Reset();
3331
3332 ASSERT_TRUE(pool_->HasGroup("a"));
3333 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103334 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033335 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3336
3337 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3338
3339 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103340 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033341 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3342}
3343
3344TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
3345 CreatePool(4, 4);
3346 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3347
3348 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523349 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033350 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3351 params_,
[email protected]bb1c4662013-11-14 00:00:073352 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523353 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033354 pool_.get(),
3355 BoundNetLog()));
3356 ASSERT_EQ(OK, callback1.WaitForResult());
3357
3358 ASSERT_TRUE(pool_->HasGroup("a"));
3359 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103360 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033361 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3362 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3363
3364 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3365
3366 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103367 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033368 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3369 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3370}
3371
3372TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
3373 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3374 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3375
3376 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3377 BoundNetLog());
3378
3379 ASSERT_TRUE(pool_->HasGroup("a"));
3380 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103381 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033382 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("a"));
3383
3384 pool_->RequestSockets("b", &params_, kDefaultMaxSocketsPerGroup,
3385 BoundNetLog());
3386
3387 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103388 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]2c2bef152010-10-13 00:55:033389 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("b"));
3390}
3391
[email protected]3c819f522010-12-02 02:03:123392TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
3393 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3394 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3395
3396 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3397 BoundNetLog());
3398
3399 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]fd2e53e2011-01-14 20:40:523400
3401 connect_job_factory_->set_job_type(
3402 TestConnectJob::kMockAdditionalErrorStateJob);
3403 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3404 BoundNetLog());
3405
3406 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]3c819f522010-12-02 02:03:123407}
3408
[email protected]8159a1c2012-06-07 00:00:103409TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
[email protected]2c2bef152010-10-13 00:55:033410 CreatePool(4, 4);
3411 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3412
3413 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3414
3415 ASSERT_TRUE(pool_->HasGroup("a"));
3416 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103417 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033418 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3419
3420 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3421 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103422 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033423 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3424
3425 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523426 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033427 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3428 params_,
[email protected]bb1c4662013-11-14 00:00:073429 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523430 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033431 pool_.get(),
3432 BoundNetLog()));
3433 ASSERT_EQ(OK, callback1.WaitForResult());
3434
3435 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523436 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033437 int rv = handle2.Init("a",
3438 params_,
[email protected]bb1c4662013-11-14 00:00:073439 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523440 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033441 pool_.get(),
3442 BoundNetLog());
3443 if (rv != OK) {
3444 EXPECT_EQ(ERR_IO_PENDING, rv);
3445 EXPECT_EQ(OK, callback2.WaitForResult());
3446 }
3447
[email protected]8159a1c2012-06-07 00:00:103448 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3449 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3450 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("a"));
3451 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3452
[email protected]2c2bef152010-10-13 00:55:033453 handle1.Reset();
3454 handle2.Reset();
3455
[email protected]8159a1c2012-06-07 00:00:103456 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3457 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033458 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3459
3460 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3461 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103462 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033463 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3464}
3465
3466TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
3467 CreatePool(4, 4);
3468 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3469
3470 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3471
3472 ASSERT_TRUE(pool_->HasGroup("a"));
3473 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103474 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033475 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3476
3477 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3478 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103479 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033480 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3481
3482 pool_->RequestSockets("a", &params_, 3, BoundNetLog());
3483 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103484 EXPECT_EQ(3, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033485 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3486
3487 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3488 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103489 EXPECT_EQ(3, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033490 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3491}
3492
3493TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
3494 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3495 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3496
3497 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3498
3499 ASSERT_TRUE(pool_->HasGroup("a"));
3500 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103501 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033502 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3503
3504 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523505 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033506 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3507 params_,
[email protected]bb1c4662013-11-14 00:00:073508 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523509 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033510 pool_.get(),
3511 BoundNetLog()));
3512
3513 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103514 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033515 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3516
3517 ASSERT_EQ(OK, callback1.WaitForResult());
3518
[email protected]0dc88b32014-03-26 20:12:283519 // Make sure if a preconnected socket is not fully connected when a request
[email protected]034df0f32013-01-07 23:17:483520 // starts, it has a connect start time.
3521 TestLoadTimingInfoConnectedNotReused(handle1);
[email protected]2c2bef152010-10-13 00:55:033522 handle1.Reset();
3523
3524 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3525}
3526
[email protected]034df0f32013-01-07 23:17:483527// Checks that fully connected preconnect jobs have no connect times, and are
3528// marked as reused.
3529TEST_F(ClientSocketPoolBaseTest, ConnectedPreconnectJobsHaveNoConnectTimes) {
3530 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3531 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3532 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3533
3534 ASSERT_TRUE(pool_->HasGroup("a"));
3535 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3536 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3537 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3538
3539 ClientSocketHandle handle;
3540 TestCompletionCallback callback;
3541 EXPECT_EQ(OK, handle.Init("a",
3542 params_,
[email protected]bb1c4662013-11-14 00:00:073543 DEFAULT_PRIORITY,
[email protected]034df0f32013-01-07 23:17:483544 callback.callback(),
3545 pool_.get(),
3546 BoundNetLog()));
3547
3548 // Make sure the idle socket was used.
3549 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3550
3551 TestLoadTimingInfoConnectedReused(handle);
3552 handle.Reset();
3553 TestLoadTimingInfoNotConnected(handle);
3554}
3555
[email protected]dcbe168a2010-12-02 03:14:463556// http://crbug.com/64940 regression test.
3557TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
3558 const int kMaxTotalSockets = 3;
3559 const int kMaxSocketsPerGroup = 2;
3560 CreatePool(kMaxTotalSockets, kMaxSocketsPerGroup);
3561 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3562
3563 // Note that group name ordering matters here. "a" comes before "b", so
3564 // CloseOneIdleSocket() will try to close "a"'s idle socket.
3565
3566 // Set up one idle socket in "a".
3567 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523568 TestCompletionCallback callback1;
[email protected]dcbe168a2010-12-02 03:14:463569 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3570 params_,
[email protected]bb1c4662013-11-14 00:00:073571 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523572 callback1.callback(),
[email protected]dcbe168a2010-12-02 03:14:463573 pool_.get(),
3574 BoundNetLog()));
3575
3576 ASSERT_EQ(OK, callback1.WaitForResult());
3577 handle1.Reset();
3578 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3579
3580 // Set up two active sockets in "b".
3581 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523582 TestCompletionCallback callback2;
[email protected]dcbe168a2010-12-02 03:14:463583 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("b",
3584 params_,
[email protected]bb1c4662013-11-14 00:00:073585 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523586 callback1.callback(),
[email protected]dcbe168a2010-12-02 03:14:463587 pool_.get(),
3588 BoundNetLog()));
3589 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("b",
3590 params_,
[email protected]bb1c4662013-11-14 00:00:073591 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523592 callback2.callback(),
[email protected]dcbe168a2010-12-02 03:14:463593 pool_.get(),
3594 BoundNetLog()));
3595
3596 ASSERT_EQ(OK, callback1.WaitForResult());
3597 ASSERT_EQ(OK, callback2.WaitForResult());
3598 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103599 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463600 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3601
3602 // Now we have 1 idle socket in "a" and 2 active sockets in "b". This means
3603 // we've maxed out on sockets, since we set |kMaxTotalSockets| to 3.
3604 // Requesting 2 preconnected sockets for "a" should fail to allocate any more
3605 // sockets for "a", and "b" should still have 2 active sockets.
3606
3607 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3608 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103609 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]dcbe168a2010-12-02 03:14:463610 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3611 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3612 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103613 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463614 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3615 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3616
3617 // Now release the 2 active sockets for "b". This will give us 1 idle socket
3618 // in "a" and 2 idle sockets in "b". Requesting 2 preconnected sockets for
3619 // "a" should result in closing 1 for "b".
3620 handle1.Reset();
3621 handle2.Reset();
3622 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("b"));
3623 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3624
3625 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3626 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103627 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]dcbe168a2010-12-02 03:14:463628 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3629 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3630 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103631 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463632 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("b"));
3633 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3634}
3635
[email protected]b7b8be42011-07-12 12:46:413636TEST_F(ClientSocketPoolBaseTest, PreconnectWithoutBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073637 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3638 pool_->EnableConnectBackupJobs();
3639
3640 // Make the ConnectJob hang until it times out, shorten the timeout.
3641 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3642 connect_job_factory_->set_timeout_duration(
3643 base::TimeDelta::FromMilliseconds(500));
3644 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3645 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103646 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073647 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073648
[email protected]b7b8be42011-07-12 12:46:413649 // Verify the backup timer doesn't create a backup job, by making
3650 // the backup job a pending job instead of a waiting job, so it
3651 // *would* complete if it were created.
[email protected]a9fc8fc2011-05-10 02:41:073652 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
skyostil4891b25b2015-06-11 11:43:453653 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
3654 FROM_HERE, base::MessageLoop::QuitClosure(),
[email protected]2da659e2013-05-23 20:51:343655 base::TimeDelta::FromSeconds(1));
3656 base::MessageLoop::current()->Run();
[email protected]a9fc8fc2011-05-10 02:41:073657 EXPECT_FALSE(pool_->HasGroup("a"));
3658}
3659
[email protected]b7b8be42011-07-12 12:46:413660TEST_F(ClientSocketPoolBaseTest, PreconnectWithBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073661 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3662 pool_->EnableConnectBackupJobs();
3663
3664 // Make the ConnectJob hang forever.
3665 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3666 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3667 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103668 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073669 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]2da659e2013-05-23 20:51:343670 base::MessageLoop::current()->RunUntilIdle();
[email protected]a9fc8fc2011-05-10 02:41:073671
3672 // Make the backup job be a pending job, so it completes normally.
3673 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3674 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:523675 TestCompletionCallback callback;
[email protected]a9fc8fc2011-05-10 02:41:073676 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
3677 params_,
[email protected]bb1c4662013-11-14 00:00:073678 DEFAULT_PRIORITY,
[email protected]6ecf2b92011-12-15 01:14:523679 callback.callback(),
[email protected]a9fc8fc2011-05-10 02:41:073680 pool_.get(),
3681 BoundNetLog()));
[email protected]b7b8be42011-07-12 12:46:413682 // Timer has started, but the backup connect job shouldn't be created yet.
[email protected]a9fc8fc2011-05-10 02:41:073683 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103684 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073685 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3686 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3687 ASSERT_EQ(OK, callback.WaitForResult());
3688
3689 // The hung connect job should still be there, but everything else should be
3690 // complete.
3691 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103692 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073693 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3694 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3695}
3696
[email protected]0dc88b32014-03-26 20:12:283697// Tests that a preconnect that starts out with unread data can still be used.
3698// http://crbug.com/334467
3699TEST_F(ClientSocketPoolBaseTest, PreconnectWithUnreadData) {
3700 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3701 connect_job_factory_->set_job_type(TestConnectJob::kMockUnreadDataJob);
3702
3703 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3704
3705 ASSERT_TRUE(pool_->HasGroup("a"));
3706 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3707 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3708 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3709
3710 // Fail future jobs to be sure that handle receives the preconnected socket
3711 // rather than closing it and making a new one.
3712 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3713 ClientSocketHandle handle;
3714 TestCompletionCallback callback;
3715 EXPECT_EQ(OK, handle.Init("a",
3716 params_,
3717 DEFAULT_PRIORITY,
3718 callback.callback(),
3719 pool_.get(),
3720 BoundNetLog()));
3721
3722 ASSERT_TRUE(pool_->HasGroup("a"));
3723 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3724 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3725 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3726
3727 // Drain the pending read.
3728 EXPECT_EQ(1, handle.socket()->Read(NULL, 1, CompletionCallback()));
3729
3730 TestLoadTimingInfoConnectedReused(handle);
3731 handle.Reset();
3732
3733 // The socket should be usable now that it's idle again.
3734 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3735}
3736
[email protected]043b68c82013-08-22 23:41:523737class MockLayeredPool : public HigherLayeredPool {
[email protected]58e562f2013-04-22 17:32:203738 public:
3739 MockLayeredPool(TestClientSocketPool* pool,
3740 const std::string& group_name)
3741 : pool_(pool),
[email protected]58e562f2013-04-22 17:32:203742 group_name_(group_name),
3743 can_release_connection_(true) {
[email protected]043b68c82013-08-22 23:41:523744 pool_->AddHigherLayeredPool(this);
[email protected]58e562f2013-04-22 17:32:203745 }
3746
3747 ~MockLayeredPool() {
[email protected]043b68c82013-08-22 23:41:523748 pool_->RemoveHigherLayeredPool(this);
[email protected]58e562f2013-04-22 17:32:203749 }
3750
3751 int RequestSocket(TestClientSocketPool* pool) {
[email protected]bb1c4662013-11-14 00:00:073752 scoped_refptr<TestSocketParams> params(
3753 new TestSocketParams(false /* ignore_limits */));
3754 return handle_.Init(group_name_, params, DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203755 callback_.callback(), pool, BoundNetLog());
3756 }
3757
3758 int RequestSocketWithoutLimits(TestClientSocketPool* pool) {
[email protected]bb1c4662013-11-14 00:00:073759 scoped_refptr<TestSocketParams> params(
3760 new TestSocketParams(true /* ignore_limits */));
3761 return handle_.Init(group_name_, params, MAXIMUM_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203762 callback_.callback(), pool, BoundNetLog());
3763 }
3764
3765 bool ReleaseOneConnection() {
3766 if (!handle_.is_initialized() || !can_release_connection_) {
3767 return false;
3768 }
3769 handle_.socket()->Disconnect();
3770 handle_.Reset();
3771 return true;
3772 }
3773
3774 void set_can_release_connection(bool can_release_connection) {
3775 can_release_connection_ = can_release_connection;
3776 }
3777
3778 MOCK_METHOD0(CloseOneIdleConnection, bool());
3779
3780 private:
3781 TestClientSocketPool* const pool_;
[email protected]58e562f2013-04-22 17:32:203782 ClientSocketHandle handle_;
3783 TestCompletionCallback callback_;
3784 const std::string group_name_;
3785 bool can_release_connection_;
3786};
3787
3788TEST_F(ClientSocketPoolBaseTest, FailToCloseIdleSocketsNotHeldByLayeredPool) {
3789 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3790 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3791
3792 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
3793 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3794 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3795 .WillOnce(Return(false));
[email protected]043b68c82013-08-22 23:41:523796 EXPECT_FALSE(pool_->CloseOneIdleConnectionInHigherLayeredPool());
[email protected]58e562f2013-04-22 17:32:203797}
3798
3799TEST_F(ClientSocketPoolBaseTest, ForciblyCloseIdleSocketsHeldByLayeredPool) {
3800 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3801 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3802
3803 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
3804 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3805 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3806 .WillOnce(Invoke(&mock_layered_pool,
3807 &MockLayeredPool::ReleaseOneConnection));
[email protected]043b68c82013-08-22 23:41:523808 EXPECT_TRUE(pool_->CloseOneIdleConnectionInHigherLayeredPool());
[email protected]58e562f2013-04-22 17:32:203809}
3810
3811// Tests the basic case of closing an idle socket in a higher layered pool when
3812// a new request is issued and the lower layer pool is stalled.
3813TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsHeldByLayeredPoolWhenNeeded) {
3814 CreatePool(1, 1);
3815 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3816
3817 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
3818 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3819 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3820 .WillOnce(Invoke(&mock_layered_pool,
3821 &MockLayeredPool::ReleaseOneConnection));
3822 ClientSocketHandle handle;
3823 TestCompletionCallback callback;
3824 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
3825 params_,
[email protected]bb1c4662013-11-14 00:00:073826 DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203827 callback.callback(),
3828 pool_.get(),
3829 BoundNetLog()));
3830 EXPECT_EQ(OK, callback.WaitForResult());
3831}
3832
3833// Same as above, but the idle socket is in the same group as the stalled
3834// socket, and closes the only other request in its group when closing requests
3835// in higher layered pools. This generally shouldn't happen, but it may be
3836// possible if a higher level pool issues a request and the request is
3837// subsequently cancelled. Even if it's not possible, best not to crash.
3838TEST_F(ClientSocketPoolBaseTest,
3839 CloseIdleSocketsHeldByLayeredPoolWhenNeededSameGroup) {
3840 CreatePool(2, 2);
3841 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3842
3843 // Need a socket in another group for the pool to be stalled (If a group
3844 // has the maximum number of connections already, it's not stalled).
3845 ClientSocketHandle handle1;
3846 TestCompletionCallback callback1;
3847 EXPECT_EQ(OK, handle1.Init("group1",
3848 params_,
[email protected]bb1c4662013-11-14 00:00:073849 DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203850 callback1.callback(),
3851 pool_.get(),
3852 BoundNetLog()));
3853
3854 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
3855 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3856 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3857 .WillOnce(Invoke(&mock_layered_pool,
3858 &MockLayeredPool::ReleaseOneConnection));
3859 ClientSocketHandle handle;
3860 TestCompletionCallback callback2;
3861 EXPECT_EQ(ERR_IO_PENDING, handle.Init("group2",
3862 params_,
[email protected]bb1c4662013-11-14 00:00:073863 DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203864 callback2.callback(),
3865 pool_.get(),
3866 BoundNetLog()));
3867 EXPECT_EQ(OK, callback2.WaitForResult());
3868}
3869
3870// Tests the case when an idle socket can be closed when a new request is
3871// issued, and the new request belongs to a group that was previously stalled.
3872TEST_F(ClientSocketPoolBaseTest,
3873 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded) {
3874 CreatePool(2, 2);
3875 std::list<TestConnectJob::JobType> job_types;
3876 job_types.push_back(TestConnectJob::kMockJob);
3877 job_types.push_back(TestConnectJob::kMockJob);
3878 job_types.push_back(TestConnectJob::kMockJob);
3879 job_types.push_back(TestConnectJob::kMockJob);
3880 connect_job_factory_->set_job_types(&job_types);
3881
3882 ClientSocketHandle handle1;
3883 TestCompletionCallback callback1;
3884 EXPECT_EQ(OK, handle1.Init("group1",
3885 params_,
[email protected]bb1c4662013-11-14 00:00:073886 DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203887 callback1.callback(),
3888 pool_.get(),
3889 BoundNetLog()));
3890
3891 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
3892 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3893 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3894 .WillRepeatedly(Invoke(&mock_layered_pool,
3895 &MockLayeredPool::ReleaseOneConnection));
3896 mock_layered_pool.set_can_release_connection(false);
3897
3898 // The third request is made when the socket pool is in a stalled state.
3899 ClientSocketHandle handle3;
3900 TestCompletionCallback callback3;
3901 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("group3",
3902 params_,
[email protected]bb1c4662013-11-14 00:00:073903 DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203904 callback3.callback(),
3905 pool_.get(),
3906 BoundNetLog()));
3907
3908 base::RunLoop().RunUntilIdle();
3909 EXPECT_FALSE(callback3.have_result());
3910
3911 // The fourth request is made when the pool is no longer stalled. The third
3912 // request should be serviced first, since it was issued first and has the
3913 // same priority.
3914 mock_layered_pool.set_can_release_connection(true);
3915 ClientSocketHandle handle4;
3916 TestCompletionCallback callback4;
3917 EXPECT_EQ(ERR_IO_PENDING, handle4.Init("group3",
3918 params_,
[email protected]bb1c4662013-11-14 00:00:073919 DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203920 callback4.callback(),
3921 pool_.get(),
3922 BoundNetLog()));
3923 EXPECT_EQ(OK, callback3.WaitForResult());
3924 EXPECT_FALSE(callback4.have_result());
3925
3926 // Closing a handle should free up another socket slot.
3927 handle1.Reset();
3928 EXPECT_EQ(OK, callback4.WaitForResult());
3929}
3930
3931// Tests the case when an idle socket can be closed when a new request is
3932// issued, and the new request belongs to a group that was previously stalled.
3933//
3934// The two differences from the above test are that the stalled requests are not
3935// in the same group as the layered pool's request, and the the fourth request
3936// has a higher priority than the third one, so gets a socket first.
3937TEST_F(ClientSocketPoolBaseTest,
3938 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded2) {
3939 CreatePool(2, 2);
3940 std::list<TestConnectJob::JobType> job_types;
3941 job_types.push_back(TestConnectJob::kMockJob);
3942 job_types.push_back(TestConnectJob::kMockJob);
3943 job_types.push_back(TestConnectJob::kMockJob);
3944 job_types.push_back(TestConnectJob::kMockJob);
3945 connect_job_factory_->set_job_types(&job_types);
3946
3947 ClientSocketHandle handle1;
3948 TestCompletionCallback callback1;
3949 EXPECT_EQ(OK, handle1.Init("group1",
3950 params_,
[email protected]bb1c4662013-11-14 00:00:073951 DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:203952 callback1.callback(),
3953 pool_.get(),
3954 BoundNetLog()));
3955
3956 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
3957 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3958 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3959 .WillRepeatedly(Invoke(&mock_layered_pool,
3960 &MockLayeredPool::ReleaseOneConnection));
3961 mock_layered_pool.set_can_release_connection(false);
3962
3963 // The third request is made when the socket pool is in a stalled state.
3964 ClientSocketHandle handle3;
3965 TestCompletionCallback callback3;
3966 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("group3",
3967 params_,
3968 MEDIUM,
3969 callback3.callback(),
3970 pool_.get(),
3971 BoundNetLog()));
3972
3973 base::RunLoop().RunUntilIdle();
3974 EXPECT_FALSE(callback3.have_result());
3975
3976 // The fourth request is made when the pool is no longer stalled. This
3977 // request has a higher priority than the third request, so is serviced first.
3978 mock_layered_pool.set_can_release_connection(true);
3979 ClientSocketHandle handle4;
3980 TestCompletionCallback callback4;
3981 EXPECT_EQ(ERR_IO_PENDING, handle4.Init("group3",
3982 params_,
3983 HIGHEST,
3984 callback4.callback(),
3985 pool_.get(),
3986 BoundNetLog()));
3987 EXPECT_EQ(OK, callback4.WaitForResult());
3988 EXPECT_FALSE(callback3.have_result());
3989
3990 // Closing a handle should free up another socket slot.
3991 handle1.Reset();
3992 EXPECT_EQ(OK, callback3.WaitForResult());
3993}
3994
3995TEST_F(ClientSocketPoolBaseTest,
3996 CloseMultipleIdleSocketsHeldByLayeredPoolWhenNeeded) {
3997 CreatePool(1, 1);
3998 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3999
4000 MockLayeredPool mock_layered_pool1(pool_.get(), "foo");
4001 EXPECT_EQ(OK, mock_layered_pool1.RequestSocket(pool_.get()));
4002 EXPECT_CALL(mock_layered_pool1, CloseOneIdleConnection())
4003 .WillRepeatedly(Invoke(&mock_layered_pool1,
4004 &MockLayeredPool::ReleaseOneConnection));
4005 MockLayeredPool mock_layered_pool2(pool_.get(), "bar");
4006 EXPECT_EQ(OK, mock_layered_pool2.RequestSocketWithoutLimits(pool_.get()));
4007 EXPECT_CALL(mock_layered_pool2, CloseOneIdleConnection())
4008 .WillRepeatedly(Invoke(&mock_layered_pool2,
4009 &MockLayeredPool::ReleaseOneConnection));
4010 ClientSocketHandle handle;
4011 TestCompletionCallback callback;
4012 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
4013 params_,
[email protected]bb1c4662013-11-14 00:00:074014 DEFAULT_PRIORITY,
[email protected]58e562f2013-04-22 17:32:204015 callback.callback(),
4016 pool_.get(),
4017 BoundNetLog()));
4018 EXPECT_EQ(OK, callback.WaitForResult());
4019}
4020
[email protected]b021ece62013-06-11 11:06:334021// Test that when a socket pool and group are at their limits, a request
4022// with |ignore_limits| triggers creation of a new socket, and gets the socket
4023// instead of a request with the same priority that was issued earlier, but
4024// that does not have |ignore_limits| set.
4025TEST_F(ClientSocketPoolBaseTest, IgnoreLimits) {
[email protected]bb1c4662013-11-14 00:00:074026 scoped_refptr<TestSocketParams> params_ignore_limits(
4027 new TestSocketParams(true /* ignore_limits */));
[email protected]b021ece62013-06-11 11:06:334028 CreatePool(1, 1);
4029
4030 // Issue a request to reach the socket pool limit.
[email protected]bb1c4662013-11-14 00:00:074031 EXPECT_EQ(OK, StartRequestWithParams("a", MAXIMUM_PRIORITY, params_));
[email protected]b021ece62013-06-11 11:06:334032 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4033
4034 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4035
[email protected]bb1c4662013-11-14 00:00:074036 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithParams("a", MAXIMUM_PRIORITY,
[email protected]b021ece62013-06-11 11:06:334037 params_));
4038 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4039
[email protected]bb1c4662013-11-14 00:00:074040 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithParams("a", MAXIMUM_PRIORITY,
[email protected]b021ece62013-06-11 11:06:334041 params_ignore_limits));
4042 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4043
4044 EXPECT_EQ(OK, request(2)->WaitForResult());
4045 EXPECT_FALSE(request(1)->have_result());
4046}
4047
[email protected]c55fabd2013-11-04 23:26:564048// Test that when a socket pool and group are at their limits, a ConnectJob
4049// issued for a request with |ignore_limits| set is not cancelled when a request
4050// without |ignore_limits| issued to the same group is cancelled.
4051TEST_F(ClientSocketPoolBaseTest, IgnoreLimitsCancelOtherJob) {
[email protected]bb1c4662013-11-14 00:00:074052 scoped_refptr<TestSocketParams> params_ignore_limits(
4053 new TestSocketParams(true /* ignore_limits */));
[email protected]c55fabd2013-11-04 23:26:564054 CreatePool(1, 1);
4055
4056 // Issue a request to reach the socket pool limit.
[email protected]bb1c4662013-11-14 00:00:074057 EXPECT_EQ(OK, StartRequestWithParams("a", MAXIMUM_PRIORITY, params_));
[email protected]c55fabd2013-11-04 23:26:564058 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4059
4060 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4061
[email protected]bb1c4662013-11-14 00:00:074062 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithParams("a", MAXIMUM_PRIORITY,
4063 params_));
[email protected]c55fabd2013-11-04 23:26:564064 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
4065
[email protected]bb1c4662013-11-14 00:00:074066 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithParams("a", MAXIMUM_PRIORITY,
[email protected]b021ece62013-06-11 11:06:334067 params_ignore_limits));
4068 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4069
4070 // Cancel the pending request without ignore_limits set. The ConnectJob
4071 // should not be cancelled.
4072 request(1)->handle()->Reset();
4073 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4074
4075 EXPECT_EQ(OK, request(2)->WaitForResult());
4076 EXPECT_FALSE(request(1)->have_result());
4077}
4078
[email protected]f6d1d6eb2009-06-24 20:16:094079} // namespace
4080
4081} // namespace net