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) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/tcp_client_socket.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/address_list.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/io_buffer.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/net_errors.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_log.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_log_unittest.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/test_completion_callback.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/winsock_init.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/dns/mock_host_resolver.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/client_socket_factory.h" 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/socket/tcp_listen_socket.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/platform_test.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kServerReply[] = "HTTP/1.1 404 Not Found"; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum ClientSocketTestTypes { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TCP, 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SCTP 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TransportClientSocketTest 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public StreamListenSocket::Delegate, 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public ::testing::TestWithParam<ClientSocketTestTypes> { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransportClientSocketTest() 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : listen_port_(0), 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_factory_(ClientSocketFactory::GetDefaultFactory()), 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close_server_socket_on_next_send_(false) { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~TransportClientSocketTest() { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Implement StreamListenSocket::Delegate methods 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void DidAccept(StreamListenSocket* server, 5158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_ptr<StreamListenSocket> connection) OVERRIDE { 5258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) connected_sock_.reset( 5358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) static_cast<TCPListenSocket*>(connection.release())); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void DidRead(StreamListenSocket*, const char* str, int len) OVERRIDE { 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(dkegel): this might not be long enough to tickle some bugs. 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connected_sock_->Send(kServerReply, arraysize(kServerReply) - 1, 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false /* Don't append line feed */); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (close_server_socket_on_next_send_) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseServerSocket(); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void DidClose(StreamListenSocket* sock) OVERRIDE {} 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Testcase hooks 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetUp(); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CloseServerSocket() { 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // delete the connected_sock_, which will close it. 6958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) connected_sock_.reset(); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void PauseServerReads() { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connected_sock_->PauseReads(); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ResumeServerReads() { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connected_sock_->ResumeReads(); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int DrainClientSocket(IOBuffer* buf, 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 buf_len, 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 bytes_to_read, 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback* callback); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SendClientRequest(); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void set_close_server_socket_on_next_send(bool close) { 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close_server_socket_on_next_send_ = close; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int listen_port_; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CapturingNetLog net_log_; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClientSocketFactory* const socket_factory_; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<StreamSocket> sock_; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 9858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_ptr<TCPListenSocket> listen_sock_; 9958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_ptr<TCPListenSocket> connected_sock_; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool close_server_socket_on_next_send_; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TransportClientSocketTest::SetUp() { 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::testing::TestWithParam<ClientSocketTestTypes>::SetUp(); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find a free port to listen on 10758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_ptr<TCPListenSocket> sock; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int port; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Range of ports to listen on. Shouldn't need to try many. 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kMinPort = 10100; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kMaxPort = 10200; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnsureWinsockInit(); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (port = kMinPort; port < kMaxPort; port++) { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sock = TCPListenSocket::CreateAndListen("127.0.0.1", port, this); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sock.get()) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASSERT_TRUE(sock.get() != NULL); 12158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) listen_sock_ = sock.Pass(); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listen_port_ = port; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddressList addr; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // MockHostResolver resolves everything to 127.0.0.1. 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<HostResolver> resolver(new MockHostResolver()); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HostResolver::RequestInfo info(HostPortPair("localhost", listen_port_)); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback; 1293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int rv = resolver->Resolve( 1303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) info, DEFAULT_PRIORITY, &addr, callback.callback(), NULL, BoundNetLog()); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_EQ(ERR_IO_PENDING, rv); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = callback.WaitForResult(); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_EQ(rv, OK); 1343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) sock_ = 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_factory_->CreateTransportClientSocket(addr, 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &net_log_, 1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NetLog::Source()); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int TransportClientSocketTest::DrainClientSocket( 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IOBuffer* buf, uint32 buf_len, 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 bytes_to_read, TestCompletionCallback* callback) { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = OK; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 bytes_read = 0; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (bytes_read < bytes_to_read) { 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = sock_->Read(buf, buf_len, callback->callback()); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv == ERR_IO_PENDING) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = callback->WaitForResult(); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GE(rv, 0); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_read += rv; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<int>(bytes_read); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TransportClientSocketTest::SendClientRequest() { 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char request_text[] = "GET / HTTP/1.0\r\n\r\n"; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<IOBuffer> request_buffer( 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new IOBuffer(arraysize(request_text) - 1)); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1); 168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) rv = sock_->Write( 169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) request_buffer.get(), arraysize(request_text) - 1, callback.callback()); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv == ERR_IO_PENDING) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = callback.WaitForResult(); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(rv, static_cast<int>(arraysize(request_text) - 1)); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(leighton): Add SCTP to this list when it is ready. 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)INSTANTIATE_TEST_CASE_P(StreamSocket, 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransportClientSocketTest, 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::testing::Values(TCP)); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(TransportClientSocketTest, Connect) { 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(sock_->IsConnected()); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = sock_->Connect(callback.callback()); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::CapturingNetLog::CapturedEntryList net_log_entries; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log_.GetEntries(&net_log_entries); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(net::LogContainsBeginEvent( 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log_entries, 0, net::NetLog::TYPE_SOCKET_ALIVE)); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(net::LogContainsBeginEvent( 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log_entries, 1, net::NetLog::TYPE_TCP_CONNECT)); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != OK) { 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(rv, ERR_IO_PENDING); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = callback.WaitForResult(); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(rv, OK); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(sock_->IsConnected()); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log_.GetEntries(&net_log_entries); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(net::LogContainsEndEvent( 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log_entries, -1, net::NetLog::TYPE_TCP_CONNECT)); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sock_->Disconnect(); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(sock_->IsConnected()); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(TransportClientSocketTest, IsConnected) { 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<IOBuffer> buf(new IOBuffer(4096)); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 bytes_read; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(sock_->IsConnected()); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(sock_->IsConnectedAndIdle()); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = sock_->Connect(callback.callback()); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != OK) { 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(rv, ERR_IO_PENDING); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = callback.WaitForResult(); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(rv, OK); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(sock_->IsConnected()); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(sock_->IsConnectedAndIdle()); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Send the request and wait for the server to respond. 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendClientRequest(); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Drain a single byte so we know we've received some data. 229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bytes_read = DrainClientSocket(buf.get(), 1, 1, &callback); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(bytes_read, 1u); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Socket should be considered connected, but not idle, due to 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pending data. 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(sock_->IsConnected()); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(sock_->IsConnectedAndIdle()); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 237868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bytes_read = DrainClientSocket( 238868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) buf.get(), 4096, arraysize(kServerReply) - 2, &callback); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(bytes_read, arraysize(kServerReply) - 2); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // After draining the data, the socket should be back to connected 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and idle. 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(sock_->IsConnected()); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(sock_->IsConnectedAndIdle()); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This time close the server socket immediately after the server response. 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_close_server_socket_on_next_send(true); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendClientRequest(); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bytes_read = DrainClientSocket(buf.get(), 1, 1, &callback); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(bytes_read, 1u); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // As above because of data. 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(sock_->IsConnected()); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(sock_->IsConnectedAndIdle()); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 257868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bytes_read = DrainClientSocket( 258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) buf.get(), 4096, arraysize(kServerReply) - 2, &callback); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(bytes_read, arraysize(kServerReply) - 2); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Once the data is drained, the socket should now be seen as not 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // connected. 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sock_->IsConnected()) { 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In the unlikely event that the server's connection closure is not 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // processed in time, wait for the connection to be closed. 266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) rv = sock_->Read(buf.get(), 4096, callback.callback()); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, callback.GetResult(rv)); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(sock_->IsConnected()); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(sock_->IsConnectedAndIdle()); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(TransportClientSocketTest, Read) { 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = sock_->Connect(callback.callback()); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != OK) { 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(rv, ERR_IO_PENDING); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = callback.WaitForResult(); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(rv, OK); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendClientRequest(); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<IOBuffer> buf(new IOBuffer(4096)); 285868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) uint32 bytes_read = DrainClientSocket( 286868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) buf.get(), 4096, arraysize(kServerReply) - 1, &callback); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(bytes_read, arraysize(kServerReply) - 1); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // All data has been read now. Read once more to force an ERR_IO_PENDING, and 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // then close the server socket, and note the close. 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 292868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) rv = sock_->Read(buf.get(), 4096, callback.callback()); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(ERR_IO_PENDING, rv); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseServerSocket(); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, callback.WaitForResult()); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(TransportClientSocketTest, Read_SmallChunks) { 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback; 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = sock_->Connect(callback.callback()); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != OK) { 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(rv, ERR_IO_PENDING); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = callback.WaitForResult(); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(rv, OK); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendClientRequest(); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<IOBuffer> buf(new IOBuffer(1)); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 bytes_read = 0; 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (bytes_read < arraysize(kServerReply) - 1) { 312868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) rv = sock_->Read(buf.get(), 1, callback.callback()); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv == ERR_IO_PENDING) 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = callback.WaitForResult(); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1, rv); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_read += rv; 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // All data has been read now. Read once more to force an ERR_IO_PENDING, and 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // then close the server socket, and note the close. 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) rv = sock_->Read(buf.get(), 1, callback.callback()); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(ERR_IO_PENDING, rv); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseServerSocket(); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, callback.WaitForResult()); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(TransportClientSocketTest, Read_Interrupted) { 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback; 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = sock_->Connect(callback.callback()); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != OK) { 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(ERR_IO_PENDING, rv); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = callback.WaitForResult(); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(rv, OK); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendClientRequest(); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Do a partial read and then exit. This test should not crash! 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<IOBuffer> buf(new IOBuffer(16)); 344868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) rv = sock_->Read(buf.get(), 16, callback.callback()); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (rv == ERR_IO_PENDING) 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = callback.WaitForResult(); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_NE(0, rv); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(TransportClientSocketTest, DISABLED_FullDuplex_ReadFirst) { 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback; 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = sock_->Connect(callback.callback()); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != OK) { 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(rv, ERR_IO_PENDING); 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = callback.WaitForResult(); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(rv, OK); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Read first. There's no data, so it should return ERR_IO_PENDING. 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kBufLen = 4096; 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<IOBuffer> buf(new IOBuffer(kBufLen)); 366868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) rv = sock_->Read(buf.get(), kBufLen, callback.callback()); 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, rv); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PauseServerReads(); 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kWriteBufLen = 64 * 1024; 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kWriteBufLen)); 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* request_data = request_buffer->data(); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(request_data, 'A', kWriteBufLen); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback write_callback; 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (true) { 377868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) rv = sock_->Write( 378868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) request_buffer.get(), kWriteBufLen, write_callback.callback()); 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv == ERR_IO_PENDING) { 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResumeServerReads(); 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = write_callback.WaitForResult(); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // At this point, both read and write have returned ERR_IO_PENDING, and the 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // write callback has executed. We wait for the read callback to run now to 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // make sure that the socket can handle full duplex communications. 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = callback.WaitForResult(); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GE(rv, 0); 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(TransportClientSocketTest, DISABLED_FullDuplex_WriteFirst) { 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback; 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = sock_->Connect(callback.callback()); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != OK) { 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(ERR_IO_PENDING, rv); 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = callback.WaitForResult(); 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, rv); 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PauseServerReads(); 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kWriteBufLen = 64 * 1024; 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kWriteBufLen)); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* request_data = request_buffer->data(); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(request_data, 'A', kWriteBufLen); 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback write_callback; 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (true) { 414868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) rv = sock_->Write( 415868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) request_buffer.get(), kWriteBufLen, write_callback.callback()); 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv == ERR_IO_PENDING) 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now we have the Write() blocked on ERR_IO_PENDING. It's time to force the 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Read() to block on ERR_IO_PENDING too. 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kBufLen = 4096; 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<IOBuffer> buf(new IOBuffer(kBufLen)); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (true) { 428868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) rv = sock_->Read(buf.get(), kBufLen, callback.callback()); 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv == ERR_IO_PENDING) 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // At this point, both read and write have returned ERR_IO_PENDING. Now we 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // run the write and read callbacks to make sure they can handle full duplex 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // communications. 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResumeServerReads(); 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = write_callback.WaitForResult(); 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GE(rv, 0); 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It's possible the read is blocked because it's already read all the data. 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Close the server socket, so there will at least be a 0-byte read. 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseServerSocket(); 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = callback.WaitForResult(); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GE(rv, 0); 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 451