Home | History | Annotate | Download | only in socket
      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 "net/socket/tcp_server_socket.h"
      6 
      7 #include "base/compiler_specific.h"
      8 #include "base/scoped_ptr.h"
      9 #include "net/base/address_list.h"
     10 #include "net/base/ip_endpoint.h"
     11 #include "net/base/net_errors.h"
     12 #include "net/base/sys_addrinfo.h"
     13 #include "net/base/test_completion_callback.h"
     14 #include "net/socket/tcp_client_socket.h"
     15 #include "testing/gtest/include/gtest/gtest.h"
     16 #include "testing/platform_test.h"
     17 
     18 namespace net {
     19 
     20 namespace {
     21 const int kListenBacklog = 5;
     22 
     23 class TCPServerSocketTest : public PlatformTest {
     24  protected:
     25   TCPServerSocketTest()
     26       : socket_(NULL, NetLog::Source()) {
     27   }
     28 
     29   void SetUp() OVERRIDE {
     30     IPEndPoint address;
     31     ParseAddress("127.0.0.1", 0, &address);
     32     ASSERT_EQ(OK, socket_.Listen(address, kListenBacklog));
     33     ASSERT_EQ(OK, socket_.GetLocalAddress(&local_address_));
     34   }
     35 
     36   void ParseAddress(std::string ip_str, int port, IPEndPoint* address) {
     37     IPAddressNumber ip_number;
     38     bool rv = ParseIPLiteralToNumber(ip_str, &ip_number);
     39     if (!rv)
     40       return;
     41     *address = IPEndPoint(ip_number, port);
     42   }
     43 
     44   static IPEndPoint GetPeerAddress(ClientSocket* socket) {
     45     AddressList address;
     46     EXPECT_EQ(OK, socket->GetPeerAddress(&address));
     47     IPEndPoint endpoint;
     48     EXPECT_TRUE(endpoint.FromSockAddr(
     49         address.head()->ai_addr, address.head()->ai_addrlen));
     50     return endpoint;
     51   }
     52 
     53   TCPServerSocket socket_;
     54   IPEndPoint local_address_;
     55 };
     56 
     57 TEST_F(TCPServerSocketTest, Accept) {
     58   TestCompletionCallback connect_callback;
     59   TCPClientSocket connecting_socket(AddressList(local_address_.address(),
     60                                                 local_address_.port(), false),
     61                                     NULL, NetLog::Source());
     62   connecting_socket.Connect(&connect_callback);
     63 
     64   TestCompletionCallback accept_callback;
     65   scoped_ptr<ClientSocket> accepted_socket;
     66   int result = socket_.Accept(&accepted_socket, &accept_callback);
     67   if (result == ERR_IO_PENDING)
     68     result = accept_callback.WaitForResult();
     69   ASSERT_EQ(OK, result);
     70 
     71   ASSERT_TRUE(accepted_socket.get() != NULL);
     72 
     73   // Both sockets should be on the loopback network interface.
     74   EXPECT_EQ(GetPeerAddress(accepted_socket.get()).address(),
     75             local_address_.address());
     76 
     77   EXPECT_EQ(OK, connect_callback.WaitForResult());
     78 }
     79 
     80 // Test Accept() callback.
     81 TEST_F(TCPServerSocketTest, AcceptAsync) {
     82   TestCompletionCallback accept_callback;
     83   scoped_ptr<ClientSocket> accepted_socket;
     84 
     85   ASSERT_EQ(ERR_IO_PENDING, socket_.Accept(&accepted_socket, &accept_callback));
     86 
     87   TestCompletionCallback connect_callback;
     88   TCPClientSocket connecting_socket(AddressList(local_address_.address(),
     89                                                 local_address_.port(), false),
     90                                     NULL, NetLog::Source());
     91   connecting_socket.Connect(&connect_callback);
     92 
     93   EXPECT_EQ(OK, connect_callback.WaitForResult());
     94   EXPECT_EQ(OK, accept_callback.WaitForResult());
     95 
     96   EXPECT_TRUE(accepted_socket != NULL);
     97 
     98   // Both sockets should be on the loopback network interface.
     99   EXPECT_EQ(GetPeerAddress(accepted_socket.get()).address(),
    100             local_address_.address());
    101 }
    102 
    103 // Accept two connections simultaneously.
    104 TEST_F(TCPServerSocketTest, Accept2Connections) {
    105   TestCompletionCallback accept_callback;
    106   scoped_ptr<ClientSocket> accepted_socket;
    107 
    108   ASSERT_EQ(ERR_IO_PENDING,
    109             socket_.Accept(&accepted_socket, &accept_callback));
    110 
    111   TestCompletionCallback connect_callback;
    112   TCPClientSocket connecting_socket(AddressList(local_address_.address(),
    113                                                 local_address_.port(), false),
    114                                     NULL, NetLog::Source());
    115   connecting_socket.Connect(&connect_callback);
    116 
    117   TestCompletionCallback connect_callback2;
    118   TCPClientSocket connecting_socket2(AddressList(local_address_.address(),
    119                                                  local_address_.port(), false),
    120                                      NULL, NetLog::Source());
    121   connecting_socket2.Connect(&connect_callback2);
    122 
    123   EXPECT_EQ(OK, accept_callback.WaitForResult());
    124 
    125   TestCompletionCallback accept_callback2;
    126   scoped_ptr<ClientSocket> accepted_socket2;
    127   int result = socket_.Accept(&accepted_socket2, &accept_callback2);
    128   if (result == ERR_IO_PENDING)
    129     result = accept_callback2.WaitForResult();
    130   ASSERT_EQ(OK, result);
    131 
    132   EXPECT_EQ(OK, connect_callback.WaitForResult());
    133 
    134   EXPECT_TRUE(accepted_socket != NULL);
    135   EXPECT_TRUE(accepted_socket2 != NULL);
    136   EXPECT_NE(accepted_socket.get(), accepted_socket2.get());
    137 
    138   EXPECT_EQ(GetPeerAddress(accepted_socket.get()).address(),
    139             local_address_.address());
    140   EXPECT_EQ(GetPeerAddress(accepted_socket2.get()).address(),
    141             local_address_.address());
    142 }
    143 
    144 }  // namespace
    145 
    146 }  // namespace net
    147