1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/proxy/proxy_resolver_mojo.h"
12 #include "base/bind.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/memory/scoped_vector.h"
15 #include "base/run_loop.h"
16 #include "base/stl_util.h"
17 #include "mojo/common/common_type_converters.h"
18 #include "net/base/load_states.h"
19 #include "net/base/net_errors.h"
20 #include "net/base/test_completion_callback.h"
21 #include "net/log/net_log.h"
22 #include "net/proxy/mojo_proxy_resolver_factory.h"
23 #include "net/proxy/mojo_proxy_type_converters.h"
24 #include "net/proxy/proxy_info.h"
25 #include "net/proxy/proxy_resolver.h"
26 #include "net/proxy/proxy_resolver_error_observer.h"
27 #include "net/proxy/proxy_resolver_script_data.h"
28 #include "testing/gtest/include/gtest/gtest.h"
29 #include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h"
30 #include "third_party/mojo/src/mojo/public/cpp/bindings/error_handler.h"
37 const char kScriptData
[] = "FooBarBaz";
38 const char kExampleUrl
[] = "http://www.example.com";
40 struct CreateProxyResolverAction
{
46 WAIT_FOR_CLIENT_DISCONNECT
,
49 static CreateProxyResolverAction
ReturnResult(
50 const std::string
& expected_pac_script
,
52 CreateProxyResolverAction result
;
53 result
.expected_pac_script
= expected_pac_script
;
58 static CreateProxyResolverAction
DropClient(
59 const std::string
& expected_pac_script
) {
60 CreateProxyResolverAction result
;
61 result
.expected_pac_script
= expected_pac_script
;
62 result
.action
= DROP_CLIENT
;
66 static CreateProxyResolverAction
DropResolver(
67 const std::string
& expected_pac_script
) {
68 CreateProxyResolverAction result
;
69 result
.expected_pac_script
= expected_pac_script
;
70 result
.action
= DROP_RESOLVER
;
74 static CreateProxyResolverAction
DropBoth(
75 const std::string
& expected_pac_script
) {
76 CreateProxyResolverAction result
;
77 result
.expected_pac_script
= expected_pac_script
;
78 result
.action
= DROP_BOTH
;
82 static CreateProxyResolverAction
WaitForClientDisconnect(
83 const std::string
& expected_pac_script
) {
84 CreateProxyResolverAction result
;
85 result
.expected_pac_script
= expected_pac_script
;
86 result
.action
= WAIT_FOR_CLIENT_DISCONNECT
;
90 std::string expected_pac_script
;
91 Action action
= COMPLETE
;
95 struct GetProxyForUrlAction
{
98 // Drop the request by closing the reply channel.
100 // Disconnect the service.
102 // Wait for the client pipe to be disconnected.
103 WAIT_FOR_CLIENT_DISCONNECT
,
104 // Send a LoadStateChanged message and keep the client pipe open.
105 SEND_LOAD_STATE_AND_BLOCK
,
108 GetProxyForUrlAction() {}
109 GetProxyForUrlAction(const GetProxyForUrlAction
& old
) {
112 expected_url
= old
.expected_url
;
113 proxy_servers
= old
.proxy_servers
.Clone();
116 static GetProxyForUrlAction
ReturnError(const GURL
& url
, Error error
) {
117 GetProxyForUrlAction result
;
118 result
.expected_url
= url
;
119 result
.error
= error
;
123 static GetProxyForUrlAction
ReturnServers(
125 const mojo::Array
<interfaces::ProxyServerPtr
>& proxy_servers
) {
126 GetProxyForUrlAction result
;
127 result
.expected_url
= url
;
128 result
.proxy_servers
= proxy_servers
.Clone();
132 static GetProxyForUrlAction
DropRequest(const GURL
& url
) {
133 GetProxyForUrlAction result
;
134 result
.expected_url
= url
;
135 result
.action
= DROP
;
139 static GetProxyForUrlAction
Disconnect(const GURL
& url
) {
140 GetProxyForUrlAction result
;
141 result
.expected_url
= url
;
142 result
.action
= DISCONNECT
;
146 static GetProxyForUrlAction
WaitForClientDisconnect(const GURL
& url
) {
147 GetProxyForUrlAction result
;
148 result
.expected_url
= url
;
149 result
.action
= WAIT_FOR_CLIENT_DISCONNECT
;
153 static GetProxyForUrlAction
SendLoadStateChanged(const GURL
& url
) {
154 GetProxyForUrlAction result
;
155 result
.expected_url
= url
;
156 result
.action
= SEND_LOAD_STATE_AND_BLOCK
;
160 Action action
= COMPLETE
;
162 mojo::Array
<interfaces::ProxyServerPtr
> proxy_servers
;
166 class MockMojoProxyResolver
: public interfaces::ProxyResolver
{
168 MockMojoProxyResolver();
169 ~MockMojoProxyResolver() override
;
171 void AddGetProxyAction(GetProxyForUrlAction action
);
173 void WaitForNextRequest();
175 void ClearBlockedClients();
177 void AddConnection(mojo::InterfaceRequest
<interfaces::ProxyResolver
> req
);
180 // Overridden from interfaces::ProxyResolver:
182 const mojo::String
& url
,
183 interfaces::ProxyResolverRequestClientPtr client
) override
;
187 std::string pac_script_data_
;
189 std::queue
<GetProxyForUrlAction
> get_proxy_actions_
;
191 base::Closure quit_closure_
;
193 ScopedVector
<interfaces::ProxyResolverRequestClientPtr
> blocked_clients_
;
194 mojo::Binding
<interfaces::ProxyResolver
> binding_
;
197 MockMojoProxyResolver::~MockMojoProxyResolver() {
198 EXPECT_TRUE(get_proxy_actions_
.empty())
199 << "Actions remaining: " << get_proxy_actions_
.size();
202 MockMojoProxyResolver::MockMojoProxyResolver() : binding_(this) {
205 void MockMojoProxyResolver::AddGetProxyAction(GetProxyForUrlAction action
) {
206 get_proxy_actions_
.push(action
);
209 void MockMojoProxyResolver::WaitForNextRequest() {
210 base::RunLoop run_loop
;
211 quit_closure_
= run_loop
.QuitClosure();
215 void MockMojoProxyResolver::WakeWaiter() {
216 if (!quit_closure_
.is_null())
218 quit_closure_
.Reset();
221 void MockMojoProxyResolver::ClearBlockedClients() {
222 blocked_clients_
.clear();
225 void MockMojoProxyResolver::AddConnection(
226 mojo::InterfaceRequest
<interfaces::ProxyResolver
> req
) {
227 if (binding_
.is_bound())
229 binding_
.Bind(req
.Pass());
232 void MockMojoProxyResolver::GetProxyForUrl(
233 const mojo::String
& url
,
234 interfaces::ProxyResolverRequestClientPtr client
) {
235 ASSERT_FALSE(get_proxy_actions_
.empty());
236 GetProxyForUrlAction action
= get_proxy_actions_
.front();
237 get_proxy_actions_
.pop();
239 EXPECT_EQ(action
.expected_url
.spec(), url
.To
<std::string
>());
240 switch (action
.action
) {
241 case GetProxyForUrlAction::COMPLETE
:
242 client
->ReportResult(action
.error
, action
.proxy_servers
.Pass());
244 case GetProxyForUrlAction::DROP
:
247 case GetProxyForUrlAction::DISCONNECT
:
250 case GetProxyForUrlAction::WAIT_FOR_CLIENT_DISCONNECT
:
251 ASSERT_FALSE(client
.WaitForIncomingResponse());
253 case GetProxyForUrlAction::SEND_LOAD_STATE_AND_BLOCK
:
254 client
->LoadStateChanged(LOAD_STATE_RESOLVING_HOST_IN_PROXY_SCRIPT
);
255 blocked_clients_
.push_back(
256 new interfaces::ProxyResolverRequestClientPtr(client
.Pass()));
264 Request(ProxyResolver
* resolver
, const GURL
& url
);
270 int error() const { return error_
; }
271 const ProxyInfo
& results() const { return results_
; }
272 LoadState
load_state() { return resolver_
->GetLoadState(handle_
); }
275 ProxyResolver
* resolver_
;
278 ProxyResolver::RequestHandle handle_
;
280 TestCompletionCallback callback_
;
283 Request::Request(ProxyResolver
* resolver
, const GURL
& url
)
284 : resolver_(resolver
), url_(url
), error_(0) {
287 int Request::Resolve() {
289 error_
= resolver_
->GetProxyForURL(url_
, &results_
, callback_
.callback(),
294 void Request::Cancel() {
295 resolver_
->CancelRequest(handle_
);
298 int Request::WaitForResult() {
299 error_
= callback_
.WaitForResult();
303 class MockMojoProxyResolverFactory
: public interfaces::ProxyResolverFactory
{
305 MockMojoProxyResolverFactory(
306 MockMojoProxyResolver
* resolver
,
307 mojo::InterfaceRequest
<interfaces::ProxyResolverFactory
> req
);
308 ~MockMojoProxyResolverFactory() override
;
310 void AddCreateProxyResolverAction(CreateProxyResolverAction action
);
312 void WaitForNextRequest();
314 void ClearBlockedClients();
317 // Overridden from interfaces::ProxyResolver:
319 const mojo::String
& pac_url
,
320 mojo::InterfaceRequest
<interfaces::ProxyResolver
> request
,
321 interfaces::HostResolverPtr host_resolver
,
322 interfaces::ProxyResolverErrorObserverPtr error_observer
,
323 interfaces::ProxyResolverFactoryRequestClientPtr client
) override
;
327 MockMojoProxyResolver
* resolver_
;
328 std::queue
<CreateProxyResolverAction
> create_resolver_actions_
;
330 base::Closure quit_closure_
;
332 ScopedVector
<interfaces::ProxyResolverFactoryRequestClientPtr
>
334 ScopedVector
<mojo::InterfaceRequest
<interfaces::ProxyResolver
>>
335 blocked_resolver_requests_
;
336 mojo::Binding
<interfaces::ProxyResolverFactory
> binding_
;
339 MockMojoProxyResolverFactory::MockMojoProxyResolverFactory(
340 MockMojoProxyResolver
* resolver
,
341 mojo::InterfaceRequest
<interfaces::ProxyResolverFactory
> req
)
342 : resolver_(resolver
), binding_(this, req
.Pass()) {
345 MockMojoProxyResolverFactory::~MockMojoProxyResolverFactory() {
346 EXPECT_TRUE(create_resolver_actions_
.empty())
347 << "Actions remaining: " << create_resolver_actions_
.size();
350 void MockMojoProxyResolverFactory::AddCreateProxyResolverAction(
351 CreateProxyResolverAction action
) {
352 create_resolver_actions_
.push(action
);
355 void MockMojoProxyResolverFactory::WaitForNextRequest() {
356 base::RunLoop run_loop
;
357 quit_closure_
= run_loop
.QuitClosure();
361 void MockMojoProxyResolverFactory::WakeWaiter() {
362 if (!quit_closure_
.is_null())
364 quit_closure_
.Reset();
367 void MockMojoProxyResolverFactory::ClearBlockedClients() {
368 blocked_clients_
.clear();
371 void MockMojoProxyResolverFactory::CreateResolver(
372 const mojo::String
& pac_script
,
373 mojo::InterfaceRequest
<interfaces::ProxyResolver
> request
,
374 interfaces::HostResolverPtr host_resolver
,
375 interfaces::ProxyResolverErrorObserverPtr error_observer
,
376 interfaces::ProxyResolverFactoryRequestClientPtr client
) {
377 ASSERT_FALSE(create_resolver_actions_
.empty());
378 CreateProxyResolverAction action
= create_resolver_actions_
.front();
379 create_resolver_actions_
.pop();
381 EXPECT_EQ(action
.expected_pac_script
, pac_script
.To
<std::string
>());
382 switch (action
.action
) {
383 case CreateProxyResolverAction::COMPLETE
:
384 if (action
.error
== OK
)
385 resolver_
->AddConnection(request
.Pass());
386 client
->ReportResult(action
.error
);
388 case CreateProxyResolverAction::DROP_CLIENT
:
389 // Save |request| so its pipe isn't closed.
390 blocked_resolver_requests_
.push_back(
391 new mojo::InterfaceRequest
<interfaces::ProxyResolver
>(
394 case CreateProxyResolverAction::DROP_RESOLVER
:
395 // Save |client| so its pipe isn't closed.
396 blocked_clients_
.push_back(
397 new interfaces::ProxyResolverFactoryRequestClientPtr(client
.Pass()));
399 case CreateProxyResolverAction::DROP_BOTH
:
400 // Both |request| and |client| will be closed.
402 case CreateProxyResolverAction::WAIT_FOR_CLIENT_DISCONNECT
:
403 ASSERT_FALSE(client
.WaitForIncomingResponse());
411 class ProxyResolverMojoTest
: public testing::Test
,
412 public MojoProxyResolverFactory
{
414 void SetUp() override
{
415 mock_proxy_resolver_factory_
.reset(new MockMojoProxyResolverFactory(
416 &mock_proxy_resolver_
, mojo::GetProxy(&factory_ptr_
)));
417 proxy_resolver_factory_mojo_
.reset(new ProxyResolverFactoryMojo(
419 base::Callback
<scoped_ptr
<ProxyResolverErrorObserver
>()>()));
422 scoped_ptr
<Request
> MakeRequest(const GURL
& url
) {
423 return make_scoped_ptr(new Request(proxy_resolver_mojo_
.get(), url
));
426 scoped_ptr
<base::ScopedClosureRunner
> CreateResolver(
427 const mojo::String
& pac_script
,
428 mojo::InterfaceRequest
<interfaces::ProxyResolver
> req
,
429 interfaces::HostResolverPtr host_resolver
,
430 interfaces::ProxyResolverErrorObserverPtr error_observer
,
431 interfaces::ProxyResolverFactoryRequestClientPtr client
) override
{
432 factory_ptr_
->CreateResolver(pac_script
, req
.Pass(), host_resolver
.Pass(),
433 error_observer
.Pass(), client
.Pass());
434 return make_scoped_ptr(
435 new base::ScopedClosureRunner(on_delete_callback_
.closure()));
438 mojo::Array
<interfaces::ProxyServerPtr
> ProxyServersFromPacString(
439 const std::string
& pac_string
) {
440 ProxyInfo proxy_info
;
441 proxy_info
.UsePacString(pac_string
);
443 return mojo::Array
<interfaces::ProxyServerPtr
>::From(
444 proxy_info
.proxy_list().GetAll());
447 void CreateProxyResolver() {
448 mock_proxy_resolver_factory_
->AddCreateProxyResolverAction(
449 CreateProxyResolverAction::ReturnResult(kScriptData
, OK
));
450 TestCompletionCallback callback
;
451 scoped_refptr
<ProxyResolverScriptData
> pac_script(
452 ProxyResolverScriptData::FromUTF8(kScriptData
));
453 scoped_ptr
<ProxyResolverFactory::Request
> request
;
456 callback
.GetResult(proxy_resolver_factory_mojo_
->CreateProxyResolver(
457 pac_script
, &proxy_resolver_mojo_
, callback
.callback(), &request
)));
458 EXPECT_TRUE(request
);
459 ASSERT_TRUE(proxy_resolver_mojo_
);
462 void DeleteProxyResolverCallback(const CompletionCallback
& callback
,
464 proxy_resolver_mojo_
.reset();
465 callback
.Run(result
);
468 scoped_ptr
<MockMojoProxyResolverFactory
> mock_proxy_resolver_factory_
;
469 interfaces::ProxyResolverFactoryPtr factory_ptr_
;
470 scoped_ptr
<ProxyResolverFactory
> proxy_resolver_factory_mojo_
;
472 MockMojoProxyResolver mock_proxy_resolver_
;
473 scoped_ptr
<ProxyResolver
> proxy_resolver_mojo_
;
474 TestClosure on_delete_callback_
;
477 TEST_F(ProxyResolverMojoTest
, CreateProxyResolver
) {
478 CreateProxyResolver();
481 TEST_F(ProxyResolverMojoTest
, CreateProxyResolver_Empty
) {
482 TestCompletionCallback callback
;
483 scoped_refptr
<ProxyResolverScriptData
> pac_script(
484 ProxyResolverScriptData::FromUTF8(""));
485 scoped_ptr
<ProxyResolverFactory::Request
> request
;
487 ERR_PAC_SCRIPT_FAILED
,
488 callback
.GetResult(proxy_resolver_factory_mojo_
->CreateProxyResolver(
489 pac_script
, &proxy_resolver_mojo_
, callback
.callback(), &request
)));
490 EXPECT_FALSE(request
);
493 TEST_F(ProxyResolverMojoTest
, CreateProxyResolver_Url
) {
494 TestCompletionCallback callback
;
495 scoped_refptr
<ProxyResolverScriptData
> pac_script(
496 ProxyResolverScriptData::FromURL(GURL(kExampleUrl
)));
497 scoped_ptr
<ProxyResolverFactory::Request
> request
;
499 ERR_PAC_SCRIPT_FAILED
,
500 callback
.GetResult(proxy_resolver_factory_mojo_
->CreateProxyResolver(
501 pac_script
, &proxy_resolver_mojo_
, callback
.callback(), &request
)));
502 EXPECT_FALSE(request
);
505 TEST_F(ProxyResolverMojoTest
, CreateProxyResolver_Failed
) {
506 mock_proxy_resolver_factory_
->AddCreateProxyResolverAction(
507 CreateProxyResolverAction::ReturnResult(kScriptData
,
508 ERR_PAC_STATUS_NOT_OK
));
510 TestCompletionCallback callback
;
511 scoped_refptr
<ProxyResolverScriptData
> pac_script(
512 ProxyResolverScriptData::FromUTF8(kScriptData
));
513 scoped_ptr
<ProxyResolverFactory::Request
> request
;
515 ERR_PAC_STATUS_NOT_OK
,
516 callback
.GetResult(proxy_resolver_factory_mojo_
->CreateProxyResolver(
517 pac_script
, &proxy_resolver_mojo_
, callback
.callback(), &request
)));
518 EXPECT_TRUE(request
);
519 on_delete_callback_
.WaitForResult();
521 // A second attempt succeeds.
522 CreateProxyResolver();
525 TEST_F(ProxyResolverMojoTest
, CreateProxyResolver_BothDisconnected
) {
526 mock_proxy_resolver_factory_
->AddCreateProxyResolverAction(
527 CreateProxyResolverAction::DropBoth(kScriptData
));
529 scoped_refptr
<ProxyResolverScriptData
> pac_script(
530 ProxyResolverScriptData::FromUTF8(kScriptData
));
531 scoped_ptr
<ProxyResolverFactory::Request
> request
;
532 TestCompletionCallback callback
;
534 ERR_PAC_SCRIPT_TERMINATED
,
535 callback
.GetResult(proxy_resolver_factory_mojo_
->CreateProxyResolver(
536 pac_script
, &proxy_resolver_mojo_
, callback
.callback(), &request
)));
537 EXPECT_TRUE(request
);
540 TEST_F(ProxyResolverMojoTest
, CreateProxyResolver_ClientDisconnected
) {
541 mock_proxy_resolver_factory_
->AddCreateProxyResolverAction(
542 CreateProxyResolverAction::DropClient(kScriptData
));
544 scoped_refptr
<ProxyResolverScriptData
> pac_script(
545 ProxyResolverScriptData::FromUTF8(kScriptData
));
546 scoped_ptr
<ProxyResolverFactory::Request
> request
;
547 TestCompletionCallback callback
;
549 ERR_PAC_SCRIPT_TERMINATED
,
550 callback
.GetResult(proxy_resolver_factory_mojo_
->CreateProxyResolver(
551 pac_script
, &proxy_resolver_mojo_
, callback
.callback(), &request
)));
552 EXPECT_TRUE(request
);
555 TEST_F(ProxyResolverMojoTest
, CreateProxyResolver_ResolverDisconnected
) {
556 mock_proxy_resolver_factory_
->AddCreateProxyResolverAction(
557 CreateProxyResolverAction::DropResolver(kScriptData
));
559 scoped_refptr
<ProxyResolverScriptData
> pac_script(
560 ProxyResolverScriptData::FromUTF8(kScriptData
));
561 scoped_ptr
<ProxyResolverFactory::Request
> request
;
562 TestCompletionCallback callback
;
564 ERR_PAC_SCRIPT_TERMINATED
,
565 callback
.GetResult(proxy_resolver_factory_mojo_
->CreateProxyResolver(
566 pac_script
, &proxy_resolver_mojo_
, callback
.callback(), &request
)));
567 EXPECT_TRUE(request
);
568 on_delete_callback_
.WaitForResult();
571 TEST_F(ProxyResolverMojoTest
, CreateProxyResolver_Cancel
) {
572 mock_proxy_resolver_factory_
->AddCreateProxyResolverAction(
573 CreateProxyResolverAction::WaitForClientDisconnect(kScriptData
));
575 scoped_refptr
<ProxyResolverScriptData
> pac_script(
576 ProxyResolverScriptData::FromUTF8(kScriptData
));
577 scoped_ptr
<ProxyResolverFactory::Request
> request
;
578 TestCompletionCallback callback
;
579 EXPECT_EQ(ERR_IO_PENDING
, proxy_resolver_factory_mojo_
->CreateProxyResolver(
580 pac_script
, &proxy_resolver_mojo_
,
581 callback
.callback(), &request
));
582 ASSERT_TRUE(request
);
585 // The Mojo request is still made.
586 mock_proxy_resolver_factory_
->WaitForNextRequest();
587 on_delete_callback_
.WaitForResult();
590 TEST_F(ProxyResolverMojoTest
, GetProxyForURL
) {
591 mock_proxy_resolver_
.AddGetProxyAction(GetProxyForUrlAction::ReturnServers(
592 GURL(kExampleUrl
), ProxyServersFromPacString("DIRECT")));
593 CreateProxyResolver();
595 scoped_ptr
<Request
> request(MakeRequest(GURL(kExampleUrl
)));
596 EXPECT_EQ(ERR_IO_PENDING
, request
->Resolve());
597 EXPECT_EQ(OK
, request
->WaitForResult());
599 EXPECT_EQ("DIRECT", request
->results().ToPacString());
602 TEST_F(ProxyResolverMojoTest
, GetProxyForURL_LoadState
) {
603 mock_proxy_resolver_
.AddGetProxyAction(
604 GetProxyForUrlAction::SendLoadStateChanged(GURL(kExampleUrl
)));
605 CreateProxyResolver();
607 scoped_ptr
<Request
> request(MakeRequest(GURL(kExampleUrl
)));
608 EXPECT_EQ(ERR_IO_PENDING
, request
->Resolve());
609 EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL
, request
->load_state());
610 while (request
->load_state() == LOAD_STATE_RESOLVING_PROXY_FOR_URL
)
611 base::RunLoop().RunUntilIdle();
612 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST_IN_PROXY_SCRIPT
, request
->load_state());
613 mock_proxy_resolver_
.ClearBlockedClients();
614 EXPECT_EQ(ERR_PAC_SCRIPT_TERMINATED
, request
->WaitForResult());
617 TEST_F(ProxyResolverMojoTest
, GetProxyForURL_MultipleResults
) {
618 static const char kPacString
[] =
619 "PROXY foo1:80;DIRECT;SOCKS foo2:1234;"
620 "SOCKS5 foo3:1080;HTTPS foo4:443;QUIC foo6:8888";
621 mock_proxy_resolver_
.AddGetProxyAction(GetProxyForUrlAction::ReturnServers(
622 GURL(kExampleUrl
), ProxyServersFromPacString(kPacString
)));
623 CreateProxyResolver();
625 scoped_ptr
<Request
> request(MakeRequest(GURL(kExampleUrl
)));
626 EXPECT_EQ(ERR_IO_PENDING
, request
->Resolve());
627 EXPECT_EQ(OK
, request
->WaitForResult());
629 EXPECT_EQ(kPacString
, request
->results().ToPacString());
632 TEST_F(ProxyResolverMojoTest
, GetProxyForURL_Error
) {
633 mock_proxy_resolver_
.AddGetProxyAction(
634 GetProxyForUrlAction::ReturnError(GURL(kExampleUrl
), ERR_UNEXPECTED
));
635 CreateProxyResolver();
637 scoped_ptr
<Request
> request(MakeRequest(GURL(kExampleUrl
)));
638 EXPECT_EQ(ERR_IO_PENDING
, request
->Resolve());
639 EXPECT_EQ(ERR_UNEXPECTED
, request
->WaitForResult());
641 EXPECT_TRUE(request
->results().is_empty());
644 TEST_F(ProxyResolverMojoTest
, GetProxyForURL_Cancel
) {
645 mock_proxy_resolver_
.AddGetProxyAction(
646 GetProxyForUrlAction::WaitForClientDisconnect(GURL(kExampleUrl
)));
647 CreateProxyResolver();
649 scoped_ptr
<Request
> request(MakeRequest(GURL(kExampleUrl
)));
650 EXPECT_EQ(ERR_IO_PENDING
, request
->Resolve());
653 // The Mojo request is still made.
654 mock_proxy_resolver_
.WaitForNextRequest();
657 TEST_F(ProxyResolverMojoTest
, GetProxyForURL_MultipleRequests
) {
658 mock_proxy_resolver_
.AddGetProxyAction(GetProxyForUrlAction::ReturnServers(
659 GURL(kExampleUrl
), ProxyServersFromPacString("DIRECT")));
660 mock_proxy_resolver_
.AddGetProxyAction(GetProxyForUrlAction::ReturnServers(
661 GURL("https://www.chromium.org"),
662 ProxyServersFromPacString("HTTPS foo:443")));
663 CreateProxyResolver();
665 scoped_ptr
<Request
> request1(MakeRequest(GURL(kExampleUrl
)));
666 EXPECT_EQ(ERR_IO_PENDING
, request1
->Resolve());
667 scoped_ptr
<Request
> request2(MakeRequest(GURL("https://www.chromium.org")));
668 EXPECT_EQ(ERR_IO_PENDING
, request2
->Resolve());
670 EXPECT_EQ(OK
, request1
->WaitForResult());
671 EXPECT_EQ(OK
, request2
->WaitForResult());
673 EXPECT_EQ("DIRECT", request1
->results().ToPacString());
674 EXPECT_EQ("HTTPS foo:443", request2
->results().ToPacString());
677 TEST_F(ProxyResolverMojoTest
, GetProxyForURL_Disconnect
) {
678 mock_proxy_resolver_
.AddGetProxyAction(
679 GetProxyForUrlAction::Disconnect(GURL(kExampleUrl
)));
680 CreateProxyResolver();
682 scoped_ptr
<Request
> request(MakeRequest(GURL(kExampleUrl
)));
683 EXPECT_EQ(ERR_IO_PENDING
, request
->Resolve());
684 EXPECT_EQ(ERR_PAC_SCRIPT_TERMINATED
, request
->WaitForResult());
685 EXPECT_TRUE(request
->results().is_empty());
689 // Calling GetProxyForURL after a disconnect should fail.
690 scoped_ptr
<Request
> request(MakeRequest(GURL(kExampleUrl
)));
691 EXPECT_EQ(ERR_PAC_SCRIPT_TERMINATED
, request
->Resolve());
695 TEST_F(ProxyResolverMojoTest
, GetProxyForURL_ClientClosed
) {
696 mock_proxy_resolver_
.AddGetProxyAction(
697 GetProxyForUrlAction::DropRequest(GURL(kExampleUrl
)));
698 CreateProxyResolver();
700 scoped_ptr
<Request
> request1(MakeRequest(GURL(kExampleUrl
)));
701 EXPECT_EQ(ERR_IO_PENDING
, request1
->Resolve());
703 EXPECT_EQ(ERR_PAC_SCRIPT_TERMINATED
, request1
->WaitForResult());
706 TEST_F(ProxyResolverMojoTest
, GetProxyForURL_DeleteInCallback
) {
707 mock_proxy_resolver_
.AddGetProxyAction(GetProxyForUrlAction::ReturnServers(
708 GURL(kExampleUrl
), ProxyServersFromPacString("DIRECT")));
709 CreateProxyResolver();
712 TestCompletionCallback callback
;
713 ProxyResolver::RequestHandle handle
;
716 callback
.GetResult(proxy_resolver_mojo_
->GetProxyForURL(
717 GURL(kExampleUrl
), &results
,
718 base::Bind(&ProxyResolverMojoTest::DeleteProxyResolverCallback
,
719 base::Unretained(this), callback
.callback()),
721 on_delete_callback_
.WaitForResult();
724 TEST_F(ProxyResolverMojoTest
, GetProxyForURL_DeleteInCallbackFromDisconnect
) {
725 mock_proxy_resolver_
.AddGetProxyAction(
726 GetProxyForUrlAction::Disconnect(GURL(kExampleUrl
)));
727 CreateProxyResolver();
730 TestCompletionCallback callback
;
731 ProxyResolver::RequestHandle handle
;
733 EXPECT_EQ(ERR_PAC_SCRIPT_TERMINATED
,
734 callback
.GetResult(proxy_resolver_mojo_
->GetProxyForURL(
735 GURL(kExampleUrl
), &results
,
736 base::Bind(&ProxyResolverMojoTest::DeleteProxyResolverCallback
,
737 base::Unretained(this), callback
.callback()),
739 on_delete_callback_
.WaitForResult();
742 TEST_F(ProxyResolverMojoTest
, DeleteResolver
) {
743 CreateProxyResolver();
744 proxy_resolver_mojo_
.reset();
745 on_delete_callback_
.WaitForResult();