Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 "base/bind.h" | |
| 8 #include "base/memory/ref_counted.h" | 9 #include "base/memory/ref_counted.h" |
| 9 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| 10 #include "net/base/address_list.h" | 11 #include "net/base/address_list.h" |
| 11 #include "net/base/io_buffer.h" | 12 #include "net/base/io_buffer.h" |
| 12 #include "net/base/net_errors.h" | 13 #include "net/base/net_errors.h" |
| 13 #include "net/base/test_completion_callback.h" | 14 #include "net/base/test_completion_callback.h" |
| 14 #include "net/base/winsock_init.h" | 15 #include "net/base/winsock_init.h" |
| 15 #include "net/dns/mock_host_resolver.h" | 16 #include "net/dns/mock_host_resolver.h" |
| 16 #include "net/log/net_log.h" | 17 #include "net/log/net_log.h" |
| 17 #include "net/log/net_log_unittest.h" | 18 #include "net/log/net_log_unittest.h" |
| 18 #include "net/socket/client_socket_factory.h" | 19 #include "net/socket/client_socket_factory.h" |
| 19 #include "net/socket/tcp_listen_socket.h" | 20 #include "net/socket/tcp_server_socket.h" |
| 20 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
| 21 #include "testing/platform_test.h" | 22 #include "testing/platform_test.h" |
| 22 | 23 |
| 23 namespace net { | 24 namespace net { |
| 24 | 25 |
| 25 namespace { | 26 namespace { |
| 26 | 27 |
| 27 const char kServerReply[] = "HTTP/1.1 404 Not Found"; | 28 const char kServerReply[] = "HTTP/1.1 404 Not Found"; |
| 28 | 29 |
| 29 enum ClientSocketTestTypes { | 30 enum ClientSocketTestTypes { |
| 30 TCP, | 31 TCP, |
| 31 SCTP | 32 SCTP |
| 32 }; | 33 }; |
| 33 | 34 |
| 34 } // namespace | 35 } // namespace |
| 35 | 36 |
| 36 class TransportClientSocketTest | 37 class TransportClientSocketTest |
| 37 : public StreamListenSocket::Delegate, | 38 : public ::testing::TestWithParam<ClientSocketTestTypes> { |
| 38 public ::testing::TestWithParam<ClientSocketTestTypes> { | |
| 39 public: | 39 public: |
| 40 TransportClientSocketTest() | 40 TransportClientSocketTest() |
| 41 : listen_port_(0), | 41 : listen_port_(0), |
| 42 socket_factory_(ClientSocketFactory::GetDefaultFactory()), | 42 socket_factory_(ClientSocketFactory::GetDefaultFactory()), |
| 43 close_server_socket_on_next_send_(false) { | 43 close_server_socket_on_next_send_(false) { |
| 44 } | 44 } |
| 45 | 45 |
| 46 virtual ~TransportClientSocketTest() { | 46 virtual ~TransportClientSocketTest() { |
| 47 } | 47 } |
| 48 | 48 |
| 49 // Implement StreamListenSocket::Delegate methods | |
| 50 void DidAccept(StreamListenSocket* server, | |
| 51 scoped_ptr<StreamListenSocket> connection) override { | |
| 52 connected_sock_.reset( | |
| 53 static_cast<TCPListenSocket*>(connection.release())); | |
| 54 } | |
| 55 void DidRead(StreamListenSocket*, const char* str, int len) override { | |
| 56 // TODO(dkegel): this might not be long enough to tickle some bugs. | |
| 57 connected_sock_->Send(kServerReply, arraysize(kServerReply) - 1, | |
| 58 false /* Don't append line feed */); | |
| 59 if (close_server_socket_on_next_send_) | |
| 60 CloseServerSocket(); | |
| 61 } | |
| 62 void DidClose(StreamListenSocket* sock) override {} | |
| 63 | |
| 64 // Testcase hooks | 49 // Testcase hooks |
| 65 void SetUp() override; | 50 void SetUp() override; |
| 66 | 51 |
| 67 void CloseServerSocket() { | 52 void CloseServerSocket() { |
| 68 // delete the connected_sock_, which will close it. | 53 // delete the connected_sock_, which will close it. |
| 69 connected_sock_.reset(); | 54 connected_sock_.reset(); |
| 70 } | 55 } |
| 71 | 56 |
| 72 void PauseServerReads() { | 57 void AcceptCallback(int res) {} |
| 73 connected_sock_->PauseReads(); | |
| 74 } | |
| 75 | |
| 76 void ResumeServerReads() { | |
| 77 connected_sock_->ResumeReads(); | |
| 78 } | |
| 79 | 58 |
| 80 int DrainClientSocket(IOBuffer* buf, | 59 int DrainClientSocket(IOBuffer* buf, |
| 81 uint32 buf_len, | 60 uint32 buf_len, |
| 82 uint32 bytes_to_read, | 61 uint32 bytes_to_read, |
| 83 TestCompletionCallback* callback); | 62 TestCompletionCallback* callback); |
| 84 | 63 |
| 85 void SendClientRequest(); | 64 void ProcessRequest(); |
| 86 | 65 |
| 87 void set_close_server_socket_on_next_send(bool close) { | 66 void set_close_server_socket_on_next_send(bool close) { |
| 88 close_server_socket_on_next_send_ = close; | 67 close_server_socket_on_next_send_ = close; |
| 89 } | 68 } |
| 90 | 69 |
| 91 protected: | 70 protected: |
| 92 uint16 listen_port_; | 71 uint16 listen_port_; |
| 93 CapturingNetLog net_log_; | 72 CapturingNetLog net_log_; |
| 94 ClientSocketFactory* const socket_factory_; | 73 ClientSocketFactory* const socket_factory_; |
| 95 scoped_ptr<StreamSocket> sock_; | 74 scoped_ptr<StreamSocket> sock_; |
| 96 | 75 |
| 97 private: | 76 private: |
| 98 scoped_ptr<TCPListenSocket> listen_sock_; | 77 scoped_ptr<TCPServerSocket> listen_sock_; |
| 99 scoped_ptr<TCPListenSocket> connected_sock_; | 78 scoped_ptr<StreamSocket> connected_sock_; |
| 100 bool close_server_socket_on_next_send_; | 79 bool close_server_socket_on_next_send_; |
| 101 }; | 80 }; |
| 102 | 81 |
| 103 void TransportClientSocketTest::SetUp() { | 82 void TransportClientSocketTest::SetUp() { |
| 104 ::testing::TestWithParam<ClientSocketTestTypes>::SetUp(); | 83 ::testing::TestWithParam<ClientSocketTestTypes>::SetUp(); |
| 105 | 84 |
| 85 listen_sock_.reset(new TCPServerSocket(NULL, NetLog::Source())); | |
| 106 // Find a free port to listen on | 86 // Find a free port to listen on |
| 107 scoped_ptr<TCPListenSocket> sock; | |
| 108 uint16 port; | 87 uint16 port; |
| 109 // Range of ports to listen on. Shouldn't need to try many. | 88 // Range of ports to listen on. Shouldn't need to try many. |
| 110 const uint16 kMinPort = 10100; | 89 const uint16 kMinPort = 10100; |
| 111 const uint16 kMaxPort = 10200; | 90 const uint16 kMaxPort = 10200; |
| 112 #if defined(OS_WIN) | 91 #if defined(OS_WIN) |
| 113 EnsureWinsockInit(); | 92 EnsureWinsockInit(); |
| 114 #endif | 93 #endif |
|
mmenke
2015/04/06 18:37:33
Also, we can remove this #if block - creating the
xunjieli
2015/04/08 14:47:19
Done.
| |
| 94 net::IPAddressNumber address; | |
| 95 net::ParseIPLiteralToNumber("127.0.0.1", &address); | |
| 115 for (port = kMinPort; port < kMaxPort; port++) { | 96 for (port = kMinPort; port < kMaxPort; port++) { |
|
mmenke
2015/04/06 18:30:03
While we're here, can we get rid of this loop?
I
xunjieli
2015/04/08 14:47:19
Done.
| |
| 116 sock = TCPListenSocket::CreateAndListen("127.0.0.1", port, this); | 97 if (listen_sock_->Listen(IPEndPoint(address, port), 1) == net::OK) |
| 117 if (sock.get()) | |
| 118 break; | 98 break; |
| 119 } | 99 } |
| 120 ASSERT_TRUE(sock.get() != NULL); | |
| 121 listen_sock_ = sock.Pass(); | |
| 122 listen_port_ = port; | 100 listen_port_ = port; |
| 101 listen_sock_->Accept(&connected_sock_, | |
| 102 base::Bind(&TransportClientSocketTest::AcceptCallback, | |
|
xunjieli
2015/04/03 20:19:23
Using a dummy callback here, not sure if there's a
mmenke
2015/04/06 18:30:03
How about having AcceptCallback quite a base::RunL
xunjieli
2015/04/08 14:47:19
Done. Good idea! thanks
| |
| 103 base::Unretained(this))); | |
| 123 | 104 |
| 124 AddressList addr; | 105 AddressList addr; |
| 125 // MockHostResolver resolves everything to 127.0.0.1. | 106 // MockHostResolver resolves everything to 127.0.0.1. |
| 126 scoped_ptr<HostResolver> resolver(new MockHostResolver()); | 107 scoped_ptr<HostResolver> resolver(new MockHostResolver()); |
| 127 HostResolver::RequestInfo info(HostPortPair("localhost", listen_port_)); | 108 HostResolver::RequestInfo info(HostPortPair("localhost", listen_port_)); |
| 128 TestCompletionCallback callback; | 109 TestCompletionCallback callback; |
| 129 int rv = resolver->Resolve( | 110 int rv = resolver->Resolve( |
| 130 info, DEFAULT_PRIORITY, &addr, callback.callback(), NULL, BoundNetLog()); | 111 info, DEFAULT_PRIORITY, &addr, callback.callback(), NULL, BoundNetLog()); |
| 131 CHECK_EQ(ERR_IO_PENDING, rv); | 112 CHECK_EQ(ERR_IO_PENDING, rv); |
| 132 rv = callback.WaitForResult(); | 113 rv = callback.WaitForResult(); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 150 if (rv == ERR_IO_PENDING) | 131 if (rv == ERR_IO_PENDING) |
| 151 rv = callback->WaitForResult(); | 132 rv = callback->WaitForResult(); |
| 152 | 133 |
| 153 EXPECT_GE(rv, 0); | 134 EXPECT_GE(rv, 0); |
| 154 bytes_read += rv; | 135 bytes_read += rv; |
| 155 } | 136 } |
| 156 | 137 |
| 157 return static_cast<int>(bytes_read); | 138 return static_cast<int>(bytes_read); |
| 158 } | 139 } |
| 159 | 140 |
| 160 void TransportClientSocketTest::SendClientRequest() { | 141 void TransportClientSocketTest::ProcessRequest() { |
| 142 // Send client request. | |
| 161 const char request_text[] = "GET / HTTP/1.0\r\n\r\n"; | 143 const char request_text[] = "GET / HTTP/1.0\r\n\r\n"; |
| 162 scoped_refptr<IOBuffer> request_buffer( | 144 int request_len = arraysize(request_text) - 1; |
|
mmenke
2015/04/06 18:30:03
Much cleaner to have this in a variable. Maybe ju
xunjieli
2015/04/08 14:47:19
Partially done. Sorry, I am not sure what you mean
| |
| 163 new IOBuffer(arraysize(request_text) - 1)); | 145 scoped_refptr<IOBuffer> request_buffer(new IOBuffer(request_len)); |
| 164 TestCompletionCallback callback; | 146 TestCompletionCallback callback; |
| 165 int rv; | 147 int rv; |
| 166 | 148 |
| 167 memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1); | 149 memcpy(request_buffer->data(), request_text, request_len); |
| 168 rv = sock_->Write( | 150 rv = sock_->Write(request_buffer.get(), request_len, callback.callback()); |
| 169 request_buffer.get(), arraysize(request_text) - 1, callback.callback()); | |
| 170 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); | 151 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); |
| 171 | 152 |
| 172 if (rv == ERR_IO_PENDING) | 153 if (rv == ERR_IO_PENDING) |
| 173 rv = callback.WaitForResult(); | 154 rv = callback.WaitForResult(); |
| 174 EXPECT_EQ(rv, static_cast<int>(arraysize(request_text) - 1)); | 155 EXPECT_EQ(rv, request_len); |
|
mmenke
2015/04/06 18:30:03
nit: Flip order, expected should go first (Know t
xunjieli
2015/04/08 14:47:19
Done. Right!
| |
| 156 | |
| 157 // Confirms that the server receives what client sent. | |
| 158 scoped_refptr<IOBufferWithSize> read_buffer( | |
| 159 new IOBufferWithSize(request_len + 1)); | |
|
mmenke
2015/04/06 18:30:03
Is the +1 needed?
xunjieli
2015/04/08 14:47:19
I am not sure. I thought we need to have 1 byte ex
| |
| 160 TestCompletionCallback read_callback; | |
| 161 int read_result = connected_sock_->Read( | |
| 162 read_buffer.get(), read_buffer->size(), read_callback.callback()); | |
|
mmenke
2015/04/06 18:30:03
I don't believe can actually be completely sure we
xunjieli
2015/04/08 14:47:19
Done.
| |
| 163 read_result = read_callback.GetResult(read_result); | |
| 164 ASSERT_EQ(request_len, read_result); | |
| 165 std::string message(request_text); | |
| 166 std::string received_message(read_buffer->data(), read_result); | |
| 167 ASSERT_EQ(message, received_message); | |
| 168 | |
| 169 // Write response. | |
| 170 // TODO(dkegel): this might not be long enough to tickle some bugs. | |
| 171 TestCompletionCallback write_callback; | |
| 172 scoped_refptr<IOBufferWithSize> write_buffer( | |
| 173 new IOBufferWithSize(arraysize(kServerReply))); | |
| 174 memmove(write_buffer->data(), kServerReply, arraysize(kServerReply) - 1); | |
| 175 int write_result = | |
| 176 connected_sock_->Write(write_buffer.get(), arraysize(kServerReply) - 1, | |
| 177 write_callback.callback()); | |
| 178 write_result = write_callback.GetResult(write_result); | |
|
mmenke
2015/04/06 18:30:03
Should handle ERR_IO_PENDING, like above, and I al
xunjieli
2015/04/08 14:47:19
But GetResult will wait if it is ERR_IO_PENDING ri
| |
| 179 ASSERT_EQ((int)(arraysize(kServerReply) - 1), write_result); | |
| 180 if (close_server_socket_on_next_send_) | |
| 181 CloseServerSocket(); | |
| 175 } | 182 } |
| 176 | 183 |
| 177 // TODO(leighton): Add SCTP to this list when it is ready. | 184 // TODO(leighton): Add SCTP to this list when it is ready. |
| 178 INSTANTIATE_TEST_CASE_P(StreamSocket, | 185 INSTANTIATE_TEST_CASE_P(StreamSocket, |
| 179 TransportClientSocketTest, | 186 TransportClientSocketTest, |
| 180 ::testing::Values(TCP)); | 187 ::testing::Values(TCP)); |
| 181 | 188 |
| 182 TEST_P(TransportClientSocketTest, Connect) { | 189 TEST_P(TransportClientSocketTest, Connect) { |
| 183 TestCompletionCallback callback; | 190 TestCompletionCallback callback; |
| 184 EXPECT_FALSE(sock_->IsConnected()); | 191 EXPECT_FALSE(sock_->IsConnected()); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 216 int rv = sock_->Connect(callback.callback()); | 223 int rv = sock_->Connect(callback.callback()); |
| 217 if (rv != OK) { | 224 if (rv != OK) { |
| 218 ASSERT_EQ(rv, ERR_IO_PENDING); | 225 ASSERT_EQ(rv, ERR_IO_PENDING); |
| 219 rv = callback.WaitForResult(); | 226 rv = callback.WaitForResult(); |
| 220 EXPECT_EQ(rv, OK); | 227 EXPECT_EQ(rv, OK); |
| 221 } | 228 } |
| 222 EXPECT_TRUE(sock_->IsConnected()); | 229 EXPECT_TRUE(sock_->IsConnected()); |
| 223 EXPECT_TRUE(sock_->IsConnectedAndIdle()); | 230 EXPECT_TRUE(sock_->IsConnectedAndIdle()); |
| 224 | 231 |
| 225 // Send the request and wait for the server to respond. | 232 // Send the request and wait for the server to respond. |
| 226 SendClientRequest(); | 233 ProcessRequest(); |
| 227 | 234 |
| 228 // Drain a single byte so we know we've received some data. | 235 // Drain a single byte so we know we've received some data. |
| 229 bytes_read = DrainClientSocket(buf.get(), 1, 1, &callback); | 236 bytes_read = DrainClientSocket(buf.get(), 1, 1, &callback); |
| 230 ASSERT_EQ(bytes_read, 1u); | 237 ASSERT_EQ(bytes_read, 1u); |
| 231 | 238 |
| 232 // Socket should be considered connected, but not idle, due to | 239 // Socket should be considered connected, but not idle, due to |
| 233 // pending data. | 240 // pending data. |
| 234 EXPECT_TRUE(sock_->IsConnected()); | 241 EXPECT_TRUE(sock_->IsConnected()); |
| 235 EXPECT_FALSE(sock_->IsConnectedAndIdle()); | 242 EXPECT_FALSE(sock_->IsConnectedAndIdle()); |
| 236 | 243 |
| 237 bytes_read = DrainClientSocket( | 244 bytes_read = DrainClientSocket( |
| 238 buf.get(), 4096, arraysize(kServerReply) - 2, &callback); | 245 buf.get(), 4096, arraysize(kServerReply) - 2, &callback); |
| 239 ASSERT_EQ(bytes_read, arraysize(kServerReply) - 2); | 246 ASSERT_EQ(bytes_read, arraysize(kServerReply) - 2); |
| 240 | 247 |
| 241 // After draining the data, the socket should be back to connected | 248 // After draining the data, the socket should be back to connected |
| 242 // and idle. | 249 // and idle. |
| 243 EXPECT_TRUE(sock_->IsConnected()); | 250 EXPECT_TRUE(sock_->IsConnected()); |
| 244 EXPECT_TRUE(sock_->IsConnectedAndIdle()); | 251 EXPECT_TRUE(sock_->IsConnectedAndIdle()); |
| 245 | 252 |
| 246 // This time close the server socket immediately after the server response. | 253 // This time close the server socket immediately after the server response. |
| 247 set_close_server_socket_on_next_send(true); | 254 set_close_server_socket_on_next_send(true); |
| 248 SendClientRequest(); | 255 ProcessRequest(); |
| 249 | 256 |
| 250 bytes_read = DrainClientSocket(buf.get(), 1, 1, &callback); | 257 bytes_read = DrainClientSocket(buf.get(), 1, 1, &callback); |
| 251 ASSERT_EQ(bytes_read, 1u); | 258 ASSERT_EQ(bytes_read, 1u); |
| 252 | 259 |
| 253 // As above because of data. | 260 // As above because of data. |
| 254 EXPECT_TRUE(sock_->IsConnected()); | 261 EXPECT_TRUE(sock_->IsConnected()); |
| 255 EXPECT_FALSE(sock_->IsConnectedAndIdle()); | 262 EXPECT_FALSE(sock_->IsConnectedAndIdle()); |
| 256 | 263 |
| 257 bytes_read = DrainClientSocket( | 264 bytes_read = DrainClientSocket( |
| 258 buf.get(), 4096, arraysize(kServerReply) - 2, &callback); | 265 buf.get(), 4096, arraysize(kServerReply) - 2, &callback); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 272 | 279 |
| 273 TEST_P(TransportClientSocketTest, Read) { | 280 TEST_P(TransportClientSocketTest, Read) { |
| 274 TestCompletionCallback callback; | 281 TestCompletionCallback callback; |
| 275 int rv = sock_->Connect(callback.callback()); | 282 int rv = sock_->Connect(callback.callback()); |
| 276 if (rv != OK) { | 283 if (rv != OK) { |
| 277 ASSERT_EQ(rv, ERR_IO_PENDING); | 284 ASSERT_EQ(rv, ERR_IO_PENDING); |
| 278 | 285 |
| 279 rv = callback.WaitForResult(); | 286 rv = callback.WaitForResult(); |
| 280 EXPECT_EQ(rv, OK); | 287 EXPECT_EQ(rv, OK); |
| 281 } | 288 } |
| 282 SendClientRequest(); | 289 ProcessRequest(); |
| 283 | 290 |
| 284 scoped_refptr<IOBuffer> buf(new IOBuffer(4096)); | 291 scoped_refptr<IOBuffer> buf(new IOBuffer(4096)); |
| 285 uint32 bytes_read = DrainClientSocket( | 292 uint32 bytes_read = DrainClientSocket( |
| 286 buf.get(), 4096, arraysize(kServerReply) - 1, &callback); | 293 buf.get(), 4096, arraysize(kServerReply) - 1, &callback); |
| 287 ASSERT_EQ(bytes_read, arraysize(kServerReply) - 1); | 294 ASSERT_EQ(bytes_read, arraysize(kServerReply) - 1); |
| 288 | 295 |
| 289 // All data has been read now. Read once more to force an ERR_IO_PENDING, and | 296 // All data has been read now. Read once more to force an ERR_IO_PENDING, and |
| 290 // then close the server socket, and note the close. | 297 // then close the server socket, and note the close. |
| 291 | 298 |
| 292 rv = sock_->Read(buf.get(), 4096, callback.callback()); | 299 rv = sock_->Read(buf.get(), 4096, callback.callback()); |
| 293 ASSERT_EQ(ERR_IO_PENDING, rv); | 300 ASSERT_EQ(ERR_IO_PENDING, rv); |
| 294 CloseServerSocket(); | 301 CloseServerSocket(); |
| 295 EXPECT_EQ(0, callback.WaitForResult()); | 302 EXPECT_EQ(0, callback.WaitForResult()); |
| 296 } | 303 } |
| 297 | 304 |
| 298 TEST_P(TransportClientSocketTest, Read_SmallChunks) { | 305 TEST_P(TransportClientSocketTest, Read_SmallChunks) { |
| 299 TestCompletionCallback callback; | 306 TestCompletionCallback callback; |
| 300 int rv = sock_->Connect(callback.callback()); | 307 int rv = sock_->Connect(callback.callback()); |
| 301 if (rv != OK) { | 308 if (rv != OK) { |
| 302 ASSERT_EQ(rv, ERR_IO_PENDING); | 309 ASSERT_EQ(rv, ERR_IO_PENDING); |
| 303 | 310 |
| 304 rv = callback.WaitForResult(); | 311 rv = callback.WaitForResult(); |
| 305 EXPECT_EQ(rv, OK); | 312 EXPECT_EQ(rv, OK); |
| 306 } | 313 } |
| 307 SendClientRequest(); | 314 ProcessRequest(); |
| 308 | 315 |
| 309 scoped_refptr<IOBuffer> buf(new IOBuffer(1)); | 316 scoped_refptr<IOBuffer> buf(new IOBuffer(1)); |
| 310 uint32 bytes_read = 0; | 317 uint32 bytes_read = 0; |
| 311 while (bytes_read < arraysize(kServerReply) - 1) { | 318 while (bytes_read < arraysize(kServerReply) - 1) { |
| 312 rv = sock_->Read(buf.get(), 1, callback.callback()); | 319 rv = sock_->Read(buf.get(), 1, callback.callback()); |
| 313 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); | 320 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); |
| 314 | 321 |
| 315 if (rv == ERR_IO_PENDING) | 322 if (rv == ERR_IO_PENDING) |
| 316 rv = callback.WaitForResult(); | 323 rv = callback.WaitForResult(); |
| 317 | 324 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 330 | 337 |
| 331 TEST_P(TransportClientSocketTest, Read_Interrupted) { | 338 TEST_P(TransportClientSocketTest, Read_Interrupted) { |
| 332 TestCompletionCallback callback; | 339 TestCompletionCallback callback; |
| 333 int rv = sock_->Connect(callback.callback()); | 340 int rv = sock_->Connect(callback.callback()); |
| 334 if (rv != OK) { | 341 if (rv != OK) { |
| 335 ASSERT_EQ(ERR_IO_PENDING, rv); | 342 ASSERT_EQ(ERR_IO_PENDING, rv); |
| 336 | 343 |
| 337 rv = callback.WaitForResult(); | 344 rv = callback.WaitForResult(); |
| 338 EXPECT_EQ(rv, OK); | 345 EXPECT_EQ(rv, OK); |
| 339 } | 346 } |
| 340 SendClientRequest(); | 347 ProcessRequest(); |
| 341 | 348 |
| 342 // Do a partial read and then exit. This test should not crash! | 349 // Do a partial read and then exit. This test should not crash! |
| 343 scoped_refptr<IOBuffer> buf(new IOBuffer(16)); | 350 scoped_refptr<IOBuffer> buf(new IOBuffer(16)); |
| 344 rv = sock_->Read(buf.get(), 16, callback.callback()); | 351 rv = sock_->Read(buf.get(), 16, callback.callback()); |
| 345 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); | 352 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); |
| 346 | 353 |
| 347 if (rv == ERR_IO_PENDING) | 354 if (rv == ERR_IO_PENDING) |
| 348 rv = callback.WaitForResult(); | 355 rv = callback.WaitForResult(); |
| 349 | 356 |
| 350 EXPECT_NE(0, rv); | 357 EXPECT_NE(0, rv); |
| 351 } | 358 } |
| 352 | 359 |
| 353 TEST_P(TransportClientSocketTest, DISABLED_FullDuplex_ReadFirst) { | 360 TEST_P(TransportClientSocketTest, DISABLED_FullDuplex_ReadFirst) { |
| 354 TestCompletionCallback callback; | 361 TestCompletionCallback callback; |
| 355 int rv = sock_->Connect(callback.callback()); | 362 int rv = sock_->Connect(callback.callback()); |
| 356 if (rv != OK) { | 363 if (rv != OK) { |
| 357 ASSERT_EQ(rv, ERR_IO_PENDING); | 364 ASSERT_EQ(rv, ERR_IO_PENDING); |
| 358 | 365 |
| 359 rv = callback.WaitForResult(); | 366 rv = callback.WaitForResult(); |
| 360 EXPECT_EQ(rv, OK); | 367 EXPECT_EQ(rv, OK); |
| 361 } | 368 } |
| 362 | 369 |
| 363 // Read first. There's no data, so it should return ERR_IO_PENDING. | 370 // Read first. There's no data, so it should return ERR_IO_PENDING. |
| 364 const int kBufLen = 4096; | 371 const int kBufLen = 4096; |
| 365 scoped_refptr<IOBuffer> buf(new IOBuffer(kBufLen)); | 372 scoped_refptr<IOBuffer> buf(new IOBuffer(kBufLen)); |
| 366 rv = sock_->Read(buf.get(), kBufLen, callback.callback()); | 373 rv = sock_->Read(buf.get(), kBufLen, callback.callback()); |
| 367 EXPECT_EQ(ERR_IO_PENDING, rv); | 374 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 368 | 375 |
| 369 PauseServerReads(); | 376 // PauseServerReads(); |
| 370 const int kWriteBufLen = 64 * 1024; | 377 const int kWriteBufLen = 64 * 1024; |
| 371 scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kWriteBufLen)); | 378 scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kWriteBufLen)); |
| 372 char* request_data = request_buffer->data(); | 379 char* request_data = request_buffer->data(); |
| 373 memset(request_data, 'A', kWriteBufLen); | 380 memset(request_data, 'A', kWriteBufLen); |
| 374 TestCompletionCallback write_callback; | 381 TestCompletionCallback write_callback; |
| 375 | 382 |
| 376 while (true) { | 383 while (true) { |
| 377 rv = sock_->Write( | 384 rv = sock_->Write( |
| 378 request_buffer.get(), kWriteBufLen, write_callback.callback()); | 385 request_buffer.get(), kWriteBufLen, write_callback.callback()); |
| 379 ASSERT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); | 386 ASSERT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); |
| 380 | 387 |
| 381 if (rv == ERR_IO_PENDING) { | 388 if (rv == ERR_IO_PENDING) { |
| 382 ResumeServerReads(); | 389 // ResumeServerReads(); |
| 383 rv = write_callback.WaitForResult(); | 390 rv = write_callback.WaitForResult(); |
| 384 break; | 391 break; |
| 385 } | 392 } |
| 386 } | 393 } |
| 387 | 394 |
| 388 // At this point, both read and write have returned ERR_IO_PENDING, and the | 395 // At this point, both read and write have returned ERR_IO_PENDING, and the |
| 389 // write callback has executed. We wait for the read callback to run now to | 396 // write callback has executed. We wait for the read callback to run now to |
| 390 // make sure that the socket can handle full duplex communications. | 397 // make sure that the socket can handle full duplex communications. |
| 391 | 398 |
| 392 rv = callback.WaitForResult(); | 399 rv = callback.WaitForResult(); |
|
xunjieli
2015/04/03 20:19:23
I wonder what the best way to deal with these two
mmenke
2015/04/06 18:30:03
In this test, the problem is the buffer is full.
mmenke
2015/04/06 18:44:38
One other option: You could make the connected_so
xunjieli
2015/04/08 14:47:19
Done. Right, I should have write something to conn
| |
| 393 EXPECT_GE(rv, 0); | 400 EXPECT_GE(rv, 0); |
| 394 } | 401 } |
| 395 | 402 |
| 396 TEST_P(TransportClientSocketTest, DISABLED_FullDuplex_WriteFirst) { | 403 TEST_P(TransportClientSocketTest, DISABLED_FullDuplex_WriteFirst) { |
| 397 TestCompletionCallback callback; | 404 TestCompletionCallback callback; |
| 398 int rv = sock_->Connect(callback.callback()); | 405 int rv = sock_->Connect(callback.callback()); |
| 399 if (rv != OK) { | 406 if (rv != OK) { |
| 400 ASSERT_EQ(ERR_IO_PENDING, rv); | 407 ASSERT_EQ(ERR_IO_PENDING, rv); |
| 401 | 408 |
| 402 rv = callback.WaitForResult(); | 409 rv = callback.WaitForResult(); |
| 403 EXPECT_EQ(OK, rv); | 410 EXPECT_EQ(OK, rv); |
| 404 } | 411 } |
| 405 | 412 |
| 406 PauseServerReads(); | 413 // PauseServerReads(); |
| 407 const int kWriteBufLen = 64 * 1024; | 414 const int kWriteBufLen = 64 * 1024; |
| 408 scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kWriteBufLen)); | 415 scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kWriteBufLen)); |
| 409 char* request_data = request_buffer->data(); | 416 char* request_data = request_buffer->data(); |
| 410 memset(request_data, 'A', kWriteBufLen); | 417 memset(request_data, 'A', kWriteBufLen); |
| 411 TestCompletionCallback write_callback; | 418 TestCompletionCallback write_callback; |
| 412 | 419 |
| 413 while (true) { | 420 while (true) { |
| 414 rv = sock_->Write( | 421 rv = sock_->Write( |
| 415 request_buffer.get(), kWriteBufLen, write_callback.callback()); | 422 request_buffer.get(), kWriteBufLen, write_callback.callback()); |
| 416 ASSERT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); | 423 ASSERT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 428 rv = sock_->Read(buf.get(), kBufLen, callback.callback()); | 435 rv = sock_->Read(buf.get(), kBufLen, callback.callback()); |
| 429 ASSERT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); | 436 ASSERT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); |
| 430 if (rv == ERR_IO_PENDING) | 437 if (rv == ERR_IO_PENDING) |
| 431 break; | 438 break; |
| 432 } | 439 } |
| 433 | 440 |
| 434 // At this point, both read and write have returned ERR_IO_PENDING. Now we | 441 // At this point, both read and write have returned ERR_IO_PENDING. Now we |
| 435 // run the write and read callbacks to make sure they can handle full duplex | 442 // run the write and read callbacks to make sure they can handle full duplex |
| 436 // communications. | 443 // communications. |
| 437 | 444 |
| 438 ResumeServerReads(); | 445 // ResumeServerReads(); |
| 439 rv = write_callback.WaitForResult(); | 446 rv = write_callback.WaitForResult(); |
| 440 EXPECT_GE(rv, 0); | 447 EXPECT_GE(rv, 0); |
| 441 | 448 |
| 442 // It's possible the read is blocked because it's already read all the data. | 449 // It's possible the read is blocked because it's already read all the data. |
| 443 // Close the server socket, so there will at least be a 0-byte read. | 450 // Close the server socket, so there will at least be a 0-byte read. |
| 444 CloseServerSocket(); | 451 CloseServerSocket(); |
| 445 | 452 |
| 446 rv = callback.WaitForResult(); | 453 rv = callback.WaitForResult(); |
| 447 EXPECT_GE(rv, 0); | 454 EXPECT_GE(rv, 0); |
| 448 } | 455 } |
| 449 | 456 |
| 450 } // namespace net | 457 } // namespace net |
| OLD | NEW |