blob: 12b7b06b3c64b9b462f70daddd6a8abefb2085ae [file] [log] [blame]
David Ghandehari9e5b5872016-07-28 09:50:04 -07001// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/socket/client_socket_pool_base.h"
6
Andrew Top0d1858f2019-05-15 22:01:47 -07007#include <utility>
David Ghandehari9e5b5872016-07-28 09:50:04 -07008#include <vector>
9
10#include "base/bind.h"
11#include "base/bind_helpers.h"
12#include "base/callback.h"
Andrew Top0d1858f2019-05-15 22:01:47 -070013#include "base/location.h"
14#include "base/logging.h"
15#include "base/macros.h"
David Ghandehari9e5b5872016-07-28 09:50:04 -070016#include "base/memory/ref_counted.h"
David Ghandehari9e5b5872016-07-28 09:50:04 -070017#include "base/memory/weak_ptr.h"
Andrew Top0d1858f2019-05-15 22:01:47 -070018#include "base/message_loop/message_loop.h"
19#include "base/run_loop.h"
20#include "base/single_thread_task_runner.h"
21#include "base/strings/string_number_conversions.h"
22#include "base/strings/stringprintf.h"
David Ghandehari9e5b5872016-07-28 09:50:04 -070023#include "base/threading/platform_thread.h"
Andrew Top0d1858f2019-05-15 22:01:47 -070024#include "base/threading/thread_task_runner_handle.h"
David Ghandehari9e5b5872016-07-28 09:50:04 -070025#include "base/values.h"
Andrew Top0d1858f2019-05-15 22:01:47 -070026#include "net/base/load_timing_info.h"
27#include "net/base/load_timing_info_test_util.h"
David Ghandehari9e5b5872016-07-28 09:50:04 -070028#include "net/base/net_errors.h"
David Ghandehari9e5b5872016-07-28 09:50:04 -070029#include "net/base/request_priority.h"
30#include "net/base/test_completion_callback.h"
31#include "net/http/http_response_headers.h"
Andrew Top0d1858f2019-05-15 22:01:47 -070032#include "net/log/net_log.h"
33#include "net/log/net_log_event_type.h"
34#include "net/log/net_log_source.h"
35#include "net/log/net_log_source_type.h"
36#include "net/log/test_net_log.h"
37#include "net/log/test_net_log_entry.h"
38#include "net/log/test_net_log_util.h"
David Ghandehari9e5b5872016-07-28 09:50:04 -070039#include "net/socket/client_socket_factory.h"
40#include "net/socket/client_socket_handle.h"
Andrew Top0d1858f2019-05-15 22:01:47 -070041#include "net/socket/datagram_client_socket.h"
42#include "net/socket/socket_performance_watcher.h"
43#include "net/socket/socket_tag.h"
David Ghandehari9e5b5872016-07-28 09:50:04 -070044#include "net/socket/socket_test_util.h"
Andrew Top0d1858f2019-05-15 22:01:47 -070045#include "net/socket/ssl_client_socket.h"
David Ghandehari9e5b5872016-07-28 09:50:04 -070046#include "net/socket/stream_socket.h"
Andrew Top0d1858f2019-05-15 22:01:47 -070047#include "net/test/gtest_util.h"
48#include "net/test/test_with_scoped_task_environment.h"
49#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
50#include "starboard/types.h"
David Ghandehari9e5b5872016-07-28 09:50:04 -070051#include "testing/gmock/include/gmock/gmock.h"
52#include "testing/gtest/include/gtest/gtest.h"
53
Andrew Top0d1858f2019-05-15 22:01:47 -070054using net::test::IsError;
55using net::test::IsOk;
56
David Ghandehari9e5b5872016-07-28 09:50:04 -070057using ::testing::Invoke;
58using ::testing::Return;
59
60namespace net {
61
62namespace {
63
64const int kDefaultMaxSockets = 4;
65const int kDefaultMaxSocketsPerGroup = 2;
Andrew Top0d1858f2019-05-15 22:01:47 -070066
67// Make sure |handle| sets load times correctly when it has been assigned a
68// reused socket.
69void TestLoadTimingInfoConnectedReused(const ClientSocketHandle& handle) {
70 LoadTimingInfo load_timing_info;
71 // Only pass true in as |is_reused|, as in general, HttpStream types should
72 // have stricter concepts of reuse than socket pools.
73 EXPECT_TRUE(handle.GetLoadTimingInfo(true, &load_timing_info));
74
75 EXPECT_EQ(true, load_timing_info.socket_reused);
76 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
77
78 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
79 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
80}
81
82// Make sure |handle| sets load times correctly when it has been assigned a
83// fresh socket. Also runs TestLoadTimingInfoConnectedReused, since the owner
84// of a connection where |is_reused| is false may consider the connection
85// reused.
86void TestLoadTimingInfoConnectedNotReused(const ClientSocketHandle& handle) {
87 EXPECT_FALSE(handle.is_reused());
88
89 LoadTimingInfo load_timing_info;
90 EXPECT_TRUE(handle.GetLoadTimingInfo(false, &load_timing_info));
91
92 EXPECT_FALSE(load_timing_info.socket_reused);
93 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
94
95 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
96 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
97 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
98
99 TestLoadTimingInfoConnectedReused(handle);
100}
101
102// Make sure |handle| sets load times correctly, in the case that it does not
103// currently have a socket.
104void TestLoadTimingInfoNotConnected(const ClientSocketHandle& handle) {
105 // Should only be set to true once a socket is assigned, if at all.
106 EXPECT_FALSE(handle.is_reused());
107
108 LoadTimingInfo load_timing_info;
109 EXPECT_FALSE(handle.GetLoadTimingInfo(false, &load_timing_info));
110
111 EXPECT_FALSE(load_timing_info.socket_reused);
112 EXPECT_EQ(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
113
114 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
115 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
116}
David Ghandehari9e5b5872016-07-28 09:50:04 -0700117
118class TestSocketParams : public base::RefCounted<TestSocketParams> {
119 public:
Andrew Top0d1858f2019-05-15 22:01:47 -0700120 explicit TestSocketParams() = default;
David Ghandehari9e5b5872016-07-28 09:50:04 -0700121
122 private:
123 friend class base::RefCounted<TestSocketParams>;
Andrew Top0d1858f2019-05-15 22:01:47 -0700124 ~TestSocketParams() = default;
David Ghandehari9e5b5872016-07-28 09:50:04 -0700125};
126typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
127
128class MockClientSocket : public StreamSocket {
129 public:
Andrew Top0d1858f2019-05-15 22:01:47 -0700130 explicit MockClientSocket(net::NetLog* net_log)
131 : connected_(false),
132 has_unread_data_(false),
133 net_log_(NetLogWithSource::Make(net_log, NetLogSourceType::SOCKET)),
134 was_used_to_convey_data_(false) {}
David Ghandehari9e5b5872016-07-28 09:50:04 -0700135
Andrew Top0d1858f2019-05-15 22:01:47 -0700136 // Sets whether the socket has unread data. If true, the next call to Read()
137 // will return 1 byte and IsConnectedAndIdle() will return false.
138 void set_has_unread_data(bool has_unread_data) {
139 has_unread_data_ = has_unread_data;
David Ghandehari9e5b5872016-07-28 09:50:04 -0700140 }
141
Andrew Top0d1858f2019-05-15 22:01:47 -0700142 // Socket implementation.
143 int Read(IOBuffer* /* buf */,
144 int len,
145 CompletionOnceCallback /* callback */) override {
146 if (has_unread_data_ && len > 0) {
147 has_unread_data_ = false;
148 was_used_to_convey_data_ = true;
149 return 1;
150 }
151 return ERR_UNEXPECTED;
152 }
153
154 int Write(
155 IOBuffer* /* buf */,
156 int len,
157 CompletionOnceCallback /* callback */,
158 const NetworkTrafficAnnotationTag& /*traffic_annotation*/) override {
David Ghandehari9e5b5872016-07-28 09:50:04 -0700159 was_used_to_convey_data_ = true;
160 return len;
161 }
Andrew Top0d1858f2019-05-15 22:01:47 -0700162 int SetReceiveBufferSize(int32_t size) override { return OK; }
163 int SetSendBufferSize(int32_t size) override { return OK; }
David Ghandehari9e5b5872016-07-28 09:50:04 -0700164
165 // StreamSocket implementation.
Andrew Top0d1858f2019-05-15 22:01:47 -0700166 int Connect(CompletionOnceCallback callback) override {
David Ghandehari9e5b5872016-07-28 09:50:04 -0700167 connected_ = true;
168 return OK;
169 }
170
Andrew Top0d1858f2019-05-15 22:01:47 -0700171 void Disconnect() override { connected_ = false; }
172 bool IsConnected() const override { return connected_; }
173 bool IsConnectedAndIdle() const override {
174 return connected_ && !has_unread_data_;
175 }
David Ghandehari9e5b5872016-07-28 09:50:04 -0700176
Andrew Top0d1858f2019-05-15 22:01:47 -0700177 int GetPeerAddress(IPEndPoint* /* address */) const override {
David Ghandehari9e5b5872016-07-28 09:50:04 -0700178 return ERR_UNEXPECTED;
179 }
180
Andrew Top0d1858f2019-05-15 22:01:47 -0700181 int GetLocalAddress(IPEndPoint* /* address */) const override {
David Ghandehari9e5b5872016-07-28 09:50:04 -0700182 return ERR_UNEXPECTED;
183 }
184
Andrew Top0d1858f2019-05-15 22:01:47 -0700185 const NetLogWithSource& NetLog() const override { return net_log_; }
David Ghandehari9e5b5872016-07-28 09:50:04 -0700186
Andrew Top0d1858f2019-05-15 22:01:47 -0700187 bool WasEverUsed() const override { return was_used_to_convey_data_; }
188 bool WasAlpnNegotiated() const override { return false; }
189 NextProto GetNegotiatedProtocol() const override { return kProtoUnknown; }
190 bool GetSSLInfo(SSLInfo* ssl_info) override { return false; }
191 void GetConnectionAttempts(ConnectionAttempts* out) const override {
192 out->clear();
David Ghandehari9e5b5872016-07-28 09:50:04 -0700193 }
Andrew Top0d1858f2019-05-15 22:01:47 -0700194 void ClearConnectionAttempts() override {}
195 void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
196 int64_t GetTotalReceivedBytes() const override {
197 NOTIMPLEMENTED();
198 return 0;
David Ghandehari9e5b5872016-07-28 09:50:04 -0700199 }
Andrew Top0d1858f2019-05-15 22:01:47 -0700200 void ApplySocketTag(const SocketTag& tag) override {}
David Ghandehari9e5b5872016-07-28 09:50:04 -0700201
202 private:
203 bool connected_;
Andrew Top0d1858f2019-05-15 22:01:47 -0700204 bool has_unread_data_;
205 NetLogWithSource net_log_;
David Ghandehari9e5b5872016-07-28 09:50:04 -0700206 bool was_used_to_convey_data_;
David Ghandehari9e5b5872016-07-28 09:50:04 -0700207
208 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
209};
210
211class TestConnectJob;
212
213class MockClientSocketFactory : public ClientSocketFactory {
214 public:
215 MockClientSocketFactory() : allocation_count_(0) {}
216
Andrew Top0d1858f2019-05-15 22:01:47 -0700217 std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
David Ghandehari9e5b5872016-07-28 09:50:04 -0700218 DatagramSocket::BindType bind_type,
David Ghandehari9e5b5872016-07-28 09:50:04 -0700219 NetLog* net_log,
Andrew Top0d1858f2019-05-15 22:01:47 -0700220 const NetLogSource& source) override {
David Ghandehari9e5b5872016-07-28 09:50:04 -0700221 NOTREACHED();
Andrew Top0d1858f2019-05-15 22:01:47 -0700222 return std::unique_ptr<DatagramClientSocket>();
David Ghandehari9e5b5872016-07-28 09:50:04 -0700223 }
224
Andrew Top0d1858f2019-05-15 22:01:47 -0700225 std::unique_ptr<TransportClientSocket> CreateTransportClientSocket(
David Ghandehari9e5b5872016-07-28 09:50:04 -0700226 const AddressList& addresses,
Andrew Top0d1858f2019-05-15 22:01:47 -0700227 std::unique_ptr<
228 SocketPerformanceWatcher> /* socket_performance_watcher */,
David Ghandehari9e5b5872016-07-28 09:50:04 -0700229 NetLog* /* net_log */,
Andrew Top0d1858f2019-05-15 22:01:47 -0700230 const NetLogSource& /*source*/) override {
David Ghandehari9e5b5872016-07-28 09:50:04 -0700231 allocation_count_++;
Andrew Top0d1858f2019-05-15 22:01:47 -0700232 return nullptr;
David Ghandehari9e5b5872016-07-28 09:50:04 -0700233 }
234
Andrew Top0d1858f2019-05-15 22:01:47 -0700235 std::unique_ptr<SSLClientSocket> CreateSSLClientSocket(
236 std::unique_ptr<ClientSocketHandle> transport_socket,
David Ghandehari9e5b5872016-07-28 09:50:04 -0700237 const HostPortPair& host_and_port,
238 const SSLConfig& ssl_config,
Andrew Top0d1858f2019-05-15 22:01:47 -0700239 const SSLClientSocketContext& context) override {
David Ghandehari9e5b5872016-07-28 09:50:04 -0700240 NOTIMPLEMENTED();
Andrew Top0d1858f2019-05-15 22:01:47 -0700241 return std::unique_ptr<SSLClientSocket>();
242 }
243 std::unique_ptr<ProxyClientSocket> CreateProxyClientSocket(
244 std::unique_ptr<ClientSocketHandle> transport_socket,
245 const std::string& user_agent,
246 const HostPortPair& endpoint,
247 HttpAuthController* http_auth_controller,
248 bool tunnel,
249 bool using_spdy,
250 NextProto negotiated_protocol,
251 bool is_https_proxy,
252 const NetworkTrafficAnnotationTag& traffic_annotation) override {
253 NOTIMPLEMENTED();
254 return nullptr;
David Ghandehari9e5b5872016-07-28 09:50:04 -0700255 }
256
Andrew Top0d1858f2019-05-15 22:01:47 -0700257 void ClearSSLSessionCache() override { NOTIMPLEMENTED(); }
David Ghandehari9e5b5872016-07-28 09:50:04 -0700258
259 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
Andrew Top0d1858f2019-05-15 22:01:47 -0700260
David Ghandehari9e5b5872016-07-28 09:50:04 -0700261 void SignalJobs();
262
Andrew Top0d1858f2019-05-15 22:01:47 -0700263 void SignalJob(size_t job);
264
265 void SetJobLoadState(size_t job, LoadState load_state);
266
David Ghandehari9e5b5872016-07-28 09:50:04 -0700267 int allocation_count() const { return allocation_count_; }
268
269 private:
270 int allocation_count_;
271 std::vector<TestConnectJob*> waiting_jobs_;
272};
273
274class TestConnectJob : public ConnectJob {
275 public:
276 enum JobType {
277 kMockJob,
278 kMockFailingJob,
279 kMockPendingJob,
280 kMockPendingFailingJob,
281 kMockWaitingJob,
David Ghandehari9e5b5872016-07-28 09:50:04 -0700282 kMockRecoverableJob,
283 kMockPendingRecoverableJob,
284 kMockAdditionalErrorStateJob,
285 kMockPendingAdditionalErrorStateJob,
Andrew Top0d1858f2019-05-15 22:01:47 -0700286 kMockUnreadDataJob,
David Ghandehari9e5b5872016-07-28 09:50:04 -0700287 };
288
289 // The kMockPendingJob uses a slight delay before allowing the connect
290 // to complete.
291 static const int kPendingConnectDelay = 2;
292
293 TestConnectJob(JobType job_type,
294 const std::string& group_name,
295 const TestClientSocketPoolBase::Request& request,
296 base::TimeDelta timeout_duration,
297 ConnectJob::Delegate* delegate,
298 MockClientSocketFactory* client_socket_factory,
299 NetLog* net_log)
Andrew Top0d1858f2019-05-15 22:01:47 -0700300 : ConnectJob(
301 group_name,
302 timeout_duration,
303 request.priority(),
304 request.socket_tag(),
305 request.respect_limits(),
306 delegate,
307 NetLogWithSource::Make(net_log,
308 NetLogSourceType::TRANSPORT_CONNECT_JOB)),
David Ghandehari9e5b5872016-07-28 09:50:04 -0700309 job_type_(job_type),
310 client_socket_factory_(client_socket_factory),
David Ghandehari9e5b5872016-07-28 09:50:04 -0700311 load_state_(LOAD_STATE_IDLE),
Andrew Top0d1858f2019-05-15 22:01:47 -0700312 store_additional_error_state_(false),
313 weak_factory_(this) {}
David Ghandehari9e5b5872016-07-28 09:50:04 -0700314
315 void Signal() {
316 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
317 }
318
Andrew Top0d1858f2019-05-15 22:01:47 -0700319 void set_load_state(LoadState load_state) { load_state_ = load_state; }
David Ghandehari9e5b5872016-07-28 09:50:04 -0700320
Andrew Top0d1858f2019-05-15 22:01:47 -0700321 // From ConnectJob:
322
323 LoadState GetLoadState() const override { return load_state_; }
324
325 void GetAdditionalErrorState(ClientSocketHandle* handle) override {
David Ghandehari9e5b5872016-07-28 09:50:04 -0700326 if (store_additional_error_state_) {
327 // Set all of the additional error state fields in some way.
328 handle->set_is_ssl_error(true);
329 HttpResponseInfo info;
Andrew Top0d1858f2019-05-15 22:01:47 -0700330 info.headers = new HttpResponseHeaders(std::string());
David Ghandehari9e5b5872016-07-28 09:50:04 -0700331 handle->set_ssl_error_response_info(info);
332 }
333 }
334
335 private:
Andrew Top0d1858f2019-05-15 22:01:47 -0700336 // From ConnectJob:
David Ghandehari9e5b5872016-07-28 09:50:04 -0700337
Andrew Top0d1858f2019-05-15 22:01:47 -0700338 int ConnectInternal() override {
David Ghandehari9e5b5872016-07-28 09:50:04 -0700339 AddressList ignored;
Andrew Top0d1858f2019-05-15 22:01:47 -0700340 client_socket_factory_->CreateTransportClientSocket(ignored, NULL, NULL,
341 NetLogSource());
342 SetSocket(std::unique_ptr<StreamSocket>(
343 new MockClientSocket(net_log().net_log())));
David Ghandehari9e5b5872016-07-28 09:50:04 -0700344 switch (job_type_) {
345 case kMockJob:
346 return DoConnect(true /* successful */, false /* sync */,
347 false /* recoverable */);
348 case kMockFailingJob:
349 return DoConnect(false /* error */, false /* sync */,
350 false /* recoverable */);
351 case kMockPendingJob:
352 set_load_state(LOAD_STATE_CONNECTING);
353
354 // Depending on execution timings, posting a delayed task can result
355 // in the task getting executed the at the earliest possible
356 // opportunity or only after returning once from the message loop and
357 // then a second call into the message loop. In order to make behavior
358 // more deterministic, we change the default delay to 2ms. This should
359 // always require us to wait for the second call into the message loop.
360 //
361 // N.B. The correct fix for this and similar timing problems is to
362 // abstract time for the purpose of unittests. Unfortunately, we have
363 // a lot of third-party components that directly call the various
364 // time functions, so this change would be rather invasive.
Andrew Top0d1858f2019-05-15 22:01:47 -0700365 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
David Ghandehari9e5b5872016-07-28 09:50:04 -0700366 FROM_HERE,
367 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
Andrew Top0d1858f2019-05-15 22:01:47 -0700368 weak_factory_.GetWeakPtr(), true /* successful */,
369 true /* async */, false /* recoverable */),
David Ghandehari9e5b5872016-07-28 09:50:04 -0700370 base::TimeDelta::FromMilliseconds(kPendingConnectDelay));
371 return ERR_IO_PENDING;
372 case kMockPendingFailingJob:
373 set_load_state(LOAD_STATE_CONNECTING);
Andrew Top0d1858f2019-05-15 22:01:47 -0700374 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
David Ghandehari9e5b5872016-07-28 09:50:04 -0700375 FROM_HERE,
376 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
Andrew Top0d1858f2019-05-15 22:01:47 -0700377 weak_factory_.GetWeakPtr(), false /* error */,
378 true /* async */, false /* recoverable */),
David Ghandehari9e5b5872016-07-28 09:50:04 -0700379 base::TimeDelta::FromMilliseconds(2));
380 return ERR_IO_PENDING;
381 case kMockWaitingJob:
Andrew Top0d1858f2019-05-15 22:01:47 -0700382 set_load_state(LOAD_STATE_CONNECTING);
David Ghandehari9e5b5872016-07-28 09:50:04 -0700383 client_socket_factory_->WaitForSignal(this);
384 waiting_success_ = true;
385 return ERR_IO_PENDING;
David Ghandehari9e5b5872016-07-28 09:50:04 -0700386 case kMockRecoverableJob:
387 return DoConnect(false /* error */, false /* sync */,
388 true /* recoverable */);
389 case kMockPendingRecoverableJob:
390 set_load_state(LOAD_STATE_CONNECTING);
Andrew Top0d1858f2019-05-15 22:01:47 -0700391 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
David Ghandehari9e5b5872016-07-28 09:50:04 -0700392 FROM_HERE,
393 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
Andrew Top0d1858f2019-05-15 22:01:47 -0700394 weak_factory_.GetWeakPtr(), false /* error */,
395 true /* async */, true /* recoverable */),
David Ghandehari9e5b5872016-07-28 09:50:04 -0700396 base::TimeDelta::FromMilliseconds(2));
397 return ERR_IO_PENDING;
398 case kMockAdditionalErrorStateJob:
399 store_additional_error_state_ = true;
400 return DoConnect(false /* error */, false /* sync */,
401 false /* recoverable */);
402 case kMockPendingAdditionalErrorStateJob:
403 set_load_state(LOAD_STATE_CONNECTING);
404 store_additional_error_state_ = true;
Andrew Top0d1858f2019-05-15 22:01:47 -0700405 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
David Ghandehari9e5b5872016-07-28 09:50:04 -0700406 FROM_HERE,
407 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
Andrew Top0d1858f2019-05-15 22:01:47 -0700408 weak_factory_.GetWeakPtr(), false /* error */,
409 true /* async */, false /* recoverable */),
David Ghandehari9e5b5872016-07-28 09:50:04 -0700410 base::TimeDelta::FromMilliseconds(2));
411 return ERR_IO_PENDING;
Andrew Top0d1858f2019-05-15 22:01:47 -0700412 case kMockUnreadDataJob: {
413 int ret = DoConnect(true /* successful */, false /* sync */,
414 false /* recoverable */);
415 static_cast<MockClientSocket*>(socket())->set_has_unread_data(true);
416 return ret;
417 }
David Ghandehari9e5b5872016-07-28 09:50:04 -0700418 default:
419 NOTREACHED();
Andrew Top0d1858f2019-05-15 22:01:47 -0700420 SetSocket(std::unique_ptr<StreamSocket>());
David Ghandehari9e5b5872016-07-28 09:50:04 -0700421 return ERR_FAILED;
422 }
423 }
424
David Ghandehari9e5b5872016-07-28 09:50:04 -0700425 int DoConnect(bool succeed, bool was_async, bool recoverable) {
426 int result = OK;
427 if (succeed) {
Andrew Top0d1858f2019-05-15 22:01:47 -0700428 socket()->Connect(CompletionOnceCallback());
David Ghandehari9e5b5872016-07-28 09:50:04 -0700429 } else if (recoverable) {
430 result = ERR_PROXY_AUTH_REQUESTED;
431 } else {
432 result = ERR_CONNECTION_FAILED;
Andrew Top0d1858f2019-05-15 22:01:47 -0700433 SetSocket(std::unique_ptr<StreamSocket>());
David Ghandehari9e5b5872016-07-28 09:50:04 -0700434 }
435
436 if (was_async)
437 NotifyDelegateOfCompletion(result);
438 return result;
439 }
440
David Ghandehari9e5b5872016-07-28 09:50:04 -0700441 bool waiting_success_;
442 const JobType job_type_;
443 MockClientSocketFactory* const client_socket_factory_;
David Ghandehari9e5b5872016-07-28 09:50:04 -0700444 LoadState load_state_;
445 bool store_additional_error_state_;
446
Andrew Top0d1858f2019-05-15 22:01:47 -0700447 base::WeakPtrFactory<TestConnectJob> weak_factory_;
448
David Ghandehari9e5b5872016-07-28 09:50:04 -0700449 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
450};
451
452class TestConnectJobFactory
453 : public TestClientSocketPoolBase::ConnectJobFactory {
454 public:
Andrew Top0d1858f2019-05-15 22:01:47 -0700455 TestConnectJobFactory(MockClientSocketFactory* client_socket_factory,
456 NetLog* net_log)
David Ghandehari9e5b5872016-07-28 09:50:04 -0700457 : job_type_(TestConnectJob::kMockJob),
458 job_types_(NULL),
Andrew Top0d1858f2019-05-15 22:01:47 -0700459 client_socket_factory_(client_socket_factory),
460 net_log_(net_log) {
461 }
David Ghandehari9e5b5872016-07-28 09:50:04 -0700462
Andrew Top0d1858f2019-05-15 22:01:47 -0700463 ~TestConnectJobFactory() override = default;
David Ghandehari9e5b5872016-07-28 09:50:04 -0700464
465 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
466
467 void set_job_types(std::list<TestConnectJob::JobType>* job_types) {
468 job_types_ = job_types;
469 CHECK(!job_types_->empty());
470 }
471
472 void set_timeout_duration(base::TimeDelta timeout_duration) {
473 timeout_duration_ = timeout_duration;
474 }
475
476 // ConnectJobFactory implementation.
477
Andrew Top0d1858f2019-05-15 22:01:47 -0700478 std::unique_ptr<ConnectJob> NewConnectJob(
David Ghandehari9e5b5872016-07-28 09:50:04 -0700479 const std::string& group_name,
480 const TestClientSocketPoolBase::Request& request,
Andrew Top0d1858f2019-05-15 22:01:47 -0700481 ConnectJob::Delegate* delegate) const override {
David Ghandehari9e5b5872016-07-28 09:50:04 -0700482 EXPECT_TRUE(!job_types_ || !job_types_->empty());
483 TestConnectJob::JobType job_type = job_type_;
484 if (job_types_ && !job_types_->empty()) {
485 job_type = job_types_->front();
486 job_types_->pop_front();
487 }
Andrew Top0d1858f2019-05-15 22:01:47 -0700488 return std::unique_ptr<ConnectJob>(
489 new TestConnectJob(job_type, group_name, request, timeout_duration_,
490 delegate, client_socket_factory_, net_log_));
David Ghandehari9e5b5872016-07-28 09:50:04 -0700491 }
492
Andrew Top0d1858f2019-05-15 22:01:47 -0700493 base::TimeDelta ConnectionTimeout() const override {
David Ghandehari9e5b5872016-07-28 09:50:04 -0700494 return timeout_duration_;
495 }
496
497 private:
498 TestConnectJob::JobType job_type_;
499 std::list<TestConnectJob::JobType>* job_types_;
500 base::TimeDelta timeout_duration_;
501 MockClientSocketFactory* const client_socket_factory_;
Andrew Top0d1858f2019-05-15 22:01:47 -0700502 NetLog* net_log_;
David Ghandehari9e5b5872016-07-28 09:50:04 -0700503
504 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
505};
506
507class TestClientSocketPool : public ClientSocketPool {
508 public:
Andrew Top0d1858f2019-05-15 22:01:47 -0700509 typedef TestSocketParams SocketParams;
510
David Ghandehari9e5b5872016-07-28 09:50:04 -0700511 TestClientSocketPool(
512 int max_sockets,
513 int max_sockets_per_group,
David Ghandehari9e5b5872016-07-28 09:50:04 -0700514 base::TimeDelta unused_idle_socket_timeout,
515 base::TimeDelta used_idle_socket_timeout,
516 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
Andrew Top0d1858f2019-05-15 22:01:47 -0700517 : base_(NULL,
518 max_sockets,
519 max_sockets_per_group,
520 unused_idle_socket_timeout,
521 used_idle_socket_timeout,
David Ghandehari9e5b5872016-07-28 09:50:04 -0700522 connect_job_factory) {}
523
Andrew Top0d1858f2019-05-15 22:01:47 -0700524 ~TestClientSocketPool() override = default;
David Ghandehari9e5b5872016-07-28 09:50:04 -0700525
Andrew Top0d1858f2019-05-15 22:01:47 -0700526 int RequestSocket(const std::string& group_name,
527 const void* params,
528 RequestPriority priority,
529 const SocketTag& socket_tag,
530 RespectLimits respect_limits,
531 ClientSocketHandle* handle,
532 CompletionOnceCallback callback,
533 const NetLogWithSource& net_log) override {
David Ghandehari9e5b5872016-07-28 09:50:04 -0700534 const scoped_refptr<TestSocketParams>* casted_socket_params =
535 static_cast<const scoped_refptr<TestSocketParams>*>(params);
536 return base_.RequestSocket(group_name, *casted_socket_params, priority,
Andrew Top0d1858f2019-05-15 22:01:47 -0700537 socket_tag, respect_limits, handle,
538 std::move(callback), net_log);
David Ghandehari9e5b5872016-07-28 09:50:04 -0700539 }
540
Andrew Top0d1858f2019-05-15 22:01:47 -0700541 void RequestSockets(const std::string& group_name,
542 const void* params,
543 int num_sockets,
544 const NetLogWithSource& net_log) override {
David Ghandehari9e5b5872016-07-28 09:50:04 -0700545 const scoped_refptr<TestSocketParams>* casted_params =
546 static_cast<const scoped_refptr<TestSocketParams>*>(params);
547
548 base_.RequestSockets(group_name, *casted_params, num_sockets, net_log);
549 }
550
Andrew Top0d1858f2019-05-15 22:01:47 -0700551 void SetPriority(const std::string& group_name,
552 ClientSocketHandle* handle,
553 RequestPriority priority) override {
554 base_.SetPriority(group_name, handle, priority);
555 }
556
557 void CancelRequest(const std::string& group_name,
558 ClientSocketHandle* handle) override {
David Ghandehari9e5b5872016-07-28 09:50:04 -0700559 base_.CancelRequest(group_name, handle);
560 }
561
Andrew Top0d1858f2019-05-15 22:01:47 -0700562 void ReleaseSocket(const std::string& group_name,
563 std::unique_ptr<StreamSocket> socket,
564 int id) override {
565 base_.ReleaseSocket(group_name, std::move(socket), id);
David Ghandehari9e5b5872016-07-28 09:50:04 -0700566 }
567
Andrew Top0d1858f2019-05-15 22:01:47 -0700568 void FlushWithError(int error) override { base_.FlushWithError(error); }
569
570 bool IsStalled() const override { return base_.IsStalled(); }
571
572 void CloseIdleSockets() override { base_.CloseIdleSockets(); }
573
574 void CloseIdleSocketsInGroup(const std::string& group_name) override {
575 base_.CloseIdleSocketsInGroup(group_name);
David Ghandehari9e5b5872016-07-28 09:50:04 -0700576 }
577
Andrew Top0d1858f2019-05-15 22:01:47 -0700578 int IdleSocketCount() const override { return base_.idle_socket_count(); }
David Ghandehari9e5b5872016-07-28 09:50:04 -0700579
Andrew Top0d1858f2019-05-15 22:01:47 -0700580 int IdleSocketCountInGroup(const std::string& group_name) const override {
David Ghandehari9e5b5872016-07-28 09:50:04 -0700581 return base_.IdleSocketCountInGroup(group_name);
582 }
583
Andrew Top0d1858f2019-05-15 22:01:47 -0700584 LoadState GetLoadState(const std::string& group_name,
585 const ClientSocketHandle* handle) const override {
David Ghandehari9e5b5872016-07-28 09:50:04 -0700586 return base_.GetLoadState(group_name, handle);
587 }
588
Andrew Top0d1858f2019-05-15 22:01:47 -0700589 void AddHigherLayeredPool(HigherLayeredPool* higher_pool) override {
590 base_.AddHigherLayeredPool(higher_pool);
David Ghandehari9e5b5872016-07-28 09:50:04 -0700591 }
592
Andrew Top0d1858f2019-05-15 22:01:47 -0700593 void RemoveHigherLayeredPool(HigherLayeredPool* higher_pool) override {
594 base_.RemoveHigherLayeredPool(higher_pool);
David Ghandehari9e5b5872016-07-28 09:50:04 -0700595 }
596
Andrew Top0d1858f2019-05-15 22:01:47 -0700597 std::unique_ptr<base::DictionaryValue> GetInfoAsValue(
David Ghandehari9e5b5872016-07-28 09:50:04 -0700598 const std::string& name,
599 const std::string& type,
Andrew Top200ce4b2018-01-29 13:43:50 -0800600 bool include_nested_pools) const override {
David Ghandehari9e5b5872016-07-28 09:50:04 -0700601 return base_.GetInfoAsValue(name, type);
602 }
603
Andrew Top0d1858f2019-05-15 22:01:47 -0700604 base::TimeDelta ConnectionTimeout() const override {
David Ghandehari9e5b5872016-07-28 09:50:04 -0700605 return base_.ConnectionTimeout();
606 }
607
David Ghandehari9e5b5872016-07-28 09:50:04 -0700608 const TestClientSocketPoolBase* base() const { return &base_; }
609
610 int NumUnassignedConnectJobsInGroup(const std::string& group_name) const {
611 return base_.NumUnassignedConnectJobsInGroup(group_name);
612 }
613
614 int NumConnectJobsInGroup(const std::string& group_name) const {
615 return base_.NumConnectJobsInGroup(group_name);
616 }
617
618 int NumActiveSocketsInGroup(const std::string& group_name) const {
619 return base_.NumActiveSocketsInGroup(group_name);
620 }
621
622 bool HasGroup(const std::string& group_name) const {
623 return base_.HasGroup(group_name);
624 }
625
626 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
627
628 void EnableConnectBackupJobs() { base_.EnableConnectBackupJobs(); }
629
Andrew Top0d1858f2019-05-15 22:01:47 -0700630 bool CloseOneIdleConnectionInHigherLayeredPool() {
631 return base_.CloseOneIdleConnectionInHigherLayeredPool();
David Ghandehari9e5b5872016-07-28 09:50:04 -0700632 }
633
634 private:
635 TestClientSocketPoolBase base_;
636
637 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
638};
639
640} // namespace
641
David Ghandehari9e5b5872016-07-28 09:50:04 -0700642namespace {
643
644void MockClientSocketFactory::SignalJobs() {
Andrew Top0d1858f2019-05-15 22:01:47 -0700645 for (auto it = waiting_jobs_.begin(); it != waiting_jobs_.end(); ++it) {
David Ghandehari9e5b5872016-07-28 09:50:04 -0700646 (*it)->Signal();
647 }
648 waiting_jobs_.clear();
649}
650
Andrew Top0d1858f2019-05-15 22:01:47 -0700651void MockClientSocketFactory::SignalJob(size_t job) {
652 ASSERT_LT(job, waiting_jobs_.size());
653 waiting_jobs_[job]->Signal();
654 waiting_jobs_.erase(waiting_jobs_.begin() + job);
655}
656
657void MockClientSocketFactory::SetJobLoadState(size_t job,
658 LoadState load_state) {
659 ASSERT_LT(job, waiting_jobs_.size());
660 waiting_jobs_[job]->set_load_state(load_state);
661}
662
David Ghandehari9e5b5872016-07-28 09:50:04 -0700663class TestConnectJobDelegate : public ConnectJob::Delegate {
664 public:
Andrew Top0d1858f2019-05-15 22:01:47 -0700665 TestConnectJobDelegate() : have_result_(false), result_(OK) {}
666 ~TestConnectJobDelegate() override = default;
David Ghandehari9e5b5872016-07-28 09:50:04 -0700667
Andrew Top0d1858f2019-05-15 22:01:47 -0700668 void OnConnectJobComplete(int result, ConnectJob* job) override {
David Ghandehari9e5b5872016-07-28 09:50:04 -0700669 result_ = result;
Andrew Top0d1858f2019-05-15 22:01:47 -0700670 std::unique_ptr<ConnectJob> owned_job(job);
671 std::unique_ptr<StreamSocket> socket = owned_job->PassSocket();
David Ghandehari9e5b5872016-07-28 09:50:04 -0700672 // socket.get() should be NULL iff result != OK
Andrew Top0d1858f2019-05-15 22:01:47 -0700673 EXPECT_EQ(socket == NULL, result != OK);
David Ghandehari9e5b5872016-07-28 09:50:04 -0700674 have_result_ = true;
Andrew Top0d1858f2019-05-15 22:01:47 -0700675 if (quit_wait_on_result_)
676 std::move(quit_wait_on_result_).Run();
David Ghandehari9e5b5872016-07-28 09:50:04 -0700677 }
678
679 int WaitForResult() {
Andrew Top0d1858f2019-05-15 22:01:47 -0700680 DCHECK(!quit_wait_on_result_);
David Ghandehari9e5b5872016-07-28 09:50:04 -0700681 while (!have_result_) {
Andrew Top0d1858f2019-05-15 22:01:47 -0700682 base::RunLoop run_loop;
683 quit_wait_on_result_ = run_loop.QuitClosure();
684 run_loop.Run();
David Ghandehari9e5b5872016-07-28 09:50:04 -0700685 }
686 have_result_ = false; // auto-reset for next callback
687 return result_;
688 }
689
690 private:
691 bool have_result_;
Andrew Top0d1858f2019-05-15 22:01:47 -0700692 base::OnceClosure quit_wait_on_result_;
David Ghandehari9e5b5872016-07-28 09:50:04 -0700693 int result_;
694};
695
Andrew Top0d1858f2019-05-15 22:01:47 -0700696class ClientSocketPoolBaseTest : public TestWithScopedTaskEnvironment {
David Ghandehari9e5b5872016-07-28 09:50:04 -0700697 protected:
Andrew Top0d1858f2019-05-15 22:01:47 -0700698 ClientSocketPoolBaseTest() : params_(new TestSocketParams()) {
David Ghandehari9e5b5872016-07-28 09:50:04 -0700699 connect_backup_jobs_enabled_ =
700 internal::ClientSocketPoolBaseHelper::connect_backup_jobs_enabled();
701 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(true);
David Ghandehari9e5b5872016-07-28 09:50:04 -0700702 }
703
Andrew Top0d1858f2019-05-15 22:01:47 -0700704 ~ClientSocketPoolBaseTest() override {
David Ghandehari9e5b5872016-07-28 09:50:04 -0700705 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
706 connect_backup_jobs_enabled_);
David Ghandehari9e5b5872016-07-28 09:50:04 -0700707 }
708
709 void CreatePool(int max_sockets, int max_sockets_per_group) {
710 CreatePoolWithIdleTimeouts(
711 max_sockets,
712 max_sockets_per_group,
713 ClientSocketPool::unused_idle_socket_timeout(),
714 ClientSocketPool::used_idle_socket_timeout());
715 }
716
717 void CreatePoolWithIdleTimeouts(
718 int max_sockets, int max_sockets_per_group,
719 base::TimeDelta unused_idle_socket_timeout,
720 base::TimeDelta used_idle_socket_timeout) {
721 DCHECK(!pool_.get());
Andrew Top0d1858f2019-05-15 22:01:47 -0700722 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_,
723 &net_log_);
David Ghandehari9e5b5872016-07-28 09:50:04 -0700724 pool_.reset(new TestClientSocketPool(max_sockets,
725 max_sockets_per_group,
David Ghandehari9e5b5872016-07-28 09:50:04 -0700726 unused_idle_socket_timeout,
727 used_idle_socket_timeout,
728 connect_job_factory_));
729 }
730
Andrew Top0d1858f2019-05-15 22:01:47 -0700731 int StartRequestWithIgnoreLimits(
732 const std::string& group_name,
733 RequestPriority priority,
734 ClientSocketPool::RespectLimits respect_limits) {
735 return test_base_.StartRequestUsingPool(pool_.get(), group_name, priority,
736 respect_limits, params_);
737 }
738
739 int StartRequest(const std::string& group_name, RequestPriority priority) {
740 return StartRequestWithIgnoreLimits(
741 group_name, priority, ClientSocketPool::RespectLimits::ENABLED);
David Ghandehari9e5b5872016-07-28 09:50:04 -0700742 }
743
744 int GetOrderOfRequest(size_t index) const {
745 return test_base_.GetOrderOfRequest(index);
746 }
747
748 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
749 return test_base_.ReleaseOneConnection(keep_alive);
750 }
751
752 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
753 test_base_.ReleaseAllConnections(keep_alive);
754 }
755
756 TestSocketRequest* request(int i) { return test_base_.request(i); }
757 size_t requests_size() const { return test_base_.requests_size(); }
Andrew Top0d1858f2019-05-15 22:01:47 -0700758 std::vector<std::unique_ptr<TestSocketRequest>>* requests() {
759 return test_base_.requests();
760 }
761 // Only counts the requests that get sockets asynchronously;
762 // synchronous completions are not registered by this count.
David Ghandehari9e5b5872016-07-28 09:50:04 -0700763 size_t completion_count() const { return test_base_.completion_count(); }
764
Andrew Top0d1858f2019-05-15 22:01:47 -0700765 TestNetLog net_log_;
David Ghandehari9e5b5872016-07-28 09:50:04 -0700766 bool connect_backup_jobs_enabled_;
David Ghandehari9e5b5872016-07-28 09:50:04 -0700767 MockClientSocketFactory client_socket_factory_;
768 TestConnectJobFactory* connect_job_factory_;
769 scoped_refptr<TestSocketParams> params_;
Andrew Top0d1858f2019-05-15 22:01:47 -0700770 std::unique_ptr<TestClientSocketPool> pool_;
David Ghandehari9e5b5872016-07-28 09:50:04 -0700771 ClientSocketPoolTest test_base_;
772};
773
David Ghandehari9e5b5872016-07-28 09:50:04 -0700774// Even though a timeout is specified, it doesn't time out on a synchronous
775// completion.
776TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
777 TestConnectJobDelegate delegate;
778 ClientSocketHandle ignored;
779 TestClientSocketPoolBase::Request request(
Andrew Top0d1858f2019-05-15 22:01:47 -0700780 &ignored, CompletionOnceCallback(), DEFAULT_PRIORITY, SocketTag(),
781 ClientSocketPool::RespectLimits::ENABLED,
782 internal::ClientSocketPoolBaseHelper::NORMAL, params_,
783 NetLogWithSource());
784 std::unique_ptr<TestConnectJob> job(
785 new TestConnectJob(TestConnectJob::kMockJob, "a", request,
786 base::TimeDelta::FromMicroseconds(1), &delegate,
787 &client_socket_factory_, NULL));
788 EXPECT_THAT(job->Connect(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -0700789}
790
791TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
792 TestConnectJobDelegate delegate;
793 ClientSocketHandle ignored;
Andrew Top0d1858f2019-05-15 22:01:47 -0700794 TestNetLog log;
David Ghandehari9e5b5872016-07-28 09:50:04 -0700795
796 TestClientSocketPoolBase::Request request(
Andrew Top0d1858f2019-05-15 22:01:47 -0700797 &ignored, CompletionOnceCallback(), DEFAULT_PRIORITY, SocketTag(),
798 ClientSocketPool::RespectLimits::ENABLED,
799 internal::ClientSocketPoolBaseHelper::NORMAL, params_,
800 NetLogWithSource());
David Ghandehari9e5b5872016-07-28 09:50:04 -0700801 // Deleted by TestConnectJobDelegate.
802 TestConnectJob* job =
803 new TestConnectJob(TestConnectJob::kMockPendingJob,
804 "a",
805 request,
806 base::TimeDelta::FromMicroseconds(1),
807 &delegate,
808 &client_socket_factory_,
809 &log);
Andrew Top0d1858f2019-05-15 22:01:47 -0700810 ASSERT_THAT(job->Connect(), IsError(ERR_IO_PENDING));
David Ghandehari9e5b5872016-07-28 09:50:04 -0700811 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
Andrew Top0d1858f2019-05-15 22:01:47 -0700812 EXPECT_THAT(delegate.WaitForResult(), IsError(ERR_TIMED_OUT));
David Ghandehari9e5b5872016-07-28 09:50:04 -0700813
Andrew Top0d1858f2019-05-15 22:01:47 -0700814 TestNetLogEntry::List entries;
David Ghandehari9e5b5872016-07-28 09:50:04 -0700815 log.GetEntries(&entries);
816
817 EXPECT_EQ(6u, entries.size());
Andrew Top0d1858f2019-05-15 22:01:47 -0700818 EXPECT_TRUE(LogContainsBeginEvent(entries, 0,
819 NetLogEventType::SOCKET_POOL_CONNECT_JOB));
David Ghandehari9e5b5872016-07-28 09:50:04 -0700820 EXPECT_TRUE(LogContainsBeginEvent(
Andrew Top0d1858f2019-05-15 22:01:47 -0700821 entries, 1, NetLogEventType::SOCKET_POOL_CONNECT_JOB_CONNECT));
822 EXPECT_TRUE(LogContainsEvent(entries, 2,
823 NetLogEventType::CONNECT_JOB_SET_SOCKET,
824 NetLogEventPhase::NONE));
David Ghandehari9e5b5872016-07-28 09:50:04 -0700825 EXPECT_TRUE(LogContainsEvent(
Andrew Top0d1858f2019-05-15 22:01:47 -0700826 entries, 3, NetLogEventType::SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
827 NetLogEventPhase::NONE));
David Ghandehari9e5b5872016-07-28 09:50:04 -0700828 EXPECT_TRUE(LogContainsEndEvent(
Andrew Top0d1858f2019-05-15 22:01:47 -0700829 entries, 4, NetLogEventType::SOCKET_POOL_CONNECT_JOB_CONNECT));
830 EXPECT_TRUE(LogContainsEndEvent(entries, 5,
831 NetLogEventType::SOCKET_POOL_CONNECT_JOB));
David Ghandehari9e5b5872016-07-28 09:50:04 -0700832}
833
834TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
835 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
836
837 TestCompletionCallback callback;
838 ClientSocketHandle handle;
Andrew Top0d1858f2019-05-15 22:01:47 -0700839 BoundTestNetLog log;
840 TestLoadTimingInfoNotConnected(handle);
David Ghandehari9e5b5872016-07-28 09:50:04 -0700841
Andrew Top0d1858f2019-05-15 22:01:47 -0700842 EXPECT_EQ(OK, handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
843 ClientSocketPool::RespectLimits::ENABLED,
844 callback.callback(), pool_.get(), log.bound()));
David Ghandehari9e5b5872016-07-28 09:50:04 -0700845 EXPECT_TRUE(handle.is_initialized());
846 EXPECT_TRUE(handle.socket());
Andrew Top0d1858f2019-05-15 22:01:47 -0700847 TestLoadTimingInfoConnectedNotReused(handle);
David Ghandehari9e5b5872016-07-28 09:50:04 -0700848
Andrew Top0d1858f2019-05-15 22:01:47 -0700849 handle.Reset();
850 TestLoadTimingInfoNotConnected(handle);
851
852 TestNetLogEntry::List entries;
David Ghandehari9e5b5872016-07-28 09:50:04 -0700853 log.GetEntries(&entries);
854
855 EXPECT_EQ(4u, entries.size());
Andrew Top0d1858f2019-05-15 22:01:47 -0700856 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKET_POOL));
David Ghandehari9e5b5872016-07-28 09:50:04 -0700857 EXPECT_TRUE(LogContainsEvent(
Andrew Top0d1858f2019-05-15 22:01:47 -0700858 entries, 1, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
859 NetLogEventPhase::NONE));
860 EXPECT_TRUE(LogContainsEvent(entries, 2,
861 NetLogEventType::SOCKET_POOL_BOUND_TO_SOCKET,
862 NetLogEventPhase::NONE));
863 EXPECT_TRUE(LogContainsEndEvent(entries, 3, NetLogEventType::SOCKET_POOL));
David Ghandehari9e5b5872016-07-28 09:50:04 -0700864}
865
866TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
867 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
868
869 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
Andrew Top0d1858f2019-05-15 22:01:47 -0700870 BoundTestNetLog log;
David Ghandehari9e5b5872016-07-28 09:50:04 -0700871
872 ClientSocketHandle handle;
873 TestCompletionCallback callback;
874 // Set the additional error state members to ensure that they get cleared.
875 handle.set_is_ssl_error(true);
876 HttpResponseInfo info;
Andrew Top0d1858f2019-05-15 22:01:47 -0700877 info.headers = new HttpResponseHeaders(std::string());
David Ghandehari9e5b5872016-07-28 09:50:04 -0700878 handle.set_ssl_error_response_info(info);
879 EXPECT_EQ(ERR_CONNECTION_FAILED,
Andrew Top0d1858f2019-05-15 22:01:47 -0700880 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
881 ClientSocketPool::RespectLimits::ENABLED,
882 callback.callback(), pool_.get(), log.bound()));
David Ghandehari9e5b5872016-07-28 09:50:04 -0700883 EXPECT_FALSE(handle.socket());
884 EXPECT_FALSE(handle.is_ssl_error());
885 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
Andrew Top0d1858f2019-05-15 22:01:47 -0700886 TestLoadTimingInfoNotConnected(handle);
David Ghandehari9e5b5872016-07-28 09:50:04 -0700887
Andrew Top0d1858f2019-05-15 22:01:47 -0700888 TestNetLogEntry::List entries;
David Ghandehari9e5b5872016-07-28 09:50:04 -0700889 log.GetEntries(&entries);
890
891 EXPECT_EQ(3u, entries.size());
Andrew Top0d1858f2019-05-15 22:01:47 -0700892 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKET_POOL));
David Ghandehari9e5b5872016-07-28 09:50:04 -0700893 EXPECT_TRUE(LogContainsEvent(
Andrew Top0d1858f2019-05-15 22:01:47 -0700894 entries, 1, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
895 NetLogEventPhase::NONE));
896 EXPECT_TRUE(LogContainsEndEvent(entries, 2, NetLogEventType::SOCKET_POOL));
David Ghandehari9e5b5872016-07-28 09:50:04 -0700897}
898
899TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
900 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
901
902 // TODO(eroman): Check that the NetLog contains this event.
903
Andrew Top0d1858f2019-05-15 22:01:47 -0700904 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
905 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
906 EXPECT_THAT(StartRequest("c", DEFAULT_PRIORITY), IsOk());
907 EXPECT_THAT(StartRequest("d", DEFAULT_PRIORITY), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -0700908
909 EXPECT_EQ(static_cast<int>(requests_size()),
910 client_socket_factory_.allocation_count());
911 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
912
Andrew Top0d1858f2019-05-15 22:01:47 -0700913 EXPECT_THAT(StartRequest("e", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
914 EXPECT_THAT(StartRequest("f", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
915 EXPECT_THAT(StartRequest("g", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
David Ghandehari9e5b5872016-07-28 09:50:04 -0700916
917 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
918
919 EXPECT_EQ(static_cast<int>(requests_size()),
920 client_socket_factory_.allocation_count());
921 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
922
923 EXPECT_EQ(1, GetOrderOfRequest(1));
924 EXPECT_EQ(2, GetOrderOfRequest(2));
925 EXPECT_EQ(3, GetOrderOfRequest(3));
926 EXPECT_EQ(4, GetOrderOfRequest(4));
927 EXPECT_EQ(5, GetOrderOfRequest(5));
928 EXPECT_EQ(6, GetOrderOfRequest(6));
929 EXPECT_EQ(7, GetOrderOfRequest(7));
930
931 // Make sure we test order of all requests made.
932 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
933}
934
935TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
936 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
937
938 // TODO(eroman): Check that the NetLog contains this event.
939
940 // Reach all limits: max total sockets, and max sockets per group.
Andrew Top0d1858f2019-05-15 22:01:47 -0700941 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
942 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
943 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
944 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -0700945
946 EXPECT_EQ(static_cast<int>(requests_size()),
947 client_socket_factory_.allocation_count());
948 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
949
950 // Now create a new group and verify that we don't starve it.
Andrew Top0d1858f2019-05-15 22:01:47 -0700951 EXPECT_THAT(StartRequest("c", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
David Ghandehari9e5b5872016-07-28 09:50:04 -0700952
953 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
954
955 EXPECT_EQ(static_cast<int>(requests_size()),
956 client_socket_factory_.allocation_count());
957 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
958
959 EXPECT_EQ(1, GetOrderOfRequest(1));
960 EXPECT_EQ(2, GetOrderOfRequest(2));
961 EXPECT_EQ(3, GetOrderOfRequest(3));
962 EXPECT_EQ(4, GetOrderOfRequest(4));
963 EXPECT_EQ(5, GetOrderOfRequest(5));
964
965 // Make sure we test order of all requests made.
966 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
967}
968
969TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
970 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
971
Andrew Top0d1858f2019-05-15 22:01:47 -0700972 EXPECT_THAT(StartRequest("b", LOWEST), IsOk());
973 EXPECT_THAT(StartRequest("a", MEDIUM), IsOk());
974 EXPECT_THAT(StartRequest("b", HIGHEST), IsOk());
975 EXPECT_THAT(StartRequest("a", LOWEST), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -0700976
977 EXPECT_EQ(static_cast<int>(requests_size()),
978 client_socket_factory_.allocation_count());
979
Andrew Top0d1858f2019-05-15 22:01:47 -0700980 EXPECT_THAT(StartRequest("c", LOWEST), IsError(ERR_IO_PENDING));
981 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
982 EXPECT_THAT(StartRequest("b", HIGHEST), IsError(ERR_IO_PENDING));
David Ghandehari9e5b5872016-07-28 09:50:04 -0700983
984 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
985
986 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
987
988 // First 4 requests don't have to wait, and finish in order.
989 EXPECT_EQ(1, GetOrderOfRequest(1));
990 EXPECT_EQ(2, GetOrderOfRequest(2));
991 EXPECT_EQ(3, GetOrderOfRequest(3));
992 EXPECT_EQ(4, GetOrderOfRequest(4));
993
994 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
995 // and then ("c", LOWEST).
996 EXPECT_EQ(7, GetOrderOfRequest(5));
997 EXPECT_EQ(6, GetOrderOfRequest(6));
998 EXPECT_EQ(5, GetOrderOfRequest(7));
999
1000 // Make sure we test order of all requests made.
1001 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
1002}
1003
Andrew Top0d1858f2019-05-15 22:01:47 -07001004// Test reprioritizing a request before completion doesn't interfere with
1005// its completion.
1006TEST_F(ClientSocketPoolBaseTest, ReprioritizeOne) {
1007 CreatePool(kDefaultMaxSockets, 1);
1008
1009 EXPECT_THAT(StartRequest("a", LOWEST), IsError(OK));
1010 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1011 EXPECT_TRUE(request(0)->handle()->socket());
1012 EXPECT_FALSE(request(1)->handle()->socket());
1013
1014 request(1)->handle()->SetPriority(MEDIUM);
1015
1016 ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE);
1017
1018 EXPECT_TRUE(request(1)->handle()->socket());
1019}
1020
1021// Reprioritize a request up past another one and make sure that changes the
1022// completion order.
1023TEST_F(ClientSocketPoolBaseTest, ReprioritizeUpReorder) {
1024 CreatePool(kDefaultMaxSockets, 1);
1025
1026 EXPECT_THAT(StartRequest("a", LOWEST), IsError(OK));
1027 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1028 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
1029 EXPECT_TRUE(request(0)->handle()->socket());
1030 EXPECT_FALSE(request(1)->handle()->socket());
1031 EXPECT_FALSE(request(2)->handle()->socket());
1032
1033 request(2)->handle()->SetPriority(HIGHEST);
1034
1035 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1036
1037 EXPECT_EQ(1, GetOrderOfRequest(1));
1038 EXPECT_EQ(3, GetOrderOfRequest(2));
1039 EXPECT_EQ(2, GetOrderOfRequest(3));
1040}
1041
1042// Reprioritize a request without changing relative priorities and check
1043// that the order doesn't change.
1044TEST_F(ClientSocketPoolBaseTest, ReprioritizeUpNoReorder) {
1045 CreatePool(kDefaultMaxSockets, 1);
1046
1047 EXPECT_THAT(StartRequest("a", LOWEST), IsError(OK));
1048 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1049 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1050 EXPECT_TRUE(request(0)->handle()->socket());
1051 EXPECT_FALSE(request(1)->handle()->socket());
1052 EXPECT_FALSE(request(2)->handle()->socket());
1053
1054 request(2)->handle()->SetPriority(MEDIUM);
1055
1056 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1057
1058 EXPECT_EQ(1, GetOrderOfRequest(1));
1059 EXPECT_EQ(2, GetOrderOfRequest(2));
1060 EXPECT_EQ(3, GetOrderOfRequest(3));
1061}
1062
1063// Reprioritize a request past down another one and make sure that changes the
1064// completion order.
1065TEST_F(ClientSocketPoolBaseTest, ReprioritizeDownReorder) {
1066 CreatePool(kDefaultMaxSockets, 1);
1067
1068 EXPECT_THAT(StartRequest("a", LOWEST), IsError(OK));
1069 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
1070 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1071 EXPECT_TRUE(request(0)->handle()->socket());
1072 EXPECT_FALSE(request(1)->handle()->socket());
1073 EXPECT_FALSE(request(2)->handle()->socket());
1074
1075 request(1)->handle()->SetPriority(LOW);
1076
1077 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1078
1079 EXPECT_EQ(1, GetOrderOfRequest(1));
1080 EXPECT_EQ(3, GetOrderOfRequest(2));
1081 EXPECT_EQ(2, GetOrderOfRequest(3));
1082}
1083
1084// Reprioritize a request to the same level as another and confirm it is
1085// put after the old request.
1086TEST_F(ClientSocketPoolBaseTest, ReprioritizeResetFIFO) {
1087 CreatePool(kDefaultMaxSockets, 1);
1088
1089 EXPECT_THAT(StartRequest("a", LOWEST), IsError(OK));
1090 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
1091 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1092 EXPECT_TRUE(request(0)->handle()->socket());
1093 EXPECT_FALSE(request(1)->handle()->socket());
1094 EXPECT_FALSE(request(2)->handle()->socket());
1095
1096 request(1)->handle()->SetPriority(MEDIUM);
1097
1098 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1099
1100 EXPECT_EQ(1, GetOrderOfRequest(1));
1101 EXPECT_EQ(3, GetOrderOfRequest(2));
1102 EXPECT_EQ(2, GetOrderOfRequest(3));
1103}
1104
David Ghandehari9e5b5872016-07-28 09:50:04 -07001105TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
1106 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1107
Andrew Top0d1858f2019-05-15 22:01:47 -07001108 EXPECT_THAT(StartRequest("a", LOWEST), IsOk());
1109 EXPECT_THAT(StartRequest("a", LOW), IsOk());
1110 EXPECT_THAT(StartRequest("b", HIGHEST), IsOk());
1111 EXPECT_THAT(StartRequest("b", MEDIUM), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07001112
1113 EXPECT_EQ(static_cast<int>(requests_size()),
1114 client_socket_factory_.allocation_count());
1115
Andrew Top0d1858f2019-05-15 22:01:47 -07001116 EXPECT_THAT(StartRequest("c", MEDIUM), IsError(ERR_IO_PENDING));
1117 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1118 EXPECT_THAT(StartRequest("b", HIGHEST), IsError(ERR_IO_PENDING));
David Ghandehari9e5b5872016-07-28 09:50:04 -07001119
1120 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1121
1122 EXPECT_EQ(static_cast<int>(requests_size()),
1123 client_socket_factory_.allocation_count());
1124 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
1125
1126 // First 4 requests don't have to wait, and finish in order.
1127 EXPECT_EQ(1, GetOrderOfRequest(1));
1128 EXPECT_EQ(2, GetOrderOfRequest(2));
1129 EXPECT_EQ(3, GetOrderOfRequest(3));
1130 EXPECT_EQ(4, GetOrderOfRequest(4));
1131
1132 // Request ("b", 7) has the highest priority, but we can't make new socket for
1133 // group "b", because it has reached the per-group limit. Then we make
1134 // socket for ("c", 6), because it has higher priority than ("a", 4),
1135 // and we still can't make a socket for group "b".
1136 EXPECT_EQ(5, GetOrderOfRequest(5));
1137 EXPECT_EQ(6, GetOrderOfRequest(6));
1138 EXPECT_EQ(7, GetOrderOfRequest(7));
1139
1140 // Make sure we test order of all requests made.
1141 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
1142}
1143
1144// Make sure that we count connecting sockets against the total limit.
1145TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
1146 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1147
Andrew Top0d1858f2019-05-15 22:01:47 -07001148 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1149 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
1150 EXPECT_THAT(StartRequest("c", DEFAULT_PRIORITY), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07001151
1152 // Create one asynchronous request.
1153 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
Andrew Top0d1858f2019-05-15 22:01:47 -07001154 EXPECT_THAT(StartRequest("d", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
David Ghandehari9e5b5872016-07-28 09:50:04 -07001155
1156 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1157 // actually become pending until 2ms after they have been created. In order
1158 // to flush all tasks, we need to wait so that we know there are no
1159 // soon-to-be-pending tasks waiting.
1160 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
Andrew Top0d1858f2019-05-15 22:01:47 -07001161 base::RunLoop().RunUntilIdle();
David Ghandehari9e5b5872016-07-28 09:50:04 -07001162
1163 // The next synchronous request should wait for its turn.
1164 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
Andrew Top0d1858f2019-05-15 22:01:47 -07001165 EXPECT_THAT(StartRequest("e", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
David Ghandehari9e5b5872016-07-28 09:50:04 -07001166
1167 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1168
1169 EXPECT_EQ(static_cast<int>(requests_size()),
1170 client_socket_factory_.allocation_count());
1171
1172 EXPECT_EQ(1, GetOrderOfRequest(1));
1173 EXPECT_EQ(2, GetOrderOfRequest(2));
1174 EXPECT_EQ(3, GetOrderOfRequest(3));
1175 EXPECT_EQ(4, GetOrderOfRequest(4));
1176 EXPECT_EQ(5, GetOrderOfRequest(5));
1177
1178 // Make sure we test order of all requests made.
1179 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
1180}
1181
1182TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
1183 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1184 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1185
Andrew Top0d1858f2019-05-15 22:01:47 -07001186 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1187 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1188 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1189 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07001190
1191 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1192
1193 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1194
Andrew Top0d1858f2019-05-15 22:01:47 -07001195 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1196 EXPECT_THAT(StartRequest("c", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
David Ghandehari9e5b5872016-07-28 09:50:04 -07001197
1198 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1199
1200 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1201 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1202 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1203 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
1204 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1205 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1206 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
1207}
1208
1209TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
1210 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1211 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1212
1213 ClientSocketHandle handle;
1214 TestCompletionCallback callback;
1215 EXPECT_EQ(ERR_IO_PENDING,
Andrew Top0d1858f2019-05-15 22:01:47 -07001216 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
1217 ClientSocketPool::RespectLimits::ENABLED,
1218 callback.callback(), pool_.get(), NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07001219
1220 ClientSocketHandle handles[4];
1221 for (size_t i = 0; i < arraysize(handles); ++i) {
1222 TestCompletionCallback callback;
Andrew Top0d1858f2019-05-15 22:01:47 -07001223 EXPECT_EQ(
1224 ERR_IO_PENDING,
1225 handles[i].Init("b", params_, DEFAULT_PRIORITY, SocketTag(),
1226 ClientSocketPool::RespectLimits::ENABLED,
1227 callback.callback(), pool_.get(), NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07001228 }
1229
1230 // One will be stalled, cancel all the handles now.
1231 // This should hit the OnAvailableSocketSlot() code where we previously had
1232 // stalled groups, but no longer have any.
1233 for (size_t i = 0; i < arraysize(handles); ++i)
1234 handles[i].Reset();
1235}
1236
1237TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
1238 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1239 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1240
1241 {
1242 ClientSocketHandle handles[kDefaultMaxSockets];
1243 TestCompletionCallback callbacks[kDefaultMaxSockets];
1244 for (int i = 0; i < kDefaultMaxSockets; ++i) {
Andrew Top0d1858f2019-05-15 22:01:47 -07001245 EXPECT_EQ(OK, handles[i].Init(base::IntToString(i), params_,
1246 DEFAULT_PRIORITY, SocketTag(),
1247 ClientSocketPool::RespectLimits::ENABLED,
1248 callbacks[i].callback(), pool_.get(),
1249 NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07001250 }
1251
1252 // Force a stalled group.
1253 ClientSocketHandle stalled_handle;
1254 TestCompletionCallback callback;
Andrew Top0d1858f2019-05-15 22:01:47 -07001255 EXPECT_EQ(ERR_IO_PENDING,
1256 stalled_handle.Init("foo", params_, DEFAULT_PRIORITY, SocketTag(),
1257 ClientSocketPool::RespectLimits::ENABLED,
1258 callback.callback(), pool_.get(),
1259 NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07001260
1261 // Cancel the stalled request.
1262 stalled_handle.Reset();
1263
1264 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1265 EXPECT_EQ(0, pool_->IdleSocketCount());
1266
1267 // Dropping out of scope will close all handles and return them to idle.
1268 }
1269
1270 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1271 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
1272}
1273
1274TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
1275 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1276 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1277
1278 {
1279 ClientSocketHandle handles[kDefaultMaxSockets];
1280 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1281 TestCompletionCallback callback;
Andrew Top0d1858f2019-05-15 22:01:47 -07001282 EXPECT_EQ(ERR_IO_PENDING,
1283 handles[i].Init(
1284 base::IntToString(i), params_, DEFAULT_PRIORITY,
1285 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1286 callback.callback(), pool_.get(), NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07001287 }
1288
1289 // Force a stalled group.
1290 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1291 ClientSocketHandle stalled_handle;
1292 TestCompletionCallback callback;
Andrew Top0d1858f2019-05-15 22:01:47 -07001293 EXPECT_EQ(ERR_IO_PENDING,
1294 stalled_handle.Init("foo", params_, DEFAULT_PRIORITY, SocketTag(),
1295 ClientSocketPool::RespectLimits::ENABLED,
1296 callback.callback(), pool_.get(),
1297 NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07001298
1299 // Since it is stalled, it should have no connect jobs.
1300 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
1301 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
1302
1303 // Cancel the stalled request.
1304 handles[0].Reset();
1305
1306 // Now we should have a connect job.
1307 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("foo"));
1308 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
1309
1310 // The stalled socket should connect.
Andrew Top0d1858f2019-05-15 22:01:47 -07001311 EXPECT_THAT(callback.WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07001312
1313 EXPECT_EQ(kDefaultMaxSockets + 1,
1314 client_socket_factory_.allocation_count());
1315 EXPECT_EQ(0, pool_->IdleSocketCount());
1316 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
1317 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
1318
1319 // Dropping out of scope will close all handles and return them to idle.
1320 }
1321
1322 EXPECT_EQ(1, pool_->IdleSocketCount());
1323}
1324
1325TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1326 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1327 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1328
1329 ClientSocketHandle stalled_handle;
1330 TestCompletionCallback callback;
1331 {
1332 EXPECT_FALSE(pool_->IsStalled());
1333 ClientSocketHandle handles[kDefaultMaxSockets];
1334 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1335 TestCompletionCallback callback;
Andrew Top0d1858f2019-05-15 22:01:47 -07001336 EXPECT_EQ(OK, handles[i].Init(base::StringPrintf("Take 2: %d", i),
1337 params_, DEFAULT_PRIORITY, SocketTag(),
1338 ClientSocketPool::RespectLimits::ENABLED,
1339 callback.callback(), pool_.get(),
1340 NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07001341 }
1342
1343 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1344 EXPECT_EQ(0, pool_->IdleSocketCount());
1345 EXPECT_FALSE(pool_->IsStalled());
1346
1347 // Now we will hit the socket limit.
Andrew Top0d1858f2019-05-15 22:01:47 -07001348 EXPECT_EQ(ERR_IO_PENDING,
1349 stalled_handle.Init("foo", params_, DEFAULT_PRIORITY, SocketTag(),
1350 ClientSocketPool::RespectLimits::ENABLED,
1351 callback.callback(), pool_.get(),
1352 NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07001353 EXPECT_TRUE(pool_->IsStalled());
1354
1355 // Dropping out of scope will close all handles and return them to idle.
1356 }
1357
1358 // But if we wait for it, the released idle sockets will be closed in
1359 // preference of the waiting request.
Andrew Top0d1858f2019-05-15 22:01:47 -07001360 EXPECT_THAT(callback.WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07001361
1362 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1363 EXPECT_EQ(3, pool_->IdleSocketCount());
1364}
1365
1366// Regression test for http://crbug.com/40952.
1367TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1368 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1369 pool_->EnableConnectBackupJobs();
1370 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1371
1372 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1373 ClientSocketHandle handle;
1374 TestCompletionCallback callback;
Andrew Top0d1858f2019-05-15 22:01:47 -07001375 EXPECT_EQ(
1376 OK, handle.Init(base::IntToString(i), params_, DEFAULT_PRIORITY,
1377 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1378 callback.callback(), pool_.get(), NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07001379 }
1380
1381 // Flush all the DoReleaseSocket tasks.
Andrew Top0d1858f2019-05-15 22:01:47 -07001382 base::RunLoop().RunUntilIdle();
David Ghandehari9e5b5872016-07-28 09:50:04 -07001383
1384 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1385 // reuse a socket.
1386 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1387 ClientSocketHandle handle;
1388 TestCompletionCallback callback;
1389
1390 // "0" is special here, since it should be the first entry in the sorted map,
1391 // which is the one which we would close an idle socket for. We shouldn't
1392 // close an idle socket though, since we should reuse the idle socket.
Andrew Top0d1858f2019-05-15 22:01:47 -07001393 EXPECT_EQ(OK,
1394 handle.Init("0", params_, DEFAULT_PRIORITY, SocketTag(),
1395 ClientSocketPool::RespectLimits::ENABLED,
1396 callback.callback(), pool_.get(), NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07001397
1398 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1399 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1400}
1401
1402TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
1403 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1404
Andrew Top0d1858f2019-05-15 22:01:47 -07001405 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1406 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1407 EXPECT_THAT(StartRequest("a", IDLE), IsError(ERR_IO_PENDING));
1408 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
1409 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1410 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
1411 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1412 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
David Ghandehari9e5b5872016-07-28 09:50:04 -07001413
1414 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
David Ghandehari9e5b5872016-07-28 09:50:04 -07001415 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1416 client_socket_factory_.allocation_count());
1417 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1418 completion_count());
1419
1420 EXPECT_EQ(1, GetOrderOfRequest(1));
1421 EXPECT_EQ(2, GetOrderOfRequest(2));
1422 EXPECT_EQ(8, GetOrderOfRequest(3));
1423 EXPECT_EQ(6, GetOrderOfRequest(4));
1424 EXPECT_EQ(4, GetOrderOfRequest(5));
1425 EXPECT_EQ(3, GetOrderOfRequest(6));
1426 EXPECT_EQ(5, GetOrderOfRequest(7));
1427 EXPECT_EQ(7, GetOrderOfRequest(8));
1428
1429 // Make sure we test order of all requests made.
1430 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
1431}
1432
1433TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
1434 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1435
Andrew Top0d1858f2019-05-15 22:01:47 -07001436 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1437 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1438 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
1439 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1440 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
1441 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1442 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
David Ghandehari9e5b5872016-07-28 09:50:04 -07001443
1444 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1445
1446 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
Andrew Top0d1858f2019-05-15 22:01:47 -07001447 EXPECT_THAT(request(i)->WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07001448
1449 EXPECT_EQ(static_cast<int>(requests_size()),
1450 client_socket_factory_.allocation_count());
1451 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1452 completion_count());
1453}
1454
1455// This test will start up a RequestSocket() and then immediately Cancel() it.
1456// The pending connect job will be cancelled and should not call back into
1457// ClientSocketPoolBase.
1458TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
1459 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1460
1461 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1462 ClientSocketHandle handle;
1463 TestCompletionCallback callback;
Andrew Top0d1858f2019-05-15 22:01:47 -07001464 EXPECT_EQ(ERR_IO_PENDING,
1465 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
1466 ClientSocketPool::RespectLimits::ENABLED,
1467 callback.callback(), pool_.get(), NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07001468 handle.Reset();
1469}
1470
1471TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
1472 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1473
1474 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1475 ClientSocketHandle handle;
1476 TestCompletionCallback callback;
1477
Andrew Top0d1858f2019-05-15 22:01:47 -07001478 EXPECT_EQ(ERR_IO_PENDING,
1479 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
1480 ClientSocketPool::RespectLimits::ENABLED,
1481 callback.callback(), pool_.get(), NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07001482
1483 handle.Reset();
1484
1485 TestCompletionCallback callback2;
1486 EXPECT_EQ(ERR_IO_PENDING,
Andrew Top0d1858f2019-05-15 22:01:47 -07001487 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
1488 ClientSocketPool::RespectLimits::ENABLED,
1489 callback2.callback(), pool_.get(), NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07001490
Andrew Top0d1858f2019-05-15 22:01:47 -07001491 EXPECT_THAT(callback2.WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07001492 EXPECT_FALSE(callback.have_result());
1493
1494 handle.Reset();
1495}
1496
1497TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
1498 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1499
Andrew Top0d1858f2019-05-15 22:01:47 -07001500 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1501 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1502 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
1503 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1504 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
1505 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1506 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
David Ghandehari9e5b5872016-07-28 09:50:04 -07001507
1508 // Cancel a request.
1509 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
1510 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1511 (*requests())[index_to_cancel]->handle()->Reset();
1512
1513 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
1514
1515 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1516 client_socket_factory_.allocation_count());
1517 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1518 completion_count());
1519
1520 EXPECT_EQ(1, GetOrderOfRequest(1));
1521 EXPECT_EQ(2, GetOrderOfRequest(2));
1522 EXPECT_EQ(5, GetOrderOfRequest(3));
1523 EXPECT_EQ(3, GetOrderOfRequest(4));
1524 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1525 GetOrderOfRequest(5)); // Canceled request.
1526 EXPECT_EQ(4, GetOrderOfRequest(6));
1527 EXPECT_EQ(6, GetOrderOfRequest(7));
1528
1529 // Make sure we test order of all requests made.
1530 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
1531}
1532
Andrew Top0d1858f2019-05-15 22:01:47 -07001533// Function to be used as a callback on socket request completion. It first
1534// disconnects the successfully connected socket from the first request, and
1535// then reuses the ClientSocketHandle to request another socket.
1536//
1537// |nested_callback| is called with the result of the second socket request.
1538void RequestSocketOnComplete(ClientSocketHandle* handle,
1539 TestClientSocketPool* pool,
1540 TestConnectJobFactory* test_connect_job_factory,
1541 TestConnectJob::JobType next_job_type,
1542 TestCompletionCallback* nested_callback,
1543 int first_request_result) {
1544 EXPECT_THAT(first_request_result, IsOk());
1545
1546 test_connect_job_factory->set_job_type(next_job_type);
1547
1548 // Don't allow reuse of the socket. Disconnect it and then release it.
1549 if (handle->socket())
1550 handle->socket()->Disconnect();
1551 handle->Reset();
1552
1553 scoped_refptr<TestSocketParams> params(new TestSocketParams());
1554 TestCompletionCallback callback;
1555 int rv = handle->Init("a", params, LOWEST, SocketTag(),
1556 ClientSocketPool::RespectLimits::ENABLED,
1557 nested_callback->callback(), pool, NetLogWithSource());
1558 if (rv != ERR_IO_PENDING) {
1559 DCHECK_EQ(TestConnectJob::kMockJob, next_job_type);
1560 nested_callback->callback().Run(rv);
1561 } else {
1562 DCHECK_EQ(TestConnectJob::kMockPendingJob, next_job_type);
David Ghandehari9e5b5872016-07-28 09:50:04 -07001563 }
Andrew Top0d1858f2019-05-15 22:01:47 -07001564}
David Ghandehari9e5b5872016-07-28 09:50:04 -07001565
Andrew Top0d1858f2019-05-15 22:01:47 -07001566// Tests the case where a second socket is requested in a completion callback,
1567// and the second socket connects asynchronously. Reuses the same
1568// ClientSocketHandle for the second socket, after disconnecting the first.
David Ghandehari9e5b5872016-07-28 09:50:04 -07001569TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
1570 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1571
1572 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1573 ClientSocketHandle handle;
Andrew Top0d1858f2019-05-15 22:01:47 -07001574 TestCompletionCallback second_result_callback;
1575 int rv = handle.Init(
1576 "a", params_, DEFAULT_PRIORITY, SocketTag(),
1577 ClientSocketPool::RespectLimits::ENABLED,
1578 base::Bind(&RequestSocketOnComplete, &handle, pool_.get(),
1579 connect_job_factory_, TestConnectJob::kMockPendingJob,
1580 &second_result_callback),
1581 pool_.get(), NetLogWithSource());
1582 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
David Ghandehari9e5b5872016-07-28 09:50:04 -07001583
Andrew Top0d1858f2019-05-15 22:01:47 -07001584 EXPECT_THAT(second_result_callback.WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07001585}
1586
Andrew Top0d1858f2019-05-15 22:01:47 -07001587// Tests the case where a second socket is requested in a completion callback,
1588// and the second socket connects synchronously. Reuses the same
1589// ClientSocketHandle for the second socket, after disconnecting the first.
David Ghandehari9e5b5872016-07-28 09:50:04 -07001590TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
1591 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1592
1593 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1594 ClientSocketHandle handle;
Andrew Top0d1858f2019-05-15 22:01:47 -07001595 TestCompletionCallback second_result_callback;
1596 int rv = handle.Init(
1597 "a", params_, DEFAULT_PRIORITY, SocketTag(),
1598 ClientSocketPool::RespectLimits::ENABLED,
1599 base::Bind(&RequestSocketOnComplete, &handle, pool_.get(),
1600 connect_job_factory_, TestConnectJob::kMockPendingJob,
1601 &second_result_callback),
1602 pool_.get(), NetLogWithSource());
1603 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
David Ghandehari9e5b5872016-07-28 09:50:04 -07001604
Andrew Top0d1858f2019-05-15 22:01:47 -07001605 EXPECT_THAT(second_result_callback.WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07001606}
1607
1608// Make sure that pending requests get serviced after active requests get
1609// cancelled.
1610TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
1611 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1612
1613 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1614
Andrew Top0d1858f2019-05-15 22:01:47 -07001615 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1616 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1617 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1618 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1619 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1620 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1621 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
David Ghandehari9e5b5872016-07-28 09:50:04 -07001622
1623 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1624 // Let's cancel them.
1625 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
1626 ASSERT_FALSE(request(i)->handle()->is_initialized());
1627 request(i)->handle()->Reset();
1628 }
1629
1630 // Let's wait for the rest to complete now.
1631 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
Andrew Top0d1858f2019-05-15 22:01:47 -07001632 EXPECT_THAT(request(i)->WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07001633 request(i)->handle()->Reset();
1634 }
1635
1636 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1637 completion_count());
1638}
1639
1640// Make sure that pending requests get serviced after active requests fail.
1641TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
1642 const size_t kMaxSockets = 5;
1643 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
1644
1645 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1646
1647 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1648 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
1649
1650 // Queue up all the requests
1651 for (size_t i = 0; i < kNumberOfRequests; ++i)
Andrew Top0d1858f2019-05-15 22:01:47 -07001652 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
David Ghandehari9e5b5872016-07-28 09:50:04 -07001653
1654 for (size_t i = 0; i < kNumberOfRequests; ++i)
Andrew Top0d1858f2019-05-15 22:01:47 -07001655 EXPECT_THAT(request(i)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
1656}
1657
1658// Make sure that pending requests that complete synchronously get serviced
1659// after active requests fail. See https://crbug.com/723748
1660TEST_F(ClientSocketPoolBaseTest, HandleMultipleSyncFailuresAfterAsyncFailure) {
1661 const size_t kNumberOfRequests = 10;
1662 const size_t kMaxSockets = 1;
1663 CreatePool(kMaxSockets, kMaxSockets);
1664
1665 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1666
1667 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1668
1669 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
1670
1671 // Queue up all the other requests
1672 for (size_t i = 1; i < kNumberOfRequests; ++i)
1673 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1674
1675 // Make sure all requests fail, instead of hanging.
1676 for (size_t i = 0; i < kNumberOfRequests; ++i)
1677 EXPECT_THAT(request(i)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
David Ghandehari9e5b5872016-07-28 09:50:04 -07001678}
1679
1680TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
1681 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1682
1683 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1684
1685 ClientSocketHandle handle;
1686 TestCompletionCallback callback;
Andrew Top0d1858f2019-05-15 22:01:47 -07001687 int rv = handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
1688 ClientSocketPool::RespectLimits::ENABLED,
1689 callback.callback(), pool_.get(), NetLogWithSource());
1690 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
David Ghandehari9e5b5872016-07-28 09:50:04 -07001691
1692 // Cancel the active request.
1693 handle.Reset();
1694
Andrew Top0d1858f2019-05-15 22:01:47 -07001695 rv = handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
1696 ClientSocketPool::RespectLimits::ENABLED,
1697 callback.callback(), pool_.get(), NetLogWithSource());
1698 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1699 EXPECT_THAT(callback.WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07001700
1701 EXPECT_FALSE(handle.is_reused());
Andrew Top0d1858f2019-05-15 22:01:47 -07001702 TestLoadTimingInfoConnectedNotReused(handle);
David Ghandehari9e5b5872016-07-28 09:50:04 -07001703 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1704}
1705
Andrew Top0d1858f2019-05-15 22:01:47 -07001706TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsForced) {
1707 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1708 ClientSocketHandle handle;
1709 TestCompletionCallback callback;
1710 BoundTestNetLog log;
1711 int rv = handle.Init("a", params_, LOWEST, SocketTag(),
1712 ClientSocketPool::RespectLimits::ENABLED,
1713 callback.callback(), pool_.get(), log.bound());
1714 EXPECT_THAT(rv, IsOk());
1715 handle.Reset();
1716 EXPECT_EQ(1, pool_->IdleSocketCount());
1717 pool_->CloseIdleSockets();
1718}
1719
1720TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsInGroupForced) {
1721 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1722 TestCompletionCallback callback;
1723 BoundTestNetLog log;
1724 ClientSocketHandle handle1;
1725 int rv = handle1.Init("a", params_, LOWEST, SocketTag(),
1726 ClientSocketPool::RespectLimits::ENABLED,
1727 callback.callback(), pool_.get(), log.bound());
1728 EXPECT_THAT(rv, IsOk());
1729 ClientSocketHandle handle2;
1730 rv = handle2.Init("a", params_, LOWEST, SocketTag(),
1731 ClientSocketPool::RespectLimits::ENABLED,
1732 callback.callback(), pool_.get(), log.bound());
1733 ClientSocketHandle handle3;
1734 rv = handle3.Init("b", params_, LOWEST, SocketTag(),
1735 ClientSocketPool::RespectLimits::ENABLED,
1736 callback.callback(), pool_.get(), log.bound());
1737 EXPECT_THAT(rv, IsOk());
1738 handle1.Reset();
1739 handle2.Reset();
1740 handle3.Reset();
1741 EXPECT_EQ(3, pool_->IdleSocketCount());
1742 pool_->CloseIdleSocketsInGroup("a");
1743 EXPECT_EQ(1, pool_->IdleSocketCount());
1744}
1745
1746TEST_F(ClientSocketPoolBaseTest, CleanUpUnusableIdleSockets) {
1747 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1748 ClientSocketHandle handle;
1749 TestCompletionCallback callback;
1750 BoundTestNetLog log;
1751 int rv = handle.Init("a", params_, LOWEST, SocketTag(),
1752 ClientSocketPool::RespectLimits::ENABLED,
1753 callback.callback(), pool_.get(), log.bound());
1754 EXPECT_THAT(rv, IsOk());
1755 StreamSocket* socket = handle.socket();
1756 handle.Reset();
1757 EXPECT_EQ(1, pool_->IdleSocketCount());
1758
1759 // Disconnect socket now to make the socket unusable.
1760 socket->Disconnect();
1761 ClientSocketHandle handle2;
1762 rv = handle2.Init("a", params_, LOWEST, SocketTag(),
1763 ClientSocketPool::RespectLimits::ENABLED,
1764 callback.callback(), pool_.get(), log.bound());
1765 EXPECT_THAT(rv, IsOk());
1766 EXPECT_FALSE(handle2.is_reused());
1767}
1768
David Ghandehari9e5b5872016-07-28 09:50:04 -07001769// Regression test for http://crbug.com/17985.
1770TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1771 const int kMaxSockets = 3;
1772 const int kMaxSocketsPerGroup = 2;
1773 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1774
1775 const RequestPriority kHighPriority = HIGHEST;
1776
Andrew Top0d1858f2019-05-15 22:01:47 -07001777 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
1778 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07001779
1780 // This is going to be a pending request in an otherwise empty group.
Andrew Top0d1858f2019-05-15 22:01:47 -07001781 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
David Ghandehari9e5b5872016-07-28 09:50:04 -07001782
1783 // Reach the maximum socket limit.
Andrew Top0d1858f2019-05-15 22:01:47 -07001784 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07001785
1786 // Create a stalled group with high priorities.
Andrew Top0d1858f2019-05-15 22:01:47 -07001787 EXPECT_THAT(StartRequest("c", kHighPriority), IsError(ERR_IO_PENDING));
1788 EXPECT_THAT(StartRequest("c", kHighPriority), IsError(ERR_IO_PENDING));
David Ghandehari9e5b5872016-07-28 09:50:04 -07001789
1790 // Release the first two sockets from "a". Because this is a keepalive,
1791 // the first release will unblock the pending request for "a". The
1792 // second release will unblock a request for "c", becaue it is the next
1793 // high priority socket.
1794 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1795 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1796
1797 // Closing idle sockets should not get us into trouble, but in the bug
1798 // we were hitting a CHECK here.
1799 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1800 pool_->CloseIdleSockets();
1801
Andrew Top0d1858f2019-05-15 22:01:47 -07001802 // Run the released socket wakeups.
1803 base::RunLoop().RunUntilIdle();
David Ghandehari9e5b5872016-07-28 09:50:04 -07001804}
1805
1806TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
1807 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1808
1809 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1810 ClientSocketHandle handle;
1811 TestCompletionCallback callback;
Andrew Top0d1858f2019-05-15 22:01:47 -07001812 BoundTestNetLog log;
1813 int rv = handle.Init("a", params_, LOWEST, SocketTag(),
1814 ClientSocketPool::RespectLimits::ENABLED,
1815 callback.callback(), pool_.get(), log.bound());
1816 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
David Ghandehari9e5b5872016-07-28 09:50:04 -07001817 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
Andrew Top0d1858f2019-05-15 22:01:47 -07001818 TestLoadTimingInfoNotConnected(handle);
1819
1820 EXPECT_THAT(callback.WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07001821 EXPECT_TRUE(handle.is_initialized());
1822 EXPECT_TRUE(handle.socket());
Andrew Top0d1858f2019-05-15 22:01:47 -07001823 TestLoadTimingInfoConnectedNotReused(handle);
David Ghandehari9e5b5872016-07-28 09:50:04 -07001824
Andrew Top0d1858f2019-05-15 22:01:47 -07001825 handle.Reset();
1826 TestLoadTimingInfoNotConnected(handle);
1827
1828 TestNetLogEntry::List entries;
David Ghandehari9e5b5872016-07-28 09:50:04 -07001829 log.GetEntries(&entries);
1830
1831 EXPECT_EQ(4u, entries.size());
Andrew Top0d1858f2019-05-15 22:01:47 -07001832 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKET_POOL));
David Ghandehari9e5b5872016-07-28 09:50:04 -07001833 EXPECT_TRUE(LogContainsEvent(
Andrew Top0d1858f2019-05-15 22:01:47 -07001834 entries, 1, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1835 NetLogEventPhase::NONE));
1836 EXPECT_TRUE(LogContainsEvent(entries, 2,
1837 NetLogEventType::SOCKET_POOL_BOUND_TO_SOCKET,
1838 NetLogEventPhase::NONE));
1839 EXPECT_TRUE(LogContainsEndEvent(entries, 3, NetLogEventType::SOCKET_POOL));
David Ghandehari9e5b5872016-07-28 09:50:04 -07001840}
1841
1842TEST_F(ClientSocketPoolBaseTest,
1843 InitConnectionAsynchronousFailure) {
1844 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1845
1846 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1847 ClientSocketHandle handle;
1848 TestCompletionCallback callback;
Andrew Top0d1858f2019-05-15 22:01:47 -07001849 BoundTestNetLog log;
David Ghandehari9e5b5872016-07-28 09:50:04 -07001850 // Set the additional error state members to ensure that they get cleared.
1851 handle.set_is_ssl_error(true);
1852 HttpResponseInfo info;
Andrew Top0d1858f2019-05-15 22:01:47 -07001853 info.headers = new HttpResponseHeaders(std::string());
David Ghandehari9e5b5872016-07-28 09:50:04 -07001854 handle.set_ssl_error_response_info(info);
Andrew Top0d1858f2019-05-15 22:01:47 -07001855 EXPECT_EQ(ERR_IO_PENDING,
1856 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
1857 ClientSocketPool::RespectLimits::ENABLED,
1858 callback.callback(), pool_.get(), log.bound()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07001859 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
Andrew Top0d1858f2019-05-15 22:01:47 -07001860 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
David Ghandehari9e5b5872016-07-28 09:50:04 -07001861 EXPECT_FALSE(handle.is_ssl_error());
1862 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
1863
Andrew Top0d1858f2019-05-15 22:01:47 -07001864 TestNetLogEntry::List entries;
David Ghandehari9e5b5872016-07-28 09:50:04 -07001865 log.GetEntries(&entries);
1866
1867 EXPECT_EQ(3u, entries.size());
Andrew Top0d1858f2019-05-15 22:01:47 -07001868 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKET_POOL));
David Ghandehari9e5b5872016-07-28 09:50:04 -07001869 EXPECT_TRUE(LogContainsEvent(
Andrew Top0d1858f2019-05-15 22:01:47 -07001870 entries, 1, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1871 NetLogEventPhase::NONE));
1872 EXPECT_TRUE(LogContainsEndEvent(entries, 2, NetLogEventType::SOCKET_POOL));
1873}
1874
1875// Check that an async ConnectJob failure does not result in creation of a new
1876// ConnectJob when there's another pending request also waiting on its own
1877// ConnectJob. See http://crbug.com/463960.
1878TEST_F(ClientSocketPoolBaseTest, AsyncFailureWithPendingRequestWithJob) {
1879 CreatePool(2, 2);
1880 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1881
1882 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1883 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
1884
1885 EXPECT_THAT(request(0)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
1886 EXPECT_THAT(request(1)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
1887
1888 EXPECT_EQ(2, client_socket_factory_.allocation_count());
David Ghandehari9e5b5872016-07-28 09:50:04 -07001889}
1890
1891TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
1892 // TODO(eroman): Add back the log expectations! Removed them because the
1893 // ordering is difficult, and some may fire during destructor.
1894 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1895
1896 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1897 ClientSocketHandle handle;
1898 TestCompletionCallback callback;
1899 ClientSocketHandle handle2;
1900 TestCompletionCallback callback2;
1901
1902 EXPECT_EQ(ERR_IO_PENDING,
Andrew Top0d1858f2019-05-15 22:01:47 -07001903 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
1904 ClientSocketPool::RespectLimits::ENABLED,
1905 callback.callback(), pool_.get(), NetLogWithSource()));
1906 BoundTestNetLog log2;
1907 EXPECT_EQ(
1908 ERR_IO_PENDING,
1909 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
1910 ClientSocketPool::RespectLimits::ENABLED,
1911 callback2.callback(), pool_.get(), NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07001912
1913 handle.Reset();
1914
1915
1916 // At this point, request 2 is just waiting for the connect job to finish.
1917
Andrew Top0d1858f2019-05-15 22:01:47 -07001918 EXPECT_THAT(callback2.WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07001919 handle2.Reset();
1920
1921 // Now request 2 has actually finished.
1922 // TODO(eroman): Add back log expectations.
1923}
1924
1925TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
1926 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1927
1928 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1929
Andrew Top0d1858f2019-05-15 22:01:47 -07001930 EXPECT_THAT(StartRequest("a", LOWEST), IsError(ERR_IO_PENDING));
1931 EXPECT_THAT(StartRequest("a", LOW), IsError(ERR_IO_PENDING));
1932 EXPECT_THAT(StartRequest("a", MEDIUM), IsError(ERR_IO_PENDING));
1933 EXPECT_THAT(StartRequest("a", HIGHEST), IsError(ERR_IO_PENDING));
David Ghandehari9e5b5872016-07-28 09:50:04 -07001934
1935 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1936 (*requests())[2]->handle()->Reset();
1937 (*requests())[3]->handle()->Reset();
1938 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1939
1940 (*requests())[1]->handle()->Reset();
1941 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1942
1943 (*requests())[0]->handle()->Reset();
1944 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1945}
1946
1947// When requests and ConnectJobs are not coupled, the request will get serviced
1948// by whatever comes first.
1949TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
1950 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1951
1952 // Start job 1 (async OK)
1953 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1954
1955 std::vector<TestSocketRequest*> request_order;
1956 size_t completion_count; // unused
1957 TestSocketRequest req1(&request_order, &completion_count);
Andrew Top0d1858f2019-05-15 22:01:47 -07001958 int rv =
1959 req1.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
1960 ClientSocketPool::RespectLimits::ENABLED,
1961 req1.callback(), pool_.get(), NetLogWithSource());
1962 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1963 EXPECT_THAT(req1.WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07001964
1965 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1966 // without a job.
1967 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1968
1969 TestSocketRequest req2(&request_order, &completion_count);
Andrew Top0d1858f2019-05-15 22:01:47 -07001970 rv = req2.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
1971 ClientSocketPool::RespectLimits::ENABLED,
1972 req2.callback(), pool_.get(), NetLogWithSource());
1973 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
David Ghandehari9e5b5872016-07-28 09:50:04 -07001974 TestSocketRequest req3(&request_order, &completion_count);
Andrew Top0d1858f2019-05-15 22:01:47 -07001975 rv = req3.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
1976 ClientSocketPool::RespectLimits::ENABLED,
1977 req3.callback(), pool_.get(), NetLogWithSource());
1978 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
David Ghandehari9e5b5872016-07-28 09:50:04 -07001979
1980 // Both Requests 2 and 3 are pending. We release socket 1 which should
1981 // service request 2. Request 3 should still be waiting.
1982 req1.handle()->Reset();
Andrew Top0d1858f2019-05-15 22:01:47 -07001983 // Run the released socket wakeups.
1984 base::RunLoop().RunUntilIdle();
David Ghandehari9e5b5872016-07-28 09:50:04 -07001985 ASSERT_TRUE(req2.handle()->socket());
Andrew Top0d1858f2019-05-15 22:01:47 -07001986 EXPECT_THAT(req2.WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07001987 EXPECT_FALSE(req3.handle()->socket());
1988
1989 // Signal job 2, which should service request 3.
1990
1991 client_socket_factory_.SignalJobs();
Andrew Top0d1858f2019-05-15 22:01:47 -07001992 EXPECT_THAT(req3.WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07001993
1994 ASSERT_EQ(3U, request_order.size());
1995 EXPECT_EQ(&req1, request_order[0]);
1996 EXPECT_EQ(&req2, request_order[1]);
1997 EXPECT_EQ(&req3, request_order[2]);
1998 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1999}
2000
2001// The requests are not coupled to the jobs. So, the requests should finish in
2002// their priority / insertion order.
2003TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
2004 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2005 // First two jobs are async.
2006 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2007
2008 std::vector<TestSocketRequest*> request_order;
2009 size_t completion_count; // unused
2010 TestSocketRequest req1(&request_order, &completion_count);
Andrew Top0d1858f2019-05-15 22:01:47 -07002011 int rv =
2012 req1.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2013 ClientSocketPool::RespectLimits::ENABLED,
2014 req1.callback(), pool_.get(), NetLogWithSource());
2015 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
David Ghandehari9e5b5872016-07-28 09:50:04 -07002016
2017 TestSocketRequest req2(&request_order, &completion_count);
Andrew Top0d1858f2019-05-15 22:01:47 -07002018 rv = req2.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2019 ClientSocketPool::RespectLimits::ENABLED,
2020 req2.callback(), pool_.get(), NetLogWithSource());
2021 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
David Ghandehari9e5b5872016-07-28 09:50:04 -07002022
2023 // The pending job is sync.
2024 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2025
2026 TestSocketRequest req3(&request_order, &completion_count);
Andrew Top0d1858f2019-05-15 22:01:47 -07002027 rv = req3.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2028 ClientSocketPool::RespectLimits::ENABLED,
2029 req3.callback(), pool_.get(), NetLogWithSource());
2030 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
David Ghandehari9e5b5872016-07-28 09:50:04 -07002031
Andrew Top0d1858f2019-05-15 22:01:47 -07002032 EXPECT_THAT(req1.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
2033 EXPECT_THAT(req2.WaitForResult(), IsOk());
2034 EXPECT_THAT(req3.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
David Ghandehari9e5b5872016-07-28 09:50:04 -07002035
2036 ASSERT_EQ(3U, request_order.size());
2037 EXPECT_EQ(&req1, request_order[0]);
2038 EXPECT_EQ(&req2, request_order[1]);
2039 EXPECT_EQ(&req3, request_order[2]);
2040}
2041
Andrew Top0d1858f2019-05-15 22:01:47 -07002042// Test GetLoadState in the case there's only one socket request.
2043TEST_F(ClientSocketPoolBaseTest, LoadStateOneRequest) {
David Ghandehari9e5b5872016-07-28 09:50:04 -07002044 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
Andrew Top0d1858f2019-05-15 22:01:47 -07002045 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
David Ghandehari9e5b5872016-07-28 09:50:04 -07002046
2047 ClientSocketHandle handle;
2048 TestCompletionCallback callback;
Andrew Top0d1858f2019-05-15 22:01:47 -07002049 int rv = handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2050 ClientSocketPool::RespectLimits::ENABLED,
2051 callback.callback(), pool_.get(), NetLogWithSource());
2052 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2053 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
David Ghandehari9e5b5872016-07-28 09:50:04 -07002054
Andrew Top0d1858f2019-05-15 22:01:47 -07002055 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2056 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
2057
2058 // No point in completing the connection, since ClientSocketHandles only
2059 // expect the LoadState to be checked while connecting.
2060}
2061
2062// Test GetLoadState in the case there are two socket requests.
2063// Only the first connection in the pool should affect the pool's load status.
2064TEST_F(ClientSocketPoolBaseTest, LoadStateTwoRequests) {
2065 CreatePool(2, 2);
2066 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2067
2068 ClientSocketHandle handle;
2069 TestCompletionCallback callback;
2070 int rv = handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2071 ClientSocketPool::RespectLimits::ENABLED,
2072 callback.callback(), pool_.get(), NetLogWithSource());
2073 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2074 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
David Ghandehari9e5b5872016-07-28 09:50:04 -07002075
2076 ClientSocketHandle handle2;
2077 TestCompletionCallback callback2;
Andrew Top0d1858f2019-05-15 22:01:47 -07002078 rv = handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2079 ClientSocketPool::RespectLimits::ENABLED,
2080 callback2.callback(), pool_.get(), NetLogWithSource());
2081 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2082 client_socket_factory_.SetJobLoadState(1, LOAD_STATE_RESOLVING_HOST);
2083
2084 // Check that both handles report the state of the first job.
2085 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle.GetLoadState());
2086 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle2.GetLoadState());
2087
2088 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_CONNECTING);
2089
2090 // Check that both handles change to LOAD_STATE_CONNECTING.
2091 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2092 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
2093}
2094
2095// Test that the second connection request does not affect the pool's load
2096// status.
2097TEST_F(ClientSocketPoolBaseTest, LoadStateTwoRequestsChangeSecondRequestState) {
2098 CreatePool(2, 2);
2099 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2100
2101 ClientSocketHandle handle;
2102 TestCompletionCallback callback;
2103 int rv = handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2104 ClientSocketPool::RespectLimits::ENABLED,
2105 callback.callback(), pool_.get(), NetLogWithSource());
2106 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2107
2108 ClientSocketHandle handle2;
2109 TestCompletionCallback callback2;
2110 rv = handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2111 ClientSocketPool::RespectLimits::ENABLED,
2112 callback2.callback(), pool_.get(), NetLogWithSource());
2113 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2114 client_socket_factory_.SetJobLoadState(1, LOAD_STATE_RESOLVING_HOST);
2115
2116 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2117 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
2118
2119 // First job connects and the first request gets the socket. The
2120 // second handle switches to the state of the remaining ConnectJob.
2121 client_socket_factory_.SignalJob(0);
2122 EXPECT_THAT(callback.WaitForResult(), IsOk());
2123 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle2.GetLoadState());
2124}
2125
2126// Test GetLoadState in the case the per-group limit is reached.
2127TEST_F(ClientSocketPoolBaseTest, LoadStateGroupLimit) {
2128 CreatePool(2, 1);
2129 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2130
2131 ClientSocketHandle handle;
2132 TestCompletionCallback callback;
2133 int rv = handle.Init("a", params_, MEDIUM, SocketTag(),
2134 ClientSocketPool::RespectLimits::ENABLED,
2135 callback.callback(), pool_.get(), NetLogWithSource());
2136 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2137 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2138
2139 // Request another socket from the same pool, buth with a higher priority.
2140 // The first request should now be stalled at the socket group limit.
2141 ClientSocketHandle handle2;
2142 TestCompletionCallback callback2;
2143 rv = handle2.Init("a", params_, HIGHEST, SocketTag(),
2144 ClientSocketPool::RespectLimits::ENABLED,
2145 callback2.callback(), pool_.get(), NetLogWithSource());
2146 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2147 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2148 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
2149
2150 // The first handle should remain stalled as the other socket goes through
2151 // the connect process.
2152
2153 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2154 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2155 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle2.GetLoadState());
2156
2157 client_socket_factory_.SignalJob(0);
2158 EXPECT_THAT(callback2.WaitForResult(), IsOk());
2159 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2160
2161 // Closing the second socket should cause the stalled handle to finally get a
2162 // ConnectJob.
2163 handle2.socket()->Disconnect();
2164 handle2.Reset();
2165 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2166}
2167
2168// Test GetLoadState in the case the per-pool limit is reached.
2169TEST_F(ClientSocketPoolBaseTest, LoadStatePoolLimit) {
2170 CreatePool(2, 2);
2171 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2172
2173 ClientSocketHandle handle;
2174 TestCompletionCallback callback;
2175 int rv = handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2176 ClientSocketPool::RespectLimits::ENABLED,
2177 callback.callback(), pool_.get(), NetLogWithSource());
2178 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2179
2180 // Request for socket from another pool.
2181 ClientSocketHandle handle2;
2182 TestCompletionCallback callback2;
2183 rv = handle2.Init("b", params_, DEFAULT_PRIORITY, SocketTag(),
2184 ClientSocketPool::RespectLimits::ENABLED,
2185 callback2.callback(), pool_.get(), NetLogWithSource());
2186 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2187
2188 // Request another socket from the first pool. Request should stall at the
2189 // socket pool limit.
2190 ClientSocketHandle handle3;
2191 TestCompletionCallback callback3;
2192 rv = handle3.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2193 ClientSocketPool::RespectLimits::ENABLED,
2194 callback2.callback(), pool_.get(), NetLogWithSource());
2195 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2196
2197 // The third handle should remain stalled as the other sockets in its group
2198 // goes through the connect process.
2199
2200 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2201 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2202
2203 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2204 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
2205 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2206
2207 client_socket_factory_.SignalJob(0);
2208 EXPECT_THAT(callback.WaitForResult(), IsOk());
2209 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2210
2211 // Closing a socket should allow the stalled handle to finally get a new
2212 // ConnectJob.
2213 handle.socket()->Disconnect();
2214 handle.Reset();
2215 EXPECT_EQ(LOAD_STATE_CONNECTING, handle3.GetLoadState());
David Ghandehari9e5b5872016-07-28 09:50:04 -07002216}
2217
2218TEST_F(ClientSocketPoolBaseTest, Recoverable) {
2219 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2220 connect_job_factory_->set_job_type(TestConnectJob::kMockRecoverableJob);
2221
2222 ClientSocketHandle handle;
2223 TestCompletionCallback callback;
2224 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED,
Andrew Top0d1858f2019-05-15 22:01:47 -07002225 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2226 ClientSocketPool::RespectLimits::ENABLED,
2227 callback.callback(), pool_.get(), NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07002228 EXPECT_TRUE(handle.is_initialized());
2229 EXPECT_TRUE(handle.socket());
2230}
2231
2232TEST_F(ClientSocketPoolBaseTest, AsyncRecoverable) {
2233 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2234
2235 connect_job_factory_->set_job_type(
2236 TestConnectJob::kMockPendingRecoverableJob);
2237 ClientSocketHandle handle;
2238 TestCompletionCallback callback;
2239 EXPECT_EQ(ERR_IO_PENDING,
Andrew Top0d1858f2019-05-15 22:01:47 -07002240 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2241 ClientSocketPool::RespectLimits::ENABLED,
2242 callback.callback(), pool_.get(), NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07002243 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
Andrew Top0d1858f2019-05-15 22:01:47 -07002244 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_PROXY_AUTH_REQUESTED));
David Ghandehari9e5b5872016-07-28 09:50:04 -07002245 EXPECT_TRUE(handle.is_initialized());
2246 EXPECT_TRUE(handle.socket());
2247}
2248
2249TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
2250 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2251 connect_job_factory_->set_job_type(
2252 TestConnectJob::kMockAdditionalErrorStateJob);
2253
2254 ClientSocketHandle handle;
2255 TestCompletionCallback callback;
2256 EXPECT_EQ(ERR_CONNECTION_FAILED,
Andrew Top0d1858f2019-05-15 22:01:47 -07002257 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2258 ClientSocketPool::RespectLimits::ENABLED,
2259 callback.callback(), pool_.get(), NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07002260 EXPECT_FALSE(handle.is_initialized());
2261 EXPECT_FALSE(handle.socket());
2262 EXPECT_TRUE(handle.is_ssl_error());
2263 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
2264}
2265
2266TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
2267 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2268
2269 connect_job_factory_->set_job_type(
2270 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2271 ClientSocketHandle handle;
2272 TestCompletionCallback callback;
2273 EXPECT_EQ(ERR_IO_PENDING,
Andrew Top0d1858f2019-05-15 22:01:47 -07002274 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2275 ClientSocketPool::RespectLimits::ENABLED,
2276 callback.callback(), pool_.get(), NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07002277 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
Andrew Top0d1858f2019-05-15 22:01:47 -07002278 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
David Ghandehari9e5b5872016-07-28 09:50:04 -07002279 EXPECT_FALSE(handle.is_initialized());
2280 EXPECT_FALSE(handle.socket());
2281 EXPECT_TRUE(handle.is_ssl_error());
2282 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
2283}
2284
Andrew Top0d1858f2019-05-15 22:01:47 -07002285// Make sure we can reuse sockets.
2286TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSocketsReuse) {
David Ghandehari9e5b5872016-07-28 09:50:04 -07002287 CreatePoolWithIdleTimeouts(
2288 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2289 base::TimeDelta(), // Time out unused sockets immediately.
2290 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2291
2292 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2293
2294 ClientSocketHandle handle;
2295 TestCompletionCallback callback;
Andrew Top0d1858f2019-05-15 22:01:47 -07002296 int rv = handle.Init("a", params_, LOWEST, SocketTag(),
2297 ClientSocketPool::RespectLimits::ENABLED,
2298 callback.callback(), pool_.get(), NetLogWithSource());
2299 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
David Ghandehari9e5b5872016-07-28 09:50:04 -07002300 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
Andrew Top0d1858f2019-05-15 22:01:47 -07002301 ASSERT_THAT(callback.WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07002302
2303 // Use and release the socket.
Andrew Top0d1858f2019-05-15 22:01:47 -07002304 EXPECT_EQ(1, handle.socket()->Write(NULL, 1, CompletionOnceCallback(),
2305 TRAFFIC_ANNOTATION_FOR_TESTS));
2306 TestLoadTimingInfoConnectedNotReused(handle);
David Ghandehari9e5b5872016-07-28 09:50:04 -07002307 handle.Reset();
2308
2309 // Should now have one idle socket.
2310 ASSERT_EQ(1, pool_->IdleSocketCount());
2311
2312 // Request a new socket. This should reuse the old socket and complete
2313 // synchronously.
Andrew Top0d1858f2019-05-15 22:01:47 -07002314 BoundTestNetLog log;
2315 rv = handle.Init("a", params_, LOWEST, SocketTag(),
2316 ClientSocketPool::RespectLimits::ENABLED,
2317 CompletionOnceCallback(), pool_.get(), log.bound());
2318 ASSERT_THAT(rv, IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07002319 EXPECT_TRUE(handle.is_reused());
Andrew Top0d1858f2019-05-15 22:01:47 -07002320 TestLoadTimingInfoConnectedReused(handle);
David Ghandehari9e5b5872016-07-28 09:50:04 -07002321
2322 ASSERT_TRUE(pool_->HasGroup("a"));
2323 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2324 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2325
Andrew Top0d1858f2019-05-15 22:01:47 -07002326 TestNetLogEntry::List entries;
David Ghandehari9e5b5872016-07-28 09:50:04 -07002327 log.GetEntries(&entries);
2328 EXPECT_TRUE(LogContainsEntryWithType(
Andrew Top0d1858f2019-05-15 22:01:47 -07002329 entries, 1, NetLogEventType::SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
David Ghandehari9e5b5872016-07-28 09:50:04 -07002330}
2331
Andrew Top0d1858f2019-05-15 22:01:47 -07002332// Make sure we cleanup old unused sockets.
2333TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSocketsNoReuse) {
David Ghandehari9e5b5872016-07-28 09:50:04 -07002334 CreatePoolWithIdleTimeouts(
2335 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2336 base::TimeDelta(), // Time out unused sockets immediately
2337 base::TimeDelta()); // Time out used sockets immediately
2338
2339 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2340
2341 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2342
2343 ClientSocketHandle handle;
2344 TestCompletionCallback callback;
Andrew Top0d1858f2019-05-15 22:01:47 -07002345 int rv = handle.Init("a", params_, LOWEST, SocketTag(),
2346 ClientSocketPool::RespectLimits::ENABLED,
2347 callback.callback(), pool_.get(), NetLogWithSource());
2348 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
David Ghandehari9e5b5872016-07-28 09:50:04 -07002349 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2350
2351 ClientSocketHandle handle2;
2352 TestCompletionCallback callback2;
Andrew Top0d1858f2019-05-15 22:01:47 -07002353 rv = handle2.Init("a", params_, LOWEST, SocketTag(),
2354 ClientSocketPool::RespectLimits::ENABLED,
2355 callback2.callback(), pool_.get(), NetLogWithSource());
2356 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
David Ghandehari9e5b5872016-07-28 09:50:04 -07002357 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
2358
2359 // Cancel one of the requests. Wait for the other, which will get the first
2360 // job. Release the socket. Run the loop again to make sure the second
2361 // socket is sitting idle and the first one is released (since ReleaseSocket()
2362 // just posts a DoReleaseSocket() task).
2363
2364 handle.Reset();
Andrew Top0d1858f2019-05-15 22:01:47 -07002365 ASSERT_THAT(callback2.WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07002366 // Use the socket.
Andrew Top0d1858f2019-05-15 22:01:47 -07002367 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, CompletionOnceCallback(),
2368 TRAFFIC_ANNOTATION_FOR_TESTS));
David Ghandehari9e5b5872016-07-28 09:50:04 -07002369 handle2.Reset();
2370
2371 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2372 // actually become pending until 2ms after they have been created. In order
2373 // to flush all tasks, we need to wait so that we know there are no
2374 // soon-to-be-pending tasks waiting.
2375 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
Andrew Top0d1858f2019-05-15 22:01:47 -07002376 base::RunLoop().RunUntilIdle();
David Ghandehari9e5b5872016-07-28 09:50:04 -07002377
2378 // Both sockets should now be idle.
2379 ASSERT_EQ(2, pool_->IdleSocketCount());
2380
2381 // Request a new socket. This should cleanup the unused and timed out ones.
2382 // A new socket will be created rather than reusing the idle one.
Andrew Top0d1858f2019-05-15 22:01:47 -07002383 BoundTestNetLog log;
David Ghandehari9e5b5872016-07-28 09:50:04 -07002384 TestCompletionCallback callback3;
Andrew Top0d1858f2019-05-15 22:01:47 -07002385 rv = handle.Init("a", params_, LOWEST, SocketTag(),
2386 ClientSocketPool::RespectLimits::ENABLED,
2387 callback3.callback(), pool_.get(), log.bound());
2388 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
2389 ASSERT_THAT(callback3.WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07002390 EXPECT_FALSE(handle.is_reused());
2391
2392 // Make sure the idle socket is closed.
2393 ASSERT_TRUE(pool_->HasGroup("a"));
2394 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2395 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2396
Andrew Top0d1858f2019-05-15 22:01:47 -07002397 TestNetLogEntry::List entries;
David Ghandehari9e5b5872016-07-28 09:50:04 -07002398 log.GetEntries(&entries);
2399 EXPECT_FALSE(LogContainsEntryWithType(
Andrew Top0d1858f2019-05-15 22:01:47 -07002400 entries, 1, NetLogEventType::SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
David Ghandehari9e5b5872016-07-28 09:50:04 -07002401}
2402
2403// Make sure that we process all pending requests even when we're stalling
2404// because of multiple releasing disconnected sockets.
2405TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
2406 CreatePoolWithIdleTimeouts(
2407 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2408 base::TimeDelta(), // Time out unused sockets immediately.
2409 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2410
2411 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2412
2413 // Startup 4 connect jobs. Two of them will be pending.
2414
2415 ClientSocketHandle handle;
2416 TestCompletionCallback callback;
Andrew Top0d1858f2019-05-15 22:01:47 -07002417 int rv = handle.Init("a", params_, LOWEST, SocketTag(),
2418 ClientSocketPool::RespectLimits::ENABLED,
2419 callback.callback(), pool_.get(), NetLogWithSource());
2420 EXPECT_THAT(rv, IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07002421
2422 ClientSocketHandle handle2;
2423 TestCompletionCallback callback2;
Andrew Top0d1858f2019-05-15 22:01:47 -07002424 rv = handle2.Init("a", params_, LOWEST, SocketTag(),
2425 ClientSocketPool::RespectLimits::ENABLED,
2426 callback2.callback(), pool_.get(), NetLogWithSource());
2427 EXPECT_THAT(rv, IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07002428
2429 ClientSocketHandle handle3;
2430 TestCompletionCallback callback3;
Andrew Top0d1858f2019-05-15 22:01:47 -07002431 rv = handle3.Init("a", params_, LOWEST, SocketTag(),
2432 ClientSocketPool::RespectLimits::ENABLED,
2433 callback3.callback(), pool_.get(), NetLogWithSource());
2434 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
David Ghandehari9e5b5872016-07-28 09:50:04 -07002435
2436 ClientSocketHandle handle4;
2437 TestCompletionCallback callback4;
Andrew Top0d1858f2019-05-15 22:01:47 -07002438 rv = handle4.Init("a", params_, LOWEST, SocketTag(),
2439 ClientSocketPool::RespectLimits::ENABLED,
2440 callback4.callback(), pool_.get(), NetLogWithSource());
2441 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
David Ghandehari9e5b5872016-07-28 09:50:04 -07002442
2443 // Release two disconnected sockets.
2444
2445 handle.socket()->Disconnect();
2446 handle.Reset();
2447 handle2.socket()->Disconnect();
2448 handle2.Reset();
2449
Andrew Top0d1858f2019-05-15 22:01:47 -07002450 EXPECT_THAT(callback3.WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07002451 EXPECT_FALSE(handle3.is_reused());
Andrew Top0d1858f2019-05-15 22:01:47 -07002452 EXPECT_THAT(callback4.WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07002453 EXPECT_FALSE(handle4.is_reused());
2454}
2455
2456// Regression test for http://crbug.com/42267.
2457// When DoReleaseSocket() is processed for one socket, it is blocked because the
2458// other stalled groups all have releasing sockets, so no progress can be made.
2459TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
2460 CreatePoolWithIdleTimeouts(
2461 4 /* socket limit */, 4 /* socket limit per group */,
2462 base::TimeDelta(), // Time out unused sockets immediately.
2463 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2464
2465 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2466
2467 // Max out the socket limit with 2 per group.
2468
2469 ClientSocketHandle handle_a[4];
2470 TestCompletionCallback callback_a[4];
2471 ClientSocketHandle handle_b[4];
2472 TestCompletionCallback callback_b[4];
2473
2474 for (int i = 0; i < 2; ++i) {
Andrew Top0d1858f2019-05-15 22:01:47 -07002475 EXPECT_EQ(OK, handle_a[i].Init("a", params_, LOWEST, SocketTag(),
2476 ClientSocketPool::RespectLimits::ENABLED,
2477 callback_a[i].callback(), pool_.get(),
2478 NetLogWithSource()));
2479 EXPECT_EQ(OK, handle_b[i].Init("b", params_, LOWEST, SocketTag(),
2480 ClientSocketPool::RespectLimits::ENABLED,
2481 callback_b[i].callback(), pool_.get(),
2482 NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07002483 }
2484
2485 // Make 4 pending requests, 2 per group.
2486
2487 for (int i = 2; i < 4; ++i) {
2488 EXPECT_EQ(ERR_IO_PENDING,
Andrew Top0d1858f2019-05-15 22:01:47 -07002489 handle_a[i].Init("a", params_, LOWEST, SocketTag(),
2490 ClientSocketPool::RespectLimits::ENABLED,
2491 callback_a[i].callback(), pool_.get(),
2492 NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07002493 EXPECT_EQ(ERR_IO_PENDING,
Andrew Top0d1858f2019-05-15 22:01:47 -07002494 handle_b[i].Init("b", params_, LOWEST, SocketTag(),
2495 ClientSocketPool::RespectLimits::ENABLED,
2496 callback_b[i].callback(), pool_.get(),
2497 NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07002498 }
2499
2500 // Release b's socket first. The order is important, because in
2501 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2502 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2503 // first, which has a releasing socket, so it refuses to start up another
2504 // ConnectJob. So, we used to infinite loop on this.
2505 handle_b[0].socket()->Disconnect();
2506 handle_b[0].Reset();
2507 handle_a[0].socket()->Disconnect();
2508 handle_a[0].Reset();
2509
2510 // Used to get stuck here.
Andrew Top0d1858f2019-05-15 22:01:47 -07002511 base::RunLoop().RunUntilIdle();
David Ghandehari9e5b5872016-07-28 09:50:04 -07002512
2513 handle_b[1].socket()->Disconnect();
2514 handle_b[1].Reset();
2515 handle_a[1].socket()->Disconnect();
2516 handle_a[1].Reset();
2517
2518 for (int i = 2; i < 4; ++i) {
Andrew Top0d1858f2019-05-15 22:01:47 -07002519 EXPECT_THAT(callback_b[i].WaitForResult(), IsOk());
2520 EXPECT_THAT(callback_a[i].WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07002521 }
2522}
2523
2524TEST_F(ClientSocketPoolBaseTest,
2525 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2526 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2527
2528 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2529
Andrew Top0d1858f2019-05-15 22:01:47 -07002530 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
2531 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
2532 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
2533 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsError(ERR_IO_PENDING));
David Ghandehari9e5b5872016-07-28 09:50:04 -07002534
Andrew Top0d1858f2019-05-15 22:01:47 -07002535 EXPECT_THAT((*requests())[0]->WaitForResult(), IsOk());
2536 EXPECT_THAT((*requests())[1]->WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07002537 EXPECT_EQ(2u, completion_count());
2538
2539 // Releases one connection.
2540 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
Andrew Top0d1858f2019-05-15 22:01:47 -07002541 EXPECT_THAT((*requests())[2]->WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07002542
2543 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
Andrew Top0d1858f2019-05-15 22:01:47 -07002544 EXPECT_THAT((*requests())[3]->WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07002545 EXPECT_EQ(4u, completion_count());
2546
2547 EXPECT_EQ(1, GetOrderOfRequest(1));
2548 EXPECT_EQ(2, GetOrderOfRequest(2));
2549 EXPECT_EQ(3, GetOrderOfRequest(3));
2550 EXPECT_EQ(4, GetOrderOfRequest(4));
2551
2552 // Make sure we test order of all requests made.
2553 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
2554}
2555
2556class TestReleasingSocketRequest : public TestCompletionCallbackBase {
2557 public:
2558 TestReleasingSocketRequest(TestClientSocketPool* pool,
2559 int expected_result,
2560 bool reset_releasing_handle)
2561 : pool_(pool),
2562 expected_result_(expected_result),
Andrew Top0d1858f2019-05-15 22:01:47 -07002563 reset_releasing_handle_(reset_releasing_handle) {}
David Ghandehari9e5b5872016-07-28 09:50:04 -07002564
Andrew Top0d1858f2019-05-15 22:01:47 -07002565 ~TestReleasingSocketRequest() override = default;
David Ghandehari9e5b5872016-07-28 09:50:04 -07002566
2567 ClientSocketHandle* handle() { return &handle_; }
2568
Andrew Top0d1858f2019-05-15 22:01:47 -07002569 CompletionOnceCallback callback() {
2570 return base::BindOnce(&TestReleasingSocketRequest::OnComplete,
2571 base::Unretained(this));
2572 }
David Ghandehari9e5b5872016-07-28 09:50:04 -07002573
2574 private:
2575 void OnComplete(int result) {
2576 SetResult(result);
2577 if (reset_releasing_handle_)
2578 handle_.Reset();
2579
2580 scoped_refptr<TestSocketParams> con_params(new TestSocketParams());
Andrew Top0d1858f2019-05-15 22:01:47 -07002581 EXPECT_EQ(
2582 expected_result_,
2583 handle2_.Init("a", con_params, DEFAULT_PRIORITY, SocketTag(),
2584 ClientSocketPool::RespectLimits::ENABLED,
2585 CompletionOnceCallback(), pool_, NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07002586 }
2587
2588 TestClientSocketPool* const pool_;
2589 int expected_result_;
2590 bool reset_releasing_handle_;
2591 ClientSocketHandle handle_;
2592 ClientSocketHandle handle2_;
David Ghandehari9e5b5872016-07-28 09:50:04 -07002593};
2594
2595
2596TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2597 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2598
Andrew Top0d1858f2019-05-15 22:01:47 -07002599 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
2600 EXPECT_THAT(StartRequest("a", DEFAULT_PRIORITY), IsOk());
2601 EXPECT_THAT(StartRequest("b", DEFAULT_PRIORITY), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07002602
2603 EXPECT_EQ(static_cast<int>(requests_size()),
2604 client_socket_factory_.allocation_count());
2605
2606 connect_job_factory_->set_job_type(
2607 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2608 TestReleasingSocketRequest req(pool_.get(), OK, false);
Andrew Top0d1858f2019-05-15 22:01:47 -07002609 EXPECT_EQ(
2610 ERR_IO_PENDING,
2611 req.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2612 ClientSocketPool::RespectLimits::ENABLED,
2613 req.callback(), pool_.get(), NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07002614 // The next job should complete synchronously
2615 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2616
Andrew Top0d1858f2019-05-15 22:01:47 -07002617 EXPECT_THAT(req.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
David Ghandehari9e5b5872016-07-28 09:50:04 -07002618 EXPECT_FALSE(req.handle()->is_initialized());
2619 EXPECT_FALSE(req.handle()->socket());
2620 EXPECT_TRUE(req.handle()->is_ssl_error());
2621 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
2622}
2623
2624// http://crbug.com/44724 regression test.
2625// We start releasing the pool when we flush on network change. When that
2626// happens, the only active references are in the ClientSocketHandles. When a
2627// ConnectJob completes and calls back into the last ClientSocketHandle, that
2628// callback can release the last reference and delete the pool. After the
2629// callback finishes, we go back to the stack frame within the now-deleted pool.
2630// Executing any code that refers to members of the now-deleted pool can cause
2631// crashes.
2632TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2633 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2634 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2635
2636 ClientSocketHandle handle;
2637 TestCompletionCallback callback;
Andrew Top0d1858f2019-05-15 22:01:47 -07002638 EXPECT_EQ(ERR_IO_PENDING,
2639 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2640 ClientSocketPool::RespectLimits::ENABLED,
2641 callback.callback(), pool_.get(), NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07002642
2643 pool_->FlushWithError(ERR_NETWORK_CHANGED);
2644
2645 // We'll call back into this now.
2646 callback.WaitForResult();
2647}
2648
2649TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2650 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2651 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2652
2653 ClientSocketHandle handle;
2654 TestCompletionCallback callback;
Andrew Top0d1858f2019-05-15 22:01:47 -07002655 EXPECT_EQ(ERR_IO_PENDING,
2656 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2657 ClientSocketPool::RespectLimits::ENABLED,
2658 callback.callback(), pool_.get(), NetLogWithSource()));
2659 EXPECT_THAT(callback.WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07002660 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2661
2662 pool_->FlushWithError(ERR_NETWORK_CHANGED);
2663
2664 handle.Reset();
Andrew Top0d1858f2019-05-15 22:01:47 -07002665 base::RunLoop().RunUntilIdle();
David Ghandehari9e5b5872016-07-28 09:50:04 -07002666
Andrew Top0d1858f2019-05-15 22:01:47 -07002667 EXPECT_EQ(ERR_IO_PENDING,
2668 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2669 ClientSocketPool::RespectLimits::ENABLED,
2670 callback.callback(), pool_.get(), NetLogWithSource()));
2671 EXPECT_THAT(callback.WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07002672 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2673}
2674
2675class ConnectWithinCallback : public TestCompletionCallbackBase {
2676 public:
Andrew Top0d1858f2019-05-15 22:01:47 -07002677 ConnectWithinCallback(const std::string& group_name,
2678 const scoped_refptr<TestSocketParams>& params,
2679 TestClientSocketPool* pool)
2680 : group_name_(group_name), params_(params), pool_(pool) {}
David Ghandehari9e5b5872016-07-28 09:50:04 -07002681
Andrew Top0d1858f2019-05-15 22:01:47 -07002682 ~ConnectWithinCallback() override = default;
David Ghandehari9e5b5872016-07-28 09:50:04 -07002683
2684 int WaitForNestedResult() {
2685 return nested_callback_.WaitForResult();
2686 }
2687
Andrew Top0d1858f2019-05-15 22:01:47 -07002688 CompletionOnceCallback callback() {
2689 return base::BindOnce(&ConnectWithinCallback::OnComplete,
2690 base::Unretained(this));
2691 }
David Ghandehari9e5b5872016-07-28 09:50:04 -07002692
2693 private:
2694 void OnComplete(int result) {
2695 SetResult(result);
Andrew Top0d1858f2019-05-15 22:01:47 -07002696 EXPECT_EQ(
2697 ERR_IO_PENDING,
2698 handle_.Init(group_name_, params_, DEFAULT_PRIORITY, SocketTag(),
2699 ClientSocketPool::RespectLimits::ENABLED,
2700 nested_callback_.callback(), pool_, NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07002701 }
2702
2703 const std::string group_name_;
2704 const scoped_refptr<TestSocketParams> params_;
2705 TestClientSocketPool* const pool_;
2706 ClientSocketHandle handle_;
David Ghandehari9e5b5872016-07-28 09:50:04 -07002707 TestCompletionCallback nested_callback_;
2708
2709 DISALLOW_COPY_AND_ASSIGN(ConnectWithinCallback);
2710};
2711
2712TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
2713 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2714
2715 // First job will be waiting until it gets aborted.
2716 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2717
2718 ClientSocketHandle handle;
2719 ConnectWithinCallback callback("a", params_, pool_.get());
Andrew Top0d1858f2019-05-15 22:01:47 -07002720 EXPECT_EQ(ERR_IO_PENDING,
2721 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2722 ClientSocketPool::RespectLimits::ENABLED,
2723 callback.callback(), pool_.get(), NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07002724
2725 // Second job will be started during the first callback, and will
2726 // asynchronously complete with OK.
2727 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2728 pool_->FlushWithError(ERR_NETWORK_CHANGED);
Andrew Top0d1858f2019-05-15 22:01:47 -07002729 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NETWORK_CHANGED));
2730 EXPECT_THAT(callback.WaitForNestedResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07002731}
2732
2733// Cancel a pending socket request while we're at max sockets,
2734// and verify that the backup socket firing doesn't cause a crash.
2735TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
2736 // Max 4 sockets globally, max 4 sockets per group.
2737 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2738 pool_->EnableConnectBackupJobs();
2739
2740 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2741 // timer.
2742 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2743 ClientSocketHandle handle;
2744 TestCompletionCallback callback;
Andrew Top0d1858f2019-05-15 22:01:47 -07002745 EXPECT_EQ(ERR_IO_PENDING,
2746 handle.Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
2747 ClientSocketPool::RespectLimits::ENABLED,
2748 callback.callback(), pool_.get(), NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07002749
2750 // Start (MaxSockets - 1) connected sockets to reach max sockets.
2751 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2752 ClientSocketHandle handles[kDefaultMaxSockets];
2753 for (int i = 1; i < kDefaultMaxSockets; ++i) {
2754 TestCompletionCallback callback;
Andrew Top0d1858f2019-05-15 22:01:47 -07002755 EXPECT_EQ(OK, handles[i].Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
2756 ClientSocketPool::RespectLimits::ENABLED,
2757 callback.callback(), pool_.get(),
2758 NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07002759 }
2760
Andrew Top0d1858f2019-05-15 22:01:47 -07002761 base::RunLoop().RunUntilIdle();
David Ghandehari9e5b5872016-07-28 09:50:04 -07002762
2763 // Cancel the pending request.
2764 handle.Reset();
2765
2766 // Wait for the backup timer to fire (add some slop to ensure it fires)
2767 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2768 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
2769
Andrew Top0d1858f2019-05-15 22:01:47 -07002770 base::RunLoop().RunUntilIdle();
David Ghandehari9e5b5872016-07-28 09:50:04 -07002771 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
2772}
2773
2774TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
2775 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2776 pool_->EnableConnectBackupJobs();
2777
2778 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2779 // timer.
2780 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2781 ClientSocketHandle handle;
2782 TestCompletionCallback callback;
Andrew Top0d1858f2019-05-15 22:01:47 -07002783 EXPECT_EQ(ERR_IO_PENDING,
2784 handle.Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
2785 ClientSocketPool::RespectLimits::ENABLED,
2786 callback.callback(), pool_.get(), NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07002787 ASSERT_TRUE(pool_->HasGroup("bar"));
2788 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2789 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("bar"));
2790
2791 // Cancel the socket request. This should cancel the backup timer. Wait for
2792 // the backup time to see if it indeed got canceled.
2793 handle.Reset();
2794 // Wait for the backup timer to fire (add some slop to ensure it fires)
2795 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2796 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
Andrew Top0d1858f2019-05-15 22:01:47 -07002797 base::RunLoop().RunUntilIdle();
David Ghandehari9e5b5872016-07-28 09:50:04 -07002798 ASSERT_TRUE(pool_->HasGroup("bar"));
2799 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2800}
2801
2802TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
2803 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2804 pool_->EnableConnectBackupJobs();
2805
2806 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2807 // timer.
2808 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2809 ClientSocketHandle handle;
2810 TestCompletionCallback callback;
Andrew Top0d1858f2019-05-15 22:01:47 -07002811 EXPECT_EQ(ERR_IO_PENDING,
2812 handle.Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
2813 ClientSocketPool::RespectLimits::ENABLED,
2814 callback.callback(), pool_.get(), NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07002815 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2816 ClientSocketHandle handle2;
2817 TestCompletionCallback callback2;
Andrew Top0d1858f2019-05-15 22:01:47 -07002818 EXPECT_EQ(
2819 ERR_IO_PENDING,
2820 handle2.Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
2821 ClientSocketPool::RespectLimits::ENABLED,
2822 callback2.callback(), pool_.get(), NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07002823 ASSERT_TRUE(pool_->HasGroup("bar"));
2824 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("bar"));
2825
2826 // Cancel request 1 and then complete request 2. With the requests finished,
2827 // the backup timer should be cancelled.
2828 handle.Reset();
Andrew Top0d1858f2019-05-15 22:01:47 -07002829 EXPECT_THAT(callback2.WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07002830 // Wait for the backup timer to fire (add some slop to ensure it fires)
2831 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2832 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
Andrew Top0d1858f2019-05-15 22:01:47 -07002833 base::RunLoop().RunUntilIdle();
David Ghandehari9e5b5872016-07-28 09:50:04 -07002834}
2835
2836// Test delayed socket binding for the case where we have two connects,
2837// and while one is waiting on a connect, the other frees up.
2838// The socket waiting on a connect should switch immediately to the freed
2839// up socket.
2840TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
2841 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2842 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2843
2844 ClientSocketHandle handle1;
2845 TestCompletionCallback callback;
2846 EXPECT_EQ(ERR_IO_PENDING,
Andrew Top0d1858f2019-05-15 22:01:47 -07002847 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2848 ClientSocketPool::RespectLimits::ENABLED,
2849 callback.callback(), pool_.get(), NetLogWithSource()));
2850 EXPECT_THAT(callback.WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07002851
2852 // No idle sockets, no pending jobs.
2853 EXPECT_EQ(0, pool_->IdleSocketCount());
2854 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2855
2856 // Create a second socket to the same host, but this one will wait.
2857 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2858 ClientSocketHandle handle2;
2859 EXPECT_EQ(ERR_IO_PENDING,
Andrew Top0d1858f2019-05-15 22:01:47 -07002860 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2861 ClientSocketPool::RespectLimits::ENABLED,
2862 callback.callback(), pool_.get(), NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07002863 // No idle sockets, and one connecting job.
2864 EXPECT_EQ(0, pool_->IdleSocketCount());
2865 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2866
2867 // Return the first handle to the pool. This will initiate the delayed
2868 // binding.
2869 handle1.Reset();
2870
Andrew Top0d1858f2019-05-15 22:01:47 -07002871 base::RunLoop().RunUntilIdle();
David Ghandehari9e5b5872016-07-28 09:50:04 -07002872
2873 // Still no idle sockets, still one pending connect job.
2874 EXPECT_EQ(0, pool_->IdleSocketCount());
2875 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2876
2877 // The second socket connected, even though it was a Waiting Job.
Andrew Top0d1858f2019-05-15 22:01:47 -07002878 EXPECT_THAT(callback.WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07002879
2880 // And we can see there is still one job waiting.
2881 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2882
2883 // Finally, signal the waiting Connect.
2884 client_socket_factory_.SignalJobs();
2885 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2886
Andrew Top0d1858f2019-05-15 22:01:47 -07002887 base::RunLoop().RunUntilIdle();
David Ghandehari9e5b5872016-07-28 09:50:04 -07002888}
2889
2890// Test delayed socket binding when a group is at capacity and one
2891// of the group's sockets frees up.
2892TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
2893 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2894 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2895
2896 ClientSocketHandle handle1;
2897 TestCompletionCallback callback;
2898 EXPECT_EQ(ERR_IO_PENDING,
Andrew Top0d1858f2019-05-15 22:01:47 -07002899 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2900 ClientSocketPool::RespectLimits::ENABLED,
2901 callback.callback(), pool_.get(), NetLogWithSource()));
2902 EXPECT_THAT(callback.WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07002903
2904 // No idle sockets, no pending jobs.
2905 EXPECT_EQ(0, pool_->IdleSocketCount());
2906 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2907
2908 // Create a second socket to the same host, but this one will wait.
2909 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2910 ClientSocketHandle handle2;
2911 EXPECT_EQ(ERR_IO_PENDING,
Andrew Top0d1858f2019-05-15 22:01:47 -07002912 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2913 ClientSocketPool::RespectLimits::ENABLED,
2914 callback.callback(), pool_.get(), NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07002915 // No idle sockets, and one connecting job.
2916 EXPECT_EQ(0, pool_->IdleSocketCount());
2917 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2918
2919 // Return the first handle to the pool. This will initiate the delayed
2920 // binding.
2921 handle1.Reset();
2922
Andrew Top0d1858f2019-05-15 22:01:47 -07002923 base::RunLoop().RunUntilIdle();
David Ghandehari9e5b5872016-07-28 09:50:04 -07002924
2925 // Still no idle sockets, still one pending connect job.
2926 EXPECT_EQ(0, pool_->IdleSocketCount());
2927 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2928
2929 // The second socket connected, even though it was a Waiting Job.
Andrew Top0d1858f2019-05-15 22:01:47 -07002930 EXPECT_THAT(callback.WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07002931
2932 // And we can see there is still one job waiting.
2933 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2934
2935 // Finally, signal the waiting Connect.
2936 client_socket_factory_.SignalJobs();
2937 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2938
Andrew Top0d1858f2019-05-15 22:01:47 -07002939 base::RunLoop().RunUntilIdle();
David Ghandehari9e5b5872016-07-28 09:50:04 -07002940}
2941
2942// Test out the case where we have one socket connected, one
2943// connecting, when the first socket finishes and goes idle.
2944// Although the second connection is pending, the second request
2945// should complete, by taking the first socket's idle socket.
2946TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
2947 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2948 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2949
2950 ClientSocketHandle handle1;
2951 TestCompletionCallback callback;
2952 EXPECT_EQ(ERR_IO_PENDING,
Andrew Top0d1858f2019-05-15 22:01:47 -07002953 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2954 ClientSocketPool::RespectLimits::ENABLED,
2955 callback.callback(), pool_.get(), NetLogWithSource()));
2956 EXPECT_THAT(callback.WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07002957
2958 // No idle sockets, no pending jobs.
2959 EXPECT_EQ(0, pool_->IdleSocketCount());
2960 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2961
2962 // Create a second socket to the same host, but this one will wait.
2963 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2964 ClientSocketHandle handle2;
2965 EXPECT_EQ(ERR_IO_PENDING,
Andrew Top0d1858f2019-05-15 22:01:47 -07002966 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
2967 ClientSocketPool::RespectLimits::ENABLED,
2968 callback.callback(), pool_.get(), NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07002969 // No idle sockets, and one connecting job.
2970 EXPECT_EQ(0, pool_->IdleSocketCount());
2971 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2972
2973 // Return the first handle to the pool. This will initiate the delayed
2974 // binding.
2975 handle1.Reset();
2976
Andrew Top0d1858f2019-05-15 22:01:47 -07002977 base::RunLoop().RunUntilIdle();
David Ghandehari9e5b5872016-07-28 09:50:04 -07002978
2979 // Still no idle sockets, still one pending connect job.
2980 EXPECT_EQ(0, pool_->IdleSocketCount());
2981 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2982
2983 // The second socket connected, even though it was a Waiting Job.
Andrew Top0d1858f2019-05-15 22:01:47 -07002984 EXPECT_THAT(callback.WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07002985
2986 // And we can see there is still one job waiting.
2987 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2988
2989 // Finally, signal the waiting Connect.
2990 client_socket_factory_.SignalJobs();
2991 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2992
Andrew Top0d1858f2019-05-15 22:01:47 -07002993 base::RunLoop().RunUntilIdle();
David Ghandehari9e5b5872016-07-28 09:50:04 -07002994}
2995
2996// Cover the case where on an available socket slot, we have one pending
2997// request that completes synchronously, thereby making the Group empty.
2998TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
2999 const int kUnlimitedSockets = 100;
3000 const int kOneSocketPerGroup = 1;
3001 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
3002
3003 // Make the first request asynchronous fail.
3004 // This will free up a socket slot later.
3005 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
3006
3007 ClientSocketHandle handle1;
3008 TestCompletionCallback callback1;
Andrew Top0d1858f2019-05-15 22:01:47 -07003009 EXPECT_EQ(
3010 ERR_IO_PENDING,
3011 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3012 ClientSocketPool::RespectLimits::ENABLED,
3013 callback1.callback(), pool_.get(), NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07003014 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3015
3016 // Make the second request synchronously fail. This should make the Group
3017 // empty.
3018 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3019 ClientSocketHandle handle2;
3020 TestCompletionCallback callback2;
3021 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
3022 // when created.
Andrew Top0d1858f2019-05-15 22:01:47 -07003023 EXPECT_EQ(
3024 ERR_IO_PENDING,
3025 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3026 ClientSocketPool::RespectLimits::ENABLED,
3027 callback2.callback(), pool_.get(), NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07003028
3029 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3030
Andrew Top0d1858f2019-05-15 22:01:47 -07003031 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
3032 EXPECT_THAT(callback2.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
David Ghandehari9e5b5872016-07-28 09:50:04 -07003033 EXPECT_FALSE(pool_->HasGroup("a"));
3034}
3035
3036TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
3037 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3038
3039 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3040
3041 ClientSocketHandle handle1;
3042 TestCompletionCallback callback1;
Andrew Top0d1858f2019-05-15 22:01:47 -07003043 EXPECT_EQ(
3044 ERR_IO_PENDING,
3045 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3046 ClientSocketPool::RespectLimits::ENABLED,
3047 callback1.callback(), pool_.get(), NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07003048
3049 ClientSocketHandle handle2;
3050 TestCompletionCallback callback2;
Andrew Top0d1858f2019-05-15 22:01:47 -07003051 EXPECT_EQ(
3052 ERR_IO_PENDING,
3053 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3054 ClientSocketPool::RespectLimits::ENABLED,
3055 callback2.callback(), pool_.get(), NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07003056 ClientSocketHandle handle3;
3057 TestCompletionCallback callback3;
Andrew Top0d1858f2019-05-15 22:01:47 -07003058 EXPECT_EQ(
3059 ERR_IO_PENDING,
3060 handle3.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3061 ClientSocketPool::RespectLimits::ENABLED,
3062 callback3.callback(), pool_.get(), NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07003063
Andrew Top0d1858f2019-05-15 22:01:47 -07003064 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3065 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3066 EXPECT_THAT(callback3.WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07003067
3068 // Use the socket.
Andrew Top0d1858f2019-05-15 22:01:47 -07003069 EXPECT_EQ(1, handle1.socket()->Write(NULL, 1, CompletionOnceCallback(),
3070 TRAFFIC_ANNOTATION_FOR_TESTS));
3071 EXPECT_EQ(1, handle3.socket()->Write(NULL, 1, CompletionOnceCallback(),
3072 TRAFFIC_ANNOTATION_FOR_TESTS));
David Ghandehari9e5b5872016-07-28 09:50:04 -07003073
3074 handle1.Reset();
3075 handle2.Reset();
3076 handle3.Reset();
3077
Andrew Top0d1858f2019-05-15 22:01:47 -07003078 EXPECT_EQ(
3079 OK, handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3080 ClientSocketPool::RespectLimits::ENABLED,
3081 callback1.callback(), pool_.get(), NetLogWithSource()));
3082 EXPECT_EQ(
3083 OK, handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3084 ClientSocketPool::RespectLimits::ENABLED,
3085 callback2.callback(), pool_.get(), NetLogWithSource()));
3086 EXPECT_EQ(
3087 OK, handle3.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3088 ClientSocketPool::RespectLimits::ENABLED,
3089 callback3.callback(), pool_.get(), NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07003090
3091 EXPECT_TRUE(handle1.socket()->WasEverUsed());
3092 EXPECT_TRUE(handle2.socket()->WasEverUsed());
3093 EXPECT_FALSE(handle3.socket()->WasEverUsed());
3094}
3095
3096TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
3097 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3098 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3099
Andrew Top0d1858f2019-05-15 22:01:47 -07003100 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
David Ghandehari9e5b5872016-07-28 09:50:04 -07003101
3102 ASSERT_TRUE(pool_->HasGroup("a"));
3103 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3104 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
3105 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3106
3107 ClientSocketHandle handle1;
3108 TestCompletionCallback callback1;
Andrew Top0d1858f2019-05-15 22:01:47 -07003109 EXPECT_EQ(
3110 ERR_IO_PENDING,
3111 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3112 ClientSocketPool::RespectLimits::ENABLED,
3113 callback1.callback(), pool_.get(), NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07003114
3115 ClientSocketHandle handle2;
3116 TestCompletionCallback callback2;
Andrew Top0d1858f2019-05-15 22:01:47 -07003117 EXPECT_EQ(
3118 ERR_IO_PENDING,
3119 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3120 ClientSocketPool::RespectLimits::ENABLED,
3121 callback2.callback(), pool_.get(), NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07003122
3123 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3124 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3125 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3126
Andrew Top0d1858f2019-05-15 22:01:47 -07003127 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3128 EXPECT_THAT(callback2.WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07003129 handle1.Reset();
3130 handle2.Reset();
3131
3132 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3133 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3134 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3135}
3136
3137TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
3138 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3139 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3140
3141 ClientSocketHandle handle1;
3142 TestCompletionCallback callback1;
Andrew Top0d1858f2019-05-15 22:01:47 -07003143 EXPECT_EQ(
3144 ERR_IO_PENDING,
3145 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3146 ClientSocketPool::RespectLimits::ENABLED,
3147 callback1.callback(), pool_.get(), NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07003148
3149 ASSERT_TRUE(pool_->HasGroup("a"));
3150 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3151 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3152 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3153
Andrew Top0d1858f2019-05-15 22:01:47 -07003154 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
David Ghandehari9e5b5872016-07-28 09:50:04 -07003155
3156 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3157 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
3158 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3159
3160 ClientSocketHandle handle2;
3161 TestCompletionCallback callback2;
Andrew Top0d1858f2019-05-15 22:01:47 -07003162 EXPECT_EQ(
3163 ERR_IO_PENDING,
3164 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3165 ClientSocketPool::RespectLimits::ENABLED,
3166 callback2.callback(), pool_.get(), NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07003167
3168 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3169 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3170 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3171
Andrew Top0d1858f2019-05-15 22:01:47 -07003172 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3173 EXPECT_THAT(callback2.WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07003174 handle1.Reset();
3175 handle2.Reset();
3176
3177 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3178 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3179 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3180}
3181
3182TEST_F(ClientSocketPoolBaseTest,
3183 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
3184 CreatePool(4, 4);
3185 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3186
3187 ClientSocketHandle handle1;
3188 TestCompletionCallback callback1;
Andrew Top0d1858f2019-05-15 22:01:47 -07003189 EXPECT_EQ(
3190 ERR_IO_PENDING,
3191 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3192 ClientSocketPool::RespectLimits::ENABLED,
3193 callback1.callback(), pool_.get(), NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07003194
3195 ClientSocketHandle handle2;
3196 TestCompletionCallback callback2;
Andrew Top0d1858f2019-05-15 22:01:47 -07003197 EXPECT_EQ(
3198 ERR_IO_PENDING,
3199 handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3200 ClientSocketPool::RespectLimits::ENABLED,
3201 callback2.callback(), pool_.get(), NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07003202
3203 ClientSocketHandle handle3;
3204 TestCompletionCallback callback3;
Andrew Top0d1858f2019-05-15 22:01:47 -07003205 EXPECT_EQ(
3206 ERR_IO_PENDING,
3207 handle3.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3208 ClientSocketPool::RespectLimits::ENABLED,
3209 callback3.callback(), pool_.get(), NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07003210
3211 ASSERT_TRUE(pool_->HasGroup("a"));
3212 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
3213 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3214 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3215
Andrew Top0d1858f2019-05-15 22:01:47 -07003216 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
David Ghandehari9e5b5872016-07-28 09:50:04 -07003217
3218 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
3219 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3220 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3221
Andrew Top0d1858f2019-05-15 22:01:47 -07003222 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3223 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3224 EXPECT_THAT(callback3.WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07003225 handle1.Reset();
3226 handle2.Reset();
3227 handle3.Reset();
3228
3229 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3230 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3231 EXPECT_EQ(3, pool_->IdleSocketCountInGroup("a"));
3232}
3233
3234TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
3235 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3236 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3237
3238 ASSERT_FALSE(pool_->HasGroup("a"));
3239
Andrew Top0d1858f2019-05-15 22:01:47 -07003240 pool_->RequestSockets("a", &params_, kDefaultMaxSockets, NetLogWithSource());
David Ghandehari9e5b5872016-07-28 09:50:04 -07003241
3242 ASSERT_TRUE(pool_->HasGroup("a"));
3243 EXPECT_EQ(kDefaultMaxSockets, pool_->NumConnectJobsInGroup("a"));
3244 EXPECT_EQ(kDefaultMaxSockets, pool_->NumUnassignedConnectJobsInGroup("a"));
3245
3246 ASSERT_FALSE(pool_->HasGroup("b"));
3247
Andrew Top0d1858f2019-05-15 22:01:47 -07003248 pool_->RequestSockets("b", &params_, kDefaultMaxSockets, NetLogWithSource());
David Ghandehari9e5b5872016-07-28 09:50:04 -07003249
3250 ASSERT_FALSE(pool_->HasGroup("b"));
3251}
3252
3253TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
3254 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3255 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3256
3257 ASSERT_FALSE(pool_->HasGroup("a"));
3258
3259 pool_->RequestSockets("a", &params_, kDefaultMaxSockets - 1,
Andrew Top0d1858f2019-05-15 22:01:47 -07003260 NetLogWithSource());
David Ghandehari9e5b5872016-07-28 09:50:04 -07003261
3262 ASSERT_TRUE(pool_->HasGroup("a"));
3263 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->NumConnectJobsInGroup("a"));
3264 EXPECT_EQ(kDefaultMaxSockets - 1,
3265 pool_->NumUnassignedConnectJobsInGroup("a"));
3266 EXPECT_FALSE(pool_->IsStalled());
3267
3268 ASSERT_FALSE(pool_->HasGroup("b"));
3269
Andrew Top0d1858f2019-05-15 22:01:47 -07003270 pool_->RequestSockets("b", &params_, kDefaultMaxSockets, NetLogWithSource());
David Ghandehari9e5b5872016-07-28 09:50:04 -07003271
3272 ASSERT_TRUE(pool_->HasGroup("b"));
3273 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("b"));
3274 EXPECT_FALSE(pool_->IsStalled());
3275}
3276
3277TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
3278 CreatePool(4, 4);
3279 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3280
3281 ClientSocketHandle handle1;
3282 TestCompletionCallback callback1;
Andrew Top0d1858f2019-05-15 22:01:47 -07003283 EXPECT_EQ(
3284 ERR_IO_PENDING,
3285 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3286 ClientSocketPool::RespectLimits::ENABLED,
3287 callback1.callback(), pool_.get(), NetLogWithSource()));
3288 ASSERT_THAT(callback1.WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07003289 handle1.Reset();
3290
3291 ASSERT_TRUE(pool_->HasGroup("a"));
3292 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3293 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3294 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3295
Andrew Top0d1858f2019-05-15 22:01:47 -07003296 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
David Ghandehari9e5b5872016-07-28 09:50:04 -07003297
3298 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3299 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
3300 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3301}
3302
3303TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
3304 CreatePool(4, 4);
3305 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3306
3307 ClientSocketHandle handle1;
3308 TestCompletionCallback callback1;
Andrew Top0d1858f2019-05-15 22:01:47 -07003309 EXPECT_EQ(
3310 ERR_IO_PENDING,
3311 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3312 ClientSocketPool::RespectLimits::ENABLED,
3313 callback1.callback(), pool_.get(), NetLogWithSource()));
3314 ASSERT_THAT(callback1.WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07003315
3316 ASSERT_TRUE(pool_->HasGroup("a"));
3317 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3318 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3319 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3320 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3321
Andrew Top0d1858f2019-05-15 22:01:47 -07003322 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
David Ghandehari9e5b5872016-07-28 09:50:04 -07003323
3324 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3325 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
3326 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3327 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3328}
3329
3330TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
3331 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3332 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3333
3334 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
Andrew Top0d1858f2019-05-15 22:01:47 -07003335 NetLogWithSource());
David Ghandehari9e5b5872016-07-28 09:50:04 -07003336
3337 ASSERT_TRUE(pool_->HasGroup("a"));
3338 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3339 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3340 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("a"));
3341
3342 pool_->RequestSockets("b", &params_, kDefaultMaxSocketsPerGroup,
Andrew Top0d1858f2019-05-15 22:01:47 -07003343 NetLogWithSource());
David Ghandehari9e5b5872016-07-28 09:50:04 -07003344
3345 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3346 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
3347 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("b"));
3348}
3349
3350TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
3351 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3352 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3353
3354 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
Andrew Top0d1858f2019-05-15 22:01:47 -07003355 NetLogWithSource());
David Ghandehari9e5b5872016-07-28 09:50:04 -07003356
3357 ASSERT_FALSE(pool_->HasGroup("a"));
3358
3359 connect_job_factory_->set_job_type(
3360 TestConnectJob::kMockAdditionalErrorStateJob);
3361 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
Andrew Top0d1858f2019-05-15 22:01:47 -07003362 NetLogWithSource());
David Ghandehari9e5b5872016-07-28 09:50:04 -07003363
3364 ASSERT_FALSE(pool_->HasGroup("a"));
3365}
3366
3367TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
3368 CreatePool(4, 4);
3369 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3370
Andrew Top0d1858f2019-05-15 22:01:47 -07003371 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
David Ghandehari9e5b5872016-07-28 09:50:04 -07003372
3373 ASSERT_TRUE(pool_->HasGroup("a"));
3374 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3375 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
3376 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3377
Andrew Top0d1858f2019-05-15 22:01:47 -07003378 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
David Ghandehari9e5b5872016-07-28 09:50:04 -07003379 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3380 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
3381 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3382
3383 ClientSocketHandle handle1;
3384 TestCompletionCallback callback1;
Andrew Top0d1858f2019-05-15 22:01:47 -07003385 EXPECT_EQ(
3386 ERR_IO_PENDING,
3387 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3388 ClientSocketPool::RespectLimits::ENABLED,
3389 callback1.callback(), pool_.get(), NetLogWithSource()));
3390 ASSERT_THAT(callback1.WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07003391
3392 ClientSocketHandle handle2;
3393 TestCompletionCallback callback2;
Andrew Top0d1858f2019-05-15 22:01:47 -07003394 int rv = handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3395 ClientSocketPool::RespectLimits::ENABLED,
3396 callback2.callback(), pool_.get(), NetLogWithSource());
David Ghandehari9e5b5872016-07-28 09:50:04 -07003397 if (rv != OK) {
Andrew Top0d1858f2019-05-15 22:01:47 -07003398 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3399 EXPECT_THAT(callback2.WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07003400 }
3401
3402 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3403 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3404 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("a"));
3405 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3406
3407 handle1.Reset();
3408 handle2.Reset();
3409
3410 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3411 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3412 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3413
Andrew Top0d1858f2019-05-15 22:01:47 -07003414 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
David Ghandehari9e5b5872016-07-28 09:50:04 -07003415 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3416 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3417 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3418}
3419
3420TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
3421 CreatePool(4, 4);
3422 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3423
Andrew Top0d1858f2019-05-15 22:01:47 -07003424 pool_->RequestSockets("a", &params_, 1, NetLogWithSource());
David Ghandehari9e5b5872016-07-28 09:50:04 -07003425
3426 ASSERT_TRUE(pool_->HasGroup("a"));
3427 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3428 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
3429 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3430
Andrew Top0d1858f2019-05-15 22:01:47 -07003431 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
David Ghandehari9e5b5872016-07-28 09:50:04 -07003432 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3433 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
3434 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3435
Andrew Top0d1858f2019-05-15 22:01:47 -07003436 pool_->RequestSockets("a", &params_, 3, NetLogWithSource());
David Ghandehari9e5b5872016-07-28 09:50:04 -07003437 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
3438 EXPECT_EQ(3, pool_->NumUnassignedConnectJobsInGroup("a"));
3439 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3440
Andrew Top0d1858f2019-05-15 22:01:47 -07003441 pool_->RequestSockets("a", &params_, 1, NetLogWithSource());
David Ghandehari9e5b5872016-07-28 09:50:04 -07003442 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
3443 EXPECT_EQ(3, pool_->NumUnassignedConnectJobsInGroup("a"));
3444 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3445}
3446
3447TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
3448 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3449 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3450
Andrew Top0d1858f2019-05-15 22:01:47 -07003451 pool_->RequestSockets("a", &params_, 1, NetLogWithSource());
David Ghandehari9e5b5872016-07-28 09:50:04 -07003452
3453 ASSERT_TRUE(pool_->HasGroup("a"));
3454 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3455 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
3456 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3457
3458 ClientSocketHandle handle1;
3459 TestCompletionCallback callback1;
Andrew Top0d1858f2019-05-15 22:01:47 -07003460 EXPECT_EQ(
3461 ERR_IO_PENDING,
3462 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3463 ClientSocketPool::RespectLimits::ENABLED,
3464 callback1.callback(), pool_.get(), NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07003465
3466 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3467 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3468 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3469
Andrew Top0d1858f2019-05-15 22:01:47 -07003470 ASSERT_THAT(callback1.WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07003471
Andrew Top0d1858f2019-05-15 22:01:47 -07003472 // Make sure if a preconnected socket is not fully connected when a request
3473 // starts, it has a connect start time.
3474 TestLoadTimingInfoConnectedNotReused(handle1);
David Ghandehari9e5b5872016-07-28 09:50:04 -07003475 handle1.Reset();
3476
3477 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3478}
3479
Andrew Top0d1858f2019-05-15 22:01:47 -07003480// Checks that fully connected preconnect jobs have no connect times, and are
3481// marked as reused.
3482TEST_F(ClientSocketPoolBaseTest, ConnectedPreconnectJobsHaveNoConnectTimes) {
3483 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3484 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3485 pool_->RequestSockets("a", &params_, 1, NetLogWithSource());
3486
3487 ASSERT_TRUE(pool_->HasGroup("a"));
3488 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3489 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3490 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3491
3492 ClientSocketHandle handle;
3493 TestCompletionCallback callback;
3494 EXPECT_EQ(OK,
3495 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3496 ClientSocketPool::RespectLimits::ENABLED,
3497 callback.callback(), pool_.get(), NetLogWithSource()));
3498
3499 // Make sure the idle socket was used.
3500 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3501
3502 TestLoadTimingInfoConnectedReused(handle);
3503 handle.Reset();
3504 TestLoadTimingInfoNotConnected(handle);
3505}
3506
David Ghandehari9e5b5872016-07-28 09:50:04 -07003507// http://crbug.com/64940 regression test.
3508TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
3509 const int kMaxTotalSockets = 3;
3510 const int kMaxSocketsPerGroup = 2;
3511 CreatePool(kMaxTotalSockets, kMaxSocketsPerGroup);
3512 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3513
3514 // Note that group name ordering matters here. "a" comes before "b", so
3515 // CloseOneIdleSocket() will try to close "a"'s idle socket.
3516
3517 // Set up one idle socket in "a".
3518 ClientSocketHandle handle1;
3519 TestCompletionCallback callback1;
Andrew Top0d1858f2019-05-15 22:01:47 -07003520 EXPECT_EQ(
3521 ERR_IO_PENDING,
3522 handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3523 ClientSocketPool::RespectLimits::ENABLED,
3524 callback1.callback(), pool_.get(), NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07003525
Andrew Top0d1858f2019-05-15 22:01:47 -07003526 ASSERT_THAT(callback1.WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07003527 handle1.Reset();
3528 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3529
3530 // Set up two active sockets in "b".
3531 ClientSocketHandle handle2;
3532 TestCompletionCallback callback2;
Andrew Top0d1858f2019-05-15 22:01:47 -07003533 EXPECT_EQ(
3534 ERR_IO_PENDING,
3535 handle1.Init("b", params_, DEFAULT_PRIORITY, SocketTag(),
3536 ClientSocketPool::RespectLimits::ENABLED,
3537 callback1.callback(), pool_.get(), NetLogWithSource()));
3538 EXPECT_EQ(
3539 ERR_IO_PENDING,
3540 handle2.Init("b", params_, DEFAULT_PRIORITY, SocketTag(),
3541 ClientSocketPool::RespectLimits::ENABLED,
3542 callback2.callback(), pool_.get(), NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07003543
Andrew Top0d1858f2019-05-15 22:01:47 -07003544 ASSERT_THAT(callback1.WaitForResult(), IsOk());
3545 ASSERT_THAT(callback2.WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07003546 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3547 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
3548 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3549
3550 // Now we have 1 idle socket in "a" and 2 active sockets in "b". This means
3551 // we've maxed out on sockets, since we set |kMaxTotalSockets| to 3.
3552 // Requesting 2 preconnected sockets for "a" should fail to allocate any more
3553 // sockets for "a", and "b" should still have 2 active sockets.
3554
Andrew Top0d1858f2019-05-15 22:01:47 -07003555 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
David Ghandehari9e5b5872016-07-28 09:50:04 -07003556 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3557 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3558 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3559 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3560 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3561 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
3562 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3563 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3564
3565 // Now release the 2 active sockets for "b". This will give us 1 idle socket
3566 // in "a" and 2 idle sockets in "b". Requesting 2 preconnected sockets for
3567 // "a" should result in closing 1 for "b".
3568 handle1.Reset();
3569 handle2.Reset();
3570 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("b"));
3571 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3572
Andrew Top0d1858f2019-05-15 22:01:47 -07003573 pool_->RequestSockets("a", &params_, 2, NetLogWithSource());
David Ghandehari9e5b5872016-07-28 09:50:04 -07003574 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3575 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
3576 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3577 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3578 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3579 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
3580 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("b"));
3581 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3582}
3583
3584TEST_F(ClientSocketPoolBaseTest, PreconnectWithoutBackupJob) {
3585 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3586 pool_->EnableConnectBackupJobs();
3587
3588 // Make the ConnectJob hang until it times out, shorten the timeout.
3589 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3590 connect_job_factory_->set_timeout_duration(
3591 base::TimeDelta::FromMilliseconds(500));
Andrew Top0d1858f2019-05-15 22:01:47 -07003592 pool_->RequestSockets("a", &params_, 1, NetLogWithSource());
David Ghandehari9e5b5872016-07-28 09:50:04 -07003593 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3594 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
3595 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3596
3597 // Verify the backup timer doesn't create a backup job, by making
3598 // the backup job a pending job instead of a waiting job, so it
3599 // *would* complete if it were created.
3600 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
Andrew Top0d1858f2019-05-15 22:01:47 -07003601 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
3602 FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated(),
3603 base::TimeDelta::FromSeconds(1));
3604 base::RunLoop().Run();
David Ghandehari9e5b5872016-07-28 09:50:04 -07003605 EXPECT_FALSE(pool_->HasGroup("a"));
3606}
3607
3608TEST_F(ClientSocketPoolBaseTest, PreconnectWithBackupJob) {
3609 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3610 pool_->EnableConnectBackupJobs();
3611
3612 // Make the ConnectJob hang forever.
3613 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
Andrew Top0d1858f2019-05-15 22:01:47 -07003614 pool_->RequestSockets("a", &params_, 1, NetLogWithSource());
David Ghandehari9e5b5872016-07-28 09:50:04 -07003615 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3616 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
3617 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
Andrew Top0d1858f2019-05-15 22:01:47 -07003618 base::RunLoop().RunUntilIdle();
David Ghandehari9e5b5872016-07-28 09:50:04 -07003619
3620 // Make the backup job be a pending job, so it completes normally.
3621 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3622 ClientSocketHandle handle;
3623 TestCompletionCallback callback;
Andrew Top0d1858f2019-05-15 22:01:47 -07003624 EXPECT_EQ(ERR_IO_PENDING,
3625 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3626 ClientSocketPool::RespectLimits::ENABLED,
3627 callback.callback(), pool_.get(), NetLogWithSource()));
David Ghandehari9e5b5872016-07-28 09:50:04 -07003628 // Timer has started, but the backup connect job shouldn't be created yet.
3629 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3630 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3631 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3632 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
Andrew Top0d1858f2019-05-15 22:01:47 -07003633 ASSERT_THAT(callback.WaitForResult(), IsOk());
David Ghandehari9e5b5872016-07-28 09:50:04 -07003634
3635 // The hung connect job should still be there, but everything else should be
3636 // complete.
3637 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3638 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3639 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3640 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3641}
3642
Andrew Top0d1858f2019-05-15 22:01:47 -07003643// Tests that a preconnect that starts out with unread data can still be used.
3644// http://crbug.com/334467
3645TEST_F(ClientSocketPoolBaseTest, PreconnectWithUnreadData) {
3646 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3647 connect_job_factory_->set_job_type(TestConnectJob::kMockUnreadDataJob);
3648
3649 pool_->RequestSockets("a", &params_, 1, NetLogWithSource());
3650
3651 ASSERT_TRUE(pool_->HasGroup("a"));
3652 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3653 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3654 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3655
3656 // Fail future jobs to be sure that handle receives the preconnected socket
3657 // rather than closing it and making a new one.
3658 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3659 ClientSocketHandle handle;
3660 TestCompletionCallback callback;
3661 EXPECT_EQ(OK,
3662 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3663 ClientSocketPool::RespectLimits::ENABLED,
3664 callback.callback(), pool_.get(), NetLogWithSource()));
3665
3666 ASSERT_TRUE(pool_->HasGroup("a"));
3667 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3668 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3669 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3670
3671 // Drain the pending read.
3672 EXPECT_EQ(1, handle.socket()->Read(NULL, 1, CompletionOnceCallback()));
3673
3674 TestLoadTimingInfoConnectedReused(handle);
3675 handle.Reset();
3676
3677 // The socket should be usable now that it's idle again.
3678 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3679}
3680
3681class MockLayeredPool : public HigherLayeredPool {
3682 public:
3683 MockLayeredPool(TestClientSocketPool* pool,
3684 const std::string& group_name)
3685 : pool_(pool),
3686 group_name_(group_name),
3687 can_release_connection_(true) {
3688 pool_->AddHigherLayeredPool(this);
3689 }
3690
3691 ~MockLayeredPool() override { pool_->RemoveHigherLayeredPool(this); }
3692
3693 int RequestSocket(TestClientSocketPool* pool) {
3694 scoped_refptr<TestSocketParams> params(new TestSocketParams());
3695 return handle_.Init(group_name_, params, DEFAULT_PRIORITY, SocketTag(),
3696 ClientSocketPool::RespectLimits::ENABLED,
3697 callback_.callback(), pool, NetLogWithSource());
3698 }
3699
3700 int RequestSocketWithoutLimits(TestClientSocketPool* pool) {
3701 scoped_refptr<TestSocketParams> params(new TestSocketParams());
3702 return handle_.Init(group_name_, params, MAXIMUM_PRIORITY, SocketTag(),
3703 ClientSocketPool::RespectLimits::DISABLED,
3704 callback_.callback(), pool, NetLogWithSource());
3705 }
3706
3707 bool ReleaseOneConnection() {
3708 if (!handle_.is_initialized() || !can_release_connection_) {
3709 return false;
3710 }
3711 handle_.socket()->Disconnect();
3712 handle_.Reset();
3713 return true;
3714 }
3715
3716 void set_can_release_connection(bool can_release_connection) {
3717 can_release_connection_ = can_release_connection;
3718 }
3719
3720 MOCK_METHOD0(CloseOneIdleConnection, bool());
3721
3722 private:
3723 TestClientSocketPool* const pool_;
3724 ClientSocketHandle handle_;
3725 TestCompletionCallback callback_;
3726 const std::string group_name_;
3727 bool can_release_connection_;
3728};
3729
3730TEST_F(ClientSocketPoolBaseTest, FailToCloseIdleSocketsNotHeldByLayeredPool) {
3731 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3732 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3733
3734 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
3735 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
3736 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3737 .WillOnce(Return(false));
3738 EXPECT_FALSE(pool_->CloseOneIdleConnectionInHigherLayeredPool());
3739}
3740
3741TEST_F(ClientSocketPoolBaseTest, ForciblyCloseIdleSocketsHeldByLayeredPool) {
3742 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3743 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3744
3745 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
3746 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
3747 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3748 .WillOnce(Invoke(&mock_layered_pool,
3749 &MockLayeredPool::ReleaseOneConnection));
3750 EXPECT_TRUE(pool_->CloseOneIdleConnectionInHigherLayeredPool());
3751}
3752
3753// Tests the basic case of closing an idle socket in a higher layered pool when
3754// a new request is issued and the lower layer pool is stalled.
3755TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsHeldByLayeredPoolWhenNeeded) {
3756 CreatePool(1, 1);
3757 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3758
3759 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
3760 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
3761 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3762 .WillOnce(Invoke(&mock_layered_pool,
3763 &MockLayeredPool::ReleaseOneConnection));
3764 ClientSocketHandle handle;
3765 TestCompletionCallback callback;
3766 EXPECT_EQ(ERR_IO_PENDING,
3767 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3768 ClientSocketPool::RespectLimits::ENABLED,
3769 callback.callback(), pool_.get(), NetLogWithSource()));
3770 EXPECT_THAT(callback.WaitForResult(), IsOk());
3771}
3772
3773// Same as above, but the idle socket is in the same group as the stalled
3774// socket, and closes the only other request in its group when closing requests
3775// in higher layered pools. This generally shouldn't happen, but it may be
3776// possible if a higher level pool issues a request and the request is
3777// subsequently cancelled. Even if it's not possible, best not to crash.
3778TEST_F(ClientSocketPoolBaseTest,
3779 CloseIdleSocketsHeldByLayeredPoolWhenNeededSameGroup) {
3780 CreatePool(2, 2);
3781 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3782
3783 // Need a socket in another group for the pool to be stalled (If a group
3784 // has the maximum number of connections already, it's not stalled).
3785 ClientSocketHandle handle1;
3786 TestCompletionCallback callback1;
3787 EXPECT_EQ(
3788 OK, handle1.Init("group1", params_, DEFAULT_PRIORITY, SocketTag(),
3789 ClientSocketPool::RespectLimits::ENABLED,
3790 callback1.callback(), pool_.get(), NetLogWithSource()));
3791
3792 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
3793 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
3794 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3795 .WillOnce(Invoke(&mock_layered_pool,
3796 &MockLayeredPool::ReleaseOneConnection));
3797 ClientSocketHandle handle;
3798 TestCompletionCallback callback2;
3799 EXPECT_EQ(ERR_IO_PENDING,
3800 handle.Init("group2", params_, DEFAULT_PRIORITY, SocketTag(),
3801 ClientSocketPool::RespectLimits::ENABLED,
3802 callback2.callback(), pool_.get(), NetLogWithSource()));
3803 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3804}
3805
3806// Tests the case when an idle socket can be closed when a new request is
3807// issued, and the new request belongs to a group that was previously stalled.
3808TEST_F(ClientSocketPoolBaseTest,
3809 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded) {
3810 CreatePool(2, 2);
3811 std::list<TestConnectJob::JobType> job_types;
3812 job_types.push_back(TestConnectJob::kMockJob);
3813 job_types.push_back(TestConnectJob::kMockJob);
3814 job_types.push_back(TestConnectJob::kMockJob);
3815 job_types.push_back(TestConnectJob::kMockJob);
3816 connect_job_factory_->set_job_types(&job_types);
3817
3818 ClientSocketHandle handle1;
3819 TestCompletionCallback callback1;
3820 EXPECT_EQ(
3821 OK, handle1.Init("group1", params_, DEFAULT_PRIORITY, SocketTag(),
3822 ClientSocketPool::RespectLimits::ENABLED,
3823 callback1.callback(), pool_.get(), NetLogWithSource()));
3824
3825 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
3826 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
3827 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3828 .WillRepeatedly(Invoke(&mock_layered_pool,
3829 &MockLayeredPool::ReleaseOneConnection));
3830 mock_layered_pool.set_can_release_connection(false);
3831
3832 // The third request is made when the socket pool is in a stalled state.
3833 ClientSocketHandle handle3;
3834 TestCompletionCallback callback3;
3835 EXPECT_EQ(
3836 ERR_IO_PENDING,
3837 handle3.Init("group3", params_, DEFAULT_PRIORITY, SocketTag(),
3838 ClientSocketPool::RespectLimits::ENABLED,
3839 callback3.callback(), pool_.get(), NetLogWithSource()));
3840
3841 base::RunLoop().RunUntilIdle();
3842 EXPECT_FALSE(callback3.have_result());
3843
3844 // The fourth request is made when the pool is no longer stalled. The third
3845 // request should be serviced first, since it was issued first and has the
3846 // same priority.
3847 mock_layered_pool.set_can_release_connection(true);
3848 ClientSocketHandle handle4;
3849 TestCompletionCallback callback4;
3850 EXPECT_EQ(
3851 ERR_IO_PENDING,
3852 handle4.Init("group3", params_, DEFAULT_PRIORITY, SocketTag(),
3853 ClientSocketPool::RespectLimits::ENABLED,
3854 callback4.callback(), pool_.get(), NetLogWithSource()));
3855 EXPECT_THAT(callback3.WaitForResult(), IsOk());
3856 EXPECT_FALSE(callback4.have_result());
3857
3858 // Closing a handle should free up another socket slot.
3859 handle1.Reset();
3860 EXPECT_THAT(callback4.WaitForResult(), IsOk());
3861}
3862
3863// Tests the case when an idle socket can be closed when a new request is
3864// issued, and the new request belongs to a group that was previously stalled.
3865//
3866// The two differences from the above test are that the stalled requests are not
3867// in the same group as the layered pool's request, and the the fourth request
3868// has a higher priority than the third one, so gets a socket first.
3869TEST_F(ClientSocketPoolBaseTest,
3870 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded2) {
3871 CreatePool(2, 2);
3872 std::list<TestConnectJob::JobType> job_types;
3873 job_types.push_back(TestConnectJob::kMockJob);
3874 job_types.push_back(TestConnectJob::kMockJob);
3875 job_types.push_back(TestConnectJob::kMockJob);
3876 job_types.push_back(TestConnectJob::kMockJob);
3877 connect_job_factory_->set_job_types(&job_types);
3878
3879 ClientSocketHandle handle1;
3880 TestCompletionCallback callback1;
3881 EXPECT_EQ(
3882 OK, handle1.Init("group1", params_, DEFAULT_PRIORITY, SocketTag(),
3883 ClientSocketPool::RespectLimits::ENABLED,
3884 callback1.callback(), pool_.get(), NetLogWithSource()));
3885
3886 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
3887 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
3888 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3889 .WillRepeatedly(Invoke(&mock_layered_pool,
3890 &MockLayeredPool::ReleaseOneConnection));
3891 mock_layered_pool.set_can_release_connection(false);
3892
3893 // The third request is made when the socket pool is in a stalled state.
3894 ClientSocketHandle handle3;
3895 TestCompletionCallback callback3;
3896 EXPECT_EQ(
3897 ERR_IO_PENDING,
3898 handle3.Init("group3", params_, MEDIUM, SocketTag(),
3899 ClientSocketPool::RespectLimits::ENABLED,
3900 callback3.callback(), pool_.get(), NetLogWithSource()));
3901
3902 base::RunLoop().RunUntilIdle();
3903 EXPECT_FALSE(callback3.have_result());
3904
3905 // The fourth request is made when the pool is no longer stalled. This
3906 // request has a higher priority than the third request, so is serviced first.
3907 mock_layered_pool.set_can_release_connection(true);
3908 ClientSocketHandle handle4;
3909 TestCompletionCallback callback4;
3910 EXPECT_EQ(
3911 ERR_IO_PENDING,
3912 handle4.Init("group3", params_, HIGHEST, SocketTag(),
3913 ClientSocketPool::RespectLimits::ENABLED,
3914 callback4.callback(), pool_.get(), NetLogWithSource()));
3915 EXPECT_THAT(callback4.WaitForResult(), IsOk());
3916 EXPECT_FALSE(callback3.have_result());
3917
3918 // Closing a handle should free up another socket slot.
3919 handle1.Reset();
3920 EXPECT_THAT(callback3.WaitForResult(), IsOk());
3921}
3922
3923TEST_F(ClientSocketPoolBaseTest,
3924 CloseMultipleIdleSocketsHeldByLayeredPoolWhenNeeded) {
3925 CreatePool(1, 1);
3926 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3927
3928 MockLayeredPool mock_layered_pool1(pool_.get(), "foo");
3929 EXPECT_THAT(mock_layered_pool1.RequestSocket(pool_.get()), IsOk());
3930 EXPECT_CALL(mock_layered_pool1, CloseOneIdleConnection())
3931 .WillRepeatedly(Invoke(&mock_layered_pool1,
3932 &MockLayeredPool::ReleaseOneConnection));
3933 MockLayeredPool mock_layered_pool2(pool_.get(), "bar");
3934 EXPECT_THAT(mock_layered_pool2.RequestSocketWithoutLimits(pool_.get()),
3935 IsOk());
3936 EXPECT_CALL(mock_layered_pool2, CloseOneIdleConnection())
3937 .WillRepeatedly(Invoke(&mock_layered_pool2,
3938 &MockLayeredPool::ReleaseOneConnection));
3939 ClientSocketHandle handle;
3940 TestCompletionCallback callback;
3941 EXPECT_EQ(ERR_IO_PENDING,
3942 handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
3943 ClientSocketPool::RespectLimits::ENABLED,
3944 callback.callback(), pool_.get(), NetLogWithSource()));
3945 EXPECT_THAT(callback.WaitForResult(), IsOk());
3946}
3947
3948// Test that when a socket pool and group are at their limits, a request
3949// with RespectLimits::DISABLED triggers creation of a new socket, and gets the
3950// socket instead of a request with the same priority that was issued earlier,
3951// but has RespectLimits::ENABLED.
3952TEST_F(ClientSocketPoolBaseTest, IgnoreLimits) {
3953 CreatePool(1, 1);
3954
3955 // Issue a request to reach the socket pool limit.
3956 EXPECT_EQ(
3957 OK, StartRequestWithIgnoreLimits(
3958 "a", MAXIMUM_PRIORITY, ClientSocketPool::RespectLimits::ENABLED));
3959 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3960
3961 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3962
3963 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
3964 "a", MAXIMUM_PRIORITY,
3965 ClientSocketPool::RespectLimits::ENABLED));
3966 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3967
3968 // Issue a request that ignores the limits, so a new ConnectJob is
3969 // created.
3970 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
3971 "a", MAXIMUM_PRIORITY,
3972 ClientSocketPool::RespectLimits::DISABLED));
3973 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3974
3975 EXPECT_THAT(request(2)->WaitForResult(), IsOk());
3976 EXPECT_FALSE(request(1)->have_result());
3977}
3978
3979// Test that when a socket pool and group are at their limits, a ConnectJob
3980// issued for a request with RespectLimits::DISABLED is not cancelled when a
3981// request with RespectLimits::ENABLED issued to the same group is cancelled.
3982TEST_F(ClientSocketPoolBaseTest, IgnoreLimitsCancelOtherJob) {
3983 CreatePool(1, 1);
3984
3985 // Issue a request to reach the socket pool limit.
3986 EXPECT_EQ(
3987 OK, StartRequestWithIgnoreLimits(
3988 "a", MAXIMUM_PRIORITY, ClientSocketPool::RespectLimits::ENABLED));
3989 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3990
3991 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3992
3993 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
3994 "a", MAXIMUM_PRIORITY,
3995 ClientSocketPool::RespectLimits::ENABLED));
3996 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3997
3998 // Issue a request with RespectLimits::DISABLED, so a new ConnectJob is
3999 // created.
4000 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
4001 "a", MAXIMUM_PRIORITY,
4002 ClientSocketPool::RespectLimits::DISABLED));
4003 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4004
4005 // Cancel the pending request with RespectLimits::ENABLED. The ConnectJob
4006 // should not be cancelled.
4007 request(1)->handle()->Reset();
4008 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4009
4010 EXPECT_THAT(request(2)->WaitForResult(), IsOk());
4011 EXPECT_FALSE(request(1)->have_result());
4012}
4013
David Ghandehari9e5b5872016-07-28 09:50:04 -07004014} // namespace
4015
4016} // namespace net