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 // This file contains some tests for TCPClientSocket.
6 // transport_client_socket_unittest.cc contans some other tests that
7 // are common for TCP and other types of sockets.
8
9 #include "net/socket/tcp_client_socket.h"
10
11 #include <stddef.h>
12
13 #include <set>
14 #include <string>
15 #include <vector>
16
17 #include "base/strings/string_number_conversions.h"
18 #include "base/test/bind.h"
19 #include "base/test/power_monitor_test.h"
20 #include "base/test/scoped_feature_list.h"
21 #include "base/test/task_environment.h"
22 #include "build/build_config.h"
23 #include "net/base/features.h"
24 #include "net/base/ip_address.h"
25 #include "net/base/ip_endpoint.h"
26 #include "net/base/net_errors.h"
27 #include "net/base/test_completion_callback.h"
28 #include "net/log/net_log_source.h"
29 #include "net/nqe/network_quality_estimator_test_util.h"
30 #include "net/socket/socket_performance_watcher.h"
31 #include "net/socket/socket_test_util.h"
32 #include "net/socket/tcp_server_socket.h"
33 #include "net/test/embedded_test_server/embedded_test_server.h"
34 #include "net/test/gtest_util.h"
35 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
36 #include "testing/gmock/include/gmock/gmock.h"
37 #include "testing/gtest/include/gtest/gtest.h"
38
39 // This matches logic in tcp_client_socket.cc. Only used once, but defining it
40 // in this file instead of just inlining the OS checks where its used makes it
41 // more grep-able.
42 #if !BUILDFLAG(IS_ANDROID)
43 #define TCP_CLIENT_SOCKET_OBSERVES_SUSPEND
44 #endif
45
46 using net::test::IsError;
47 using net::test::IsOk;
48 using testing::Not;
49
50 namespace base {
51 class TimeDelta;
52 }
53
54 namespace net {
55
56 namespace {
57
58 class TCPClientSocketTest : public testing::Test {
59 public:
TCPClientSocketTest()60 TCPClientSocketTest()
61 : task_environment_(base::test::TaskEnvironment::MainThreadType::IO) {}
62
~TCPClientSocketTest()63 ~TCPClientSocketTest() override { base::PowerMonitor::ShutdownForTesting(); }
64
Suspend()65 void Suspend() { power_monitor_source_.Suspend(); }
Resume()66 void Resume() { power_monitor_source_.Resume(); }
67
CreateConnectedSockets(std::unique_ptr<StreamSocket> * accepted_socket,std::unique_ptr<TCPClientSocket> * client_socket,std::unique_ptr<ServerSocket> * server_socket_opt=nullptr)68 void CreateConnectedSockets(
69 std::unique_ptr<StreamSocket>* accepted_socket,
70 std::unique_ptr<TCPClientSocket>* client_socket,
71 std::unique_ptr<ServerSocket>* server_socket_opt = nullptr) {
72 IPAddress local_address = IPAddress::IPv4Localhost();
73
74 std::unique_ptr<TCPServerSocket> server_socket =
75 std::make_unique<TCPServerSocket>(nullptr, NetLogSource());
76 ASSERT_THAT(server_socket->Listen(IPEndPoint(local_address, 0), 1,
77 /*ipv6_only=*/std::nullopt),
78 IsOk());
79 IPEndPoint server_address;
80 ASSERT_THAT(server_socket->GetLocalAddress(&server_address), IsOk());
81
82 *client_socket = std::make_unique<TCPClientSocket>(
83 AddressList(server_address), nullptr, nullptr, nullptr, NetLogSource());
84
85 EXPECT_THAT((*client_socket)->Bind(IPEndPoint(local_address, 0)), IsOk());
86
87 IPEndPoint local_address_result;
88 EXPECT_THAT((*client_socket)->GetLocalAddress(&local_address_result),
89 IsOk());
90 EXPECT_EQ(local_address, local_address_result.address());
91
92 TestCompletionCallback connect_callback;
93 int connect_result = (*client_socket)->Connect(connect_callback.callback());
94
95 TestCompletionCallback accept_callback;
96 int result =
97 server_socket->Accept(accepted_socket, accept_callback.callback());
98 result = accept_callback.GetResult(result);
99 ASSERT_THAT(result, IsOk());
100
101 ASSERT_THAT(connect_callback.GetResult(connect_result), IsOk());
102
103 EXPECT_TRUE((*client_socket)->IsConnected());
104 EXPECT_TRUE((*accepted_socket)->IsConnected());
105 if (server_socket_opt)
106 *server_socket_opt = std::move(server_socket);
107 }
108
109 private:
110 base::test::TaskEnvironment task_environment_;
111 base::test::ScopedPowerMonitorTestSource power_monitor_source_;
112 };
113
114 // Try binding a socket to loopback interface and verify that we can
115 // still connect to a server on the same interface.
TEST_F(TCPClientSocketTest,BindLoopbackToLoopback)116 TEST_F(TCPClientSocketTest, BindLoopbackToLoopback) {
117 IPAddress lo_address = IPAddress::IPv4Localhost();
118
119 TCPServerSocket server(nullptr, NetLogSource());
120 ASSERT_THAT(server.Listen(IPEndPoint(lo_address, 0), 1,
121 /*ipv6_only=*/std::nullopt),
122 IsOk());
123 IPEndPoint server_address;
124 ASSERT_THAT(server.GetLocalAddress(&server_address), IsOk());
125
126 TCPClientSocket socket(AddressList(server_address), nullptr, nullptr, nullptr,
127 NetLogSource());
128
129 EXPECT_THAT(socket.Bind(IPEndPoint(lo_address, 0)), IsOk());
130
131 IPEndPoint local_address_result;
132 EXPECT_THAT(socket.GetLocalAddress(&local_address_result), IsOk());
133 EXPECT_EQ(lo_address, local_address_result.address());
134
135 TestCompletionCallback connect_callback;
136 int connect_result = socket.Connect(connect_callback.callback());
137
138 TestCompletionCallback accept_callback;
139 std::unique_ptr<StreamSocket> accepted_socket;
140 int result = server.Accept(&accepted_socket, accept_callback.callback());
141 result = accept_callback.GetResult(result);
142 ASSERT_THAT(result, IsOk());
143
144 EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
145
146 EXPECT_TRUE(socket.IsConnected());
147 socket.Disconnect();
148 EXPECT_FALSE(socket.IsConnected());
149 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
150 socket.GetLocalAddress(&local_address_result));
151 }
152
153 // Try to bind socket to the loopback interface and connect to an
154 // external address, verify that connection fails.
TEST_F(TCPClientSocketTest,BindLoopbackToExternal)155 TEST_F(TCPClientSocketTest, BindLoopbackToExternal) {
156 IPAddress external_ip(72, 14, 213, 105);
157 TCPClientSocket socket(AddressList::CreateFromIPAddress(external_ip, 80),
158 nullptr, nullptr, nullptr, NetLogSource());
159
160 EXPECT_THAT(socket.Bind(IPEndPoint(IPAddress::IPv4Localhost(), 0)), IsOk());
161
162 TestCompletionCallback connect_callback;
163 int result = socket.Connect(connect_callback.callback());
164
165 // We may get different errors here on different system, but
166 // connect() is not expected to succeed.
167 EXPECT_THAT(connect_callback.GetResult(result), Not(IsOk()));
168 }
169
170 // Bind a socket to the IPv4 loopback interface and try to connect to
171 // the IPv6 loopback interface, verify that connection fails.
TEST_F(TCPClientSocketTest,BindLoopbackToIPv6)172 TEST_F(TCPClientSocketTest, BindLoopbackToIPv6) {
173 TCPServerSocket server(nullptr, NetLogSource());
174 int listen_result =
175 server.Listen(IPEndPoint(IPAddress::IPv6Localhost(), 0), 1,
176 /*ipv6_only=*/std::nullopt);
177 if (listen_result != OK) {
178 LOG(ERROR) << "Failed to listen on ::1 - probably because IPv6 is disabled."
179 " Skipping the test";
180 return;
181 }
182
183 IPEndPoint server_address;
184 ASSERT_THAT(server.GetLocalAddress(&server_address), IsOk());
185 TCPClientSocket socket(AddressList(server_address), nullptr, nullptr, nullptr,
186 NetLogSource());
187
188 EXPECT_THAT(socket.Bind(IPEndPoint(IPAddress::IPv4Localhost(), 0)), IsOk());
189
190 TestCompletionCallback connect_callback;
191 int result = socket.Connect(connect_callback.callback());
192
193 EXPECT_THAT(connect_callback.GetResult(result), Not(IsOk()));
194 }
195
TEST_F(TCPClientSocketTest,WasEverUsed)196 TEST_F(TCPClientSocketTest, WasEverUsed) {
197 IPAddress lo_address = IPAddress::IPv4Localhost();
198 TCPServerSocket server(nullptr, NetLogSource());
199 ASSERT_THAT(
200 server.Listen(IPEndPoint(lo_address, 0), 1, /*ipv6_only=*/std::nullopt),
201 IsOk());
202 IPEndPoint server_address;
203 ASSERT_THAT(server.GetLocalAddress(&server_address), IsOk());
204
205 TCPClientSocket socket(AddressList(server_address), nullptr, nullptr, nullptr,
206 NetLogSource());
207
208 EXPECT_FALSE(socket.WasEverUsed());
209
210 EXPECT_THAT(socket.Bind(IPEndPoint(lo_address, 0)), IsOk());
211
212 // Just connecting the socket should not set WasEverUsed.
213 TestCompletionCallback connect_callback;
214 int connect_result = socket.Connect(connect_callback.callback());
215 EXPECT_FALSE(socket.WasEverUsed());
216
217 TestCompletionCallback accept_callback;
218 std::unique_ptr<StreamSocket> accepted_socket;
219 int result = server.Accept(&accepted_socket, accept_callback.callback());
220 ASSERT_THAT(accept_callback.GetResult(result), IsOk());
221 EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
222
223 EXPECT_FALSE(socket.WasEverUsed());
224 EXPECT_TRUE(socket.IsConnected());
225
226 // Writing some data to the socket _should_ set WasEverUsed.
227 const char kRequest[] = "GET / HTTP/1.0";
228 auto write_buffer = base::MakeRefCounted<StringIOBuffer>(kRequest);
229 TestCompletionCallback write_callback;
230 socket.Write(write_buffer.get(), write_buffer->size(),
231 write_callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
232 EXPECT_TRUE(socket.WasEverUsed());
233 socket.Disconnect();
234 EXPECT_FALSE(socket.IsConnected());
235
236 EXPECT_TRUE(socket.WasEverUsed());
237
238 // Re-use the socket, which should set WasEverUsed to false.
239 EXPECT_THAT(socket.Bind(IPEndPoint(lo_address, 0)), IsOk());
240 TestCompletionCallback connect_callback2;
241 connect_result = socket.Connect(connect_callback2.callback());
242 EXPECT_FALSE(socket.WasEverUsed());
243 }
244
245 // Tests that DNS aliases can be stored in a socket for reuse.
TEST_F(TCPClientSocketTest,DnsAliasesPersistForReuse)246 TEST_F(TCPClientSocketTest, DnsAliasesPersistForReuse) {
247 IPAddress lo_address = IPAddress::IPv4Localhost();
248 TCPServerSocket server(nullptr, NetLogSource());
249 ASSERT_THAT(
250 server.Listen(IPEndPoint(lo_address, 0), 1, /*ipv6_only=*/std::nullopt),
251 IsOk());
252 IPEndPoint server_address;
253 ASSERT_THAT(server.GetLocalAddress(&server_address), IsOk());
254
255 // Create a socket.
256 TCPClientSocket socket(AddressList(server_address), nullptr, nullptr, nullptr,
257 NetLogSource());
258 EXPECT_FALSE(socket.WasEverUsed());
259 EXPECT_THAT(socket.Bind(IPEndPoint(lo_address, 0)), IsOk());
260
261 // The socket's DNS aliases are unset.
262 EXPECT_TRUE(socket.GetDnsAliases().empty());
263
264 // Set the aliases.
265 std::set<std::string> dns_aliases({"alias1", "alias2", "host"});
266 socket.SetDnsAliases(dns_aliases);
267
268 // Verify that the aliases are set.
269 EXPECT_THAT(socket.GetDnsAliases(),
270 testing::UnorderedElementsAre("alias1", "alias2", "host"));
271
272 // Connect the socket.
273 TestCompletionCallback connect_callback;
274 int connect_result = socket.Connect(connect_callback.callback());
275 EXPECT_FALSE(socket.WasEverUsed());
276 TestCompletionCallback accept_callback;
277 std::unique_ptr<StreamSocket> accepted_socket;
278 int result = server.Accept(&accepted_socket, accept_callback.callback());
279 ASSERT_THAT(accept_callback.GetResult(result), IsOk());
280 EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
281 EXPECT_FALSE(socket.WasEverUsed());
282 EXPECT_TRUE(socket.IsConnected());
283
284 // Write some data to the socket to set WasEverUsed, so that the
285 // socket can be re-used.
286 const char kRequest[] = "GET / HTTP/1.0";
287 auto write_buffer = base::MakeRefCounted<StringIOBuffer>(kRequest);
288 TestCompletionCallback write_callback;
289 socket.Write(write_buffer.get(), write_buffer->size(),
290 write_callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
291 EXPECT_TRUE(socket.WasEverUsed());
292 socket.Disconnect();
293 EXPECT_FALSE(socket.IsConnected());
294 EXPECT_TRUE(socket.WasEverUsed());
295
296 // Re-use the socket, and verify that the aliases are still set.
297 EXPECT_THAT(socket.Bind(IPEndPoint(lo_address, 0)), IsOk());
298 TestCompletionCallback connect_callback2;
299 connect_result = socket.Connect(connect_callback2.callback());
300 EXPECT_FALSE(socket.WasEverUsed());
301 EXPECT_THAT(socket.GetDnsAliases(),
302 testing::ElementsAre("alias1", "alias2", "host"));
303 }
304
305 class TestSocketPerformanceWatcher : public SocketPerformanceWatcher {
306 public:
307 TestSocketPerformanceWatcher() = default;
308
309 TestSocketPerformanceWatcher(const TestSocketPerformanceWatcher&) = delete;
310 TestSocketPerformanceWatcher& operator=(const TestSocketPerformanceWatcher&) =
311 delete;
312
313 ~TestSocketPerformanceWatcher() override = default;
314
ShouldNotifyUpdatedRTT() const315 bool ShouldNotifyUpdatedRTT() const override { return true; }
316
OnUpdatedRTTAvailable(const base::TimeDelta & rtt)317 void OnUpdatedRTTAvailable(const base::TimeDelta& rtt) override {}
318
OnConnectionChanged()319 void OnConnectionChanged() override { connection_changed_count_++; }
320
connection_changed_count() const321 size_t connection_changed_count() const { return connection_changed_count_; }
322
323 private:
324 size_t connection_changed_count_ = 0u;
325 };
326
327 // TestSocketPerformanceWatcher requires kernel support for tcp_info struct, and
328 // so it is enabled only on certain platforms.
329 #if defined(TCP_INFO) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
330 #define MAYBE_TestSocketPerformanceWatcher TestSocketPerformanceWatcher
331 #else
332 #define MAYBE_TestSocketPerformanceWatcher TestSocketPerformanceWatcher
333 #endif
334 // Tests if the socket performance watcher is notified if the same socket is
335 // used for a different connection.
TEST_F(TCPClientSocketTest,MAYBE_TestSocketPerformanceWatcher)336 TEST_F(TCPClientSocketTest, MAYBE_TestSocketPerformanceWatcher) {
337 const size_t kNumIPs = 2;
338 IPAddressList ip_list;
339 for (size_t i = 0; i < kNumIPs; ++i)
340 ip_list.push_back(IPAddress(72, 14, 213, i));
341
342 auto watcher = std::make_unique<TestSocketPerformanceWatcher>();
343 TestSocketPerformanceWatcher* watcher_ptr = watcher.get();
344
345 std::vector<std::string> aliases({"example.com"});
346
347 TCPClientSocket socket(
348 AddressList::CreateFromIPAddressList(ip_list, std::move(aliases)),
349 std::move(watcher), nullptr, nullptr, NetLogSource());
350
351 EXPECT_THAT(socket.Bind(IPEndPoint(IPAddress::IPv4Localhost(), 0)), IsOk());
352
353 TestCompletionCallback connect_callback;
354
355 ASSERT_NE(OK, connect_callback.GetResult(
356 socket.Connect(connect_callback.callback())));
357
358 EXPECT_EQ(kNumIPs - 1, watcher_ptr->connection_changed_count());
359 }
360
361 // On Android, where socket tagging is supported, verify that
362 // TCPClientSocket::Tag works as expected.
363 #if BUILDFLAG(IS_ANDROID)
TEST_F(TCPClientSocketTest,Tag)364 TEST_F(TCPClientSocketTest, Tag) {
365 if (!CanGetTaggedBytes()) {
366 DVLOG(0) << "Skipping test - GetTaggedBytes unsupported.";
367 return;
368 }
369
370 // Start test server.
371 EmbeddedTestServer test_server;
372 test_server.AddDefaultHandlers(base::FilePath());
373 ASSERT_TRUE(test_server.Start());
374
375 AddressList addr_list;
376 ASSERT_TRUE(test_server.GetAddressList(&addr_list));
377 TCPClientSocket s(addr_list, nullptr, nullptr, nullptr, NetLogSource());
378
379 // Verify TCP connect packets are tagged and counted properly.
380 int32_t tag_val1 = 0x12345678;
381 uint64_t old_traffic = GetTaggedBytes(tag_val1);
382 SocketTag tag1(SocketTag::UNSET_UID, tag_val1);
383 s.ApplySocketTag(tag1);
384 TestCompletionCallback connect_callback;
385 int connect_result = s.Connect(connect_callback.callback());
386 EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
387 EXPECT_GT(GetTaggedBytes(tag_val1), old_traffic);
388
389 // Verify socket can be retagged with a new value and the current process's
390 // UID.
391 int32_t tag_val2 = 0x87654321;
392 old_traffic = GetTaggedBytes(tag_val2);
393 SocketTag tag2(getuid(), tag_val2);
394 s.ApplySocketTag(tag2);
395 const char kRequest1[] = "GET / HTTP/1.0";
396 auto write_buffer1 = base::MakeRefCounted<StringIOBuffer>(kRequest1);
397 TestCompletionCallback write_callback1;
398 EXPECT_EQ(s.Write(write_buffer1.get(), strlen(kRequest1),
399 write_callback1.callback(), TRAFFIC_ANNOTATION_FOR_TESTS),
400 static_cast<int>(strlen(kRequest1)));
401 EXPECT_GT(GetTaggedBytes(tag_val2), old_traffic);
402
403 // Verify socket can be retagged with a new value and the current process's
404 // UID.
405 old_traffic = GetTaggedBytes(tag_val1);
406 s.ApplySocketTag(tag1);
407 const char kRequest2[] = "\n\n";
408 scoped_refptr<IOBufferWithSize> write_buffer2 =
409 base::MakeRefCounted<IOBufferWithSize>(strlen(kRequest2));
410 memmove(write_buffer2->data(), kRequest2, strlen(kRequest2));
411 TestCompletionCallback write_callback2;
412 EXPECT_EQ(s.Write(write_buffer2.get(), strlen(kRequest2),
413 write_callback2.callback(), TRAFFIC_ANNOTATION_FOR_TESTS),
414 static_cast<int>(strlen(kRequest2)));
415 EXPECT_GT(GetTaggedBytes(tag_val1), old_traffic);
416
417 s.Disconnect();
418 }
419
TEST_F(TCPClientSocketTest,TagAfterConnect)420 TEST_F(TCPClientSocketTest, TagAfterConnect) {
421 if (!CanGetTaggedBytes()) {
422 DVLOG(0) << "Skipping test - GetTaggedBytes unsupported.";
423 return;
424 }
425
426 // Start test server.
427 EmbeddedTestServer test_server;
428 test_server.AddDefaultHandlers(base::FilePath());
429 ASSERT_TRUE(test_server.Start());
430
431 AddressList addr_list;
432 ASSERT_TRUE(test_server.GetAddressList(&addr_list));
433 TCPClientSocket s(addr_list, nullptr, nullptr, nullptr, NetLogSource());
434
435 // Connect socket.
436 TestCompletionCallback connect_callback;
437 int connect_result = s.Connect(connect_callback.callback());
438 EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
439
440 // Verify socket can be tagged with a new value and the current process's
441 // UID.
442 int32_t tag_val2 = 0x87654321;
443 uint64_t old_traffic = GetTaggedBytes(tag_val2);
444 SocketTag tag2(getuid(), tag_val2);
445 s.ApplySocketTag(tag2);
446 const char kRequest1[] = "GET / HTTP/1.0";
447 auto write_buffer1 = base::MakeRefCounted<StringIOBuffer>(kRequest1);
448 TestCompletionCallback write_callback1;
449 EXPECT_EQ(s.Write(write_buffer1.get(), strlen(kRequest1),
450 write_callback1.callback(), TRAFFIC_ANNOTATION_FOR_TESTS),
451 static_cast<int>(strlen(kRequest1)));
452 EXPECT_GT(GetTaggedBytes(tag_val2), old_traffic);
453
454 // Verify socket can be retagged with a new value and the current process's
455 // UID.
456 int32_t tag_val1 = 0x12345678;
457 old_traffic = GetTaggedBytes(tag_val1);
458 SocketTag tag1(SocketTag::UNSET_UID, tag_val1);
459 s.ApplySocketTag(tag1);
460 const char kRequest2[] = "\n\n";
461 auto write_buffer2 = base::MakeRefCounted<StringIOBuffer>(kRequest2);
462 TestCompletionCallback write_callback2;
463 EXPECT_EQ(s.Write(write_buffer2.get(), strlen(kRequest2),
464 write_callback2.callback(), TRAFFIC_ANNOTATION_FOR_TESTS),
465 static_cast<int>(strlen(kRequest2)));
466 EXPECT_GT(GetTaggedBytes(tag_val1), old_traffic);
467
468 s.Disconnect();
469 }
470 #endif // BUILDFLAG(IS_ANDROID)
471
472 // TCP socket that hangs indefinitely when establishing a connection.
473 class NeverConnectingTCPClientSocket : public TCPClientSocket {
474 public:
NeverConnectingTCPClientSocket(const AddressList & addresses,std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher,NetworkQualityEstimator * network_quality_estimator,net::NetLog * net_log,const net::NetLogSource & source)475 NeverConnectingTCPClientSocket(
476 const AddressList& addresses,
477 std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher,
478 NetworkQualityEstimator* network_quality_estimator,
479 net::NetLog* net_log,
480 const net::NetLogSource& source)
481 : TCPClientSocket(addresses,
482 std::move(socket_performance_watcher),
483 network_quality_estimator,
484 net_log,
485 source) {}
486
487 // Returns the number of times that ConnectInternal() was called.
connect_internal_counter() const488 int connect_internal_counter() const { return connect_internal_counter_; }
489
490 private:
ConnectInternal(const IPEndPoint & endpoint)491 int ConnectInternal(const IPEndPoint& endpoint) override {
492 connect_internal_counter_++;
493 return ERR_IO_PENDING;
494 }
495
496 int connect_internal_counter_ = 0;
497 };
498
499 // Tests for closing sockets on suspend mode.
500 #if defined(TCP_CLIENT_SOCKET_OBSERVES_SUSPEND)
501
502 // Entering suspend mode shouldn't affect sockets that haven't connected yet, or
503 // listening server sockets.
TEST_F(TCPClientSocketTest,SuspendBeforeConnect)504 TEST_F(TCPClientSocketTest, SuspendBeforeConnect) {
505 IPAddress lo_address = IPAddress::IPv4Localhost();
506
507 TCPServerSocket server(nullptr, NetLogSource());
508 ASSERT_THAT(
509 server.Listen(IPEndPoint(lo_address, 0), 1, /*ipv6_only=*/std::nullopt),
510 IsOk());
511 IPEndPoint server_address;
512 ASSERT_THAT(server.GetLocalAddress(&server_address), IsOk());
513
514 TCPClientSocket socket(AddressList(server_address), nullptr, nullptr, nullptr,
515 NetLogSource());
516
517 EXPECT_THAT(socket.Bind(IPEndPoint(lo_address, 0)), IsOk());
518
519 IPEndPoint local_address_result;
520 EXPECT_THAT(socket.GetLocalAddress(&local_address_result), IsOk());
521 EXPECT_EQ(lo_address, local_address_result.address());
522
523 TestCompletionCallback accept_callback;
524 std::unique_ptr<StreamSocket> accepted_socket;
525 ASSERT_THAT(server.Accept(&accepted_socket, accept_callback.callback()),
526 IsError(ERR_IO_PENDING));
527
528 Suspend();
529 // Power notifications happen asynchronously, so have to wait for the socket
530 // to be notified of the suspend event.
531 base::RunLoop().RunUntilIdle();
532
533 TestCompletionCallback connect_callback;
534 int connect_result = socket.Connect(connect_callback.callback());
535
536 ASSERT_THAT(accept_callback.WaitForResult(), IsOk());
537
538 ASSERT_THAT(connect_callback.GetResult(connect_result), IsOk());
539
540 EXPECT_TRUE(socket.IsConnected());
541 EXPECT_TRUE(accepted_socket->IsConnected());
542 }
543
TEST_F(TCPClientSocketTest,SuspendDuringConnect)544 TEST_F(TCPClientSocketTest, SuspendDuringConnect) {
545 IPAddress lo_address = IPAddress::IPv4Localhost();
546
547 TCPServerSocket server(nullptr, NetLogSource());
548 ASSERT_THAT(
549 server.Listen(IPEndPoint(lo_address, 0), 1, /*ipv6_only=*/std::nullopt),
550 IsOk());
551 IPEndPoint server_address;
552 ASSERT_THAT(server.GetLocalAddress(&server_address), IsOk());
553
554 NeverConnectingTCPClientSocket socket(AddressList(server_address), nullptr,
555 nullptr, nullptr, NetLogSource());
556
557 EXPECT_THAT(socket.Bind(IPEndPoint(lo_address, 0)), IsOk());
558
559 IPEndPoint local_address_result;
560 EXPECT_THAT(socket.GetLocalAddress(&local_address_result), IsOk());
561 EXPECT_EQ(lo_address, local_address_result.address());
562
563 TestCompletionCallback connect_callback;
564 int rv = socket.Connect(connect_callback.callback());
565 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
566 Suspend();
567 EXPECT_THAT(connect_callback.WaitForResult(),
568 IsError(ERR_NETWORK_IO_SUSPENDED));
569 }
570
TEST_F(TCPClientSocketTest,SuspendDuringConnectMultipleAddresses)571 TEST_F(TCPClientSocketTest, SuspendDuringConnectMultipleAddresses) {
572 IPAddress lo_address = IPAddress::IPv4Localhost();
573
574 TCPServerSocket server(nullptr, NetLogSource());
575 ASSERT_THAT(server.Listen(IPEndPoint(IPAddress(0, 0, 0, 0), 0), 1,
576 /*ipv6_only=*/std::nullopt),
577 IsOk());
578 IPEndPoint server_address;
579 ASSERT_THAT(server.GetLocalAddress(&server_address), IsOk());
580
581 AddressList address_list;
582 address_list.push_back(
583 IPEndPoint(IPAddress(127, 0, 0, 1), server_address.port()));
584 address_list.push_back(
585 IPEndPoint(IPAddress(127, 0, 0, 2), server_address.port()));
586 NeverConnectingTCPClientSocket socket(address_list, nullptr, nullptr, nullptr,
587 NetLogSource());
588
589 EXPECT_THAT(socket.Bind(IPEndPoint(lo_address, 0)), IsOk());
590
591 IPEndPoint local_address_result;
592 EXPECT_THAT(socket.GetLocalAddress(&local_address_result), IsOk());
593 EXPECT_EQ(lo_address, local_address_result.address());
594
595 TestCompletionCallback connect_callback;
596 int rv = socket.Connect(connect_callback.callback());
597 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
598 Suspend();
599 EXPECT_THAT(connect_callback.WaitForResult(),
600 IsError(ERR_NETWORK_IO_SUSPENDED));
601 }
602
TEST_F(TCPClientSocketTest,SuspendWhileIdle)603 TEST_F(TCPClientSocketTest, SuspendWhileIdle) {
604 std::unique_ptr<StreamSocket> accepted_socket;
605 std::unique_ptr<TCPClientSocket> client_socket;
606 std::unique_ptr<ServerSocket> server_socket;
607 CreateConnectedSockets(&accepted_socket, &client_socket, &server_socket);
608
609 Suspend();
610 // Power notifications happen asynchronously.
611 base::RunLoop().RunUntilIdle();
612
613 auto buffer = base::MakeRefCounted<IOBufferWithSize>(1);
614 buffer->data()[0] = '1';
615 TestCompletionCallback callback;
616 // Check that the client socket is disconnected, and actions fail with
617 // ERR_NETWORK_IO_SUSPENDED.
618 EXPECT_FALSE(client_socket->IsConnected());
619 EXPECT_THAT(client_socket->Read(buffer.get(), 1, callback.callback()),
620 IsError(ERR_NETWORK_IO_SUSPENDED));
621 EXPECT_THAT(client_socket->Write(buffer.get(), 1, callback.callback(),
622 TRAFFIC_ANNOTATION_FOR_TESTS),
623 IsError(ERR_NETWORK_IO_SUSPENDED));
624
625 // Check that the accepted socket is disconnected, and actions fail with
626 // ERR_NETWORK_IO_SUSPENDED.
627 EXPECT_FALSE(accepted_socket->IsConnected());
628 EXPECT_THAT(accepted_socket->Read(buffer.get(), 1, callback.callback()),
629 IsError(ERR_NETWORK_IO_SUSPENDED));
630 EXPECT_THAT(accepted_socket->Write(buffer.get(), 1, callback.callback(),
631 TRAFFIC_ANNOTATION_FOR_TESTS),
632 IsError(ERR_NETWORK_IO_SUSPENDED));
633
634 // Reconnecting the socket should work.
635 TestCompletionCallback connect_callback;
636 int connect_result = client_socket->Connect(connect_callback.callback());
637 accepted_socket.reset();
638 TestCompletionCallback accept_callback;
639 int accept_result =
640 server_socket->Accept(&accepted_socket, accept_callback.callback());
641 ASSERT_THAT(accept_callback.GetResult(accept_result), IsOk());
642 EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
643 }
644
TEST_F(TCPClientSocketTest,SuspendDuringRead)645 TEST_F(TCPClientSocketTest, SuspendDuringRead) {
646 std::unique_ptr<StreamSocket> accepted_socket;
647 std::unique_ptr<TCPClientSocket> client_socket;
648 CreateConnectedSockets(&accepted_socket, &client_socket);
649
650 // Start a read. This shouldn't complete, since the other end of the pipe
651 // writes no data.
652 auto read_buffer = base::MakeRefCounted<IOBufferWithSize>(1);
653 read_buffer->data()[0] = '1';
654 TestCompletionCallback callback;
655 ASSERT_THAT(client_socket->Read(read_buffer.get(), 1, callback.callback()),
656 IsError(ERR_IO_PENDING));
657
658 // Simulate a suspend event. Can't use a real power event, as it would affect
659 // |accepted_socket| as well.
660 client_socket->OnSuspend();
661 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NETWORK_IO_SUSPENDED));
662
663 // Check that the client socket really is disconnected.
664 EXPECT_FALSE(client_socket->IsConnected());
665 EXPECT_THAT(client_socket->Read(read_buffer.get(), 1, callback.callback()),
666 IsError(ERR_NETWORK_IO_SUSPENDED));
667 EXPECT_THAT(client_socket->Write(read_buffer.get(), 1, callback.callback(),
668 TRAFFIC_ANNOTATION_FOR_TESTS),
669 IsError(ERR_NETWORK_IO_SUSPENDED));
670 }
671
TEST_F(TCPClientSocketTest,SuspendDuringWrite)672 TEST_F(TCPClientSocketTest, SuspendDuringWrite) {
673 std::unique_ptr<StreamSocket> accepted_socket;
674 std::unique_ptr<TCPClientSocket> client_socket;
675 CreateConnectedSockets(&accepted_socket, &client_socket);
676
677 // Write to the socket until a write doesn't complete synchronously.
678 const int kBufferSize = 4096;
679 auto write_buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
680 memset(write_buffer->data(), '1', kBufferSize);
681 TestCompletionCallback callback;
682 while (true) {
683 int rv =
684 client_socket->Write(write_buffer.get(), kBufferSize,
685 callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
686 if (rv == ERR_IO_PENDING)
687 break;
688 ASSERT_GT(rv, 0);
689 }
690
691 // Simulate a suspend event. Can't use a real power event, as it would affect
692 // |accepted_socket| as well.
693 client_socket->OnSuspend();
694 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NETWORK_IO_SUSPENDED));
695
696 // Check that the client socket really is disconnected.
697 EXPECT_FALSE(client_socket->IsConnected());
698 EXPECT_THAT(client_socket->Read(write_buffer.get(), 1, callback.callback()),
699 IsError(ERR_NETWORK_IO_SUSPENDED));
700 EXPECT_THAT(client_socket->Write(write_buffer.get(), 1, callback.callback(),
701 TRAFFIC_ANNOTATION_FOR_TESTS),
702 IsError(ERR_NETWORK_IO_SUSPENDED));
703 }
704
TEST_F(TCPClientSocketTest,SuspendDuringReadAndWrite)705 TEST_F(TCPClientSocketTest, SuspendDuringReadAndWrite) {
706 enum class ReadCallbackAction {
707 kNone,
708 kDestroySocket,
709 kDisconnectSocket,
710 kReconnectSocket,
711 };
712
713 for (ReadCallbackAction read_callback_action : {
714 ReadCallbackAction::kNone,
715 ReadCallbackAction::kDestroySocket,
716 ReadCallbackAction::kDisconnectSocket,
717 ReadCallbackAction::kReconnectSocket,
718 }) {
719 std::unique_ptr<StreamSocket> accepted_socket;
720 std::unique_ptr<TCPClientSocket> client_socket;
721 std::unique_ptr<ServerSocket> server_socket;
722 CreateConnectedSockets(&accepted_socket, &client_socket, &server_socket);
723
724 // Start a read. This shouldn't complete, since the other end of the pipe
725 // writes no data.
726 auto read_buffer = base::MakeRefCounted<IOBufferWithSize>(1);
727 read_buffer->data()[0] = '1';
728 TestCompletionCallback read_callback;
729
730 // Used int the ReadCallbackAction::kReconnectSocket case, since can't run a
731 // nested message loop in the read callback.
732 TestCompletionCallback nested_connect_callback;
733 int nested_connect_result;
734
735 CompletionOnceCallback read_completion_once_callback =
736 base::BindLambdaForTesting([&](int result) {
737 EXPECT_FALSE(client_socket->IsConnected());
738 switch (read_callback_action) {
739 case ReadCallbackAction::kNone:
740 break;
741 case ReadCallbackAction::kDestroySocket:
742 client_socket.reset();
743 break;
744 case ReadCallbackAction::kDisconnectSocket:
745 client_socket->Disconnect();
746 break;
747 case ReadCallbackAction::kReconnectSocket: {
748 TestCompletionCallback connect_callback;
749 nested_connect_result =
750 client_socket->Connect(nested_connect_callback.callback());
751 break;
752 }
753 }
754 read_callback.callback().Run(result);
755 });
756 ASSERT_THAT(client_socket->Read(read_buffer.get(), 1,
757 std::move(read_completion_once_callback)),
758 IsError(ERR_IO_PENDING));
759
760 // Write to the socket until a write doesn't complete synchronously.
761 const int kBufferSize = 4096;
762 auto write_buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
763 memset(write_buffer->data(), '1', kBufferSize);
764 TestCompletionCallback write_callback;
765 while (true) {
766 int rv = client_socket->Write(write_buffer.get(), kBufferSize,
767 write_callback.callback(),
768 TRAFFIC_ANNOTATION_FOR_TESTS);
769 if (rv == ERR_IO_PENDING)
770 break;
771 ASSERT_GT(rv, 0);
772 }
773
774 // Simulate a suspend event. Can't use a real power event, as it would
775 // affect |accepted_socket| as well.
776 client_socket->OnSuspend();
777 EXPECT_THAT(read_callback.WaitForResult(),
778 IsError(ERR_NETWORK_IO_SUSPENDED));
779 if (read_callback_action == ReadCallbackAction::kNone) {
780 EXPECT_THAT(write_callback.WaitForResult(),
781 IsError(ERR_NETWORK_IO_SUSPENDED));
782
783 // Check that the client socket really is disconnected.
784 EXPECT_FALSE(client_socket->IsConnected());
785 EXPECT_THAT(
786 client_socket->Read(read_buffer.get(), 1, read_callback.callback()),
787 IsError(ERR_NETWORK_IO_SUSPENDED));
788 EXPECT_THAT(
789 client_socket->Write(write_buffer.get(), 1, write_callback.callback(),
790 TRAFFIC_ANNOTATION_FOR_TESTS),
791 IsError(ERR_NETWORK_IO_SUSPENDED));
792 } else {
793 // Each of the actions taken in the read callback will cancel the pending
794 // write callback.
795 EXPECT_FALSE(write_callback.have_result());
796 }
797
798 if (read_callback_action == ReadCallbackAction::kReconnectSocket) {
799 // Finish establishing a connection, just to make sure the reconnect case
800 // completely works.
801 accepted_socket.reset();
802 TestCompletionCallback accept_callback;
803 int accept_result =
804 server_socket->Accept(&accepted_socket, accept_callback.callback());
805 ASSERT_THAT(accept_callback.GetResult(accept_result), IsOk());
806 EXPECT_THAT(nested_connect_callback.GetResult(nested_connect_result),
807 IsOk());
808 }
809 }
810 }
811
812 #endif // defined(TCP_CLIENT_SOCKET_OBSERVES_SUSPEND)
813
814 // Scoped helper to override the TCP connect attempt policy.
815 class OverrideTcpConnectAttemptTimeout {
816 public:
OverrideTcpConnectAttemptTimeout(double rtt_multipilier,base::TimeDelta min_timeout,base::TimeDelta max_timeout)817 OverrideTcpConnectAttemptTimeout(double rtt_multipilier,
818 base::TimeDelta min_timeout,
819 base::TimeDelta max_timeout) {
820 base::FieldTrialParams params;
821 params[features::kTimeoutTcpConnectAttemptRTTMultiplier.name] =
822 base::NumberToString(rtt_multipilier);
823 params[features::kTimeoutTcpConnectAttemptMin.name] =
824 base::NumberToString(min_timeout.InMilliseconds()) + "ms";
825 params[features::kTimeoutTcpConnectAttemptMax.name] =
826 base::NumberToString(max_timeout.InMilliseconds()) + "ms";
827
828 scoped_feature_list_.InitAndEnableFeatureWithParameters(
829 features::kTimeoutTcpConnectAttempt, params);
830 }
831
832 private:
833 base::test::ScopedFeatureList scoped_feature_list_;
834 };
835
836 // Test fixture that uses a MOCK_TIME test environment, so time can
837 // be advanced programmatically.
838 class TCPClientSocketMockTimeTest : public testing::Test {
839 public:
TCPClientSocketMockTimeTest()840 TCPClientSocketMockTimeTest()
841 : task_environment_(base::test::TaskEnvironment::MainThreadType::IO,
842 base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
843
844 protected:
845 base::test::TaskEnvironment task_environment_;
846 };
847
848 // Tests that no TCP connect timeout is enforced by default (i.e.
849 // when the feature is disabled).
TEST_F(TCPClientSocketMockTimeTest,NoConnectAttemptTimeoutByDefault)850 TEST_F(TCPClientSocketMockTimeTest, NoConnectAttemptTimeoutByDefault) {
851 IPEndPoint server_address(IPAddress::IPv4Localhost(), 80);
852 NeverConnectingTCPClientSocket socket(AddressList(server_address), nullptr,
853 nullptr, nullptr, NetLogSource());
854
855 TestCompletionCallback connect_callback;
856 int rv = socket.Connect(connect_callback.callback());
857 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
858
859 // After 4 minutes, the socket should still be connecting.
860 task_environment_.FastForwardBy(base::Minutes(4));
861 EXPECT_FALSE(connect_callback.have_result());
862 EXPECT_FALSE(socket.IsConnected());
863
864 // 1 attempt was made.
865 EXPECT_EQ(1, socket.connect_internal_counter());
866 }
867
868 // Tests that the maximum timeout is used when there is no estimated
869 // RTT.
TEST_F(TCPClientSocketMockTimeTest,ConnectAttemptTimeoutUsesMaxWhenNoRTT)870 TEST_F(TCPClientSocketMockTimeTest, ConnectAttemptTimeoutUsesMaxWhenNoRTT) {
871 OverrideTcpConnectAttemptTimeout override_timeout(1, base::Seconds(4),
872 base::Seconds(10));
873
874 IPEndPoint server_address(IPAddress::IPv4Localhost(), 80);
875
876 // Pass a null NetworkQualityEstimator, so the TCPClientSocket is unable to
877 // estimate the RTT.
878 NeverConnectingTCPClientSocket socket(AddressList(server_address), nullptr,
879 nullptr, nullptr, NetLogSource());
880
881 // Start connecting.
882 TestCompletionCallback connect_callback;
883 int rv = socket.Connect(connect_callback.callback());
884 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
885
886 // Advance to t=3.1s
887 // Should still be pending, as this is before the minimum timeout.
888 task_environment_.FastForwardBy(base::Milliseconds(3100));
889 EXPECT_FALSE(connect_callback.have_result());
890 EXPECT_FALSE(socket.IsConnected());
891
892 // Advance to t=4.1s
893 // Should still be pending. This is after the minimum timeout, but before the
894 // maximum.
895 task_environment_.FastForwardBy(base::Seconds(1));
896 EXPECT_FALSE(connect_callback.have_result());
897 EXPECT_FALSE(socket.IsConnected());
898
899 // Advance to t=10.1s
900 // Should now be timed out, as this is after the maximum timeout.
901 task_environment_.FastForwardBy(base::Seconds(6));
902 rv = connect_callback.GetResult(rv);
903 ASSERT_THAT(rv, IsError(ERR_TIMED_OUT));
904
905 // 1 attempt was made.
906 EXPECT_EQ(1, socket.connect_internal_counter());
907 }
908
909 // Tests that the minimum timeout is used when the adaptive timeout using RTT
910 // ends up being too low.
TEST_F(TCPClientSocketMockTimeTest,ConnectAttemptTimeoutUsesMinWhenRTTLow)911 TEST_F(TCPClientSocketMockTimeTest, ConnectAttemptTimeoutUsesMinWhenRTTLow) {
912 OverrideTcpConnectAttemptTimeout override_timeout(5, base::Seconds(4),
913 base::Seconds(10));
914
915 // Set the estimated RTT to 1 millisecond.
916 TestNetworkQualityEstimator network_quality_estimator;
917 network_quality_estimator.SetStartTimeNullTransportRtt(base::Milliseconds(1));
918
919 IPEndPoint server_address(IPAddress::IPv4Localhost(), 80);
920
921 NeverConnectingTCPClientSocket socket(AddressList(server_address), nullptr,
922 &network_quality_estimator, nullptr,
923 NetLogSource());
924
925 // Start connecting.
926 TestCompletionCallback connect_callback;
927 int rv = socket.Connect(connect_callback.callback());
928 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
929
930 // Advance to t=1.1s
931 // Should be pending, since although the adaptive timeout has been reached, it
932 // is lower than the minimum timeout.
933 task_environment_.FastForwardBy(base::Milliseconds(1100));
934 EXPECT_FALSE(connect_callback.have_result());
935 EXPECT_FALSE(socket.IsConnected());
936
937 // Advance to t=4.1s
938 // Should have timed out due to hitting the minimum timeout.
939 task_environment_.FastForwardBy(base::Seconds(3));
940 rv = connect_callback.GetResult(rv);
941 ASSERT_THAT(rv, IsError(ERR_TIMED_OUT));
942
943 // 1 attempt was made.
944 EXPECT_EQ(1, socket.connect_internal_counter());
945 }
946
947 // Tests that the maximum timeout is used when the adaptive timeout from RTT is
948 // too high.
TEST_F(TCPClientSocketMockTimeTest,ConnectAttemptTimeoutUsesMinWhenRTTHigh)949 TEST_F(TCPClientSocketMockTimeTest, ConnectAttemptTimeoutUsesMinWhenRTTHigh) {
950 OverrideTcpConnectAttemptTimeout override_timeout(5, base::Seconds(4),
951 base::Seconds(10));
952
953 // Set the estimated RTT to 5 seconds.
954 TestNetworkQualityEstimator network_quality_estimator;
955 network_quality_estimator.SetStartTimeNullTransportRtt(base::Seconds(5));
956
957 IPEndPoint server_address(IPAddress::IPv4Localhost(), 80);
958
959 NeverConnectingTCPClientSocket socket(AddressList(server_address), nullptr,
960 &network_quality_estimator, nullptr,
961 NetLogSource());
962
963 // Start connecting.
964 TestCompletionCallback connect_callback;
965 int rv = socket.Connect(connect_callback.callback());
966 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
967
968 // Advance to t=10.1s
969 // The socket should have timed out due to hitting the maximum timeout. Had
970 // the adaptive timeout been used, the socket would instead be timing out at
971 // t=25s.
972 task_environment_.FastForwardBy(base::Milliseconds(10100));
973 rv = connect_callback.GetResult(rv);
974 ASSERT_THAT(rv, IsError(ERR_TIMED_OUT));
975
976 // 1 attempt was made.
977 EXPECT_EQ(1, socket.connect_internal_counter());
978 }
979
980 // Tests that an adaptive timeout is used for TCP connection attempts based on
981 // the estimated RTT.
TEST_F(TCPClientSocketMockTimeTest,ConnectAttemptTimeoutUsesRTT)982 TEST_F(TCPClientSocketMockTimeTest, ConnectAttemptTimeoutUsesRTT) {
983 OverrideTcpConnectAttemptTimeout override_timeout(5, base::Seconds(4),
984 base::Seconds(10));
985
986 // Set the estimated RTT to 1 second. Since the multiplier is set to 5, the
987 // total adaptive timeout will be 5 seconds.
988 TestNetworkQualityEstimator network_quality_estimator;
989 network_quality_estimator.SetStartTimeNullTransportRtt(base::Seconds(1));
990
991 IPEndPoint server_address(IPAddress::IPv4Localhost(), 80);
992
993 NeverConnectingTCPClientSocket socket(AddressList(server_address), nullptr,
994 &network_quality_estimator, nullptr,
995 NetLogSource());
996
997 // Start connecting.
998 TestCompletionCallback connect_callback;
999 int rv = socket.Connect(connect_callback.callback());
1000 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
1001
1002 // Advance to t=4.1s
1003 // The socket should still be pending. Had the minimum timeout been enforced,
1004 // it would instead have timed out now.
1005 task_environment_.FastForwardBy(base::Milliseconds(4100));
1006 EXPECT_FALSE(connect_callback.have_result());
1007 EXPECT_FALSE(socket.IsConnected());
1008
1009 // Advance to t=5.1s
1010 // The adaptive timeout was at t=5s, so it should now be timed out.
1011 task_environment_.FastForwardBy(base::Seconds(1));
1012 rv = connect_callback.GetResult(rv);
1013 ASSERT_THAT(rv, IsError(ERR_TIMED_OUT));
1014
1015 // 1 attempt was made.
1016 EXPECT_EQ(1, socket.connect_internal_counter());
1017 }
1018
1019 // Tests that when multiple TCP connect attempts are made, the timeout for each
1020 // one is applied independently.
TEST_F(TCPClientSocketMockTimeTest,ConnectAttemptTimeoutIndependent)1021 TEST_F(TCPClientSocketMockTimeTest, ConnectAttemptTimeoutIndependent) {
1022 OverrideTcpConnectAttemptTimeout override_timeout(5, base::Seconds(4),
1023 base::Seconds(10));
1024
1025 // This test will attempt connecting to 5 endpoints.
1026 const size_t kNumIps = 5;
1027
1028 AddressList addresses;
1029 for (size_t i = 0; i < kNumIps; ++i)
1030 addresses.push_back(IPEndPoint(IPAddress::IPv4Localhost(), 80 + i));
1031
1032 NeverConnectingTCPClientSocket socket(addresses, nullptr, nullptr, nullptr,
1033 NetLogSource());
1034
1035 // Start connecting.
1036 TestCompletionCallback connect_callback;
1037 int rv = socket.Connect(connect_callback.callback());
1038 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
1039
1040 // Advance to t=49s
1041 // Should still be pending.
1042 task_environment_.FastForwardBy(base::Seconds(49));
1043 EXPECT_FALSE(connect_callback.have_result());
1044 EXPECT_FALSE(socket.IsConnected());
1045
1046 // Advance to t=50.1s
1047 // All attempts should take 50 seconds to complete (5 attempts, 10 seconds
1048 // each). So by this point the overall connect attempt will have timed out.
1049 task_environment_.FastForwardBy(base::Milliseconds(1100));
1050 rv = connect_callback.GetResult(rv);
1051 ASSERT_THAT(rv, IsError(ERR_TIMED_OUT));
1052
1053 // 5 attempts were made.
1054 EXPECT_EQ(5, socket.connect_internal_counter());
1055 }
1056
1057 } // namespace
1058
1059 } // namespace net
1060