Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(26)

Side by Side Diff: net/socket/tcp_socket_unittest.cc

Issue 1376473003: Notify NQE of TCP RTT values (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added throttle on TCP socket notifications (with tests) Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/socket/tcp_socket.h" 5 #include "net/socket/tcp_socket.h"
6 6
7 #include <stddef.h>
7 #include <string.h> 8 #include <string.h>
8 9
9 #include <string> 10 #include <string>
10 #include <vector> 11 #include <vector>
11 12
12 #include "base/memory/ref_counted.h" 13 #include "base/memory/ref_counted.h"
13 #include "base/memory/scoped_ptr.h" 14 #include "base/memory/scoped_ptr.h"
15 #include "base/test/simple_test_tick_clock.h"
16 #include "base/time/time.h"
14 #include "net/base/address_list.h" 17 #include "net/base/address_list.h"
15 #include "net/base/io_buffer.h" 18 #include "net/base/io_buffer.h"
16 #include "net/base/ip_endpoint.h" 19 #include "net/base/ip_endpoint.h"
17 #include "net/base/ip_endpoint.h" 20 #include "net/base/ip_endpoint.h"
18 #include "net/base/net_errors.h" 21 #include "net/base/net_errors.h"
19 #include "net/base/sockaddr_storage.h" 22 #include "net/base/sockaddr_storage.h"
23 #include "net/base/socket_performance_watcher.h"
20 #include "net/base/test_completion_callback.h" 24 #include "net/base/test_completion_callback.h"
21 #include "net/socket/tcp_client_socket.h" 25 #include "net/socket/tcp_client_socket.h"
22 #include "testing/gtest/include/gtest/gtest.h" 26 #include "testing/gtest/include/gtest/gtest.h"
23 #include "testing/platform_test.h" 27 #include "testing/platform_test.h"
24 28
25 namespace net { 29 namespace net {
26 30
27 namespace { 31 namespace {
32
33 class TestSocketPerformanceWatcher : public SocketPerformanceWatcher {
34 public:
35 explicit TestSocketPerformanceWatcher(bool should_notify_updated_rtt)
36 : should_notify_updated_rtt_(should_notify_updated_rtt),
37 connection_changed_count_(0u),
38 rtt_notification_count_(0u) {}
39 ~TestSocketPerformanceWatcher() override {}
40
41 bool ShouldNotifyUpdatedRTT() const override {
42 return should_notify_updated_rtt_;
43 }
44
45 void OnUpdatedRTTAvailable(const base::TimeDelta& rtt) override {
46 rtt_notification_count_++;
47 }
48
49 void OnConnectionChanged() override { connection_changed_count_++; }
50
51 size_t rtt_notification_count() const { return rtt_notification_count_; }
52
53 size_t connection_changed_count() const { return connection_changed_count_; }
54
55 private:
56 const bool should_notify_updated_rtt_;
57 size_t connection_changed_count_;
58 size_t rtt_notification_count_;
59
60 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcher);
61 };
62
28 const int kListenBacklog = 5; 63 const int kListenBacklog = 5;
29 64
30 class TCPSocketTest : public PlatformTest { 65 class TCPSocketTest : public PlatformTest {
31 protected: 66 protected:
32 TCPSocketTest() : socket_(NULL, NetLog::Source()) { 67 TCPSocketTest() : socket_(NULL, NULL, NetLog::Source()) {}
33 }
34 68
35 void SetUpListenIPv4() { 69 void SetUpListenIPv4() {
36 ASSERT_EQ(OK, socket_.Open(ADDRESS_FAMILY_IPV4)); 70 ASSERT_EQ(OK, socket_.Open(ADDRESS_FAMILY_IPV4));
37 ASSERT_EQ(OK, socket_.Bind(IPEndPoint(IPAddress::IPv4Localhost(), 0))); 71 ASSERT_EQ(OK, socket_.Bind(IPEndPoint(IPAddress::IPv4Localhost(), 0)));
38 ASSERT_EQ(OK, socket_.Listen(kListenBacklog)); 72 ASSERT_EQ(OK, socket_.Listen(kListenBacklog));
39 ASSERT_EQ(OK, socket_.GetLocalAddress(&local_address_)); 73 ASSERT_EQ(OK, socket_.GetLocalAddress(&local_address_));
40 } 74 }
41 75
42 void SetUpListenIPv6(bool* success) { 76 void SetUpListenIPv6(bool* success) {
43 *success = false; 77 *success = false;
(...skipping 11 matching lines...) Expand all
55 89
56 void TestAcceptAsync() { 90 void TestAcceptAsync() {
57 TestCompletionCallback accept_callback; 91 TestCompletionCallback accept_callback;
58 scoped_ptr<TCPSocket> accepted_socket; 92 scoped_ptr<TCPSocket> accepted_socket;
59 IPEndPoint accepted_address; 93 IPEndPoint accepted_address;
60 ASSERT_EQ(ERR_IO_PENDING, 94 ASSERT_EQ(ERR_IO_PENDING,
61 socket_.Accept(&accepted_socket, &accepted_address, 95 socket_.Accept(&accepted_socket, &accepted_address,
62 accept_callback.callback())); 96 accept_callback.callback()));
63 97
64 TestCompletionCallback connect_callback; 98 TestCompletionCallback connect_callback;
65 TCPClientSocket connecting_socket(local_address_list(), 99 TCPClientSocket connecting_socket(local_address_list(), NULL, NULL,
66 NULL, NetLog::Source()); 100 NetLog::Source());
67 connecting_socket.Connect(connect_callback.callback()); 101 connecting_socket.Connect(connect_callback.callback());
68 102
69 EXPECT_EQ(OK, connect_callback.WaitForResult()); 103 EXPECT_EQ(OK, connect_callback.WaitForResult());
70 EXPECT_EQ(OK, accept_callback.WaitForResult()); 104 EXPECT_EQ(OK, accept_callback.WaitForResult());
71 105
72 EXPECT_TRUE(accepted_socket.get()); 106 EXPECT_TRUE(accepted_socket.get());
73 107
74 // Both sockets should be on the loopback network interface. 108 // Both sockets should be on the loopback network interface.
75 EXPECT_EQ(accepted_address.address(), local_address_.address()); 109 EXPECT_EQ(accepted_address.address(), local_address_.address());
76 } 110 }
77 111
112 #if defined(TCP_INFO) || defined(OS_LINUX)
113 // Tests that notifications to Socket Performance Watcher (SPW) are delivered
114 // correctly. |advance_ticks| is the duration by which the clock is advanced
115 // before a message is read. |should_notify_updated_rtt| is true if the SPW
116 // is interested in receiving RTT notifications. |num_messages| is the number
117 // of messages that are written/read by the sockets.
118 // |expect_connection_changed_count| is the expected number of connection
119 // change notifications received by the SPW. |expect_rtt_notification_count|
120 // is the expected number of RTT notifications received by the SPW.
121 // This test works by writing |num_messages| to the socket. A different
122 // socket (with a SPW attached to it) reads the messages.
123 void TestSPWNotifications(const base::TimeDelta& advance_ticks,
124 bool should_notify_updated_rtt,
125 size_t num_messages,
126 size_t expect_connection_changed_count,
127 size_t expect_rtt_notification_count) {
128 ASSERT_NO_FATAL_FAILURE(SetUpListenIPv4());
129
130 scoped_ptr<base::SimpleTestTickClock> tick_clock(
131 new base::SimpleTestTickClock());
132 base::SimpleTestTickClock* tick_clock_ptr = tick_clock.get();
133 tick_clock_ptr->SetNowTicks(base::TimeTicks::Now());
134
135 TestCompletionCallback connect_callback;
136
137 scoped_ptr<TestSocketPerformanceWatcher> watcher(
138 new TestSocketPerformanceWatcher(should_notify_updated_rtt));
139 TestSocketPerformanceWatcher* watcher_ptr = watcher.get();
140
141 TCPSocket connecting_socket(std::move(watcher), NULL, NetLog::Source());
142 connecting_socket.SetTickClockForTesting(std::move(tick_clock));
143
144 int result = connecting_socket.Open(ADDRESS_FAMILY_IPV4);
145 ASSERT_EQ(OK, result);
146 connecting_socket.Connect(local_address_, connect_callback.callback());
Ryan Sleevi 2016/04/11 22:06:56 You never seem to check the result here? Seems lik
tbansal1 2016/04/12 16:14:33 Not sure if I understand the comment. Result is c
Ryan Sleevi 2016/04/12 21:08:31 Ah, I missed that.
tbansal1 2016/04/12 22:39:19 Acknowledged.
147
148 TestCompletionCallback accept_callback;
149 scoped_ptr<TCPSocket> accepted_socket;
150 IPEndPoint accepted_address;
151 result = socket_.Accept(&accepted_socket, &accepted_address,
152 accept_callback.callback());
153 ASSERT_EQ(OK, accept_callback.GetResult(result));
154
155 ASSERT_TRUE(accepted_socket.get());
156
157 // Both sockets should be on the loopback network interface.
158 EXPECT_EQ(accepted_address.address(), local_address_.address());
159
160 EXPECT_EQ(OK, connect_callback.WaitForResult());
Ryan Sleevi 2016/04/12 21:08:31 Should it be an ASSERT?
tbansal1 2016/04/12 22:39:19 Done.
161
162 for (size_t i = 0; i < num_messages; ++i) {
163 tick_clock_ptr->Advance(advance_ticks);
164
165 // Use a 1 byte message so that it is written and read in one attempt.
Ryan Sleevi 2016/04/11 22:06:57 There's no guarantee that this statement will appl
tbansal1 2016/04/12 16:14:34 I do not understand this comment. Is it possible
Ryan Sleevi 2016/04/12 21:08:31 It's possible that you'll get 0 bytes written with
tbansal1 2016/04/12 22:39:19 Acknowledged. I have rewritten the comment.
166 const std::string message("t");
167 std::vector<char> buffer(message.size());
Ryan Sleevi 2016/04/11 22:06:57 This just seems wasteful; why not std::vector<cha
tbansal1 2016/04/12 16:14:34 I simplified the test significantly.
168 ASSERT_EQ(1u, message.size());
Ryan Sleevi 2016/04/11 22:06:57 Seems... unnecessary?
tbansal1 2016/04/12 16:14:34 Done.
169
170 size_t bytes_written = 0;
171 scoped_refptr<IOBufferWithSize> write_buffer(
172 new IOBufferWithSize(message.size() - bytes_written));
173 memmove(write_buffer->data(), message.data() + bytes_written,
174 message.size() - bytes_written);
175
176 TestCompletionCallback write_callback;
177 int write_result = accepted_socket->Write(
178 write_buffer.get(), write_buffer->size(), write_callback.callback());
179 write_result = write_callback.GetResult(write_result);
Ryan Sleevi 2016/04/11 22:06:57 Combine write_callback.GetResult(accepted_socket->
tbansal1 2016/04/12 16:14:34 This test is similar to "ReadWrite" below. Also, w
Ryan Sleevi 2016/04/12 21:08:31 You can't assume that the underlying implementatio
tbansal1 2016/04/12 22:39:19 Thanks. I did not know that some operating systems
180 ASSERT_TRUE(write_result >= 0);
Ryan Sleevi 2016/04/11 22:06:57 ASSERT_GE
tbansal1 2016/04/12 16:14:34 Done.
181 bytes_written += write_result;
182 ASSERT_TRUE(bytes_written <= message.size());
183 ASSERT_EQ(bytes_written, message.size());
184
185 size_t bytes_read = 0;
186 scoped_refptr<IOBufferWithSize> read_buffer(
187 new IOBufferWithSize(message.size() - bytes_read));
Ryan Sleevi 2016/04/11 22:06:57 bytes_read is always 0 (see line 185)
tbansal1 2016/04/12 16:14:34 Done.
188 TestCompletionCallback read_callback;
189 int read_result = connecting_socket.Read(
190 read_buffer.get(), read_buffer->size(), read_callback.callback());
191 read_result = read_callback.GetResult(read_result);
192 ASSERT_TRUE(read_result >= 0);
Ryan Sleevi 2016/04/11 22:06:57 GE
tbansal1 2016/04/12 16:14:34 Done.
193 ASSERT_TRUE(bytes_read + read_result <= message.size());
Ryan Sleevi 2016/04/11 22:06:56 LE buffer.size()
tbansal1 2016/04/12 16:14:33 Done.
194 memmove(&buffer[bytes_read], read_buffer->data(), read_result);
Ryan Sleevi 2016/04/11 22:06:57 Seems unnecessary
tbansal1 2016/04/12 16:14:34 Done.
195 bytes_read += read_result;
Ryan Sleevi 2016/04/11 22:06:57 Seems unnecessary given the above?
tbansal1 2016/04/12 16:14:33 Done.
196 ASSERT_EQ(bytes_read, message.size());
197
198 std::string received_message(buffer.begin(), buffer.end());
Ryan Sleevi 2016/04/11 22:06:57 You copy back into a string, which is also unneces
tbansal1 2016/04/12 16:14:33 Done.
199 ASSERT_EQ(message, received_message);
200 }
201 EXPECT_EQ(expect_connection_changed_count,
202 watcher_ptr->connection_changed_count());
203 EXPECT_EQ(expect_rtt_notification_count,
204 watcher_ptr->rtt_notification_count());
205 }
206 #endif // defined(TCP_INFO) || defined(OS_LINUX)
207
78 AddressList local_address_list() const { 208 AddressList local_address_list() const {
79 return AddressList(local_address_); 209 return AddressList(local_address_);
80 } 210 }
81 211
82 TCPSocket socket_; 212 TCPSocket socket_;
83 IPEndPoint local_address_; 213 IPEndPoint local_address_;
84 }; 214 };
85 215
86 // Test listening and accepting with a socket bound to an IPv4 address. 216 // Test listening and accepting with a socket bound to an IPv4 address.
87 TEST_F(TCPSocketTest, Accept) { 217 TEST_F(TCPSocketTest, Accept) {
88 ASSERT_NO_FATAL_FAILURE(SetUpListenIPv4()); 218 ASSERT_NO_FATAL_FAILURE(SetUpListenIPv4());
89 219
90 TestCompletionCallback connect_callback; 220 TestCompletionCallback connect_callback;
91 // TODO(yzshen): Switch to use TCPSocket when it supports client socket 221 // TODO(yzshen): Switch to use TCPSocket when it supports client socket
92 // operations. 222 // operations.
93 TCPClientSocket connecting_socket(local_address_list(), 223 TCPClientSocket connecting_socket(local_address_list(), NULL, NULL,
94 NULL, NetLog::Source()); 224 NetLog::Source());
95 connecting_socket.Connect(connect_callback.callback()); 225 connecting_socket.Connect(connect_callback.callback());
96 226
97 TestCompletionCallback accept_callback; 227 TestCompletionCallback accept_callback;
98 scoped_ptr<TCPSocket> accepted_socket; 228 scoped_ptr<TCPSocket> accepted_socket;
99 IPEndPoint accepted_address; 229 IPEndPoint accepted_address;
100 int result = socket_.Accept(&accepted_socket, &accepted_address, 230 int result = socket_.Accept(&accepted_socket, &accepted_address,
101 accept_callback.callback()); 231 accept_callback.callback());
102 if (result == ERR_IO_PENDING) 232 if (result == ERR_IO_PENDING)
103 result = accept_callback.WaitForResult(); 233 result = accept_callback.WaitForResult();
104 ASSERT_EQ(OK, result); 234 ASSERT_EQ(OK, result);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 272
143 TestCompletionCallback accept_callback; 273 TestCompletionCallback accept_callback;
144 scoped_ptr<TCPSocket> accepted_socket; 274 scoped_ptr<TCPSocket> accepted_socket;
145 IPEndPoint accepted_address; 275 IPEndPoint accepted_address;
146 276
147 ASSERT_EQ(ERR_IO_PENDING, 277 ASSERT_EQ(ERR_IO_PENDING,
148 socket_.Accept(&accepted_socket, &accepted_address, 278 socket_.Accept(&accepted_socket, &accepted_address,
149 accept_callback.callback())); 279 accept_callback.callback()));
150 280
151 TestCompletionCallback connect_callback; 281 TestCompletionCallback connect_callback;
152 TCPClientSocket connecting_socket(local_address_list(), 282 TCPClientSocket connecting_socket(local_address_list(), NULL, NULL,
153 NULL, NetLog::Source()); 283 NetLog::Source());
154 connecting_socket.Connect(connect_callback.callback()); 284 connecting_socket.Connect(connect_callback.callback());
155 285
156 TestCompletionCallback connect_callback2; 286 TestCompletionCallback connect_callback2;
157 TCPClientSocket connecting_socket2(local_address_list(), 287 TCPClientSocket connecting_socket2(local_address_list(), NULL, NULL,
158 NULL, NetLog::Source()); 288 NetLog::Source());
159 connecting_socket2.Connect(connect_callback2.callback()); 289 connecting_socket2.Connect(connect_callback2.callback());
160 290
161 EXPECT_EQ(OK, accept_callback.WaitForResult()); 291 EXPECT_EQ(OK, accept_callback.WaitForResult());
162 292
163 TestCompletionCallback accept_callback2; 293 TestCompletionCallback accept_callback2;
164 scoped_ptr<TCPSocket> accepted_socket2; 294 scoped_ptr<TCPSocket> accepted_socket2;
165 IPEndPoint accepted_address2; 295 IPEndPoint accepted_address2;
166 296
167 int result = socket_.Accept(&accepted_socket2, &accepted_address2, 297 int result = socket_.Accept(&accepted_socket2, &accepted_address2,
168 accept_callback2.callback()); 298 accept_callback2.callback());
(...skipping 13 matching lines...) Expand all
182 } 312 }
183 313
184 // Test listening and accepting with a socket bound to an IPv6 address. 314 // Test listening and accepting with a socket bound to an IPv6 address.
185 TEST_F(TCPSocketTest, AcceptIPv6) { 315 TEST_F(TCPSocketTest, AcceptIPv6) {
186 bool initialized = false; 316 bool initialized = false;
187 ASSERT_NO_FATAL_FAILURE(SetUpListenIPv6(&initialized)); 317 ASSERT_NO_FATAL_FAILURE(SetUpListenIPv6(&initialized));
188 if (!initialized) 318 if (!initialized)
189 return; 319 return;
190 320
191 TestCompletionCallback connect_callback; 321 TestCompletionCallback connect_callback;
192 TCPClientSocket connecting_socket(local_address_list(), 322 TCPClientSocket connecting_socket(local_address_list(), NULL, NULL,
193 NULL, NetLog::Source()); 323 NetLog::Source());
194 connecting_socket.Connect(connect_callback.callback()); 324 connecting_socket.Connect(connect_callback.callback());
195 325
196 TestCompletionCallback accept_callback; 326 TestCompletionCallback accept_callback;
197 scoped_ptr<TCPSocket> accepted_socket; 327 scoped_ptr<TCPSocket> accepted_socket;
198 IPEndPoint accepted_address; 328 IPEndPoint accepted_address;
199 int result = socket_.Accept(&accepted_socket, &accepted_address, 329 int result = socket_.Accept(&accepted_socket, &accepted_address,
200 accept_callback.callback()); 330 accept_callback.callback());
201 if (result == ERR_IO_PENDING) 331 if (result == ERR_IO_PENDING)
202 result = accept_callback.WaitForResult(); 332 result = accept_callback.WaitForResult();
203 ASSERT_EQ(OK, result); 333 ASSERT_EQ(OK, result);
204 334
205 EXPECT_TRUE(accepted_socket.get()); 335 EXPECT_TRUE(accepted_socket.get());
206 336
207 // Both sockets should be on the loopback network interface. 337 // Both sockets should be on the loopback network interface.
208 EXPECT_EQ(accepted_address.address(), local_address_.address()); 338 EXPECT_EQ(accepted_address.address(), local_address_.address());
209 339
210 EXPECT_EQ(OK, connect_callback.WaitForResult()); 340 EXPECT_EQ(OK, connect_callback.WaitForResult());
211 } 341 }
212 342
213 TEST_F(TCPSocketTest, ReadWrite) { 343 TEST_F(TCPSocketTest, ReadWrite) {
214 ASSERT_NO_FATAL_FAILURE(SetUpListenIPv4()); 344 ASSERT_NO_FATAL_FAILURE(SetUpListenIPv4());
215 345
216 TestCompletionCallback connect_callback; 346 TestCompletionCallback connect_callback;
217 TCPSocket connecting_socket(NULL, NetLog::Source()); 347 TCPSocket connecting_socket(NULL, NULL, NetLog::Source());
218 int result = connecting_socket.Open(ADDRESS_FAMILY_IPV4); 348 int result = connecting_socket.Open(ADDRESS_FAMILY_IPV4);
219 ASSERT_EQ(OK, result); 349 ASSERT_EQ(OK, result);
220 connecting_socket.Connect(local_address_, connect_callback.callback()); 350 connecting_socket.Connect(local_address_, connect_callback.callback());
221 351
222 TestCompletionCallback accept_callback; 352 TestCompletionCallback accept_callback;
223 scoped_ptr<TCPSocket> accepted_socket; 353 scoped_ptr<TCPSocket> accepted_socket;
224 IPEndPoint accepted_address; 354 IPEndPoint accepted_address;
225 result = socket_.Accept(&accepted_socket, &accepted_address, 355 result = socket_.Accept(&accepted_socket, &accepted_address,
226 accept_callback.callback()); 356 accept_callback.callback());
227 ASSERT_EQ(OK, accept_callback.GetResult(result)); 357 ASSERT_EQ(OK, accept_callback.GetResult(result));
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 ASSERT_TRUE(read_result >= 0); 393 ASSERT_TRUE(read_result >= 0);
264 ASSERT_TRUE(bytes_read + read_result <= message.size()); 394 ASSERT_TRUE(bytes_read + read_result <= message.size());
265 memmove(&buffer[bytes_read], read_buffer->data(), read_result); 395 memmove(&buffer[bytes_read], read_buffer->data(), read_result);
266 bytes_read += read_result; 396 bytes_read += read_result;
267 } 397 }
268 398
269 std::string received_message(buffer.begin(), buffer.end()); 399 std::string received_message(buffer.begin(), buffer.end());
270 ASSERT_EQ(message, received_message); 400 ASSERT_EQ(message, received_message);
271 } 401 }
272 402
403 // These tests require kernel support for tcp_info struct, and so they are
404 // enabled only on certain platforms.
405 #if defined(TCP_INFO) || defined(OS_LINUX)
406 // If SocketPerformanceWatcher::ShouldNotifyUpdatedRTT always returns false,
407 // then the wtatcher should not receive any notifications.
408 TEST_F(TCPSocketTest, SPWNotInterested) {
409 TestSPWNotifications(base::TimeDelta::FromSeconds(0), false, 2u, 0u, 0u);
410 }
411
412 // One notification should be received when the socket connects. No additional
413 // notifications should be received when the message is read because the clock
414 // is not advanced.
415 TEST_F(TCPSocketTest, SPWNoAdvance) {
416 TestSPWNotifications(base::TimeDelta::FromSeconds(0), true, 2u, 0u, 1u);
417 }
418
419 // One notification should be received when the socket connects. One
420 // additional notification should be received for each message read since this
421 // test advances clock by 2 seconds (which is longer than the minimum interval
422 // between consecutive notifications) before every read.
423 TEST_F(TCPSocketTest, SPWAdvance) {
424 TestSPWNotifications(base::TimeDelta::FromSeconds(2), true, 2u, 0u, 3u);
425 }
426 #endif // defined(TCP_INFO) || defined(OS_LINUX)
427
273 } // namespace 428 } // namespace
274 } // namespace net 429 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698