diff options
author | rtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-09 05:11:41 +0000 |
---|---|---|
committer | rtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-09 05:11:41 +0000 |
commit | d67d10528eb68753d19db1698b3688fa48fa44b3 (patch) | |
tree | 3797e452b5c689ff8da97dc9a73b775c610b07ea /net | |
parent | 785db4fe43f9b4b3ce1231dec4d723e379ed992b (diff) | |
download | chromium_src-d67d10528eb68753d19db1698b3688fa48fa44b3.zip chromium_src-d67d10528eb68753d19db1698b3688fa48fa44b3.tar.gz chromium_src-d67d10528eb68753d19db1698b3688fa48fa44b3.tar.bz2 |
Collect stats to investigate the viability of UDP
connectivity from the browser (first cut). Collect
stats for TCP connectivity also.
- What percentage of users can get a message end-to-end
to an TCP and UDP server.
- What is the latency for TCP and UDP messages.
Added TCP and UDP echo servers to testserver.py
for unittests.
BUG=82565
TEST=udp tests
Review URL: http://codereview.chromium.org/7056031
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@88495 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r-- | net/base/test_data_stream.cc | 68 | ||||
-rw-r--r-- | net/base/test_data_stream.h | 48 | ||||
-rw-r--r-- | net/curvecp/test_client.h | 2 | ||||
-rw-r--r-- | net/curvecp/test_data_stream.h | 88 | ||||
-rw-r--r-- | net/curvecp/test_server.h | 2 | ||||
-rw-r--r-- | net/net.gyp | 2 | ||||
-rw-r--r-- | net/test/test_server.cc | 8 | ||||
-rw-r--r-- | net/test/test_server.h | 2 | ||||
-rwxr-xr-x | net/tools/testserver/testserver.py | 85 |
9 files changed, 214 insertions, 91 deletions
diff --git a/net/base/test_data_stream.cc b/net/base/test_data_stream.cc new file mode 100644 index 0000000..6672804 --- /dev/null +++ b/net/base/test_data_stream.cc @@ -0,0 +1,68 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/base/test_data_stream.h" + +namespace net { + +TestDataStream::TestDataStream() { + Reset(); +} + +// Fill |buffer| with |length| bytes of data from the stream. +void TestDataStream::GetBytes(char* buffer, int length) { + while (length) { + AdvanceIndex(); + int bytes_to_copy = std::min(length, bytes_remaining_); + memcpy(buffer, buffer_ptr_, bytes_to_copy); + buffer += bytes_to_copy; + Consume(bytes_to_copy); + length -= bytes_to_copy; + } +} + +bool TestDataStream::VerifyBytes(const char *buffer, int length) { + while (length) { + AdvanceIndex(); + int bytes_to_compare = std::min(length, bytes_remaining_); + if (memcmp(buffer, buffer_ptr_, bytes_to_compare)) + return false; + Consume(bytes_to_compare); + length -= bytes_to_compare; + buffer += bytes_to_compare; + } + return true; +} + +void TestDataStream::Reset() { + index_ = 0; + bytes_remaining_ = 0; + buffer_ptr_ = buffer_; +} + +// If there is no data spilled over from the previous index, advance the +// index and fill the buffer. +void TestDataStream::AdvanceIndex() { + if (bytes_remaining_ == 0) { + // Convert it to ascii, but don't bother to reverse it. + // (e.g. 12345 becomes "54321") + int val = index_++; + do { + buffer_[bytes_remaining_++] = (val % 10) + '0'; + } while ((val /= 10) > 0); + buffer_[bytes_remaining_++] = '.'; + } +} + +// Consume data from the spill buffer. +void TestDataStream::Consume(int bytes) { + bytes_remaining_ -= bytes; + if (bytes_remaining_) + buffer_ptr_ += bytes; + else + buffer_ptr_ = buffer_; +} + +} // namespace net + diff --git a/net/base/test_data_stream.h b/net/base/test_data_stream.h new file mode 100644 index 0000000..b92a9f3 --- /dev/null +++ b/net/base/test_data_stream.h @@ -0,0 +1,48 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NET_BASE_TEST_DATA_STREAM_H_ +#define NET_BASE_TEST_DATA_STREAM_H_ +#pragma once + +#include <string.h> // for memcpy(). +#include <algorithm> +#include "net/base/net_api.h" + +// This is a class for generating an infinite stream of data which can be +// verified independently to be the correct stream of data. + +namespace net { + +class NET_API TestDataStream { + public: + TestDataStream(); + + // Fill |buffer| with |length| bytes of data from the stream. + void GetBytes(char* buffer, int length); + + // Verify that |buffer| contains the expected next |length| bytes from the + // stream. Returns true if correct, false otherwise. + bool VerifyBytes(const char *buffer, int length); + + // Resets all the data. + void Reset(); + + private: + // If there is no data spilled over from the previous index, advance the + // index and fill the buffer. + void AdvanceIndex(); + + // Consume data from the spill buffer. + void Consume(int bytes); + + int index_; + int bytes_remaining_; + char buffer_[16]; + char* buffer_ptr_; +}; + +} // namespace net + +#endif // NET_BASE_TEST_DATA_STREAM_H_ diff --git a/net/curvecp/test_client.h b/net/curvecp/test_client.h index 08f496f..e992ce8 100644 --- a/net/curvecp/test_client.h +++ b/net/curvecp/test_client.h @@ -10,7 +10,7 @@ #include "net/base/completion_callback.h" #include "net/base/host_port_pair.h" #include "net/base/io_buffer.h" -#include "net/curvecp/test_data_stream.h" +#include "net/base/test_data_stream.h" namespace net { diff --git a/net/curvecp/test_data_stream.h b/net/curvecp/test_data_stream.h deleted file mode 100644 index d2bbc87..0000000 --- a/net/curvecp/test_data_stream.h +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_CURVECP_TEST_DATA_STREAM_H_ -#define NET_CURVECP_TEST_DATA_STREAM_H_ -#pragma once - -#include <string.h> // for memcpy() -#include <algorithm> - -// This is a test class for generating an infinite stream of data which can -// be verified independently to be the correct stream of data. - -namespace net { - -class TestDataStream { - public: - TestDataStream() { - Reset(); - } - - // Fill |buffer| with |length| bytes of data from the stream. - void GetBytes(char* buffer, int length) { - while (length) { - AdvanceIndex(); - int bytes_to_copy = std::min(length, bytes_remaining_); - memcpy(buffer, buffer_ptr_, bytes_to_copy); - buffer += bytes_to_copy; - Consume(bytes_to_copy); - length -= bytes_to_copy; - } - } - - // Verify that |buffer| contains the expected next |length| bytes from the - // stream. Returns true if correct, false otherwise. - bool VerifyBytes(const char *buffer, int length) { - while (length) { - AdvanceIndex(); - int bytes_to_compare = std::min(length, bytes_remaining_); - if (memcmp(buffer, buffer_ptr_, bytes_to_compare)) - return false; - Consume(bytes_to_compare); - length -= bytes_to_compare; - buffer += bytes_to_compare; - } - return true; - } - - void Reset() { - index_ = 0; - bytes_remaining_ = 0; - buffer_ptr_ = buffer_; - } - - private: - // If there is no data spilled over from the previous index, advance the - // index and fill the buffer. - void AdvanceIndex() { - if (bytes_remaining_ == 0) { - // Convert it to ascii, but don't bother to reverse it. - // (e.g. 12345 becomes "54321") - int val = index_++; - do { - buffer_[bytes_remaining_++] = (val % 10) + '0'; - } while ((val /= 10) > 0); - buffer_[bytes_remaining_++] = '.'; - } - } - - // Consume data from the spill buffer. - void Consume(int bytes) { - bytes_remaining_ -= bytes; - if (bytes_remaining_) - buffer_ptr_ += bytes; - else - buffer_ptr_ = buffer_; - } - - int index_; - int bytes_remaining_; - char buffer_[16]; - char* buffer_ptr_; -}; - -} // namespace net - -#endif // NET_CURVECP_TEST_DATA_STREAM_H_ diff --git a/net/curvecp/test_server.h b/net/curvecp/test_server.h index 22c44e4..a941401 100644 --- a/net/curvecp/test_server.h +++ b/net/curvecp/test_server.h @@ -8,8 +8,8 @@ #include "base/task.h" #include "net/base/completion_callback.h" +#include "net/base/test_data_stream.h" #include "net/curvecp/curvecp_server_socket.h" -#include "net/curvecp/test_data_stream.h" namespace net { diff --git a/net/net.gyp b/net/net.gyp index dd23a99..63045517 100644 --- a/net/net.gyp +++ b/net/net.gyp @@ -198,6 +198,8 @@ 'base/ssl_info.h', 'base/static_cookie_policy.cc', 'base/static_cookie_policy.h', + 'base/test_data_stream.cc', + 'base/test_data_stream.h', 'base/test_root_certs.cc', 'base/test_root_certs.h', 'base/test_root_certs_mac.cc', diff --git a/net/test/test_server.cc b/net/test/test_server.cc index b6d3286..b3821bb 100644 --- a/net/test/test_server.cc +++ b/net/test/test_server.cc @@ -182,6 +182,10 @@ std::string TestServer::GetScheme() const { return "http"; case TYPE_HTTPS: return "https"; + case TYPE_TCP_ECHO: + NOTREACHED(); + case TYPE_UDP_ECHO: + NOTREACHED(); default: NOTREACHED(); } @@ -357,6 +361,10 @@ bool TestServer::AddCommandLineArguments(CommandLine* command_line) const { command_line->AppendArg("-f"); } else if (type_ == TYPE_SYNC) { command_line->AppendArg("--sync"); + } else if (type_ == TYPE_TCP_ECHO) { + command_line->AppendArg("--tcp-echo"); + } else if (type_ == TYPE_UDP_ECHO) { + command_line->AppendArg("--udp-echo"); } else if (type_ == TYPE_HTTPS) { FilePath certificate_path(certificates_dir_); certificate_path = certificate_path.Append( diff --git a/net/test/test_server.h b/net/test/test_server.h index 03a4dfc..81b0ad3 100644 --- a/net/test/test_server.h +++ b/net/test/test_server.h @@ -42,6 +42,8 @@ class TestServer { TYPE_HTTP, TYPE_HTTPS, TYPE_SYNC, + TYPE_TCP_ECHO, + TYPE_UDP_ECHO, }; // Container for various options to control how the HTTPS server is diff --git a/net/tools/testserver/testserver.py b/net/tools/testserver/testserver.py index c8fab2b..693b50b 100755 --- a/net/tools/testserver/testserver.py +++ b/net/tools/testserver/testserver.py @@ -3,7 +3,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""This is a simple HTTP server used for testing Chrome. +"""This is a simple HTTP/FTP/SYNC/TCP ECHO/UDP ECHO/ server used for testing +Chrome. It supports several test URLs, as specified by the handlers in TestPageHandler. By default, it listens on an ephemeral port and sends the port number back to @@ -52,6 +53,8 @@ if sys.platform == 'win32': SERVER_HTTP = 0 SERVER_FTP = 1 SERVER_SYNC = 2 +SERVER_TCP_ECHO = 3 +SERVER_UDP_ECHO = 4 # Using debug() seems to cause hangs on XP: see http://crbug.com/64515 . debug_output = sys.stderr @@ -209,6 +212,42 @@ class SyncHTTPServer(StoppableHTTPServer): asyncore.dispatcher.handle_expt_event) +class TCPEchoServer(SocketServer.TCPServer): + """A TCP echo server that echoes back what it has received.""" + + def server_bind(self): + """Override server_bind to store the server name.""" + SocketServer.TCPServer.server_bind(self) + host, port = self.socket.getsockname()[:2] + self.server_name = socket.getfqdn(host) + self.server_port = port + + def serve_forever(self): + self.stop = False + self.nonce_time = None + while not self.stop: + self.handle_request() + self.socket.close() + + +class UDPEchoServer(SocketServer.UDPServer): + """A UDP echo server that echoes back what it has received.""" + + def server_bind(self): + """Override server_bind to store the server name.""" + SocketServer.UDPServer.server_bind(self) + host, port = self.socket.getsockname()[:2] + self.server_name = socket.getfqdn(host) + self.server_port = port + + def serve_forever(self): + self.stop = False + self.nonce_time = None + while not self.stop: + self.handle_request() + self.socket.close() + + class BasePageHandler(BaseHTTPServer.BaseHTTPRequestHandler): def __init__(self, request, client_address, socket_server, @@ -1446,6 +1485,34 @@ def MakeDataDir(): return my_data_dir + +class TCPEchoHandler(SocketServer.BaseRequestHandler): + """The RequestHandler class for TCP echo server. + + It is instantiated once per connection to the server, and overrides the + handle() method to implement communication to the client. + """ + + def handle(self): + data = self.request.recv(65536) + if not data: + return + self.request.send(data) + + +class UDPEchoHandler(SocketServer.BaseRequestHandler): + """The RequestHandler class for UDP echo server. + + It is instantiated once per connection to the server, and overrides the + handle() method to implement communication to the client. + """ + + def handle(self): + data = self.request[0].strip() + socket = self.request[1] + socket.sendto(data, self.client_address) + + class FileMultiplexer: def __init__(self, fd1, fd2) : self.__fd1 = fd1 @@ -1509,6 +1576,14 @@ def main(options, args): print 'Sync XMPP server started on port %d...' % server.xmpp_port server_data['port'] = server.server_port server_data['xmpp_port'] = server.xmpp_port + elif options.server_type == SERVER_TCP_ECHO: + server = TCPEchoServer(('127.0.0.1', port), TCPEchoHandler) + print 'Echo TCP server started on port %d...' % server.server_port + server_data['port'] = server.server_port + elif options.server_type == SERVER_UDP_ECHO: + server = UDPEchoServer(('127.0.0.1', port), UDPEchoHandler) + print 'Echo UDP server started on port %d...' % server.server_port + server_data['port'] = server.server_port # means FTP Server else: my_data_dir = MakeDataDir() @@ -1571,6 +1646,14 @@ if __name__ == '__main__': const=SERVER_SYNC, default=SERVER_HTTP, dest='server_type', help='start up a sync server.') + option_parser.add_option('', '--tcp-echo', action='store_const', + const=SERVER_TCP_ECHO, default=SERVER_HTTP, + dest='server_type', + help='start up a tcp echo server.') + option_parser.add_option('', '--udp-echo', action='store_const', + const=SERVER_UDP_ECHO, default=SERVER_HTTP, + dest='server_type', + help='start up a udp echo server.') option_parser.add_option('', '--log-to-console', action='store_const', const=True, default=False, dest='log_to_console', |