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 |