15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 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) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/socket/tcp_listen_socket_unittest.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <fcntl.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/types.h> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/posix/eintr_wrapper.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/sys_byteorder.h" 13424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "net/base/ip_endpoint.h" 14424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "net/base/net_errors.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_util.h" 16424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "net/socket/socket_descriptor.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/platform_test.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const int kReadBufSize = 1024; 2268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char kHelloWorld[] = "HELLO, WORLD"; 2368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char kLoopback[] = "127.0.0.1"; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TCPListenSocketTester::TCPListenSocketTester() 26424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) : loop_(NULL), 27424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) cv_(&lock_), 28424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) server_port_(0) {} 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TCPListenSocketTester::SetUp() { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Thread::Options options; 3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) options.message_loop_type = base::MessageLoop::TYPE_IO; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thread_.reset(new base::Thread("socketio_test")); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thread_->StartWithOptions(options); 3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) loop_ = reinterpret_cast<base::MessageLoopForIO*>(thread_->message_loop()); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loop_->PostTask(FROM_HERE, base::Bind( 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &TCPListenSocketTester::Listen, this)); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // verify Listen succeeded 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NextAction(); 42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASSERT_FALSE(server_.get() == NULL); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(ACTION_LISTEN, last_action_.type()); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int server_port = GetServerPort(); 46424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_GT(server_port, 0); 47424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // verify the connect/accept and setup test_socket_ 49424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) test_socket_ = CreatePlatformSocket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 50424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_NE(kInvalidSocket, test_socket_); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct sockaddr_in client; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client.sin_family = AF_INET; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client.sin_addr.s_addr = inet_addr(kLoopback); 54424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) client.sin_port = base::HostToNet16(server_port); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ret = HANDLE_EINTR( 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connect(test_socket_, reinterpret_cast<sockaddr*>(&client), 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(client))); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The connect() call may be interrupted by a signal. When connect() 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is retried on EINTR, it fails with EISCONN. 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == StreamListenSocket::kSocketError) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(EISCONN, errno); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't have signals. 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_NE(StreamListenSocket::kSocketError, ret); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NextAction(); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(ACTION_ACCEPT, last_action_.type()); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TCPListenSocketTester::TearDown() { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0, closesocket(test_socket_)); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX) 76a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ASSERT_EQ(0, IGNORE_EINTR(close(test_socket_))); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NextAction(); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(ACTION_CLOSE, last_action_.type()); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loop_->PostTask(FROM_HERE, base::Bind( 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &TCPListenSocketTester::Shutdown, this)); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NextAction(); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(ACTION_SHUTDOWN, last_action_.type()); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thread_.reset(); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loop_ = NULL; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TCPListenSocketTester::ReportAction( 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const TCPListenSocketTestAction& action) { 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock locked(lock_); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) queue_.push_back(action); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cv_.Broadcast(); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TCPListenSocketTester::NextAction() { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock locked(lock_); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (queue_.empty()) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cv_.Wait(); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_action_ = queue_.front(); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) queue_.pop_front(); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int TCPListenSocketTester::ClearTestSocket() { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char buf[kReadBufSize]; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int len_ret = 0; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int len = HANDLE_EINTR(recv(test_socket_, buf, kReadBufSize, 0)); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (len == StreamListenSocket::kSocketError || len == 0) { 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len_ret += len; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (true); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return len_ret; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TCPListenSocketTester::Shutdown() { 12058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) connection_.reset(); 12158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) server_.reset(); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportAction(TCPListenSocketTestAction(ACTION_SHUTDOWN)); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TCPListenSocketTester::Listen() { 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_ = DoListen(); 127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASSERT_TRUE(server_.get()); 128424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 129424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // The server's port will be needed to open the client socket. 130424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) IPEndPoint local_address; 131424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_EQ(OK, server_->GetLocalAddress(&local_address)); 132424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) SetServerPort(local_address.port()); 133424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportAction(TCPListenSocketTestAction(ACTION_LISTEN)); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TCPListenSocketTester::SendFromTester() { 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_->Send(kHelloWorld); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportAction(TCPListenSocketTestAction(ACTION_SEND)); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TCPListenSocketTester::TestClientSend() { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(Send(test_socket_, kHelloWorld)); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NextAction(); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(ACTION_READ, last_action_.type()); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(last_action_.data(), kHelloWorld); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TCPListenSocketTester::TestClientSendLong() { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t hello_len = strlen(kHelloWorld); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string long_string; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t long_len = 0; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < 200; i++) { 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long_string += kHelloWorld; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long_len += hello_len; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(Send(test_socket_, long_string)); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t read_len = 0; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (read_len < long_len) { 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NextAction(); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(ACTION_READ, last_action_.type()); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string last_data = last_action_.data(); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t len = last_data.length(); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (long_string.compare(read_len, len, last_data)) { 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(long_string.compare(read_len, len, last_data), 0); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_len += last_data.length(); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(read_len, long_len); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TCPListenSocketTester::TestServerSend() { 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loop_->PostTask(FROM_HERE, base::Bind( 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &TCPListenSocketTester::SendFromTester, this)); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NextAction(); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(ACTION_SEND, last_action_.type()); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int buf_len = 200; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char buf[buf_len+1]; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned recv_len = 0; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (recv_len < strlen(kHelloWorld)) { 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int r = HANDLE_EINTR(recv(test_socket_, 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) buf + recv_len, buf_len - recv_len, 0)); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_GE(r, 0); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) recv_len += static_cast<unsigned>(r); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!r) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buf[recv_len] = 0; 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_STREQ(kHelloWorld, buf); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TCPListenSocketTester::TestServerSendMultiple() { 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Send enough data to exceed the socket receive window. 20kb is probably a 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // safe bet. 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int send_count = (1024*20) / (sizeof(kHelloWorld)-1); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Send multiple writes. Since no reading is occurring the data should be 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // buffered in TCPListenSocket. 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int i = 0; i < send_count; ++i) { 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loop_->PostTask(FROM_HERE, base::Bind( 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &TCPListenSocketTester::SendFromTester, this)); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NextAction(); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(ACTION_SEND, last_action_.type()); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make multiple reads. All of the data should eventually be returned. 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char buf[sizeof(kHelloWorld)]; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int buf_len = sizeof(kHelloWorld); 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int i = 0; i < send_count; ++i) { 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned recv_len = 0; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (recv_len < buf_len-1) { 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int r = HANDLE_EINTR(recv(test_socket_, 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) buf + recv_len, buf_len - 1 - recv_len, 0)); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_GE(r, 0); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) recv_len += static_cast<unsigned>(r); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!r) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buf[recv_len] = 0; 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_STREQ(kHelloWorld, buf); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TCPListenSocketTester::Send(SocketDescriptor sock, 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& str) { 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int len = static_cast<int>(str.length()); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int send_len = HANDLE_EINTR(send(sock, str.data(), len, 0)); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (send_len == StreamListenSocket::kSocketError) { 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "send failed: " << errno; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (send_len != len) { 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void TCPListenSocketTester::DidAccept( 23858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) StreamListenSocket* server, 23958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_ptr<StreamListenSocket> connection) { 24058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) connection_ = connection.Pass(); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportAction(TCPListenSocketTestAction(ACTION_ACCEPT)); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TCPListenSocketTester::DidRead(StreamListenSocket* connection, 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* data, 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int len) { 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string str(data, len); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportAction(TCPListenSocketTestAction(ACTION_READ, str)); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TCPListenSocketTester::DidClose(StreamListenSocket* sock) { 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportAction(TCPListenSocketTestAction(ACTION_CLOSE)); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TCPListenSocketTester::~TCPListenSocketTester() {} 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)scoped_ptr<TCPListenSocket> TCPListenSocketTester::DoListen() { 258424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Let the OS pick a free port. 259424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return TCPListenSocket::CreateAndListen(kLoopback, 0, this); 260424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 261424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 262424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)int TCPListenSocketTester::GetServerPort() { 263424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::AutoLock locked(lock_); 264424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return server_port_; 265424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 266424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 267424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void TCPListenSocketTester::SetServerPort(int server_port) { 268424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::AutoLock locked(lock_); 269424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) server_port_ = server_port; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 272424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)class TCPListenSocketTest : public PlatformTest { 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TCPListenSocketTest() { 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tester_ = NULL; 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetUp() { 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PlatformTest::SetUp(); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tester_ = new TCPListenSocketTester(); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tester_->SetUp(); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void TearDown() { 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PlatformTest::TearDown(); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tester_->TearDown(); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tester_ = NULL; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<TCPListenSocketTester> tester_; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TCPListenSocketTest, ClientSend) { 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tester_->TestClientSend(); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TCPListenSocketTest, ClientSendLong) { 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tester_->TestClientSendLong(); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TCPListenSocketTest, ServerSend) { 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tester_->TestServerSend(); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TCPListenSocketTest, ServerSendMultiple) { 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tester_->TestServerSendMultiple(); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 310