| Index: net/udp/udp_socket_unittest.cc
|
| diff --git a/net/udp/udp_socket_unittest.cc b/net/udp/udp_socket_unittest.cc
|
| index 221be01f6312d0fc283f1ea9b02489861d7b7c11..4f902a3f0ba139c2a95f83434e3286a95f3549dc 100644
|
| --- a/net/udp/udp_socket_unittest.cc
|
| +++ b/net/udp/udp_socket_unittest.cc
|
| @@ -9,7 +9,10 @@
|
|
|
| #include "base/basictypes.h"
|
| #include "base/bind.h"
|
| +#include "base/memory/weak_ptr.h"
|
| +#include "base/message_loop/message_loop.h"
|
| #include "base/metrics/histogram.h"
|
| +#include "base/run_loop.h"
|
| #include "base/stl_util.h"
|
| #include "net/base/io_buffer.h"
|
| #include "net/base/ip_endpoint.h"
|
| @@ -27,9 +30,7 @@ namespace {
|
|
|
| class UDPSocketTest : public PlatformTest {
|
| public:
|
| - UDPSocketTest()
|
| - : buffer_(new IOBufferWithSize(kMaxRead)) {
|
| - }
|
| + UDPSocketTest() : buffer_(new IOBufferWithSize(kMaxRead)) {}
|
|
|
| // Blocks until data is read from the socket.
|
| std::string RecvFromSocket(UDPServerSocket* socket) {
|
| @@ -112,22 +113,36 @@ class UDPSocketTest : public PlatformTest {
|
| return bytes_sent;
|
| }
|
|
|
| + void WriteSocketIgnoreResult(UDPClientSocket* socket, std::string msg) {
|
| + WriteSocket(socket, msg);
|
| + }
|
| +
|
| + // Creates an address from ip address and port and writes it to |*address|.
|
| + void CreateUDPAddress(std::string ip_str, uint16 port, IPEndPoint* address) {
|
| + IPAddressNumber ip_number;
|
| + bool rv = ParseIPLiteralToNumber(ip_str, &ip_number);
|
| + if (!rv)
|
| + return;
|
| + *address = IPEndPoint(ip_number, port);
|
| + }
|
| +
|
| + // Run unit test for a connection test.
|
| + // |use_nonblocking_io| is used to switch between overlapped and non-blocking
|
| + // IO on Windows. It has no effect in other ports.
|
| + void ConnectTest(bool use_nonblocking_io);
|
| +
|
| protected:
|
| static const int kMaxRead = 1024;
|
| scoped_refptr<IOBufferWithSize> buffer_;
|
| IPEndPoint recv_from_address_;
|
| };
|
|
|
| -// Creates and address from an ip/port and returns it in |address|.
|
| -void CreateUDPAddress(std::string ip_str, uint16 port, IPEndPoint* address) {
|
| - IPAddressNumber ip_number;
|
| - bool rv = ParseIPLiteralToNumber(ip_str, &ip_number);
|
| - if (!rv)
|
| - return;
|
| - *address = IPEndPoint(ip_number, port);
|
| +void ReadCompleteCallback(int* result_out, base::Closure callback, int result) {
|
| + *result_out = result;
|
| + callback.Run();
|
| }
|
|
|
| -TEST_F(UDPSocketTest, Connect) {
|
| +void UDPSocketTest::ConnectTest(bool use_nonblocking_io) {
|
| const uint16 kPort = 9999;
|
| std::string simple_message("hello world!");
|
|
|
| @@ -137,6 +152,10 @@ TEST_F(UDPSocketTest, Connect) {
|
| CapturingNetLog server_log;
|
| scoped_ptr<UDPServerSocket> server(
|
| new UDPServerSocket(&server_log, NetLog::Source()));
|
| +#if defined(OS_WIN)
|
| + if (use_nonblocking_io)
|
| + server->UseNonBlockingIO();
|
| +#endif
|
| server->AllowAddressReuse();
|
| int rv = server->Listen(bind_address);
|
| ASSERT_EQ(OK, rv);
|
| @@ -146,10 +165,13 @@ TEST_F(UDPSocketTest, Connect) {
|
| CreateUDPAddress("127.0.0.1", kPort, &server_address);
|
| CapturingNetLog client_log;
|
| scoped_ptr<UDPClientSocket> client(
|
| - new UDPClientSocket(DatagramSocket::DEFAULT_BIND,
|
| - RandIntCallback(),
|
| - &client_log,
|
| - NetLog::Source()));
|
| + new UDPClientSocket(DatagramSocket::DEFAULT_BIND, RandIntCallback(),
|
| + &client_log, NetLog::Source()));
|
| +#if defined(OS_WIN)
|
| + if (use_nonblocking_io)
|
| + client->UseNonBlockingIO();
|
| +#endif
|
| +
|
| rv = client->Connect(server_address);
|
| EXPECT_EQ(OK, rv);
|
|
|
| @@ -169,6 +191,23 @@ TEST_F(UDPSocketTest, Connect) {
|
| str = ReadSocket(client.get());
|
| DCHECK(simple_message == str);
|
|
|
| + // Test asynchronous read. Server waits for message.
|
| + base::RunLoop run_loop;
|
| + int read_result = 0;
|
| + rv = server->RecvFrom(
|
| + buffer_.get(), kMaxRead, &recv_from_address_,
|
| + base::Bind(&ReadCompleteCallback, &read_result, run_loop.QuitClosure()));
|
| + EXPECT_EQ(ERR_IO_PENDING, rv);
|
| +
|
| + // Client sends to the server.
|
| + base::MessageLoop::current()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&UDPSocketTest::WriteSocketIgnoreResult,
|
| + base::Unretained(this), client.get(), simple_message));
|
| + run_loop.Run();
|
| + EXPECT_EQ(simple_message.length(), static_cast<size_t>(read_result));
|
| + EXPECT_EQ(simple_message, std::string(buffer_->data(), read_result));
|
| +
|
| // Delete sockets so they log their final events.
|
| server.reset();
|
| client.reset();
|
| @@ -176,33 +215,47 @@ TEST_F(UDPSocketTest, Connect) {
|
| // Check the server's log.
|
| CapturingNetLog::CapturedEntryList server_entries;
|
| server_log.GetEntries(&server_entries);
|
| - EXPECT_EQ(4u, server_entries.size());
|
| - EXPECT_TRUE(LogContainsBeginEvent(
|
| - server_entries, 0, NetLog::TYPE_SOCKET_ALIVE));
|
| + EXPECT_EQ(5u, server_entries.size());
|
| + EXPECT_TRUE(
|
| + LogContainsBeginEvent(server_entries, 0, NetLog::TYPE_SOCKET_ALIVE));
|
| EXPECT_TRUE(LogContainsEvent(
|
| server_entries, 1, NetLog::TYPE_UDP_BYTES_RECEIVED, NetLog::PHASE_NONE));
|
| + EXPECT_TRUE(LogContainsEvent(server_entries, 2, NetLog::TYPE_UDP_BYTES_SENT,
|
| + NetLog::PHASE_NONE));
|
| EXPECT_TRUE(LogContainsEvent(
|
| - server_entries, 2, NetLog::TYPE_UDP_BYTES_SENT, NetLog::PHASE_NONE));
|
| - EXPECT_TRUE(LogContainsEndEvent(
|
| - server_entries, 3, NetLog::TYPE_SOCKET_ALIVE));
|
| + server_entries, 3, NetLog::TYPE_UDP_BYTES_RECEIVED, NetLog::PHASE_NONE));
|
| + EXPECT_TRUE(
|
| + LogContainsEndEvent(server_entries, 4, NetLog::TYPE_SOCKET_ALIVE));
|
|
|
| // Check the client's log.
|
| CapturingNetLog::CapturedEntryList client_entries;
|
| client_log.GetEntries(&client_entries);
|
| - EXPECT_EQ(6u, client_entries.size());
|
| - EXPECT_TRUE(LogContainsBeginEvent(
|
| - client_entries, 0, NetLog::TYPE_SOCKET_ALIVE));
|
| - EXPECT_TRUE(LogContainsBeginEvent(
|
| - client_entries, 1, NetLog::TYPE_UDP_CONNECT));
|
| - EXPECT_TRUE(LogContainsEndEvent(
|
| - client_entries, 2, NetLog::TYPE_UDP_CONNECT));
|
| - EXPECT_TRUE(LogContainsEvent(
|
| - client_entries, 3, NetLog::TYPE_UDP_BYTES_SENT, NetLog::PHASE_NONE));
|
| + EXPECT_EQ(7u, client_entries.size());
|
| + EXPECT_TRUE(
|
| + LogContainsBeginEvent(client_entries, 0, NetLog::TYPE_SOCKET_ALIVE));
|
| + EXPECT_TRUE(
|
| + LogContainsBeginEvent(client_entries, 1, NetLog::TYPE_UDP_CONNECT));
|
| + EXPECT_TRUE(LogContainsEndEvent(client_entries, 2, NetLog::TYPE_UDP_CONNECT));
|
| + EXPECT_TRUE(LogContainsEvent(client_entries, 3, NetLog::TYPE_UDP_BYTES_SENT,
|
| + NetLog::PHASE_NONE));
|
| EXPECT_TRUE(LogContainsEvent(
|
| client_entries, 4, NetLog::TYPE_UDP_BYTES_RECEIVED, NetLog::PHASE_NONE));
|
| - EXPECT_TRUE(LogContainsEndEvent(
|
| - client_entries, 5, NetLog::TYPE_SOCKET_ALIVE));
|
| + EXPECT_TRUE(LogContainsEvent(client_entries, 5, NetLog::TYPE_UDP_BYTES_SENT,
|
| + NetLog::PHASE_NONE));
|
| + EXPECT_TRUE(
|
| + LogContainsEndEvent(client_entries, 6, NetLog::TYPE_SOCKET_ALIVE));
|
| +}
|
| +
|
| +TEST_F(UDPSocketTest, Connect) {
|
| + // The variable |use_nonblocking_io| has no effect in non-Windows ports.
|
| + ConnectTest(false);
|
| +}
|
| +
|
| +#if defined(OS_WIN)
|
| +TEST_F(UDPSocketTest, ConnectNonBlocking) {
|
| + ConnectTest(true);
|
| }
|
| +#endif
|
|
|
| #if defined(OS_MACOSX)
|
| // UDPSocketPrivate_Broadcast is disabled for OSX because it requires
|
|
|