summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authorsergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-23 02:06:54 +0000
committersergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-23 02:06:54 +0000
commitc7a132fad4caf6b7389e5ccbb7c4ca5ed0bb1a54 (patch)
treeadd1bf99e82fc25c6177b84ce928ce0fb363a336 /content
parentbdecc3ed22954279b41659121aa69ec29589a46d (diff)
downloadchromium_src-c7a132fad4caf6b7389e5ccbb7c4ca5ed0bb1a54.zip
chromium_src-c7a132fad4caf6b7389e5ccbb7c4ca5ed0bb1a54.tar.gz
chromium_src-c7a132fad4caf6b7389e5ccbb7c4ca5ed0bb1a54.tar.bz2
Unittests for P2P TCP Sockets Host.
BUG=None TEST=Unittests Review URL: http://codereview.chromium.org/6883054 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@82771 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r--content/browser/renderer_host/p2p/socket_host.h2
-rw-r--r--content/browser/renderer_host/p2p/socket_host_tcp.h3
-rw-r--r--content/browser/renderer_host/p2p/socket_host_tcp_server.h6
-rw-r--r--content/browser/renderer_host/p2p/socket_host_tcp_server_unittest.cc161
-rw-r--r--content/browser/renderer_host/p2p/socket_host_tcp_unittest.cc167
-rw-r--r--content/browser/renderer_host/p2p/socket_host_test_utils.h240
-rw-r--r--content/browser/renderer_host/p2p/socket_host_udp_unittest.cc99
7 files changed, 593 insertions, 85 deletions
diff --git a/content/browser/renderer_host/p2p/socket_host.h b/content/browser/renderer_host/p2p/socket_host.h
index 76699d5..b78a7f9 100644
--- a/content/browser/renderer_host/p2p/socket_host.h
+++ b/content/browser/renderer_host/p2p/socket_host.h
@@ -31,6 +31,8 @@ class P2PSocketHost {
const net::IPEndPoint& remote_address, int id) = 0;
protected:
+ friend class P2PSocketHostTcpTest;
+
enum StunMessageType {
STUN_BINDING_REQUEST = 0x0001,
STUN_BINDING_RESPONSE = 0x0101,
diff --git a/content/browser/renderer_host/p2p/socket_host_tcp.h b/content/browser/renderer_host/p2p/socket_host_tcp.h
index 917e622..01a9861 100644
--- a/content/browser/renderer_host/p2p/socket_host_tcp.h
+++ b/content/browser/renderer_host/p2p/socket_host_tcp.h
@@ -38,6 +38,9 @@ class P2PSocketHostTcp : public P2PSocketHost {
const net::IPEndPoint& remote_address, int id) OVERRIDE;
private:
+ friend class P2PSocketHostTcpTest;
+ friend class P2PSocketHostTcpServerTest;
+
void OnError();
void DoRead();
diff --git a/content/browser/renderer_host/p2p/socket_host_tcp_server.h b/content/browser/renderer_host/p2p/socket_host_tcp_server.h
index d0b7268..7bafa76 100644
--- a/content/browser/renderer_host/p2p/socket_host_tcp_server.h
+++ b/content/browser/renderer_host/p2p/socket_host_tcp_server.h
@@ -21,7 +21,7 @@ class ClientSocket;
class P2PSocketHostTcpServer : public P2PSocketHost {
public:
P2PSocketHostTcpServer(IPC::Message::Sender* message_sender,
- int routing_id, int id);
+ int routing_id, int id);
virtual ~P2PSocketHostTcpServer();
// P2PSocketHost overrides.
@@ -33,6 +33,8 @@ class P2PSocketHostTcpServer : public P2PSocketHost {
const net::IPEndPoint& remote_address, int id) OVERRIDE;
private:
+ friend class P2PSocketHostTcpServerTest;
+
typedef std::map<net::IPEndPoint, net::ClientSocket*> AcceptedSocketsMap;
void OnError();
@@ -43,7 +45,7 @@ class P2PSocketHostTcpServer : public P2PSocketHost {
// Callback for Accept().
void OnAccepted(int result);
- scoped_ptr<net::TCPServerSocket> socket_;
+ scoped_ptr<net::ServerSocket> socket_;
net::IPEndPoint local_address_;
scoped_ptr<net::ClientSocket> accept_socket_;
diff --git a/content/browser/renderer_host/p2p/socket_host_tcp_server_unittest.cc b/content/browser/renderer_host/p2p/socket_host_tcp_server_unittest.cc
new file mode 100644
index 0000000..e8eb51a
--- /dev/null
+++ b/content/browser/renderer_host/p2p/socket_host_tcp_server_unittest.cc
@@ -0,0 +1,161 @@
+// 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 "content/browser/renderer_host/p2p/socket_host_tcp_server.h"
+
+#include "content/browser/renderer_host/p2p/socket_host_tcp.h"
+#include "content/browser/renderer_host/p2p/socket_host_test_utils.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using ::testing::_;
+using ::testing::DeleteArg;
+using ::testing::DoAll;
+using ::testing::Return;
+
+namespace {
+
+class FakeServerSocket : public net::ServerSocket {
+ public:
+ FakeServerSocket()
+ : listening_(false),
+ accept_socket_(NULL),
+ accept_callback_(NULL) {
+ }
+
+ ~FakeServerSocket() { }
+
+ bool listening() { return listening_; }
+
+ void AddIncoming(net::ClientSocket* socket) {
+ if (accept_callback_) {
+ DCHECK(incoming_sockets_.empty());
+ accept_socket_->reset(socket);
+ accept_socket_ = NULL;
+ net::CompletionCallback* cb = accept_callback_;
+ accept_callback_ = NULL;
+ cb->Run(net::OK);
+ } else {
+ incoming_sockets_.push_back(socket);
+ }
+ }
+
+ // net::ServerSocket implementation.
+ virtual int Listen(const net::IPEndPoint& address, int backlog) OVERRIDE {
+ local_address_ = address;
+ listening_ = true;
+ return net::OK;
+ }
+
+ virtual int GetLocalAddress(net::IPEndPoint* address) const OVERRIDE {
+ *address = local_address_;
+ return net::OK;
+ }
+
+ virtual int Accept(scoped_ptr<net::ClientSocket>* socket,
+ net::CompletionCallback* callback) OVERRIDE {
+ DCHECK(socket);
+ if (!incoming_sockets_.empty()) {
+ socket->reset(incoming_sockets_.front());
+ incoming_sockets_.pop_front();
+ return net::OK;
+ } else {
+ accept_socket_ = socket;
+ accept_callback_ = callback;
+ return net::ERR_IO_PENDING;
+ }
+ }
+
+ private:
+ bool listening_;
+
+ net::IPEndPoint local_address_;
+
+ scoped_ptr<net::ClientSocket>* accept_socket_;
+ net::CompletionCallback* accept_callback_;
+
+ std::list<net::ClientSocket*> incoming_sockets_;
+};
+
+} // namespace
+
+class P2PSocketHostTcpServerTest : public testing::Test {
+ protected:
+ virtual void SetUp() OVERRIDE {
+ socket_ = new FakeServerSocket();
+ socket_host_.reset(new P2PSocketHostTcpServer(&sender_, 0, 0));
+ socket_host_->socket_.reset(socket_);
+
+ EXPECT_CALL(sender_, Send(
+ MatchMessage(static_cast<uint32>(P2PMsg_OnSocketCreated::ID))))
+ .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
+
+ socket_host_->Init(ParseAddress(kTestLocalIpAddress, 0),
+ ParseAddress(kTestIpAddress1, kTestPort1));
+ EXPECT_TRUE(socket_->listening());
+ }
+
+ // Needed by the chilt classes because only this class is a friend
+ // of P2PSocketHostTcp.
+ net::ClientSocket* GetSocketFormTcpSocketHost(P2PSocketHostTcp* host) {
+ return host->socket_.get();
+ }
+
+ MockIPCSender sender_;
+ FakeServerSocket* socket_; // Owned by |socket_host_|.
+ scoped_ptr<P2PSocketHostTcpServer> socket_host_;
+};
+
+// Accept incoming connection.
+TEST_F(P2PSocketHostTcpServerTest, Accept) {
+ FakeSocket* incoming = new FakeSocket(NULL);
+ incoming->SetLocalAddress(ParseAddress(kTestLocalIpAddress, kTestPort1));
+ net::IPEndPoint addr = ParseAddress(kTestIpAddress1, kTestPort1);
+ incoming->SetPeerAddress(addr);
+
+ EXPECT_CALL(sender_, Send(MatchIncomingSocketMessage(addr)))
+ .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
+ socket_->AddIncoming(incoming);
+
+ const int kAcceptedSocketId = 1;
+
+ scoped_ptr<P2PSocketHost> new_host(
+ socket_host_->AcceptIncomingTcpConnection(addr, kAcceptedSocketId));
+ ASSERT_TRUE(new_host.get() != NULL);
+ EXPECT_EQ(incoming, GetSocketFormTcpSocketHost(
+ reinterpret_cast<P2PSocketHostTcp*>(new_host.get())));
+}
+
+// Accept 2 simultaneous connections.
+TEST_F(P2PSocketHostTcpServerTest, Accept2) {
+ FakeSocket* incoming1 = new FakeSocket(NULL);
+ incoming1->SetLocalAddress(ParseAddress(kTestLocalIpAddress, kTestPort1));
+ net::IPEndPoint addr1 = ParseAddress(kTestIpAddress1, kTestPort1);
+ incoming1->SetPeerAddress(addr1);
+ FakeSocket* incoming2 = new FakeSocket(NULL);
+ incoming2->SetLocalAddress(ParseAddress(kTestLocalIpAddress, kTestPort1));
+ net::IPEndPoint addr2 = ParseAddress(kTestIpAddress2, kTestPort2);
+ incoming2->SetPeerAddress(addr2);
+
+ EXPECT_CALL(sender_, Send(MatchIncomingSocketMessage(addr1)))
+ .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
+ EXPECT_CALL(sender_, Send(MatchIncomingSocketMessage(addr2)))
+ .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
+ socket_->AddIncoming(incoming1);
+ socket_->AddIncoming(incoming2);
+
+ const int kAcceptedSocketId1 = 1;
+ const int kAcceptedSocketId2 = 2;
+
+ scoped_ptr<P2PSocketHost> new_host1(
+ socket_host_->AcceptIncomingTcpConnection(addr1, kAcceptedSocketId1));
+ ASSERT_TRUE(new_host1.get() != NULL);
+ EXPECT_EQ(incoming1, GetSocketFormTcpSocketHost(
+ reinterpret_cast<P2PSocketHostTcp*>(new_host1.get())));
+ scoped_ptr<P2PSocketHost> new_host2(
+ socket_host_->AcceptIncomingTcpConnection(addr2, kAcceptedSocketId2));
+ ASSERT_TRUE(new_host2.get() != NULL);
+ EXPECT_EQ(incoming2, GetSocketFormTcpSocketHost(
+ reinterpret_cast<P2PSocketHostTcp*>(new_host2.get())));
+}
diff --git a/content/browser/renderer_host/p2p/socket_host_tcp_unittest.cc b/content/browser/renderer_host/p2p/socket_host_tcp_unittest.cc
new file mode 100644
index 0000000..af118f1
--- /dev/null
+++ b/content/browser/renderer_host/p2p/socket_host_tcp_unittest.cc
@@ -0,0 +1,167 @@
+// 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 "content/browser/renderer_host/p2p/socket_host_tcp.h"
+
+#include <deque>
+
+#include "content/browser/renderer_host/p2p/socket_host_test_utils.h"
+#include "net/base/sys_byteorder.h"
+#include "net/socket/client_socket.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using ::testing::_;
+using ::testing::DeleteArg;
+using ::testing::DoAll;
+using ::testing::Return;
+
+class P2PSocketHostTcpTest : public testing::Test {
+ protected:
+ virtual void SetUp() OVERRIDE {
+ EXPECT_CALL(sender_, Send(
+ MatchMessage(static_cast<uint32>(P2PMsg_OnSocketCreated::ID))))
+ .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
+
+ socket_host_.reset(new P2PSocketHostTcp(&sender_, 0, 0));
+ socket_ = new FakeSocket(&sent_data_);
+ socket_->SetLocalAddress(ParseAddress(kTestLocalIpAddress, kTestPort1));
+ socket_host_->socket_.reset(socket_);
+
+ dest_ = ParseAddress(kTestIpAddress1, kTestPort1);
+
+ local_address_ = ParseAddress(kTestLocalIpAddress, kTestPort1);
+
+ socket_host_->remote_address_ = dest_;
+ socket_host_->state_ = P2PSocketHost::STATE_CONNECTING;
+ socket_host_->OnConnected(net::OK);
+ }
+
+ std::string IntToSize(int size) {
+ std::string result;
+ uint16 size16 = htons(size);
+ result.resize(sizeof(size16));
+ memcpy(&result[0], &size16, sizeof(size16));
+ return result;
+ }
+
+ std::string sent_data_;
+ FakeSocket* socket_; // Owned by |socket_host_|.
+ scoped_ptr<P2PSocketHostTcp> socket_host_;
+ MockIPCSender sender_;
+
+ net::IPEndPoint local_address_;
+
+ net::IPEndPoint dest_;
+ net::IPEndPoint dest2_;
+};
+
+// Verify that we can send STUN message and that they are formatted
+// properly.
+TEST_F(P2PSocketHostTcpTest, SendStunNoAuth) {
+ std::vector<char> packet1;
+ CreateStunRequest(&packet1);
+ socket_host_->Send(dest_, packet1);
+
+ std::vector<char> packet2;
+ CreateStunResponse(&packet2);
+ socket_host_->Send(dest_, packet2);
+
+ std::vector<char> packet3;
+ CreateStunError(&packet3);
+ socket_host_->Send(dest_, packet3);
+
+ std::string expected_data;
+ expected_data.append(IntToSize(packet1.size()));
+ expected_data.append(packet1.begin(), packet1.end());
+ expected_data.append(IntToSize(packet2.size()));
+ expected_data.append(packet2.begin(), packet2.end());
+ expected_data.append(IntToSize(packet3.size()));
+ expected_data.append(packet3.begin(), packet3.end());
+
+ EXPECT_EQ(expected_data, sent_data_);
+}
+
+// Verify that we can receive STUN messages from the socket, and that
+// the messages are parsed properly.
+TEST_F(P2PSocketHostTcpTest, ReceiveStun) {
+ std::vector<char> packet1;
+ CreateStunRequest(&packet1);
+ socket_host_->Send(dest_, packet1);
+
+ std::vector<char> packet2;
+ CreateStunResponse(&packet2);
+ socket_host_->Send(dest_, packet2);
+
+ std::vector<char> packet3;
+ CreateStunError(&packet3);
+ socket_host_->Send(dest_, packet3);
+
+ std::string received_data;
+ received_data.append(IntToSize(packet1.size()));
+ received_data.append(packet1.begin(), packet1.end());
+ received_data.append(IntToSize(packet2.size()));
+ received_data.append(packet2.begin(), packet2.end());
+ received_data.append(IntToSize(packet3.size()));
+ received_data.append(packet3.begin(), packet3.end());
+
+ EXPECT_CALL(sender_, Send(MatchPacketMessage(packet1)))
+ .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
+ EXPECT_CALL(sender_, Send(MatchPacketMessage(packet2)))
+ .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
+ EXPECT_CALL(sender_, Send(MatchPacketMessage(packet3)))
+ .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
+
+ size_t pos = 0;
+ size_t step_sizes[] = {3, 2, 1};
+ size_t step = 0;
+ while (pos < received_data.size()) {
+ size_t step_size = std::min(step_sizes[step], received_data.size() - pos);
+ socket_->AppendInputData(&received_data[pos], step_size);
+ pos += step_size;
+ if (++step >= arraysize(step_sizes))
+ step = 0;
+ }
+}
+
+// Verify that we can't send data before we've received STUN response
+// from the other side.
+TEST_F(P2PSocketHostTcpTest, SendDataNoAuth) {
+ EXPECT_CALL(sender_, Send(
+ MatchMessage(static_cast<uint32>(P2PMsg_OnError::ID))))
+ .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
+
+ std::vector<char> packet;
+ CreateRandomPacket(&packet);
+ socket_host_->Send(dest_, packet);
+
+ EXPECT_EQ(0U, sent_data_.size());
+}
+
+// Verify that we can send data after we've received STUN response
+// from the other side.
+TEST_F(P2PSocketHostTcpTest, SendAfterStunRequest) {
+ // Receive packet from |dest_|.
+ std::vector<char> request_packet;
+ CreateStunRequest(&request_packet);
+
+ std::string received_data;
+ received_data.append(IntToSize(request_packet.size()));
+ received_data.append(request_packet.begin(), request_packet.end());
+
+ EXPECT_CALL(sender_, Send(MatchPacketMessage(request_packet)))
+ .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
+ socket_->AppendInputData(&received_data[0], received_data.size());
+
+ // Now we should be able to send any data to |dest_|.
+ std::vector<char> packet;
+ CreateRandomPacket(&packet);
+ socket_host_->Send(dest_, packet);
+
+ std::string expected_data;
+ expected_data.append(IntToSize(packet.size()));
+ expected_data.append(packet.begin(), packet.end());
+
+ EXPECT_EQ(expected_data, sent_data_);
+}
diff --git a/content/browser/renderer_host/p2p/socket_host_test_utils.h b/content/browser/renderer_host/p2p/socket_host_test_utils.h
new file mode 100644
index 0000000..1db590c
--- /dev/null
+++ b/content/browser/renderer_host/p2p/socket_host_test_utils.h
@@ -0,0 +1,240 @@
+// 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 CONTENT_BROWSER_RENDERER_HOST_P2P_SOCKET_HOST_TEST_UTILS_H_
+#define CONTENT_BROWSER_RENDERER_HOST_P2P_SOCKET_HOST_TEST_UTILS_H_
+
+#include <vector>
+
+#include "content/common/p2p_messages.h"
+#include "ipc/ipc_message.h"
+#include "ipc/ipc_message_utils.h"
+#include "net/base/address_list.h"
+#include "net/base/completion_callback.h"
+#include "net/base/io_buffer.h"
+#include "net/base/net_errors.h"
+#include "net/base/sys_byteorder.h"
+#include "net/socket/client_socket.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+const char kTestLocalIpAddress[] = "123.44.22.4";
+const char kTestIpAddress1[] = "123.44.22.31";
+const int kTestPort1 = 234;
+const char kTestIpAddress2[] = "133.11.22.33";
+const int kTestPort2 = 543;
+
+const int kStunHeaderSize = 20;
+const uint16 kStunBindingRequest = 0x0001;
+const uint16 kStunBindingResponse = 0x0102;
+const uint16 kStunBindingError = 0x0111;
+const uint32 kStunMagicCookie = 0x2112A442;
+
+class MockIPCSender : public IPC::Message::Sender {
+ public:
+ MOCK_METHOD1(Send, bool(IPC::Message* msg));
+};
+
+class FakeSocket : public net::ClientSocket {
+ public:
+ FakeSocket(std::string* written_data)
+ : read_pending_(false),
+ written_data_(written_data),
+ input_pos_(0) {
+ }
+ virtual ~FakeSocket() { }
+
+ void AppendInputData(const char* data, int data_size) {
+ input_data_.insert(input_data_.end(), data, data + data_size);
+ // Complete pending read if any.
+ if (read_pending_) {
+ read_pending_ = false;
+ int result = std::min(read_buffer_size_,
+ static_cast<int>(input_data_.size() - input_pos_));
+ CHECK(result > 0);
+ memcpy(read_buffer_->data(), &input_data_[0] + input_pos_, result);
+ input_pos_ += result;
+ read_buffer_ = NULL;
+ net::CompletionCallback* cb = read_callback_;
+ read_callback_ = NULL;
+ cb->Run(result);
+ }
+ }
+ int input_pos() const { return input_pos_; }
+ bool read_pending() const { return read_pending_; }
+
+ void SetPeerAddress(const net::IPEndPoint& peer_address) {
+ peer_address_ = peer_address;
+ }
+
+ void SetLocalAddress(const net::IPEndPoint& local_address) {
+ local_address_ = local_address;
+ }
+
+ // net::Socket interface.
+ virtual int Read(net::IOBuffer* buf, int buf_len,
+ net::CompletionCallback* callback) OVERRIDE {
+ DCHECK(buf);
+ if (input_pos_ < static_cast<int>(input_data_.size())){
+ int result = std::min(buf_len,
+ static_cast<int>(input_data_.size()) - input_pos_);
+ memcpy(buf->data(), &(*input_data_.begin()) + input_pos_, result);
+ input_pos_ += result;
+ return result;
+ } else {
+ read_pending_ = true;
+ read_buffer_ = buf;
+ read_buffer_size_ = buf_len;
+ read_callback_ = callback;
+ return net::ERR_IO_PENDING;
+ }
+ }
+
+ virtual int Write(net::IOBuffer* buf, int buf_len,
+ net::CompletionCallback* callback) OVERRIDE {
+ DCHECK(buf);
+ if (written_data_) {
+ written_data_->insert(written_data_->end(),
+ buf->data(), buf->data() + buf_len);
+ }
+ return buf_len;
+ }
+
+
+ virtual bool SetReceiveBufferSize(int32 size) OVERRIDE {
+ NOTIMPLEMENTED();
+ return false;
+ }
+ virtual bool SetSendBufferSize(int32 size) OVERRIDE {
+ NOTIMPLEMENTED();
+ return false;
+ }
+
+ virtual int Connect(net::CompletionCallback* callback) OVERRIDE {
+ return 0;
+ }
+
+ virtual void Disconnect() OVERRIDE {
+ NOTREACHED();
+ }
+
+ virtual bool IsConnected() const OVERRIDE {
+ return true;
+ }
+
+ virtual bool IsConnectedAndIdle() const OVERRIDE {
+ return false;
+ }
+
+ virtual int GetPeerAddress(net::AddressList* address) const OVERRIDE {
+ *address = net::AddressList(peer_address_.address(),
+ peer_address_.port(), false);
+ return net::OK;
+ }
+
+ virtual int GetLocalAddress(net::IPEndPoint* address) const OVERRIDE {
+ *address = local_address_;
+ return net::OK;
+ }
+
+ virtual const net::BoundNetLog& NetLog() const OVERRIDE {
+ NOTREACHED();
+ return net_log_;
+ }
+
+ virtual void SetSubresourceSpeculation() OVERRIDE {
+ NOTREACHED();
+ }
+
+ virtual void SetOmniboxSpeculation() OVERRIDE {
+ NOTREACHED();
+ }
+
+ virtual bool WasEverUsed() const OVERRIDE {
+ return true;
+ }
+
+ virtual bool UsingTCPFastOpen() const OVERRIDE {
+ return false;
+ }
+
+ private:
+ bool read_pending_;
+ scoped_refptr<net::IOBuffer> read_buffer_;
+ int read_buffer_size_;
+ net::CompletionCallback* read_callback_;
+
+ std::string* written_data_;
+ std::string input_data_;
+ int input_pos_;
+
+ net::IPEndPoint peer_address_;
+ net::IPEndPoint local_address_;
+
+ net::BoundNetLog net_log_;
+};
+
+void CreateRandomPacket(std::vector<char>* packet) {
+ size_t size = kStunHeaderSize + rand() % 1000;
+ packet->resize(size);
+ for (size_t i = 0; i < size; i++) {
+ (*packet)[i] = rand() % 256;
+ }
+ // Always set the first bit to ensure that generated packet is not
+ // valid STUN packet.
+ (*packet)[0] = (*packet)[0] | 0x80;
+}
+
+void CreateStunPacket(std::vector<char>* packet, uint16 type) {
+ CreateRandomPacket(packet);
+ *reinterpret_cast<uint16*>(&*packet->begin()) = htons(type);
+ *reinterpret_cast<uint16*>(&*packet->begin() + 2) =
+ htons(packet->size() - kStunHeaderSize);
+ *reinterpret_cast<uint32*>(&*packet->begin() + 4) = htonl(kStunMagicCookie);
+}
+
+void CreateStunRequest(std::vector<char>* packet) {
+ CreateStunPacket(packet, kStunBindingRequest);
+}
+
+void CreateStunResponse(std::vector<char>* packet) {
+ CreateStunPacket(packet, kStunBindingResponse);
+}
+
+void CreateStunError(std::vector<char>* packet) {
+ CreateStunPacket(packet, kStunBindingError);
+}
+
+net::IPEndPoint ParseAddress(const std::string ip_str, int port) {
+ net::IPAddressNumber ip;
+ EXPECT_TRUE(net::ParseIPLiteralToNumber(ip_str, &ip));
+ return net::IPEndPoint(ip, port);
+}
+
+MATCHER_P(MatchMessage, type, "") {
+ return arg->type() == type;
+}
+
+MATCHER_P(MatchPacketMessage, packet_content, "") {
+ if (arg->type() != P2PMsg_OnDataReceived::ID)
+ return false;
+ P2PMsg_OnDataReceived::Param params;
+ IPC::MessageWithTuple<P2PMsg_OnDataReceived::Param>::Read(arg, &params);
+ return params.c == packet_content;
+}
+
+MATCHER_P(MatchIncomingSocketMessage, address, "") {
+ if (arg->type() != P2PMsg_OnIncomingTcpConnection::ID)
+ return false;
+ P2PMsg_OnIncomingTcpConnection::Param params;
+ IPC::MessageWithTuple<P2PMsg_OnIncomingTcpConnection::Param>::Read(
+ arg, &params);
+ return params.b == address;
+}
+
+} // namespace
+
+#endif // CONTENT_BROWSER_RENDERER_HOST_P2P_SOCKET_HOST_TEST_UTILS_H_
diff --git a/content/browser/renderer_host/p2p/socket_host_udp_unittest.cc b/content/browser/renderer_host/p2p/socket_host_udp_unittest.cc
index 076faae..cd517b8 100644
--- a/content/browser/renderer_host/p2p/socket_host_udp_unittest.cc
+++ b/content/browser/renderer_host/p2p/socket_host_udp_unittest.cc
@@ -2,22 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "build/build_config.h"
-
-#if defined(OS_WIN)
-#include <winsock2.h> // for htonl
-#else
-#include <arpa/inet.h>
-#endif
+#include "content/browser/renderer_host/p2p/socket_host_udp.h"
#include <deque>
#include <vector>
-#include "content/browser/renderer_host/p2p/socket_host_udp.h"
-#include "content/common/p2p_messages.h"
+#include "content/browser/renderer_host/p2p/socket_host_test_utils.h"
#include "net/base/io_buffer.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
+#include "net/base/sys_byteorder.h"
#include "net/udp/datagram_server_socket.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -29,18 +23,6 @@ using ::testing::Return;
namespace {
-const char kTestLocalIpAddress[] = "123.44.22.4";
-const char kTestIpAddress1[] = "123.44.22.31";
-const int kTestPort1 = 234;
-const char kTestIpAddress2[] = "133.11.22.33";
-const int kTestPort2 = 543;
-
-const int kStunHeaderSize = 20;
-const uint16 kStunBindingRequest = 0x0001;
-const uint16 kStunBindingResponse = 0x0102;
-const uint16 kStunBindingError = 0x0111;
-const uint32 kStunMagicCookie = 0x2112A442;
-
class FakeDatagramServerSocket : public net::DatagramServerSocket {
public:
typedef std::pair<net::IPEndPoint, std::vector<char> > UDPPacket;
@@ -124,20 +106,11 @@ class FakeDatagramServerSocket : public net::DatagramServerSocket {
net::CompletionCallback* recv_callback_;
};
-class MockIPCSender : public IPC::Message::Sender {
- public:
- MOCK_METHOD1(Send, bool(IPC::Message* msg));
-};
-
-MATCHER_P(MatchMessage, type, "") {
- return arg->type() == type;
-}
-
} // namespace
class P2PSocketHostUdpTest : public testing::Test {
protected:
- void SetUp() OVERRIDE {
+ virtual void SetUp() OVERRIDE {
EXPECT_CALL(sender_, Send(
MatchMessage(static_cast<uint32>(P2PMsg_OnSocketCreated::ID))))
.WillOnce(DoAll(DeleteArg<0>(), Return(true)));
@@ -146,48 +119,11 @@ class P2PSocketHostUdpTest : public testing::Test {
socket_ = new FakeDatagramServerSocket(&sent_packets_);
socket_host_->socket_.reset(socket_);
- net::IPAddressNumber local_ip;
- ASSERT_TRUE(net::ParseIPLiteralToNumber(kTestLocalIpAddress, &local_ip));
- local_address_ = net::IPEndPoint(local_ip, kTestPort1);
+ local_address_ = ParseAddress(kTestLocalIpAddress, kTestPort1);
socket_host_->Init(local_address_, net::IPEndPoint());
- net::IPAddressNumber ip1;
- ASSERT_TRUE(net::ParseIPLiteralToNumber(kTestIpAddress1, &ip1));
- dest1_ = net::IPEndPoint(ip1, kTestPort1);
- net::IPAddressNumber ip2;
- ASSERT_TRUE(net::ParseIPLiteralToNumber(kTestIpAddress2, &ip2));
- dest2_ = net::IPEndPoint(ip2, kTestPort2);
- }
-
- void CreateRandomPacket(std::vector<char>* packet) {
- size_t size = kStunHeaderSize + rand() % 1000;
- packet->resize(size);
- for (size_t i = 0; i < size; i++) {
- (*packet)[i] = rand() % 256;
- }
- // Always set the first bit to ensure that generated packet is not
- // valid STUN packet.
- (*packet)[0] = (*packet)[0] | 0x80;
- }
-
- void CreateStunPacket(std::vector<char>* packet, uint16 type) {
- CreateRandomPacket(packet);
- *reinterpret_cast<uint16*>(&*packet->begin()) = htons(type);
- *reinterpret_cast<uint16*>(&*packet->begin() + 2) =
- htons(packet->size() - kStunHeaderSize);
- *reinterpret_cast<uint32*>(&*packet->begin() + 4) = htonl(kStunMagicCookie);
- }
-
- void CreateStunRequest(std::vector<char>* packet) {
- CreateStunPacket(packet, kStunBindingRequest);
- }
-
- void CreateStunResponse(std::vector<char>* packet) {
- CreateStunPacket(packet, kStunBindingResponse);
- }
-
- void CreateStunError(std::vector<char>* packet) {
- CreateStunPacket(packet, kStunBindingError);
+ dest1_ = ParseAddress(kTestIpAddress1, kTestPort1);
+ dest2_ = ParseAddress(kTestIpAddress2, kTestPort2);
}
std::deque<FakeDatagramServerSocket::UDPPacket> sent_packets_;
@@ -239,13 +175,12 @@ TEST_F(P2PSocketHostUdpTest, SendDataNoAuth) {
// Verify that we can send data after we've received STUN request
// from the other side.
TEST_F(P2PSocketHostUdpTest, SendAfterStunRequest) {
- EXPECT_CALL(sender_, Send(
- MatchMessage(static_cast<uint32>(P2PMsg_OnDataReceived::ID))))
- .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
-
// Receive packet from |dest1_|.
std::vector<char> request_packet;
CreateStunRequest(&request_packet);
+
+ EXPECT_CALL(sender_, Send(MatchPacketMessage(request_packet)))
+ .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
socket_->ReceivePacket(dest1_, request_packet);
// Now we should be able to send any data to |dest1_|.
@@ -260,13 +195,12 @@ TEST_F(P2PSocketHostUdpTest, SendAfterStunRequest) {
// Verify that we can send data after we've received STUN response
// from the other side.
TEST_F(P2PSocketHostUdpTest, SendAfterStunResponse) {
- EXPECT_CALL(sender_, Send(
- MatchMessage(static_cast<uint32>(P2PMsg_OnDataReceived::ID))))
- .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
-
// Receive packet from |dest1_|.
std::vector<char> request_packet;
CreateStunRequest(&request_packet);
+
+ EXPECT_CALL(sender_, Send(MatchPacketMessage(request_packet)))
+ .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
socket_->ReceivePacket(dest1_, request_packet);
// Now we should be able to send any data to |dest1_|.
@@ -281,13 +215,12 @@ TEST_F(P2PSocketHostUdpTest, SendAfterStunResponse) {
// Verify messages still cannot be sent to an unathorized host after
// successful binding with different host.
TEST_F(P2PSocketHostUdpTest, SendAfterStunResponseDifferentHost) {
- EXPECT_CALL(sender_, Send(
- MatchMessage(static_cast<uint32>(P2PMsg_OnDataReceived::ID))))
- .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
-
// Receive packet from |dest1_|.
std::vector<char> request_packet;
CreateStunRequest(&request_packet);
+
+ EXPECT_CALL(sender_, Send(MatchPacketMessage(request_packet)))
+ .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
socket_->ReceivePacket(dest1_, request_packet);
// Should fail when trying to send the same packet to |dest2_|.