tcp_listen_socket_unittest.cc revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
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" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_util.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/platform_test.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int TCPListenSocketTester::kTestPort = 9999; 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kReadBufSize = 1024; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kHelloWorld[] = "HELLO, WORLD"; 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kMaxQueueSize = 20; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kLoopback[] = "127.0.0.1"; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kDefaultTimeoutMs = 5000; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TCPListenSocketTester::TCPListenSocketTester() 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : thread_(NULL), 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loop_(NULL), 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_(NULL), 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_(NULL), 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cv_(&lock_) { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TCPListenSocketTester::SetUp() { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Thread::Options options; 3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) options.message_loop_type = base::MessageLoop::TYPE_IO; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thread_.reset(new base::Thread("socketio_test")); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thread_->StartWithOptions(options); 3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) loop_ = reinterpret_cast<base::MessageLoopForIO*>(thread_->message_loop()); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loop_->PostTask(FROM_HERE, base::Bind( 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &TCPListenSocketTester::Listen, this)); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // verify Listen succeeded 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NextAction(); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(server_ == NULL); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(ACTION_LISTEN, last_action_.type()); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // verify the connect/accept and setup test_socket_ 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test_socket_ = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_NE(StreamListenSocket::kInvalidSocket, test_socket_); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct sockaddr_in client; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client.sin_family = AF_INET; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client.sin_addr.s_addr = inet_addr(kLoopback); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client.sin_port = base::HostToNet16(kTestPort); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ret = HANDLE_EINTR( 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connect(test_socket_, reinterpret_cast<sockaddr*>(&client), 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(client))); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The connect() call may be interrupted by a signal. When connect() 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is retried on EINTR, it fails with EISCONN. 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == StreamListenSocket::kSocketError) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(EISCONN, errno); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't have signals. 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_NE(StreamListenSocket::kSocketError, ret); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NextAction(); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(ACTION_ACCEPT, last_action_.type()); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TCPListenSocketTester::TearDown() { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0, closesocket(test_socket_)); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0, HANDLE_EINTR(close(test_socket_))); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NextAction(); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(ACTION_CLOSE, last_action_.type()); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loop_->PostTask(FROM_HERE, base::Bind( 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &TCPListenSocketTester::Shutdown, this)); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NextAction(); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(ACTION_SHUTDOWN, last_action_.type()); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thread_.reset(); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loop_ = NULL; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TCPListenSocketTester::ReportAction( 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const TCPListenSocketTestAction& action) { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock locked(lock_); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) queue_.push_back(action); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cv_.Broadcast(); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TCPListenSocketTester::NextAction() { 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock locked(lock_); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (queue_.empty()) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cv_.Wait(); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_action_ = queue_.front(); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) queue_.pop_front(); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int TCPListenSocketTester::ClearTestSocket() { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char buf[kReadBufSize]; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int len_ret = 0; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int len = HANDLE_EINTR(recv(test_socket_, buf, kReadBufSize, 0)); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (len == StreamListenSocket::kSocketError || len == 0) { 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len_ret += len; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (true); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return len_ret; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TCPListenSocketTester::Shutdown() { 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_->Release(); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_ = NULL; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_->Release(); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_ = NULL; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportAction(TCPListenSocketTestAction(ACTION_SHUTDOWN)); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TCPListenSocketTester::Listen() { 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_ = DoListen(); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(server_); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_->AddRef(); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportAction(TCPListenSocketTestAction(ACTION_LISTEN)); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TCPListenSocketTester::SendFromTester() { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_->Send(kHelloWorld); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportAction(TCPListenSocketTestAction(ACTION_SEND)); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TCPListenSocketTester::TestClientSend() { 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(Send(test_socket_, kHelloWorld)); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NextAction(); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(ACTION_READ, last_action_.type()); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(last_action_.data(), kHelloWorld); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TCPListenSocketTester::TestClientSendLong() { 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t hello_len = strlen(kHelloWorld); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string long_string; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t long_len = 0; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < 200; i++) { 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long_string += kHelloWorld; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long_len += hello_len; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(Send(test_socket_, long_string)); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t read_len = 0; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (read_len < long_len) { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NextAction(); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(ACTION_READ, last_action_.type()); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string last_data = last_action_.data(); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t len = last_data.length(); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (long_string.compare(read_len, len, last_data)) { 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(long_string.compare(read_len, len, last_data), 0); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_len += last_data.length(); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(read_len, long_len); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TCPListenSocketTester::TestServerSend() { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loop_->PostTask(FROM_HERE, base::Bind( 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &TCPListenSocketTester::SendFromTester, this)); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NextAction(); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(ACTION_SEND, last_action_.type()); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int buf_len = 200; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char buf[buf_len+1]; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned recv_len = 0; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (recv_len < strlen(kHelloWorld)) { 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int r = HANDLE_EINTR(recv(test_socket_, 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) buf + recv_len, buf_len - recv_len, 0)); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_GE(r, 0); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) recv_len += static_cast<unsigned>(r); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!r) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buf[recv_len] = 0; 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_STREQ(kHelloWorld, buf); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TCPListenSocketTester::TestServerSendMultiple() { 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Send enough data to exceed the socket receive window. 20kb is probably a 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // safe bet. 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int send_count = (1024*20) / (sizeof(kHelloWorld)-1); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Send multiple writes. Since no reading is occurring the data should be 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // buffered in TCPListenSocket. 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int i = 0; i < send_count; ++i) { 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loop_->PostTask(FROM_HERE, base::Bind( 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &TCPListenSocketTester::SendFromTester, this)); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NextAction(); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(ACTION_SEND, last_action_.type()); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make multiple reads. All of the data should eventually be returned. 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char buf[sizeof(kHelloWorld)]; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int buf_len = sizeof(kHelloWorld); 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int i = 0; i < send_count; ++i) { 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned recv_len = 0; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (recv_len < buf_len-1) { 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int r = HANDLE_EINTR(recv(test_socket_, 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) buf + recv_len, buf_len - 1 - recv_len, 0)); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_GE(r, 0); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) recv_len += static_cast<unsigned>(r); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!r) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buf[recv_len] = 0; 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_STREQ(kHelloWorld, buf); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TCPListenSocketTester::Send(SocketDescriptor sock, 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& str) { 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int len = static_cast<int>(str.length()); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int send_len = HANDLE_EINTR(send(sock, str.data(), len, 0)); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (send_len == StreamListenSocket::kSocketError) { 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "send failed: " << errno; 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (send_len != len) { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TCPListenSocketTester::DidAccept(StreamListenSocket* server, 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StreamListenSocket* connection) { 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_ = connection; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_->AddRef(); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportAction(TCPListenSocketTestAction(ACTION_ACCEPT)); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TCPListenSocketTester::DidRead(StreamListenSocket* connection, 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* data, 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int len) { 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string str(data, len); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportAction(TCPListenSocketTestAction(ACTION_READ, str)); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TCPListenSocketTester::DidClose(StreamListenSocket* sock) { 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportAction(TCPListenSocketTestAction(ACTION_CLOSE)); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TCPListenSocketTester::~TCPListenSocketTester() {} 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<TCPListenSocket> TCPListenSocketTester::DoListen() { 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCPListenSocket::CreateAndListen(kLoopback, kTestPort, this); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TCPListenSocketTest: public PlatformTest { 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TCPListenSocketTest() { 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tester_ = NULL; 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetUp() { 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PlatformTest::SetUp(); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tester_ = new TCPListenSocketTester(); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tester_->SetUp(); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void TearDown() { 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PlatformTest::TearDown(); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tester_->TearDown(); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tester_ = NULL; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<TCPListenSocketTester> tester_; 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TCPListenSocketTest, ClientSend) { 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tester_->TestClientSend(); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TCPListenSocketTest, ClientSendLong) { 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tester_->TestClientSendLong(); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TCPListenSocketTest, ServerSend) { 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tester_->TestServerSend(); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TCPListenSocketTest, ServerSendMultiple) { 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tester_->TestServerSendMultiple(); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 297