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