Home | History | Annotate | Download | only in p2p
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "content/browser/renderer_host/p2p/socket_host_tcp_server.h"
      6 
      7 #include <list>
      8 
      9 #include "content/browser/renderer_host/p2p/socket_host_tcp.h"
     10 #include "content/browser/renderer_host/p2p/socket_host_test_utils.h"
     11 #include "net/base/completion_callback.h"
     12 #include "testing/gmock/include/gmock/gmock.h"
     13 #include "testing/gtest/include/gtest/gtest.h"
     14 
     15 using ::testing::_;
     16 using ::testing::DeleteArg;
     17 using ::testing::DoAll;
     18 using ::testing::Return;
     19 
     20 namespace {
     21 
     22 class FakeServerSocket : public net::ServerSocket {
     23  public:
     24   FakeServerSocket()
     25       : listening_(false),
     26         accept_socket_(NULL) {
     27   }
     28 
     29   virtual ~FakeServerSocket() {}
     30 
     31   bool listening() { return listening_; }
     32 
     33   void AddIncoming(net::StreamSocket* socket) {
     34     if (!accept_callback_.is_null()) {
     35       DCHECK(incoming_sockets_.empty());
     36       accept_socket_->reset(socket);
     37       accept_socket_ = NULL;
     38 
     39       // This copy is necessary because this implementation of ServerSocket
     40       // bases logic on the null-ness of |accept_callback_| in the bound
     41       // callback.
     42       net::CompletionCallback cb = accept_callback_;
     43       accept_callback_.Reset();
     44       cb.Run(net::OK);
     45     } else {
     46       incoming_sockets_.push_back(socket);
     47     }
     48   }
     49 
     50   virtual int Listen(const net::IPEndPoint& address, int backlog) OVERRIDE {
     51     local_address_ = address;
     52     listening_ = true;
     53     return net::OK;
     54   }
     55 
     56   virtual int GetLocalAddress(net::IPEndPoint* address) const OVERRIDE {
     57     *address = local_address_;
     58     return net::OK;
     59   }
     60 
     61   virtual int Accept(scoped_ptr<net::StreamSocket>* socket,
     62                      const net::CompletionCallback& callback) OVERRIDE {
     63     DCHECK(socket);
     64     if (!incoming_sockets_.empty()) {
     65       socket->reset(incoming_sockets_.front());
     66       incoming_sockets_.pop_front();
     67       return net::OK;
     68     } else {
     69       accept_socket_ = socket;
     70       accept_callback_ = callback;
     71       return net::ERR_IO_PENDING;
     72     }
     73   }
     74 
     75  private:
     76   bool listening_;
     77 
     78   net::IPEndPoint local_address_;
     79 
     80   scoped_ptr<net::StreamSocket>* accept_socket_;
     81   net::CompletionCallback accept_callback_;
     82 
     83   std::list<net::StreamSocket*> incoming_sockets_;
     84 };
     85 
     86 }  // namespace
     87 
     88 namespace content {
     89 
     90 class P2PSocketHostTcpServerTest : public testing::Test {
     91  protected:
     92   virtual void SetUp() OVERRIDE {
     93     socket_ = new FakeServerSocket();
     94     socket_host_.reset(
     95         new P2PSocketHostTcpServer(&sender_, 0, P2P_SOCKET_TCP_CLIENT));
     96     socket_host_->socket_.reset(socket_);
     97 
     98     EXPECT_CALL(sender_, Send(
     99         MatchMessage(static_cast<uint32>(P2PMsg_OnSocketCreated::ID))))
    100         .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
    101 
    102     P2PHostAndIPEndPoint dest;
    103     dest.ip_address = ParseAddress(kTestIpAddress1, kTestPort1);
    104 
    105     socket_host_->Init(ParseAddress(kTestLocalIpAddress, 0),
    106                        dest);
    107     EXPECT_TRUE(socket_->listening());
    108   }
    109 
    110   // Needed by the chilt classes because only this class is a friend
    111   // of P2PSocketHostTcp.
    112   net::StreamSocket* GetSocketFormTcpSocketHost(P2PSocketHostTcp* host) {
    113     return host->socket_.get();
    114   }
    115 
    116   MockIPCSender sender_;
    117   FakeServerSocket* socket_;  // Owned by |socket_host_|.
    118   scoped_ptr<P2PSocketHostTcpServer> socket_host_;
    119 };
    120 
    121 // Accept incoming connection.
    122 TEST_F(P2PSocketHostTcpServerTest, Accept) {
    123   FakeSocket* incoming = new FakeSocket(NULL);
    124   incoming->SetLocalAddress(ParseAddress(kTestLocalIpAddress, kTestPort1));
    125   net::IPEndPoint addr = ParseAddress(kTestIpAddress1, kTestPort1);
    126   incoming->SetPeerAddress(addr);
    127 
    128   EXPECT_CALL(sender_, Send(MatchIncomingSocketMessage(addr)))
    129       .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
    130   socket_->AddIncoming(incoming);
    131 
    132   const int kAcceptedSocketId = 1;
    133 
    134   scoped_ptr<P2PSocketHost> new_host(
    135       socket_host_->AcceptIncomingTcpConnection(addr, kAcceptedSocketId));
    136   ASSERT_TRUE(new_host.get() != NULL);
    137   EXPECT_EQ(incoming, GetSocketFormTcpSocketHost(
    138       reinterpret_cast<P2PSocketHostTcp*>(new_host.get())));
    139 }
    140 
    141 // Accept 2 simultaneous connections.
    142 TEST_F(P2PSocketHostTcpServerTest, Accept2) {
    143   FakeSocket* incoming1 = new FakeSocket(NULL);
    144   incoming1->SetLocalAddress(ParseAddress(kTestLocalIpAddress, kTestPort1));
    145   net::IPEndPoint addr1 = ParseAddress(kTestIpAddress1, kTestPort1);
    146   incoming1->SetPeerAddress(addr1);
    147   FakeSocket* incoming2 = new FakeSocket(NULL);
    148   incoming2->SetLocalAddress(ParseAddress(kTestLocalIpAddress, kTestPort1));
    149   net::IPEndPoint addr2 = ParseAddress(kTestIpAddress2, kTestPort2);
    150   incoming2->SetPeerAddress(addr2);
    151 
    152   EXPECT_CALL(sender_, Send(MatchIncomingSocketMessage(addr1)))
    153       .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
    154   EXPECT_CALL(sender_, Send(MatchIncomingSocketMessage(addr2)))
    155       .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
    156   socket_->AddIncoming(incoming1);
    157   socket_->AddIncoming(incoming2);
    158 
    159   const int kAcceptedSocketId1 = 1;
    160   const int kAcceptedSocketId2 = 2;
    161 
    162   scoped_ptr<P2PSocketHost> new_host1(
    163       socket_host_->AcceptIncomingTcpConnection(addr1, kAcceptedSocketId1));
    164   ASSERT_TRUE(new_host1.get() != NULL);
    165   EXPECT_EQ(incoming1, GetSocketFormTcpSocketHost(
    166       reinterpret_cast<P2PSocketHostTcp*>(new_host1.get())));
    167   scoped_ptr<P2PSocketHost> new_host2(
    168       socket_host_->AcceptIncomingTcpConnection(addr2, kAcceptedSocketId2));
    169   ASSERT_TRUE(new_host2.get() != NULL);
    170   EXPECT_EQ(incoming2, GetSocketFormTcpSocketHost(
    171       reinterpret_cast<P2PSocketHostTcp*>(new_host2.get())));
    172 }
    173 
    174 }  // namespace content
    175