| 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 |