Evict resources from resource pool after timeout
[chromium-blink-merge.git] / net / socket / transport_client_socket_unittest.cc
blob9ab358cb8917be165a65bc2200a6e26f82316ce5
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.
5 #include <string>
7 #include "base/basictypes.h"
8 #include "base/bind.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/run_loop.h"
12 #include "net/base/address_list.h"
13 #include "net/base/io_buffer.h"
14 #include "net/base/net_errors.h"
15 #include "net/base/test_completion_callback.h"
16 #include "net/dns/mock_host_resolver.h"
17 #include "net/log/net_log.h"
18 #include "net/log/test_net_log.h"
19 #include "net/log/test_net_log_entry.h"
20 #include "net/log/test_net_log_util.h"
21 #include "net/socket/client_socket_factory.h"
22 #include "net/socket/tcp_client_socket.h"
23 #include "net/socket/tcp_server_socket.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25 #include "testing/platform_test.h"
27 namespace net {
29 namespace {
31 const char kServerReply[] = "HTTP/1.1 404 Not Found";
33 enum ClientSocketTestTypes { TCP, SCTP };
35 } // namespace
37 class TransportClientSocketTest
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) {}
45 virtual ~TransportClientSocketTest() {}
47 // Testcase hooks
48 void SetUp() override;
50 void CloseServerSocket() {
51 // delete the connected_sock_, which will close it.
52 connected_sock_.reset();
55 void AcceptCallback(int res) {
56 ASSERT_EQ(OK, res);
57 connect_loop_.Quit();
60 int DrainClientSocket(IOBuffer* buf,
61 uint32 buf_len,
62 uint32 bytes_to_read,
63 TestCompletionCallback* callback);
65 // Establishes a connection to the server.
66 void EstablishConnection(TestCompletionCallback* callback);
68 // Sends a request from the client to the server socket. Makes the server read
69 // the request and send a response.
70 void SendRequestAndResponse();
72 // Makes |connected_sock_| to read |expected_bytes_read| bytes. Returns the
73 // the data read as a string.
74 std::string ReadServerData(int expected_bytes_read);
76 // Sends server response.
77 void SendServerResponse();
79 void set_close_server_socket_on_next_send(bool close) {
80 close_server_socket_on_next_send_ = close;
83 protected:
84 base::RunLoop connect_loop_;
85 uint16 listen_port_;
86 TestNetLog net_log_;
87 ClientSocketFactory* const socket_factory_;
88 scoped_ptr<StreamSocket> sock_;
89 scoped_ptr<StreamSocket> connected_sock_;
91 private:
92 scoped_ptr<TCPServerSocket> listen_sock_;
93 bool close_server_socket_on_next_send_;
96 void TransportClientSocketTest::SetUp() {
97 ::testing::TestWithParam<ClientSocketTestTypes>::SetUp();
99 // Open a server socket on an ephemeral port.
100 listen_sock_.reset(new TCPServerSocket(NULL, NetLog::Source()));
101 IPAddressNumber address;
102 ParseIPLiteralToNumber("127.0.0.1", &address);
103 IPEndPoint local_address(address, 0);
104 ASSERT_EQ(OK, listen_sock_->Listen(local_address, 1));
105 // Get the server's address (including the actual port number).
106 ASSERT_EQ(OK, listen_sock_->GetLocalAddress(&local_address));
107 listen_port_ = local_address.port();
108 listen_sock_->Accept(&connected_sock_,
109 base::Bind(&TransportClientSocketTest::AcceptCallback,
110 base::Unretained(this)));
112 AddressList addr;
113 // MockHostResolver resolves everything to 127.0.0.1.
114 scoped_ptr<HostResolver> resolver(new MockHostResolver());
115 HostResolver::RequestInfo info(HostPortPair("localhost", listen_port_));
116 TestCompletionCallback callback;
117 int rv = resolver->Resolve(info, DEFAULT_PRIORITY, &addr, callback.callback(),
118 NULL, BoundNetLog());
119 CHECK_EQ(ERR_IO_PENDING, rv);
120 rv = callback.WaitForResult();
121 CHECK_EQ(rv, OK);
122 sock_ = socket_factory_->CreateTransportClientSocket(addr, &net_log_,
123 NetLog::Source());
126 int TransportClientSocketTest::DrainClientSocket(
127 IOBuffer* buf,
128 uint32 buf_len,
129 uint32 bytes_to_read,
130 TestCompletionCallback* callback) {
131 int rv = OK;
132 uint32 bytes_read = 0;
134 while (bytes_read < bytes_to_read) {
135 rv = sock_->Read(buf, buf_len, callback->callback());
136 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
137 rv = callback->GetResult(rv);
138 EXPECT_GT(rv, 0);
139 bytes_read += rv;
142 return static_cast<int>(bytes_read);
145 void TransportClientSocketTest::EstablishConnection(
146 TestCompletionCallback* callback) {
147 int rv = sock_->Connect(callback->callback());
148 // Wait for |listen_sock_| to accept a connection.
149 connect_loop_.Run();
150 // Now wait for the client socket to accept the connection.
151 EXPECT_EQ(OK, callback->GetResult(rv));
154 void TransportClientSocketTest::SendRequestAndResponse() {
155 // Send client request.
156 const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
157 int request_len = strlen(request_text);
158 scoped_refptr<DrainableIOBuffer> request_buffer(
159 new DrainableIOBuffer(new IOBuffer(request_len), request_len));
160 memcpy(request_buffer->data(), request_text, request_len);
162 int bytes_written = 0;
163 while (request_buffer->BytesRemaining() > 0) {
164 TestCompletionCallback write_callback;
165 int write_result =
166 sock_->Write(request_buffer.get(), request_buffer->BytesRemaining(),
167 write_callback.callback());
168 write_result = write_callback.GetResult(write_result);
169 ASSERT_GT(write_result, 0);
170 ASSERT_LE(bytes_written + write_result, request_len);
171 request_buffer->DidConsume(write_result);
172 bytes_written += write_result;
174 ASSERT_EQ(request_len, bytes_written);
176 // Confirm that the server receives what client sent.
177 std::string data_received = ReadServerData(bytes_written);
178 ASSERT_TRUE(connected_sock_->IsConnectedAndIdle());
179 ASSERT_EQ(request_text, data_received);
181 // Write server response.
182 SendServerResponse();
185 void TransportClientSocketTest::SendServerResponse() {
186 // TODO(dkegel): this might not be long enough to tickle some bugs.
187 int reply_len = strlen(kServerReply);
188 scoped_refptr<DrainableIOBuffer> write_buffer(
189 new DrainableIOBuffer(new IOBuffer(reply_len), reply_len));
190 memcpy(write_buffer->data(), kServerReply, reply_len);
191 int bytes_written = 0;
192 while (write_buffer->BytesRemaining() > 0) {
193 TestCompletionCallback write_callback;
194 int write_result = connected_sock_->Write(write_buffer.get(),
195 write_buffer->BytesRemaining(),
196 write_callback.callback());
197 write_result = write_callback.GetResult(write_result);
198 ASSERT_GE(write_result, 0);
199 ASSERT_LE(bytes_written + write_result, reply_len);
200 write_buffer->DidConsume(write_result);
201 bytes_written += write_result;
203 if (close_server_socket_on_next_send_)
204 CloseServerSocket();
207 std::string TransportClientSocketTest::ReadServerData(int expected_bytes_read) {
208 int bytes_read = 0;
209 scoped_refptr<IOBufferWithSize> read_buffer(
210 new IOBufferWithSize(expected_bytes_read));
211 while (bytes_read < expected_bytes_read) {
212 TestCompletionCallback read_callback;
213 int rv = connected_sock_->Read(read_buffer.get(),
214 expected_bytes_read - bytes_read,
215 read_callback.callback());
216 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
217 rv = read_callback.GetResult(rv);
218 EXPECT_GE(rv, 0);
219 bytes_read += rv;
221 EXPECT_EQ(expected_bytes_read, bytes_read);
222 return std::string(read_buffer->data(), bytes_read);
225 // TODO(leighton): Add SCTP to this list when it is ready.
226 INSTANTIATE_TEST_CASE_P(StreamSocket,
227 TransportClientSocketTest,
228 ::testing::Values(TCP));
230 TEST_P(TransportClientSocketTest, Connect) {
231 TestCompletionCallback callback;
232 EXPECT_FALSE(sock_->IsConnected());
234 int rv = sock_->Connect(callback.callback());
235 // Wait for |listen_sock_| to accept a connection.
236 connect_loop_.Run();
238 TestNetLogEntry::List net_log_entries;
239 net_log_.GetEntries(&net_log_entries);
240 EXPECT_TRUE(
241 LogContainsBeginEvent(net_log_entries, 0, NetLog::TYPE_SOCKET_ALIVE));
242 EXPECT_TRUE(
243 LogContainsBeginEvent(net_log_entries, 1, NetLog::TYPE_TCP_CONNECT));
244 // Now wait for the client socket to accept the connection.
245 if (rv != OK) {
246 ASSERT_EQ(rv, ERR_IO_PENDING);
247 rv = callback.WaitForResult();
248 EXPECT_EQ(rv, OK);
251 EXPECT_TRUE(sock_->IsConnected());
252 net_log_.GetEntries(&net_log_entries);
253 EXPECT_TRUE(
254 LogContainsEndEvent(net_log_entries, -1, NetLog::TYPE_TCP_CONNECT));
256 sock_->Disconnect();
257 EXPECT_FALSE(sock_->IsConnected());
260 TEST_P(TransportClientSocketTest, IsConnected) {
261 scoped_refptr<IOBuffer> buf(new IOBuffer(4096));
262 TestCompletionCallback callback;
263 uint32 bytes_read;
265 EXPECT_FALSE(sock_->IsConnected());
266 EXPECT_FALSE(sock_->IsConnectedAndIdle());
268 EstablishConnection(&callback);
270 EXPECT_TRUE(sock_->IsConnected());
271 EXPECT_TRUE(sock_->IsConnectedAndIdle());
273 // Send the request and wait for the server to respond.
274 SendRequestAndResponse();
276 // Drain a single byte so we know we've received some data.
277 bytes_read = DrainClientSocket(buf.get(), 1, 1, &callback);
278 ASSERT_EQ(bytes_read, 1u);
280 // Socket should be considered connected, but not idle, due to
281 // pending data.
282 EXPECT_TRUE(sock_->IsConnected());
283 EXPECT_FALSE(sock_->IsConnectedAndIdle());
285 bytes_read =
286 DrainClientSocket(buf.get(), 4096, strlen(kServerReply) - 1, &callback);
287 ASSERT_EQ(bytes_read, strlen(kServerReply) - 1);
289 // After draining the data, the socket should be back to connected
290 // and idle.
291 EXPECT_TRUE(sock_->IsConnected());
292 EXPECT_TRUE(sock_->IsConnectedAndIdle());
294 // This time close the server socket immediately after the server response.
295 set_close_server_socket_on_next_send(true);
296 SendRequestAndResponse();
298 bytes_read = DrainClientSocket(buf.get(), 1, 1, &callback);
299 ASSERT_EQ(bytes_read, 1u);
301 // As above because of data.
302 EXPECT_TRUE(sock_->IsConnected());
303 EXPECT_FALSE(sock_->IsConnectedAndIdle());
305 bytes_read =
306 DrainClientSocket(buf.get(), 4096, strlen(kServerReply) - 1, &callback);
307 ASSERT_EQ(bytes_read, strlen(kServerReply) - 1);
309 // Once the data is drained, the socket should now be seen as not
310 // connected.
311 if (sock_->IsConnected()) {
312 // In the unlikely event that the server's connection closure is not
313 // processed in time, wait for the connection to be closed.
314 int rv = sock_->Read(buf.get(), 4096, callback.callback());
315 EXPECT_EQ(0, callback.GetResult(rv));
316 EXPECT_FALSE(sock_->IsConnected());
318 EXPECT_FALSE(sock_->IsConnectedAndIdle());
321 TEST_P(TransportClientSocketTest, Read) {
322 TestCompletionCallback callback;
323 EstablishConnection(&callback);
325 SendRequestAndResponse();
327 scoped_refptr<IOBuffer> buf(new IOBuffer(4096));
328 uint32 bytes_read =
329 DrainClientSocket(buf.get(), 4096, strlen(kServerReply), &callback);
330 ASSERT_EQ(bytes_read, strlen(kServerReply));
331 ASSERT_EQ(std::string(kServerReply), std::string(buf->data(), bytes_read));
333 // All data has been read now. Read once more to force an ERR_IO_PENDING, and
334 // then close the server socket, and note the close.
336 int rv = sock_->Read(buf.get(), 4096, callback.callback());
337 ASSERT_EQ(ERR_IO_PENDING, rv);
338 CloseServerSocket();
339 EXPECT_EQ(0, callback.WaitForResult());
342 TEST_P(TransportClientSocketTest, Read_SmallChunks) {
343 TestCompletionCallback callback;
344 EstablishConnection(&callback);
346 SendRequestAndResponse();
348 scoped_refptr<IOBuffer> buf(new IOBuffer(1));
349 uint32 bytes_read = 0;
350 while (bytes_read < strlen(kServerReply)) {
351 int rv = sock_->Read(buf.get(), 1, callback.callback());
352 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
354 rv = callback.GetResult(rv);
356 ASSERT_EQ(1, rv);
357 bytes_read += rv;
360 // All data has been read now. Read once more to force an ERR_IO_PENDING, and
361 // then close the server socket, and note the close.
363 int rv = sock_->Read(buf.get(), 1, callback.callback());
364 ASSERT_EQ(ERR_IO_PENDING, rv);
365 CloseServerSocket();
366 EXPECT_EQ(0, callback.WaitForResult());
369 TEST_P(TransportClientSocketTest, Read_Interrupted) {
370 TestCompletionCallback callback;
371 EstablishConnection(&callback);
373 SendRequestAndResponse();
375 // Do a partial read and then exit. This test should not crash!
376 scoped_refptr<IOBuffer> buf(new IOBuffer(16));
377 int rv = sock_->Read(buf.get(), 16, callback.callback());
378 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
380 rv = callback.GetResult(rv);
382 EXPECT_NE(0, rv);
385 TEST_P(TransportClientSocketTest, FullDuplex_ReadFirst) {
386 TestCompletionCallback callback;
387 EstablishConnection(&callback);
389 // Read first. There's no data, so it should return ERR_IO_PENDING.
390 const int kBufLen = 4096;
391 scoped_refptr<IOBuffer> buf(new IOBuffer(kBufLen));
392 int rv = sock_->Read(buf.get(), kBufLen, callback.callback());
393 EXPECT_EQ(ERR_IO_PENDING, rv);
395 const int kWriteBufLen = 64 * 1024;
396 scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kWriteBufLen));
397 char* request_data = request_buffer->data();
398 memset(request_data, 'A', kWriteBufLen);
399 TestCompletionCallback write_callback;
401 int bytes_written = 0;
402 while (true) {
403 rv = sock_->Write(request_buffer.get(), kWriteBufLen,
404 write_callback.callback());
405 ASSERT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
406 if (rv == ERR_IO_PENDING) {
407 ReadServerData(bytes_written);
408 SendServerResponse();
409 rv = write_callback.WaitForResult();
410 break;
412 bytes_written += rv;
415 // At this point, both read and write have returned ERR_IO_PENDING, and the
416 // write callback has executed. We wait for the read callback to run now to
417 // make sure that the socket can handle full duplex communications.
419 rv = callback.WaitForResult();
420 EXPECT_GE(rv, 0);
423 TEST_P(TransportClientSocketTest, FullDuplex_WriteFirst) {
424 TestCompletionCallback callback;
425 EstablishConnection(&callback);
427 const int kWriteBufLen = 64 * 1024;
428 scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kWriteBufLen));
429 char* request_data = request_buffer->data();
430 memset(request_data, 'A', kWriteBufLen);
431 TestCompletionCallback write_callback;
433 int bytes_written = 0;
434 while (true) {
435 int rv = sock_->Write(request_buffer.get(), kWriteBufLen,
436 write_callback.callback());
437 ASSERT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
439 if (rv == ERR_IO_PENDING)
440 break;
441 bytes_written += rv;
444 // Now we have the Write() blocked on ERR_IO_PENDING. It's time to force the
445 // Read() to block on ERR_IO_PENDING too.
447 const int kBufLen = 4096;
448 scoped_refptr<IOBuffer> buf(new IOBuffer(kBufLen));
449 while (true) {
450 int rv = sock_->Read(buf.get(), kBufLen, callback.callback());
451 ASSERT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
452 if (rv == ERR_IO_PENDING)
453 break;
456 // At this point, both read and write have returned ERR_IO_PENDING. Now we
457 // run the write and read callbacks to make sure they can handle full duplex
458 // communications.
460 ReadServerData(bytes_written);
461 SendServerResponse();
462 int rv = write_callback.WaitForResult();
463 EXPECT_GE(rv, 0);
465 // It's possible the read is blocked because it's already read all the data.
466 // Close the server socket, so there will at least be a 0-byte read.
467 CloseServerSocket();
469 rv = callback.WaitForResult();
470 EXPECT_GE(rv, 0);
473 } // namespace net