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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: net/socket/tcp_socket_unittest.cc
diff --git a/net/socket/tcp_socket_unittest.cc b/net/socket/tcp_socket_unittest.cc
index 15f935516739d3716d9d146fbb0bdbf8cd9ca0ea..60753f449da2b6fd0aa36209fa8bb67e243b60b8 100644
--- a/net/socket/tcp_socket_unittest.cc
+++ b/net/socket/tcp_socket_unittest.cc
@@ -4,6 +4,7 @@
#include "net/socket/tcp_socket.h"
+#include <stddef.h>
#include <string.h>
#include <string>
@@ -11,12 +12,15 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
+#include "base/test/simple_test_tick_clock.h"
+#include "base/time/time.h"
#include "net/base/address_list.h"
#include "net/base/io_buffer.h"
#include "net/base/ip_endpoint.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
#include "net/base/sockaddr_storage.h"
+#include "net/base/socket_performance_watcher.h"
#include "net/base/test_completion_callback.h"
#include "net/socket/tcp_client_socket.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -25,12 +29,42 @@
namespace net {
namespace {
+
+class TestSocketPerformanceWatcher : public SocketPerformanceWatcher {
+ public:
+ explicit TestSocketPerformanceWatcher(bool should_notify_updated_rtt)
+ : should_notify_updated_rtt_(should_notify_updated_rtt),
+ connection_changed_count_(0u),
+ rtt_notification_count_(0u) {}
+ ~TestSocketPerformanceWatcher() override {}
+
+ bool ShouldNotifyUpdatedRTT() const override {
+ return should_notify_updated_rtt_;
+ }
+
+ void OnUpdatedRTTAvailable(const base::TimeDelta& rtt) override {
+ rtt_notification_count_++;
+ }
+
+ void OnConnectionChanged() override { connection_changed_count_++; }
+
+ size_t rtt_notification_count() const { return rtt_notification_count_; }
+
+ size_t connection_changed_count() const { return connection_changed_count_; }
+
+ private:
+ const bool should_notify_updated_rtt_;
+ size_t connection_changed_count_;
+ size_t rtt_notification_count_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcher);
+};
+
const int kListenBacklog = 5;
class TCPSocketTest : public PlatformTest {
protected:
- TCPSocketTest() : socket_(NULL, NetLog::Source()) {
- }
+ TCPSocketTest() : socket_(NULL, NULL, NetLog::Source()) {}
void SetUpListenIPv4() {
ASSERT_EQ(OK, socket_.Open(ADDRESS_FAMILY_IPV4));
@@ -62,8 +96,8 @@ class TCPSocketTest : public PlatformTest {
accept_callback.callback()));
TestCompletionCallback connect_callback;
- TCPClientSocket connecting_socket(local_address_list(),
- NULL, NetLog::Source());
+ TCPClientSocket connecting_socket(local_address_list(), NULL, NULL,
+ NetLog::Source());
connecting_socket.Connect(connect_callback.callback());
EXPECT_EQ(OK, connect_callback.WaitForResult());
@@ -75,6 +109,102 @@ class TCPSocketTest : public PlatformTest {
EXPECT_EQ(accepted_address.address(), local_address_.address());
}
+#if defined(TCP_INFO) || defined(OS_LINUX)
+ // Tests that notifications to Socket Performance Watcher (SPW) are delivered
+ // correctly. |advance_ticks| is the duration by which the clock is advanced
+ // before a message is read. |should_notify_updated_rtt| is true if the SPW
+ // is interested in receiving RTT notifications. |num_messages| is the number
+ // of messages that are written/read by the sockets.
+ // |expect_connection_changed_count| is the expected number of connection
+ // change notifications received by the SPW. |expect_rtt_notification_count|
+ // is the expected number of RTT notifications received by the SPW.
+ // This test works by writing |num_messages| to the socket. A different
+ // socket (with a SPW attached to it) reads the messages.
+ void TestSPWNotifications(const base::TimeDelta& advance_ticks,
+ bool should_notify_updated_rtt,
+ size_t num_messages,
+ size_t expect_connection_changed_count,
+ size_t expect_rtt_notification_count) {
+ ASSERT_NO_FATAL_FAILURE(SetUpListenIPv4());
+
+ scoped_ptr<base::SimpleTestTickClock> tick_clock(
+ new base::SimpleTestTickClock());
+ base::SimpleTestTickClock* tick_clock_ptr = tick_clock.get();
+ tick_clock_ptr->SetNowTicks(base::TimeTicks::Now());
+
+ TestCompletionCallback connect_callback;
+
+ scoped_ptr<TestSocketPerformanceWatcher> watcher(
+ new TestSocketPerformanceWatcher(should_notify_updated_rtt));
+ TestSocketPerformanceWatcher* watcher_ptr = watcher.get();
+
+ TCPSocket connecting_socket(std::move(watcher), NULL, NetLog::Source());
+ connecting_socket.SetTickClockForTesting(std::move(tick_clock));
+
+ int result = connecting_socket.Open(ADDRESS_FAMILY_IPV4);
+ ASSERT_EQ(OK, result);
+ 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.
+
+ TestCompletionCallback accept_callback;
+ scoped_ptr<TCPSocket> accepted_socket;
+ IPEndPoint accepted_address;
+ result = socket_.Accept(&accepted_socket, &accepted_address,
+ accept_callback.callback());
+ ASSERT_EQ(OK, accept_callback.GetResult(result));
+
+ ASSERT_TRUE(accepted_socket.get());
+
+ // Both sockets should be on the loopback network interface.
+ EXPECT_EQ(accepted_address.address(), local_address_.address());
+
+ 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.
+
+ for (size_t i = 0; i < num_messages; ++i) {
+ tick_clock_ptr->Advance(advance_ticks);
+
+ // 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.
+ const std::string message("t");
+ 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.
+ ASSERT_EQ(1u, message.size());
Ryan Sleevi 2016/04/11 22:06:57 Seems... unnecessary?
tbansal1 2016/04/12 16:14:34 Done.
+
+ size_t bytes_written = 0;
+ scoped_refptr<IOBufferWithSize> write_buffer(
+ new IOBufferWithSize(message.size() - bytes_written));
+ memmove(write_buffer->data(), message.data() + bytes_written,
+ message.size() - bytes_written);
+
+ TestCompletionCallback write_callback;
+ int write_result = accepted_socket->Write(
+ write_buffer.get(), write_buffer->size(), write_callback.callback());
+ 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
+ ASSERT_TRUE(write_result >= 0);
Ryan Sleevi 2016/04/11 22:06:57 ASSERT_GE
tbansal1 2016/04/12 16:14:34 Done.
+ bytes_written += write_result;
+ ASSERT_TRUE(bytes_written <= message.size());
+ ASSERT_EQ(bytes_written, message.size());
+
+ size_t bytes_read = 0;
+ scoped_refptr<IOBufferWithSize> read_buffer(
+ 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.
+ TestCompletionCallback read_callback;
+ int read_result = connecting_socket.Read(
+ read_buffer.get(), read_buffer->size(), read_callback.callback());
+ read_result = read_callback.GetResult(read_result);
+ ASSERT_TRUE(read_result >= 0);
Ryan Sleevi 2016/04/11 22:06:57 GE
tbansal1 2016/04/12 16:14:34 Done.
+ 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.
+ 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.
+ 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.
+ ASSERT_EQ(bytes_read, message.size());
+
+ 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.
+ ASSERT_EQ(message, received_message);
+ }
+ EXPECT_EQ(expect_connection_changed_count,
+ watcher_ptr->connection_changed_count());
+ EXPECT_EQ(expect_rtt_notification_count,
+ watcher_ptr->rtt_notification_count());
+ }
+#endif // defined(TCP_INFO) || defined(OS_LINUX)
+
AddressList local_address_list() const {
return AddressList(local_address_);
}
@@ -90,8 +220,8 @@ TEST_F(TCPSocketTest, Accept) {
TestCompletionCallback connect_callback;
// TODO(yzshen): Switch to use TCPSocket when it supports client socket
// operations.
- TCPClientSocket connecting_socket(local_address_list(),
- NULL, NetLog::Source());
+ TCPClientSocket connecting_socket(local_address_list(), NULL, NULL,
+ NetLog::Source());
connecting_socket.Connect(connect_callback.callback());
TestCompletionCallback accept_callback;
@@ -149,13 +279,13 @@ TEST_F(TCPSocketTest, Accept2Connections) {
accept_callback.callback()));
TestCompletionCallback connect_callback;
- TCPClientSocket connecting_socket(local_address_list(),
- NULL, NetLog::Source());
+ TCPClientSocket connecting_socket(local_address_list(), NULL, NULL,
+ NetLog::Source());
connecting_socket.Connect(connect_callback.callback());
TestCompletionCallback connect_callback2;
- TCPClientSocket connecting_socket2(local_address_list(),
- NULL, NetLog::Source());
+ TCPClientSocket connecting_socket2(local_address_list(), NULL, NULL,
+ NetLog::Source());
connecting_socket2.Connect(connect_callback2.callback());
EXPECT_EQ(OK, accept_callback.WaitForResult());
@@ -189,8 +319,8 @@ TEST_F(TCPSocketTest, AcceptIPv6) {
return;
TestCompletionCallback connect_callback;
- TCPClientSocket connecting_socket(local_address_list(),
- NULL, NetLog::Source());
+ TCPClientSocket connecting_socket(local_address_list(), NULL, NULL,
+ NetLog::Source());
connecting_socket.Connect(connect_callback.callback());
TestCompletionCallback accept_callback;
@@ -214,7 +344,7 @@ TEST_F(TCPSocketTest, ReadWrite) {
ASSERT_NO_FATAL_FAILURE(SetUpListenIPv4());
TestCompletionCallback connect_callback;
- TCPSocket connecting_socket(NULL, NetLog::Source());
+ TCPSocket connecting_socket(NULL, NULL, NetLog::Source());
int result = connecting_socket.Open(ADDRESS_FAMILY_IPV4);
ASSERT_EQ(OK, result);
connecting_socket.Connect(local_address_, connect_callback.callback());
@@ -270,5 +400,30 @@ TEST_F(TCPSocketTest, ReadWrite) {
ASSERT_EQ(message, received_message);
}
+// These tests require kernel support for tcp_info struct, and so they are
+// enabled only on certain platforms.
+#if defined(TCP_INFO) || defined(OS_LINUX)
+// If SocketPerformanceWatcher::ShouldNotifyUpdatedRTT always returns false,
+// then the wtatcher should not receive any notifications.
+TEST_F(TCPSocketTest, SPWNotInterested) {
+ TestSPWNotifications(base::TimeDelta::FromSeconds(0), false, 2u, 0u, 0u);
+}
+
+// One notification should be received when the socket connects. No additional
+// notifications should be received when the message is read because the clock
+// is not advanced.
+TEST_F(TCPSocketTest, SPWNoAdvance) {
+ TestSPWNotifications(base::TimeDelta::FromSeconds(0), true, 2u, 0u, 1u);
+}
+
+// One notification should be received when the socket connects. One
+// additional notification should be received for each message read since this
+// test advances clock by 2 seconds (which is longer than the minimum interval
+// between consecutive notifications) before every read.
+TEST_F(TCPSocketTest, SPWAdvance) {
+ TestSPWNotifications(base::TimeDelta::FromSeconds(2), true, 2u, 0u, 3u);
+}
+#endif // defined(TCP_INFO) || defined(OS_LINUX)
+
} // namespace
} // namespace net

Powered by Google App Engine
This is Rietveld 408576698