| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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_pool.h" | 5 #include "net/socket/tcp_client_socket_pool.h" |
| 6 | 6 |
| 7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
| 8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
| 9 #include "net/base/mock_host_resolver.h" | 9 #include "net/base/mock_host_resolver.h" |
| 10 #include "net/base/net_errors.h" | 10 #include "net/base/net_errors.h" |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 | 202 |
| 203 scoped_refptr<MockHostResolver> host_resolver_; | 203 scoped_refptr<MockHostResolver> host_resolver_; |
| 204 MockClientSocketFactory client_socket_factory_; | 204 MockClientSocketFactory client_socket_factory_; |
| 205 scoped_refptr<ClientSocketPool> pool_; | 205 scoped_refptr<ClientSocketPool> pool_; |
| 206 }; | 206 }; |
| 207 | 207 |
| 208 TEST_F(TCPClientSocketPoolTest, Basic) { | 208 TEST_F(TCPClientSocketPoolTest, Basic) { |
| 209 TestCompletionCallback callback; | 209 TestCompletionCallback callback; |
| 210 ClientSocketHandle handle(pool_.get()); | 210 ClientSocketHandle handle(pool_.get()); |
| 211 HostResolver::RequestInfo info("www.google.com", 80); | 211 HostResolver::RequestInfo info("www.google.com", 80); |
| 212 int rv = handle.Init("a", info, 0, &callback); | 212 int rv = handle.Init(NULL, "a", info, 0, &callback); |
| 213 EXPECT_EQ(ERR_IO_PENDING, rv); | 213 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 214 EXPECT_FALSE(handle.is_initialized()); | 214 EXPECT_FALSE(handle.is_initialized()); |
| 215 EXPECT_FALSE(handle.socket()); | 215 EXPECT_FALSE(handle.socket()); |
| 216 | 216 |
| 217 EXPECT_EQ(OK, callback.WaitForResult()); | 217 EXPECT_EQ(OK, callback.WaitForResult()); |
| 218 EXPECT_TRUE(handle.is_initialized()); | 218 EXPECT_TRUE(handle.is_initialized()); |
| 219 EXPECT_TRUE(handle.socket()); | 219 EXPECT_TRUE(handle.socket()); |
| 220 | 220 |
| 221 handle.Reset(); | 221 handle.Reset(); |
| 222 } | 222 } |
| 223 | 223 |
| 224 TEST_F(TCPClientSocketPoolTest, InitHostResolutionFailure) { | 224 TEST_F(TCPClientSocketPoolTest, InitHostResolutionFailure) { |
| 225 host_resolver_->rules()->AddSimulatedFailure("unresolvable.host.name"); | 225 host_resolver_->rules()->AddSimulatedFailure("unresolvable.host.name"); |
| 226 TestSocketRequest req(pool_.get(), &request_order_, &completion_count_); | 226 TestSocketRequest req(pool_.get(), &request_order_, &completion_count_); |
| 227 HostResolver::RequestInfo info("unresolvable.host.name", 80); | 227 HostResolver::RequestInfo info("unresolvable.host.name", 80); |
| 228 EXPECT_EQ(ERR_IO_PENDING, | 228 EXPECT_EQ(ERR_IO_PENDING, |
| 229 req.handle()->Init("a", info, kDefaultPriority, &req)); | 229 req.handle()->Init(NULL, "a", info, kDefaultPriority, &req)); |
| 230 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, req.WaitForResult()); | 230 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, req.WaitForResult()); |
| 231 } | 231 } |
| 232 | 232 |
| 233 TEST_F(TCPClientSocketPoolTest, InitConnectionFailure) { | 233 TEST_F(TCPClientSocketPoolTest, InitConnectionFailure) { |
| 234 client_socket_factory_.set_client_socket_type( | 234 client_socket_factory_.set_client_socket_type( |
| 235 MockClientSocketFactory::MOCK_FAILING_CLIENT_SOCKET); | 235 MockClientSocketFactory::MOCK_FAILING_CLIENT_SOCKET); |
| 236 TestSocketRequest req(pool_.get(), &request_order_, &completion_count_); | 236 TestSocketRequest req(pool_.get(), &request_order_, &completion_count_); |
| 237 HostResolver::RequestInfo info("a", 80); | 237 HostResolver::RequestInfo info("a", 80); |
| 238 EXPECT_EQ(ERR_IO_PENDING, | 238 EXPECT_EQ(ERR_IO_PENDING, |
| 239 req.handle()->Init("a", info, kDefaultPriority, &req)); | 239 req.handle()->Init(NULL, "a", info, kDefaultPriority, &req)); |
| 240 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult()); | 240 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult()); |
| 241 | 241 |
| 242 // Make the host resolutions complete synchronously this time. | 242 // Make the host resolutions complete synchronously this time. |
| 243 host_resolver_->set_synchronous_mode(true); | 243 host_resolver_->set_synchronous_mode(true); |
| 244 EXPECT_EQ(ERR_CONNECTION_FAILED, | 244 EXPECT_EQ(ERR_CONNECTION_FAILED, |
| 245 req.handle()->Init("a", info, kDefaultPriority, &req)); | 245 req.handle()->Init(NULL, "a", info, kDefaultPriority, &req)); |
| 246 } | 246 } |
| 247 | 247 |
| 248 TEST_F(TCPClientSocketPoolTest, PendingRequests) { | 248 TEST_F(TCPClientSocketPoolTest, PendingRequests) { |
| 249 // First request finishes asynchronously. | 249 // First request finishes asynchronously. |
| 250 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); | 250 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); |
| 251 EXPECT_EQ(OK, requests_[0]->WaitForResult()); | 251 EXPECT_EQ(OK, requests_[0]->WaitForResult()); |
| 252 | 252 |
| 253 // Make all subsequent host resolutions complete synchronously. | 253 // Make all subsequent host resolutions complete synchronously. |
| 254 host_resolver_->set_synchronous_mode(true); | 254 host_resolver_->set_synchronous_mode(true); |
| 255 | 255 |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 EXPECT_EQ(6U, completion_count_); | 341 EXPECT_EQ(6U, completion_count_); |
| 342 } | 342 } |
| 343 | 343 |
| 344 // This test will start up a RequestSocket() and then immediately Cancel() it. | 344 // This test will start up a RequestSocket() and then immediately Cancel() it. |
| 345 // The pending host resolution will eventually complete, and destroy the | 345 // The pending host resolution will eventually complete, and destroy the |
| 346 // ClientSocketPool which will crash if the group was not cleared properly. | 346 // ClientSocketPool which will crash if the group was not cleared properly. |
| 347 TEST_F(TCPClientSocketPoolTest, CancelRequestClearGroup) { | 347 TEST_F(TCPClientSocketPoolTest, CancelRequestClearGroup) { |
| 348 TestSocketRequest req(pool_.get(), &request_order_, &completion_count_); | 348 TestSocketRequest req(pool_.get(), &request_order_, &completion_count_); |
| 349 HostResolver::RequestInfo info("www.google.com", 80); | 349 HostResolver::RequestInfo info("www.google.com", 80); |
| 350 EXPECT_EQ(ERR_IO_PENDING, | 350 EXPECT_EQ(ERR_IO_PENDING, |
| 351 req.handle()->Init("a", info, kDefaultPriority, &req)); | 351 req.handle()->Init(NULL, "a", info, kDefaultPriority, &req)); |
| 352 req.handle()->Reset(); | 352 req.handle()->Reset(); |
| 353 | 353 |
| 354 PlatformThread::Sleep(100); | 354 PlatformThread::Sleep(100); |
| 355 | 355 |
| 356 // There is a race condition here. If the worker pool doesn't post the task | 356 // There is a race condition here. If the worker pool doesn't post the task |
| 357 // before we get here, then this might not run ConnectingSocket::OnIOComplete | 357 // before we get here, then this might not run ConnectingSocket::OnIOComplete |
| 358 // and therefore leak the canceled ConnectingSocket. However, other tests | 358 // and therefore leak the canceled ConnectingSocket. However, other tests |
| 359 // after this will call MessageLoop::RunAllPending() which should prevent a | 359 // after this will call MessageLoop::RunAllPending() which should prevent a |
| 360 // leak, unless the worker thread takes longer than all of them. | 360 // leak, unless the worker thread takes longer than all of them. |
| 361 MessageLoop::current()->RunAllPending(); | 361 MessageLoop::current()->RunAllPending(); |
| 362 } | 362 } |
| 363 | 363 |
| 364 TEST_F(TCPClientSocketPoolTest, TwoRequestsCancelOne) { | 364 TEST_F(TCPClientSocketPoolTest, TwoRequestsCancelOne) { |
| 365 TestSocketRequest req(pool_.get(), &request_order_, &completion_count_); | 365 TestSocketRequest req(pool_.get(), &request_order_, &completion_count_); |
| 366 TestSocketRequest req2(pool_.get(), &request_order_, &completion_count_); | 366 TestSocketRequest req2(pool_.get(), &request_order_, &completion_count_); |
| 367 | 367 |
| 368 HostResolver::RequestInfo info("www.google.com", 80); | 368 HostResolver::RequestInfo info("www.google.com", 80); |
| 369 EXPECT_EQ(ERR_IO_PENDING, | 369 EXPECT_EQ(ERR_IO_PENDING, |
| 370 req.handle()->Init("a", info, kDefaultPriority, &req)); | 370 req.handle()->Init(NULL, "a", info, kDefaultPriority, &req)); |
| 371 EXPECT_EQ(ERR_IO_PENDING, | 371 EXPECT_EQ(ERR_IO_PENDING, |
| 372 req2.handle()->Init("a", info, kDefaultPriority, &req2)); | 372 req2.handle()->Init(NULL, "a", info, kDefaultPriority, &req2)); |
| 373 | 373 |
| 374 req.handle()->Reset(); | 374 req.handle()->Reset(); |
| 375 | 375 |
| 376 EXPECT_EQ(OK, req2.WaitForResult()); | 376 EXPECT_EQ(OK, req2.WaitForResult()); |
| 377 req2.handle()->Reset(); | 377 req2.handle()->Reset(); |
| 378 } | 378 } |
| 379 | 379 |
| 380 TEST_F(TCPClientSocketPoolTest, ConnectCancelConnect) { | 380 TEST_F(TCPClientSocketPoolTest, ConnectCancelConnect) { |
| 381 client_socket_factory_.set_client_socket_type( | 381 client_socket_factory_.set_client_socket_type( |
| 382 MockClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET); | 382 MockClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET); |
| 383 ClientSocketHandle handle(pool_.get()); | 383 ClientSocketHandle handle(pool_.get()); |
| 384 TestCompletionCallback callback; | 384 TestCompletionCallback callback; |
| 385 TestSocketRequest req(pool_.get(), &request_order_, &completion_count_); | 385 TestSocketRequest req(pool_.get(), &request_order_, &completion_count_); |
| 386 | 386 |
| 387 HostResolver::RequestInfo info("www.google.com", 80); | 387 HostResolver::RequestInfo info("www.google.com", 80); |
| 388 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", info, kDefaultPriority, &callback))
; | 388 EXPECT_EQ(ERR_IO_PENDING, |
| 389 handle.Init(NULL, "a", info, kDefaultPriority, &callback)); |
| 389 | 390 |
| 390 handle.Reset(); | 391 handle.Reset(); |
| 391 | 392 |
| 392 TestCompletionCallback callback2; | 393 TestCompletionCallback callback2; |
| 393 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", info, kDefaultPriority, &callback2)
); | 394 EXPECT_EQ(ERR_IO_PENDING, |
| 395 handle.Init(NULL, "a", info, kDefaultPriority, &callback2)); |
| 394 | 396 |
| 395 host_resolver_->set_synchronous_mode(true); | 397 host_resolver_->set_synchronous_mode(true); |
| 396 // At this point, handle has two ConnectingSockets out for it. Due to the | 398 // At this point, handle has two ConnectingSockets out for it. Due to the |
| 397 // setting the mock resolver into synchronous mode, the host resolution for | 399 // setting the mock resolver into synchronous mode, the host resolution for |
| 398 // both will return in the same loop of the MessageLoop. The client socket | 400 // both will return in the same loop of the MessageLoop. The client socket |
| 399 // is a pending socket, so the Connect() will asynchronously complete on the | 401 // is a pending socket, so the Connect() will asynchronously complete on the |
| 400 // next loop of the MessageLoop. That means that the first | 402 // next loop of the MessageLoop. That means that the first |
| 401 // ConnectingSocket will enter OnIOComplete, and then the second one will. | 403 // ConnectingSocket will enter OnIOComplete, and then the second one will. |
| 402 // If the first one is not cancelled, it will advance the load state, and | 404 // If the first one is not cancelled, it will advance the load state, and |
| 403 // then the second one will crash. | 405 // then the second one will crash. |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 472 : handle_(handle), | 474 : handle_(handle), |
| 473 within_callback_(false) {} | 475 within_callback_(false) {} |
| 474 | 476 |
| 475 virtual void RunWithParams(const Tuple1<int>& params) { | 477 virtual void RunWithParams(const Tuple1<int>& params) { |
| 476 callback_.RunWithParams(params); | 478 callback_.RunWithParams(params); |
| 477 ASSERT_EQ(OK, params.a); | 479 ASSERT_EQ(OK, params.a); |
| 478 | 480 |
| 479 if (!within_callback_) { | 481 if (!within_callback_) { |
| 480 handle_->Reset(); | 482 handle_->Reset(); |
| 481 within_callback_ = true; | 483 within_callback_ = true; |
| 482 int rv = handle_->Init( | 484 int rv = handle_->Init(NULL, "a", |
| 483 "a", HostResolver::RequestInfo("www.google.com", 80), 0, this); | 485 HostResolver::RequestInfo("www.google.com", 80), 0, this); |
| 484 EXPECT_EQ(OK, rv); | 486 EXPECT_EQ(OK, rv); |
| 485 } | 487 } |
| 486 } | 488 } |
| 487 | 489 |
| 488 int WaitForResult() { | 490 int WaitForResult() { |
| 489 return callback_.WaitForResult(); | 491 return callback_.WaitForResult(); |
| 490 } | 492 } |
| 491 | 493 |
| 492 private: | 494 private: |
| 493 ClientSocketHandle* const handle_; | 495 ClientSocketHandle* const handle_; |
| 494 bool within_callback_; | 496 bool within_callback_; |
| 495 TestCompletionCallback callback_; | 497 TestCompletionCallback callback_; |
| 496 }; | 498 }; |
| 497 | 499 |
| 498 TEST_F(TCPClientSocketPoolTest, RequestTwice) { | 500 TEST_F(TCPClientSocketPoolTest, RequestTwice) { |
| 499 ClientSocketHandle handle(pool_.get()); | 501 ClientSocketHandle handle(pool_.get()); |
| 500 RequestSocketCallback callback(&handle); | 502 RequestSocketCallback callback(&handle); |
| 501 int rv = handle.Init( | 503 int rv = handle.Init(NULL, "a", |
| 502 "a", HostResolver::RequestInfo("www.google.com", 80), 0, &callback); | 504 HostResolver::RequestInfo("www.google.com", 80), 0, &callback); |
| 503 ASSERT_EQ(ERR_IO_PENDING, rv); | 505 ASSERT_EQ(ERR_IO_PENDING, rv); |
| 504 | 506 |
| 505 // The callback is going to request "www.google.com". We want it to complete | 507 // The callback is going to request "www.google.com". We want it to complete |
| 506 // synchronously this time. | 508 // synchronously this time. |
| 507 host_resolver_->set_synchronous_mode(true); | 509 host_resolver_->set_synchronous_mode(true); |
| 508 | 510 |
| 509 EXPECT_EQ(OK, callback.WaitForResult()); | 511 EXPECT_EQ(OK, callback.WaitForResult()); |
| 510 | 512 |
| 511 handle.Reset(); | 513 handle.Reset(); |
| 512 } | 514 } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 554 for (int i = 0; i < kNumRequests; i++) | 556 for (int i = 0; i < kNumRequests; i++) |
| 555 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); | 557 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); |
| 556 | 558 |
| 557 for (int i = 0; i < kNumRequests; i++) | 559 for (int i = 0; i < kNumRequests; i++) |
| 558 EXPECT_EQ(ERR_CONNECTION_FAILED, requests_[i]->WaitForResult()); | 560 EXPECT_EQ(ERR_CONNECTION_FAILED, requests_[i]->WaitForResult()); |
| 559 } | 561 } |
| 560 | 562 |
| 561 } // namespace | 563 } // namespace |
| 562 | 564 |
| 563 } // namespace net | 565 } // namespace net |
| OLD | NEW |