1 // Copyright 2012 The Chromium Authors
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 <stdint.h>
6
7 #include <utility>
8 #include <vector>
9
10 #include "base/check_op.h"
11 #include "base/functional/bind.h"
12 #include "base/functional/callback.h"
13 #include "base/functional/callback_helpers.h"
14 #include "base/location.h"
15 #include "base/memory/raw_ptr.h"
16 #include "base/memory/ref_counted.h"
17 #include "base/memory/weak_ptr.h"
18 #include "base/notreached.h"
19 #include "base/run_loop.h"
20 #include "base/strings/string_number_conversions.h"
21 #include "base/strings/stringprintf.h"
22 #include "base/task/single_thread_task_runner.h"
23 #include "base/test/scoped_feature_list.h"
24 #include "base/threading/platform_thread.h"
25 #include "base/time/time.h"
26 #include "base/values.h"
27 #include "net/base/features.h"
28 #include "net/base/host_port_pair.h"
29 #include "net/base/load_timing_info.h"
30 #include "net/base/load_timing_info_test_util.h"
31 #include "net/base/net_errors.h"
32 #include "net/base/network_anonymization_key.h"
33 #include "net/base/privacy_mode.h"
34 #include "net/base/proxy_chain.h"
35 #include "net/base/proxy_string_util.h"
36 #include "net/base/request_priority.h"
37 #include "net/base/schemeful_site.h"
38 #include "net/base/test_completion_callback.h"
39 #include "net/dns/public/resolve_error_info.h"
40 #include "net/dns/public/secure_dns_policy.h"
41 #include "net/http/http_response_headers.h"
42 #include "net/http/http_response_info.h"
43 #include "net/log/net_log.h"
44 #include "net/log/net_log_event_type.h"
45 #include "net/log/net_log_source.h"
46 #include "net/log/net_log_source_type.h"
47 #include "net/log/test_net_log.h"
48 #include "net/log/test_net_log_util.h"
49 #include "net/socket/client_socket_factory.h"
50 #include "net/socket/client_socket_handle.h"
51 #include "net/socket/connect_job_factory.h"
52 #include "net/socket/datagram_client_socket.h"
53 #include "net/socket/socket_performance_watcher.h"
54 #include "net/socket/socket_tag.h"
55 #include "net/socket/socket_test_util.h"
56 #include "net/socket/ssl_client_socket.h"
57 #include "net/socket/stream_socket.h"
58 #include "net/socket/transport_client_socket_pool.h"
59 #include "net/socket/transport_connect_job.h"
60 #include "net/ssl/ssl_cert_request_info.h"
61 #include "net/test/gtest_util.h"
62 #include "net/test/test_with_task_environment.h"
63 #include "net/traffic_annotation/network_traffic_annotation.h"
64 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
65 #include "testing/gmock/include/gmock/gmock.h"
66 #include "testing/gtest/include/gtest/gtest.h"
67 #include "third_party/abseil-cpp/absl/types/optional.h"
68 #include "url/scheme_host_port.h"
69 #include "url/url_constants.h"
70
71 using net::test::IsError;
72 using net::test::IsOk;
73
74 using ::testing::Invoke;
75 using ::testing::Return;
76
77 namespace net {
78
79 namespace {
80
81 const int kDefaultMaxSockets = 4;
82 const int kDefaultMaxSocketsPerGroup = 2;
83 constexpr base::TimeDelta kUnusedIdleSocketTimeout = base::Seconds(10);
84
TestGroupId(base::StringPiece host,int port=80,base::StringPiece scheme=url::kHttpScheme,PrivacyMode privacy_mode=PrivacyMode::PRIVACY_MODE_DISABLED,NetworkAnonymizationKey network_anonymization_key=NetworkAnonymizationKey ())85 ClientSocketPool::GroupId TestGroupId(
86 base::StringPiece host,
87 int port = 80,
88 base::StringPiece scheme = url::kHttpScheme,
89 PrivacyMode privacy_mode = PrivacyMode::PRIVACY_MODE_DISABLED,
90 NetworkAnonymizationKey network_anonymization_key =
91 NetworkAnonymizationKey()) {
92 return ClientSocketPool::GroupId(url::SchemeHostPort(scheme, host, port),
93 privacy_mode, network_anonymization_key,
94 SecureDnsPolicy::kAllow);
95 }
96
97 // Make sure |handle| sets load times correctly when it has been assigned a
98 // reused socket.
TestLoadTimingInfoConnectedReused(const ClientSocketHandle & handle)99 void TestLoadTimingInfoConnectedReused(const ClientSocketHandle& handle) {
100 LoadTimingInfo load_timing_info;
101 // Only pass true in as |is_reused|, as in general, HttpStream types should
102 // have stricter concepts of reuse than socket pools.
103 EXPECT_TRUE(handle.GetLoadTimingInfo(true, &load_timing_info));
104
105 EXPECT_EQ(true, load_timing_info.socket_reused);
106 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
107
108 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
109 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
110 }
111
112 // Make sure |handle| sets load times correctly when it has been assigned a
113 // fresh socket. Also runs TestLoadTimingInfoConnectedReused, since the owner
114 // of a connection where |is_reused| is false may consider the connection
115 // reused.
TestLoadTimingInfoConnectedNotReused(const ClientSocketHandle & handle)116 void TestLoadTimingInfoConnectedNotReused(const ClientSocketHandle& handle) {
117 EXPECT_FALSE(handle.is_reused());
118
119 LoadTimingInfo load_timing_info;
120 EXPECT_TRUE(handle.GetLoadTimingInfo(false, &load_timing_info));
121
122 EXPECT_FALSE(load_timing_info.socket_reused);
123 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
124
125 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
126 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
127 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
128
129 TestLoadTimingInfoConnectedReused(handle);
130 }
131
132 // Make sure |handle| sets load times correctly, in the case that it does not
133 // currently have a socket.
TestLoadTimingInfoNotConnected(const ClientSocketHandle & handle)134 void TestLoadTimingInfoNotConnected(const ClientSocketHandle& handle) {
135 // Should only be set to true once a socket is assigned, if at all.
136 EXPECT_FALSE(handle.is_reused());
137
138 LoadTimingInfo load_timing_info;
139 EXPECT_FALSE(handle.GetLoadTimingInfo(false, &load_timing_info));
140
141 EXPECT_FALSE(load_timing_info.socket_reused);
142 EXPECT_EQ(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
143
144 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
145 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
146 }
147
148 class MockClientSocket : public StreamSocket {
149 public:
MockClientSocket(net::NetLog * net_log)150 explicit MockClientSocket(net::NetLog* net_log)
151 : net_log_(NetLogWithSource::Make(net_log, NetLogSourceType::SOCKET)) {}
152
153 MockClientSocket(const MockClientSocket&) = delete;
154 MockClientSocket& operator=(const MockClientSocket&) = delete;
155
156 // Sets whether the socket has unread data. If true, the next call to Read()
157 // will return 1 byte and IsConnectedAndIdle() will return false.
set_has_unread_data(bool has_unread_data)158 void set_has_unread_data(bool has_unread_data) {
159 has_unread_data_ = has_unread_data;
160 }
161
162 // Socket implementation.
Read(IOBuffer *,int len,CompletionOnceCallback)163 int Read(IOBuffer* /* buf */,
164 int len,
165 CompletionOnceCallback /* callback */) override {
166 if (has_unread_data_ && len > 0) {
167 has_unread_data_ = false;
168 was_used_to_convey_data_ = true;
169 return 1;
170 }
171 return ERR_UNEXPECTED;
172 }
173
Write(IOBuffer *,int len,CompletionOnceCallback,const NetworkTrafficAnnotationTag &)174 int Write(
175 IOBuffer* /* buf */,
176 int len,
177 CompletionOnceCallback /* callback */,
178 const NetworkTrafficAnnotationTag& /*traffic_annotation*/) override {
179 was_used_to_convey_data_ = true;
180 return len;
181 }
SetReceiveBufferSize(int32_t size)182 int SetReceiveBufferSize(int32_t size) override { return OK; }
SetSendBufferSize(int32_t size)183 int SetSendBufferSize(int32_t size) override { return OK; }
184
185 // StreamSocket implementation.
Connect(CompletionOnceCallback callback)186 int Connect(CompletionOnceCallback callback) override {
187 connected_ = true;
188 return OK;
189 }
190
Disconnect()191 void Disconnect() override { connected_ = false; }
IsConnected() const192 bool IsConnected() const override { return connected_; }
IsConnectedAndIdle() const193 bool IsConnectedAndIdle() const override {
194 return connected_ && !has_unread_data_;
195 }
196
GetPeerAddress(IPEndPoint *) const197 int GetPeerAddress(IPEndPoint* /* address */) const override {
198 return ERR_UNEXPECTED;
199 }
200
GetLocalAddress(IPEndPoint *) const201 int GetLocalAddress(IPEndPoint* /* address */) const override {
202 return ERR_UNEXPECTED;
203 }
204
NetLog() const205 const NetLogWithSource& NetLog() const override { return net_log_; }
206
WasEverUsed() const207 bool WasEverUsed() const override { return was_used_to_convey_data_; }
GetNegotiatedProtocol() const208 NextProto GetNegotiatedProtocol() const override { return kProtoUnknown; }
GetSSLInfo(SSLInfo * ssl_info)209 bool GetSSLInfo(SSLInfo* ssl_info) override { return false; }
GetTotalReceivedBytes() const210 int64_t GetTotalReceivedBytes() const override {
211 NOTIMPLEMENTED();
212 return 0;
213 }
ApplySocketTag(const SocketTag & tag)214 void ApplySocketTag(const SocketTag& tag) override {}
215
216 private:
217 bool connected_ = false;
218 bool has_unread_data_ = false;
219 NetLogWithSource net_log_;
220 bool was_used_to_convey_data_ = false;
221 };
222
223 class TestConnectJob;
224
225 class MockClientSocketFactory : public ClientSocketFactory {
226 public:
227 MockClientSocketFactory() = default;
228
CreateDatagramClientSocket(DatagramSocket::BindType bind_type,NetLog * net_log,const NetLogSource & source)229 std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
230 DatagramSocket::BindType bind_type,
231 NetLog* net_log,
232 const NetLogSource& source) override {
233 NOTREACHED();
234 return nullptr;
235 }
236
CreateTransportClientSocket(const AddressList & addresses,std::unique_ptr<SocketPerformanceWatcher>,NetworkQualityEstimator *,NetLog *,const NetLogSource &)237 std::unique_ptr<TransportClientSocket> CreateTransportClientSocket(
238 const AddressList& addresses,
239 std::unique_ptr<
240 SocketPerformanceWatcher> /* socket_performance_watcher */,
241 NetworkQualityEstimator* /* network_quality_estimator */,
242 NetLog* /* net_log */,
243 const NetLogSource& /*source*/) override {
244 allocation_count_++;
245 return nullptr;
246 }
247
CreateSSLClientSocket(SSLClientContext * context,std::unique_ptr<StreamSocket> stream_socket,const HostPortPair & host_and_port,const SSLConfig & ssl_config)248 std::unique_ptr<SSLClientSocket> CreateSSLClientSocket(
249 SSLClientContext* context,
250 std::unique_ptr<StreamSocket> stream_socket,
251 const HostPortPair& host_and_port,
252 const SSLConfig& ssl_config) override {
253 NOTIMPLEMENTED();
254 return nullptr;
255 }
256
WaitForSignal(TestConnectJob * job)257 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
258
259 void SignalJobs();
260
261 void SignalJob(size_t job);
262
263 void SetJobLoadState(size_t job, LoadState load_state);
264
265 // Sets the HasConnectionEstablished value of the specified job to true,
266 // without invoking the callback.
267 void SetJobHasEstablishedConnection(size_t job);
268
allocation_count() const269 int allocation_count() const { return allocation_count_; }
270
271 private:
272 int allocation_count_ = 0;
273 std::vector<TestConnectJob*> waiting_jobs_;
274 };
275
276 class TestConnectJob : public ConnectJob {
277 public:
278 enum JobType {
279 kMockJob,
280 kMockFailingJob,
281 kMockPendingJob,
282 kMockPendingFailingJob,
283 kMockWaitingJob,
284
285 // Certificate errors return a socket in addition to an error code.
286 kMockCertErrorJob,
287 kMockPendingCertErrorJob,
288
289 kMockAdditionalErrorStateJob,
290 kMockPendingAdditionalErrorStateJob,
291 kMockUnreadDataJob,
292
293 kMockAuthChallengeOnceJob,
294 kMockAuthChallengeTwiceJob,
295 kMockAuthChallengeOnceFailingJob,
296 kMockAuthChallengeTwiceFailingJob,
297 };
298
299 // The kMockPendingJob uses a slight delay before allowing the connect
300 // to complete.
301 static const int kPendingConnectDelay = 2;
302
TestConnectJob(JobType job_type,RequestPriority request_priority,SocketTag socket_tag,base::TimeDelta timeout_duration,const CommonConnectJobParams * common_connect_job_params,ConnectJob::Delegate * delegate,MockClientSocketFactory * client_socket_factory)303 TestConnectJob(JobType job_type,
304 RequestPriority request_priority,
305 SocketTag socket_tag,
306 base::TimeDelta timeout_duration,
307 const CommonConnectJobParams* common_connect_job_params,
308 ConnectJob::Delegate* delegate,
309 MockClientSocketFactory* client_socket_factory)
310 : ConnectJob(request_priority,
311 socket_tag,
312 timeout_duration,
313 common_connect_job_params,
314 delegate,
315 nullptr /* net_log */,
316 NetLogSourceType::TRANSPORT_CONNECT_JOB,
317 NetLogEventType::TRANSPORT_CONNECT_JOB_CONNECT),
318 job_type_(job_type),
319 client_socket_factory_(client_socket_factory) {}
320
321 TestConnectJob(const TestConnectJob&) = delete;
322 TestConnectJob& operator=(const TestConnectJob&) = delete;
323
Signal()324 void Signal() {
325 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
326 }
327
set_load_state(LoadState load_state)328 void set_load_state(LoadState load_state) { load_state_ = load_state; }
329
set_has_established_connection()330 void set_has_established_connection() {
331 DCHECK(!has_established_connection_);
332 has_established_connection_ = true;
333 }
334
335 // From ConnectJob:
336
GetLoadState() const337 LoadState GetLoadState() const override { return load_state_; }
338
HasEstablishedConnection() const339 bool HasEstablishedConnection() const override {
340 return has_established_connection_;
341 }
342
GetResolveErrorInfo() const343 ResolveErrorInfo GetResolveErrorInfo() const override {
344 return ResolveErrorInfo(OK);
345 }
346
IsSSLError() const347 bool IsSSLError() const override { return store_additional_error_state_; }
348
GetCertRequestInfo()349 scoped_refptr<SSLCertRequestInfo> GetCertRequestInfo() override {
350 if (store_additional_error_state_)
351 return base::MakeRefCounted<SSLCertRequestInfo>();
352 return nullptr;
353 }
354
355 private:
356 // From ConnectJob:
357
ConnectInternal()358 int ConnectInternal() override {
359 AddressList ignored;
360 client_socket_factory_->CreateTransportClientSocket(
361 ignored, nullptr, nullptr, nullptr, NetLogSource());
362 switch (job_type_) {
363 case kMockJob:
364 return DoConnect(true /* successful */, false /* sync */,
365 false /* cert_error */);
366 case kMockFailingJob:
367 return DoConnect(false /* error */, false /* sync */,
368 false /* cert_error */);
369 case kMockPendingJob:
370 set_load_state(LOAD_STATE_CONNECTING);
371
372 // Depending on execution timings, posting a delayed task can result
373 // in the task getting executed the at the earliest possible
374 // opportunity or only after returning once from the message loop and
375 // then a second call into the message loop. In order to make behavior
376 // more deterministic, we change the default delay to 2ms. This should
377 // always require us to wait for the second call into the message loop.
378 //
379 // N.B. The correct fix for this and similar timing problems is to
380 // abstract time for the purpose of unittests. Unfortunately, we have
381 // a lot of third-party components that directly call the various
382 // time functions, so this change would be rather invasive.
383 base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
384 FROM_HERE,
385 base::BindOnce(base::IgnoreResult(&TestConnectJob::DoConnect),
386 weak_factory_.GetWeakPtr(), true /* successful */,
387 true /* async */, false /* cert_error */),
388 base::Milliseconds(kPendingConnectDelay));
389 return ERR_IO_PENDING;
390 case kMockPendingFailingJob:
391 set_load_state(LOAD_STATE_CONNECTING);
392 base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
393 FROM_HERE,
394 base::BindOnce(base::IgnoreResult(&TestConnectJob::DoConnect),
395 weak_factory_.GetWeakPtr(), false /* error */,
396 true /* async */, false /* cert_error */),
397 base::Milliseconds(2));
398 return ERR_IO_PENDING;
399 case kMockWaitingJob:
400 set_load_state(LOAD_STATE_CONNECTING);
401 client_socket_factory_->WaitForSignal(this);
402 waiting_success_ = true;
403 return ERR_IO_PENDING;
404 case kMockCertErrorJob:
405 return DoConnect(false /* error */, false /* sync */,
406 true /* cert_error */);
407 case kMockPendingCertErrorJob:
408 set_load_state(LOAD_STATE_CONNECTING);
409 base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
410 FROM_HERE,
411 base::BindOnce(base::IgnoreResult(&TestConnectJob::DoConnect),
412 weak_factory_.GetWeakPtr(), false /* error */,
413 true /* async */, true /* cert_error */),
414 base::Milliseconds(2));
415 return ERR_IO_PENDING;
416 case kMockAdditionalErrorStateJob:
417 store_additional_error_state_ = true;
418 return DoConnect(false /* error */, false /* sync */,
419 false /* cert_error */);
420 case kMockPendingAdditionalErrorStateJob:
421 set_load_state(LOAD_STATE_CONNECTING);
422 store_additional_error_state_ = true;
423 base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
424 FROM_HERE,
425 base::BindOnce(base::IgnoreResult(&TestConnectJob::DoConnect),
426 weak_factory_.GetWeakPtr(), false /* error */,
427 true /* async */, false /* cert_error */),
428 base::Milliseconds(2));
429 return ERR_IO_PENDING;
430 case kMockUnreadDataJob: {
431 int ret = DoConnect(true /* successful */, false /* sync */,
432 false /* cert_error */);
433 static_cast<MockClientSocket*>(socket())->set_has_unread_data(true);
434 return ret;
435 }
436 case kMockAuthChallengeOnceJob:
437 set_load_state(LOAD_STATE_CONNECTING);
438 DoAdvanceAuthChallenge(1, true /* succeed_after_last_challenge */);
439 return ERR_IO_PENDING;
440 case kMockAuthChallengeTwiceJob:
441 set_load_state(LOAD_STATE_CONNECTING);
442 DoAdvanceAuthChallenge(2, true /* succeed_after_last_challenge */);
443 return ERR_IO_PENDING;
444 case kMockAuthChallengeOnceFailingJob:
445 set_load_state(LOAD_STATE_CONNECTING);
446 DoAdvanceAuthChallenge(1, false /* succeed_after_last_challenge */);
447 return ERR_IO_PENDING;
448 case kMockAuthChallengeTwiceFailingJob:
449 set_load_state(LOAD_STATE_CONNECTING);
450 DoAdvanceAuthChallenge(2, false /* succeed_after_last_challenge */);
451 return ERR_IO_PENDING;
452 default:
453 NOTREACHED();
454 SetSocket(std::unique_ptr<StreamSocket>(), absl::nullopt);
455 return ERR_FAILED;
456 }
457 }
458
ChangePriorityInternal(RequestPriority priority)459 void ChangePriorityInternal(RequestPriority priority) override {}
460
DoConnect(bool succeed,bool was_async,bool cert_error)461 int DoConnect(bool succeed, bool was_async, bool cert_error) {
462 int result = OK;
463 has_established_connection_ = true;
464 if (succeed) {
465 SetSocket(std::make_unique<MockClientSocket>(net_log().net_log()),
466 absl::nullopt);
467 socket()->Connect(CompletionOnceCallback());
468 } else if (cert_error) {
469 SetSocket(std::make_unique<MockClientSocket>(net_log().net_log()),
470 absl::nullopt);
471 result = ERR_CERT_COMMON_NAME_INVALID;
472 } else {
473 result = ERR_CONNECTION_FAILED;
474 SetSocket(std::unique_ptr<StreamSocket>(), absl::nullopt);
475 }
476
477 if (was_async)
478 NotifyDelegateOfCompletion(result);
479 return result;
480 }
481
DoAdvanceAuthChallenge(int remaining_challenges,bool succeed_after_last_challenge)482 void DoAdvanceAuthChallenge(int remaining_challenges,
483 bool succeed_after_last_challenge) {
484 base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
485 FROM_HERE,
486 base::BindOnce(&TestConnectJob::InvokeNextProxyAuthCallback,
487 weak_factory_.GetWeakPtr(), remaining_challenges,
488 succeed_after_last_challenge));
489 }
490
InvokeNextProxyAuthCallback(int remaining_challenges,bool succeed_after_last_challenge)491 void InvokeNextProxyAuthCallback(int remaining_challenges,
492 bool succeed_after_last_challenge) {
493 set_load_state(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL);
494 if (remaining_challenges == 0) {
495 DoConnect(succeed_after_last_challenge, true /* was_async */,
496 false /* cert_error */);
497 return;
498 }
499
500 // Integration tests make sure HttpResponseInfo and HttpAuthController work.
501 // The auth tests here are just focused on ConnectJob bookkeeping.
502 HttpResponseInfo info;
503 NotifyDelegateOfProxyAuth(
504 info, nullptr /* http_auth_controller */,
505 base::BindOnce(&TestConnectJob::DoAdvanceAuthChallenge,
506 weak_factory_.GetWeakPtr(), remaining_challenges - 1,
507 succeed_after_last_challenge));
508 }
509
510 bool waiting_success_;
511 const JobType job_type_;
512 const raw_ptr<MockClientSocketFactory> client_socket_factory_;
513 LoadState load_state_ = LOAD_STATE_IDLE;
514 bool has_established_connection_ = false;
515 bool store_additional_error_state_ = false;
516
517 base::WeakPtrFactory<TestConnectJob> weak_factory_{this};
518 };
519
520 class TestConnectJobFactory : public ConnectJobFactory {
521 public:
TestConnectJobFactory(MockClientSocketFactory * client_socket_factory)522 explicit TestConnectJobFactory(MockClientSocketFactory* client_socket_factory)
523 : client_socket_factory_(client_socket_factory) {}
524
525 TestConnectJobFactory(const TestConnectJobFactory&) = delete;
526 TestConnectJobFactory& operator=(const TestConnectJobFactory&) = delete;
527
528 ~TestConnectJobFactory() override = default;
529
set_job_type(TestConnectJob::JobType job_type)530 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
531
set_job_types(std::list<TestConnectJob::JobType> * job_types)532 void set_job_types(std::list<TestConnectJob::JobType>* job_types) {
533 job_types_ = job_types;
534 CHECK(!job_types_->empty());
535 }
536
set_timeout_duration(base::TimeDelta timeout_duration)537 void set_timeout_duration(base::TimeDelta timeout_duration) {
538 timeout_duration_ = timeout_duration;
539 }
540
541 // ConnectJobFactory implementation.
542
CreateConnectJob(Endpoint endpoint,const ProxyChain & proxy_chain,const absl::optional<NetworkTrafficAnnotationTag> & proxy_annotation_tag,const SSLConfig * ssl_config_for_origin,const SSLConfig * base_ssl_configs_for_proxies,bool force_tunnel,PrivacyMode privacy_mode,const OnHostResolutionCallback & resolution_callback,RequestPriority request_priority,SocketTag socket_tag,const NetworkAnonymizationKey & network_anonymization_key,SecureDnsPolicy secure_dns_policy,const CommonConnectJobParams * common_connect_job_params,ConnectJob::Delegate * delegate) const543 std::unique_ptr<ConnectJob> CreateConnectJob(
544 Endpoint endpoint,
545 const ProxyChain& proxy_chain,
546 const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
547 const SSLConfig* ssl_config_for_origin,
548 const SSLConfig* base_ssl_configs_for_proxies,
549 bool force_tunnel,
550 PrivacyMode privacy_mode,
551 const OnHostResolutionCallback& resolution_callback,
552 RequestPriority request_priority,
553 SocketTag socket_tag,
554 const NetworkAnonymizationKey& network_anonymization_key,
555 SecureDnsPolicy secure_dns_policy,
556 const CommonConnectJobParams* common_connect_job_params,
557 ConnectJob::Delegate* delegate) const override {
558 EXPECT_TRUE(!job_types_ || !job_types_->empty());
559 TestConnectJob::JobType job_type = job_type_;
560 if (job_types_ && !job_types_->empty()) {
561 job_type = job_types_->front();
562 job_types_->pop_front();
563 }
564 return std::make_unique<TestConnectJob>(
565 job_type, request_priority, socket_tag, timeout_duration_,
566 common_connect_job_params, delegate, client_socket_factory_);
567 }
568
569 private:
570 TestConnectJob::JobType job_type_ = TestConnectJob::kMockJob;
571 raw_ptr<std::list<TestConnectJob::JobType>> job_types_ = nullptr;
572 base::TimeDelta timeout_duration_;
573 const raw_ptr<MockClientSocketFactory> client_socket_factory_;
574 };
575
576 } // namespace
577
578 namespace {
579
SignalJobs()580 void MockClientSocketFactory::SignalJobs() {
581 for (auto* waiting_job : waiting_jobs_) {
582 waiting_job->Signal();
583 }
584 waiting_jobs_.clear();
585 }
586
SignalJob(size_t job)587 void MockClientSocketFactory::SignalJob(size_t job) {
588 ASSERT_LT(job, waiting_jobs_.size());
589 waiting_jobs_[job]->Signal();
590 waiting_jobs_.erase(waiting_jobs_.begin() + job);
591 }
592
SetJobLoadState(size_t job,LoadState load_state)593 void MockClientSocketFactory::SetJobLoadState(size_t job,
594 LoadState load_state) {
595 ASSERT_LT(job, waiting_jobs_.size());
596 waiting_jobs_[job]->set_load_state(load_state);
597 }
598
SetJobHasEstablishedConnection(size_t job)599 void MockClientSocketFactory::SetJobHasEstablishedConnection(size_t job) {
600 ASSERT_LT(job, waiting_jobs_.size());
601 waiting_jobs_[job]->set_has_established_connection();
602 }
603
604 class ClientSocketPoolBaseTest : public TestWithTaskEnvironment {
605 protected:
ClientSocketPoolBaseTest()606 ClientSocketPoolBaseTest()
607 : TestWithTaskEnvironment(
608 base::test::TaskEnvironment::TimeSource::MOCK_TIME),
609 params_(ClientSocketPool::SocketParams::CreateForHttpForTesting()) {
610 connect_backup_jobs_enabled_ =
611 TransportClientSocketPool::connect_backup_jobs_enabled();
612 TransportClientSocketPool::set_connect_backup_jobs_enabled(true);
613 }
614
~ClientSocketPoolBaseTest()615 ~ClientSocketPoolBaseTest() override {
616 TransportClientSocketPool::set_connect_backup_jobs_enabled(
617 connect_backup_jobs_enabled_);
618 }
619
CreatePool(int max_sockets,int max_sockets_per_group,bool enable_backup_connect_jobs=false)620 void CreatePool(int max_sockets,
621 int max_sockets_per_group,
622 bool enable_backup_connect_jobs = false) {
623 CreatePoolWithIdleTimeouts(max_sockets, max_sockets_per_group,
624 kUnusedIdleSocketTimeout,
625 ClientSocketPool::used_idle_socket_timeout(),
626 enable_backup_connect_jobs);
627 }
628
CreatePoolWithIdleTimeouts(int max_sockets,int max_sockets_per_group,base::TimeDelta unused_idle_socket_timeout,base::TimeDelta used_idle_socket_timeout,bool enable_backup_connect_jobs=false,ProxyChain proxy_chain=ProxyChain::Direct ())629 void CreatePoolWithIdleTimeouts(
630 int max_sockets,
631 int max_sockets_per_group,
632 base::TimeDelta unused_idle_socket_timeout,
633 base::TimeDelta used_idle_socket_timeout,
634 bool enable_backup_connect_jobs = false,
635 ProxyChain proxy_chain = ProxyChain::Direct()) {
636 DCHECK(!pool_.get());
637 std::unique_ptr<TestConnectJobFactory> connect_job_factory =
638 std::make_unique<TestConnectJobFactory>(&client_socket_factory_);
639 connect_job_factory_ = connect_job_factory.get();
640 pool_ = TransportClientSocketPool::CreateForTesting(
641 max_sockets, max_sockets_per_group, unused_idle_socket_timeout,
642 used_idle_socket_timeout, proxy_chain, /*is_for_websockets=*/false,
643 &common_connect_job_params_, std::move(connect_job_factory),
644 nullptr /* ssl_config_service */, enable_backup_connect_jobs);
645 }
646
StartRequestWithIgnoreLimits(const ClientSocketPool::GroupId & group_id,RequestPriority priority,ClientSocketPool::RespectLimits respect_limits)647 int StartRequestWithIgnoreLimits(
648 const ClientSocketPool::GroupId& group_id,
649 RequestPriority priority,
650 ClientSocketPool::RespectLimits respect_limits) {
651 return test_base_.StartRequestUsingPool(pool_.get(), group_id, priority,
652 respect_limits, params_);
653 }
654
StartRequest(const ClientSocketPool::GroupId & group_id,RequestPriority priority)655 int StartRequest(const ClientSocketPool::GroupId& group_id,
656 RequestPriority priority) {
657 return StartRequestWithIgnoreLimits(
658 group_id, priority, ClientSocketPool::RespectLimits::ENABLED);
659 }
660
GetOrderOfRequest(size_t index) const661 int GetOrderOfRequest(size_t index) const {
662 return test_base_.GetOrderOfRequest(index);
663 }
664
ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive)665 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
666 return test_base_.ReleaseOneConnection(keep_alive);
667 }
668
ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive)669 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
670 test_base_.ReleaseAllConnections(keep_alive);
671 }
672
673 // Expects a single NetLogEventType::SOCKET_POOL_CLOSING_SOCKET in |net_log_|.
674 // It should be logged for the provided source and have the indicated reason.
ExpectSocketClosedWithReason(NetLogSource expected_source,const char * expected_reason)675 void ExpectSocketClosedWithReason(NetLogSource expected_source,
676 const char* expected_reason) {
677 auto entries = net_log_observer_.GetEntriesForSourceWithType(
678 expected_source, NetLogEventType::SOCKET_POOL_CLOSING_SOCKET,
679 NetLogEventPhase::NONE);
680 ASSERT_EQ(1u, entries.size());
681 ASSERT_TRUE(entries[0].HasParams());
682 const std::string* reason = entries[0].params.FindString("reason");
683 ASSERT_TRUE(reason);
684 EXPECT_EQ(expected_reason, *reason);
685 }
686
request(int i)687 TestSocketRequest* request(int i) { return test_base_.request(i); }
requests_size() const688 size_t requests_size() const { return test_base_.requests_size(); }
requests()689 std::vector<std::unique_ptr<TestSocketRequest>>* requests() {
690 return test_base_.requests();
691 }
692 // Only counts the requests that get sockets asynchronously;
693 // synchronous completions are not registered by this count.
completion_count() const694 size_t completion_count() const { return test_base_.completion_count(); }
695
696 const CommonConnectJobParams common_connect_job_params_{
697 /*client_socket_factory=*/nullptr,
698 /*host_resolver=*/nullptr,
699 /*http_auth_cache=*/nullptr,
700 /*http_auth_handler_factory=*/nullptr,
701 /*spdy_session_pool=*/nullptr,
702 /*quic_supported_versions=*/nullptr,
703 /*quic_stream_factory=*/nullptr,
704 /*proxy_delegate=*/nullptr,
705 /*http_user_agent_settings=*/nullptr,
706 /*ssl_client_context=*/nullptr,
707 /*socket_performance_watcher_factory=*/nullptr,
708 /*network_quality_estimator=*/nullptr,
709 NetLog::Get(),
710 /*websocket_endpoint_lock_manager=*/nullptr,
711 /*http_server_properties=*/nullptr,
712 /*alpn_protos=*/nullptr,
713 /*application_settings=*/nullptr,
714 /*ignore_certificate_errors=*/nullptr};
715 bool connect_backup_jobs_enabled_;
716 MockClientSocketFactory client_socket_factory_;
717 RecordingNetLogObserver net_log_observer_;
718
719 // These parameters are never actually used to create a TransportConnectJob.
720 scoped_refptr<ClientSocketPool::SocketParams> params_;
721
722 // Must outlive `connect_job_factory_`
723 std::unique_ptr<TransportClientSocketPool> pool_;
724
725 raw_ptr<TestConnectJobFactory> connect_job_factory_;
726 ClientSocketPoolTest test_base_;
727 };
728
TEST_F(ClientSocketPoolBaseTest,BasicSynchronous)729 TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
730 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
731
732 TestCompletionCallback callback;
733 ClientSocketHandle handle;
734 NetLogWithSource net_log_with_source =
735 NetLogWithSource::Make(NetLogSourceType::NONE);
736
737 TestLoadTimingInfoNotConnected(handle);
738
739 EXPECT_EQ(OK, handle.Init(
740 TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
741 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
742 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
743 pool_.get(), net_log_with_source));
744 EXPECT_TRUE(handle.is_initialized());
745 EXPECT_TRUE(handle.socket());
746 TestLoadTimingInfoConnectedNotReused(handle);
747
748 handle.Reset();
749 TestLoadTimingInfoNotConnected(handle);
750
751 auto entries =
752 net_log_observer_.GetEntriesForSource(net_log_with_source.source());
753
754 EXPECT_EQ(5u, entries.size());
755 EXPECT_TRUE(LogContainsEvent(
756 entries, 0, NetLogEventType::TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET,
757 NetLogEventPhase::NONE));
758 EXPECT_TRUE(LogContainsBeginEvent(entries, 1, NetLogEventType::SOCKET_POOL));
759 EXPECT_TRUE(LogContainsEvent(
760 entries, 2, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
761 NetLogEventPhase::NONE));
762 EXPECT_TRUE(LogContainsEvent(entries, 3,
763 NetLogEventType::SOCKET_POOL_BOUND_TO_SOCKET,
764 NetLogEventPhase::NONE));
765 EXPECT_TRUE(LogContainsEndEvent(entries, 4, NetLogEventType::SOCKET_POOL));
766 }
767
TEST_F(ClientSocketPoolBaseTest,InitConnectionFailure)768 TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
769 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
770
771 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
772 NetLogWithSource net_log_with_source =
773 NetLogWithSource::Make(NetLogSourceType::NONE);
774
775 ClientSocketHandle handle;
776 TestCompletionCallback callback;
777 // Set the additional error state members to ensure that they get cleared.
778 handle.set_is_ssl_error(true);
779 handle.set_ssl_cert_request_info(base::MakeRefCounted<SSLCertRequestInfo>());
780 EXPECT_EQ(
781 ERR_CONNECTION_FAILED,
782 handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
783 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
784 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
785 pool_.get(), net_log_with_source));
786 EXPECT_FALSE(handle.socket());
787 EXPECT_FALSE(handle.is_ssl_error());
788 EXPECT_FALSE(handle.ssl_cert_request_info());
789 TestLoadTimingInfoNotConnected(handle);
790
791 auto entries =
792 net_log_observer_.GetEntriesForSource(net_log_with_source.source());
793
794 EXPECT_EQ(4u, entries.size());
795 EXPECT_TRUE(LogContainsEvent(
796 entries, 0, NetLogEventType::TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET,
797 NetLogEventPhase::NONE));
798 EXPECT_TRUE(LogContainsBeginEvent(entries, 1, NetLogEventType::SOCKET_POOL));
799 EXPECT_TRUE(LogContainsEvent(
800 entries, 2, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
801 NetLogEventPhase::NONE));
802 EXPECT_TRUE(LogContainsEndEvent(entries, 3, NetLogEventType::SOCKET_POOL));
803 }
804
805 // Test releasing an open socket into the socket pool, telling the socket pool
806 // to close the socket.
TEST_F(ClientSocketPoolBaseTest,ReleaseAndCloseConnection)807 TEST_F(ClientSocketPoolBaseTest, ReleaseAndCloseConnection) {
808 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
809
810 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
811 ASSERT_TRUE(request(0)->handle()->socket());
812 net::NetLogSource source = request(0)->handle()->socket()->NetLog().source();
813 ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE);
814
815 EXPECT_EQ(0, pool_->IdleSocketCount());
816 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
817
818 ExpectSocketClosedWithReason(
819 source, TransportClientSocketPool::kClosedConnectionReturnedToPool);
820 }
821
TEST_F(ClientSocketPoolBaseTest,SocketWithUnreadDataReturnedToPool)822 TEST_F(ClientSocketPoolBaseTest, SocketWithUnreadDataReturnedToPool) {
823 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
824 connect_job_factory_->set_job_type(TestConnectJob::kMockUnreadDataJob);
825
826 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
827 ASSERT_TRUE(request(0)->handle()->socket());
828 net::NetLogSource source = request(0)->handle()->socket()->NetLog().source();
829 EXPECT_TRUE(request(0)->handle()->socket()->IsConnected());
830 EXPECT_FALSE(request(0)->handle()->socket()->IsConnectedAndIdle());
831 ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE);
832
833 EXPECT_EQ(0, pool_->IdleSocketCount());
834 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
835
836 ExpectSocketClosedWithReason(
837 source, TransportClientSocketPool::kDataReceivedUnexpectedly);
838 }
839
840 // Make sure different groups do not share sockets.
TEST_F(ClientSocketPoolBaseTest,GroupSeparation)841 TEST_F(ClientSocketPoolBaseTest, GroupSeparation) {
842 base::test::ScopedFeatureList feature_list;
843 feature_list.InitAndEnableFeature(
844 features::kPartitionConnectionsByNetworkIsolationKey);
845
846 CreatePool(1000 /* max_sockets */, 2 /* max_sockets_per_group */);
847
848 const HostPortPair kHostPortPairs[] = {
849 {"a", 80},
850 {"a", 443},
851 {"b", 80},
852 };
853
854 const char* const kSchemes[] = {
855 url::kHttpScheme,
856 url::kHttpsScheme,
857 };
858
859 const PrivacyMode kPrivacyModes[] = {PrivacyMode::PRIVACY_MODE_DISABLED,
860 PrivacyMode::PRIVACY_MODE_ENABLED};
861
862 const SchemefulSite kSiteA(GURL("http://a.test/"));
863 const SchemefulSite kSiteB(GURL("http://b.test/"));
864 const NetworkAnonymizationKey kNetworkAnonymizationKeys[] = {
865 NetworkAnonymizationKey::CreateSameSite(kSiteA),
866 NetworkAnonymizationKey::CreateSameSite(kSiteB),
867 };
868
869 const SecureDnsPolicy kSecureDnsPolicys[] = {SecureDnsPolicy::kAllow,
870 SecureDnsPolicy::kDisable};
871
872 int total_idle_sockets = 0;
873
874 // Walk through each GroupId, making sure that requesting a socket for one
875 // group does not return a previously connected socket for another group.
876 for (const auto& host_port_pair : kHostPortPairs) {
877 SCOPED_TRACE(host_port_pair.ToString());
878 for (const char* scheme : kSchemes) {
879 SCOPED_TRACE(scheme);
880 for (const auto& privacy_mode : kPrivacyModes) {
881 SCOPED_TRACE(privacy_mode);
882 for (const auto& network_anonymization_key :
883 kNetworkAnonymizationKeys) {
884 SCOPED_TRACE(network_anonymization_key.ToDebugString());
885 for (const auto& secure_dns_policy : kSecureDnsPolicys) {
886 SCOPED_TRACE(static_cast<int>(secure_dns_policy));
887
888 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
889
890 ClientSocketPool::GroupId group_id(
891 url::SchemeHostPort(scheme, host_port_pair.host(),
892 host_port_pair.port()),
893 privacy_mode, network_anonymization_key, secure_dns_policy);
894
895 EXPECT_FALSE(pool_->HasGroupForTesting(group_id));
896
897 TestCompletionCallback callback;
898 ClientSocketHandle handle;
899
900 // Since the group is empty, requesting a socket should not complete
901 // synchronously.
902 EXPECT_THAT(handle.Init(group_id, params_, absl::nullopt,
903 DEFAULT_PRIORITY, SocketTag(),
904 ClientSocketPool::RespectLimits::ENABLED,
905 callback.callback(),
906 ClientSocketPool::ProxyAuthCallback(),
907 pool_.get(), NetLogWithSource()),
908 IsError(ERR_IO_PENDING));
909 EXPECT_TRUE(pool_->HasGroupForTesting(group_id));
910 EXPECT_EQ(total_idle_sockets, pool_->IdleSocketCount());
911
912 EXPECT_THAT(callback.WaitForResult(), IsOk());
913 EXPECT_TRUE(handle.socket());
914 EXPECT_TRUE(pool_->HasGroupForTesting(group_id));
915 EXPECT_EQ(total_idle_sockets, pool_->IdleSocketCount());
916
917 // Return socket to pool.
918 handle.Reset();
919 EXPECT_EQ(total_idle_sockets + 1, pool_->IdleSocketCount());
920
921 // Requesting a socket again should return the same socket as
922 // before, so should complete synchronously.
923 EXPECT_THAT(handle.Init(group_id, params_, absl::nullopt,
924 DEFAULT_PRIORITY, SocketTag(),
925 ClientSocketPool::RespectLimits::ENABLED,
926 callback.callback(),
927 ClientSocketPool::ProxyAuthCallback(),
928 pool_.get(), NetLogWithSource()),
929 IsOk());
930 EXPECT_TRUE(handle.socket());
931 EXPECT_EQ(total_idle_sockets, pool_->IdleSocketCount());
932
933 // Return socket to pool again.
934 handle.Reset();
935 EXPECT_EQ(total_idle_sockets + 1, pool_->IdleSocketCount());
936
937 ++total_idle_sockets;
938 }
939 }
940 }
941 }
942 }
943 }
944
TEST_F(ClientSocketPoolBaseTest,TotalLimit)945 TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
946 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
947
948 // TODO(eroman): Check that the NetLog contains this event.
949
950 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
951 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
952 EXPECT_THAT(StartRequest(TestGroupId("c"), DEFAULT_PRIORITY), IsOk());
953 EXPECT_THAT(StartRequest(TestGroupId("d"), DEFAULT_PRIORITY), IsOk());
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_THAT(StartRequest(TestGroupId("e"), DEFAULT_PRIORITY),
960 IsError(ERR_IO_PENDING));
961 EXPECT_THAT(StartRequest(TestGroupId("f"), DEFAULT_PRIORITY),
962 IsError(ERR_IO_PENDING));
963 EXPECT_THAT(StartRequest(TestGroupId("g"), DEFAULT_PRIORITY),
964 IsError(ERR_IO_PENDING));
965
966 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
967
968 EXPECT_EQ(static_cast<int>(requests_size()),
969 client_socket_factory_.allocation_count());
970 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
971
972 EXPECT_EQ(1, GetOrderOfRequest(1));
973 EXPECT_EQ(2, GetOrderOfRequest(2));
974 EXPECT_EQ(3, GetOrderOfRequest(3));
975 EXPECT_EQ(4, GetOrderOfRequest(4));
976 EXPECT_EQ(5, GetOrderOfRequest(5));
977 EXPECT_EQ(6, GetOrderOfRequest(6));
978 EXPECT_EQ(7, GetOrderOfRequest(7));
979
980 // Make sure we test order of all requests made.
981 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
982 }
983
TEST_F(ClientSocketPoolBaseTest,TotalLimitReachedNewGroup)984 TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
985 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
986
987 // TODO(eroman): Check that the NetLog contains this event.
988
989 // Reach all limits: max total sockets, and max sockets per group.
990 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
991 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
992 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
993 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
994
995 EXPECT_EQ(static_cast<int>(requests_size()),
996 client_socket_factory_.allocation_count());
997 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
998
999 // Now create a new group and verify that we don't starve it.
1000 EXPECT_THAT(StartRequest(TestGroupId("c"), DEFAULT_PRIORITY),
1001 IsError(ERR_IO_PENDING));
1002
1003 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1004
1005 EXPECT_EQ(static_cast<int>(requests_size()),
1006 client_socket_factory_.allocation_count());
1007 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
1008
1009 EXPECT_EQ(1, GetOrderOfRequest(1));
1010 EXPECT_EQ(2, GetOrderOfRequest(2));
1011 EXPECT_EQ(3, GetOrderOfRequest(3));
1012 EXPECT_EQ(4, GetOrderOfRequest(4));
1013 EXPECT_EQ(5, GetOrderOfRequest(5));
1014
1015 // Make sure we test order of all requests made.
1016 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
1017 }
1018
TEST_F(ClientSocketPoolBaseTest,TotalLimitRespectsPriority)1019 TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
1020 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1021
1022 EXPECT_THAT(StartRequest(TestGroupId("b"), LOWEST), IsOk());
1023 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsOk());
1024 EXPECT_THAT(StartRequest(TestGroupId("b"), HIGHEST), IsOk());
1025 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsOk());
1026
1027 EXPECT_EQ(static_cast<int>(requests_size()),
1028 client_socket_factory_.allocation_count());
1029
1030 EXPECT_THAT(StartRequest(TestGroupId("c"), LOWEST), IsError(ERR_IO_PENDING));
1031 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1032 EXPECT_THAT(StartRequest(TestGroupId("b"), HIGHEST), IsError(ERR_IO_PENDING));
1033
1034 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1035
1036 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
1037
1038 // First 4 requests don't have to wait, and finish in order.
1039 EXPECT_EQ(1, GetOrderOfRequest(1));
1040 EXPECT_EQ(2, GetOrderOfRequest(2));
1041 EXPECT_EQ(3, GetOrderOfRequest(3));
1042 EXPECT_EQ(4, GetOrderOfRequest(4));
1043
1044 // Request ("b", HIGHEST) has the highest priority, then (TestGroupId("a"),
1045 // MEDIUM), and then ("c", LOWEST).
1046 EXPECT_EQ(7, GetOrderOfRequest(5));
1047 EXPECT_EQ(6, GetOrderOfRequest(6));
1048 EXPECT_EQ(5, GetOrderOfRequest(7));
1049
1050 // Make sure we test order of all requests made.
1051 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
1052 }
1053
1054 // Test reprioritizing a request before completion doesn't interfere with
1055 // its completion.
TEST_F(ClientSocketPoolBaseTest,ReprioritizeOne)1056 TEST_F(ClientSocketPoolBaseTest, ReprioritizeOne) {
1057 CreatePool(kDefaultMaxSockets, 1);
1058
1059 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
1060 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1061 EXPECT_TRUE(request(0)->handle()->socket());
1062 EXPECT_FALSE(request(1)->handle()->socket());
1063
1064 request(1)->handle()->SetPriority(HIGHEST);
1065
1066 ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE);
1067
1068 EXPECT_TRUE(request(1)->handle()->socket());
1069 }
1070
1071 // Reprioritize a request up past another one and make sure that changes the
1072 // completion order.
TEST_F(ClientSocketPoolBaseTest,ReprioritizeUpReorder)1073 TEST_F(ClientSocketPoolBaseTest, ReprioritizeUpReorder) {
1074 CreatePool(kDefaultMaxSockets, 1);
1075
1076 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
1077 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1078 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
1079 EXPECT_TRUE(request(0)->handle()->socket());
1080 EXPECT_FALSE(request(1)->handle()->socket());
1081 EXPECT_FALSE(request(2)->handle()->socket());
1082
1083 request(2)->handle()->SetPriority(HIGHEST);
1084
1085 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1086
1087 EXPECT_EQ(1, GetOrderOfRequest(1));
1088 EXPECT_EQ(3, GetOrderOfRequest(2));
1089 EXPECT_EQ(2, GetOrderOfRequest(3));
1090 }
1091
1092 // Reprioritize a request without changing relative priorities and check
1093 // that the order doesn't change.
TEST_F(ClientSocketPoolBaseTest,ReprioritizeUpNoReorder)1094 TEST_F(ClientSocketPoolBaseTest, ReprioritizeUpNoReorder) {
1095 CreatePool(kDefaultMaxSockets, 1);
1096
1097 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
1098 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1099 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
1100 EXPECT_TRUE(request(0)->handle()->socket());
1101 EXPECT_FALSE(request(1)->handle()->socket());
1102 EXPECT_FALSE(request(2)->handle()->socket());
1103
1104 request(2)->handle()->SetPriority(MEDIUM);
1105
1106 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1107
1108 EXPECT_EQ(1, GetOrderOfRequest(1));
1109 EXPECT_EQ(2, GetOrderOfRequest(2));
1110 EXPECT_EQ(3, GetOrderOfRequest(3));
1111 }
1112
1113 // Reprioritize a request past down another one and make sure that changes the
1114 // completion order.
TEST_F(ClientSocketPoolBaseTest,ReprioritizeDownReorder)1115 TEST_F(ClientSocketPoolBaseTest, ReprioritizeDownReorder) {
1116 CreatePool(kDefaultMaxSockets, 1);
1117
1118 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
1119 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
1120 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1121 EXPECT_TRUE(request(0)->handle()->socket());
1122 EXPECT_FALSE(request(1)->handle()->socket());
1123 EXPECT_FALSE(request(2)->handle()->socket());
1124
1125 request(1)->handle()->SetPriority(LOW);
1126
1127 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1128
1129 EXPECT_EQ(1, GetOrderOfRequest(1));
1130 EXPECT_EQ(3, GetOrderOfRequest(2));
1131 EXPECT_EQ(2, GetOrderOfRequest(3));
1132 }
1133
1134 // Reprioritize a request to the same level as another and confirm it is
1135 // put after the old request.
TEST_F(ClientSocketPoolBaseTest,ReprioritizeResetFIFO)1136 TEST_F(ClientSocketPoolBaseTest, ReprioritizeResetFIFO) {
1137 CreatePool(kDefaultMaxSockets, 1);
1138
1139 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
1140 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
1141 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1142 EXPECT_TRUE(request(0)->handle()->socket());
1143 EXPECT_FALSE(request(1)->handle()->socket());
1144 EXPECT_FALSE(request(2)->handle()->socket());
1145
1146 request(1)->handle()->SetPriority(MEDIUM);
1147
1148 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1149
1150 EXPECT_EQ(1, GetOrderOfRequest(1));
1151 EXPECT_EQ(3, GetOrderOfRequest(2));
1152 EXPECT_EQ(2, GetOrderOfRequest(3));
1153 }
1154
TEST_F(ClientSocketPoolBaseTest,TotalLimitRespectsGroupLimit)1155 TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
1156 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1157
1158 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsOk());
1159 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsOk());
1160 EXPECT_THAT(StartRequest(TestGroupId("b"), HIGHEST), IsOk());
1161 EXPECT_THAT(StartRequest(TestGroupId("b"), MEDIUM), IsOk());
1162
1163 EXPECT_EQ(static_cast<int>(requests_size()),
1164 client_socket_factory_.allocation_count());
1165
1166 EXPECT_THAT(StartRequest(TestGroupId("c"), MEDIUM), IsError(ERR_IO_PENDING));
1167 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
1168 EXPECT_THAT(StartRequest(TestGroupId("b"), HIGHEST), IsError(ERR_IO_PENDING));
1169
1170 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1171
1172 EXPECT_EQ(static_cast<int>(requests_size()),
1173 client_socket_factory_.allocation_count());
1174 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
1175
1176 // First 4 requests don't have to wait, and finish in order.
1177 EXPECT_EQ(1, GetOrderOfRequest(1));
1178 EXPECT_EQ(2, GetOrderOfRequest(2));
1179 EXPECT_EQ(3, GetOrderOfRequest(3));
1180 EXPECT_EQ(4, GetOrderOfRequest(4));
1181
1182 // Request ("b", 7) has the highest priority, but we can't make new socket for
1183 // group "b", because it has reached the per-group limit. Then we make
1184 // socket for ("c", 6), because it has higher priority than ("a", 4),
1185 // and we still can't make a socket for group "b".
1186 EXPECT_EQ(5, GetOrderOfRequest(5));
1187 EXPECT_EQ(6, GetOrderOfRequest(6));
1188 EXPECT_EQ(7, GetOrderOfRequest(7));
1189
1190 // Make sure we test order of all requests made.
1191 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
1192 }
1193
1194 // Make sure that we count connecting sockets against the total limit.
TEST_F(ClientSocketPoolBaseTest,TotalLimitCountsConnectingSockets)1195 TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
1196 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1197
1198 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1199 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
1200 EXPECT_THAT(StartRequest(TestGroupId("c"), DEFAULT_PRIORITY), IsOk());
1201
1202 // Create one asynchronous request.
1203 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1204 EXPECT_THAT(StartRequest(TestGroupId("d"), DEFAULT_PRIORITY),
1205 IsError(ERR_IO_PENDING));
1206
1207 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1208 // actually become pending until 2ms after they have been created. In order
1209 // to flush all tasks, we need to wait so that we know there are no
1210 // soon-to-be-pending tasks waiting.
1211 FastForwardBy(base::Milliseconds(10));
1212
1213 // The next synchronous request should wait for its turn.
1214 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1215 EXPECT_THAT(StartRequest(TestGroupId("e"), DEFAULT_PRIORITY),
1216 IsError(ERR_IO_PENDING));
1217
1218 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1219
1220 EXPECT_EQ(static_cast<int>(requests_size()),
1221 client_socket_factory_.allocation_count());
1222
1223 EXPECT_EQ(1, GetOrderOfRequest(1));
1224 EXPECT_EQ(2, GetOrderOfRequest(2));
1225 EXPECT_EQ(3, GetOrderOfRequest(3));
1226 EXPECT_EQ(4, GetOrderOfRequest(4));
1227 EXPECT_EQ(5, GetOrderOfRequest(5));
1228
1229 // Make sure we test order of all requests made.
1230 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
1231 }
1232
TEST_F(ClientSocketPoolBaseTest,CorrectlyCountStalledGroups)1233 TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
1234 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1235 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1236
1237 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1238 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1239 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1240 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1241
1242 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1243
1244 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1245
1246 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY),
1247 IsError(ERR_IO_PENDING));
1248 EXPECT_THAT(StartRequest(TestGroupId("c"), DEFAULT_PRIORITY),
1249 IsError(ERR_IO_PENDING));
1250
1251 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1252
1253 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1254 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1255 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1256 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
1257 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1258 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1259 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
1260 }
1261
TEST_F(ClientSocketPoolBaseTest,StallAndThenCancelAndTriggerAvailableSocket)1262 TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
1263 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1264 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1265
1266 TestCompletionCallback callback;
1267 ClientSocketHandle stalled_handle;
1268 EXPECT_EQ(ERR_IO_PENDING,
1269 stalled_handle.Init(
1270 TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
1271 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1272 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1273 pool_.get(), NetLogWithSource()));
1274
1275 ClientSocketHandle handles[4];
1276 for (auto& handle : handles) {
1277 EXPECT_EQ(
1278 ERR_IO_PENDING,
1279 handle.Init(TestGroupId("b"), params_, absl::nullopt, DEFAULT_PRIORITY,
1280 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1281 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1282 pool_.get(), NetLogWithSource()));
1283 }
1284
1285 // One will be stalled, cancel all the handles now.
1286 // This should hit the OnAvailableSocketSlot() code where we previously had
1287 // stalled groups, but no longer have any.
1288 for (auto& handle : handles)
1289 handle.Reset();
1290 }
1291
TEST_F(ClientSocketPoolBaseTest,CancelStalledSocketAtSocketLimit)1292 TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
1293 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1294 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1295
1296 {
1297 ClientSocketHandle handles[kDefaultMaxSockets];
1298 TestCompletionCallback callbacks[kDefaultMaxSockets];
1299 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1300 EXPECT_EQ(OK, handles[i].Init(TestGroupId("a" + base::NumberToString(i)),
1301 params_, absl::nullopt, DEFAULT_PRIORITY,
1302 SocketTag(),
1303 ClientSocketPool::RespectLimits::ENABLED,
1304 callbacks[i].callback(),
1305 ClientSocketPool::ProxyAuthCallback(),
1306 pool_.get(), NetLogWithSource()));
1307 }
1308
1309 // Force a stalled group.
1310 ClientSocketHandle stalled_handle;
1311 TestCompletionCallback callback;
1312 EXPECT_EQ(ERR_IO_PENDING,
1313 stalled_handle.Init(
1314 TestGroupId("foo"), params_, absl::nullopt, DEFAULT_PRIORITY,
1315 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1316 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1317 pool_.get(), NetLogWithSource()));
1318
1319 // Cancel the stalled request.
1320 stalled_handle.Reset();
1321
1322 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1323 EXPECT_EQ(0, pool_->IdleSocketCount());
1324
1325 // Dropping out of scope will close all handles and return them to idle.
1326 }
1327
1328 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1329 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
1330 }
1331
TEST_F(ClientSocketPoolBaseTest,CancelPendingSocketAtSocketLimit)1332 TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
1333 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1334 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1335
1336 {
1337 ClientSocketHandle handles[kDefaultMaxSockets];
1338 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1339 TestCompletionCallback callback;
1340 EXPECT_EQ(ERR_IO_PENDING,
1341 handles[i].Init(
1342 TestGroupId("a" + base::NumberToString(i)), params_,
1343 absl::nullopt, DEFAULT_PRIORITY, SocketTag(),
1344 ClientSocketPool::RespectLimits::ENABLED,
1345 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1346 pool_.get(), NetLogWithSource()));
1347 }
1348
1349 // Force a stalled group.
1350 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1351 ClientSocketHandle stalled_handle;
1352 TestCompletionCallback callback;
1353 EXPECT_EQ(ERR_IO_PENDING,
1354 stalled_handle.Init(
1355 TestGroupId("foo"), params_, absl::nullopt, DEFAULT_PRIORITY,
1356 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1357 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1358 pool_.get(), NetLogWithSource()));
1359
1360 // Since it is stalled, it should have no connect jobs.
1361 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("foo")));
1362 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
1363 TestGroupId("foo")));
1364 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroupForTesting(
1365 TestGroupId("foo")));
1366
1367 // Cancel the stalled request.
1368 handles[0].Reset();
1369
1370 // Now we should have a connect job.
1371 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("foo")));
1372 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
1373 TestGroupId("foo")));
1374 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroupForTesting(
1375 TestGroupId("foo")));
1376
1377 // The stalled socket should connect.
1378 EXPECT_THAT(callback.WaitForResult(), IsOk());
1379
1380 EXPECT_EQ(kDefaultMaxSockets + 1,
1381 client_socket_factory_.allocation_count());
1382 EXPECT_EQ(0, pool_->IdleSocketCount());
1383 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("foo")));
1384 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
1385 TestGroupId("foo")));
1386 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroupForTesting(
1387 TestGroupId("foo")));
1388
1389 // Dropping out of scope will close all handles and return them to idle.
1390 }
1391
1392 EXPECT_EQ(1, pool_->IdleSocketCount());
1393 }
1394
TEST_F(ClientSocketPoolBaseTest,WaitForStalledSocketAtSocketLimit)1395 TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1396 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1397 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1398
1399 ClientSocketHandle stalled_handle;
1400 TestCompletionCallback callback;
1401 {
1402 EXPECT_FALSE(pool_->IsStalled());
1403 ClientSocketHandle handles[kDefaultMaxSockets];
1404 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1405 EXPECT_EQ(
1406 OK, handles[i].Init(
1407 TestGroupId(base::StringPrintf("take-2-%d", i)), params_,
1408 absl::nullopt, DEFAULT_PRIORITY, SocketTag(),
1409 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1410 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
1411 NetLogWithSource()));
1412 }
1413
1414 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1415 EXPECT_EQ(0, pool_->IdleSocketCount());
1416 EXPECT_FALSE(pool_->IsStalled());
1417
1418 // Now we will hit the socket limit.
1419 EXPECT_EQ(ERR_IO_PENDING,
1420 stalled_handle.Init(
1421 TestGroupId("foo"), params_, absl::nullopt, DEFAULT_PRIORITY,
1422 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1423 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1424 pool_.get(), NetLogWithSource()));
1425 EXPECT_TRUE(pool_->IsStalled());
1426
1427 // Dropping out of scope will close all handles and return them to idle.
1428 }
1429
1430 // But if we wait for it, the released idle sockets will be closed in
1431 // preference of the waiting request.
1432 EXPECT_THAT(callback.WaitForResult(), IsOk());
1433
1434 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1435 EXPECT_EQ(3, pool_->IdleSocketCount());
1436 }
1437
1438 // Regression test for http://crbug.com/40952.
TEST_F(ClientSocketPoolBaseTest,CloseIdleSocketAtSocketLimitDeleteGroup)1439 TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1440 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1441 true /* enable_backup_connect_jobs */);
1442 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1443
1444 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1445 ClientSocketHandle handle;
1446 TestCompletionCallback callback;
1447 EXPECT_EQ(
1448 OK,
1449 handle.Init(TestGroupId("a" + base::NumberToString(i)), params_,
1450 absl::nullopt, DEFAULT_PRIORITY, SocketTag(),
1451 ClientSocketPool::RespectLimits::ENABLED,
1452 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1453 pool_.get(), NetLogWithSource()));
1454 }
1455
1456 // Flush all the DoReleaseSocket tasks.
1457 base::RunLoop().RunUntilIdle();
1458
1459 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1460 // reuse a socket.
1461 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1462 ClientSocketHandle handle;
1463 TestCompletionCallback callback;
1464
1465 // "a0" is special here, since it should be the first entry in the sorted map,
1466 // which is the one which we would close an idle socket for. We shouldn't
1467 // close an idle socket though, since we should reuse the idle socket.
1468 EXPECT_EQ(OK, handle.Init(
1469 TestGroupId("a0"), params_, absl::nullopt, DEFAULT_PRIORITY,
1470 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1471 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1472 pool_.get(), NetLogWithSource()));
1473
1474 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1475 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1476 }
1477
TEST_F(ClientSocketPoolBaseTest,PendingRequests)1478 TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
1479 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1480
1481 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1482 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1483 EXPECT_THAT(StartRequest(TestGroupId("a"), IDLE), IsError(ERR_IO_PENDING));
1484 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
1485 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1486 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
1487 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
1488 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
1489
1490 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
1491 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1492 client_socket_factory_.allocation_count());
1493 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1494 completion_count());
1495
1496 EXPECT_EQ(1, GetOrderOfRequest(1));
1497 EXPECT_EQ(2, GetOrderOfRequest(2));
1498 EXPECT_EQ(8, GetOrderOfRequest(3));
1499 EXPECT_EQ(6, GetOrderOfRequest(4));
1500 EXPECT_EQ(4, GetOrderOfRequest(5));
1501 EXPECT_EQ(3, GetOrderOfRequest(6));
1502 EXPECT_EQ(5, GetOrderOfRequest(7));
1503 EXPECT_EQ(7, GetOrderOfRequest(8));
1504
1505 // Make sure we test order of all requests made.
1506 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
1507 }
1508
TEST_F(ClientSocketPoolBaseTest,PendingRequests_NoKeepAlive)1509 TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
1510 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1511
1512 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1513 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1514 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
1515 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1516 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
1517 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
1518 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
1519
1520 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1521
1522 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
1523 EXPECT_THAT(request(i)->WaitForResult(), IsOk());
1524
1525 EXPECT_EQ(static_cast<int>(requests_size()),
1526 client_socket_factory_.allocation_count());
1527 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1528 completion_count());
1529 }
1530
TEST_F(ClientSocketPoolBaseTest,ResetAndCloseSocket)1531 TEST_F(ClientSocketPoolBaseTest, ResetAndCloseSocket) {
1532 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1533
1534 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1535 ClientSocketHandle handle;
1536 TestCompletionCallback callback;
1537 EXPECT_EQ(
1538 ERR_IO_PENDING,
1539 handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
1540 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1541 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1542 pool_.get(), NetLogWithSource()));
1543
1544 EXPECT_THAT(callback.WaitForResult(), IsOk());
1545 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1546 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1547 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
1548 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1549
1550 handle.ResetAndCloseSocket();
1551 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
1552 }
1553
1554 // This test will start up a socket request and then call Reset() on the handle.
1555 // The pending ConnectJob should not be destroyed.
TEST_F(ClientSocketPoolBaseTest,CancelRequestKeepsConnectJob)1556 TEST_F(ClientSocketPoolBaseTest, CancelRequestKeepsConnectJob) {
1557 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1558
1559 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1560 ClientSocketHandle handle;
1561 TestCompletionCallback callback;
1562 EXPECT_EQ(
1563 ERR_IO_PENDING,
1564 handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
1565 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1566 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1567 pool_.get(), NetLogWithSource()));
1568 handle.Reset();
1569 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1570 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1571 }
1572
1573 // This test will start up a socket request and then call ResetAndCloseSocket()
1574 // on the handle. The pending ConnectJob or connected socket should be
1575 // destroyed.
TEST_F(ClientSocketPoolBaseTest,CancelRequestAndCloseSocket)1576 TEST_F(ClientSocketPoolBaseTest, CancelRequestAndCloseSocket) {
1577 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1578
1579 // When true, the socket connects before it's canceled.
1580 for (bool cancel_when_callback_pending : {false, true}) {
1581 if (cancel_when_callback_pending) {
1582 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1583 } else {
1584 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1585 }
1586 ClientSocketHandle handle;
1587 TestCompletionCallback callback;
1588 EXPECT_EQ(
1589 ERR_IO_PENDING,
1590 handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
1591 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1592 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1593 pool_.get(), NetLogWithSource()));
1594 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1595 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1596
1597 if (cancel_when_callback_pending) {
1598 client_socket_factory_.SignalJobs();
1599 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1600 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1601 }
1602
1603 handle.ResetAndCloseSocket();
1604 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
1605 }
1606 }
1607
TEST_F(ClientSocketPoolBaseTest,CancelRequestAndCloseSocketWhenMoreRequestsThanConnectJobs)1608 TEST_F(ClientSocketPoolBaseTest,
1609 CancelRequestAndCloseSocketWhenMoreRequestsThanConnectJobs) {
1610 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1611
1612 // When true, the sockets connect before they're canceled.
1613 for (bool cancel_when_callback_pending : {false, true}) {
1614 if (cancel_when_callback_pending) {
1615 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1616 } else {
1617 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1618 }
1619
1620 std::vector<std::unique_ptr<ClientSocketHandle>> handles;
1621 TestCompletionCallback callback;
1622 // Make |kDefaultMaxSockets + 1| socket requests.
1623 for (int i = 0; i < kDefaultMaxSocketsPerGroup + 1; ++i) {
1624 std::unique_ptr<ClientSocketHandle> handle =
1625 std::make_unique<ClientSocketHandle>();
1626 EXPECT_EQ(ERR_IO_PENDING,
1627 handle->Init(
1628 TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
1629 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1630 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1631 pool_.get(), NetLogWithSource()));
1632 handles.push_back(std::move(handle));
1633 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1634 EXPECT_EQ(
1635 static_cast<size_t>(std::min(i + 1, kDefaultMaxSocketsPerGroup)),
1636 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1637 }
1638
1639 if (cancel_when_callback_pending) {
1640 client_socket_factory_.SignalJobs();
1641 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1642 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1643 pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1644 }
1645
1646 // Calling ResetAndCloseSocket() on a handle should not cancel a ConnectJob
1647 // or close a socket, since there are more requests than ConnectJobs or
1648 // sockets.
1649 handles[kDefaultMaxSocketsPerGroup]->ResetAndCloseSocket();
1650 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1651 if (cancel_when_callback_pending) {
1652 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1653 pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1654 } else {
1655 EXPECT_EQ(static_cast<size_t>(kDefaultMaxSocketsPerGroup),
1656 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1657 }
1658
1659 // Calling ResetAndCloseSocket() on other handles should cancel a ConnectJob
1660 // or close a socket.
1661 for (int i = kDefaultMaxSocketsPerGroup - 1; i >= 0; --i) {
1662 handles[i]->ResetAndCloseSocket();
1663 if (i > 0) {
1664 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1665 if (cancel_when_callback_pending) {
1666 EXPECT_EQ(i,
1667 pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1668 } else {
1669 EXPECT_EQ(static_cast<size_t>(i),
1670 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1671 }
1672 } else {
1673 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
1674 }
1675 }
1676 }
1677 }
1678
TEST_F(ClientSocketPoolBaseTest,ConnectCancelConnect)1679 TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
1680 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1681
1682 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1683 ClientSocketHandle handle;
1684 TestCompletionCallback callback;
1685
1686 EXPECT_EQ(
1687 ERR_IO_PENDING,
1688 handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
1689 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1690 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1691 pool_.get(), NetLogWithSource()));
1692
1693 handle.Reset();
1694 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1695 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1696
1697 // This will create a second ConnectJob, since the other ConnectJob was
1698 // previously assigned to a request.
1699 TestCompletionCallback callback2;
1700 EXPECT_EQ(
1701 ERR_IO_PENDING,
1702 handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
1703 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1704 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
1705 pool_.get(), NetLogWithSource()));
1706
1707 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1708 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1709
1710 EXPECT_THAT(callback2.WaitForResult(), IsOk());
1711 EXPECT_FALSE(callback.have_result());
1712 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1713 // One ConnectJob completed, and its socket is now assigned to |handle|.
1714 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1715 // The other ConnectJob should have either completed, or still be connecting.
1716 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")) +
1717 pool_->IdleSocketCountInGroup(TestGroupId("a")));
1718
1719 handle.Reset();
1720 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1721 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")) +
1722 pool_->IdleSocketCountInGroup(TestGroupId("a")));
1723 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1724 }
1725
TEST_F(ClientSocketPoolBaseTest,CancelRequest)1726 TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
1727 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1728
1729 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1730 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1731 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
1732 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1733 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
1734 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
1735 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
1736
1737 // Cancel a request.
1738 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
1739 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1740 (*requests())[index_to_cancel]->handle()->Reset();
1741
1742 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
1743
1744 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1745 client_socket_factory_.allocation_count());
1746 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1747 completion_count());
1748
1749 EXPECT_EQ(1, GetOrderOfRequest(1));
1750 EXPECT_EQ(2, GetOrderOfRequest(2));
1751 EXPECT_EQ(5, GetOrderOfRequest(3));
1752 EXPECT_EQ(3, GetOrderOfRequest(4));
1753 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1754 GetOrderOfRequest(5)); // Canceled request.
1755 EXPECT_EQ(4, GetOrderOfRequest(6));
1756 EXPECT_EQ(6, GetOrderOfRequest(7));
1757
1758 // Make sure we test order of all requests made.
1759 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
1760 }
1761
1762 // Function to be used as a callback on socket request completion. It first
1763 // disconnects the successfully connected socket from the first request, and
1764 // then reuses the ClientSocketHandle to request another socket.
1765 //
1766 // |nested_callback| is called with the result of the second socket request.
RequestSocketOnComplete(ClientSocketHandle * handle,TransportClientSocketPool * pool,TestConnectJobFactory * test_connect_job_factory,TestConnectJob::JobType next_job_type,TestCompletionCallback * nested_callback,int first_request_result)1767 void RequestSocketOnComplete(ClientSocketHandle* handle,
1768 TransportClientSocketPool* pool,
1769 TestConnectJobFactory* test_connect_job_factory,
1770 TestConnectJob::JobType next_job_type,
1771 TestCompletionCallback* nested_callback,
1772 int first_request_result) {
1773 EXPECT_THAT(first_request_result, IsOk());
1774
1775 test_connect_job_factory->set_job_type(next_job_type);
1776
1777 // Don't allow reuse of the socket. Disconnect it and then release it.
1778 if (handle->socket())
1779 handle->socket()->Disconnect();
1780 handle->Reset();
1781
1782 TestCompletionCallback callback;
1783 int rv = handle->Init(
1784 TestGroupId("a"),
1785 ClientSocketPool::SocketParams::CreateForHttpForTesting(), absl::nullopt,
1786 LOWEST, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1787 nested_callback->callback(), ClientSocketPool::ProxyAuthCallback(), pool,
1788 NetLogWithSource());
1789 if (rv != ERR_IO_PENDING) {
1790 DCHECK_EQ(TestConnectJob::kMockJob, next_job_type);
1791 nested_callback->callback().Run(rv);
1792 } else {
1793 DCHECK_EQ(TestConnectJob::kMockPendingJob, next_job_type);
1794 }
1795 }
1796
1797 // Tests the case where a second socket is requested in a completion callback,
1798 // and the second socket connects asynchronously. Reuses the same
1799 // ClientSocketHandle for the second socket, after disconnecting the first.
TEST_F(ClientSocketPoolBaseTest,RequestPendingJobTwice)1800 TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
1801 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1802
1803 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1804 ClientSocketHandle handle;
1805 TestCompletionCallback second_result_callback;
1806 int rv = handle.Init(
1807 TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY, SocketTag(),
1808 ClientSocketPool::RespectLimits::ENABLED,
1809 base::BindOnce(&RequestSocketOnComplete, &handle, pool_.get(),
1810 connect_job_factory_, TestConnectJob::kMockPendingJob,
1811 &second_result_callback),
1812 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
1813 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
1814
1815 EXPECT_THAT(second_result_callback.WaitForResult(), IsOk());
1816 }
1817
1818 // Tests the case where a second socket is requested in a completion callback,
1819 // and the second socket connects synchronously. Reuses the same
1820 // ClientSocketHandle for the second socket, after disconnecting the first.
TEST_F(ClientSocketPoolBaseTest,RequestPendingJobThenSynchronous)1821 TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
1822 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1823
1824 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1825 ClientSocketHandle handle;
1826 TestCompletionCallback second_result_callback;
1827 int rv = handle.Init(
1828 TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY, SocketTag(),
1829 ClientSocketPool::RespectLimits::ENABLED,
1830 base::BindOnce(&RequestSocketOnComplete, &handle, pool_.get(),
1831 connect_job_factory_, TestConnectJob::kMockPendingJob,
1832 &second_result_callback),
1833 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
1834 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
1835
1836 EXPECT_THAT(second_result_callback.WaitForResult(), IsOk());
1837 }
1838
1839 // Make sure that pending requests get serviced after active requests get
1840 // cancelled.
TEST_F(ClientSocketPoolBaseTest,CancelActiveRequestWithPendingRequests)1841 TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
1842 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1843
1844 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1845
1846 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1847 IsError(ERR_IO_PENDING));
1848 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1849 IsError(ERR_IO_PENDING));
1850 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1851 IsError(ERR_IO_PENDING));
1852 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1853 IsError(ERR_IO_PENDING));
1854 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1855 IsError(ERR_IO_PENDING));
1856 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1857 IsError(ERR_IO_PENDING));
1858 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1859 IsError(ERR_IO_PENDING));
1860
1861 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1862 // Let's cancel them.
1863 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
1864 ASSERT_FALSE(request(i)->handle()->is_initialized());
1865 request(i)->handle()->Reset();
1866 }
1867
1868 // Let's wait for the rest to complete now.
1869 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
1870 EXPECT_THAT(request(i)->WaitForResult(), IsOk());
1871 request(i)->handle()->Reset();
1872 }
1873
1874 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1875 completion_count());
1876 }
1877
1878 // Make sure that pending requests get serviced after active requests fail.
TEST_F(ClientSocketPoolBaseTest,FailingActiveRequestWithPendingRequests)1879 TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
1880 const size_t kMaxSockets = 5;
1881 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
1882
1883 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1884
1885 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1886 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
1887
1888 // Queue up all the requests
1889 for (size_t i = 0; i < kNumberOfRequests; ++i)
1890 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1891 IsError(ERR_IO_PENDING));
1892
1893 for (size_t i = 0; i < kNumberOfRequests; ++i)
1894 EXPECT_THAT(request(i)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
1895 }
1896
1897 // Make sure that pending requests that complete synchronously get serviced
1898 // after active requests fail. See https://crbug.com/723748
TEST_F(ClientSocketPoolBaseTest,HandleMultipleSyncFailuresAfterAsyncFailure)1899 TEST_F(ClientSocketPoolBaseTest, HandleMultipleSyncFailuresAfterAsyncFailure) {
1900 const size_t kNumberOfRequests = 10;
1901 const size_t kMaxSockets = 1;
1902 CreatePool(kMaxSockets, kMaxSockets);
1903
1904 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1905
1906 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1907 IsError(ERR_IO_PENDING));
1908
1909 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
1910
1911 // Queue up all the other requests
1912 for (size_t i = 1; i < kNumberOfRequests; ++i)
1913 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1914 IsError(ERR_IO_PENDING));
1915
1916 // Make sure all requests fail, instead of hanging.
1917 for (size_t i = 0; i < kNumberOfRequests; ++i)
1918 EXPECT_THAT(request(i)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
1919 }
1920
TEST_F(ClientSocketPoolBaseTest,CancelActiveRequestThenRequestSocket)1921 TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
1922 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1923
1924 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1925
1926 ClientSocketHandle handle;
1927 TestCompletionCallback callback;
1928 int rv = handle.Init(
1929 TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY, SocketTag(),
1930 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1931 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
1932 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1933
1934 // Cancel the active request.
1935 handle.Reset();
1936
1937 rv = handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
1938 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1939 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1940 pool_.get(), NetLogWithSource());
1941 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1942 EXPECT_THAT(callback.WaitForResult(), IsOk());
1943
1944 EXPECT_FALSE(handle.is_reused());
1945 TestLoadTimingInfoConnectedNotReused(handle);
1946 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1947 }
1948
TEST_F(ClientSocketPoolBaseTest,CloseIdleSocketsForced)1949 TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsForced) {
1950 const char kReason[] = "Really nifty reason";
1951
1952 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1953 ClientSocketHandle handle;
1954 TestCompletionCallback callback;
1955 int rv =
1956 handle.Init(TestGroupId("a"), params_, absl::nullopt, LOWEST, SocketTag(),
1957 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1958 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
1959 NetLogWithSource::Make(NetLogSourceType::NONE));
1960 EXPECT_THAT(rv, IsOk());
1961 ASSERT_TRUE(handle.socket());
1962 NetLogSource source = handle.socket()->NetLog().source();
1963 handle.Reset();
1964 EXPECT_EQ(1, pool_->IdleSocketCount());
1965 pool_->CloseIdleSockets(kReason);
1966 ExpectSocketClosedWithReason(source, kReason);
1967 }
1968
TEST_F(ClientSocketPoolBaseTest,CloseIdleSocketsInGroupForced)1969 TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsInGroupForced) {
1970 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1971 TestCompletionCallback callback;
1972 NetLogWithSource net_log_with_source =
1973 NetLogWithSource::Make(NetLogSourceType::NONE);
1974 ClientSocketHandle handle1;
1975 int rv = handle1.Init(
1976 TestGroupId("a"), params_, absl::nullopt, LOWEST, SocketTag(),
1977 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1978 ClientSocketPool::ProxyAuthCallback(), pool_.get(), net_log_with_source);
1979 EXPECT_THAT(rv, IsOk());
1980 ClientSocketHandle handle2;
1981 rv = handle2.Init(TestGroupId("a"), params_, absl::nullopt, LOWEST,
1982 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1983 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1984 pool_.get(), net_log_with_source);
1985 ClientSocketHandle handle3;
1986 rv = handle3.Init(TestGroupId("b"), params_, absl::nullopt, LOWEST,
1987 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1988 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1989 pool_.get(), net_log_with_source);
1990 EXPECT_THAT(rv, IsOk());
1991 handle1.Reset();
1992 handle2.Reset();
1993 handle3.Reset();
1994 EXPECT_EQ(3, pool_->IdleSocketCount());
1995 pool_->CloseIdleSocketsInGroup(TestGroupId("a"), "Very good reason");
1996 EXPECT_EQ(1, pool_->IdleSocketCount());
1997 }
1998
TEST_F(ClientSocketPoolBaseTest,CleanUpUnusableIdleSockets)1999 TEST_F(ClientSocketPoolBaseTest, CleanUpUnusableIdleSockets) {
2000 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2001 ClientSocketHandle handle;
2002 TestCompletionCallback callback;
2003 NetLogWithSource net_log_with_source =
2004 NetLogWithSource::Make(NetLogSourceType::NONE);
2005 int rv = handle.Init(
2006 TestGroupId("a"), params_, absl::nullopt, LOWEST, SocketTag(),
2007 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2008 ClientSocketPool::ProxyAuthCallback(), pool_.get(), net_log_with_source);
2009 EXPECT_THAT(rv, IsOk());
2010 StreamSocket* socket = handle.socket();
2011 ASSERT_TRUE(socket);
2012 handle.Reset();
2013 EXPECT_EQ(1, pool_->IdleSocketCount());
2014
2015 // Disconnect socket now to make the socket unusable.
2016 NetLogSource source = socket->NetLog().source();
2017 socket->Disconnect();
2018 ClientSocketHandle handle2;
2019 rv = handle2.Init(TestGroupId("a"), params_, absl::nullopt, LOWEST,
2020 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2021 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2022 pool_.get(), net_log_with_source);
2023 EXPECT_THAT(rv, IsOk());
2024 EXPECT_FALSE(handle2.is_reused());
2025
2026 // This is admittedly not an accurate error in this case, but normally code
2027 // doesn't secretly keep a raw pointers to sockets returned to the socket pool
2028 // and close them out of band, so discovering an idle socket was closed when
2029 // trying to reuse it normally means it was closed by the remote side.
2030 ExpectSocketClosedWithReason(
2031 source, TransportClientSocketPool::kRemoteSideClosedConnection);
2032 }
2033
2034 // Regression test for http://crbug.com/17985.
TEST_F(ClientSocketPoolBaseTest,GroupWithPendingRequestsIsNotEmpty)2035 TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
2036 const int kMaxSockets = 3;
2037 const int kMaxSocketsPerGroup = 2;
2038 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
2039
2040 const RequestPriority kHighPriority = HIGHEST;
2041
2042 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
2043 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
2044
2045 // This is going to be a pending request in an otherwise empty group.
2046 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2047 IsError(ERR_IO_PENDING));
2048
2049 // Reach the maximum socket limit.
2050 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
2051
2052 // Create a stalled group with high priorities.
2053 EXPECT_THAT(StartRequest(TestGroupId("c"), kHighPriority),
2054 IsError(ERR_IO_PENDING));
2055 EXPECT_THAT(StartRequest(TestGroupId("c"), kHighPriority),
2056 IsError(ERR_IO_PENDING));
2057
2058 // Release the first two sockets from TestGroupId("a"). Because this is a
2059 // keepalive, the first release will unblock the pending request for
2060 // TestGroupId("a"). The second release will unblock a request for "c",
2061 // because it is the next high priority socket.
2062 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
2063 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
2064
2065 // Closing idle sockets should not get us into trouble, but in the bug
2066 // we were hitting a CHECK here.
2067 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
2068 pool_->CloseIdleSockets("Very good reason");
2069
2070 // Run the released socket wakeups.
2071 base::RunLoop().RunUntilIdle();
2072 }
2073
TEST_F(ClientSocketPoolBaseTest,BasicAsynchronous)2074 TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
2075 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2076
2077 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2078 ClientSocketHandle handle;
2079 TestCompletionCallback callback;
2080 NetLogWithSource net_log_with_source =
2081 NetLogWithSource::Make(NetLogSourceType::NONE);
2082 int rv = handle.Init(
2083 TestGroupId("a"), params_, absl::nullopt, LOWEST, SocketTag(),
2084 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2085 ClientSocketPool::ProxyAuthCallback(), pool_.get(), net_log_with_source);
2086 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2087 EXPECT_EQ(LOAD_STATE_CONNECTING,
2088 pool_->GetLoadState(TestGroupId("a"), &handle));
2089 TestLoadTimingInfoNotConnected(handle);
2090
2091 EXPECT_THAT(callback.WaitForResult(), IsOk());
2092 EXPECT_TRUE(handle.is_initialized());
2093 EXPECT_TRUE(handle.socket());
2094 TestLoadTimingInfoConnectedNotReused(handle);
2095
2096 handle.Reset();
2097 TestLoadTimingInfoNotConnected(handle);
2098
2099 auto entries =
2100 net_log_observer_.GetEntriesForSource(net_log_with_source.source());
2101
2102 EXPECT_EQ(5u, entries.size());
2103 EXPECT_TRUE(LogContainsEvent(
2104 entries, 0, NetLogEventType::TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET,
2105 NetLogEventPhase::NONE));
2106 EXPECT_TRUE(LogContainsBeginEvent(entries, 1, NetLogEventType::SOCKET_POOL));
2107 EXPECT_TRUE(LogContainsEvent(
2108 entries, 2, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
2109 NetLogEventPhase::NONE));
2110 EXPECT_TRUE(LogContainsEvent(entries, 3,
2111 NetLogEventType::SOCKET_POOL_BOUND_TO_SOCKET,
2112 NetLogEventPhase::NONE));
2113 EXPECT_TRUE(LogContainsEndEvent(entries, 4, NetLogEventType::SOCKET_POOL));
2114 }
2115
TEST_F(ClientSocketPoolBaseTest,InitConnectionAsynchronousFailure)2116 TEST_F(ClientSocketPoolBaseTest,
2117 InitConnectionAsynchronousFailure) {
2118 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2119
2120 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2121 ClientSocketHandle handle;
2122 TestCompletionCallback callback;
2123 NetLogWithSource net_log_with_source =
2124 NetLogWithSource::Make(NetLogSourceType::NONE);
2125 // Set the additional error state members to ensure that they get cleared.
2126 handle.set_is_ssl_error(true);
2127 handle.set_ssl_cert_request_info(base::MakeRefCounted<SSLCertRequestInfo>());
2128 EXPECT_EQ(
2129 ERR_IO_PENDING,
2130 handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
2131 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2132 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2133 pool_.get(), net_log_with_source));
2134 EXPECT_EQ(LOAD_STATE_CONNECTING,
2135 pool_->GetLoadState(TestGroupId("a"), &handle));
2136 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
2137 EXPECT_FALSE(handle.is_ssl_error());
2138 EXPECT_FALSE(handle.ssl_cert_request_info());
2139
2140 auto entries =
2141 net_log_observer_.GetEntriesForSource(net_log_with_source.source());
2142
2143 EXPECT_EQ(4u, entries.size());
2144 EXPECT_TRUE(LogContainsEvent(
2145 entries, 0, NetLogEventType::TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET,
2146 NetLogEventPhase::NONE));
2147 EXPECT_TRUE(LogContainsBeginEvent(entries, 1, NetLogEventType::SOCKET_POOL));
2148 EXPECT_TRUE(LogContainsEvent(
2149 entries, 2, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
2150 NetLogEventPhase::NONE));
2151 EXPECT_TRUE(LogContainsEndEvent(entries, 3, NetLogEventType::SOCKET_POOL));
2152 }
2153
2154 // Check that an async ConnectJob failure does not result in creation of a new
2155 // ConnectJob when there's another pending request also waiting on its own
2156 // ConnectJob. See http://crbug.com/463960.
TEST_F(ClientSocketPoolBaseTest,AsyncFailureWithPendingRequestWithJob)2157 TEST_F(ClientSocketPoolBaseTest, AsyncFailureWithPendingRequestWithJob) {
2158 CreatePool(2, 2);
2159 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2160
2161 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2162 IsError(ERR_IO_PENDING));
2163 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2164 IsError(ERR_IO_PENDING));
2165
2166 EXPECT_THAT(request(0)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
2167 EXPECT_THAT(request(1)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
2168
2169 EXPECT_EQ(2, client_socket_factory_.allocation_count());
2170 }
2171
TEST_F(ClientSocketPoolBaseTest,TwoRequestsCancelOne)2172 TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
2173 // TODO(eroman): Add back the log expectations! Removed them because the
2174 // ordering is difficult, and some may fire during destructor.
2175 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2176
2177 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2178 ClientSocketHandle handle;
2179 TestCompletionCallback callback;
2180 ClientSocketHandle handle2;
2181 TestCompletionCallback callback2;
2182
2183 EXPECT_EQ(
2184 ERR_IO_PENDING,
2185 handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
2186 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2187 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2188 pool_.get(), NetLogWithSource()));
2189 RecordingNetLogObserver log2;
2190 EXPECT_EQ(
2191 ERR_IO_PENDING,
2192 handle2.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
2193 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2194 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2195 pool_.get(), NetLogWithSource()));
2196
2197 handle.Reset();
2198
2199
2200 // At this point, request 2 is just waiting for the connect job to finish.
2201
2202 EXPECT_THAT(callback2.WaitForResult(), IsOk());
2203 handle2.Reset();
2204
2205 // Now request 2 has actually finished.
2206 // TODO(eroman): Add back log expectations.
2207 }
2208
TEST_F(ClientSocketPoolBaseTest,CancelRequestLimitsJobs)2209 TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
2210 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2211
2212 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2213
2214 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
2215 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
2216 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
2217 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
2218
2219 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
2220 static_cast<int>(
2221 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
2222 (*requests())[2]->handle()->Reset();
2223 (*requests())[3]->handle()->Reset();
2224 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
2225 static_cast<int>(
2226 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
2227
2228 (*requests())[1]->handle()->Reset();
2229 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
2230 static_cast<int>(
2231 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
2232
2233 (*requests())[0]->handle()->Reset();
2234 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
2235 static_cast<int>(
2236 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
2237 }
2238
2239 // When requests and ConnectJobs are not coupled, the request will get serviced
2240 // by whatever comes first.
TEST_F(ClientSocketPoolBaseTest,ReleaseSockets)2241 TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
2242 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2243
2244 // Start job 1 (async OK)
2245 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2246
2247 std::vector<TestSocketRequest*> request_order;
2248 size_t completion_count; // unused
2249 TestSocketRequest req1(&request_order, &completion_count);
2250 int rv = req1.handle()->Init(
2251 TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY, SocketTag(),
2252 ClientSocketPool::RespectLimits::ENABLED, req1.callback(),
2253 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
2254 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2255 EXPECT_THAT(req1.WaitForResult(), IsOk());
2256
2257 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
2258 // without a job.
2259 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2260
2261 TestSocketRequest req2(&request_order, &completion_count);
2262 rv = req2.handle()->Init(
2263 TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY, SocketTag(),
2264 ClientSocketPool::RespectLimits::ENABLED, req2.callback(),
2265 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
2266 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2267 TestSocketRequest req3(&request_order, &completion_count);
2268 rv = req3.handle()->Init(
2269 TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY, SocketTag(),
2270 ClientSocketPool::RespectLimits::ENABLED, req3.callback(),
2271 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
2272 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2273
2274 // Both Requests 2 and 3 are pending. We release socket 1 which should
2275 // service request 2. Request 3 should still be waiting.
2276 req1.handle()->Reset();
2277 // Run the released socket wakeups.
2278 base::RunLoop().RunUntilIdle();
2279 ASSERT_TRUE(req2.handle()->socket());
2280 EXPECT_THAT(req2.WaitForResult(), IsOk());
2281 EXPECT_FALSE(req3.handle()->socket());
2282
2283 // Signal job 2, which should service request 3.
2284
2285 client_socket_factory_.SignalJobs();
2286 EXPECT_THAT(req3.WaitForResult(), IsOk());
2287
2288 ASSERT_EQ(3u, request_order.size());
2289 EXPECT_EQ(&req1, request_order[0]);
2290 EXPECT_EQ(&req2, request_order[1]);
2291 EXPECT_EQ(&req3, request_order[2]);
2292 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
2293 }
2294
2295 // The requests are not coupled to the jobs. So, the requests should finish in
2296 // their priority / insertion order.
TEST_F(ClientSocketPoolBaseTest,PendingJobCompletionOrder)2297 TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
2298 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2299 // First two jobs are async.
2300 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2301
2302 std::vector<TestSocketRequest*> request_order;
2303 size_t completion_count; // unused
2304 TestSocketRequest req1(&request_order, &completion_count);
2305 int rv = req1.handle()->Init(
2306 TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY, SocketTag(),
2307 ClientSocketPool::RespectLimits::ENABLED, req1.callback(),
2308 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
2309 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2310
2311 TestSocketRequest req2(&request_order, &completion_count);
2312 rv = req2.handle()->Init(
2313 TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY, SocketTag(),
2314 ClientSocketPool::RespectLimits::ENABLED, req2.callback(),
2315 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
2316 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2317
2318 // The pending job is sync.
2319 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2320
2321 TestSocketRequest req3(&request_order, &completion_count);
2322 rv = req3.handle()->Init(
2323 TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY, SocketTag(),
2324 ClientSocketPool::RespectLimits::ENABLED, req3.callback(),
2325 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
2326 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2327
2328 EXPECT_THAT(req1.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
2329 EXPECT_THAT(req2.WaitForResult(), IsOk());
2330 EXPECT_THAT(req3.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
2331
2332 ASSERT_EQ(3u, request_order.size());
2333 EXPECT_EQ(&req1, request_order[0]);
2334 EXPECT_EQ(&req2, request_order[1]);
2335 EXPECT_EQ(&req3, request_order[2]);
2336 }
2337
2338 // Test GetLoadState in the case there's only one socket request.
TEST_F(ClientSocketPoolBaseTest,LoadStateOneRequest)2339 TEST_F(ClientSocketPoolBaseTest, LoadStateOneRequest) {
2340 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2341 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2342
2343 ClientSocketHandle handle;
2344 TestCompletionCallback callback;
2345 int rv = handle.Init(
2346 TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY, SocketTag(),
2347 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2348 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
2349 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2350 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2351
2352 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2353 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
2354
2355 // No point in completing the connection, since ClientSocketHandles only
2356 // expect the LoadState to be checked while connecting.
2357 }
2358
2359 // Test GetLoadState in the case there are two socket requests.
TEST_F(ClientSocketPoolBaseTest,LoadStateTwoRequests)2360 TEST_F(ClientSocketPoolBaseTest, LoadStateTwoRequests) {
2361 CreatePool(2, 2);
2362 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2363
2364 ClientSocketHandle handle;
2365 TestCompletionCallback callback;
2366 int rv = handle.Init(
2367 TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY, SocketTag(),
2368 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2369 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
2370 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2371 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
2372
2373 ClientSocketHandle handle2;
2374 TestCompletionCallback callback2;
2375 rv = handle2.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
2376 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2377 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2378 pool_.get(), NetLogWithSource());
2379 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2380 client_socket_factory_.SetJobLoadState(1, LOAD_STATE_RESOLVING_HOST);
2381
2382 // Each handle should reflect the state of its own job.
2383 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle.GetLoadState());
2384 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle2.GetLoadState());
2385
2386 // Update the state of the first job.
2387 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_CONNECTING);
2388
2389 // Only the state of the first request should have changed.
2390 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2391 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle2.GetLoadState());
2392
2393 // Update the state of the second job.
2394 client_socket_factory_.SetJobLoadState(1, LOAD_STATE_SSL_HANDSHAKE);
2395
2396 // Only the state of the second request should have changed.
2397 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2398 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle2.GetLoadState());
2399
2400 // Second job connects and the first request gets the socket. The
2401 // second handle switches to the state of the remaining ConnectJob.
2402 client_socket_factory_.SignalJob(1);
2403 EXPECT_THAT(callback.WaitForResult(), IsOk());
2404 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
2405 }
2406
2407 // Test GetLoadState in the case the per-group limit is reached.
TEST_F(ClientSocketPoolBaseTest,LoadStateGroupLimit)2408 TEST_F(ClientSocketPoolBaseTest, LoadStateGroupLimit) {
2409 CreatePool(2, 1);
2410 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2411
2412 ClientSocketHandle handle;
2413 TestCompletionCallback callback;
2414 int rv = handle.Init(
2415 TestGroupId("a"), params_, absl::nullopt, MEDIUM, SocketTag(),
2416 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2417 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
2418 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2419 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2420
2421 // Request another socket from the same pool, buth with a higher priority.
2422 // The first request should now be stalled at the socket group limit.
2423 ClientSocketHandle handle2;
2424 TestCompletionCallback callback2;
2425 rv = handle2.Init(TestGroupId("a"), params_, absl::nullopt, HIGHEST,
2426 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2427 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2428 pool_.get(), NetLogWithSource());
2429 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2430 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2431 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
2432
2433 // The first handle should remain stalled as the other socket goes through
2434 // the connect process.
2435
2436 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2437 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2438 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle2.GetLoadState());
2439
2440 client_socket_factory_.SignalJob(0);
2441 EXPECT_THAT(callback2.WaitForResult(), IsOk());
2442 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2443
2444 // Closing the second socket should cause the stalled handle to finally get a
2445 // ConnectJob.
2446 handle2.socket()->Disconnect();
2447 handle2.Reset();
2448 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2449 }
2450
2451 // Test GetLoadState in the case the per-pool limit is reached.
TEST_F(ClientSocketPoolBaseTest,LoadStatePoolLimit)2452 TEST_F(ClientSocketPoolBaseTest, LoadStatePoolLimit) {
2453 CreatePool(2, 2);
2454 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2455
2456 ClientSocketHandle handle;
2457 TestCompletionCallback callback;
2458 int rv = handle.Init(
2459 TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY, SocketTag(),
2460 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2461 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
2462 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2463
2464 // Request for socket from another pool.
2465 ClientSocketHandle handle2;
2466 TestCompletionCallback callback2;
2467 rv = handle2.Init(TestGroupId("b"), params_, absl::nullopt, DEFAULT_PRIORITY,
2468 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2469 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2470 pool_.get(), NetLogWithSource());
2471 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2472
2473 // Request another socket from the first pool. Request should stall at the
2474 // socket pool limit.
2475 ClientSocketHandle handle3;
2476 TestCompletionCallback callback3;
2477 rv = handle3.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
2478 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2479 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2480 pool_.get(), NetLogWithSource());
2481 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2482
2483 // The third handle should remain stalled as the other sockets in its group
2484 // goes through the connect process.
2485
2486 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2487 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2488
2489 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2490 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
2491 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2492
2493 client_socket_factory_.SignalJob(0);
2494 EXPECT_THAT(callback.WaitForResult(), IsOk());
2495 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2496
2497 // Closing a socket should allow the stalled handle to finally get a new
2498 // ConnectJob.
2499 handle.socket()->Disconnect();
2500 handle.Reset();
2501 EXPECT_EQ(LOAD_STATE_CONNECTING, handle3.GetLoadState());
2502 }
2503
TEST_F(ClientSocketPoolBaseTest,CertError)2504 TEST_F(ClientSocketPoolBaseTest, CertError) {
2505 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2506 connect_job_factory_->set_job_type(TestConnectJob::kMockCertErrorJob);
2507
2508 ClientSocketHandle handle;
2509 TestCompletionCallback callback;
2510 EXPECT_EQ(
2511 ERR_CERT_COMMON_NAME_INVALID,
2512 handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
2513 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2514 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2515 pool_.get(), NetLogWithSource()));
2516 EXPECT_TRUE(handle.is_initialized());
2517 EXPECT_TRUE(handle.socket());
2518 }
2519
TEST_F(ClientSocketPoolBaseTest,AsyncCertError)2520 TEST_F(ClientSocketPoolBaseTest, AsyncCertError) {
2521 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2522
2523 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingCertErrorJob);
2524 ClientSocketHandle handle;
2525 TestCompletionCallback callback;
2526 EXPECT_EQ(
2527 ERR_IO_PENDING,
2528 handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
2529 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2530 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2531 pool_.get(), NetLogWithSource()));
2532 EXPECT_EQ(LOAD_STATE_CONNECTING,
2533 pool_->GetLoadState(TestGroupId("a"), &handle));
2534 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CERT_COMMON_NAME_INVALID));
2535 EXPECT_TRUE(handle.is_initialized());
2536 EXPECT_TRUE(handle.socket());
2537 }
2538
TEST_F(ClientSocketPoolBaseTest,AdditionalErrorStateSynchronous)2539 TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
2540 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2541 connect_job_factory_->set_job_type(
2542 TestConnectJob::kMockAdditionalErrorStateJob);
2543
2544 ClientSocketHandle handle;
2545 TestCompletionCallback callback;
2546 EXPECT_EQ(
2547 ERR_CONNECTION_FAILED,
2548 handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
2549 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2550 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2551 pool_.get(), NetLogWithSource()));
2552 EXPECT_FALSE(handle.is_initialized());
2553 EXPECT_FALSE(handle.socket());
2554 EXPECT_TRUE(handle.is_ssl_error());
2555 EXPECT_TRUE(handle.ssl_cert_request_info());
2556 }
2557
TEST_F(ClientSocketPoolBaseTest,AdditionalErrorStateAsynchronous)2558 TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
2559 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2560
2561 connect_job_factory_->set_job_type(
2562 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2563 ClientSocketHandle handle;
2564 TestCompletionCallback callback;
2565 EXPECT_EQ(
2566 ERR_IO_PENDING,
2567 handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
2568 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2569 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2570 pool_.get(), NetLogWithSource()));
2571 EXPECT_EQ(LOAD_STATE_CONNECTING,
2572 pool_->GetLoadState(TestGroupId("a"), &handle));
2573 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
2574 EXPECT_FALSE(handle.is_initialized());
2575 EXPECT_FALSE(handle.socket());
2576 EXPECT_TRUE(handle.is_ssl_error());
2577 EXPECT_TRUE(handle.ssl_cert_request_info());
2578 }
2579
2580 // Make sure we can reuse sockets.
TEST_F(ClientSocketPoolBaseTest,CleanupTimedOutIdleSocketsReuse)2581 TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSocketsReuse) {
2582 CreatePoolWithIdleTimeouts(
2583 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2584 base::TimeDelta(), // Time out unused sockets immediately.
2585 base::Days(1)); // Don't time out used sockets.
2586
2587 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2588
2589 ClientSocketHandle handle;
2590 TestCompletionCallback callback;
2591 int rv = handle.Init(
2592 TestGroupId("a"), params_, absl::nullopt, LOWEST, SocketTag(),
2593 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2594 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
2595 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
2596 EXPECT_EQ(LOAD_STATE_CONNECTING,
2597 pool_->GetLoadState(TestGroupId("a"), &handle));
2598 ASSERT_THAT(callback.WaitForResult(), IsOk());
2599
2600 // Use and release the socket.
2601 EXPECT_EQ(1, handle.socket()->Write(nullptr, 1, CompletionOnceCallback(),
2602 TRAFFIC_ANNOTATION_FOR_TESTS));
2603 TestLoadTimingInfoConnectedNotReused(handle);
2604 handle.Reset();
2605
2606 // Should now have one idle socket.
2607 ASSERT_EQ(1, pool_->IdleSocketCount());
2608
2609 // Request a new socket. This should reuse the old socket and complete
2610 // synchronously.
2611 NetLogWithSource net_log_with_source =
2612 NetLogWithSource::Make(NetLogSourceType::NONE);
2613 rv = handle.Init(
2614 TestGroupId("a"), params_, absl::nullopt, LOWEST, SocketTag(),
2615 ClientSocketPool::RespectLimits::ENABLED, CompletionOnceCallback(),
2616 ClientSocketPool::ProxyAuthCallback(), pool_.get(), net_log_with_source);
2617 ASSERT_THAT(rv, IsOk());
2618 EXPECT_TRUE(handle.is_reused());
2619 TestLoadTimingInfoConnectedReused(handle);
2620
2621 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
2622 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
2623 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
2624
2625 auto entries =
2626 net_log_observer_.GetEntriesForSource(net_log_with_source.source());
2627 EXPECT_TRUE(LogContainsEvent(
2628 entries, 0, NetLogEventType::TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET,
2629 NetLogEventPhase::NONE));
2630 EXPECT_TRUE(LogContainsBeginEvent(entries, 1, NetLogEventType::SOCKET_POOL));
2631 EXPECT_TRUE(LogContainsEntryWithType(
2632 entries, 2, NetLogEventType::SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
2633 }
2634
2635 // Make sure we cleanup old unused sockets.
TEST_F(ClientSocketPoolBaseTest,CleanupTimedOutIdleSocketsNoReuse)2636 TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSocketsNoReuse) {
2637 CreatePoolWithIdleTimeouts(
2638 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2639 base::TimeDelta(), // Time out unused sockets immediately
2640 base::TimeDelta()); // Time out used sockets immediately
2641
2642 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2643
2644 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2645
2646 ClientSocketHandle handle;
2647 TestCompletionCallback callback;
2648 int rv = handle.Init(
2649 TestGroupId("a"), params_, absl::nullopt, LOWEST, SocketTag(),
2650 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2651 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
2652 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
2653 EXPECT_EQ(LOAD_STATE_CONNECTING,
2654 pool_->GetLoadState(TestGroupId("a"), &handle));
2655
2656 ClientSocketHandle handle2;
2657 TestCompletionCallback callback2;
2658 rv = handle2.Init(TestGroupId("a"), params_, absl::nullopt, LOWEST,
2659 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2660 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2661 pool_.get(), NetLogWithSource());
2662 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
2663 EXPECT_EQ(LOAD_STATE_CONNECTING,
2664 pool_->GetLoadState(TestGroupId("a"), &handle2));
2665
2666 // Cancel one of the requests. Wait for the other, which will get the first
2667 // job. Release the socket. Run the loop again to make sure the second
2668 // socket is sitting idle and the first one is released (since ReleaseSocket()
2669 // just posts a DoReleaseSocket() task).
2670
2671 handle.Reset();
2672 ASSERT_THAT(callback2.WaitForResult(), IsOk());
2673 // Get the NetLogSource for the socket, so the time out reason can be checked
2674 // at the end of the test.
2675 NetLogSource net_log_source2 = handle2.socket()->NetLog().source();
2676 // Use the socket.
2677 EXPECT_EQ(1, handle2.socket()->Write(nullptr, 1, CompletionOnceCallback(),
2678 TRAFFIC_ANNOTATION_FOR_TESTS));
2679 handle2.Reset();
2680
2681 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2682 // actually become pending until 2ms after they have been created. In order
2683 // to flush all tasks, we need to wait so that we know there are no
2684 // soon-to-be-pending tasks waiting.
2685 FastForwardBy(base::Milliseconds(10));
2686
2687 // Both sockets should now be idle.
2688 ASSERT_EQ(2, pool_->IdleSocketCount());
2689
2690 // Request a new socket. This should cleanup the unused and timed out ones.
2691 // A new socket will be created rather than reusing the idle one.
2692 NetLogWithSource net_log_with_source =
2693 NetLogWithSource::Make(NetLogSourceType::NONE);
2694 TestCompletionCallback callback3;
2695 rv = handle.Init(TestGroupId("a"), params_, absl::nullopt, LOWEST,
2696 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2697 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
2698 pool_.get(), net_log_with_source);
2699 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
2700 ASSERT_THAT(callback3.WaitForResult(), IsOk());
2701 EXPECT_FALSE(handle.is_reused());
2702
2703 // Make sure the idle socket is closed.
2704 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
2705 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
2706 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
2707
2708 auto entries =
2709 net_log_observer_.GetEntriesForSource(net_log_with_source.source());
2710 EXPECT_FALSE(LogContainsEntryWithType(
2711 entries, 1, NetLogEventType::SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
2712 ExpectSocketClosedWithReason(
2713 net_log_source2, TransportClientSocketPool::kIdleTimeLimitExpired);
2714 }
2715
2716 // Make sure that we process all pending requests even when we're stalling
2717 // because of multiple releasing disconnected sockets.
TEST_F(ClientSocketPoolBaseTest,MultipleReleasingDisconnectedSockets)2718 TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
2719 CreatePoolWithIdleTimeouts(
2720 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2721 base::TimeDelta(), // Time out unused sockets immediately.
2722 base::Days(1)); // Don't time out used sockets.
2723
2724 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2725
2726 // Startup 4 connect jobs. Two of them will be pending.
2727
2728 ClientSocketHandle handle;
2729 TestCompletionCallback callback;
2730 int rv = handle.Init(
2731 TestGroupId("a"), params_, absl::nullopt, LOWEST, SocketTag(),
2732 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2733 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
2734 EXPECT_THAT(rv, IsOk());
2735
2736 ClientSocketHandle handle2;
2737 TestCompletionCallback callback2;
2738 rv = handle2.Init(TestGroupId("a"), params_, absl::nullopt, LOWEST,
2739 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2740 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2741 pool_.get(), NetLogWithSource());
2742 EXPECT_THAT(rv, IsOk());
2743
2744 ClientSocketHandle handle3;
2745 TestCompletionCallback callback3;
2746 rv = handle3.Init(TestGroupId("a"), params_, absl::nullopt, LOWEST,
2747 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2748 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
2749 pool_.get(), NetLogWithSource());
2750 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2751
2752 ClientSocketHandle handle4;
2753 TestCompletionCallback callback4;
2754 rv = handle4.Init(TestGroupId("a"), params_, absl::nullopt, LOWEST,
2755 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2756 callback4.callback(), ClientSocketPool::ProxyAuthCallback(),
2757 pool_.get(), NetLogWithSource());
2758 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2759
2760 // Release two disconnected sockets.
2761
2762 handle.socket()->Disconnect();
2763 handle.Reset();
2764 handle2.socket()->Disconnect();
2765 handle2.Reset();
2766
2767 EXPECT_THAT(callback3.WaitForResult(), IsOk());
2768 EXPECT_FALSE(handle3.is_reused());
2769 EXPECT_THAT(callback4.WaitForResult(), IsOk());
2770 EXPECT_FALSE(handle4.is_reused());
2771 }
2772
2773 // Regression test for http://crbug.com/42267.
2774 // When DoReleaseSocket() is processed for one socket, it is blocked because the
2775 // other stalled groups all have releasing sockets, so no progress can be made.
TEST_F(ClientSocketPoolBaseTest,SocketLimitReleasingSockets)2776 TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
2777 CreatePoolWithIdleTimeouts(
2778 4 /* socket limit */, 4 /* socket limit per group */,
2779 base::TimeDelta(), // Time out unused sockets immediately.
2780 base::Days(1)); // Don't time out used sockets.
2781
2782 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2783
2784 // Max out the socket limit with 2 per group.
2785
2786 ClientSocketHandle handle_a[4];
2787 TestCompletionCallback callback_a[4];
2788 ClientSocketHandle handle_b[4];
2789 TestCompletionCallback callback_b[4];
2790
2791 for (int i = 0; i < 2; ++i) {
2792 EXPECT_EQ(OK, handle_a[i].Init(TestGroupId("a"), params_, absl::nullopt,
2793 LOWEST, SocketTag(),
2794 ClientSocketPool::RespectLimits::ENABLED,
2795 callback_a[i].callback(),
2796 ClientSocketPool::ProxyAuthCallback(),
2797 pool_.get(), NetLogWithSource()));
2798 EXPECT_EQ(OK, handle_b[i].Init(TestGroupId("b"), params_, absl::nullopt,
2799 LOWEST, SocketTag(),
2800 ClientSocketPool::RespectLimits::ENABLED,
2801 callback_b[i].callback(),
2802 ClientSocketPool::ProxyAuthCallback(),
2803 pool_.get(), NetLogWithSource()));
2804 }
2805
2806 // Make 4 pending requests, 2 per group.
2807
2808 for (int i = 2; i < 4; ++i) {
2809 EXPECT_EQ(
2810 ERR_IO_PENDING,
2811 handle_a[i].Init(TestGroupId("a"), params_, absl::nullopt, LOWEST,
2812 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2813 callback_a[i].callback(),
2814 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2815 NetLogWithSource()));
2816 EXPECT_EQ(
2817 ERR_IO_PENDING,
2818 handle_b[i].Init(TestGroupId("b"), params_, absl::nullopt, LOWEST,
2819 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2820 callback_b[i].callback(),
2821 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2822 NetLogWithSource()));
2823 }
2824
2825 // Release b's socket first. The order is important, because in
2826 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2827 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2828 // first, which has a releasing socket, so it refuses to start up another
2829 // ConnectJob. So, we used to infinite loop on this.
2830 handle_b[0].socket()->Disconnect();
2831 handle_b[0].Reset();
2832 handle_a[0].socket()->Disconnect();
2833 handle_a[0].Reset();
2834
2835 // Used to get stuck here.
2836 base::RunLoop().RunUntilIdle();
2837
2838 handle_b[1].socket()->Disconnect();
2839 handle_b[1].Reset();
2840 handle_a[1].socket()->Disconnect();
2841 handle_a[1].Reset();
2842
2843 for (int i = 2; i < 4; ++i) {
2844 EXPECT_THAT(callback_b[i].WaitForResult(), IsOk());
2845 EXPECT_THAT(callback_a[i].WaitForResult(), IsOk());
2846 }
2847 }
2848
TEST_F(ClientSocketPoolBaseTest,ReleasingDisconnectedSocketsMaintainsPriorityOrder)2849 TEST_F(ClientSocketPoolBaseTest,
2850 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2851 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2852
2853 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2854
2855 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2856 IsError(ERR_IO_PENDING));
2857 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2858 IsError(ERR_IO_PENDING));
2859 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2860 IsError(ERR_IO_PENDING));
2861 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2862 IsError(ERR_IO_PENDING));
2863
2864 EXPECT_THAT((*requests())[0]->WaitForResult(), IsOk());
2865 EXPECT_THAT((*requests())[1]->WaitForResult(), IsOk());
2866 EXPECT_EQ(2u, completion_count());
2867
2868 // Releases one connection.
2869 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2870 EXPECT_THAT((*requests())[2]->WaitForResult(), IsOk());
2871
2872 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2873 EXPECT_THAT((*requests())[3]->WaitForResult(), IsOk());
2874 EXPECT_EQ(4u, completion_count());
2875
2876 EXPECT_EQ(1, GetOrderOfRequest(1));
2877 EXPECT_EQ(2, GetOrderOfRequest(2));
2878 EXPECT_EQ(3, GetOrderOfRequest(3));
2879 EXPECT_EQ(4, GetOrderOfRequest(4));
2880
2881 // Make sure we test order of all requests made.
2882 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
2883 }
2884
2885 class TestReleasingSocketRequest : public TestCompletionCallbackBase {
2886 public:
TestReleasingSocketRequest(TransportClientSocketPool * pool,int expected_result,bool reset_releasing_handle)2887 TestReleasingSocketRequest(TransportClientSocketPool* pool,
2888 int expected_result,
2889 bool reset_releasing_handle)
2890 : pool_(pool),
2891 expected_result_(expected_result),
2892 reset_releasing_handle_(reset_releasing_handle) {}
2893
2894 ~TestReleasingSocketRequest() override = default;
2895
handle()2896 ClientSocketHandle* handle() { return &handle_; }
2897
callback()2898 CompletionOnceCallback callback() {
2899 return base::BindOnce(&TestReleasingSocketRequest::OnComplete,
2900 base::Unretained(this));
2901 }
2902
2903 private:
OnComplete(int result)2904 void OnComplete(int result) {
2905 SetResult(result);
2906 if (reset_releasing_handle_)
2907 handle_.Reset();
2908
2909 EXPECT_EQ(
2910 expected_result_,
2911 handle2_.Init(
2912 TestGroupId("a"),
2913 ClientSocketPool::SocketParams::CreateForHttpForTesting(),
2914 absl::nullopt, DEFAULT_PRIORITY, SocketTag(),
2915 ClientSocketPool::RespectLimits::ENABLED, CompletionOnceCallback(),
2916 ClientSocketPool::ProxyAuthCallback(), pool_, NetLogWithSource()));
2917 }
2918
2919 const raw_ptr<TransportClientSocketPool> pool_;
2920 int expected_result_;
2921 bool reset_releasing_handle_;
2922 ClientSocketHandle handle_;
2923 ClientSocketHandle handle2_;
2924 };
2925
2926
TEST_F(ClientSocketPoolBaseTest,AdditionalErrorSocketsDontUseSlot)2927 TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2928 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2929
2930 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
2931 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
2932 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
2933
2934 EXPECT_EQ(static_cast<int>(requests_size()),
2935 client_socket_factory_.allocation_count());
2936
2937 connect_job_factory_->set_job_type(
2938 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2939 TestReleasingSocketRequest req(pool_.get(), OK, false);
2940 EXPECT_EQ(ERR_IO_PENDING,
2941 req.handle()->Init(
2942 TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
2943 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2944 req.callback(), ClientSocketPool::ProxyAuthCallback(),
2945 pool_.get(), NetLogWithSource()));
2946 // The next job should complete synchronously
2947 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2948
2949 EXPECT_THAT(req.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
2950 EXPECT_FALSE(req.handle()->is_initialized());
2951 EXPECT_FALSE(req.handle()->socket());
2952 EXPECT_TRUE(req.handle()->is_ssl_error());
2953 EXPECT_TRUE(req.handle()->ssl_cert_request_info());
2954 }
2955
2956 // http://crbug.com/44724 regression test.
2957 // We start releasing the pool when we flush on network change. When that
2958 // happens, the only active references are in the ClientSocketHandles. When a
2959 // ConnectJob completes and calls back into the last ClientSocketHandle, that
2960 // callback can release the last reference and delete the pool. After the
2961 // callback finishes, we go back to the stack frame within the now-deleted pool.
2962 // Executing any code that refers to members of the now-deleted pool can cause
2963 // crashes.
TEST_F(ClientSocketPoolBaseTest,CallbackThatReleasesPool)2964 TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2965 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2966 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2967
2968 ClientSocketHandle handle;
2969 TestCompletionCallback callback;
2970 EXPECT_EQ(
2971 ERR_IO_PENDING,
2972 handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
2973 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2974 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2975 pool_.get(), NetLogWithSource()));
2976
2977 pool_->FlushWithError(ERR_NETWORK_CHANGED, "Network changed");
2978
2979 // We'll call back into this now.
2980 callback.WaitForResult();
2981 }
2982
TEST_F(ClientSocketPoolBaseTest,DoNotReuseSocketAfterFlush)2983 TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2984 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2985 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2986
2987 ClientSocketHandle handle;
2988 TestCompletionCallback callback;
2989 EXPECT_EQ(
2990 ERR_IO_PENDING,
2991 handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
2992 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2993 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2994 pool_.get(), NetLogWithSource()));
2995 EXPECT_THAT(callback.WaitForResult(), IsOk());
2996 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2997 NetLogSource source = handle.socket()->NetLog().source();
2998
2999 pool_->FlushWithError(ERR_NETWORK_CHANGED, "Network changed");
3000
3001 handle.Reset();
3002 base::RunLoop().RunUntilIdle();
3003
3004 EXPECT_EQ(
3005 ERR_IO_PENDING,
3006 handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
3007 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3008 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3009 pool_.get(), NetLogWithSource()));
3010 EXPECT_THAT(callback.WaitForResult(), IsOk());
3011 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
3012
3013 ExpectSocketClosedWithReason(
3014 source, TransportClientSocketPool::kSocketGenerationOutOfDate);
3015 }
3016
3017 class ConnectWithinCallback : public TestCompletionCallbackBase {
3018 public:
ConnectWithinCallback(const ClientSocketPool::GroupId & group_id,const scoped_refptr<ClientSocketPool::SocketParams> & params,TransportClientSocketPool * pool)3019 ConnectWithinCallback(
3020 const ClientSocketPool::GroupId& group_id,
3021 const scoped_refptr<ClientSocketPool::SocketParams>& params,
3022 TransportClientSocketPool* pool)
3023 : group_id_(group_id), params_(params), pool_(pool) {}
3024
3025 ConnectWithinCallback(const ConnectWithinCallback&) = delete;
3026 ConnectWithinCallback& operator=(const ConnectWithinCallback&) = delete;
3027
3028 ~ConnectWithinCallback() override = default;
3029
WaitForNestedResult()3030 int WaitForNestedResult() {
3031 return nested_callback_.WaitForResult();
3032 }
3033
callback()3034 CompletionOnceCallback callback() {
3035 return base::BindOnce(&ConnectWithinCallback::OnComplete,
3036 base::Unretained(this));
3037 }
3038
3039 private:
OnComplete(int result)3040 void OnComplete(int result) {
3041 SetResult(result);
3042 EXPECT_EQ(
3043 ERR_IO_PENDING,
3044 handle_.Init(group_id_, params_, absl::nullopt, DEFAULT_PRIORITY,
3045 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3046 nested_callback_.callback(),
3047 ClientSocketPool::ProxyAuthCallback(), pool_,
3048 NetLogWithSource()));
3049 }
3050
3051 const ClientSocketPool::GroupId group_id_;
3052 const scoped_refptr<ClientSocketPool::SocketParams> params_;
3053 const raw_ptr<TransportClientSocketPool> pool_;
3054 ClientSocketHandle handle_;
3055 TestCompletionCallback nested_callback_;
3056 };
3057
TEST_F(ClientSocketPoolBaseTest,AbortAllRequestsOnFlush)3058 TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
3059 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3060
3061 // First job will be waiting until it gets aborted.
3062 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3063
3064 ClientSocketHandle handle;
3065 ConnectWithinCallback callback(TestGroupId("a"), params_, pool_.get());
3066 EXPECT_EQ(
3067 ERR_IO_PENDING,
3068 handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
3069 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3070 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3071 pool_.get(), NetLogWithSource()));
3072
3073 // Second job will be started during the first callback, and will
3074 // asynchronously complete with OK.
3075 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3076 pool_->FlushWithError(ERR_NETWORK_CHANGED, "Network changed");
3077 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NETWORK_CHANGED));
3078 EXPECT_THAT(callback.WaitForNestedResult(), IsOk());
3079 }
3080
TEST_F(ClientSocketPoolBaseTest,BackupSocketWaitsForHostResolution)3081 TEST_F(ClientSocketPoolBaseTest, BackupSocketWaitsForHostResolution) {
3082 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets,
3083 true /* enable_backup_connect_jobs */);
3084
3085 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3086 ClientSocketHandle handle;
3087 TestCompletionCallback callback;
3088 EXPECT_EQ(
3089 ERR_IO_PENDING,
3090 handle.Init(TestGroupId("bar"), params_, absl::nullopt, DEFAULT_PRIORITY,
3091 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3092 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3093 pool_.get(), NetLogWithSource()));
3094 // The backup timer fires but doesn't start a new ConnectJob while resolving
3095 // the hostname.
3096 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
3097 FastForwardBy(
3098 base::Milliseconds(ClientSocketPool::kMaxConnectRetryIntervalMs * 100));
3099 EXPECT_EQ(1, client_socket_factory_.allocation_count());
3100
3101 // Once the ConnectJob has finished resolving the hostname, the backup timer
3102 // will create a ConnectJob when it fires.
3103 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_CONNECTING);
3104 FastForwardBy(
3105 base::Milliseconds(ClientSocketPool::kMaxConnectRetryIntervalMs));
3106 EXPECT_EQ(2, client_socket_factory_.allocation_count());
3107 }
3108
3109 // Test that no backup socket is created when a ConnectJob connects before it
3110 // completes.
TEST_F(ClientSocketPoolBaseTest,NoBackupSocketWhenConnected)3111 TEST_F(ClientSocketPoolBaseTest, NoBackupSocketWhenConnected) {
3112 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets,
3113 true /* enable_backup_connect_jobs */);
3114
3115 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3116 ClientSocketHandle handle;
3117 TestCompletionCallback callback;
3118 EXPECT_EQ(
3119 ERR_IO_PENDING,
3120 handle.Init(TestGroupId("bar"), params_, absl::nullopt, DEFAULT_PRIORITY,
3121 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3122 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3123 pool_.get(), NetLogWithSource()));
3124 // The backup timer fires but doesn't start a new ConnectJob while resolving
3125 // the hostname.
3126 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
3127 FastForwardBy(
3128 base::Milliseconds(ClientSocketPool::kMaxConnectRetryIntervalMs * 100));
3129 EXPECT_EQ(1, client_socket_factory_.allocation_count());
3130
3131 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
3132 client_socket_factory_.SetJobHasEstablishedConnection(0);
3133 FastForwardBy(
3134 base::Milliseconds(ClientSocketPool::kMaxConnectRetryIntervalMs * 100));
3135 EXPECT_EQ(1, client_socket_factory_.allocation_count());
3136 }
3137
3138 // Cancel a pending socket request while we're at max sockets,
3139 // and verify that the backup socket firing doesn't cause a crash.
TEST_F(ClientSocketPoolBaseTest,BackupSocketCancelAtMaxSockets)3140 TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
3141 // Max 4 sockets globally, max 4 sockets per group.
3142 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets,
3143 true /* enable_backup_connect_jobs */);
3144
3145 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
3146 // timer.
3147 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3148 ClientSocketHandle handle;
3149 TestCompletionCallback callback;
3150 EXPECT_EQ(
3151 ERR_IO_PENDING,
3152 handle.Init(TestGroupId("bar"), params_, absl::nullopt, DEFAULT_PRIORITY,
3153 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3154 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3155 pool_.get(), NetLogWithSource()));
3156
3157 // Start (MaxSockets - 1) connected sockets to reach max sockets.
3158 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3159 ClientSocketHandle handles[kDefaultMaxSockets];
3160 for (int i = 1; i < kDefaultMaxSockets; ++i) {
3161 EXPECT_EQ(OK, handles[i].Init(TestGroupId("bar"), params_, absl::nullopt,
3162 DEFAULT_PRIORITY, SocketTag(),
3163 ClientSocketPool::RespectLimits::ENABLED,
3164 callback.callback(),
3165 ClientSocketPool::ProxyAuthCallback(),
3166 pool_.get(), NetLogWithSource()));
3167 }
3168
3169 base::RunLoop().RunUntilIdle();
3170
3171 // Cancel the pending request.
3172 handle.Reset();
3173
3174 // Wait for the backup timer to fire (add some slop to ensure it fires)
3175 FastForwardBy(
3176 base::Milliseconds(ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
3177
3178 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
3179 }
3180
TEST_F(ClientSocketPoolBaseTest,CancelBackupSocketAfterCancelingAllRequests)3181 TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
3182 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets,
3183 true /* enable_backup_connect_jobs */);
3184
3185 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
3186 // timer.
3187 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3188 ClientSocketHandle handle;
3189 TestCompletionCallback callback;
3190 EXPECT_EQ(
3191 ERR_IO_PENDING,
3192 handle.Init(TestGroupId("bar"), params_, absl::nullopt, DEFAULT_PRIORITY,
3193 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3194 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3195 pool_.get(), NetLogWithSource()));
3196 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("bar")));
3197 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("bar")));
3198 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3199 TestGroupId("bar")));
3200 EXPECT_EQ(
3201 0u, pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("bar")));
3202
3203 // Cancel the socket request. This should cancel the backup timer. Wait for
3204 // the backup time to see if it indeed got canceled.
3205 handle.Reset();
3206 // Wait for the backup timer to fire (add some slop to ensure it fires)
3207 FastForwardBy(
3208 base::Milliseconds(ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
3209 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("bar")));
3210 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("bar")));
3211 }
3212
TEST_F(ClientSocketPoolBaseTest,CancelBackupSocketAfterFinishingAllRequests)3213 TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
3214 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets,
3215 true /* enable_backup_connect_jobs */);
3216
3217 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
3218 // timer.
3219 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3220 ClientSocketHandle handle;
3221 TestCompletionCallback callback;
3222 EXPECT_EQ(
3223 ERR_IO_PENDING,
3224 handle.Init(TestGroupId("bar"), params_, absl::nullopt, DEFAULT_PRIORITY,
3225 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3226 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3227 pool_.get(), NetLogWithSource()));
3228 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3229 ClientSocketHandle handle2;
3230 TestCompletionCallback callback2;
3231 EXPECT_EQ(
3232 ERR_IO_PENDING,
3233 handle2.Init(TestGroupId("bar"), params_, absl::nullopt, DEFAULT_PRIORITY,
3234 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3235 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3236 pool_.get(), NetLogWithSource()));
3237 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("bar")));
3238 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("bar")));
3239
3240 // Cancel request 1 and then complete request 2. With the requests finished,
3241 // the backup timer should be cancelled.
3242 handle.Reset();
3243 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3244 // Wait for the backup timer to fire (add some slop to ensure it fires)
3245 FastForwardBy(
3246 base::Milliseconds(ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
3247 }
3248
3249 // Test delayed socket binding for the case where we have two connects,
3250 // and while one is waiting on a connect, the other frees up.
3251 // The socket waiting on a connect should switch immediately to the freed
3252 // up socket.
TEST_F(ClientSocketPoolBaseTest,DelayedSocketBindingWaitingForConnect)3253 TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
3254 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3255 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3256
3257 ClientSocketHandle handle1;
3258 TestCompletionCallback callback;
3259 EXPECT_EQ(
3260 ERR_IO_PENDING,
3261 handle1.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
3262 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3263 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3264 pool_.get(), NetLogWithSource()));
3265 EXPECT_THAT(callback.WaitForResult(), IsOk());
3266
3267 // No idle sockets, no pending jobs.
3268 EXPECT_EQ(0, pool_->IdleSocketCount());
3269 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3270
3271 // Create a second socket to the same host, but this one will wait.
3272 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3273 ClientSocketHandle handle2;
3274 EXPECT_EQ(
3275 ERR_IO_PENDING,
3276 handle2.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
3277 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3278 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3279 pool_.get(), NetLogWithSource()));
3280 // No idle sockets, and one connecting job.
3281 EXPECT_EQ(0, pool_->IdleSocketCount());
3282 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3283
3284 // Return the first handle to the pool. This will initiate the delayed
3285 // binding.
3286 handle1.Reset();
3287
3288 base::RunLoop().RunUntilIdle();
3289
3290 // Still no idle sockets, still one pending connect job.
3291 EXPECT_EQ(0, pool_->IdleSocketCount());
3292 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3293
3294 // The second socket connected, even though it was a Waiting Job.
3295 EXPECT_THAT(callback.WaitForResult(), IsOk());
3296
3297 // And we can see there is still one job waiting.
3298 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3299
3300 // Finally, signal the waiting Connect.
3301 client_socket_factory_.SignalJobs();
3302 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3303
3304 base::RunLoop().RunUntilIdle();
3305 }
3306
3307 // Test delayed socket binding when a group is at capacity and one
3308 // of the group's sockets frees up.
TEST_F(ClientSocketPoolBaseTest,DelayedSocketBindingAtGroupCapacity)3309 TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
3310 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3311 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3312
3313 ClientSocketHandle handle1;
3314 TestCompletionCallback callback;
3315 EXPECT_EQ(
3316 ERR_IO_PENDING,
3317 handle1.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
3318 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3319 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3320 pool_.get(), NetLogWithSource()));
3321 EXPECT_THAT(callback.WaitForResult(), IsOk());
3322
3323 // No idle sockets, no pending jobs.
3324 EXPECT_EQ(0, pool_->IdleSocketCount());
3325 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3326
3327 // Create a second socket to the same host, but this one will wait.
3328 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3329 ClientSocketHandle handle2;
3330 EXPECT_EQ(
3331 ERR_IO_PENDING,
3332 handle2.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
3333 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3334 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3335 pool_.get(), NetLogWithSource()));
3336 // No idle sockets, and one connecting job.
3337 EXPECT_EQ(0, pool_->IdleSocketCount());
3338 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3339
3340 // Return the first handle to the pool. This will initiate the delayed
3341 // binding.
3342 handle1.Reset();
3343
3344 base::RunLoop().RunUntilIdle();
3345
3346 // Still no idle sockets, still one pending connect job.
3347 EXPECT_EQ(0, pool_->IdleSocketCount());
3348 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3349
3350 // The second socket connected, even though it was a Waiting Job.
3351 EXPECT_THAT(callback.WaitForResult(), IsOk());
3352
3353 // And we can see there is still one job waiting.
3354 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3355
3356 // Finally, signal the waiting Connect.
3357 client_socket_factory_.SignalJobs();
3358 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3359
3360 base::RunLoop().RunUntilIdle();
3361 }
3362
3363 // Test out the case where we have one socket connected, one
3364 // connecting, when the first socket finishes and goes idle.
3365 // Although the second connection is pending, the second request
3366 // should complete, by taking the first socket's idle socket.
TEST_F(ClientSocketPoolBaseTest,DelayedSocketBindingAtStall)3367 TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
3368 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3369 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3370
3371 ClientSocketHandle handle1;
3372 TestCompletionCallback callback;
3373 EXPECT_EQ(
3374 ERR_IO_PENDING,
3375 handle1.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
3376 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3377 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3378 pool_.get(), NetLogWithSource()));
3379 EXPECT_THAT(callback.WaitForResult(), IsOk());
3380
3381 // No idle sockets, no pending jobs.
3382 EXPECT_EQ(0, pool_->IdleSocketCount());
3383 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3384
3385 // Create a second socket to the same host, but this one will wait.
3386 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3387 ClientSocketHandle handle2;
3388 EXPECT_EQ(
3389 ERR_IO_PENDING,
3390 handle2.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
3391 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3392 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3393 pool_.get(), NetLogWithSource()));
3394 // No idle sockets, and one connecting job.
3395 EXPECT_EQ(0, pool_->IdleSocketCount());
3396 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3397
3398 // Return the first handle to the pool. This will initiate the delayed
3399 // binding.
3400 handle1.Reset();
3401
3402 base::RunLoop().RunUntilIdle();
3403
3404 // Still no idle sockets, still one pending connect job.
3405 EXPECT_EQ(0, pool_->IdleSocketCount());
3406 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3407
3408 // The second socket connected, even though it was a Waiting Job.
3409 EXPECT_THAT(callback.WaitForResult(), IsOk());
3410
3411 // And we can see there is still one job waiting.
3412 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3413
3414 // Finally, signal the waiting Connect.
3415 client_socket_factory_.SignalJobs();
3416 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3417
3418 base::RunLoop().RunUntilIdle();
3419 }
3420
3421 // Cover the case where on an available socket slot, we have one pending
3422 // request that completes synchronously, thereby making the Group empty.
TEST_F(ClientSocketPoolBaseTest,SynchronouslyProcessOnePendingRequest)3423 TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
3424 const int kUnlimitedSockets = 100;
3425 const int kOneSocketPerGroup = 1;
3426 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
3427
3428 // Make the first request asynchronous fail.
3429 // This will free up a socket slot later.
3430 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
3431
3432 ClientSocketHandle handle1;
3433 TestCompletionCallback callback1;
3434 EXPECT_EQ(
3435 ERR_IO_PENDING,
3436 handle1.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
3437 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3438 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3439 pool_.get(), NetLogWithSource()));
3440 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3441
3442 // Make the second request synchronously fail. This should make the Group
3443 // empty.
3444 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3445 ClientSocketHandle handle2;
3446 TestCompletionCallback callback2;
3447 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
3448 // when created.
3449 EXPECT_EQ(
3450 ERR_IO_PENDING,
3451 handle2.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
3452 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3453 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3454 pool_.get(), NetLogWithSource()));
3455
3456 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3457
3458 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
3459 EXPECT_THAT(callback2.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
3460 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
3461 }
3462
TEST_F(ClientSocketPoolBaseTest,PreferUsedSocketToUnusedSocket)3463 TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
3464 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3465
3466 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3467
3468 ClientSocketHandle handle1;
3469 TestCompletionCallback callback1;
3470 EXPECT_EQ(
3471 ERR_IO_PENDING,
3472 handle1.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
3473 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3474 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3475 pool_.get(), NetLogWithSource()));
3476
3477 ClientSocketHandle handle2;
3478 TestCompletionCallback callback2;
3479 EXPECT_EQ(
3480 ERR_IO_PENDING,
3481 handle2.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
3482 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3483 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3484 pool_.get(), NetLogWithSource()));
3485 ClientSocketHandle handle3;
3486 TestCompletionCallback callback3;
3487 EXPECT_EQ(
3488 ERR_IO_PENDING,
3489 handle3.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
3490 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3491 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
3492 pool_.get(), NetLogWithSource()));
3493
3494 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3495 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3496 EXPECT_THAT(callback3.WaitForResult(), IsOk());
3497
3498 // Use the socket.
3499 EXPECT_EQ(1, handle1.socket()->Write(nullptr, 1, CompletionOnceCallback(),
3500 TRAFFIC_ANNOTATION_FOR_TESTS));
3501 EXPECT_EQ(1, handle3.socket()->Write(nullptr, 1, CompletionOnceCallback(),
3502 TRAFFIC_ANNOTATION_FOR_TESTS));
3503
3504 handle1.Reset();
3505 handle2.Reset();
3506 handle3.Reset();
3507
3508 EXPECT_EQ(OK, handle1.Init(
3509 TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
3510 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3511 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3512 pool_.get(), NetLogWithSource()));
3513 EXPECT_EQ(OK, handle2.Init(
3514 TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
3515 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3516 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3517 pool_.get(), NetLogWithSource()));
3518 EXPECT_EQ(OK, handle3.Init(
3519 TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
3520 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3521 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
3522 pool_.get(), NetLogWithSource()));
3523
3524 EXPECT_TRUE(handle1.socket()->WasEverUsed());
3525 EXPECT_TRUE(handle2.socket()->WasEverUsed());
3526 EXPECT_FALSE(handle3.socket()->WasEverUsed());
3527 }
3528
TEST_F(ClientSocketPoolBaseTest,RequestSockets)3529 TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
3530 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3531 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3532
3533 TestCompletionCallback preconnect_callback;
3534 EXPECT_EQ(ERR_IO_PENDING,
3535 pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt, 2,
3536 preconnect_callback.callback(),
3537 NetLogWithSource()));
3538
3539 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3540 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3541 EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3542 TestGroupId("a")));
3543 EXPECT_EQ(2u,
3544 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3545 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3546
3547 ClientSocketHandle handle1;
3548 TestCompletionCallback callback1;
3549 EXPECT_EQ(
3550 ERR_IO_PENDING,
3551 handle1.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
3552 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3553 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3554 pool_.get(), NetLogWithSource()));
3555
3556 ClientSocketHandle handle2;
3557 TestCompletionCallback callback2;
3558 EXPECT_EQ(
3559 ERR_IO_PENDING,
3560 handle2.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
3561 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3562 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3563 pool_.get(), NetLogWithSource()));
3564
3565 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3566 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3567 TestGroupId("a")));
3568 EXPECT_EQ(0u,
3569 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3570 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3571
3572 EXPECT_THAT(preconnect_callback.WaitForResult(), IsOk());
3573 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3574 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3575 handle1.Reset();
3576 handle2.Reset();
3577
3578 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3579 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3580 TestGroupId("a")));
3581 EXPECT_EQ(0u,
3582 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3583 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3584 }
3585
TEST_F(ClientSocketPoolBaseTest,RequestSocketsWhenAlreadyHaveAConnectJob)3586 TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
3587 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3588 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3589
3590 ClientSocketHandle handle1;
3591 TestCompletionCallback callback1;
3592 EXPECT_EQ(
3593 ERR_IO_PENDING,
3594 handle1.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
3595 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3596 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3597 pool_.get(), NetLogWithSource()));
3598
3599 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3600 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3601 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3602 TestGroupId("a")));
3603 EXPECT_EQ(0u,
3604 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3605 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3606
3607 TestCompletionCallback preconnect_callback;
3608 EXPECT_EQ(ERR_IO_PENDING,
3609 pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt, 2,
3610 preconnect_callback.callback(),
3611 NetLogWithSource()));
3612
3613 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3614 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3615 TestGroupId("a")));
3616 EXPECT_EQ(1u,
3617 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3618 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3619
3620 ClientSocketHandle handle2;
3621 TestCompletionCallback callback2;
3622 EXPECT_EQ(
3623 ERR_IO_PENDING,
3624 handle2.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
3625 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3626 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3627 pool_.get(), NetLogWithSource()));
3628
3629 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3630 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3631 TestGroupId("a")));
3632 EXPECT_EQ(0u,
3633 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3634 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3635
3636 EXPECT_THAT(preconnect_callback.WaitForResult(), IsOk());
3637 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3638 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3639 handle1.Reset();
3640 handle2.Reset();
3641
3642 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3643 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3644 TestGroupId("a")));
3645 EXPECT_EQ(0u,
3646 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3647 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3648 }
3649
TEST_F(ClientSocketPoolBaseTest,RequestSocketsWhenAlreadyHaveMultipleConnectJob)3650 TEST_F(ClientSocketPoolBaseTest,
3651 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
3652 CreatePool(4, 4);
3653 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3654
3655 ClientSocketHandle handle1;
3656 TestCompletionCallback callback1;
3657 EXPECT_EQ(
3658 ERR_IO_PENDING,
3659 handle1.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
3660 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3661 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3662 pool_.get(), NetLogWithSource()));
3663
3664 ClientSocketHandle handle2;
3665 TestCompletionCallback callback2;
3666 EXPECT_EQ(
3667 ERR_IO_PENDING,
3668 handle2.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
3669 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3670 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3671 pool_.get(), NetLogWithSource()));
3672
3673 ClientSocketHandle handle3;
3674 TestCompletionCallback callback3;
3675 EXPECT_EQ(
3676 ERR_IO_PENDING,
3677 handle3.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
3678 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3679 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
3680 pool_.get(), NetLogWithSource()));
3681
3682 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3683 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3684 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3685 TestGroupId("a")));
3686 EXPECT_EQ(0u,
3687 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3688 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3689
3690 EXPECT_EQ(
3691 OK, pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt, 2,
3692 CompletionOnceCallback(), NetLogWithSource()));
3693
3694 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3695 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3696 TestGroupId("a")));
3697 EXPECT_EQ(0u,
3698 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3699 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3700
3701 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3702 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3703 EXPECT_THAT(callback3.WaitForResult(), IsOk());
3704 handle1.Reset();
3705 handle2.Reset();
3706 handle3.Reset();
3707
3708 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3709 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3710 TestGroupId("a")));
3711 EXPECT_EQ(0u,
3712 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3713 EXPECT_EQ(3u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3714 }
3715
TEST_F(ClientSocketPoolBaseTest,RequestSocketsAtMaxSocketLimit)3716 TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
3717 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3718 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3719
3720 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
3721
3722 TestCompletionCallback preconnect_callback;
3723 EXPECT_EQ(ERR_IO_PENDING,
3724 pool_->RequestSockets(
3725 TestGroupId("a"), params_, absl::nullopt, kDefaultMaxSockets,
3726 preconnect_callback.callback(), NetLogWithSource()));
3727
3728 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3729 EXPECT_EQ(kDefaultMaxSockets,
3730 static_cast<int>(
3731 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
3732 EXPECT_EQ(
3733 kDefaultMaxSockets,
3734 static_cast<int>(pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3735 TestGroupId("a"))));
3736 EXPECT_EQ(kDefaultMaxSockets,
3737 static_cast<int>(pool_->NumUnassignedConnectJobsInGroupForTesting(
3738 TestGroupId("a"))));
3739
3740 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("b")));
3741
3742 EXPECT_EQ(OK,
3743 pool_->RequestSockets(TestGroupId("b"), params_, absl::nullopt,
3744 kDefaultMaxSockets, CompletionOnceCallback(),
3745 NetLogWithSource()));
3746
3747 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("b")));
3748
3749 EXPECT_THAT(preconnect_callback.WaitForResult(), IsOk());
3750 }
3751
TEST_F(ClientSocketPoolBaseTest,RequestSocketsHitMaxSocketLimit)3752 TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
3753 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3754 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3755
3756 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
3757
3758 TestCompletionCallback preconnect_callback1;
3759 EXPECT_EQ(ERR_IO_PENDING,
3760 pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt,
3761 kDefaultMaxSockets - 1,
3762 preconnect_callback1.callback(),
3763 NetLogWithSource()));
3764
3765 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3766 EXPECT_EQ(kDefaultMaxSockets - 1,
3767 static_cast<int>(
3768 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
3769 EXPECT_EQ(
3770 kDefaultMaxSockets - 1,
3771 static_cast<int>(pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3772 TestGroupId("a"))));
3773 EXPECT_EQ(kDefaultMaxSockets - 1,
3774 static_cast<int>(pool_->NumUnassignedConnectJobsInGroupForTesting(
3775 TestGroupId("a"))));
3776 EXPECT_FALSE(pool_->IsStalled());
3777
3778 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("b")));
3779
3780 TestCompletionCallback preconnect_callback2;
3781 EXPECT_EQ(ERR_IO_PENDING,
3782 pool_->RequestSockets(
3783 TestGroupId("b"), params_, absl::nullopt, kDefaultMaxSockets,
3784 preconnect_callback2.callback(), NetLogWithSource()));
3785
3786 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("b")));
3787 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
3788 EXPECT_FALSE(pool_->IsStalled());
3789
3790 EXPECT_THAT(preconnect_callback1.WaitForResult(), IsOk());
3791 EXPECT_THAT(preconnect_callback2.WaitForResult(), IsOk());
3792 }
3793
TEST_F(ClientSocketPoolBaseTest,RequestSocketsCountIdleSockets)3794 TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
3795 CreatePool(4, 4);
3796 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3797
3798 ClientSocketHandle handle1;
3799 TestCompletionCallback callback1;
3800 EXPECT_EQ(
3801 ERR_IO_PENDING,
3802 handle1.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
3803 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3804 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3805 pool_.get(), NetLogWithSource()));
3806 ASSERT_THAT(callback1.WaitForResult(), IsOk());
3807 handle1.Reset();
3808
3809 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3810 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3811 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3812 TestGroupId("a")));
3813 EXPECT_EQ(0u,
3814 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3815 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3816
3817 TestCompletionCallback preconnect_callback;
3818 EXPECT_EQ(ERR_IO_PENDING,
3819 pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt, 2,
3820 preconnect_callback.callback(),
3821 NetLogWithSource()));
3822
3823 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3824 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3825 TestGroupId("a")));
3826 EXPECT_EQ(1u,
3827 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3828 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3829
3830 EXPECT_THAT(preconnect_callback.WaitForResult(), IsOk());
3831 }
3832
TEST_F(ClientSocketPoolBaseTest,RequestSocketsCountActiveSockets)3833 TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
3834 CreatePool(4, 4);
3835 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3836
3837 ClientSocketHandle handle1;
3838 TestCompletionCallback callback1;
3839 EXPECT_EQ(
3840 ERR_IO_PENDING,
3841 handle1.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
3842 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3843 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3844 pool_.get(), NetLogWithSource()));
3845 ASSERT_THAT(callback1.WaitForResult(), IsOk());
3846
3847 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3848 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3849 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3850 TestGroupId("a")));
3851 EXPECT_EQ(0u,
3852 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3853 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3854 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
3855
3856 TestCompletionCallback preconnect_callback;
3857 EXPECT_EQ(ERR_IO_PENDING,
3858 pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt, 2,
3859 preconnect_callback.callback(),
3860 NetLogWithSource()));
3861
3862 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3863 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3864 TestGroupId("a")));
3865 EXPECT_EQ(1u,
3866 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3867 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3868 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
3869
3870 EXPECT_THAT(preconnect_callback.WaitForResult(), IsOk());
3871 }
3872
TEST_F(ClientSocketPoolBaseTest,RequestSocketsSynchronous)3873 TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
3874 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3875 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3876
3877 EXPECT_EQ(
3878 OK, pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt,
3879 kDefaultMaxSocketsPerGroup,
3880 CompletionOnceCallback(), NetLogWithSource()));
3881
3882 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3883 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3884 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3885 TestGroupId("a")));
3886 EXPECT_EQ(0u,
3887 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3888 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
3889 static_cast<int>(pool_->IdleSocketCountInGroup(TestGroupId("a"))));
3890
3891 EXPECT_EQ(
3892 OK, pool_->RequestSockets(TestGroupId("b"), params_, absl::nullopt,
3893 kDefaultMaxSocketsPerGroup,
3894 CompletionOnceCallback(), NetLogWithSource()));
3895
3896 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
3897 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3898 TestGroupId("b")));
3899 EXPECT_EQ(0u,
3900 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("b")));
3901 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
3902 static_cast<int>(pool_->IdleSocketCountInGroup(TestGroupId("b"))));
3903 }
3904
TEST_F(ClientSocketPoolBaseTest,RequestSocketsSynchronousError)3905 TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
3906 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3907 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3908
3909 EXPECT_EQ(
3910 OK, pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt,
3911 kDefaultMaxSocketsPerGroup,
3912 CompletionOnceCallback(), NetLogWithSource()));
3913
3914 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
3915
3916 connect_job_factory_->set_job_type(
3917 TestConnectJob::kMockAdditionalErrorStateJob);
3918
3919 EXPECT_EQ(
3920 OK, pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt,
3921 kDefaultMaxSocketsPerGroup,
3922 CompletionOnceCallback(), NetLogWithSource()));
3923
3924 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
3925 }
3926
TEST_F(ClientSocketPoolBaseTest,RequestSocketsMultipleTimesDoesNothing)3927 TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
3928 CreatePool(4, 4);
3929 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3930
3931 TestCompletionCallback preconnect_callback;
3932 EXPECT_EQ(ERR_IO_PENDING,
3933 pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt, 2,
3934 preconnect_callback.callback(),
3935 NetLogWithSource()));
3936
3937 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3938 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3939 EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3940 TestGroupId("a")));
3941 EXPECT_EQ(2u,
3942 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3943 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
3944 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3945
3946 EXPECT_EQ(
3947 OK, pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt, 2,
3948 CompletionOnceCallback(), NetLogWithSource()));
3949 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3950 EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3951 TestGroupId("a")));
3952 EXPECT_EQ(2u,
3953 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3954 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
3955 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3956
3957 ClientSocketHandle handle1;
3958 TestCompletionCallback callback1;
3959 EXPECT_EQ(
3960 ERR_IO_PENDING,
3961 handle1.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
3962 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3963 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3964 pool_.get(), NetLogWithSource()));
3965
3966 client_socket_factory_.SignalJob(0);
3967 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3968
3969 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3970 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3971 TestGroupId("a")));
3972 EXPECT_EQ(1u,
3973 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3974 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
3975 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3976
3977 ClientSocketHandle handle2;
3978 TestCompletionCallback callback2;
3979 EXPECT_EQ(
3980 ERR_IO_PENDING,
3981 handle2.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
3982 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3983 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3984 pool_.get(), NetLogWithSource()));
3985 client_socket_factory_.SignalJob(0);
3986 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3987 EXPECT_THAT(preconnect_callback.WaitForResult(), IsOk());
3988
3989 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3990 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3991 TestGroupId("a")));
3992 EXPECT_EQ(0u,
3993 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3994 EXPECT_EQ(2, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
3995 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3996
3997 handle1.Reset();
3998 handle2.Reset();
3999
4000 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4001 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4002 TestGroupId("a")));
4003 EXPECT_EQ(0u,
4004 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4005 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
4006 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4007
4008 EXPECT_EQ(
4009 OK, pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt, 2,
4010 CompletionOnceCallback(), NetLogWithSource()));
4011 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4012 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4013 TestGroupId("a")));
4014 EXPECT_EQ(0u,
4015 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4016 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
4017 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4018 }
4019
TEST_F(ClientSocketPoolBaseTest,RequestSocketsDifferentNumSockets)4020 TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
4021 CreatePool(4, 4);
4022 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4023
4024 TestCompletionCallback preconnect_callback1;
4025 EXPECT_EQ(ERR_IO_PENDING,
4026 pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt, 1,
4027 preconnect_callback1.callback(),
4028 NetLogWithSource()));
4029
4030 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
4031 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4032 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4033 TestGroupId("a")));
4034 EXPECT_EQ(1u,
4035 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4036 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4037
4038 TestCompletionCallback preconnect_callback2;
4039 EXPECT_EQ(ERR_IO_PENDING,
4040 pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt, 2,
4041 preconnect_callback2.callback(),
4042 NetLogWithSource()));
4043 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4044 EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4045 TestGroupId("a")));
4046 EXPECT_EQ(2u,
4047 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4048 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4049
4050 TestCompletionCallback preconnect_callback3;
4051 EXPECT_EQ(ERR_IO_PENDING,
4052 pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt, 3,
4053 preconnect_callback3.callback(),
4054 NetLogWithSource()));
4055 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4056 EXPECT_EQ(3u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4057 TestGroupId("a")));
4058 EXPECT_EQ(3u,
4059 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4060 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4061
4062 EXPECT_EQ(
4063 OK, pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt, 1,
4064 CompletionOnceCallback(), NetLogWithSource()));
4065 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4066 EXPECT_EQ(3u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4067 TestGroupId("a")));
4068 EXPECT_EQ(3u,
4069 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4070 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4071 }
4072
TEST_F(ClientSocketPoolBaseTest,PreconnectJobsTakenByNormalRequests)4073 TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
4074 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4075 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4076
4077 TestCompletionCallback preconnect_callback;
4078 EXPECT_EQ(ERR_IO_PENDING,
4079 pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt, 1,
4080 preconnect_callback.callback(),
4081 NetLogWithSource()));
4082
4083 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
4084 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4085 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4086 TestGroupId("a")));
4087 EXPECT_EQ(1u,
4088 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4089 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4090
4091 ClientSocketHandle handle1;
4092 TestCompletionCallback callback1;
4093 EXPECT_EQ(
4094 ERR_IO_PENDING,
4095 handle1.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
4096 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4097 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4098 pool_.get(), NetLogWithSource()));
4099
4100 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4101 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4102 TestGroupId("a")));
4103 EXPECT_EQ(0u,
4104 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4105 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4106
4107 client_socket_factory_.SignalJobs();
4108 EXPECT_THAT(callback1.WaitForResult(), IsOk());
4109 EXPECT_THAT(preconnect_callback.WaitForResult(), IsOk());
4110
4111 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4112 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4113 TestGroupId("a")));
4114 EXPECT_EQ(0u,
4115 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4116 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4117 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
4118
4119 // Make sure if a preconnected socket is not fully connected when a request
4120 // starts, it has a connect start time.
4121 TestLoadTimingInfoConnectedNotReused(handle1);
4122 handle1.Reset();
4123
4124 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4125 }
4126
4127 // Checks that fully connected preconnect jobs have no connect times, and are
4128 // marked as reused.
TEST_F(ClientSocketPoolBaseTest,ConnectedPreconnectJobsHaveNoConnectTimes)4129 TEST_F(ClientSocketPoolBaseTest, ConnectedPreconnectJobsHaveNoConnectTimes) {
4130 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4131 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4132
4133 EXPECT_EQ(
4134 OK, pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt, 1,
4135 CompletionOnceCallback(), NetLogWithSource()));
4136
4137 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
4138 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4139 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4140 TestGroupId("a")));
4141 EXPECT_EQ(0u,
4142 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4143 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4144
4145 ClientSocketHandle handle;
4146 TestCompletionCallback callback;
4147 EXPECT_EQ(OK, handle.Init(
4148 TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
4149 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4150 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
4151 pool_.get(), NetLogWithSource()));
4152
4153 // Make sure the idle socket was used.
4154 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4155
4156 TestLoadTimingInfoConnectedReused(handle);
4157 handle.Reset();
4158 TestLoadTimingInfoNotConnected(handle);
4159 }
4160
4161 // http://crbug.com/64940 regression test.
TEST_F(ClientSocketPoolBaseTest,PreconnectClosesIdleSocketRemovesGroup)4162 TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
4163 const int kMaxTotalSockets = 3;
4164 const int kMaxSocketsPerGroup = 2;
4165 CreatePool(kMaxTotalSockets, kMaxSocketsPerGroup);
4166 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4167
4168 // Note that group id ordering matters here. "a" comes before "b", so
4169 // CloseOneIdleSocket() will try to close "a"'s idle socket.
4170
4171 // Set up one idle socket in "a".
4172 ClientSocketHandle handle1;
4173 TestCompletionCallback callback1;
4174 EXPECT_EQ(
4175 ERR_IO_PENDING,
4176 handle1.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
4177 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4178 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4179 pool_.get(), NetLogWithSource()));
4180 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
4181 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4182 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4183 TestGroupId("a")));
4184 EXPECT_EQ(0u,
4185 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4186 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4187
4188 client_socket_factory_.SignalJobs();
4189 ASSERT_THAT(callback1.WaitForResult(), IsOk());
4190 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4191 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4192 TestGroupId("a")));
4193 EXPECT_EQ(0u,
4194 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4195 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
4196
4197 handle1.Reset();
4198 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4199
4200 // Set up two active sockets in "b".
4201 ClientSocketHandle handle2;
4202 TestCompletionCallback callback2;
4203 EXPECT_EQ(
4204 ERR_IO_PENDING,
4205 handle1.Init(TestGroupId("b"), params_, absl::nullopt, DEFAULT_PRIORITY,
4206 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4207 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4208 pool_.get(), NetLogWithSource()));
4209 EXPECT_EQ(
4210 ERR_IO_PENDING,
4211 handle2.Init(TestGroupId("b"), params_, absl::nullopt, DEFAULT_PRIORITY,
4212 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4213 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4214 pool_.get(), NetLogWithSource()));
4215
4216 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("b")));
4217 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
4218 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4219 TestGroupId("b")));
4220 EXPECT_EQ(0u,
4221 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("b")));
4222 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
4223
4224 client_socket_factory_.SignalJobs();
4225 ASSERT_THAT(callback1.WaitForResult(), IsOk());
4226 ASSERT_THAT(callback2.WaitForResult(), IsOk());
4227 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
4228 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4229 TestGroupId("b")));
4230 EXPECT_EQ(0u,
4231 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("b")));
4232 EXPECT_EQ(2, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("b")));
4233
4234 // Now we have 1 idle socket in "a" and 2 active sockets in "b". This means
4235 // we've maxed out on sockets, since we set |kMaxTotalSockets| to 3.
4236 // Requesting 2 preconnected sockets for "a" should fail to allocate any more
4237 // sockets for "a", and "b" should still have 2 active sockets.
4238
4239 EXPECT_EQ(
4240 OK, pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt, 2,
4241 CompletionOnceCallback(), NetLogWithSource()));
4242 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4243 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4244 TestGroupId("a")));
4245 EXPECT_EQ(0u,
4246 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4247 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4248 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
4249 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
4250 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4251 TestGroupId("b")));
4252 EXPECT_EQ(0u,
4253 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("b")));
4254 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
4255 EXPECT_EQ(2, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("b")));
4256
4257 // Now release the 2 active sockets for "b". This will give us 1 idle socket
4258 // in "a" and 2 idle sockets in "b". Requesting 2 preconnected sockets for
4259 // "a" should result in closing 1 for "b".
4260 handle1.Reset();
4261 handle2.Reset();
4262 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
4263 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("b")));
4264
4265 TestCompletionCallback preconnect_callback;
4266 EXPECT_EQ(ERR_IO_PENDING,
4267 pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt, 2,
4268 preconnect_callback.callback(),
4269 NetLogWithSource()));
4270 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4271 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4272 TestGroupId("a")));
4273 EXPECT_EQ(1u,
4274 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4275 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4276 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
4277 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
4278 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4279 TestGroupId("b")));
4280 EXPECT_EQ(0u,
4281 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("b")));
4282 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
4283 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("b")));
4284 }
4285
TEST_F(ClientSocketPoolBaseTest,PreconnectWithoutBackupJob)4286 TEST_F(ClientSocketPoolBaseTest, PreconnectWithoutBackupJob) {
4287 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
4288 true /* enable_backup_connect_jobs */);
4289
4290 // Make the ConnectJob hang until it times out, shorten the timeout.
4291 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4292 connect_job_factory_->set_timeout_duration(base::Milliseconds(500));
4293 TestCompletionCallback preconnect_callback;
4294 EXPECT_EQ(ERR_IO_PENDING,
4295 pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt, 1,
4296 preconnect_callback.callback(),
4297 NetLogWithSource()));
4298 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4299 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4300 TestGroupId("a")));
4301 EXPECT_EQ(1u,
4302 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4303 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4304
4305 // Verify the backup timer doesn't create a backup job, by making
4306 // the backup job a pending job instead of a waiting job, so it
4307 // *would* complete if it were created.
4308 base::RunLoop loop;
4309 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4310 base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
4311 FROM_HERE, loop.QuitClosure(), base::Seconds(1));
4312 loop.Run();
4313 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
4314 }
4315
TEST_F(ClientSocketPoolBaseTest,PreconnectWithBackupJob)4316 TEST_F(ClientSocketPoolBaseTest, PreconnectWithBackupJob) {
4317 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
4318 true /* enable_backup_connect_jobs */);
4319
4320 // Make the ConnectJob hang forever.
4321 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4322 TestCompletionCallback preconnect_callback;
4323 EXPECT_EQ(ERR_IO_PENDING,
4324 pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt, 1,
4325 preconnect_callback.callback(),
4326 NetLogWithSource()));
4327 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4328 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4329 TestGroupId("a")));
4330 EXPECT_EQ(1u,
4331 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4332 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4333 base::RunLoop().RunUntilIdle();
4334
4335 // Make the backup job be a pending job, so it completes normally.
4336 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4337 ClientSocketHandle handle;
4338 TestCompletionCallback callback;
4339 EXPECT_EQ(
4340 ERR_IO_PENDING,
4341 handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
4342 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4343 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
4344 pool_.get(), NetLogWithSource()));
4345 // Timer has started, but the backup connect job shouldn't be created yet.
4346 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4347 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4348 TestGroupId("a")));
4349 EXPECT_EQ(0u,
4350 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4351 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4352 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
4353 ASSERT_THAT(callback.WaitForResult(), IsOk());
4354
4355 // The hung connect job should still be there, but everything else should be
4356 // complete.
4357 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4358 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4359 TestGroupId("a")));
4360 EXPECT_EQ(1u,
4361 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4362 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4363 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
4364 }
4365
4366 // Tests that a preconnect that starts out with unread data can still be used.
4367 // http://crbug.com/334467
TEST_F(ClientSocketPoolBaseTest,PreconnectWithUnreadData)4368 TEST_F(ClientSocketPoolBaseTest, PreconnectWithUnreadData) {
4369 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4370 connect_job_factory_->set_job_type(TestConnectJob::kMockUnreadDataJob);
4371
4372 EXPECT_EQ(
4373 OK, pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt, 1,
4374 CompletionOnceCallback(), NetLogWithSource()));
4375
4376 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
4377 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4378 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4379 TestGroupId("a")));
4380 EXPECT_EQ(0u,
4381 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4382 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4383
4384 // Fail future jobs to be sure that handle receives the preconnected socket
4385 // rather than closing it and making a new one.
4386 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
4387 ClientSocketHandle handle;
4388 TestCompletionCallback callback;
4389 EXPECT_EQ(OK, handle.Init(
4390 TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
4391 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4392 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
4393 pool_.get(), NetLogWithSource()));
4394
4395 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
4396 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4397 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4398 TestGroupId("a")));
4399 EXPECT_EQ(0u,
4400 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4401 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4402 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
4403
4404 // Drain the pending read.
4405 EXPECT_EQ(1, handle.socket()->Read(nullptr, 1, CompletionOnceCallback()));
4406
4407 TestLoadTimingInfoConnectedReused(handle);
4408 handle.Reset();
4409
4410 // The socket should be usable now that it's idle again.
4411 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4412 }
4413
TEST_F(ClientSocketPoolBaseTest,RequestGetsAssignedJob)4414 TEST_F(ClientSocketPoolBaseTest, RequestGetsAssignedJob) {
4415 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4416 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4417
4418 ClientSocketHandle handle1;
4419 TestCompletionCallback callback1;
4420 EXPECT_EQ(
4421 ERR_IO_PENDING,
4422 handle1.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
4423 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4424 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4425 pool_.get(), NetLogWithSource()));
4426
4427 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4428 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4429 TestGroupId("a")));
4430 EXPECT_EQ(0u,
4431 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4432 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4433
4434 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4435 &handle1));
4436 }
4437
TEST_F(ClientSocketPoolBaseTest,MultipleRequestsGetAssignedJobs)4438 TEST_F(ClientSocketPoolBaseTest, MultipleRequestsGetAssignedJobs) {
4439 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4440 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4441
4442 ClientSocketHandle handle1;
4443 TestCompletionCallback callback1;
4444 EXPECT_EQ(
4445 ERR_IO_PENDING,
4446 handle1.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
4447 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4448 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4449 pool_.get(), NetLogWithSource()));
4450
4451 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4452 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4453 TestGroupId("a")));
4454 EXPECT_EQ(0u,
4455 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4456 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4457
4458 ClientSocketHandle handle2;
4459 TestCompletionCallback callback2;
4460 EXPECT_EQ(
4461 ERR_IO_PENDING,
4462 handle2.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
4463 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4464 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4465 pool_.get(), NetLogWithSource()));
4466
4467 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4468 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4469 TestGroupId("a")));
4470 EXPECT_EQ(0u,
4471 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4472 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4473
4474 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4475 &handle1));
4476 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4477 &handle2));
4478
4479 // One job completes. The other request should still have its job.
4480 client_socket_factory_.SignalJob(0);
4481 EXPECT_THAT(callback1.WaitForResult(), IsOk());
4482
4483 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4484 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4485 TestGroupId("a")));
4486 EXPECT_EQ(0u,
4487 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4488 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
4489 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4490
4491 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4492 &handle2));
4493 }
4494
TEST_F(ClientSocketPoolBaseTest,PreconnectJobGetsAssignedToRequest)4495 TEST_F(ClientSocketPoolBaseTest, PreconnectJobGetsAssignedToRequest) {
4496 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4497 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4498
4499 TestCompletionCallback preconnect_callback;
4500 EXPECT_EQ(ERR_IO_PENDING,
4501 pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt, 1,
4502 preconnect_callback.callback(),
4503 NetLogWithSource()));
4504
4505 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
4506 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4507 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4508 TestGroupId("a")));
4509 EXPECT_EQ(1u,
4510 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4511 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4512
4513 ClientSocketHandle handle1;
4514 TestCompletionCallback callback1;
4515 EXPECT_EQ(
4516 ERR_IO_PENDING,
4517 handle1.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
4518 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4519 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4520 pool_.get(), NetLogWithSource()));
4521
4522 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4523 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4524 TestGroupId("a")));
4525 EXPECT_EQ(0u,
4526 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4527 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4528
4529 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4530 &handle1));
4531 }
4532
TEST_F(ClientSocketPoolBaseTest,HigherPriorityRequestStealsJob)4533 TEST_F(ClientSocketPoolBaseTest, HigherPriorityRequestStealsJob) {
4534 CreatePool(kDefaultMaxSockets, 1);
4535 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4536
4537 ClientSocketHandle handle1;
4538 TestCompletionCallback callback1;
4539 EXPECT_EQ(
4540 ERR_IO_PENDING,
4541 handle1.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
4542 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4543 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4544 pool_.get(), NetLogWithSource()));
4545
4546 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4547 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4548 TestGroupId("a")));
4549 EXPECT_EQ(0u,
4550 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4551 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4552
4553 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4554 &handle1));
4555
4556 // Insert a higher priority request
4557 ClientSocketHandle handle2;
4558 TestCompletionCallback callback2;
4559 EXPECT_EQ(
4560 ERR_IO_PENDING,
4561 handle2.Init(TestGroupId("a"), params_, absl::nullopt, HIGHEST,
4562 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4563 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4564 pool_.get(), NetLogWithSource()));
4565
4566 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4567 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4568 TestGroupId("a")));
4569 EXPECT_EQ(0u,
4570 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4571 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4572
4573 // The highest priority request should steal the job from the default priority
4574 // request.
4575 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4576 &handle2));
4577 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4578 &handle1));
4579 }
4580
TEST_F(ClientSocketPoolBaseTest,RequestStealsJobFromLowestRequestWithJob)4581 TEST_F(ClientSocketPoolBaseTest, RequestStealsJobFromLowestRequestWithJob) {
4582 CreatePool(3, 3);
4583 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4584
4585 ClientSocketHandle handle_lowest;
4586 TestCompletionCallback callback_lowest;
4587 EXPECT_EQ(
4588 ERR_IO_PENDING,
4589 handle_lowest.Init(TestGroupId("a"), params_, absl::nullopt, LOWEST,
4590 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4591 callback_lowest.callback(),
4592 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4593 NetLogWithSource()));
4594
4595 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4596 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4597 TestGroupId("a")));
4598 EXPECT_EQ(0u,
4599 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4600 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4601
4602 ClientSocketHandle handle_highest;
4603 TestCompletionCallback callback_highest;
4604 EXPECT_EQ(
4605 ERR_IO_PENDING,
4606 handle_highest.Init(TestGroupId("a"), params_, absl::nullopt, HIGHEST,
4607 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4608 callback_highest.callback(),
4609 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4610 NetLogWithSource()));
4611
4612 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4613 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4614 TestGroupId("a")));
4615 EXPECT_EQ(0u,
4616 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4617 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4618
4619 ClientSocketHandle handle_low;
4620 TestCompletionCallback callback_low;
4621 EXPECT_EQ(ERR_IO_PENDING,
4622 handle_low.Init(
4623 TestGroupId("a"), params_, absl::nullopt, LOW, SocketTag(),
4624 ClientSocketPool::RespectLimits::ENABLED,
4625 callback_low.callback(), ClientSocketPool::ProxyAuthCallback(),
4626 pool_.get(), NetLogWithSource()));
4627
4628 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4629 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4630 TestGroupId("a")));
4631 EXPECT_EQ(0u,
4632 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4633 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4634
4635 ClientSocketHandle handle_lowest2;
4636 TestCompletionCallback callback_lowest2;
4637 EXPECT_EQ(
4638 ERR_IO_PENDING,
4639 handle_lowest2.Init(TestGroupId("a"), params_, absl::nullopt, LOWEST,
4640 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4641 callback_lowest2.callback(),
4642 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4643 NetLogWithSource()));
4644
4645 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4646 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4647 TestGroupId("a")));
4648 EXPECT_EQ(0u,
4649 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4650 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4651
4652 // The top three requests in the queue should have jobs.
4653 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4654 &handle_highest));
4655 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4656 &handle_low));
4657 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4658 &handle_lowest));
4659 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(
4660 TestGroupId("a"), &handle_lowest2));
4661
4662 // Add another request with medium priority. It should steal the job from the
4663 // lowest priority request with a job.
4664 ClientSocketHandle handle_medium;
4665 TestCompletionCallback callback_medium;
4666 EXPECT_EQ(
4667 ERR_IO_PENDING,
4668 handle_medium.Init(TestGroupId("a"), params_, absl::nullopt, MEDIUM,
4669 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4670 callback_medium.callback(),
4671 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4672 NetLogWithSource()));
4673
4674 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4675 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4676 TestGroupId("a")));
4677 EXPECT_EQ(0u,
4678 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4679 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4680 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4681 &handle_highest));
4682 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4683 &handle_medium));
4684 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4685 &handle_low));
4686 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4687 &handle_lowest));
4688 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(
4689 TestGroupId("a"), &handle_lowest2));
4690 }
4691
TEST_F(ClientSocketPoolBaseTest,ReprioritizeRequestStealsJob)4692 TEST_F(ClientSocketPoolBaseTest, ReprioritizeRequestStealsJob) {
4693 CreatePool(kDefaultMaxSockets, 1);
4694 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4695
4696 ClientSocketHandle handle1;
4697 TestCompletionCallback callback1;
4698 EXPECT_EQ(
4699 ERR_IO_PENDING,
4700 handle1.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
4701 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4702 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4703 pool_.get(), NetLogWithSource()));
4704
4705 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4706 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4707 TestGroupId("a")));
4708 EXPECT_EQ(0u,
4709 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4710 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4711
4712 ClientSocketHandle handle2;
4713 TestCompletionCallback callback2;
4714 EXPECT_EQ(
4715 ERR_IO_PENDING,
4716 handle2.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
4717 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4718 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4719 pool_.get(), NetLogWithSource()));
4720
4721 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4722 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4723 TestGroupId("a")));
4724 EXPECT_EQ(0u,
4725 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4726 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4727
4728 // The second request doesn't get a job because we are at the limit.
4729 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4730 &handle1));
4731 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4732 &handle2));
4733
4734 // Reprioritizing the second request places it above the first, and it steals
4735 // the job from the first request.
4736 pool_->SetPriority(TestGroupId("a"), &handle2, HIGHEST);
4737 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4738 &handle2));
4739 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4740 &handle1));
4741 }
4742
TEST_F(ClientSocketPoolBaseTest,CancelRequestReassignsJob)4743 TEST_F(ClientSocketPoolBaseTest, CancelRequestReassignsJob) {
4744 CreatePool(kDefaultMaxSockets, 1);
4745 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4746
4747 ClientSocketHandle handle1;
4748 TestCompletionCallback callback1;
4749 EXPECT_EQ(
4750 ERR_IO_PENDING,
4751 handle1.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
4752 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4753 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4754 pool_.get(), NetLogWithSource()));
4755
4756 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4757 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4758 TestGroupId("a")));
4759 EXPECT_EQ(0u,
4760 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4761 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4762
4763 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4764 &handle1));
4765
4766 ClientSocketHandle handle2;
4767 TestCompletionCallback callback2;
4768 EXPECT_EQ(
4769 ERR_IO_PENDING,
4770 handle2.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
4771 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4772 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4773 pool_.get(), NetLogWithSource()));
4774
4775 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4776 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4777 TestGroupId("a")));
4778 EXPECT_EQ(0u,
4779 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4780 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4781
4782 // The second request doesn't get a job because we are the limit.
4783 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4784 &handle1));
4785 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4786 &handle2));
4787
4788 // The second request should get a job upon cancelling the first request.
4789 handle1.Reset();
4790 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4791 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4792 TestGroupId("a")));
4793 EXPECT_EQ(0u,
4794 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4795 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4796
4797 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4798 &handle2));
4799 }
4800
TEST_F(ClientSocketPoolBaseTest,JobCompletionReassignsJob)4801 TEST_F(ClientSocketPoolBaseTest, JobCompletionReassignsJob) {
4802 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4803 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4804
4805 ClientSocketHandle handle1;
4806 TestCompletionCallback callback1;
4807 EXPECT_EQ(
4808 ERR_IO_PENDING,
4809 handle1.Init(TestGroupId("a"), params_, absl::nullopt, HIGHEST,
4810 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4811 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4812 pool_.get(), NetLogWithSource()));
4813
4814 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4815 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4816 TestGroupId("a")));
4817 EXPECT_EQ(0u,
4818 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4819 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4820
4821 ClientSocketHandle handle2;
4822 TestCompletionCallback callback2;
4823 EXPECT_EQ(
4824 ERR_IO_PENDING,
4825 handle2.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
4826 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4827 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4828 pool_.get(), NetLogWithSource()));
4829
4830 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4831 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4832 TestGroupId("a")));
4833 EXPECT_EQ(0u,
4834 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4835 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4836
4837 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4838 &handle1));
4839 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4840 &handle2));
4841
4842 // The lower-priority job completes first. The higher-priority request should
4843 // get the socket, and the lower-priority request should get the remaining
4844 // job.
4845 client_socket_factory_.SignalJob(1);
4846 EXPECT_THAT(callback1.WaitForResult(), IsOk());
4847 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4848 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4849 TestGroupId("a")));
4850 EXPECT_EQ(0u,
4851 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4852 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
4853 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4854 EXPECT_TRUE(handle1.socket());
4855 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4856 &handle2));
4857 }
4858
4859 class MockLayeredPool : public HigherLayeredPool {
4860 public:
MockLayeredPool(TransportClientSocketPool * pool,const ClientSocketPool::GroupId & group_id)4861 MockLayeredPool(TransportClientSocketPool* pool,
4862 const ClientSocketPool::GroupId& group_id)
4863 : pool_(pool), group_id_(group_id) {
4864 pool_->AddHigherLayeredPool(this);
4865 }
4866
~MockLayeredPool()4867 ~MockLayeredPool() override { pool_->RemoveHigherLayeredPool(this); }
4868
RequestSocket(TransportClientSocketPool * pool)4869 int RequestSocket(TransportClientSocketPool* pool) {
4870 return handle_.Init(
4871 group_id_, ClientSocketPool::SocketParams::CreateForHttpForTesting(),
4872 absl::nullopt, DEFAULT_PRIORITY, SocketTag(),
4873 ClientSocketPool::RespectLimits::ENABLED, callback_.callback(),
4874 ClientSocketPool::ProxyAuthCallback(), pool, NetLogWithSource());
4875 }
4876
RequestSocketWithoutLimits(TransportClientSocketPool * pool)4877 int RequestSocketWithoutLimits(TransportClientSocketPool* pool) {
4878 return handle_.Init(
4879 group_id_, ClientSocketPool::SocketParams::CreateForHttpForTesting(),
4880 absl::nullopt, MAXIMUM_PRIORITY, SocketTag(),
4881 ClientSocketPool::RespectLimits::DISABLED, callback_.callback(),
4882 ClientSocketPool::ProxyAuthCallback(), pool, NetLogWithSource());
4883 }
4884
ReleaseOneConnection()4885 bool ReleaseOneConnection() {
4886 if (!handle_.is_initialized() || !can_release_connection_) {
4887 return false;
4888 }
4889 handle_.socket()->Disconnect();
4890 handle_.Reset();
4891 return true;
4892 }
4893
set_can_release_connection(bool can_release_connection)4894 void set_can_release_connection(bool can_release_connection) {
4895 can_release_connection_ = can_release_connection;
4896 }
4897
4898 MOCK_METHOD0(CloseOneIdleConnection, bool());
4899
4900 private:
4901 const raw_ptr<TransportClientSocketPool> pool_;
4902 ClientSocketHandle handle_;
4903 TestCompletionCallback callback_;
4904 const ClientSocketPool::GroupId group_id_;
4905 bool can_release_connection_ = true;
4906 };
4907
4908 // Tests the basic case of closing an idle socket in a higher layered pool when
4909 // a new request is issued and the lower layer pool is stalled.
TEST_F(ClientSocketPoolBaseTest,CloseIdleSocketsHeldByLayeredPoolWhenNeeded)4910 TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsHeldByLayeredPoolWhenNeeded) {
4911 CreatePool(1, 1);
4912 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4913
4914 MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("foo"));
4915 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
4916 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4917 .WillOnce(Invoke(&mock_layered_pool,
4918 &MockLayeredPool::ReleaseOneConnection));
4919 ClientSocketHandle handle;
4920 TestCompletionCallback callback;
4921 EXPECT_EQ(
4922 ERR_IO_PENDING,
4923 handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
4924 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4925 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
4926 pool_.get(), NetLogWithSource()));
4927 EXPECT_THAT(callback.WaitForResult(), IsOk());
4928 }
4929
4930 // Tests the case that trying to close an idle socket in a higher layered pool
4931 // fails.
TEST_F(ClientSocketPoolBaseTest,CloseIdleSocketsHeldByLayeredPoolWhenNeededFails)4932 TEST_F(ClientSocketPoolBaseTest,
4933 CloseIdleSocketsHeldByLayeredPoolWhenNeededFails) {
4934 CreatePool(1, 1);
4935 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4936
4937 MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("foo"));
4938 mock_layered_pool.set_can_release_connection(false);
4939 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
4940 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4941 .WillOnce(Invoke(&mock_layered_pool,
4942 &MockLayeredPool::ReleaseOneConnection));
4943 ClientSocketHandle handle;
4944 TestCompletionCallback callback;
4945 EXPECT_EQ(
4946 ERR_IO_PENDING,
4947 handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
4948 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4949 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
4950 pool_.get(), NetLogWithSource()));
4951 base::RunLoop().RunUntilIdle();
4952 EXPECT_FALSE(callback.have_result());
4953 }
4954
4955 // Same as above, but the idle socket is in the same group as the stalled
4956 // socket, and closes the only other request in its group when closing requests
4957 // in higher layered pools. This generally shouldn't happen, but it may be
4958 // possible if a higher level pool issues a request and the request is
4959 // subsequently cancelled. Even if it's not possible, best not to crash.
TEST_F(ClientSocketPoolBaseTest,CloseIdleSocketsHeldByLayeredPoolWhenNeededSameGroup)4960 TEST_F(ClientSocketPoolBaseTest,
4961 CloseIdleSocketsHeldByLayeredPoolWhenNeededSameGroup) {
4962 CreatePool(2, 2);
4963 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4964
4965 // Need a socket in another group for the pool to be stalled (If a group
4966 // has the maximum number of connections already, it's not stalled).
4967 ClientSocketHandle handle1;
4968 TestCompletionCallback callback1;
4969 EXPECT_EQ(OK, handle1.Init(TestGroupId("group1"), params_, absl::nullopt,
4970 DEFAULT_PRIORITY, SocketTag(),
4971 ClientSocketPool::RespectLimits::ENABLED,
4972 callback1.callback(),
4973 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4974 NetLogWithSource()));
4975
4976 MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("group2"));
4977 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
4978 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4979 .WillOnce(Invoke(&mock_layered_pool,
4980 &MockLayeredPool::ReleaseOneConnection));
4981 ClientSocketHandle handle;
4982 TestCompletionCallback callback2;
4983 EXPECT_EQ(ERR_IO_PENDING,
4984 handle.Init(
4985 TestGroupId("group2"), params_, absl::nullopt, DEFAULT_PRIORITY,
4986 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4987 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4988 pool_.get(), NetLogWithSource()));
4989 EXPECT_THAT(callback2.WaitForResult(), IsOk());
4990 }
4991
4992 // Tests the case when an idle socket can be closed when a new request is
4993 // issued, and the new request belongs to a group that was previously stalled.
TEST_F(ClientSocketPoolBaseTest,CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded)4994 TEST_F(ClientSocketPoolBaseTest,
4995 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded) {
4996 CreatePool(2, 2);
4997 std::list<TestConnectJob::JobType> job_types;
4998 job_types.push_back(TestConnectJob::kMockJob);
4999 job_types.push_back(TestConnectJob::kMockJob);
5000 job_types.push_back(TestConnectJob::kMockJob);
5001 job_types.push_back(TestConnectJob::kMockJob);
5002 connect_job_factory_->set_job_types(&job_types);
5003
5004 ClientSocketHandle handle1;
5005 TestCompletionCallback callback1;
5006 EXPECT_EQ(OK, handle1.Init(TestGroupId("group1"), params_, absl::nullopt,
5007 DEFAULT_PRIORITY, SocketTag(),
5008 ClientSocketPool::RespectLimits::ENABLED,
5009 callback1.callback(),
5010 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
5011 NetLogWithSource()));
5012
5013 MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("group2"));
5014 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
5015 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
5016 .WillRepeatedly(Invoke(&mock_layered_pool,
5017 &MockLayeredPool::ReleaseOneConnection));
5018 mock_layered_pool.set_can_release_connection(false);
5019
5020 // The third request is made when the socket pool is in a stalled state.
5021 ClientSocketHandle handle3;
5022 TestCompletionCallback callback3;
5023 EXPECT_EQ(ERR_IO_PENDING,
5024 handle3.Init(
5025 TestGroupId("group3"), params_, absl::nullopt, DEFAULT_PRIORITY,
5026 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5027 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
5028 pool_.get(), NetLogWithSource()));
5029
5030 base::RunLoop().RunUntilIdle();
5031 EXPECT_FALSE(callback3.have_result());
5032
5033 // The fourth request is made when the pool is no longer stalled. The third
5034 // request should be serviced first, since it was issued first and has the
5035 // same priority.
5036 mock_layered_pool.set_can_release_connection(true);
5037 ClientSocketHandle handle4;
5038 TestCompletionCallback callback4;
5039 EXPECT_EQ(ERR_IO_PENDING,
5040 handle4.Init(
5041 TestGroupId("group3"), params_, absl::nullopt, DEFAULT_PRIORITY,
5042 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5043 callback4.callback(), ClientSocketPool::ProxyAuthCallback(),
5044 pool_.get(), NetLogWithSource()));
5045 EXPECT_THAT(callback3.WaitForResult(), IsOk());
5046 EXPECT_FALSE(callback4.have_result());
5047
5048 // Closing a handle should free up another socket slot.
5049 handle1.Reset();
5050 EXPECT_THAT(callback4.WaitForResult(), IsOk());
5051 }
5052
5053 // Tests the case when an idle socket can be closed when a new request is
5054 // issued, and the new request belongs to a group that was previously stalled.
5055 //
5056 // The two differences from the above test are that the stalled requests are not
5057 // in the same group as the layered pool's request, and the the fourth request
5058 // has a higher priority than the third one, so gets a socket first.
TEST_F(ClientSocketPoolBaseTest,CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded2)5059 TEST_F(ClientSocketPoolBaseTest,
5060 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded2) {
5061 CreatePool(2, 2);
5062 std::list<TestConnectJob::JobType> job_types;
5063 job_types.push_back(TestConnectJob::kMockJob);
5064 job_types.push_back(TestConnectJob::kMockJob);
5065 job_types.push_back(TestConnectJob::kMockJob);
5066 job_types.push_back(TestConnectJob::kMockJob);
5067 connect_job_factory_->set_job_types(&job_types);
5068
5069 ClientSocketHandle handle1;
5070 TestCompletionCallback callback1;
5071 EXPECT_EQ(OK, handle1.Init(TestGroupId("group1"), params_, absl::nullopt,
5072 DEFAULT_PRIORITY, SocketTag(),
5073 ClientSocketPool::RespectLimits::ENABLED,
5074 callback1.callback(),
5075 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
5076 NetLogWithSource()));
5077
5078 MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("group2"));
5079 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
5080 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
5081 .WillRepeatedly(Invoke(&mock_layered_pool,
5082 &MockLayeredPool::ReleaseOneConnection));
5083 mock_layered_pool.set_can_release_connection(false);
5084
5085 // The third request is made when the socket pool is in a stalled state.
5086 ClientSocketHandle handle3;
5087 TestCompletionCallback callback3;
5088 EXPECT_EQ(
5089 ERR_IO_PENDING,
5090 handle3.Init(TestGroupId("group3"), params_, absl::nullopt, MEDIUM,
5091 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5092 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
5093 pool_.get(), NetLogWithSource()));
5094
5095 base::RunLoop().RunUntilIdle();
5096 EXPECT_FALSE(callback3.have_result());
5097
5098 // The fourth request is made when the pool is no longer stalled. This
5099 // request has a higher priority than the third request, so is serviced first.
5100 mock_layered_pool.set_can_release_connection(true);
5101 ClientSocketHandle handle4;
5102 TestCompletionCallback callback4;
5103 EXPECT_EQ(
5104 ERR_IO_PENDING,
5105 handle4.Init(TestGroupId("group3"), params_, absl::nullopt, HIGHEST,
5106 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5107 callback4.callback(), ClientSocketPool::ProxyAuthCallback(),
5108 pool_.get(), NetLogWithSource()));
5109 EXPECT_THAT(callback4.WaitForResult(), IsOk());
5110 EXPECT_FALSE(callback3.have_result());
5111
5112 // Closing a handle should free up another socket slot.
5113 handle1.Reset();
5114 EXPECT_THAT(callback3.WaitForResult(), IsOk());
5115 }
5116
TEST_F(ClientSocketPoolBaseTest,CloseMultipleIdleSocketsHeldByLayeredPoolWhenNeeded)5117 TEST_F(ClientSocketPoolBaseTest,
5118 CloseMultipleIdleSocketsHeldByLayeredPoolWhenNeeded) {
5119 CreatePool(1, 1);
5120 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
5121
5122 MockLayeredPool mock_layered_pool1(pool_.get(), TestGroupId("foo"));
5123 EXPECT_THAT(mock_layered_pool1.RequestSocket(pool_.get()), IsOk());
5124 EXPECT_CALL(mock_layered_pool1, CloseOneIdleConnection())
5125 .WillRepeatedly(Invoke(&mock_layered_pool1,
5126 &MockLayeredPool::ReleaseOneConnection));
5127 MockLayeredPool mock_layered_pool2(pool_.get(), TestGroupId("bar"));
5128 EXPECT_THAT(mock_layered_pool2.RequestSocketWithoutLimits(pool_.get()),
5129 IsOk());
5130 EXPECT_CALL(mock_layered_pool2, CloseOneIdleConnection())
5131 .WillRepeatedly(Invoke(&mock_layered_pool2,
5132 &MockLayeredPool::ReleaseOneConnection));
5133 ClientSocketHandle handle;
5134 TestCompletionCallback callback;
5135 EXPECT_EQ(
5136 ERR_IO_PENDING,
5137 handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
5138 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5139 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5140 pool_.get(), NetLogWithSource()));
5141 EXPECT_THAT(callback.WaitForResult(), IsOk());
5142 }
5143
5144 // Test that when a socket pool and group are at their limits, a request
5145 // with RespectLimits::DISABLED triggers creation of a new socket, and gets the
5146 // socket instead of a request with the same priority that was issued earlier,
5147 // but has RespectLimits::ENABLED.
TEST_F(ClientSocketPoolBaseTest,IgnoreLimits)5148 TEST_F(ClientSocketPoolBaseTest, IgnoreLimits) {
5149 CreatePool(1, 1);
5150
5151 // Issue a request to reach the socket pool limit.
5152 EXPECT_EQ(OK, StartRequestWithIgnoreLimits(
5153 TestGroupId("a"), MAXIMUM_PRIORITY,
5154 ClientSocketPool::RespectLimits::ENABLED));
5155 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5156
5157 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
5158
5159 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
5160 TestGroupId("a"), MAXIMUM_PRIORITY,
5161 ClientSocketPool::RespectLimits::ENABLED));
5162 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5163
5164 // Issue a request that ignores the limits, so a new ConnectJob is
5165 // created.
5166 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
5167 TestGroupId("a"), MAXIMUM_PRIORITY,
5168 ClientSocketPool::RespectLimits::DISABLED));
5169 ASSERT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5170
5171 EXPECT_THAT(request(2)->WaitForResult(), IsOk());
5172 EXPECT_FALSE(request(1)->have_result());
5173 }
5174
5175 // Test that when a socket pool and group are at their limits, a ConnectJob
5176 // issued for a request with RespectLimits::DISABLED is not cancelled when a
5177 // request with RespectLimits::ENABLED issued to the same group is cancelled.
TEST_F(ClientSocketPoolBaseTest,IgnoreLimitsCancelOtherJob)5178 TEST_F(ClientSocketPoolBaseTest, IgnoreLimitsCancelOtherJob) {
5179 CreatePool(1, 1);
5180
5181 // Issue a request to reach the socket pool limit.
5182 EXPECT_EQ(OK, StartRequestWithIgnoreLimits(
5183 TestGroupId("a"), MAXIMUM_PRIORITY,
5184 ClientSocketPool::RespectLimits::ENABLED));
5185 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5186
5187 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
5188
5189 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
5190 TestGroupId("a"), MAXIMUM_PRIORITY,
5191 ClientSocketPool::RespectLimits::ENABLED));
5192 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5193
5194 // Issue a request with RespectLimits::DISABLED, so a new ConnectJob is
5195 // created.
5196 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
5197 TestGroupId("a"), MAXIMUM_PRIORITY,
5198 ClientSocketPool::RespectLimits::DISABLED));
5199 ASSERT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5200
5201 // Cancel the pending request with RespectLimits::ENABLED. The ConnectJob
5202 // should not be cancelled.
5203 request(1)->handle()->Reset();
5204 ASSERT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5205
5206 EXPECT_THAT(request(2)->WaitForResult(), IsOk());
5207 EXPECT_FALSE(request(1)->have_result());
5208 }
5209
TEST_F(ClientSocketPoolBaseTest,ProxyAuthNoAuthCallback)5210 TEST_F(ClientSocketPoolBaseTest, ProxyAuthNoAuthCallback) {
5211 CreatePool(1, 1);
5212
5213 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5214
5215 ClientSocketHandle handle;
5216 TestCompletionCallback callback;
5217 EXPECT_EQ(
5218 ERR_IO_PENDING,
5219 handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
5220 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5221 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5222 pool_.get(), NetLogWithSource()));
5223
5224 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5225
5226 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_PROXY_AUTH_REQUESTED));
5227 EXPECT_FALSE(handle.is_initialized());
5228 EXPECT_FALSE(handle.socket());
5229
5230 // The group should now be empty, and thus be deleted.
5231 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
5232 }
5233
5234 class TestAuthHelper {
5235 public:
5236 TestAuthHelper() = default;
5237
5238 TestAuthHelper(const TestAuthHelper&) = delete;
5239 TestAuthHelper& operator=(const TestAuthHelper&) = delete;
5240
5241 ~TestAuthHelper() = default;
5242
InitHandle(scoped_refptr<ClientSocketPool::SocketParams> params,TransportClientSocketPool * pool,RequestPriority priority=DEFAULT_PRIORITY,ClientSocketPool::RespectLimits respect_limits=ClientSocketPool::RespectLimits::ENABLED,const ClientSocketPool::GroupId & group_id_in=TestGroupId ("a"))5243 void InitHandle(
5244 scoped_refptr<ClientSocketPool::SocketParams> params,
5245 TransportClientSocketPool* pool,
5246 RequestPriority priority = DEFAULT_PRIORITY,
5247 ClientSocketPool::RespectLimits respect_limits =
5248 ClientSocketPool::RespectLimits::ENABLED,
5249 const ClientSocketPool::GroupId& group_id_in = TestGroupId("a")) {
5250 EXPECT_EQ(ERR_IO_PENDING,
5251 handle_.Init(group_id_in, params, absl::nullopt, priority,
5252 SocketTag(), respect_limits, callback_.callback(),
5253 base::BindRepeating(&TestAuthHelper::AuthCallback,
5254 base::Unretained(this)),
5255 pool, NetLogWithSource()));
5256 }
5257
WaitForAuth()5258 void WaitForAuth() {
5259 run_loop_ = std::make_unique<base::RunLoop>();
5260 run_loop_->Run();
5261 run_loop_.reset();
5262 }
5263
WaitForAuthAndRestartSync()5264 void WaitForAuthAndRestartSync() {
5265 restart_sync_ = true;
5266 WaitForAuth();
5267 restart_sync_ = false;
5268 }
5269
WaitForAuthAndResetHandleSync()5270 void WaitForAuthAndResetHandleSync() {
5271 reset_handle_sync_ = true;
5272 WaitForAuth();
5273 reset_handle_sync_ = false;
5274 }
5275
RestartWithAuth()5276 void RestartWithAuth() {
5277 DCHECK(restart_with_auth_callback_);
5278 std::move(restart_with_auth_callback_).Run();
5279 }
5280
WaitForResult()5281 int WaitForResult() {
5282 int result = callback_.WaitForResult();
5283 // There shouldn't be any callback waiting to be invoked once the request is
5284 // complete.
5285 EXPECT_FALSE(restart_with_auth_callback_);
5286 // The socket should only be initialized on success.
5287 EXPECT_EQ(result == OK, handle_.is_initialized());
5288 EXPECT_EQ(result == OK, handle_.socket() != nullptr);
5289 return result;
5290 }
5291
handle()5292 ClientSocketHandle* handle() { return &handle_; }
auth_count() const5293 int auth_count() const { return auth_count_; }
have_result() const5294 int have_result() const { return callback_.have_result(); }
5295
5296 private:
AuthCallback(const HttpResponseInfo & response,HttpAuthController * auth_controller,base::OnceClosure restart_with_auth_callback)5297 void AuthCallback(const HttpResponseInfo& response,
5298 HttpAuthController* auth_controller,
5299 base::OnceClosure restart_with_auth_callback) {
5300 EXPECT_FALSE(restart_with_auth_callback_);
5301 EXPECT_TRUE(restart_with_auth_callback);
5302
5303 // Once there's a result, this method shouldn't be invoked again.
5304 EXPECT_FALSE(callback_.have_result());
5305
5306 ++auth_count_;
5307 run_loop_->Quit();
5308 if (restart_sync_) {
5309 std::move(restart_with_auth_callback).Run();
5310 return;
5311 }
5312
5313 restart_with_auth_callback_ = std::move(restart_with_auth_callback);
5314
5315 if (reset_handle_sync_) {
5316 handle_.Reset();
5317 return;
5318 }
5319 }
5320
5321 std::unique_ptr<base::RunLoop> run_loop_;
5322 base::OnceClosure restart_with_auth_callback_;
5323
5324 bool restart_sync_ = false;
5325 bool reset_handle_sync_ = false;
5326
5327 ClientSocketHandle handle_;
5328 int auth_count_ = 0;
5329 TestCompletionCallback callback_;
5330 };
5331
TEST_F(ClientSocketPoolBaseTest,ProxyAuthOnce)5332 TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnce) {
5333 CreatePool(1, 1);
5334 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5335
5336 TestAuthHelper auth_helper;
5337 auth_helper.InitHandle(params_, pool_.get());
5338 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5339 EXPECT_EQ(LOAD_STATE_CONNECTING,
5340 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
5341
5342 auth_helper.WaitForAuth();
5343 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5344 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
5345 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
5346
5347 auth_helper.RestartWithAuth();
5348 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5349 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
5350 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
5351
5352 EXPECT_THAT(auth_helper.WaitForResult(), IsOk());
5353 EXPECT_EQ(1, auth_helper.auth_count());
5354 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5355 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
5356 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
5357 EXPECT_EQ(0, pool_->IdleSocketCount());
5358 }
5359
TEST_F(ClientSocketPoolBaseTest,ProxyAuthOnceSync)5360 TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceSync) {
5361 CreatePool(1, 1);
5362 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5363
5364 TestAuthHelper auth_helper;
5365 auth_helper.InitHandle(params_, pool_.get());
5366 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5367 EXPECT_EQ(LOAD_STATE_CONNECTING,
5368 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
5369
5370 auth_helper.WaitForAuthAndRestartSync();
5371 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5372 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
5373 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
5374
5375 EXPECT_THAT(auth_helper.WaitForResult(), IsOk());
5376 EXPECT_EQ(1, auth_helper.auth_count());
5377 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5378 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
5379 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
5380 EXPECT_EQ(0, pool_->IdleSocketCount());
5381 }
5382
TEST_F(ClientSocketPoolBaseTest,ProxyAuthOnceFails)5383 TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceFails) {
5384 CreatePool(1, 1);
5385 connect_job_factory_->set_job_type(
5386 TestConnectJob::kMockAuthChallengeOnceFailingJob);
5387
5388 TestAuthHelper auth_helper;
5389 auth_helper.InitHandle(params_, pool_.get());
5390 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5391
5392 auth_helper.WaitForAuth();
5393 auth_helper.RestartWithAuth();
5394 EXPECT_THAT(auth_helper.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
5395
5396 EXPECT_EQ(1, auth_helper.auth_count());
5397 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
5398 EXPECT_EQ(0, pool_->IdleSocketCount());
5399 }
5400
TEST_F(ClientSocketPoolBaseTest,ProxyAuthOnceSyncFails)5401 TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceSyncFails) {
5402 CreatePool(1, 1);
5403 connect_job_factory_->set_job_type(
5404 TestConnectJob::kMockAuthChallengeOnceFailingJob);
5405
5406 TestAuthHelper auth_helper;
5407 auth_helper.InitHandle(params_, pool_.get());
5408 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5409
5410 auth_helper.WaitForAuthAndRestartSync();
5411 EXPECT_THAT(auth_helper.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
5412
5413 EXPECT_EQ(1, auth_helper.auth_count());
5414 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
5415 EXPECT_EQ(0, pool_->IdleSocketCount());
5416 }
5417
TEST_F(ClientSocketPoolBaseTest,ProxyAuthOnceDeleteHandle)5418 TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceDeleteHandle) {
5419 CreatePool(1, 1);
5420 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5421
5422 TestAuthHelper auth_helper;
5423 auth_helper.InitHandle(params_, pool_.get());
5424 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5425
5426 auth_helper.WaitForAuth();
5427 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5428
5429 auth_helper.handle()->Reset();
5430
5431 EXPECT_EQ(1, auth_helper.auth_count());
5432 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
5433 EXPECT_EQ(0, pool_->IdleSocketCount());
5434 EXPECT_FALSE(auth_helper.handle()->is_initialized());
5435 EXPECT_FALSE(auth_helper.handle()->socket());
5436 }
5437
TEST_F(ClientSocketPoolBaseTest,ProxyAuthOnceDeleteHandleSync)5438 TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceDeleteHandleSync) {
5439 CreatePool(1, 1);
5440 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5441
5442 TestAuthHelper auth_helper;
5443 auth_helper.InitHandle(params_, pool_.get());
5444 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5445
5446 auth_helper.WaitForAuthAndResetHandleSync();
5447 EXPECT_EQ(1, auth_helper.auth_count());
5448 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
5449 EXPECT_EQ(0, pool_->IdleSocketCount());
5450 EXPECT_FALSE(auth_helper.handle()->is_initialized());
5451 EXPECT_FALSE(auth_helper.handle()->socket());
5452 }
5453
TEST_F(ClientSocketPoolBaseTest,ProxyAuthOnceFlushWithError)5454 TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceFlushWithError) {
5455 CreatePool(1, 1);
5456 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5457
5458 TestAuthHelper auth_helper;
5459 auth_helper.InitHandle(params_, pool_.get());
5460 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5461
5462 auth_helper.WaitForAuth();
5463
5464 pool_->FlushWithError(ERR_FAILED, "Network changed");
5465 base::RunLoop().RunUntilIdle();
5466
5467 // When flushing the socket pool, bound sockets should delay returning the
5468 // error until completion.
5469 EXPECT_FALSE(auth_helper.have_result());
5470 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5471 EXPECT_EQ(0, pool_->IdleSocketCount());
5472
5473 auth_helper.RestartWithAuth();
5474 // The callback should be called asynchronously.
5475 EXPECT_FALSE(auth_helper.have_result());
5476
5477 EXPECT_THAT(auth_helper.WaitForResult(), IsError(ERR_FAILED));
5478 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
5479 EXPECT_EQ(0, pool_->IdleSocketCount());
5480 }
5481
TEST_F(ClientSocketPoolBaseTest,ProxyAuthTwice)5482 TEST_F(ClientSocketPoolBaseTest, ProxyAuthTwice) {
5483 CreatePool(1, 1);
5484 connect_job_factory_->set_job_type(
5485 TestConnectJob::kMockAuthChallengeTwiceJob);
5486
5487 TestAuthHelper auth_helper;
5488 auth_helper.InitHandle(params_, pool_.get());
5489 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5490 EXPECT_EQ(LOAD_STATE_CONNECTING,
5491 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
5492
5493 auth_helper.WaitForAuth();
5494 auth_helper.RestartWithAuth();
5495 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5496 EXPECT_EQ(1, auth_helper.auth_count());
5497 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
5498 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
5499
5500 auth_helper.WaitForAuth();
5501 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5502 EXPECT_EQ(2, auth_helper.auth_count());
5503 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
5504 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
5505
5506 auth_helper.RestartWithAuth();
5507 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5508 EXPECT_EQ(2, auth_helper.auth_count());
5509 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
5510 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
5511
5512 EXPECT_THAT(auth_helper.WaitForResult(), IsOk());
5513 EXPECT_EQ(2, auth_helper.auth_count());
5514 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5515 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
5516 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
5517 EXPECT_EQ(0, pool_->IdleSocketCount());
5518 }
5519
TEST_F(ClientSocketPoolBaseTest,ProxyAuthTwiceFails)5520 TEST_F(ClientSocketPoolBaseTest, ProxyAuthTwiceFails) {
5521 CreatePool(1, 1);
5522 connect_job_factory_->set_job_type(
5523 TestConnectJob::kMockAuthChallengeTwiceFailingJob);
5524
5525 TestAuthHelper auth_helper;
5526 auth_helper.InitHandle(params_, pool_.get());
5527 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5528
5529 auth_helper.WaitForAuth();
5530 auth_helper.RestartWithAuth();
5531 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5532 EXPECT_EQ(1, auth_helper.auth_count());
5533
5534 auth_helper.WaitForAuth();
5535 auth_helper.RestartWithAuth();
5536 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5537 EXPECT_EQ(2, auth_helper.auth_count());
5538
5539 EXPECT_THAT(auth_helper.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
5540 EXPECT_EQ(2, auth_helper.auth_count());
5541 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
5542 EXPECT_EQ(0, pool_->IdleSocketCount());
5543 }
5544
5545 // Makes sure that when a bound request is destroyed, a new ConnectJob is
5546 // created, if needed.
TEST_F(ClientSocketPoolBaseTest,ProxyAuthCreateNewConnectJobOnDestroyBoundRequest)5547 TEST_F(ClientSocketPoolBaseTest,
5548 ProxyAuthCreateNewConnectJobOnDestroyBoundRequest) {
5549 CreatePool(1 /* max_sockets */, 1 /* max_sockets_per_group */);
5550 connect_job_factory_->set_job_type(
5551 TestConnectJob::kMockAuthChallengeOnceFailingJob);
5552
5553 // First request creates a ConnectJob.
5554 TestAuthHelper auth_helper1;
5555 auth_helper1.InitHandle(params_, pool_.get());
5556 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5557
5558 // A second request come in, but no new ConnectJob is needed, since the limit
5559 // has been reached.
5560 TestAuthHelper auth_helper2;
5561 auth_helper2.InitHandle(params_, pool_.get());
5562 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5563
5564 // Run until the auth callback for the first request is invoked.
5565 auth_helper1.WaitForAuth();
5566 EXPECT_EQ(0, auth_helper2.auth_count());
5567 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5568 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
5569 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
5570
5571 // Make connect jobs succeed, then cancel the first request, which should
5572 // destroy the bound ConnectJob, and cause a new ConnectJob to start.
5573 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
5574 auth_helper1.handle()->Reset();
5575 EXPECT_EQ(0, auth_helper2.auth_count());
5576 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5577
5578 // The second ConnectJob should succeed.
5579 EXPECT_THAT(auth_helper2.WaitForResult(), IsOk());
5580 EXPECT_EQ(0, auth_helper2.auth_count());
5581 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5582 }
5583
5584 // Makes sure that when a bound request is destroyed, a new ConnectJob is
5585 // created for another group, if needed.
TEST_F(ClientSocketPoolBaseTest,ProxyAuthCreateNewConnectJobOnDestroyBoundRequestDifferentGroups)5586 TEST_F(ClientSocketPoolBaseTest,
5587 ProxyAuthCreateNewConnectJobOnDestroyBoundRequestDifferentGroups) {
5588 CreatePool(1 /* max_sockets */, 1 /* max_sockets_per_group */);
5589 connect_job_factory_->set_job_type(
5590 TestConnectJob::kMockAuthChallengeOnceFailingJob);
5591
5592 // First request creates a ConnectJob.
5593 TestAuthHelper auth_helper1;
5594 auth_helper1.InitHandle(params_, pool_.get(), DEFAULT_PRIORITY);
5595 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5596
5597 // A second request come in, but no new ConnectJob is needed, since the limit
5598 // has been reached.
5599 TestAuthHelper auth_helper2;
5600 auth_helper2.InitHandle(params_, pool_.get(), DEFAULT_PRIORITY,
5601 ClientSocketPool::RespectLimits::ENABLED,
5602 TestGroupId("b"));
5603 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5604 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
5605
5606 // Run until the auth callback for the first request is invoked.
5607 auth_helper1.WaitForAuth();
5608 EXPECT_EQ(0, auth_helper2.auth_count());
5609 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5610 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
5611 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
5612 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
5613 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("b")));
5614 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
5615
5616 // Make connect jobs succeed, then cancel the first request, which should
5617 // destroy the bound ConnectJob, and cause a new ConnectJob to start for the
5618 // other group.
5619 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
5620 auth_helper1.handle()->Reset();
5621 EXPECT_EQ(0, auth_helper2.auth_count());
5622 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
5623 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
5624
5625 // The second ConnectJob should succeed.
5626 EXPECT_THAT(auth_helper2.WaitForResult(), IsOk());
5627 EXPECT_EQ(0, auth_helper2.auth_count());
5628 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
5629 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
5630 }
5631
5632 // Test that once an auth challenge is bound, that's the request that gets all
5633 // subsequent calls and the socket itself.
TEST_F(ClientSocketPoolBaseTest,ProxyAuthStaysBound)5634 TEST_F(ClientSocketPoolBaseTest, ProxyAuthStaysBound) {
5635 CreatePool(1, 1);
5636 connect_job_factory_->set_job_type(
5637 TestConnectJob::kMockAuthChallengeTwiceJob);
5638
5639 // First request creates a ConnectJob.
5640 TestAuthHelper auth_helper1;
5641 auth_helper1.InitHandle(params_, pool_.get(), LOWEST);
5642 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5643
5644 // A second, higher priority request is made.
5645 TestAuthHelper auth_helper2;
5646 auth_helper2.InitHandle(params_, pool_.get(), LOW);
5647 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5648
5649 // Run until the auth callback for the second request is invoked.
5650 auth_helper2.WaitForAuth();
5651 EXPECT_EQ(0, auth_helper1.auth_count());
5652 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5653 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
5654 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
5655
5656 // Start a higher priority job. It shouldn't be able to steal |auth_helper2|'s
5657 // ConnectJob.
5658 TestAuthHelper auth_helper3;
5659 auth_helper3.InitHandle(params_, pool_.get(), HIGHEST);
5660 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5661
5662 // Start a higher job that ignores limits, creating a hanging socket. It
5663 // shouldn't be able to steal |auth_helper2|'s ConnectJob.
5664 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
5665 TestAuthHelper auth_helper4;
5666 auth_helper4.InitHandle(params_, pool_.get(), HIGHEST,
5667 ClientSocketPool::RespectLimits::DISABLED);
5668 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5669
5670 // Restart with auth, and |auth_helper2|'s auth method should be invoked
5671 // again.
5672 auth_helper2.RestartWithAuth();
5673 auth_helper2.WaitForAuth();
5674 EXPECT_EQ(0, auth_helper1.auth_count());
5675 EXPECT_FALSE(auth_helper1.have_result());
5676 EXPECT_EQ(2, auth_helper2.auth_count());
5677 EXPECT_FALSE(auth_helper2.have_result());
5678 EXPECT_EQ(0, auth_helper3.auth_count());
5679 EXPECT_FALSE(auth_helper3.have_result());
5680 EXPECT_EQ(0, auth_helper4.auth_count());
5681 EXPECT_FALSE(auth_helper4.have_result());
5682
5683 // Advance auth again, and |auth_helper2| should get the socket.
5684 auth_helper2.RestartWithAuth();
5685 EXPECT_THAT(auth_helper2.WaitForResult(), IsOk());
5686 // The hung ConnectJob for the RespectLimits::DISABLED request is still in the
5687 // socket pool.
5688 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5689 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
5690 EXPECT_EQ(0, auth_helper1.auth_count());
5691 EXPECT_FALSE(auth_helper1.have_result());
5692 EXPECT_EQ(0, auth_helper3.auth_count());
5693 EXPECT_FALSE(auth_helper3.have_result());
5694 EXPECT_EQ(0, auth_helper4.auth_count());
5695 EXPECT_FALSE(auth_helper4.have_result());
5696
5697 // If the socket is returned to the socket pool, the RespectLimits::DISABLED
5698 // socket request should be able to claim it.
5699 auth_helper2.handle()->Reset();
5700 EXPECT_THAT(auth_helper4.WaitForResult(), IsOk());
5701 EXPECT_EQ(0, auth_helper1.auth_count());
5702 EXPECT_FALSE(auth_helper1.have_result());
5703 EXPECT_EQ(0, auth_helper3.auth_count());
5704 EXPECT_FALSE(auth_helper3.have_result());
5705 EXPECT_EQ(0, auth_helper4.auth_count());
5706 }
5707
5708 enum class RefreshType {
5709 kServer,
5710 kProxy,
5711 };
5712
5713 // Common base class to test RefreshGroup() when called from either
5714 // OnSSLConfigForServersChanged() matching a specific group or the pool's proxy.
5715 //
5716 // Tests which test behavior specific to one or the other case should use
5717 // ClientSocketPoolBaseTest directly. In particular, there is no "other group"
5718 // when the pool's proxy matches.
5719 class ClientSocketPoolBaseRefreshTest
5720 : public ClientSocketPoolBaseTest,
5721 public testing::WithParamInterface<RefreshType> {
5722 public:
CreatePoolForRefresh(int max_sockets,int max_sockets_per_group,bool enable_backup_connect_jobs=false)5723 void CreatePoolForRefresh(int max_sockets,
5724 int max_sockets_per_group,
5725 bool enable_backup_connect_jobs = false) {
5726 switch (GetParam()) {
5727 case RefreshType::kServer:
5728 CreatePool(max_sockets, max_sockets_per_group,
5729 enable_backup_connect_jobs);
5730 break;
5731 case RefreshType::kProxy:
5732 CreatePoolWithIdleTimeouts(
5733 max_sockets, max_sockets_per_group, kUnusedIdleSocketTimeout,
5734 ClientSocketPool::used_idle_socket_timeout(),
5735 enable_backup_connect_jobs,
5736 PacResultElementToProxyChain("HTTPS myproxy:70"));
5737 break;
5738 }
5739 }
5740
GetGroupId()5741 static ClientSocketPool::GroupId GetGroupId() {
5742 return TestGroupId("a", 443, url::kHttpsScheme);
5743 }
5744
GetGroupIdInPartition()5745 static ClientSocketPool::GroupId GetGroupIdInPartition() {
5746 // Note this GroupId will match GetGroupId() unless
5747 // kPartitionConnectionsByNetworkAnonymizationKey is enabled.
5748 const SchemefulSite kSite(GURL("https://b/"));
5749 const auto kNetworkAnonymizationKey =
5750 NetworkAnonymizationKey::CreateSameSite(kSite);
5751 return TestGroupId("a", 443, url::kHttpsScheme,
5752 PrivacyMode::PRIVACY_MODE_DISABLED,
5753 kNetworkAnonymizationKey);
5754 }
5755
OnSSLConfigForServersChanged()5756 void OnSSLConfigForServersChanged() {
5757 switch (GetParam()) {
5758 case RefreshType::kServer:
5759 pool_->OnSSLConfigForServersChanged({HostPortPair("a", 443)});
5760 break;
5761 case RefreshType::kProxy:
5762 pool_->OnSSLConfigForServersChanged({HostPortPair("myproxy", 70)});
5763 break;
5764 }
5765 }
5766 };
5767
5768 INSTANTIATE_TEST_SUITE_P(RefreshType,
5769 ClientSocketPoolBaseRefreshTest,
5770 ::testing::Values(RefreshType::kServer,
5771 RefreshType::kProxy));
5772
TEST_P(ClientSocketPoolBaseRefreshTest,RefreshGroupCreatesNewConnectJobs)5773 TEST_P(ClientSocketPoolBaseRefreshTest, RefreshGroupCreatesNewConnectJobs) {
5774 CreatePoolForRefresh(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
5775 const ClientSocketPool::GroupId kGroupId = GetGroupId();
5776
5777 // First job will be waiting until it gets aborted.
5778 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
5779
5780 ClientSocketHandle handle;
5781 TestCompletionCallback callback;
5782 EXPECT_THAT(
5783 handle.Init(kGroupId, params_, absl::nullopt, DEFAULT_PRIORITY,
5784 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5785 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5786 pool_.get(), NetLogWithSource()),
5787 IsError(ERR_IO_PENDING));
5788
5789 // Switch connect job types, so creating a new ConnectJob will result in
5790 // success.
5791 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
5792
5793 OnSSLConfigForServersChanged();
5794 EXPECT_EQ(OK, callback.WaitForResult());
5795 ASSERT_TRUE(handle.socket());
5796 EXPECT_EQ(0, pool_->IdleSocketCount());
5797 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
5798 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(kGroupId));
5799 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(kGroupId));
5800 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId));
5801 }
5802
TEST_P(ClientSocketPoolBaseRefreshTest,RefreshGroupClosesIdleConnectJobs)5803 TEST_P(ClientSocketPoolBaseRefreshTest, RefreshGroupClosesIdleConnectJobs) {
5804 base::test::ScopedFeatureList feature_list;
5805 feature_list.InitAndEnableFeature(
5806 features::kPartitionConnectionsByNetworkIsolationKey);
5807
5808 CreatePoolForRefresh(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
5809 const ClientSocketPool::GroupId kGroupId = GetGroupId();
5810 const ClientSocketPool::GroupId kGroupIdInPartition = GetGroupIdInPartition();
5811
5812 EXPECT_EQ(
5813 OK, pool_->RequestSockets(kGroupId, params_, absl::nullopt, 2,
5814 CompletionOnceCallback(), NetLogWithSource()));
5815
5816 EXPECT_EQ(
5817 OK, pool_->RequestSockets(kGroupIdInPartition, params_, absl::nullopt, 2,
5818 CompletionOnceCallback(), NetLogWithSource()));
5819 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
5820 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupIdInPartition));
5821 EXPECT_EQ(4, pool_->IdleSocketCount());
5822 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(kGroupId));
5823 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(kGroupIdInPartition));
5824
5825 OnSSLConfigForServersChanged();
5826 EXPECT_EQ(0, pool_->IdleSocketCount());
5827 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId));
5828 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupIdInPartition));
5829 }
5830
TEST_F(ClientSocketPoolBaseTest,RefreshGroupDoesNotCloseIdleConnectJobsInOtherGroup)5831 TEST_F(ClientSocketPoolBaseTest,
5832 RefreshGroupDoesNotCloseIdleConnectJobsInOtherGroup) {
5833 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
5834 const ClientSocketPool::GroupId kGroupId =
5835 TestGroupId("a", 443, url::kHttpsScheme);
5836 const ClientSocketPool::GroupId kOtherGroupId =
5837 TestGroupId("b", 443, url::kHttpsScheme);
5838
5839 EXPECT_EQ(
5840 OK, pool_->RequestSockets(kOtherGroupId, params_, absl::nullopt, 2,
5841 CompletionOnceCallback(), NetLogWithSource()));
5842 ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
5843 EXPECT_EQ(2, pool_->IdleSocketCount());
5844 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(kOtherGroupId));
5845
5846 pool_->OnSSLConfigForServersChanged({HostPortPair("a", 443)});
5847 ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
5848 EXPECT_EQ(2, pool_->IdleSocketCount());
5849 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(kOtherGroupId));
5850 }
5851
TEST_P(ClientSocketPoolBaseRefreshTest,RefreshGroupPreventsSocketReuse)5852 TEST_P(ClientSocketPoolBaseRefreshTest, RefreshGroupPreventsSocketReuse) {
5853 CreatePoolForRefresh(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
5854 const ClientSocketPool::GroupId kGroupId = GetGroupId();
5855
5856 ClientSocketHandle handle;
5857 TestCompletionCallback callback;
5858 EXPECT_THAT(
5859 handle.Init(kGroupId, params_, absl::nullopt, DEFAULT_PRIORITY,
5860 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5861 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5862 pool_.get(), NetLogWithSource()),
5863 IsOk());
5864 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
5865 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId));
5866
5867 OnSSLConfigForServersChanged();
5868
5869 handle.Reset();
5870 EXPECT_EQ(0, pool_->IdleSocketCount());
5871 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId));
5872 }
5873
TEST_F(ClientSocketPoolBaseTest,RefreshGroupDoesNotPreventSocketReuseInOtherGroup)5874 TEST_F(ClientSocketPoolBaseTest,
5875 RefreshGroupDoesNotPreventSocketReuseInOtherGroup) {
5876 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
5877 const ClientSocketPool::GroupId kGroupId =
5878 TestGroupId("a", 443, url::kHttpsScheme);
5879 const ClientSocketPool::GroupId kOtherGroupId =
5880 TestGroupId("b", 443, url::kHttpsScheme);
5881
5882 ClientSocketHandle handle;
5883 TestCompletionCallback callback;
5884 EXPECT_THAT(
5885 handle.Init(kOtherGroupId, params_, absl::nullopt, DEFAULT_PRIORITY,
5886 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5887 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5888 pool_.get(), NetLogWithSource()),
5889 IsOk());
5890 ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
5891 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kOtherGroupId));
5892
5893 pool_->OnSSLConfigForServersChanged({HostPortPair("a", 443)});
5894
5895 handle.Reset();
5896 EXPECT_EQ(1, pool_->IdleSocketCount());
5897 ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
5898 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kOtherGroupId));
5899 }
5900
TEST_P(ClientSocketPoolBaseRefreshTest,RefreshGroupReplacesBoundConnectJobOnConnect)5901 TEST_P(ClientSocketPoolBaseRefreshTest,
5902 RefreshGroupReplacesBoundConnectJobOnConnect) {
5903 CreatePoolForRefresh(1, 1);
5904 const ClientSocketPool::GroupId kGroupId = GetGroupId();
5905 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5906
5907 TestAuthHelper auth_helper;
5908 auth_helper.InitHandle(params_, pool_.get(), DEFAULT_PRIORITY,
5909 ClientSocketPool::RespectLimits::ENABLED, kGroupId);
5910 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(kGroupId));
5911
5912 auth_helper.WaitForAuth();
5913
5914 // This should update the generation, but not cancel the old ConnectJob - it's
5915 // not safe to do anything while waiting on the original ConnectJob.
5916 OnSSLConfigForServersChanged();
5917
5918 // Providing auth credentials and restarting the request with them will cause
5919 // the ConnectJob to complete successfully, but the result will be discarded
5920 // because of the generation mismatch.
5921 auth_helper.RestartWithAuth();
5922
5923 // Despite using ConnectJobs that simulate a single challenge, a second
5924 // challenge will be seen, due to using a new ConnectJob.
5925 auth_helper.WaitForAuth();
5926 auth_helper.RestartWithAuth();
5927
5928 EXPECT_THAT(auth_helper.WaitForResult(), IsOk());
5929 EXPECT_TRUE(auth_helper.handle()->socket());
5930 EXPECT_EQ(2, auth_helper.auth_count());
5931
5932 // When released, the socket will be returned to the socket pool, and
5933 // available for reuse.
5934 auth_helper.handle()->Reset();
5935 EXPECT_EQ(1, pool_->IdleSocketCount());
5936 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
5937 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kGroupId));
5938 }
5939
TEST_F(ClientSocketPoolBaseTest,RefreshProxyRefreshesAllGroups)5940 TEST_F(ClientSocketPoolBaseTest, RefreshProxyRefreshesAllGroups) {
5941 // Create a proxy chain containing `myproxy` (which is refreshed) and
5942 // nonrefreshedproxy (which is not), verifying that if any proxy in a chain is
5943 // refreshed, all groups are refreshed.
5944 ProxyChain proxy_chain({
5945 PacResultElementToProxyServer("HTTPS myproxy:70"),
5946 PacResultElementToProxyServer("HTTPS nonrefreshedproxy:70"),
5947 });
5948 CreatePoolWithIdleTimeouts(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
5949 kUnusedIdleSocketTimeout,
5950 ClientSocketPool::used_idle_socket_timeout(),
5951 false /* no backup connect jobs */, proxy_chain);
5952
5953 const ClientSocketPool::GroupId kGroupId1 =
5954 TestGroupId("a", 443, url::kHttpsScheme);
5955 const ClientSocketPool::GroupId kGroupId2 =
5956 TestGroupId("b", 443, url::kHttpsScheme);
5957 const ClientSocketPool::GroupId kGroupId3 =
5958 TestGroupId("c", 443, url::kHttpsScheme);
5959
5960 // Make three sockets in three different groups. The third socket is released
5961 // to the pool as idle.
5962 ClientSocketHandle handle1, handle2, handle3;
5963 TestCompletionCallback callback;
5964 EXPECT_THAT(
5965 handle1.Init(kGroupId1, params_, absl::nullopt, DEFAULT_PRIORITY,
5966 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5967 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5968 pool_.get(), NetLogWithSource()),
5969 IsOk());
5970 EXPECT_THAT(
5971 handle2.Init(kGroupId2, params_, absl::nullopt, DEFAULT_PRIORITY,
5972 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5973 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5974 pool_.get(), NetLogWithSource()),
5975 IsOk());
5976 EXPECT_THAT(
5977 handle3.Init(kGroupId3, params_, absl::nullopt, DEFAULT_PRIORITY,
5978 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5979 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5980 pool_.get(), NetLogWithSource()),
5981 IsOk());
5982 handle3.Reset();
5983 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId1));
5984 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId1));
5985 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId2));
5986 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId2));
5987 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId3));
5988 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kGroupId3));
5989
5990 // Changes to some other proxy do not affect the pool. The idle socket remains
5991 // alive and closing |handle2| makes the socket available for the pool.
5992 pool_->OnSSLConfigForServersChanged({HostPortPair("someotherproxy", 70)});
5993
5994 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId1));
5995 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId1));
5996 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId2));
5997 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId2));
5998 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId3));
5999 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kGroupId3));
6000
6001 handle2.Reset();
6002 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId2));
6003 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kGroupId2));
6004
6005 // Changes to the matching proxy refreshes all groups.
6006 pool_->OnSSLConfigForServersChanged({HostPortPair("myproxy", 70)});
6007
6008 // Idle sockets are closed.
6009 EXPECT_EQ(0, pool_->IdleSocketCount());
6010 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId2));
6011 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId3));
6012
6013 // The active socket, however, continues to be active.
6014 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId1));
6015 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId1));
6016
6017 // Closing it does not make it available for the pool.
6018 handle1.Reset();
6019 EXPECT_EQ(0, pool_->IdleSocketCount());
6020 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId1));
6021 }
6022
TEST_F(ClientSocketPoolBaseTest,RefreshBothPrivacyAndNormalSockets)6023 TEST_F(ClientSocketPoolBaseTest, RefreshBothPrivacyAndNormalSockets) {
6024 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
6025
6026 const ClientSocketPool::GroupId kGroupId = TestGroupId(
6027 "a", 443, url::kHttpsScheme, PrivacyMode::PRIVACY_MODE_DISABLED);
6028 const ClientSocketPool::GroupId kGroupIdPrivacy = TestGroupId(
6029 "a", 443, url::kHttpsScheme, PrivacyMode::PRIVACY_MODE_ENABLED);
6030 const ClientSocketPool::GroupId kOtherGroupId =
6031 TestGroupId("b", 443, url::kHttpsScheme);
6032
6033 // Make a socket in each groups.
6034 ClientSocketHandle handle1, handle2, handle3;
6035 TestCompletionCallback callback;
6036 EXPECT_THAT(
6037 handle1.Init(kGroupId, params_, absl::nullopt, DEFAULT_PRIORITY,
6038 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
6039 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
6040 pool_.get(), NetLogWithSource()),
6041 IsOk());
6042 EXPECT_THAT(
6043 handle2.Init(kGroupIdPrivacy, params_, absl::nullopt, DEFAULT_PRIORITY,
6044 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
6045 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
6046 pool_.get(), NetLogWithSource()),
6047 IsOk());
6048 EXPECT_THAT(
6049 handle3.Init(kOtherGroupId, params_, absl::nullopt, DEFAULT_PRIORITY,
6050 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
6051 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
6052 pool_.get(), NetLogWithSource()),
6053 IsOk());
6054 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
6055 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId));
6056 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupIdPrivacy));
6057 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupIdPrivacy));
6058 ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
6059 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kOtherGroupId));
6060
6061 pool_->OnSSLConfigForServersChanged({HostPortPair("a", 443)});
6062
6063 // Active sockets continue to be active.
6064 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
6065 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId));
6066 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupIdPrivacy));
6067 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupIdPrivacy));
6068 ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
6069 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kOtherGroupId));
6070
6071 // Closing them leaves kOtherGroupId alone, but kGroupId and kGroupIdPrivacy
6072 // are unusable.
6073 handle1.Reset();
6074 handle2.Reset();
6075 handle3.Reset();
6076 EXPECT_EQ(1, pool_->IdleSocketCount());
6077 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId));
6078 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupIdPrivacy));
6079 EXPECT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
6080 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kOtherGroupId));
6081 }
6082
6083 } // namespace
6084
6085 } // namespace net
6086