| 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/proxy/multi_threaded_proxy_resolver.h" | 5 #include "net/proxy/multi_threaded_proxy_resolver.h" |
| 6 | 6 |
| 7 #include "base/message_loop/message_loop.h" | 7 #include "base/message_loop/message_loop.h" |
| 8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
| 9 #include "base/strings/string_util.h" | 9 #include "base/strings/string_util.h" |
| 10 #include "base/strings/stringprintf.h" | 10 #include "base/strings/stringprintf.h" |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 166 std::vector<BlockableProxyResolver*> resolvers() { | 166 std::vector<BlockableProxyResolver*> resolvers() { |
| 167 return resolvers_; | 167 return resolvers_; |
| 168 } | 168 } |
| 169 | 169 |
| 170 private: | 170 private: |
| 171 std::vector<BlockableProxyResolver*> resolvers_; | 171 std::vector<BlockableProxyResolver*> resolvers_; |
| 172 }; | 172 }; |
| 173 | 173 |
| 174 TEST(MultiThreadedProxyResolverTest, SingleThread_Basic) { | 174 TEST(MultiThreadedProxyResolverTest, SingleThread_Basic) { |
| 175 const size_t kNumThreads = 1u; | 175 const size_t kNumThreads = 1u; |
| 176 scoped_ptr<MockProxyResolver> mock(new MockProxyResolver); | 176 BlockableProxyResolverFactory* factory = new BlockableProxyResolverFactory; |
| 177 MultiThreadedProxyResolver resolver( | 177 MultiThreadedProxyResolver resolver(factory, kNumThreads); |
| 178 new ForwardingProxyResolverFactory(mock.get()), kNumThreads); | |
| 179 | 178 |
| 180 int rv; | 179 int rv; |
| 181 | 180 |
| 182 EXPECT_TRUE(resolver.expects_pac_bytes()); | 181 EXPECT_TRUE(resolver.expects_pac_bytes()); |
| 183 | 182 |
| 184 // Call SetPacScriptByData() -- verify that it reaches the synchronous | 183 // Call SetPacScriptByData() -- verify that it reaches the synchronous |
| 185 // resolver. | 184 // resolver. |
| 186 TestCompletionCallback set_script_callback; | 185 TestCompletionCallback set_script_callback; |
| 187 rv = resolver.SetPacScript( | 186 rv = resolver.SetPacScript( |
| 188 ProxyResolverScriptData::FromUTF8("pac script bytes"), | 187 ProxyResolverScriptData::FromUTF8("pac script bytes"), |
| 189 set_script_callback.callback()); | 188 set_script_callback.callback()); |
| 190 EXPECT_EQ(ERR_IO_PENDING, rv); | 189 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 191 EXPECT_EQ(OK, set_script_callback.WaitForResult()); | 190 EXPECT_EQ(OK, set_script_callback.WaitForResult()); |
| 191 ASSERT_EQ(1u, factory->resolvers().size()); |
| 192 EXPECT_EQ(ASCIIToUTF16("pac script bytes"), | 192 EXPECT_EQ(ASCIIToUTF16("pac script bytes"), |
| 193 mock->last_script_data()->utf16()); | 193 factory->resolvers()[0]->last_script_data()->utf16()); |
| 194 | 194 |
| 195 // Start request 0. | 195 // Start request 0. |
| 196 TestCompletionCallback callback0; | 196 TestCompletionCallback callback0; |
| 197 BoundTestNetLog log0; | 197 BoundTestNetLog log0; |
| 198 ProxyInfo results0; | 198 ProxyInfo results0; |
| 199 rv = resolver.GetProxyForURL(GURL("http://request0"), &results0, | 199 rv = resolver.GetProxyForURL(GURL("http://request0"), &results0, |
| 200 callback0.callback(), NULL, log0.bound()); | 200 callback0.callback(), NULL, log0.bound()); |
| 201 EXPECT_EQ(ERR_IO_PENDING, rv); | 201 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 202 | 202 |
| 203 // Wait for request 0 to finish. | 203 // Wait for request 0 to finish. |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 249 rv = callback3.WaitForResult(); | 249 rv = callback3.WaitForResult(); |
| 250 EXPECT_EQ(3, rv); | 250 EXPECT_EQ(3, rv); |
| 251 EXPECT_EQ("PROXY request3:80", results3.ToPacString()); | 251 EXPECT_EQ("PROXY request3:80", results3.ToPacString()); |
| 252 } | 252 } |
| 253 | 253 |
| 254 // Tests that the NetLog is updated to include the time the request was waiting | 254 // Tests that the NetLog is updated to include the time the request was waiting |
| 255 // to be scheduled to a thread. | 255 // to be scheduled to a thread. |
| 256 TEST(MultiThreadedProxyResolverTest, | 256 TEST(MultiThreadedProxyResolverTest, |
| 257 SingleThread_UpdatesNetLogWithThreadWait) { | 257 SingleThread_UpdatesNetLogWithThreadWait) { |
| 258 const size_t kNumThreads = 1u; | 258 const size_t kNumThreads = 1u; |
| 259 scoped_ptr<BlockableProxyResolver> mock(new BlockableProxyResolver); | 259 BlockableProxyResolverFactory* factory = new BlockableProxyResolverFactory; |
| 260 MultiThreadedProxyResolver resolver( | 260 MultiThreadedProxyResolver resolver(factory, kNumThreads); |
| 261 new ForwardingProxyResolverFactory(mock.get()), kNumThreads); | |
| 262 | 261 |
| 263 int rv; | 262 int rv; |
| 264 | 263 |
| 265 // Initialize the resolver. | 264 // Initialize the resolver. |
| 266 TestCompletionCallback init_callback; | 265 TestCompletionCallback init_callback; |
| 267 rv = resolver.SetPacScript(ProxyResolverScriptData::FromUTF8("foo"), | 266 rv = resolver.SetPacScript(ProxyResolverScriptData::FromUTF8("foo"), |
| 268 init_callback.callback()); | 267 init_callback.callback()); |
| 269 EXPECT_EQ(OK, init_callback.WaitForResult()); | 268 EXPECT_EQ(OK, init_callback.WaitForResult()); |
| 270 | 269 |
| 270 ASSERT_EQ(1u, factory->resolvers().size()); |
| 271 BlockableProxyResolver* mock = factory->resolvers()[0]; |
| 272 |
| 271 // Block the proxy resolver, so no request can complete. | 273 // Block the proxy resolver, so no request can complete. |
| 272 mock->Block(); | 274 mock->Block(); |
| 273 | 275 |
| 274 // Start request 0. | 276 // Start request 0. |
| 275 ProxyResolver::RequestHandle request0; | 277 ProxyResolver::RequestHandle request0; |
| 276 TestCompletionCallback callback0; | 278 TestCompletionCallback callback0; |
| 277 ProxyInfo results0; | 279 ProxyInfo results0; |
| 278 BoundTestNetLog log0; | 280 BoundTestNetLog log0; |
| 279 rv = resolver.GetProxyForURL(GURL("http://request0"), &results0, | 281 rv = resolver.GetProxyForURL(GURL("http://request0"), &results0, |
| 280 callback0.callback(), &request0, log0.bound()); | 282 callback0.callback(), &request0, log0.bound()); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 NetLog::TYPE_WAITING_FOR_PROXY_RESOLVER_THREAD)); | 344 NetLog::TYPE_WAITING_FOR_PROXY_RESOLVER_THREAD)); |
| 343 EXPECT_TRUE(LogContainsEndEvent( | 345 EXPECT_TRUE(LogContainsEndEvent( |
| 344 entries2, 1, | 346 entries2, 1, |
| 345 NetLog::TYPE_WAITING_FOR_PROXY_RESOLVER_THREAD)); | 347 NetLog::TYPE_WAITING_FOR_PROXY_RESOLVER_THREAD)); |
| 346 } | 348 } |
| 347 | 349 |
| 348 // Cancel a request which is in progress, and then cancel a request which | 350 // Cancel a request which is in progress, and then cancel a request which |
| 349 // is pending. | 351 // is pending. |
| 350 TEST(MultiThreadedProxyResolverTest, SingleThread_CancelRequest) { | 352 TEST(MultiThreadedProxyResolverTest, SingleThread_CancelRequest) { |
| 351 const size_t kNumThreads = 1u; | 353 const size_t kNumThreads = 1u; |
| 352 scoped_ptr<BlockableProxyResolver> mock(new BlockableProxyResolver); | 354 BlockableProxyResolverFactory* factory = new BlockableProxyResolverFactory; |
| 353 MultiThreadedProxyResolver resolver( | 355 MultiThreadedProxyResolver resolver(factory, kNumThreads); |
| 354 new ForwardingProxyResolverFactory(mock.get()), | |
| 355 kNumThreads); | |
| 356 | 356 |
| 357 int rv; | 357 int rv; |
| 358 | 358 |
| 359 // Initialize the resolver. | 359 // Initialize the resolver. |
| 360 TestCompletionCallback init_callback; | 360 TestCompletionCallback init_callback; |
| 361 rv = resolver.SetPacScript(ProxyResolverScriptData::FromUTF8("foo"), | 361 rv = resolver.SetPacScript(ProxyResolverScriptData::FromUTF8("foo"), |
| 362 init_callback.callback()); | 362 init_callback.callback()); |
| 363 EXPECT_EQ(OK, init_callback.WaitForResult()); | 363 EXPECT_EQ(OK, init_callback.WaitForResult()); |
| 364 | 364 |
| 365 ASSERT_EQ(1u, factory->resolvers().size()); |
| 366 BlockableProxyResolver* mock = factory->resolvers()[0]; |
| 367 |
| 365 // Block the proxy resolver, so no request can complete. | 368 // Block the proxy resolver, so no request can complete. |
| 366 mock->Block(); | 369 mock->Block(); |
| 367 | 370 |
| 368 // Start request 0. | 371 // Start request 0. |
| 369 ProxyResolver::RequestHandle request0; | 372 ProxyResolver::RequestHandle request0; |
| 370 TestCompletionCallback callback0; | 373 TestCompletionCallback callback0; |
| 371 ProxyInfo results0; | 374 ProxyInfo results0; |
| 372 rv = resolver.GetProxyForURL(GURL("http://request0"), &results0, | 375 rv = resolver.GetProxyForURL(GURL("http://request0"), &results0, |
| 373 callback0.callback(), &request0, BoundNetLog()); | 376 callback0.callback(), &request0, BoundNetLog()); |
| 374 EXPECT_EQ(ERR_IO_PENDING, rv); | 377 EXPECT_EQ(ERR_IO_PENDING, rv); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 419 // Requests 0 and 2 which were cancelled, hence their completion callbacks | 422 // Requests 0 and 2 which were cancelled, hence their completion callbacks |
| 420 // were never summoned. | 423 // were never summoned. |
| 421 EXPECT_FALSE(callback0.have_result()); | 424 EXPECT_FALSE(callback0.have_result()); |
| 422 EXPECT_FALSE(callback2.have_result()); | 425 EXPECT_FALSE(callback2.have_result()); |
| 423 } | 426 } |
| 424 | 427 |
| 425 // Test that deleting MultiThreadedProxyResolver while requests are | 428 // Test that deleting MultiThreadedProxyResolver while requests are |
| 426 // outstanding cancels them (and doesn't leak anything). | 429 // outstanding cancels them (and doesn't leak anything). |
| 427 TEST(MultiThreadedProxyResolverTest, SingleThread_CancelRequestByDeleting) { | 430 TEST(MultiThreadedProxyResolverTest, SingleThread_CancelRequestByDeleting) { |
| 428 const size_t kNumThreads = 1u; | 431 const size_t kNumThreads = 1u; |
| 429 scoped_ptr<BlockableProxyResolver> mock(new BlockableProxyResolver); | 432 BlockableProxyResolverFactory* factory = new BlockableProxyResolverFactory; |
| 430 scoped_ptr<MultiThreadedProxyResolver> resolver( | 433 scoped_ptr<MultiThreadedProxyResolver> resolver( |
| 431 new MultiThreadedProxyResolver( | 434 new MultiThreadedProxyResolver(factory, kNumThreads)); |
| 432 new ForwardingProxyResolverFactory(mock.get()), kNumThreads)); | |
| 433 | 435 |
| 434 int rv; | 436 int rv; |
| 435 | 437 |
| 436 // Initialize the resolver. | 438 // Initialize the resolver. |
| 437 TestCompletionCallback init_callback; | 439 TestCompletionCallback init_callback; |
| 438 rv = resolver->SetPacScript(ProxyResolverScriptData::FromUTF8("foo"), | 440 rv = resolver->SetPacScript(ProxyResolverScriptData::FromUTF8("foo"), |
| 439 init_callback.callback()); | 441 init_callback.callback()); |
| 440 EXPECT_EQ(OK, init_callback.WaitForResult()); | 442 EXPECT_EQ(OK, init_callback.WaitForResult()); |
| 441 | 443 |
| 444 ASSERT_EQ(1u, factory->resolvers().size()); |
| 445 BlockableProxyResolver* mock = factory->resolvers()[0]; |
| 446 |
| 442 // Block the proxy resolver, so no request can complete. | 447 // Block the proxy resolver, so no request can complete. |
| 443 mock->Block(); | 448 mock->Block(); |
| 444 | 449 |
| 445 // Start 3 requests. | 450 // Start 3 requests. |
| 446 | 451 |
| 447 TestCompletionCallback callback0; | 452 TestCompletionCallback callback0; |
| 448 ProxyInfo results0; | 453 ProxyInfo results0; |
| 449 rv = resolver->GetProxyForURL(GURL("http://request0"), &results0, | 454 rv = resolver->GetProxyForURL(GURL("http://request0"), &results0, |
| 450 callback0.callback(), NULL, BoundNetLog()); | 455 callback0.callback(), NULL, BoundNetLog()); |
| 451 EXPECT_EQ(ERR_IO_PENDING, rv); | 456 EXPECT_EQ(ERR_IO_PENDING, rv); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 482 | 487 |
| 483 // Check that none of the outstanding requests were completed. | 488 // Check that none of the outstanding requests were completed. |
| 484 EXPECT_FALSE(callback0.have_result()); | 489 EXPECT_FALSE(callback0.have_result()); |
| 485 EXPECT_FALSE(callback1.have_result()); | 490 EXPECT_FALSE(callback1.have_result()); |
| 486 EXPECT_FALSE(callback2.have_result()); | 491 EXPECT_FALSE(callback2.have_result()); |
| 487 } | 492 } |
| 488 | 493 |
| 489 // Cancel an outstanding call to SetPacScriptByData(). | 494 // Cancel an outstanding call to SetPacScriptByData(). |
| 490 TEST(MultiThreadedProxyResolverTest, SingleThread_CancelSetPacScript) { | 495 TEST(MultiThreadedProxyResolverTest, SingleThread_CancelSetPacScript) { |
| 491 const size_t kNumThreads = 1u; | 496 const size_t kNumThreads = 1u; |
| 492 scoped_ptr<BlockableProxyResolver> mock(new BlockableProxyResolver); | 497 BlockableProxyResolverFactory* factory = new BlockableProxyResolverFactory; |
| 493 MultiThreadedProxyResolver resolver( | 498 MultiThreadedProxyResolver resolver(factory, kNumThreads); |
| 494 new ForwardingProxyResolverFactory(mock.get()), kNumThreads); | |
| 495 | 499 |
| 496 int rv; | 500 int rv; |
| 497 | 501 |
| 498 TestCompletionCallback set_pac_script_callback; | 502 TestCompletionCallback set_pac_script_callback; |
| 499 rv = resolver.SetPacScript(ProxyResolverScriptData::FromUTF8("data"), | 503 rv = resolver.SetPacScript(ProxyResolverScriptData::FromUTF8("data"), |
| 500 set_pac_script_callback.callback()); | 504 set_pac_script_callback.callback()); |
| 501 EXPECT_EQ(ERR_IO_PENDING, rv); | 505 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 502 | 506 |
| 507 EXPECT_EQ(1u, factory->resolvers().size()); |
| 508 |
| 503 // Cancel the SetPacScriptByData request. | 509 // Cancel the SetPacScriptByData request. |
| 504 resolver.CancelSetPacScript(); | 510 resolver.CancelSetPacScript(); |
| 505 | 511 |
| 506 // Start another SetPacScript request | 512 // Start another SetPacScript request |
| 507 TestCompletionCallback set_pac_script_callback2; | 513 TestCompletionCallback set_pac_script_callback2; |
| 508 rv = resolver.SetPacScript(ProxyResolverScriptData::FromUTF8("data2"), | 514 rv = resolver.SetPacScript(ProxyResolverScriptData::FromUTF8("data2"), |
| 509 set_pac_script_callback2.callback()); | 515 set_pac_script_callback2.callback()); |
| 510 EXPECT_EQ(ERR_IO_PENDING, rv); | 516 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 511 | 517 |
| 512 // Wait for the initialization to complete. | 518 // Wait for the initialization to complete. |
| 513 | 519 |
| 514 rv = set_pac_script_callback2.WaitForResult(); | 520 rv = set_pac_script_callback2.WaitForResult(); |
| 515 EXPECT_EQ(0, rv); | 521 EXPECT_EQ(0, rv); |
| 516 EXPECT_EQ(ASCIIToUTF16("data2"), mock->last_script_data()->utf16()); | 522 ASSERT_EQ(2u, factory->resolvers().size()); |
| 523 EXPECT_EQ(ASCIIToUTF16("data2"), |
| 524 factory->resolvers()[1]->last_script_data()->utf16()); |
| 517 | 525 |
| 518 // The first SetPacScript callback should never have been completed. | 526 // The first SetPacScript callback should never have been completed. |
| 519 EXPECT_FALSE(set_pac_script_callback.have_result()); | 527 EXPECT_FALSE(set_pac_script_callback.have_result()); |
| 520 } | 528 } |
| 521 | 529 |
| 522 // Tests setting the PAC script once, lazily creating new threads, and | 530 // Tests setting the PAC script once, lazily creating new threads, and |
| 523 // cancelling requests. | 531 // cancelling requests. |
| 524 TEST(MultiThreadedProxyResolverTest, ThreeThreads_Basic) { | 532 TEST(MultiThreadedProxyResolverTest, ThreeThreads_Basic) { |
| 525 const size_t kNumThreads = 3u; | 533 const size_t kNumThreads = 3u; |
| 526 BlockableProxyResolverFactory* factory = new BlockableProxyResolverFactory; | 534 BlockableProxyResolverFactory* factory = new BlockableProxyResolverFactory; |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 694 // All in all, the first thread should have seen just 1 request. And the | 702 // All in all, the first thread should have seen just 1 request. And the |
| 695 // second thread 3 requests. | 703 // second thread 3 requests. |
| 696 ASSERT_EQ(2u, factory->resolvers().size()); | 704 ASSERT_EQ(2u, factory->resolvers().size()); |
| 697 EXPECT_EQ(1, factory->resolvers()[0]->request_count()); | 705 EXPECT_EQ(1, factory->resolvers()[0]->request_count()); |
| 698 EXPECT_EQ(3, factory->resolvers()[1]->request_count()); | 706 EXPECT_EQ(3, factory->resolvers()[1]->request_count()); |
| 699 } | 707 } |
| 700 | 708 |
| 701 } // namespace | 709 } // namespace |
| 702 | 710 |
| 703 } // namespace net | 711 } // namespace net |
| OLD | NEW |