| 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/memory/ref_counted.h" | 8 #include "base/memory/ref_counted.h" |
| 9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
| 10 #include "net/base/address_list.h" | 10 #include "net/base/address_list.h" |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 109 const int kMinPort = 10100; | 109 const int kMinPort = 10100; |
| 110 const int kMaxPort = 10200; | 110 const int kMaxPort = 10200; |
| 111 #if defined(OS_WIN) | 111 #if defined(OS_WIN) |
| 112 EnsureWinsockInit(); | 112 EnsureWinsockInit(); |
| 113 #endif | 113 #endif |
| 114 for (port = kMinPort; port < kMaxPort; port++) { | 114 for (port = kMinPort; port < kMaxPort; port++) { |
| 115 sock = TCPListenSocket::CreateAndListen("127.0.0.1", port, this); | 115 sock = TCPListenSocket::CreateAndListen("127.0.0.1", port, this); |
| 116 if (sock.get()) | 116 if (sock.get()) |
| 117 break; | 117 break; |
| 118 } | 118 } |
| 119 ASSERT_TRUE(sock != NULL); | 119 ASSERT_TRUE(sock.get() != NULL); |
| 120 listen_sock_ = sock; | 120 listen_sock_ = sock; |
| 121 listen_port_ = port; | 121 listen_port_ = port; |
| 122 | 122 |
| 123 AddressList addr; | 123 AddressList addr; |
| 124 // MockHostResolver resolves everything to 127.0.0.1. | 124 // MockHostResolver resolves everything to 127.0.0.1. |
| 125 scoped_ptr<HostResolver> resolver(new MockHostResolver()); | 125 scoped_ptr<HostResolver> resolver(new MockHostResolver()); |
| 126 HostResolver::RequestInfo info(HostPortPair("localhost", listen_port_)); | 126 HostResolver::RequestInfo info(HostPortPair("localhost", listen_port_)); |
| 127 TestCompletionCallback callback; | 127 TestCompletionCallback callback; |
| 128 int rv = resolver->Resolve(info, &addr, callback.callback(), NULL, | 128 int rv = resolver->Resolve(info, &addr, callback.callback(), NULL, |
| 129 BoundNetLog()); | 129 BoundNetLog()); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 157 } | 157 } |
| 158 | 158 |
| 159 void TransportClientSocketTest::SendClientRequest() { | 159 void TransportClientSocketTest::SendClientRequest() { |
| 160 const char request_text[] = "GET / HTTP/1.0\r\n\r\n"; | 160 const char request_text[] = "GET / HTTP/1.0\r\n\r\n"; |
| 161 scoped_refptr<IOBuffer> request_buffer( | 161 scoped_refptr<IOBuffer> request_buffer( |
| 162 new IOBuffer(arraysize(request_text) - 1)); | 162 new IOBuffer(arraysize(request_text) - 1)); |
| 163 TestCompletionCallback callback; | 163 TestCompletionCallback callback; |
| 164 int rv; | 164 int rv; |
| 165 | 165 |
| 166 memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1); | 166 memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1); |
| 167 rv = sock_->Write(request_buffer, arraysize(request_text) - 1, | 167 rv = sock_->Write( |
| 168 callback.callback()); | 168 request_buffer.get(), arraysize(request_text) - 1, callback.callback()); |
| 169 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); | 169 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); |
| 170 | 170 |
| 171 if (rv == ERR_IO_PENDING) | 171 if (rv == ERR_IO_PENDING) |
| 172 rv = callback.WaitForResult(); | 172 rv = callback.WaitForResult(); |
| 173 EXPECT_EQ(rv, static_cast<int>(arraysize(request_text) - 1)); | 173 EXPECT_EQ(rv, static_cast<int>(arraysize(request_text) - 1)); |
| 174 } | 174 } |
| 175 | 175 |
| 176 // TODO(leighton): Add SCTP to this list when it is ready. | 176 // TODO(leighton): Add SCTP to this list when it is ready. |
| 177 INSTANTIATE_TEST_CASE_P(StreamSocket, | 177 INSTANTIATE_TEST_CASE_P(StreamSocket, |
| 178 TransportClientSocketTest, | 178 TransportClientSocketTest, |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 218 rv = callback.WaitForResult(); | 218 rv = callback.WaitForResult(); |
| 219 EXPECT_EQ(rv, OK); | 219 EXPECT_EQ(rv, OK); |
| 220 } | 220 } |
| 221 EXPECT_TRUE(sock_->IsConnected()); | 221 EXPECT_TRUE(sock_->IsConnected()); |
| 222 EXPECT_TRUE(sock_->IsConnectedAndIdle()); | 222 EXPECT_TRUE(sock_->IsConnectedAndIdle()); |
| 223 | 223 |
| 224 // Send the request and wait for the server to respond. | 224 // Send the request and wait for the server to respond. |
| 225 SendClientRequest(); | 225 SendClientRequest(); |
| 226 | 226 |
| 227 // Drain a single byte so we know we've received some data. | 227 // Drain a single byte so we know we've received some data. |
| 228 bytes_read = DrainClientSocket(buf, 1, 1, &callback); | 228 bytes_read = DrainClientSocket(buf.get(), 1, 1, &callback); |
| 229 ASSERT_EQ(bytes_read, 1u); | 229 ASSERT_EQ(bytes_read, 1u); |
| 230 | 230 |
| 231 // Socket should be considered connected, but not idle, due to | 231 // Socket should be considered connected, but not idle, due to |
| 232 // pending data. | 232 // pending data. |
| 233 EXPECT_TRUE(sock_->IsConnected()); | 233 EXPECT_TRUE(sock_->IsConnected()); |
| 234 EXPECT_FALSE(sock_->IsConnectedAndIdle()); | 234 EXPECT_FALSE(sock_->IsConnectedAndIdle()); |
| 235 | 235 |
| 236 bytes_read = DrainClientSocket(buf, 4096, arraysize(kServerReply) - 2, | 236 bytes_read = DrainClientSocket( |
| 237 &callback); | 237 buf.get(), 4096, arraysize(kServerReply) - 2, &callback); |
| 238 ASSERT_EQ(bytes_read, arraysize(kServerReply) - 2); | 238 ASSERT_EQ(bytes_read, arraysize(kServerReply) - 2); |
| 239 | 239 |
| 240 // After draining the data, the socket should be back to connected | 240 // After draining the data, the socket should be back to connected |
| 241 // and idle. | 241 // and idle. |
| 242 EXPECT_TRUE(sock_->IsConnected()); | 242 EXPECT_TRUE(sock_->IsConnected()); |
| 243 EXPECT_TRUE(sock_->IsConnectedAndIdle()); | 243 EXPECT_TRUE(sock_->IsConnectedAndIdle()); |
| 244 | 244 |
| 245 // This time close the server socket immediately after the server response. | 245 // This time close the server socket immediately after the server response. |
| 246 set_close_server_socket_on_next_send(true); | 246 set_close_server_socket_on_next_send(true); |
| 247 SendClientRequest(); | 247 SendClientRequest(); |
| 248 | 248 |
| 249 bytes_read = DrainClientSocket(buf, 1, 1, &callback); | 249 bytes_read = DrainClientSocket(buf.get(), 1, 1, &callback); |
| 250 ASSERT_EQ(bytes_read, 1u); | 250 ASSERT_EQ(bytes_read, 1u); |
| 251 | 251 |
| 252 // As above because of data. | 252 // As above because of data. |
| 253 EXPECT_TRUE(sock_->IsConnected()); | 253 EXPECT_TRUE(sock_->IsConnected()); |
| 254 EXPECT_FALSE(sock_->IsConnectedAndIdle()); | 254 EXPECT_FALSE(sock_->IsConnectedAndIdle()); |
| 255 | 255 |
| 256 bytes_read = DrainClientSocket(buf, 4096, arraysize(kServerReply) - 2, | 256 bytes_read = DrainClientSocket( |
| 257 &callback); | 257 buf.get(), 4096, arraysize(kServerReply) - 2, &callback); |
| 258 ASSERT_EQ(bytes_read, arraysize(kServerReply) - 2); | 258 ASSERT_EQ(bytes_read, arraysize(kServerReply) - 2); |
| 259 | 259 |
| 260 // Once the data is drained, the socket should now be seen as not | 260 // Once the data is drained, the socket should now be seen as not |
| 261 // connected. | 261 // connected. |
| 262 if (sock_->IsConnected()) { | 262 if (sock_->IsConnected()) { |
| 263 // In the unlikely event that the server's connection closure is not | 263 // In the unlikely event that the server's connection closure is not |
| 264 // processed in time, wait for the connection to be closed. | 264 // processed in time, wait for the connection to be closed. |
| 265 rv = sock_->Read(buf, 4096, callback.callback()); | 265 rv = sock_->Read(buf.get(), 4096, callback.callback()); |
| 266 EXPECT_EQ(0, callback.GetResult(rv)); | 266 EXPECT_EQ(0, callback.GetResult(rv)); |
| 267 EXPECT_FALSE(sock_->IsConnected()); | 267 EXPECT_FALSE(sock_->IsConnected()); |
| 268 } | 268 } |
| 269 EXPECT_FALSE(sock_->IsConnectedAndIdle()); | 269 EXPECT_FALSE(sock_->IsConnectedAndIdle()); |
| 270 } | 270 } |
| 271 | 271 |
| 272 TEST_P(TransportClientSocketTest, Read) { | 272 TEST_P(TransportClientSocketTest, Read) { |
| 273 TestCompletionCallback callback; | 273 TestCompletionCallback callback; |
| 274 int rv = sock_->Connect(callback.callback()); | 274 int rv = sock_->Connect(callback.callback()); |
| 275 if (rv != OK) { | 275 if (rv != OK) { |
| 276 ASSERT_EQ(rv, ERR_IO_PENDING); | 276 ASSERT_EQ(rv, ERR_IO_PENDING); |
| 277 | 277 |
| 278 rv = callback.WaitForResult(); | 278 rv = callback.WaitForResult(); |
| 279 EXPECT_EQ(rv, OK); | 279 EXPECT_EQ(rv, OK); |
| 280 } | 280 } |
| 281 SendClientRequest(); | 281 SendClientRequest(); |
| 282 | 282 |
| 283 scoped_refptr<IOBuffer> buf(new IOBuffer(4096)); | 283 scoped_refptr<IOBuffer> buf(new IOBuffer(4096)); |
| 284 uint32 bytes_read = DrainClientSocket(buf, 4096, arraysize(kServerReply) - 1, | 284 uint32 bytes_read = DrainClientSocket( |
| 285 &callback); | 285 buf.get(), 4096, arraysize(kServerReply) - 1, &callback); |
| 286 ASSERT_EQ(bytes_read, arraysize(kServerReply) - 1); | 286 ASSERT_EQ(bytes_read, arraysize(kServerReply) - 1); |
| 287 | 287 |
| 288 // All data has been read now. Read once more to force an ERR_IO_PENDING, and | 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. | 289 // then close the server socket, and note the close. |
| 290 | 290 |
| 291 rv = sock_->Read(buf, 4096, callback.callback()); | 291 rv = sock_->Read(buf.get(), 4096, callback.callback()); |
| 292 ASSERT_EQ(ERR_IO_PENDING, rv); | 292 ASSERT_EQ(ERR_IO_PENDING, rv); |
| 293 CloseServerSocket(); | 293 CloseServerSocket(); |
| 294 EXPECT_EQ(0, callback.WaitForResult()); | 294 EXPECT_EQ(0, callback.WaitForResult()); |
| 295 } | 295 } |
| 296 | 296 |
| 297 TEST_P(TransportClientSocketTest, Read_SmallChunks) { | 297 TEST_P(TransportClientSocketTest, Read_SmallChunks) { |
| 298 TestCompletionCallback callback; | 298 TestCompletionCallback callback; |
| 299 int rv = sock_->Connect(callback.callback()); | 299 int rv = sock_->Connect(callback.callback()); |
| 300 if (rv != OK) { | 300 if (rv != OK) { |
| 301 ASSERT_EQ(rv, ERR_IO_PENDING); | 301 ASSERT_EQ(rv, ERR_IO_PENDING); |
| 302 | 302 |
| 303 rv = callback.WaitForResult(); | 303 rv = callback.WaitForResult(); |
| 304 EXPECT_EQ(rv, OK); | 304 EXPECT_EQ(rv, OK); |
| 305 } | 305 } |
| 306 SendClientRequest(); | 306 SendClientRequest(); |
| 307 | 307 |
| 308 scoped_refptr<IOBuffer> buf(new IOBuffer(1)); | 308 scoped_refptr<IOBuffer> buf(new IOBuffer(1)); |
| 309 uint32 bytes_read = 0; | 309 uint32 bytes_read = 0; |
| 310 while (bytes_read < arraysize(kServerReply) - 1) { | 310 while (bytes_read < arraysize(kServerReply) - 1) { |
| 311 rv = sock_->Read(buf, 1, callback.callback()); | 311 rv = sock_->Read(buf.get(), 1, callback.callback()); |
| 312 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); | 312 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); |
| 313 | 313 |
| 314 if (rv == ERR_IO_PENDING) | 314 if (rv == ERR_IO_PENDING) |
| 315 rv = callback.WaitForResult(); | 315 rv = callback.WaitForResult(); |
| 316 | 316 |
| 317 ASSERT_EQ(1, rv); | 317 ASSERT_EQ(1, rv); |
| 318 bytes_read += rv; | 318 bytes_read += rv; |
| 319 } | 319 } |
| 320 | 320 |
| 321 // All data has been read now. Read once more to force an ERR_IO_PENDING, and | 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. | 322 // then close the server socket, and note the close. |
| 323 | 323 |
| 324 rv = sock_->Read(buf, 1, callback.callback()); | 324 rv = sock_->Read(buf.get(), 1, callback.callback()); |
| 325 ASSERT_EQ(ERR_IO_PENDING, rv); | 325 ASSERT_EQ(ERR_IO_PENDING, rv); |
| 326 CloseServerSocket(); | 326 CloseServerSocket(); |
| 327 EXPECT_EQ(0, callback.WaitForResult()); | 327 EXPECT_EQ(0, callback.WaitForResult()); |
| 328 } | 328 } |
| 329 | 329 |
| 330 TEST_P(TransportClientSocketTest, Read_Interrupted) { | 330 TEST_P(TransportClientSocketTest, Read_Interrupted) { |
| 331 TestCompletionCallback callback; | 331 TestCompletionCallback callback; |
| 332 int rv = sock_->Connect(callback.callback()); | 332 int rv = sock_->Connect(callback.callback()); |
| 333 if (rv != OK) { | 333 if (rv != OK) { |
| 334 ASSERT_EQ(ERR_IO_PENDING, rv); | 334 ASSERT_EQ(ERR_IO_PENDING, rv); |
| 335 | 335 |
| 336 rv = callback.WaitForResult(); | 336 rv = callback.WaitForResult(); |
| 337 EXPECT_EQ(rv, OK); | 337 EXPECT_EQ(rv, OK); |
| 338 } | 338 } |
| 339 SendClientRequest(); | 339 SendClientRequest(); |
| 340 | 340 |
| 341 // Do a partial read and then exit. This test should not crash! | 341 // Do a partial read and then exit. This test should not crash! |
| 342 scoped_refptr<IOBuffer> buf(new IOBuffer(16)); | 342 scoped_refptr<IOBuffer> buf(new IOBuffer(16)); |
| 343 rv = sock_->Read(buf, 16, callback.callback()); | 343 rv = sock_->Read(buf.get(), 16, callback.callback()); |
| 344 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); | 344 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); |
| 345 | 345 |
| 346 if (rv == ERR_IO_PENDING) | 346 if (rv == ERR_IO_PENDING) |
| 347 rv = callback.WaitForResult(); | 347 rv = callback.WaitForResult(); |
| 348 | 348 |
| 349 EXPECT_NE(0, rv); | 349 EXPECT_NE(0, rv); |
| 350 } | 350 } |
| 351 | 351 |
| 352 TEST_P(TransportClientSocketTest, DISABLED_FullDuplex_ReadFirst) { | 352 TEST_P(TransportClientSocketTest, DISABLED_FullDuplex_ReadFirst) { |
| 353 TestCompletionCallback callback; | 353 TestCompletionCallback callback; |
| 354 int rv = sock_->Connect(callback.callback()); | 354 int rv = sock_->Connect(callback.callback()); |
| 355 if (rv != OK) { | 355 if (rv != OK) { |
| 356 ASSERT_EQ(rv, ERR_IO_PENDING); | 356 ASSERT_EQ(rv, ERR_IO_PENDING); |
| 357 | 357 |
| 358 rv = callback.WaitForResult(); | 358 rv = callback.WaitForResult(); |
| 359 EXPECT_EQ(rv, OK); | 359 EXPECT_EQ(rv, OK); |
| 360 } | 360 } |
| 361 | 361 |
| 362 // Read first. There's no data, so it should return ERR_IO_PENDING. | 362 // Read first. There's no data, so it should return ERR_IO_PENDING. |
| 363 const int kBufLen = 4096; | 363 const int kBufLen = 4096; |
| 364 scoped_refptr<IOBuffer> buf(new IOBuffer(kBufLen)); | 364 scoped_refptr<IOBuffer> buf(new IOBuffer(kBufLen)); |
| 365 rv = sock_->Read(buf, kBufLen, callback.callback()); | 365 rv = sock_->Read(buf.get(), kBufLen, callback.callback()); |
| 366 EXPECT_EQ(ERR_IO_PENDING, rv); | 366 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 367 | 367 |
| 368 PauseServerReads(); | 368 PauseServerReads(); |
| 369 const int kWriteBufLen = 64 * 1024; | 369 const int kWriteBufLen = 64 * 1024; |
| 370 scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kWriteBufLen)); | 370 scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kWriteBufLen)); |
| 371 char* request_data = request_buffer->data(); | 371 char* request_data = request_buffer->data(); |
| 372 memset(request_data, 'A', kWriteBufLen); | 372 memset(request_data, 'A', kWriteBufLen); |
| 373 TestCompletionCallback write_callback; | 373 TestCompletionCallback write_callback; |
| 374 | 374 |
| 375 while (true) { | 375 while (true) { |
| 376 rv = sock_->Write(request_buffer, kWriteBufLen, write_callback.callback()); | 376 rv = sock_->Write( |
| 377 request_buffer.get(), kWriteBufLen, write_callback.callback()); |
| 377 ASSERT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); | 378 ASSERT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); |
| 378 | 379 |
| 379 if (rv == ERR_IO_PENDING) { | 380 if (rv == ERR_IO_PENDING) { |
| 380 ResumeServerReads(); | 381 ResumeServerReads(); |
| 381 rv = write_callback.WaitForResult(); | 382 rv = write_callback.WaitForResult(); |
| 382 break; | 383 break; |
| 383 } | 384 } |
| 384 } | 385 } |
| 385 | 386 |
| 386 // At this point, both read and write have returned ERR_IO_PENDING, and the | 387 // At this point, both read and write have returned ERR_IO_PENDING, and the |
| (...skipping 15 matching lines...) Expand all Loading... |
| 402 } | 403 } |
| 403 | 404 |
| 404 PauseServerReads(); | 405 PauseServerReads(); |
| 405 const int kWriteBufLen = 64 * 1024; | 406 const int kWriteBufLen = 64 * 1024; |
| 406 scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kWriteBufLen)); | 407 scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kWriteBufLen)); |
| 407 char* request_data = request_buffer->data(); | 408 char* request_data = request_buffer->data(); |
| 408 memset(request_data, 'A', kWriteBufLen); | 409 memset(request_data, 'A', kWriteBufLen); |
| 409 TestCompletionCallback write_callback; | 410 TestCompletionCallback write_callback; |
| 410 | 411 |
| 411 while (true) { | 412 while (true) { |
| 412 rv = sock_->Write(request_buffer, kWriteBufLen, write_callback.callback()); | 413 rv = sock_->Write( |
| 414 request_buffer.get(), kWriteBufLen, write_callback.callback()); |
| 413 ASSERT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); | 415 ASSERT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); |
| 414 | 416 |
| 415 if (rv == ERR_IO_PENDING) | 417 if (rv == ERR_IO_PENDING) |
| 416 break; | 418 break; |
| 417 } | 419 } |
| 418 | 420 |
| 419 // Now we have the Write() blocked on ERR_IO_PENDING. It's time to force the | 421 // Now we have the Write() blocked on ERR_IO_PENDING. It's time to force the |
| 420 // Read() to block on ERR_IO_PENDING too. | 422 // Read() to block on ERR_IO_PENDING too. |
| 421 | 423 |
| 422 const int kBufLen = 4096; | 424 const int kBufLen = 4096; |
| 423 scoped_refptr<IOBuffer> buf(new IOBuffer(kBufLen)); | 425 scoped_refptr<IOBuffer> buf(new IOBuffer(kBufLen)); |
| 424 while (true) { | 426 while (true) { |
| 425 rv = sock_->Read(buf, kBufLen, callback.callback()); | 427 rv = sock_->Read(buf.get(), kBufLen, callback.callback()); |
| 426 ASSERT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); | 428 ASSERT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); |
| 427 if (rv == ERR_IO_PENDING) | 429 if (rv == ERR_IO_PENDING) |
| 428 break; | 430 break; |
| 429 } | 431 } |
| 430 | 432 |
| 431 // At this point, both read and write have returned ERR_IO_PENDING. Now we | 433 // At this point, both read and write have returned ERR_IO_PENDING. Now we |
| 432 // run the write and read callbacks to make sure they can handle full duplex | 434 // run the write and read callbacks to make sure they can handle full duplex |
| 433 // communications. | 435 // communications. |
| 434 | 436 |
| 435 ResumeServerReads(); | 437 ResumeServerReads(); |
| 436 rv = write_callback.WaitForResult(); | 438 rv = write_callback.WaitForResult(); |
| 437 EXPECT_GE(rv, 0); | 439 EXPECT_GE(rv, 0); |
| 438 | 440 |
| 439 // It's possible the read is blocked because it's already read all the data. | 441 // It's possible the read is blocked because it's already read all the data. |
| 440 // Close the server socket, so there will at least be a 0-byte read. | 442 // Close the server socket, so there will at least be a 0-byte read. |
| 441 CloseServerSocket(); | 443 CloseServerSocket(); |
| 442 | 444 |
| 443 rv = callback.WaitForResult(); | 445 rv = callback.WaitForResult(); |
| 444 EXPECT_GE(rv, 0); | 446 EXPECT_GE(rv, 0); |
| 445 } | 447 } |
| 446 | 448 |
| 447 } // namespace net | 449 } // namespace net |
| OLD | NEW |