| OLD | NEW |
| 1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/socket/tcp_client_socket.h" | 5 #include "net/socket/tcp_client_socket.h" |
| 6 | 6 |
| 7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "net/base/address_list.h" | 8 #include "net/base/address_list.h" |
| 9 #include "net/base/host_resolver.h" | 9 #include "net/base/host_resolver.h" |
| 10 #include "net/base/io_buffer.h" | 10 #include "net/base/io_buffer.h" |
| 11 #include "net/base/listen_socket.h" | 11 #include "net/base/listen_socket.h" |
| 12 #include "net/base/net_log.h" | 12 #include "net/base/net_log.h" |
| 13 #include "net/base/net_log_unittest.h" | 13 #include "net/base/net_log_unittest.h" |
| 14 #include "net/base/net_errors.h" | 14 #include "net/base/net_errors.h" |
| 15 #include "net/base/test_completion_callback.h" | 15 #include "net/base/test_completion_callback.h" |
| 16 #include "net/base/winsock_init.h" | 16 #include "net/base/winsock_init.h" |
| 17 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
| 18 #include "testing/platform_test.h" | 18 #include "testing/platform_test.h" |
| 19 | 19 |
| 20 namespace net { | 20 namespace net { |
| 21 | 21 |
| 22 namespace { | 22 namespace { |
| 23 | 23 |
| 24 const char kServerReply[] = "HTTP/1.1 404 Not Found"; | 24 const char kServerReply[] = "HTTP/1.1 404 Not Found"; |
| 25 | 25 |
| 26 class TCPClientSocketTest | 26 class TCPClientSocketTest |
| 27 : public PlatformTest, public ListenSocket::ListenSocketDelegate { | 27 : public PlatformTest, public ListenSocket::ListenSocketDelegate { |
| 28 public: | 28 public: |
| 29 TCPClientSocketTest() { | 29 TCPClientSocketTest() : net_log_(CapturingNetLog::kUnbounded) { |
| 30 } | 30 } |
| 31 | 31 |
| 32 // Implement ListenSocketDelegate methods | 32 // Implement ListenSocketDelegate methods |
| 33 virtual void DidAccept(ListenSocket* server, ListenSocket* connection) { | 33 virtual void DidAccept(ListenSocket* server, ListenSocket* connection) { |
| 34 connected_sock_ = connection; | 34 connected_sock_ = connection; |
| 35 } | 35 } |
| 36 virtual void DidRead(ListenSocket*, const std::string& s) { | 36 virtual void DidRead(ListenSocket*, const std::string& s) { |
| 37 // TODO(dkegel): this might not be long enough to tickle some bugs. | 37 // TODO(dkegel): this might not be long enough to tickle some bugs. |
| 38 connected_sock_->Send(kServerReply, | 38 connected_sock_->Send(kServerReply, |
| 39 arraysize(kServerReply) - 1, | 39 arraysize(kServerReply) - 1, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 52 void PauseServerReads() { | 52 void PauseServerReads() { |
| 53 connected_sock_->PauseReads(); | 53 connected_sock_->PauseReads(); |
| 54 } | 54 } |
| 55 | 55 |
| 56 void ResumeServerReads() { | 56 void ResumeServerReads() { |
| 57 connected_sock_->ResumeReads(); | 57 connected_sock_->ResumeReads(); |
| 58 } | 58 } |
| 59 | 59 |
| 60 protected: | 60 protected: |
| 61 int listen_port_; | 61 int listen_port_; |
| 62 CapturingNetLog net_log_; |
| 62 scoped_ptr<TCPClientSocket> sock_; | 63 scoped_ptr<TCPClientSocket> sock_; |
| 63 | 64 |
| 64 private: | 65 private: |
| 65 scoped_refptr<ListenSocket> listen_sock_; | 66 scoped_refptr<ListenSocket> listen_sock_; |
| 66 scoped_refptr<ListenSocket> connected_sock_; | 67 scoped_refptr<ListenSocket> connected_sock_; |
| 67 }; | 68 }; |
| 68 | 69 |
| 69 void TCPClientSocketTest::SetUp() { | 70 void TCPClientSocketTest::SetUp() { |
| 70 PlatformTest::SetUp(); | 71 PlatformTest::SetUp(); |
| 71 | 72 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 85 } | 86 } |
| 86 ASSERT_TRUE(sock != NULL); | 87 ASSERT_TRUE(sock != NULL); |
| 87 listen_sock_ = sock; | 88 listen_sock_ = sock; |
| 88 listen_port_ = port; | 89 listen_port_ = port; |
| 89 | 90 |
| 90 AddressList addr; | 91 AddressList addr; |
| 91 scoped_refptr<HostResolver> resolver(CreateSystemHostResolver(NULL)); | 92 scoped_refptr<HostResolver> resolver(CreateSystemHostResolver(NULL)); |
| 92 HostResolver::RequestInfo info("localhost", listen_port_); | 93 HostResolver::RequestInfo info("localhost", listen_port_); |
| 93 int rv = resolver->Resolve(info, &addr, NULL, NULL, NULL); | 94 int rv = resolver->Resolve(info, &addr, NULL, NULL, NULL); |
| 94 CHECK_EQ(rv, OK); | 95 CHECK_EQ(rv, OK); |
| 95 sock_.reset(new TCPClientSocket(addr)); | 96 sock_.reset(new TCPClientSocket(addr, &net_log_)); |
| 96 } | 97 } |
| 97 | 98 |
| 98 TEST_F(TCPClientSocketTest, Connect) { | 99 TEST_F(TCPClientSocketTest, Connect) { |
| 99 TestCompletionCallback callback; | 100 TestCompletionCallback callback; |
| 100 EXPECT_FALSE(sock_->IsConnected()); | 101 EXPECT_FALSE(sock_->IsConnected()); |
| 101 | 102 |
| 102 CapturingBoundNetLog log(CapturingNetLog::kUnbounded); | 103 int rv = sock_->Connect(&callback); |
| 103 int rv = sock_->Connect(&callback, log.bound()); | |
| 104 EXPECT_TRUE(net::LogContainsBeginEvent( | 104 EXPECT_TRUE(net::LogContainsBeginEvent( |
| 105 log.entries(), 0, net::NetLog::TYPE_TCP_CONNECT)); | 105 net_log_.entries(), 0, net::NetLog::TYPE_TCP_CONNECT)); |
| 106 if (rv != OK) { | 106 if (rv != OK) { |
| 107 ASSERT_EQ(rv, ERR_IO_PENDING); | 107 ASSERT_EQ(rv, ERR_IO_PENDING); |
| 108 EXPECT_FALSE(net::LogContainsEndEvent( | 108 EXPECT_FALSE(net::LogContainsEndEvent( |
| 109 log.entries(), -1, net::NetLog::TYPE_TCP_CONNECT)); | 109 net_log_.entries(), -1, net::NetLog::TYPE_TCP_CONNECT)); |
| 110 | 110 |
| 111 rv = callback.WaitForResult(); | 111 rv = callback.WaitForResult(); |
| 112 EXPECT_EQ(rv, OK); | 112 EXPECT_EQ(rv, OK); |
| 113 } | 113 } |
| 114 | 114 |
| 115 EXPECT_TRUE(sock_->IsConnected()); | 115 EXPECT_TRUE(sock_->IsConnected()); |
| 116 EXPECT_TRUE(net::LogContainsEndEvent( | 116 EXPECT_TRUE(net::LogContainsEndEvent( |
| 117 log.entries(), -1, net::NetLog::TYPE_TCP_CONNECT)); | 117 net_log_.entries(), -1, net::NetLog::TYPE_TCP_CONNECT)); |
| 118 | 118 |
| 119 sock_->Disconnect(); | 119 sock_->Disconnect(); |
| 120 EXPECT_FALSE(sock_->IsConnected()); | 120 EXPECT_FALSE(sock_->IsConnected()); |
| 121 } | 121 } |
| 122 | 122 |
| 123 // TODO(wtc): Add unit tests for IsConnectedAndIdle: | 123 // TODO(wtc): Add unit tests for IsConnectedAndIdle: |
| 124 // - Server closes a connection. | 124 // - Server closes a connection. |
| 125 // - Server sends data unexpectedly. | 125 // - Server sends data unexpectedly. |
| 126 | 126 |
| 127 TEST_F(TCPClientSocketTest, Read) { | 127 TEST_F(TCPClientSocketTest, Read) { |
| 128 TestCompletionCallback callback; | 128 TestCompletionCallback callback; |
| 129 int rv = sock_->Connect(&callback, NULL); | 129 int rv = sock_->Connect(&callback); |
| 130 if (rv != OK) { | 130 if (rv != OK) { |
| 131 ASSERT_EQ(rv, ERR_IO_PENDING); | 131 ASSERT_EQ(rv, ERR_IO_PENDING); |
| 132 | 132 |
| 133 rv = callback.WaitForResult(); | 133 rv = callback.WaitForResult(); |
| 134 EXPECT_EQ(rv, OK); | 134 EXPECT_EQ(rv, OK); |
| 135 } | 135 } |
| 136 | 136 |
| 137 const char request_text[] = "GET / HTTP/1.0\r\n\r\n"; | 137 const char request_text[] = "GET / HTTP/1.0\r\n\r\n"; |
| 138 scoped_refptr<IOBuffer> request_buffer = | 138 scoped_refptr<IOBuffer> request_buffer = |
| 139 new IOBuffer(arraysize(request_text) - 1); | 139 new IOBuffer(arraysize(request_text) - 1); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 164 // then close the server socket, and note the close. | 164 // then close the server socket, and note the close. |
| 165 | 165 |
| 166 rv = sock_->Read(buf, 4096, &callback); | 166 rv = sock_->Read(buf, 4096, &callback); |
| 167 ASSERT_EQ(ERR_IO_PENDING, rv); | 167 ASSERT_EQ(ERR_IO_PENDING, rv); |
| 168 CloseServerSocket(); | 168 CloseServerSocket(); |
| 169 EXPECT_EQ(0, callback.WaitForResult()); | 169 EXPECT_EQ(0, callback.WaitForResult()); |
| 170 } | 170 } |
| 171 | 171 |
| 172 TEST_F(TCPClientSocketTest, Read_SmallChunks) { | 172 TEST_F(TCPClientSocketTest, Read_SmallChunks) { |
| 173 TestCompletionCallback callback; | 173 TestCompletionCallback callback; |
| 174 int rv = sock_->Connect(&callback, NULL); | 174 int rv = sock_->Connect(&callback); |
| 175 if (rv != OK) { | 175 if (rv != OK) { |
| 176 ASSERT_EQ(rv, ERR_IO_PENDING); | 176 ASSERT_EQ(rv, ERR_IO_PENDING); |
| 177 | 177 |
| 178 rv = callback.WaitForResult(); | 178 rv = callback.WaitForResult(); |
| 179 EXPECT_EQ(rv, OK); | 179 EXPECT_EQ(rv, OK); |
| 180 } | 180 } |
| 181 | 181 |
| 182 const char request_text[] = "GET / HTTP/1.0\r\n\r\n"; | 182 const char request_text[] = "GET / HTTP/1.0\r\n\r\n"; |
| 183 scoped_refptr<IOBuffer> request_buffer = | 183 scoped_refptr<IOBuffer> request_buffer = |
| 184 new IOBuffer(arraysize(request_text) - 1); | 184 new IOBuffer(arraysize(request_text) - 1); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 209 // then close the server socket, and note the close. | 209 // then close the server socket, and note the close. |
| 210 | 210 |
| 211 rv = sock_->Read(buf, 1, &callback); | 211 rv = sock_->Read(buf, 1, &callback); |
| 212 ASSERT_EQ(ERR_IO_PENDING, rv); | 212 ASSERT_EQ(ERR_IO_PENDING, rv); |
| 213 CloseServerSocket(); | 213 CloseServerSocket(); |
| 214 EXPECT_EQ(0, callback.WaitForResult()); | 214 EXPECT_EQ(0, callback.WaitForResult()); |
| 215 } | 215 } |
| 216 | 216 |
| 217 TEST_F(TCPClientSocketTest, Read_Interrupted) { | 217 TEST_F(TCPClientSocketTest, Read_Interrupted) { |
| 218 TestCompletionCallback callback; | 218 TestCompletionCallback callback; |
| 219 int rv = sock_->Connect(&callback, NULL); | 219 int rv = sock_->Connect(&callback); |
| 220 if (rv != OK) { | 220 if (rv != OK) { |
| 221 ASSERT_EQ(ERR_IO_PENDING, rv); | 221 ASSERT_EQ(ERR_IO_PENDING, rv); |
| 222 | 222 |
| 223 rv = callback.WaitForResult(); | 223 rv = callback.WaitForResult(); |
| 224 EXPECT_EQ(rv, OK); | 224 EXPECT_EQ(rv, OK); |
| 225 } | 225 } |
| 226 | 226 |
| 227 const char request_text[] = "GET / HTTP/1.0\r\n\r\n"; | 227 const char request_text[] = "GET / HTTP/1.0\r\n\r\n"; |
| 228 scoped_refptr<IOBuffer> request_buffer = | 228 scoped_refptr<IOBuffer> request_buffer = |
| 229 new IOBuffer(arraysize(request_text) - 1); | 229 new IOBuffer(arraysize(request_text) - 1); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 243 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); | 243 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); |
| 244 | 244 |
| 245 if (rv == ERR_IO_PENDING) | 245 if (rv == ERR_IO_PENDING) |
| 246 rv = callback.WaitForResult(); | 246 rv = callback.WaitForResult(); |
| 247 | 247 |
| 248 EXPECT_NE(0, rv); | 248 EXPECT_NE(0, rv); |
| 249 } | 249 } |
| 250 | 250 |
| 251 TEST_F(TCPClientSocketTest, DISABLED_FullDuplex_ReadFirst) { | 251 TEST_F(TCPClientSocketTest, DISABLED_FullDuplex_ReadFirst) { |
| 252 TestCompletionCallback callback; | 252 TestCompletionCallback callback; |
| 253 int rv = sock_->Connect(&callback, NULL); | 253 int rv = sock_->Connect(&callback); |
| 254 if (rv != OK) { | 254 if (rv != OK) { |
| 255 ASSERT_EQ(rv, ERR_IO_PENDING); | 255 ASSERT_EQ(rv, ERR_IO_PENDING); |
| 256 | 256 |
| 257 rv = callback.WaitForResult(); | 257 rv = callback.WaitForResult(); |
| 258 EXPECT_EQ(rv, OK); | 258 EXPECT_EQ(rv, OK); |
| 259 } | 259 } |
| 260 | 260 |
| 261 // Read first. There's no data, so it should return ERR_IO_PENDING. | 261 // Read first. There's no data, so it should return ERR_IO_PENDING. |
| 262 const int kBufLen = 4096; | 262 const int kBufLen = 4096; |
| 263 scoped_refptr<IOBuffer> buf = new IOBuffer(kBufLen); | 263 scoped_refptr<IOBuffer> buf = new IOBuffer(kBufLen); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 285 // At this point, both read and write have returned ERR_IO_PENDING, and the | 285 // At this point, both read and write have returned ERR_IO_PENDING, and the |
| 286 // write callback has executed. We wait for the read callback to run now to | 286 // write callback has executed. We wait for the read callback to run now to |
| 287 // make sure that the socket can handle full duplex communications. | 287 // make sure that the socket can handle full duplex communications. |
| 288 | 288 |
| 289 rv = callback.WaitForResult(); | 289 rv = callback.WaitForResult(); |
| 290 EXPECT_GE(rv, 0); | 290 EXPECT_GE(rv, 0); |
| 291 } | 291 } |
| 292 | 292 |
| 293 TEST_F(TCPClientSocketTest, DISABLED_FullDuplex_WriteFirst) { | 293 TEST_F(TCPClientSocketTest, DISABLED_FullDuplex_WriteFirst) { |
| 294 TestCompletionCallback callback; | 294 TestCompletionCallback callback; |
| 295 int rv = sock_->Connect(&callback, NULL); | 295 int rv = sock_->Connect(&callback); |
| 296 if (rv != OK) { | 296 if (rv != OK) { |
| 297 ASSERT_EQ(ERR_IO_PENDING, rv); | 297 ASSERT_EQ(ERR_IO_PENDING, rv); |
| 298 | 298 |
| 299 rv = callback.WaitForResult(); | 299 rv = callback.WaitForResult(); |
| 300 EXPECT_EQ(OK, rv); | 300 EXPECT_EQ(OK, rv); |
| 301 } | 301 } |
| 302 | 302 |
| 303 PauseServerReads(); | 303 PauseServerReads(); |
| 304 const int kWriteBufLen = 64 * 1024; | 304 const int kWriteBufLen = 64 * 1024; |
| 305 scoped_refptr<IOBuffer> request_buffer = new IOBuffer(kWriteBufLen); | 305 scoped_refptr<IOBuffer> request_buffer = new IOBuffer(kWriteBufLen); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 339 // Close the server socket, so there will at least be a 0-byte read. | 339 // Close the server socket, so there will at least be a 0-byte read. |
| 340 CloseServerSocket(); | 340 CloseServerSocket(); |
| 341 | 341 |
| 342 rv = callback.WaitForResult(); | 342 rv = callback.WaitForResult(); |
| 343 EXPECT_GE(rv, 0); | 343 EXPECT_GE(rv, 0); |
| 344 } | 344 } |
| 345 | 345 |
| 346 } // namespace | 346 } // namespace |
| 347 | 347 |
| 348 } // namespace net | 348 } // namespace net |
| OLD | NEW |