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