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