socket_host_tcp_server_unittest.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/p2p/socket_host_tcp_server.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/p2p/socket_host_tcp.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/p2p/socket_host_test_utils.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/completion_callback.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::_;
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::DeleteArg;
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::DoAll;
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::Return;
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FakeServerSocket : public net::ServerSocket {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FakeServerSocket()
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : listening_(false),
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        accept_socket_(NULL) {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~FakeServerSocket() {}
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool listening() { return listening_; }
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddIncoming(net::StreamSocket* socket) {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!accept_callback_.is_null()) {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(incoming_sockets_.empty());
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      accept_socket_->reset(socket);
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      accept_socket_ = NULL;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // This copy is necessary because this implementation of ServerSocket
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // bases logic on the null-ness of |accept_callback_| in the bound
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // callback.
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net::CompletionCallback cb = accept_callback_;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      accept_callback_.Reset();
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cb.Run(net::OK);
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      incoming_sockets_.push_back(socket);
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // net::ServerSocket implementation.
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void AllowAddressReuse() {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int Listen(const net::IPEndPoint& address, int backlog) OVERRIDE {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    local_address_ = address;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    listening_ = true;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return net::OK;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int GetLocalAddress(net::IPEndPoint* address) const OVERRIDE {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *address = local_address_;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return net::OK;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int Accept(scoped_ptr<net::StreamSocket>* socket,
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const net::CompletionCallback& callback) OVERRIDE {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(socket);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!incoming_sockets_.empty()) {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      socket->reset(incoming_sockets_.front());
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      incoming_sockets_.pop_front();
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return net::OK;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      accept_socket_ = socket;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      accept_callback_ = callback;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return net::ERR_IO_PENDING;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool listening_;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::IPEndPoint local_address_;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<net::StreamSocket>* accept_socket_;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CompletionCallback accept_callback_;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::list<net::StreamSocket*> incoming_sockets_;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class P2PSocketHostTcpServerTest : public testing::Test {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() OVERRIDE {
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    socket_ = new FakeServerSocket();
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    socket_host_.reset(new P2PSocketHostTcpServer(&sender_, 0));
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    socket_host_->socket_.reset(socket_);
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(sender_, Send(
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MatchMessage(static_cast<uint32>(P2PMsg_OnSocketCreated::ID))))
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    socket_host_->Init(ParseAddress(kTestLocalIpAddress, 0),
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       ParseAddress(kTestIpAddress1, kTestPort1));
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(socket_->listening());
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Needed by the chilt classes because only this class is a friend
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of P2PSocketHostTcp.
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StreamSocket* GetSocketFormTcpSocketHost(P2PSocketHostTcp* host) {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return host->socket_.get();
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockIPCSender sender_;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FakeServerSocket* socket_; // Owned by |socket_host_|.
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<P2PSocketHostTcpServer> socket_host_;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Accept incoming connection.
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(P2PSocketHostTcpServerTest, Accept) {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FakeSocket* incoming = new FakeSocket(NULL);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  incoming->SetLocalAddress(ParseAddress(kTestLocalIpAddress, kTestPort1));
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::IPEndPoint addr = ParseAddress(kTestIpAddress1, kTestPort1);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  incoming->SetPeerAddress(addr);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(sender_, Send(MatchIncomingSocketMessage(addr)))
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  socket_->AddIncoming(incoming);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kAcceptedSocketId = 1;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<P2PSocketHost> new_host(
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      socket_host_->AcceptIncomingTcpConnection(addr, kAcceptedSocketId));
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(new_host.get() != NULL);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(incoming, GetSocketFormTcpSocketHost(
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<P2PSocketHostTcp*>(new_host.get())));
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Accept 2 simultaneous connections.
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(P2PSocketHostTcpServerTest, Accept2) {
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FakeSocket* incoming1 = new FakeSocket(NULL);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  incoming1->SetLocalAddress(ParseAddress(kTestLocalIpAddress, kTestPort1));
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::IPEndPoint addr1 = ParseAddress(kTestIpAddress1, kTestPort1);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  incoming1->SetPeerAddress(addr1);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FakeSocket* incoming2 = new FakeSocket(NULL);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  incoming2->SetLocalAddress(ParseAddress(kTestLocalIpAddress, kTestPort1));
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::IPEndPoint addr2 = ParseAddress(kTestIpAddress2, kTestPort2);
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  incoming2->SetPeerAddress(addr2);
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(sender_, Send(MatchIncomingSocketMessage(addr1)))
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(sender_, Send(MatchIncomingSocketMessage(addr2)))
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  socket_->AddIncoming(incoming1);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  socket_->AddIncoming(incoming2);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kAcceptedSocketId1 = 1;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kAcceptedSocketId2 = 2;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<P2PSocketHost> new_host1(
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      socket_host_->AcceptIncomingTcpConnection(addr1, kAcceptedSocketId1));
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(new_host1.get() != NULL);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(incoming1, GetSocketFormTcpSocketHost(
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<P2PSocketHostTcp*>(new_host1.get())));
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<P2PSocketHost> new_host2(
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      socket_host_->AcceptIncomingTcpConnection(addr2, kAcceptedSocketId2));
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(new_host2.get() != NULL);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(incoming2, GetSocketFormTcpSocketHost(
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<P2PSocketHostTcp*>(new_host2.get())));
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
173