Home | History | Annotate | Download | only in socket
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "net/socket/tcp_client_socket.h"
      6 
      7 #include "base/basictypes.h"
      8 #include "base/memory/ref_counted.h"
      9 #include "base/memory/scoped_ptr.h"
     10 #include "net/base/address_list.h"
     11 #include "net/base/io_buffer.h"
     12 #include "net/base/net_errors.h"
     13 #include "net/base/net_log.h"
     14 #include "net/base/net_log_unittest.h"
     15 #include "net/base/test_completion_callback.h"
     16 #include "net/base/winsock_init.h"
     17 #include "net/dns/mock_host_resolver.h"
     18 #include "net/socket/client_socket_factory.h"
     19 #include "net/socket/tcp_listen_socket.h"
     20 #include "testing/gtest/include/gtest/gtest.h"
     21 #include "testing/platform_test.h"
     22 
     23 namespace net {
     24 
     25 namespace {
     26 
     27 const char kServerReply[] = "HTTP/1.1 404 Not Found";
     28 
     29 enum ClientSocketTestTypes {
     30   TCP,
     31   SCTP
     32 };
     33 
     34 }  // namespace
     35 
     36 class TransportClientSocketTest
     37     : public StreamListenSocket::Delegate,
     38       public ::testing::TestWithParam<ClientSocketTestTypes> {
     39  public:
     40   TransportClientSocketTest()
     41       : listen_port_(0),
     42         socket_factory_(ClientSocketFactory::GetDefaultFactory()),
     43         close_server_socket_on_next_send_(false) {
     44   }
     45 
     46   virtual ~TransportClientSocketTest() {
     47   }
     48 
     49   // Implement StreamListenSocket::Delegate methods
     50   virtual void DidAccept(StreamListenSocket* server,
     51                          StreamListenSocket* connection) OVERRIDE {
     52     connected_sock_ = reinterpret_cast<TCPListenSocket*>(connection);
     53   }
     54   virtual void DidRead(StreamListenSocket*, const char* str, int len) OVERRIDE {
     55     // TODO(dkegel): this might not be long enough to tickle some bugs.
     56     connected_sock_->Send(kServerReply, arraysize(kServerReply) - 1,
     57                           false /* Don't append line feed */);
     58     if (close_server_socket_on_next_send_)
     59       CloseServerSocket();
     60   }
     61   virtual void DidClose(StreamListenSocket* sock) OVERRIDE {}
     62 
     63   // Testcase hooks
     64   virtual void SetUp();
     65 
     66   void CloseServerSocket() {
     67     // delete the connected_sock_, which will close it.
     68     connected_sock_ = NULL;
     69   }
     70 
     71   void PauseServerReads() {
     72     connected_sock_->PauseReads();
     73   }
     74 
     75   void ResumeServerReads() {
     76     connected_sock_->ResumeReads();
     77   }
     78 
     79   int DrainClientSocket(IOBuffer* buf,
     80                         uint32 buf_len,
     81                         uint32 bytes_to_read,
     82                         TestCompletionCallback* callback);
     83 
     84   void SendClientRequest();
     85 
     86   void set_close_server_socket_on_next_send(bool close) {
     87     close_server_socket_on_next_send_ = close;
     88   }
     89 
     90  protected:
     91   int listen_port_;
     92   CapturingNetLog net_log_;
     93   ClientSocketFactory* const socket_factory_;
     94   scoped_ptr<StreamSocket> sock_;
     95 
     96  private:
     97   scoped_refptr<TCPListenSocket> listen_sock_;
     98   scoped_refptr<TCPListenSocket> connected_sock_;
     99   bool close_server_socket_on_next_send_;
    100 };
    101 
    102 void TransportClientSocketTest::SetUp() {
    103   ::testing::TestWithParam<ClientSocketTestTypes>::SetUp();
    104 
    105   // Find a free port to listen on
    106   scoped_refptr<TCPListenSocket> sock;
    107   int port;
    108   // Range of ports to listen on.  Shouldn't need to try many.
    109   const int kMinPort = 10100;
    110   const int kMaxPort = 10200;
    111 #if defined(OS_WIN)
    112   EnsureWinsockInit();
    113 #endif
    114   for (port = kMinPort; port < kMaxPort; port++) {
    115     sock = TCPListenSocket::CreateAndListen("127.0.0.1", port, this);
    116     if (sock.get())
    117       break;
    118   }
    119   ASSERT_TRUE(sock.get() != NULL);
    120   listen_sock_ = sock;
    121   listen_port_ = port;
    122 
    123   AddressList addr;
    124   // MockHostResolver resolves everything to 127.0.0.1.
    125   scoped_ptr<HostResolver> resolver(new MockHostResolver());
    126   HostResolver::RequestInfo info(HostPortPair("localhost", listen_port_));
    127   TestCompletionCallback callback;
    128   int rv = resolver->Resolve(info, &addr, callback.callback(), NULL,
    129                              BoundNetLog());
    130   CHECK_EQ(ERR_IO_PENDING, rv);
    131   rv = callback.WaitForResult();
    132   CHECK_EQ(rv, OK);
    133   sock_.reset(
    134       socket_factory_->CreateTransportClientSocket(addr,
    135                                                    &net_log_,
    136                                                    NetLog::Source()));
    137 }
    138 
    139 int TransportClientSocketTest::DrainClientSocket(
    140     IOBuffer* buf, uint32 buf_len,
    141     uint32 bytes_to_read, TestCompletionCallback* callback) {
    142   int rv = OK;
    143   uint32 bytes_read = 0;
    144 
    145   while (bytes_read < bytes_to_read) {
    146     rv = sock_->Read(buf, buf_len, callback->callback());
    147     EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
    148 
    149     if (rv == ERR_IO_PENDING)
    150       rv = callback->WaitForResult();
    151 
    152     EXPECT_GE(rv, 0);
    153     bytes_read += rv;
    154   }
    155 
    156   return static_cast<int>(bytes_read);
    157 }
    158 
    159 void TransportClientSocketTest::SendClientRequest() {
    160   const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
    161   scoped_refptr<IOBuffer> request_buffer(
    162       new IOBuffer(arraysize(request_text) - 1));
    163   TestCompletionCallback callback;
    164   int rv;
    165 
    166   memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1);
    167   rv = sock_->Write(
    168       request_buffer.get(), arraysize(request_text) - 1, callback.callback());
    169   EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
    170 
    171   if (rv == ERR_IO_PENDING)
    172     rv = callback.WaitForResult();
    173   EXPECT_EQ(rv, static_cast<int>(arraysize(request_text) - 1));
    174 }
    175 
    176 // TODO(leighton):  Add SCTP to this list when it is ready.
    177 INSTANTIATE_TEST_CASE_P(StreamSocket,
    178                         TransportClientSocketTest,
    179                         ::testing::Values(TCP));
    180 
    181 TEST_P(TransportClientSocketTest, Connect) {
    182   TestCompletionCallback callback;
    183   EXPECT_FALSE(sock_->IsConnected());
    184 
    185   int rv = sock_->Connect(callback.callback());
    186 
    187   net::CapturingNetLog::CapturedEntryList net_log_entries;
    188   net_log_.GetEntries(&net_log_entries);
    189   EXPECT_TRUE(net::LogContainsBeginEvent(
    190       net_log_entries, 0, net::NetLog::TYPE_SOCKET_ALIVE));
    191   EXPECT_TRUE(net::LogContainsBeginEvent(
    192       net_log_entries, 1, net::NetLog::TYPE_TCP_CONNECT));
    193   if (rv != OK) {
    194     ASSERT_EQ(rv, ERR_IO_PENDING);
    195     rv = callback.WaitForResult();
    196     EXPECT_EQ(rv, OK);
    197   }
    198 
    199   EXPECT_TRUE(sock_->IsConnected());
    200   net_log_.GetEntries(&net_log_entries);
    201   EXPECT_TRUE(net::LogContainsEndEvent(
    202       net_log_entries, -1, net::NetLog::TYPE_TCP_CONNECT));
    203 
    204   sock_->Disconnect();
    205   EXPECT_FALSE(sock_->IsConnected());
    206 }
    207 
    208 TEST_P(TransportClientSocketTest, IsConnected) {
    209   scoped_refptr<IOBuffer> buf(new IOBuffer(4096));
    210   TestCompletionCallback callback;
    211   uint32 bytes_read;
    212 
    213   EXPECT_FALSE(sock_->IsConnected());
    214   EXPECT_FALSE(sock_->IsConnectedAndIdle());
    215   int rv = sock_->Connect(callback.callback());
    216   if (rv != OK) {
    217     ASSERT_EQ(rv, ERR_IO_PENDING);
    218     rv = callback.WaitForResult();
    219     EXPECT_EQ(rv, OK);
    220   }
    221   EXPECT_TRUE(sock_->IsConnected());
    222   EXPECT_TRUE(sock_->IsConnectedAndIdle());
    223 
    224   // Send the request and wait for the server to respond.
    225   SendClientRequest();
    226 
    227   // Drain a single byte so we know we've received some data.
    228   bytes_read = DrainClientSocket(buf.get(), 1, 1, &callback);
    229   ASSERT_EQ(bytes_read, 1u);
    230 
    231   // Socket should be considered connected, but not idle, due to
    232   // pending data.
    233   EXPECT_TRUE(sock_->IsConnected());
    234   EXPECT_FALSE(sock_->IsConnectedAndIdle());
    235 
    236   bytes_read = DrainClientSocket(
    237       buf.get(), 4096, arraysize(kServerReply) - 2, &callback);
    238   ASSERT_EQ(bytes_read, arraysize(kServerReply) - 2);
    239 
    240   // After draining the data, the socket should be back to connected
    241   // and idle.
    242   EXPECT_TRUE(sock_->IsConnected());
    243   EXPECT_TRUE(sock_->IsConnectedAndIdle());
    244 
    245   // This time close the server socket immediately after the server response.
    246   set_close_server_socket_on_next_send(true);
    247   SendClientRequest();
    248 
    249   bytes_read = DrainClientSocket(buf.get(), 1, 1, &callback);
    250   ASSERT_EQ(bytes_read, 1u);
    251 
    252   // As above because of data.
    253   EXPECT_TRUE(sock_->IsConnected());
    254   EXPECT_FALSE(sock_->IsConnectedAndIdle());
    255 
    256   bytes_read = DrainClientSocket(
    257       buf.get(), 4096, arraysize(kServerReply) - 2, &callback);
    258   ASSERT_EQ(bytes_read, arraysize(kServerReply) - 2);
    259 
    260   // Once the data is drained, the socket should now be seen as not
    261   // connected.
    262   if (sock_->IsConnected()) {
    263     // In the unlikely event that the server's connection closure is not
    264     // processed in time, wait for the connection to be closed.
    265     rv = sock_->Read(buf.get(), 4096, callback.callback());
    266     EXPECT_EQ(0, callback.GetResult(rv));
    267     EXPECT_FALSE(sock_->IsConnected());
    268   }
    269   EXPECT_FALSE(sock_->IsConnectedAndIdle());
    270 }
    271 
    272 TEST_P(TransportClientSocketTest, Read) {
    273   TestCompletionCallback callback;
    274   int rv = sock_->Connect(callback.callback());
    275   if (rv != OK) {
    276     ASSERT_EQ(rv, ERR_IO_PENDING);
    277 
    278     rv = callback.WaitForResult();
    279     EXPECT_EQ(rv, OK);
    280   }
    281   SendClientRequest();
    282 
    283   scoped_refptr<IOBuffer> buf(new IOBuffer(4096));
    284   uint32 bytes_read = DrainClientSocket(
    285       buf.get(), 4096, arraysize(kServerReply) - 1, &callback);
    286   ASSERT_EQ(bytes_read, arraysize(kServerReply) - 1);
    287 
    288   // All data has been read now.  Read once more to force an ERR_IO_PENDING, and
    289   // then close the server socket, and note the close.
    290 
    291   rv = sock_->Read(buf.get(), 4096, callback.callback());
    292   ASSERT_EQ(ERR_IO_PENDING, rv);
    293   CloseServerSocket();
    294   EXPECT_EQ(0, callback.WaitForResult());
    295 }
    296 
    297 TEST_P(TransportClientSocketTest, Read_SmallChunks) {
    298   TestCompletionCallback callback;
    299   int rv = sock_->Connect(callback.callback());
    300   if (rv != OK) {
    301     ASSERT_EQ(rv, ERR_IO_PENDING);
    302 
    303     rv = callback.WaitForResult();
    304     EXPECT_EQ(rv, OK);
    305   }
    306   SendClientRequest();
    307 
    308   scoped_refptr<IOBuffer> buf(new IOBuffer(1));
    309   uint32 bytes_read = 0;
    310   while (bytes_read < arraysize(kServerReply) - 1) {
    311     rv = sock_->Read(buf.get(), 1, callback.callback());
    312     EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
    313 
    314     if (rv == ERR_IO_PENDING)
    315       rv = callback.WaitForResult();
    316 
    317     ASSERT_EQ(1, rv);
    318     bytes_read += rv;
    319   }
    320 
    321   // All data has been read now.  Read once more to force an ERR_IO_PENDING, and
    322   // then close the server socket, and note the close.
    323 
    324   rv = sock_->Read(buf.get(), 1, callback.callback());
    325   ASSERT_EQ(ERR_IO_PENDING, rv);
    326   CloseServerSocket();
    327   EXPECT_EQ(0, callback.WaitForResult());
    328 }
    329 
    330 TEST_P(TransportClientSocketTest, Read_Interrupted) {
    331   TestCompletionCallback callback;
    332   int rv = sock_->Connect(callback.callback());
    333   if (rv != OK) {
    334     ASSERT_EQ(ERR_IO_PENDING, rv);
    335 
    336     rv = callback.WaitForResult();
    337     EXPECT_EQ(rv, OK);
    338   }
    339   SendClientRequest();
    340 
    341   // Do a partial read and then exit.  This test should not crash!
    342   scoped_refptr<IOBuffer> buf(new IOBuffer(16));
    343   rv = sock_->Read(buf.get(), 16, callback.callback());
    344   EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
    345 
    346   if (rv == ERR_IO_PENDING)
    347     rv = callback.WaitForResult();
    348 
    349   EXPECT_NE(0, rv);
    350 }
    351 
    352 TEST_P(TransportClientSocketTest, DISABLED_FullDuplex_ReadFirst) {
    353   TestCompletionCallback callback;
    354   int rv = sock_->Connect(callback.callback());
    355   if (rv != OK) {
    356     ASSERT_EQ(rv, ERR_IO_PENDING);
    357 
    358     rv = callback.WaitForResult();
    359     EXPECT_EQ(rv, OK);
    360   }
    361 
    362   // Read first.  There's no data, so it should return ERR_IO_PENDING.
    363   const int kBufLen = 4096;
    364   scoped_refptr<IOBuffer> buf(new IOBuffer(kBufLen));
    365   rv = sock_->Read(buf.get(), kBufLen, callback.callback());
    366   EXPECT_EQ(ERR_IO_PENDING, rv);
    367 
    368   PauseServerReads();
    369   const int kWriteBufLen = 64 * 1024;
    370   scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kWriteBufLen));
    371   char* request_data = request_buffer->data();
    372   memset(request_data, 'A', kWriteBufLen);
    373   TestCompletionCallback write_callback;
    374 
    375   while (true) {
    376     rv = sock_->Write(
    377         request_buffer.get(), kWriteBufLen, write_callback.callback());
    378     ASSERT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
    379 
    380     if (rv == ERR_IO_PENDING) {
    381       ResumeServerReads();
    382       rv = write_callback.WaitForResult();
    383       break;
    384     }
    385   }
    386 
    387   // At this point, both read and write have returned ERR_IO_PENDING, and the
    388   // write callback has executed.  We wait for the read callback to run now to
    389   // make sure that the socket can handle full duplex communications.
    390 
    391   rv = callback.WaitForResult();
    392   EXPECT_GE(rv, 0);
    393 }
    394 
    395 TEST_P(TransportClientSocketTest, DISABLED_FullDuplex_WriteFirst) {
    396   TestCompletionCallback callback;
    397   int rv = sock_->Connect(callback.callback());
    398   if (rv != OK) {
    399     ASSERT_EQ(ERR_IO_PENDING, rv);
    400 
    401     rv = callback.WaitForResult();
    402     EXPECT_EQ(OK, rv);
    403   }
    404 
    405   PauseServerReads();
    406   const int kWriteBufLen = 64 * 1024;
    407   scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kWriteBufLen));
    408   char* request_data = request_buffer->data();
    409   memset(request_data, 'A', kWriteBufLen);
    410   TestCompletionCallback write_callback;
    411 
    412   while (true) {
    413     rv = sock_->Write(
    414         request_buffer.get(), kWriteBufLen, write_callback.callback());
    415     ASSERT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
    416 
    417     if (rv == ERR_IO_PENDING)
    418       break;
    419   }
    420 
    421   // Now we have the Write() blocked on ERR_IO_PENDING.  It's time to force the
    422   // Read() to block on ERR_IO_PENDING too.
    423 
    424   const int kBufLen = 4096;
    425   scoped_refptr<IOBuffer> buf(new IOBuffer(kBufLen));
    426   while (true) {
    427     rv = sock_->Read(buf.get(), kBufLen, callback.callback());
    428     ASSERT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
    429     if (rv == ERR_IO_PENDING)
    430       break;
    431   }
    432 
    433   // At this point, both read and write have returned ERR_IO_PENDING.  Now we
    434   // run the write and read callbacks to make sure they can handle full duplex
    435   // communications.
    436 
    437   ResumeServerReads();
    438   rv = write_callback.WaitForResult();
    439   EXPECT_GE(rv, 0);
    440 
    441   // It's possible the read is blocked because it's already read all the data.
    442   // Close the server socket, so there will at least be a 0-byte read.
    443   CloseServerSocket();
    444 
    445   rv = callback.WaitForResult();
    446   EXPECT_GE(rv, 0);
    447 }
    448 
    449 }  // namespace net
    450