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 |