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