tcp_client_socket_unittest.cc 40 KB

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