socket_host_tcp_server_unittest.cc revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
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)  virtual int Listen(const net::IPEndPoint& address, int backlog) OVERRIDE {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    local_address_ = address;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    listening_ = true;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return net::OK;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int GetLocalAddress(net::IPEndPoint* address) const OVERRIDE {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *address = local_address_;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return net::OK;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int Accept(scoped_ptr<net::StreamSocket>* socket,
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const net::CompletionCallback& callback) OVERRIDE {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(socket);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!incoming_sockets_.empty()) {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      socket->reset(incoming_sockets_.front());
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      incoming_sockets_.pop_front();
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return net::OK;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      accept_socket_ = socket;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      accept_callback_ = callback;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return net::ERR_IO_PENDING;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool listening_;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::IPEndPoint local_address_;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<net::StreamSocket>* accept_socket_;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CompletionCallback accept_callback_;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::list<net::StreamSocket*> incoming_sockets_;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class P2PSocketHostTcpServerTest : public testing::Test {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() OVERRIDE {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    socket_ = new FakeServerSocket();
92b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    socket_host_.reset(new P2PSocketHostTcpServer(
93b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        &sender_, 0, P2P_SOCKET_TCP_CLIENT));
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    socket_host_->socket_.reset(socket_);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(sender_, Send(
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MatchMessage(static_cast<uint32>(P2PMsg_OnSocketCreated::ID))))
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    socket_host_->Init(ParseAddress(kTestLocalIpAddress, 0),
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       ParseAddress(kTestIpAddress1, kTestPort1));
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(socket_->listening());
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Needed by the chilt classes because only this class is a friend
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of P2PSocketHostTcp.
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StreamSocket* GetSocketFormTcpSocketHost(P2PSocketHostTcp* host) {
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return host->socket_.get();
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockIPCSender sender_;
1127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  FakeServerSocket* socket_;  // Owned by |socket_host_|.
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<P2PSocketHostTcpServer> socket_host_;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Accept incoming connection.
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(P2PSocketHostTcpServerTest, Accept) {
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FakeSocket* incoming = new FakeSocket(NULL);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  incoming->SetLocalAddress(ParseAddress(kTestLocalIpAddress, kTestPort1));
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::IPEndPoint addr = ParseAddress(kTestIpAddress1, kTestPort1);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  incoming->SetPeerAddress(addr);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(sender_, Send(MatchIncomingSocketMessage(addr)))
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  socket_->AddIncoming(incoming);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kAcceptedSocketId = 1;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<P2PSocketHost> new_host(
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      socket_host_->AcceptIncomingTcpConnection(addr, kAcceptedSocketId));
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(new_host.get() != NULL);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(incoming, GetSocketFormTcpSocketHost(
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<P2PSocketHostTcp*>(new_host.get())));
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Accept 2 simultaneous connections.
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(P2PSocketHostTcpServerTest, Accept2) {
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FakeSocket* incoming1 = new FakeSocket(NULL);
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  incoming1->SetLocalAddress(ParseAddress(kTestLocalIpAddress, kTestPort1));
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::IPEndPoint addr1 = ParseAddress(kTestIpAddress1, kTestPort1);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  incoming1->SetPeerAddress(addr1);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FakeSocket* incoming2 = new FakeSocket(NULL);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  incoming2->SetLocalAddress(ParseAddress(kTestLocalIpAddress, kTestPort1));
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::IPEndPoint addr2 = ParseAddress(kTestIpAddress2, kTestPort2);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  incoming2->SetPeerAddress(addr2);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(sender_, Send(MatchIncomingSocketMessage(addr1)))
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(sender_, Send(MatchIncomingSocketMessage(addr2)))
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  socket_->AddIncoming(incoming1);
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  socket_->AddIncoming(incoming2);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kAcceptedSocketId1 = 1;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kAcceptedSocketId2 = 2;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<P2PSocketHost> new_host1(
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      socket_host_->AcceptIncomingTcpConnection(addr1, kAcceptedSocketId1));
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(new_host1.get() != NULL);
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(incoming1, GetSocketFormTcpSocketHost(
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<P2PSocketHostTcp*>(new_host1.get())));
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<P2PSocketHost> new_host2(
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      socket_host_->AcceptIncomingTcpConnection(addr2, kAcceptedSocketId2));
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(new_host2.get() != NULL);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(incoming2, GetSocketFormTcpSocketHost(
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<P2PSocketHostTcp*>(new_host2.get())));
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
170