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 <utility> | 7 #include <utility> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
11 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
12 #include "base/run_loop.h" | 12 #include "base/run_loop.h" |
13 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
14 #include "base/strings/string_util.h" | 14 #include "base/strings/string_util.h" |
15 #include "base/strings/stringprintf.h" | 15 #include "base/strings/stringprintf.h" |
16 #include "base/strings/utf_string_conversions.h" | 16 #include "base/strings/utf_string_conversions.h" |
17 #include "base/synchronization/lock.h" | 17 #include "base/synchronization/lock.h" |
18 #include "base/synchronization/waitable_event.h" | 18 #include "base/synchronization/waitable_event.h" |
19 #include "base/threading/platform_thread.h" | 19 #include "base/threading/platform_thread.h" |
20 #include "net/base/net_errors.h" | 20 #include "net/base/net_errors.h" |
21 #include "net/base/test_completion_callback.h" | 21 #include "net/base/test_completion_callback.h" |
22 #include "net/log/net_log.h" | 22 #include "net/log/net_log.h" |
23 #include "net/log/test_net_log.h" | 23 #include "net/log/test_net_log.h" |
24 #include "net/log/test_net_log_entry.h" | 24 #include "net/log/test_net_log_entry.h" |
25 #include "net/log/test_net_log_util.h" | 25 #include "net/log/test_net_log_util.h" |
26 #include "net/proxy/mock_proxy_resolver.h" | 26 #include "net/proxy/mock_proxy_resolver.h" |
27 #include "net/proxy/proxy_info.h" | 27 #include "net/proxy/proxy_info.h" |
28 #include "net/proxy/proxy_resolver_factory.h" | 28 #include "net/proxy/proxy_resolver_factory.h" |
| 29 #include "net/test/gtest_util.h" |
| 30 #include "testing/gmock/include/gmock/gmock.h" |
29 #include "testing/gtest/include/gtest/gtest.h" | 31 #include "testing/gtest/include/gtest/gtest.h" |
30 #include "url/gurl.h" | 32 #include "url/gurl.h" |
31 | 33 |
| 34 using net::test::IsError; |
| 35 using net::test::IsOk; |
| 36 |
32 using base::ASCIIToUTF16; | 37 using base::ASCIIToUTF16; |
33 | 38 |
34 namespace net { | 39 namespace net { |
35 | 40 |
36 namespace { | 41 namespace { |
37 | 42 |
38 // A synchronous mock ProxyResolver implementation, which can be used in | 43 // A synchronous mock ProxyResolver implementation, which can be used in |
39 // conjunction with MultiThreadedProxyResolver. | 44 // conjunction with MultiThreadedProxyResolver. |
40 // - returns a single-item proxy list with the query's host. | 45 // - returns a single-item proxy list with the query's host. |
41 class MockProxyResolver : public ProxyResolver { | 46 class MockProxyResolver : public ProxyResolver { |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 new BlockableProxyResolverFactory); | 205 new BlockableProxyResolverFactory); |
201 factory_ = factory_owner.get(); | 206 factory_ = factory_owner.get(); |
202 resolver_factory_.reset(new SingleShotMultiThreadedProxyResolverFactory( | 207 resolver_factory_.reset(new SingleShotMultiThreadedProxyResolverFactory( |
203 num_threads, std::move(factory_owner))); | 208 num_threads, std::move(factory_owner))); |
204 TestCompletionCallback ready_callback; | 209 TestCompletionCallback ready_callback; |
205 std::unique_ptr<ProxyResolverFactory::Request> request; | 210 std::unique_ptr<ProxyResolverFactory::Request> request; |
206 resolver_factory_->CreateProxyResolver( | 211 resolver_factory_->CreateProxyResolver( |
207 ProxyResolverScriptData::FromUTF8("pac script bytes"), &resolver_, | 212 ProxyResolverScriptData::FromUTF8("pac script bytes"), &resolver_, |
208 ready_callback.callback(), &request); | 213 ready_callback.callback(), &request); |
209 EXPECT_TRUE(request); | 214 EXPECT_TRUE(request); |
210 ASSERT_EQ(OK, ready_callback.WaitForResult()); | 215 ASSERT_THAT(ready_callback.WaitForResult(), IsOk()); |
211 | 216 |
212 // Verify that the script data reaches the synchronous resolver factory. | 217 // Verify that the script data reaches the synchronous resolver factory. |
213 ASSERT_EQ(1u, factory_->script_data().size()); | 218 ASSERT_EQ(1u, factory_->script_data().size()); |
214 EXPECT_EQ(ASCIIToUTF16("pac script bytes"), | 219 EXPECT_EQ(ASCIIToUTF16("pac script bytes"), |
215 factory_->script_data()[0]->utf16()); | 220 factory_->script_data()[0]->utf16()); |
216 } | 221 } |
217 | 222 |
218 void ClearResolver() { resolver_.reset(); } | 223 void ClearResolver() { resolver_.reset(); } |
219 | 224 |
220 BlockableProxyResolverFactory& factory() { | 225 BlockableProxyResolverFactory& factory() { |
(...skipping 16 matching lines...) Expand all Loading... |
237 const size_t kNumThreads = 1u; | 242 const size_t kNumThreads = 1u; |
238 ASSERT_NO_FATAL_FAILURE(Init(kNumThreads)); | 243 ASSERT_NO_FATAL_FAILURE(Init(kNumThreads)); |
239 | 244 |
240 // Start request 0. | 245 // Start request 0. |
241 int rv; | 246 int rv; |
242 TestCompletionCallback callback0; | 247 TestCompletionCallback callback0; |
243 BoundTestNetLog log0; | 248 BoundTestNetLog log0; |
244 ProxyInfo results0; | 249 ProxyInfo results0; |
245 rv = resolver().GetProxyForURL(GURL("http://request0"), &results0, | 250 rv = resolver().GetProxyForURL(GURL("http://request0"), &results0, |
246 callback0.callback(), NULL, log0.bound()); | 251 callback0.callback(), NULL, log0.bound()); |
247 EXPECT_EQ(ERR_IO_PENDING, rv); | 252 EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); |
248 | 253 |
249 // Wait for request 0 to finish. | 254 // Wait for request 0 to finish. |
250 rv = callback0.WaitForResult(); | 255 rv = callback0.WaitForResult(); |
251 EXPECT_EQ(0, rv); | 256 EXPECT_EQ(0, rv); |
252 EXPECT_EQ("PROXY request0:80", results0.ToPacString()); | 257 EXPECT_EQ("PROXY request0:80", results0.ToPacString()); |
253 | 258 |
254 // The mock proxy resolver should have written 1 log entry. And | 259 // The mock proxy resolver should have written 1 log entry. And |
255 // on completion, this should have been copied into |log0|. | 260 // on completion, this should have been copied into |log0|. |
256 // We also have 1 log entry that was emitted by the | 261 // We also have 1 log entry that was emitted by the |
257 // MultiThreadedProxyResolver. | 262 // MultiThreadedProxyResolver. |
258 TestNetLogEntry::List entries0; | 263 TestNetLogEntry::List entries0; |
259 log0.GetEntries(&entries0); | 264 log0.GetEntries(&entries0); |
260 | 265 |
261 ASSERT_EQ(2u, entries0.size()); | 266 ASSERT_EQ(2u, entries0.size()); |
262 EXPECT_EQ(NetLog::TYPE_SUBMITTED_TO_RESOLVER_THREAD, entries0[0].type); | 267 EXPECT_EQ(NetLog::TYPE_SUBMITTED_TO_RESOLVER_THREAD, entries0[0].type); |
263 | 268 |
264 // Start 3 more requests (request1 to request3). | 269 // Start 3 more requests (request1 to request3). |
265 | 270 |
266 TestCompletionCallback callback1; | 271 TestCompletionCallback callback1; |
267 ProxyInfo results1; | 272 ProxyInfo results1; |
268 rv = resolver().GetProxyForURL(GURL("http://request1"), &results1, | 273 rv = resolver().GetProxyForURL(GURL("http://request1"), &results1, |
269 callback1.callback(), NULL, BoundNetLog()); | 274 callback1.callback(), NULL, BoundNetLog()); |
270 EXPECT_EQ(ERR_IO_PENDING, rv); | 275 EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); |
271 | 276 |
272 TestCompletionCallback callback2; | 277 TestCompletionCallback callback2; |
273 ProxyInfo results2; | 278 ProxyInfo results2; |
274 rv = resolver().GetProxyForURL(GURL("http://request2"), &results2, | 279 rv = resolver().GetProxyForURL(GURL("http://request2"), &results2, |
275 callback2.callback(), NULL, BoundNetLog()); | 280 callback2.callback(), NULL, BoundNetLog()); |
276 EXPECT_EQ(ERR_IO_PENDING, rv); | 281 EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); |
277 | 282 |
278 TestCompletionCallback callback3; | 283 TestCompletionCallback callback3; |
279 ProxyInfo results3; | 284 ProxyInfo results3; |
280 rv = resolver().GetProxyForURL(GURL("http://request3"), &results3, | 285 rv = resolver().GetProxyForURL(GURL("http://request3"), &results3, |
281 callback3.callback(), NULL, BoundNetLog()); | 286 callback3.callback(), NULL, BoundNetLog()); |
282 EXPECT_EQ(ERR_IO_PENDING, rv); | 287 EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); |
283 | 288 |
284 // Wait for the requests to finish (they must finish in the order they were | 289 // Wait for the requests to finish (they must finish in the order they were |
285 // started, which is what we check for from their magic return value) | 290 // started, which is what we check for from their magic return value) |
286 | 291 |
287 rv = callback1.WaitForResult(); | 292 rv = callback1.WaitForResult(); |
288 EXPECT_EQ(1, rv); | 293 EXPECT_EQ(1, rv); |
289 EXPECT_EQ("PROXY request1:80", results1.ToPacString()); | 294 EXPECT_EQ("PROXY request1:80", results1.ToPacString()); |
290 | 295 |
291 rv = callback2.WaitForResult(); | 296 rv = callback2.WaitForResult(); |
292 EXPECT_EQ(2, rv); | 297 EXPECT_EQ(2, rv); |
(...skipping 16 matching lines...) Expand all Loading... |
309 // Block the proxy resolver, so no request can complete. | 314 // Block the proxy resolver, so no request can complete. |
310 factory().resolvers()[0]->Block(); | 315 factory().resolvers()[0]->Block(); |
311 | 316 |
312 // Start request 0. | 317 // Start request 0. |
313 ProxyResolver::RequestHandle request0; | 318 ProxyResolver::RequestHandle request0; |
314 TestCompletionCallback callback0; | 319 TestCompletionCallback callback0; |
315 ProxyInfo results0; | 320 ProxyInfo results0; |
316 BoundTestNetLog log0; | 321 BoundTestNetLog log0; |
317 rv = resolver().GetProxyForURL(GURL("http://request0"), &results0, | 322 rv = resolver().GetProxyForURL(GURL("http://request0"), &results0, |
318 callback0.callback(), &request0, log0.bound()); | 323 callback0.callback(), &request0, log0.bound()); |
319 EXPECT_EQ(ERR_IO_PENDING, rv); | 324 EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); |
320 | 325 |
321 // Start 2 more requests (request1 and request2). | 326 // Start 2 more requests (request1 and request2). |
322 | 327 |
323 TestCompletionCallback callback1; | 328 TestCompletionCallback callback1; |
324 ProxyInfo results1; | 329 ProxyInfo results1; |
325 BoundTestNetLog log1; | 330 BoundTestNetLog log1; |
326 rv = resolver().GetProxyForURL(GURL("http://request1"), &results1, | 331 rv = resolver().GetProxyForURL(GURL("http://request1"), &results1, |
327 callback1.callback(), NULL, log1.bound()); | 332 callback1.callback(), NULL, log1.bound()); |
328 EXPECT_EQ(ERR_IO_PENDING, rv); | 333 EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); |
329 | 334 |
330 ProxyResolver::RequestHandle request2; | 335 ProxyResolver::RequestHandle request2; |
331 TestCompletionCallback callback2; | 336 TestCompletionCallback callback2; |
332 ProxyInfo results2; | 337 ProxyInfo results2; |
333 BoundTestNetLog log2; | 338 BoundTestNetLog log2; |
334 rv = resolver().GetProxyForURL(GURL("http://request2"), &results2, | 339 rv = resolver().GetProxyForURL(GURL("http://request2"), &results2, |
335 callback2.callback(), &request2, log2.bound()); | 340 callback2.callback(), &request2, log2.bound()); |
336 EXPECT_EQ(ERR_IO_PENDING, rv); | 341 EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); |
337 | 342 |
338 // Unblock the worker thread so the requests can continue running. | 343 // Unblock the worker thread so the requests can continue running. |
339 factory().resolvers()[0]->WaitUntilBlocked(); | 344 factory().resolvers()[0]->WaitUntilBlocked(); |
340 factory().resolvers()[0]->Unblock(); | 345 factory().resolvers()[0]->Unblock(); |
341 | 346 |
342 // Check that request 0 completed as expected. | 347 // Check that request 0 completed as expected. |
343 // The NetLog has 1 entry that came from the MultiThreadedProxyResolver, and | 348 // The NetLog has 1 entry that came from the MultiThreadedProxyResolver, and |
344 // 1 entry from the mock proxy resolver. | 349 // 1 entry from the mock proxy resolver. |
345 EXPECT_EQ(0, callback0.WaitForResult()); | 350 EXPECT_EQ(0, callback0.WaitForResult()); |
346 EXPECT_EQ("PROXY request0:80", results0.ToPacString()); | 351 EXPECT_EQ("PROXY request0:80", results0.ToPacString()); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
394 // Block the proxy resolver, so no request can complete. | 399 // Block the proxy resolver, so no request can complete. |
395 factory().resolvers()[0]->Block(); | 400 factory().resolvers()[0]->Block(); |
396 | 401 |
397 // Start request 0. | 402 // Start request 0. |
398 ProxyResolver::RequestHandle request0; | 403 ProxyResolver::RequestHandle request0; |
399 TestCompletionCallback callback0; | 404 TestCompletionCallback callback0; |
400 ProxyInfo results0; | 405 ProxyInfo results0; |
401 rv = | 406 rv = |
402 resolver().GetProxyForURL(GURL("http://request0"), &results0, | 407 resolver().GetProxyForURL(GURL("http://request0"), &results0, |
403 callback0.callback(), &request0, BoundNetLog()); | 408 callback0.callback(), &request0, BoundNetLog()); |
404 EXPECT_EQ(ERR_IO_PENDING, rv); | 409 EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); |
405 | 410 |
406 // Wait until requests 0 reaches the worker thread. | 411 // Wait until requests 0 reaches the worker thread. |
407 factory().resolvers()[0]->WaitUntilBlocked(); | 412 factory().resolvers()[0]->WaitUntilBlocked(); |
408 | 413 |
409 // Start 3 more requests (request1 : request3). | 414 // Start 3 more requests (request1 : request3). |
410 | 415 |
411 TestCompletionCallback callback1; | 416 TestCompletionCallback callback1; |
412 ProxyInfo results1; | 417 ProxyInfo results1; |
413 rv = resolver().GetProxyForURL(GURL("http://request1"), &results1, | 418 rv = resolver().GetProxyForURL(GURL("http://request1"), &results1, |
414 callback1.callback(), NULL, BoundNetLog()); | 419 callback1.callback(), NULL, BoundNetLog()); |
415 EXPECT_EQ(ERR_IO_PENDING, rv); | 420 EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); |
416 | 421 |
417 ProxyResolver::RequestHandle request2; | 422 ProxyResolver::RequestHandle request2; |
418 TestCompletionCallback callback2; | 423 TestCompletionCallback callback2; |
419 ProxyInfo results2; | 424 ProxyInfo results2; |
420 rv = | 425 rv = |
421 resolver().GetProxyForURL(GURL("http://request2"), &results2, | 426 resolver().GetProxyForURL(GURL("http://request2"), &results2, |
422 callback2.callback(), &request2, BoundNetLog()); | 427 callback2.callback(), &request2, BoundNetLog()); |
423 EXPECT_EQ(ERR_IO_PENDING, rv); | 428 EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); |
424 | 429 |
425 TestCompletionCallback callback3; | 430 TestCompletionCallback callback3; |
426 ProxyInfo results3; | 431 ProxyInfo results3; |
427 rv = resolver().GetProxyForURL(GURL("http://request3"), &results3, | 432 rv = resolver().GetProxyForURL(GURL("http://request3"), &results3, |
428 callback3.callback(), NULL, BoundNetLog()); | 433 callback3.callback(), NULL, BoundNetLog()); |
429 EXPECT_EQ(ERR_IO_PENDING, rv); | 434 EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); |
430 | 435 |
431 // Cancel request0 (inprogress) and request2 (pending). | 436 // Cancel request0 (inprogress) and request2 (pending). |
432 resolver().CancelRequest(request0); | 437 resolver().CancelRequest(request0); |
433 resolver().CancelRequest(request2); | 438 resolver().CancelRequest(request2); |
434 | 439 |
435 // Unblock the worker thread so the requests can continue running. | 440 // Unblock the worker thread so the requests can continue running. |
436 factory().resolvers()[0]->Unblock(); | 441 factory().resolvers()[0]->Unblock(); |
437 | 442 |
438 // Wait for requests 1 and 3 to finish. | 443 // Wait for requests 1 and 3 to finish. |
439 | 444 |
(...skipping 24 matching lines...) Expand all Loading... |
464 // Block the proxy resolver, so no request can complete. | 469 // Block the proxy resolver, so no request can complete. |
465 factory().resolvers()[0]->Block(); | 470 factory().resolvers()[0]->Block(); |
466 | 471 |
467 int rv; | 472 int rv; |
468 // Start 3 requests. | 473 // Start 3 requests. |
469 | 474 |
470 TestCompletionCallback callback0; | 475 TestCompletionCallback callback0; |
471 ProxyInfo results0; | 476 ProxyInfo results0; |
472 rv = resolver().GetProxyForURL(GURL("http://request0"), &results0, | 477 rv = resolver().GetProxyForURL(GURL("http://request0"), &results0, |
473 callback0.callback(), NULL, BoundNetLog()); | 478 callback0.callback(), NULL, BoundNetLog()); |
474 EXPECT_EQ(ERR_IO_PENDING, rv); | 479 EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); |
475 | 480 |
476 TestCompletionCallback callback1; | 481 TestCompletionCallback callback1; |
477 ProxyInfo results1; | 482 ProxyInfo results1; |
478 rv = resolver().GetProxyForURL(GURL("http://request1"), &results1, | 483 rv = resolver().GetProxyForURL(GURL("http://request1"), &results1, |
479 callback1.callback(), NULL, BoundNetLog()); | 484 callback1.callback(), NULL, BoundNetLog()); |
480 EXPECT_EQ(ERR_IO_PENDING, rv); | 485 EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); |
481 | 486 |
482 TestCompletionCallback callback2; | 487 TestCompletionCallback callback2; |
483 ProxyInfo results2; | 488 ProxyInfo results2; |
484 rv = resolver().GetProxyForURL(GURL("http://request2"), &results2, | 489 rv = resolver().GetProxyForURL(GURL("http://request2"), &results2, |
485 callback2.callback(), NULL, BoundNetLog()); | 490 callback2.callback(), NULL, BoundNetLog()); |
486 EXPECT_EQ(ERR_IO_PENDING, rv); | 491 EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); |
487 | 492 |
488 // Wait until request 0 reaches the worker thread. | 493 // Wait until request 0 reaches the worker thread. |
489 factory().resolvers()[0]->WaitUntilBlocked(); | 494 factory().resolvers()[0]->WaitUntilBlocked(); |
490 | 495 |
491 // Add some latency, to improve the chance that when | 496 // Add some latency, to improve the chance that when |
492 // MultiThreadedProxyResolver is deleted below we are still running inside | 497 // MultiThreadedProxyResolver is deleted below we are still running inside |
493 // of the worker thread. The test will pass regardless, so this race doesn't | 498 // of the worker thread. The test will pass regardless, so this race doesn't |
494 // cause flakiness. However the destruction during execution is a more | 499 // cause flakiness. However the destruction during execution is a more |
495 // interesting case to test. | 500 // interesting case to test. |
496 factory().resolvers()[0]->SetResolveLatency( | 501 factory().resolvers()[0]->SetResolveLatency( |
(...skipping 27 matching lines...) Expand all Loading... |
524 int rv; | 529 int rv; |
525 TestCompletionCallback callback[kNumRequests]; | 530 TestCompletionCallback callback[kNumRequests]; |
526 ProxyInfo results[kNumRequests]; | 531 ProxyInfo results[kNumRequests]; |
527 ProxyResolver::RequestHandle request[kNumRequests]; | 532 ProxyResolver::RequestHandle request[kNumRequests]; |
528 | 533 |
529 // Start request 0 -- this should run on thread 0 as there is nothing else | 534 // Start request 0 -- this should run on thread 0 as there is nothing else |
530 // going on right now. | 535 // going on right now. |
531 rv = resolver().GetProxyForURL(GURL("http://request0"), &results[0], | 536 rv = resolver().GetProxyForURL(GURL("http://request0"), &results[0], |
532 callback[0].callback(), &request[0], | 537 callback[0].callback(), &request[0], |
533 BoundNetLog()); | 538 BoundNetLog()); |
534 EXPECT_EQ(ERR_IO_PENDING, rv); | 539 EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); |
535 | 540 |
536 // Wait for request 0 to finish. | 541 // Wait for request 0 to finish. |
537 rv = callback[0].WaitForResult(); | 542 rv = callback[0].WaitForResult(); |
538 EXPECT_EQ(0, rv); | 543 EXPECT_EQ(0, rv); |
539 EXPECT_EQ("PROXY request0:80", results[0].ToPacString()); | 544 EXPECT_EQ("PROXY request0:80", results[0].ToPacString()); |
540 ASSERT_EQ(1u, factory().resolvers().size()); | 545 ASSERT_EQ(1u, factory().resolvers().size()); |
541 EXPECT_EQ(1, factory().resolvers()[0]->request_count()); | 546 EXPECT_EQ(1, factory().resolvers()[0]->request_count()); |
542 | 547 |
543 base::RunLoop().RunUntilIdle(); | 548 base::RunLoop().RunUntilIdle(); |
544 | 549 |
545 // We now block the first resolver to ensure a request is sent to the second | 550 // We now block the first resolver to ensure a request is sent to the second |
546 // thread. | 551 // thread. |
547 factory().resolvers()[0]->Block(); | 552 factory().resolvers()[0]->Block(); |
548 rv = resolver().GetProxyForURL(GURL("http://request1"), &results[1], | 553 rv = resolver().GetProxyForURL(GURL("http://request1"), &results[1], |
549 callback[1].callback(), &request[1], | 554 callback[1].callback(), &request[1], |
550 BoundNetLog()); | 555 BoundNetLog()); |
551 EXPECT_EQ(ERR_IO_PENDING, rv); | 556 EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); |
552 factory().resolvers()[0]->WaitUntilBlocked(); | 557 factory().resolvers()[0]->WaitUntilBlocked(); |
553 rv = resolver().GetProxyForURL(GURL("http://request2"), &results[2], | 558 rv = resolver().GetProxyForURL(GURL("http://request2"), &results[2], |
554 callback[2].callback(), &request[2], | 559 callback[2].callback(), &request[2], |
555 BoundNetLog()); | 560 BoundNetLog()); |
556 EXPECT_EQ(ERR_IO_PENDING, rv); | 561 EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); |
557 EXPECT_EQ(0, callback[2].WaitForResult()); | 562 EXPECT_EQ(0, callback[2].WaitForResult()); |
558 ASSERT_EQ(2u, factory().resolvers().size()); | 563 ASSERT_EQ(2u, factory().resolvers().size()); |
559 | 564 |
560 // We now block the second resolver as well to ensure a request is sent to the | 565 // We now block the second resolver as well to ensure a request is sent to the |
561 // third thread. | 566 // third thread. |
562 factory().resolvers()[1]->Block(); | 567 factory().resolvers()[1]->Block(); |
563 rv = resolver().GetProxyForURL(GURL("http://request3"), &results[3], | 568 rv = resolver().GetProxyForURL(GURL("http://request3"), &results[3], |
564 callback[3].callback(), &request[3], | 569 callback[3].callback(), &request[3], |
565 BoundNetLog()); | 570 BoundNetLog()); |
566 EXPECT_EQ(ERR_IO_PENDING, rv); | 571 EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); |
567 factory().resolvers()[1]->WaitUntilBlocked(); | 572 factory().resolvers()[1]->WaitUntilBlocked(); |
568 rv = resolver().GetProxyForURL(GURL("http://request4"), &results[4], | 573 rv = resolver().GetProxyForURL(GURL("http://request4"), &results[4], |
569 callback[4].callback(), &request[4], | 574 callback[4].callback(), &request[4], |
570 BoundNetLog()); | 575 BoundNetLog()); |
571 EXPECT_EQ(ERR_IO_PENDING, rv); | 576 EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); |
572 EXPECT_EQ(0, callback[4].WaitForResult()); | 577 EXPECT_EQ(0, callback[4].WaitForResult()); |
573 | 578 |
574 // We should now have a total of 3 threads, each with its own ProxyResolver | 579 // We should now have a total of 3 threads, each with its own ProxyResolver |
575 // that will get initialized with the same data. | 580 // that will get initialized with the same data. |
576 ASSERT_EQ(3u, factory().resolvers().size()); | 581 ASSERT_EQ(3u, factory().resolvers().size()); |
577 | 582 |
578 ASSERT_EQ(3u, factory().script_data().size()); | 583 ASSERT_EQ(3u, factory().script_data().size()); |
579 for (int i = 0; i < 3; ++i) { | 584 for (int i = 0; i < 3; ++i) { |
580 EXPECT_EQ(ASCIIToUTF16("pac script bytes"), | 585 EXPECT_EQ(ASCIIToUTF16("pac script bytes"), |
581 factory().script_data()[i]->utf16()) | 586 factory().script_data()[i]->utf16()) |
582 << "i=" << i; | 587 << "i=" << i; |
583 } | 588 } |
584 | 589 |
585 // Start and cancel two requests. Since the first two threads are still | 590 // Start and cancel two requests. Since the first two threads are still |
586 // blocked, they'll both be serviced by the third thread. The first request | 591 // blocked, they'll both be serviced by the third thread. The first request |
587 // will reach the resolver, but the second will still be queued when canceled. | 592 // will reach the resolver, but the second will still be queued when canceled. |
588 // Start a third request so we can be sure the resolver has completed running | 593 // Start a third request so we can be sure the resolver has completed running |
589 // the first request. | 594 // the first request. |
590 rv = resolver().GetProxyForURL(GURL("http://request5"), &results[5], | 595 rv = resolver().GetProxyForURL(GURL("http://request5"), &results[5], |
591 callback[5].callback(), &request[5], | 596 callback[5].callback(), &request[5], |
592 BoundNetLog()); | 597 BoundNetLog()); |
593 EXPECT_EQ(ERR_IO_PENDING, rv); | 598 EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); |
594 rv = resolver().GetProxyForURL(GURL("http://request6"), &results[6], | 599 rv = resolver().GetProxyForURL(GURL("http://request6"), &results[6], |
595 callback[6].callback(), &request[6], | 600 callback[6].callback(), &request[6], |
596 BoundNetLog()); | 601 BoundNetLog()); |
597 EXPECT_EQ(ERR_IO_PENDING, rv); | 602 EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); |
598 rv = resolver().GetProxyForURL(GURL("http://request7"), &results[7], | 603 rv = resolver().GetProxyForURL(GURL("http://request7"), &results[7], |
599 callback[7].callback(), &request[7], | 604 callback[7].callback(), &request[7], |
600 BoundNetLog()); | 605 BoundNetLog()); |
601 EXPECT_EQ(ERR_IO_PENDING, rv); | 606 EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); |
602 resolver().CancelRequest(request[5]); | 607 resolver().CancelRequest(request[5]); |
603 resolver().CancelRequest(request[6]); | 608 resolver().CancelRequest(request[6]); |
604 | 609 |
605 EXPECT_EQ(2, callback[7].WaitForResult()); | 610 EXPECT_EQ(2, callback[7].WaitForResult()); |
606 | 611 |
607 // Check that the cancelled requests never invoked their callback. | 612 // Check that the cancelled requests never invoked their callback. |
608 EXPECT_FALSE(callback[5].have_result()); | 613 EXPECT_FALSE(callback[5].have_result()); |
609 EXPECT_FALSE(callback[6].have_result()); | 614 EXPECT_FALSE(callback[6].have_result()); |
610 | 615 |
611 // Unblock the first two threads and wait for their requests to complete. | 616 // Unblock the first two threads and wait for their requests to complete. |
(...skipping 27 matching lines...) Expand all Loading... |
639 ProxyResolver::RequestHandle request[kNumRequests]; | 644 ProxyResolver::RequestHandle request[kNumRequests]; |
640 | 645 |
641 // Start a request that will block the first thread. | 646 // Start a request that will block the first thread. |
642 | 647 |
643 factory().resolvers()[0]->Block(); | 648 factory().resolvers()[0]->Block(); |
644 | 649 |
645 rv = resolver().GetProxyForURL(GURL("http://request0"), &results[0], | 650 rv = resolver().GetProxyForURL(GURL("http://request0"), &results[0], |
646 callback[0].callback(), &request[0], | 651 callback[0].callback(), &request[0], |
647 BoundNetLog()); | 652 BoundNetLog()); |
648 | 653 |
649 EXPECT_EQ(ERR_IO_PENDING, rv); | 654 EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); |
650 factory().resolvers()[0]->WaitUntilBlocked(); | 655 factory().resolvers()[0]->WaitUntilBlocked(); |
651 | 656 |
652 // Start 3 more requests -- they should all be serviced by thread #2 | 657 // Start 3 more requests -- they should all be serviced by thread #2 |
653 // since thread #1 is blocked. | 658 // since thread #1 is blocked. |
654 | 659 |
655 for (int i = 1; i < kNumRequests; ++i) { | 660 for (int i = 1; i < kNumRequests; ++i) { |
656 rv = resolver().GetProxyForURL( | 661 rv = resolver().GetProxyForURL( |
657 GURL(base::StringPrintf("http://request%d", i)), &results[i], | 662 GURL(base::StringPrintf("http://request%d", i)), &results[i], |
658 callback[i].callback(), &request[i], BoundNetLog()); | 663 callback[i].callback(), &request[i], BoundNetLog()); |
659 EXPECT_EQ(ERR_IO_PENDING, rv); | 664 EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); |
660 } | 665 } |
661 | 666 |
662 // Wait for the three requests to complete (they should complete in FIFO | 667 // Wait for the three requests to complete (they should complete in FIFO |
663 // order). | 668 // order). |
664 for (int i = 1; i < kNumRequests; ++i) { | 669 for (int i = 1; i < kNumRequests; ++i) { |
665 EXPECT_EQ(i - 1, callback[i].WaitForResult()); | 670 EXPECT_EQ(i - 1, callback[i].WaitForResult()); |
666 } | 671 } |
667 | 672 |
668 // Unblock the first thread. | 673 // Unblock the first thread. |
669 factory().resolvers()[0]->Unblock(); | 674 factory().resolvers()[0]->Unblock(); |
(...skipping 27 matching lines...) Expand all Loading... |
697 SingleShotMultiThreadedProxyResolverFactory resolver_factory( | 702 SingleShotMultiThreadedProxyResolverFactory resolver_factory( |
698 kNumThreads, base::WrapUnique(new FailingProxyResolverFactory)); | 703 kNumThreads, base::WrapUnique(new FailingProxyResolverFactory)); |
699 TestCompletionCallback ready_callback; | 704 TestCompletionCallback ready_callback; |
700 std::unique_ptr<ProxyResolverFactory::Request> request; | 705 std::unique_ptr<ProxyResolverFactory::Request> request; |
701 std::unique_ptr<ProxyResolver> resolver; | 706 std::unique_ptr<ProxyResolver> resolver; |
702 EXPECT_EQ(ERR_IO_PENDING, | 707 EXPECT_EQ(ERR_IO_PENDING, |
703 resolver_factory.CreateProxyResolver( | 708 resolver_factory.CreateProxyResolver( |
704 ProxyResolverScriptData::FromUTF8("pac script bytes"), | 709 ProxyResolverScriptData::FromUTF8("pac script bytes"), |
705 &resolver, ready_callback.callback(), &request)); | 710 &resolver, ready_callback.callback(), &request)); |
706 EXPECT_TRUE(request); | 711 EXPECT_TRUE(request); |
707 EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, ready_callback.WaitForResult()); | 712 EXPECT_THAT(ready_callback.WaitForResult(), IsError(ERR_PAC_SCRIPT_FAILED)); |
708 EXPECT_FALSE(resolver); | 713 EXPECT_FALSE(resolver); |
709 } | 714 } |
710 | 715 |
711 void Fail(int error) { | 716 void Fail(int error) { |
712 FAIL() << "Unexpected callback with error " << error; | 717 FAIL() << "Unexpected callback with error " << error; |
713 } | 718 } |
714 | 719 |
715 // Test that cancelling an in-progress create request works correctly. | 720 // Test that cancelling an in-progress create request works correctly. |
716 TEST_F(MultiThreadedProxyResolverTest, CancelCreate) { | 721 TEST_F(MultiThreadedProxyResolverTest, CancelCreate) { |
717 const size_t kNumThreads = 1u; | 722 const size_t kNumThreads = 1u; |
(...skipping 30 matching lines...) Expand all Loading... |
748 std::unique_ptr<ProxyResolverFactory::Request> request; | 753 std::unique_ptr<ProxyResolverFactory::Request> request; |
749 std::unique_ptr<ProxyResolver> resolver; | 754 std::unique_ptr<ProxyResolver> resolver; |
750 TestCompletionCallback callback; | 755 TestCompletionCallback callback; |
751 EXPECT_EQ(ERR_IO_PENDING, | 756 EXPECT_EQ(ERR_IO_PENDING, |
752 resolver_factory.CreateProxyResolver( | 757 resolver_factory.CreateProxyResolver( |
753 ProxyResolverScriptData::FromUTF8("pac script bytes"), | 758 ProxyResolverScriptData::FromUTF8("pac script bytes"), |
754 &resolver, base::Bind(&DeleteRequest, callback.callback(), | 759 &resolver, base::Bind(&DeleteRequest, callback.callback(), |
755 base::Unretained(&request)), | 760 base::Unretained(&request)), |
756 &request)); | 761 &request)); |
757 EXPECT_TRUE(request); | 762 EXPECT_TRUE(request); |
758 EXPECT_EQ(OK, callback.WaitForResult()); | 763 EXPECT_THAT(callback.WaitForResult(), IsOk()); |
759 } | 764 } |
760 | 765 |
761 // Test that deleting the factory with a request in-progress works correctly. | 766 // Test that deleting the factory with a request in-progress works correctly. |
762 TEST_F(MultiThreadedProxyResolverTest, DestroyFactoryWithRequestsInProgress) { | 767 TEST_F(MultiThreadedProxyResolverTest, DestroyFactoryWithRequestsInProgress) { |
763 const size_t kNumThreads = 1u; | 768 const size_t kNumThreads = 1u; |
764 std::unique_ptr<ProxyResolverFactory::Request> request; | 769 std::unique_ptr<ProxyResolverFactory::Request> request; |
765 std::unique_ptr<ProxyResolver> resolver; | 770 std::unique_ptr<ProxyResolver> resolver; |
766 { | 771 { |
767 SingleShotMultiThreadedProxyResolverFactory resolver_factory( | 772 SingleShotMultiThreadedProxyResolverFactory resolver_factory( |
768 kNumThreads, base::WrapUnique(new BlockableProxyResolverFactory)); | 773 kNumThreads, base::WrapUnique(new BlockableProxyResolverFactory)); |
769 EXPECT_EQ(ERR_IO_PENDING, | 774 EXPECT_EQ(ERR_IO_PENDING, |
770 resolver_factory.CreateProxyResolver( | 775 resolver_factory.CreateProxyResolver( |
771 ProxyResolverScriptData::FromUTF8("pac script bytes"), | 776 ProxyResolverScriptData::FromUTF8("pac script bytes"), |
772 &resolver, base::Bind(&Fail), &request)); | 777 &resolver, base::Bind(&Fail), &request)); |
773 EXPECT_TRUE(request); | 778 EXPECT_TRUE(request); |
774 } | 779 } |
775 // The factory destructor will block until the worker thread stops, but it may | 780 // The factory destructor will block until the worker thread stops, but it may |
776 // post tasks to the origin message loop which are still pending. Run them | 781 // post tasks to the origin message loop which are still pending. Run them |
777 // now to ensure it works as expected. | 782 // now to ensure it works as expected. |
778 base::RunLoop().RunUntilIdle(); | 783 base::RunLoop().RunUntilIdle(); |
779 } | 784 } |
780 | 785 |
781 } // namespace | 786 } // namespace |
782 | 787 |
783 } // namespace net | 788 } // namespace net |
OLD | NEW |