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/net_errors.h"
19 #include "net/base/test_completion_callback.h"
20 #include "net/dns/mock_host_resolver.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_script_data.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27 #include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h"
28 #include "third_party/mojo/src/mojo/public/cpp/bindings/error_handler.h"
35 const char kScriptData
[] = "FooBarBaz";
36 const char kScriptData2
[] = "BlahBlahBlah";
37 const char kExampleUrl
[] = "http://www.example.com";
39 struct SetPacScriptAction
{
45 static SetPacScriptAction
ReturnResult(Error error
) {
46 SetPacScriptAction result
;
51 static SetPacScriptAction
Disconnect() {
52 SetPacScriptAction result
;
53 result
.action
= DISCONNECT
;
57 Action action
= COMPLETE
;
61 struct GetProxyForUrlAction
{
64 // Drop the request by closing the reply channel.
66 // Disconnect the service.
68 // Wait for the client pipe to be disconnected.
69 WAIT_FOR_CLIENT_DISCONNECT
,
70 // Send a LoadStateChanged message and keep the client pipe open.
71 SEND_LOAD_STATE_AND_BLOCK
,
74 GetProxyForUrlAction() {}
75 GetProxyForUrlAction(const GetProxyForUrlAction
& old
) {
78 expected_url
= old
.expected_url
;
79 proxy_servers
= old
.proxy_servers
.Clone();
82 static GetProxyForUrlAction
ReturnError(const GURL
& url
, Error error
) {
83 GetProxyForUrlAction result
;
84 result
.expected_url
= url
;
89 static GetProxyForUrlAction
ReturnServers(
91 const mojo::Array
<interfaces::ProxyServerPtr
>& proxy_servers
) {
92 GetProxyForUrlAction result
;
93 result
.expected_url
= url
;
94 result
.proxy_servers
= proxy_servers
.Clone();
98 static GetProxyForUrlAction
DropRequest(const GURL
& url
) {
99 GetProxyForUrlAction result
;
100 result
.expected_url
= url
;
101 result
.action
= DROP
;
105 static GetProxyForUrlAction
Disconnect(const GURL
& url
) {
106 GetProxyForUrlAction result
;
107 result
.expected_url
= url
;
108 result
.action
= DISCONNECT
;
112 static GetProxyForUrlAction
WaitForClientDisconnect(const GURL
& url
) {
113 GetProxyForUrlAction result
;
114 result
.expected_url
= url
;
115 result
.action
= WAIT_FOR_CLIENT_DISCONNECT
;
119 static GetProxyForUrlAction
SendLoadStateChanged(const GURL
& url
) {
120 GetProxyForUrlAction result
;
121 result
.expected_url
= url
;
122 result
.action
= SEND_LOAD_STATE_AND_BLOCK
;
126 Action action
= COMPLETE
;
128 mojo::Array
<interfaces::ProxyServerPtr
> proxy_servers
;
132 class MockMojoProxyResolver
: public interfaces::ProxyResolver
{
134 explicit MockMojoProxyResolver(
135 mojo::InterfaceRequest
<interfaces::ProxyResolver
> req
);
136 ~MockMojoProxyResolver() override
;
138 void AddPacScriptAction(SetPacScriptAction action
);
139 // Returned script data is UTF8.
140 std::string
pac_script_data() { return pac_script_data_
; }
142 void AddGetProxyAction(GetProxyForUrlAction action
);
144 void WaitForNextRequest();
146 void ClearBlockedClients();
149 // Overridden from interfaces::ProxyResolver:
150 void SetPacScript(const mojo::String
& data
,
151 const mojo::Callback
<void(int32_t)>& callback
) override
;
153 const mojo::String
& url
,
154 interfaces::ProxyResolverRequestClientPtr client
) override
;
158 std::string pac_script_data_
;
159 std::queue
<SetPacScriptAction
> pac_script_actions_
;
161 std::queue
<GetProxyForUrlAction
> get_proxy_actions_
;
163 base::Closure quit_closure_
;
165 ScopedVector
<interfaces::ProxyResolverRequestClientPtr
> blocked_clients_
;
166 mojo::Binding
<interfaces::ProxyResolver
> binding_
;
169 MockMojoProxyResolver::MockMojoProxyResolver(
170 mojo::InterfaceRequest
<interfaces::ProxyResolver
> req
)
171 : binding_(this, req
.Pass()) {
174 MockMojoProxyResolver::~MockMojoProxyResolver() {
175 EXPECT_TRUE(pac_script_actions_
.empty())
176 << "Actions remaining: " << pac_script_actions_
.size();
177 EXPECT_TRUE(get_proxy_actions_
.empty())
178 << "Actions remaining: " << get_proxy_actions_
.size();
181 void MockMojoProxyResolver::AddPacScriptAction(SetPacScriptAction action
) {
182 pac_script_actions_
.push(action
);
185 void MockMojoProxyResolver::AddGetProxyAction(GetProxyForUrlAction action
) {
186 get_proxy_actions_
.push(action
);
189 void MockMojoProxyResolver::WaitForNextRequest() {
190 base::RunLoop run_loop
;
191 quit_closure_
= run_loop
.QuitClosure();
195 void MockMojoProxyResolver::WakeWaiter() {
196 if (!quit_closure_
.is_null())
198 quit_closure_
.Reset();
201 void MockMojoProxyResolver::SetPacScript(
202 const mojo::String
& data
,
203 const mojo::Callback
<void(int32_t)>& callback
) {
204 pac_script_data_
= data
.To
<std::string
>();
206 ASSERT_FALSE(pac_script_actions_
.empty());
207 SetPacScriptAction action
= pac_script_actions_
.front();
208 pac_script_actions_
.pop();
210 switch (action
.action
) {
211 case SetPacScriptAction::COMPLETE
:
212 callback
.Run(action
.error
);
214 case SetPacScriptAction::DISCONNECT
:
221 void MockMojoProxyResolver::ClearBlockedClients() {
222 blocked_clients_
.clear();
225 void MockMojoProxyResolver::GetProxyForUrl(
226 const mojo::String
& url
,
227 interfaces::ProxyResolverRequestClientPtr client
) {
228 ASSERT_FALSE(get_proxy_actions_
.empty());
229 GetProxyForUrlAction action
= get_proxy_actions_
.front();
230 get_proxy_actions_
.pop();
232 EXPECT_EQ(action
.expected_url
.spec(), url
.To
<std::string
>());
233 switch (action
.action
) {
234 case GetProxyForUrlAction::COMPLETE
:
235 client
->ReportResult(action
.error
, action
.proxy_servers
.Pass());
237 case GetProxyForUrlAction::DROP
:
240 case GetProxyForUrlAction::DISCONNECT
:
243 case GetProxyForUrlAction::WAIT_FOR_CLIENT_DISCONNECT
:
244 ASSERT_FALSE(client
.WaitForIncomingMethodCall());
246 case GetProxyForUrlAction::SEND_LOAD_STATE_AND_BLOCK
:
247 client
->LoadStateChanged(LOAD_STATE_RESOLVING_HOST_IN_PROXY_SCRIPT
);
248 blocked_clients_
.push_back(
249 new interfaces::ProxyResolverRequestClientPtr(client
.Pass()));
255 class TestMojoProxyResolverFactory
: public MojoProxyResolverFactory
{
257 TestMojoProxyResolverFactory();
258 ~TestMojoProxyResolverFactory() override
;
260 // Overridden from MojoProxyResolverFactory:
261 void Create(mojo::InterfaceRequest
<interfaces::ProxyResolver
> req
,
262 interfaces::HostResolverPtr host_resolver
) override
;
264 MockMojoProxyResolver
& GetMockResolver() { return *mock_proxy_resolver_
; }
266 void AddFuturePacScriptAction(int creation
, SetPacScriptAction action
);
267 void AddFutureGetProxyAction(int creation
, GetProxyForUrlAction action
);
269 int num_create_calls() const { return num_create_calls_
; }
270 void FailNextCreate() { fail_next_create_
= true; }
273 int num_create_calls_
;
274 std::map
<int, std::list
<SetPacScriptAction
>> pac_script_actions_
;
275 std::map
<int, std::list
<GetProxyForUrlAction
>> get_proxy_actions_
;
276 bool fail_next_create_
;
278 scoped_ptr
<MockMojoProxyResolver
> mock_proxy_resolver_
;
281 TestMojoProxyResolverFactory::TestMojoProxyResolverFactory()
282 : num_create_calls_(0), fail_next_create_(false) {
285 TestMojoProxyResolverFactory::~TestMojoProxyResolverFactory() {
288 void TestMojoProxyResolverFactory::Create(
289 mojo::InterfaceRequest
<interfaces::ProxyResolver
> req
,
290 interfaces::HostResolverPtr host_resolver
) {
291 if (fail_next_create_
) {
293 fail_next_create_
= false;
295 mock_proxy_resolver_
.reset(new MockMojoProxyResolver(req
.Pass()));
297 for (const auto& action
: pac_script_actions_
[num_create_calls_
])
298 mock_proxy_resolver_
->AddPacScriptAction(action
);
300 for (const auto& action
: get_proxy_actions_
[num_create_calls_
])
301 mock_proxy_resolver_
->AddGetProxyAction(action
);
306 void TestMojoProxyResolverFactory::AddFuturePacScriptAction(
308 SetPacScriptAction action
) {
309 pac_script_actions_
[creation
].push_back(action
);
312 void TestMojoProxyResolverFactory::AddFutureGetProxyAction(
314 GetProxyForUrlAction action
) {
315 get_proxy_actions_
[creation
].push_back(action
);
320 Request(ProxyResolverMojo
* resolver
, const GURL
& url
);
326 int error() const { return error_
; }
327 const ProxyInfo
& results() const { return results_
; }
328 LoadState
load_state() { return resolver_
->GetLoadState(handle_
); }
331 ProxyResolverMojo
* resolver_
;
334 ProxyResolver::RequestHandle handle_
;
336 TestCompletionCallback callback_
;
339 Request::Request(ProxyResolverMojo
* resolver
, const GURL
& url
)
340 : resolver_(resolver
), url_(url
), error_(0) {
343 int Request::Resolve() {
345 error_
= resolver_
->GetProxyForURL(url_
, &results_
, callback_
.callback(),
350 void Request::Cancel() {
351 resolver_
->CancelRequest(handle_
);
354 int Request::WaitForResult() {
355 error_
= callback_
.WaitForResult();
361 class ProxyResolverMojoTest
: public testing::Test
{
363 void SetUp() override
{
364 proxy_resolver_mojo_
.reset(new ProxyResolverMojo(
365 &mojo_proxy_resolver_factory_
, &mock_host_resolver_
));
368 scoped_ptr
<Request
> MakeRequest(const GURL
& url
) {
369 return make_scoped_ptr(new Request(proxy_resolver_mojo_
.get(), url
));
372 mojo::Array
<interfaces::ProxyServerPtr
> ProxyServersFromPacString(
373 const std::string
& pac_string
) {
374 ProxyInfo proxy_info
;
375 proxy_info
.UsePacString(pac_string
);
377 return mojo::Array
<interfaces::ProxyServerPtr
>::From(
378 proxy_info
.proxy_list().GetAll());
381 void SetPacScript(int instance
) {
382 mojo_proxy_resolver_factory_
.AddFuturePacScriptAction(
383 instance
, SetPacScriptAction::ReturnResult(OK
));
384 TestCompletionCallback callback
;
385 scoped_refptr
<ProxyResolverScriptData
> pac_script(
386 ProxyResolverScriptData::FromUTF8(kScriptData
));
387 EXPECT_EQ(OK
, callback
.GetResult(proxy_resolver_mojo_
->SetPacScript(
388 pac_script
, callback
.callback())));
391 void RunCallbackAndSetPacScript(const net::CompletionCallback
& callback
,
392 const net::CompletionCallback
& pac_callback
,
395 callback
.Run(result
);
396 mojo_proxy_resolver_factory_
.AddFuturePacScriptAction(
397 instance
, SetPacScriptAction::ReturnResult(OK
));
398 scoped_refptr
<ProxyResolverScriptData
> pac_script(
399 ProxyResolverScriptData::FromUTF8(kScriptData
));
400 EXPECT_EQ(ERR_IO_PENDING
,
401 proxy_resolver_mojo_
->SetPacScript(pac_script
, pac_callback
));
404 MockHostResolver mock_host_resolver_
;
405 TestMojoProxyResolverFactory mojo_proxy_resolver_factory_
;
406 scoped_ptr
<ProxyResolverMojo
> proxy_resolver_mojo_
;
409 TEST_F(ProxyResolverMojoTest
, SetPacScript
) {
411 EXPECT_EQ(kScriptData
,
412 mojo_proxy_resolver_factory_
.GetMockResolver().pac_script_data());
415 TEST_F(ProxyResolverMojoTest
, SetPacScript_Empty
) {
416 TestCompletionCallback callback
;
417 scoped_refptr
<ProxyResolverScriptData
> pac_script(
418 ProxyResolverScriptData::FromUTF8(""));
419 EXPECT_EQ(ERR_PAC_SCRIPT_FAILED
,
420 callback
.GetResult(proxy_resolver_mojo_
->SetPacScript(
421 pac_script
, callback
.callback())));
424 TEST_F(ProxyResolverMojoTest
, SetPacScript_Url
) {
425 TestCompletionCallback callback
;
426 scoped_refptr
<ProxyResolverScriptData
> pac_script(
427 ProxyResolverScriptData::FromURL(GURL(kExampleUrl
)));
428 EXPECT_EQ(ERR_PAC_SCRIPT_FAILED
,
429 callback
.GetResult(proxy_resolver_mojo_
->SetPacScript(
430 pac_script
, callback
.callback())));
433 TEST_F(ProxyResolverMojoTest
, SetPacScript_Failed
) {
434 mojo_proxy_resolver_factory_
.AddFuturePacScriptAction(
435 0, SetPacScriptAction::ReturnResult(ERR_PAC_STATUS_NOT_OK
));
437 TestCompletionCallback callback
;
438 scoped_refptr
<ProxyResolverScriptData
> pac_script(
439 ProxyResolverScriptData::FromUTF8(kScriptData
));
440 EXPECT_EQ(ERR_PAC_STATUS_NOT_OK
,
441 callback
.GetResult(proxy_resolver_mojo_
->SetPacScript(
442 pac_script
, callback
.callback())));
445 TEST_F(ProxyResolverMojoTest
, SetPacScript_Disconnected
) {
446 mojo_proxy_resolver_factory_
.AddFuturePacScriptAction(
447 0, SetPacScriptAction::Disconnect());
449 scoped_refptr
<ProxyResolverScriptData
> pac_script(
450 ProxyResolverScriptData::FromUTF8(kScriptData
));
451 TestCompletionCallback callback
;
452 EXPECT_EQ(ERR_IO_PENDING
, proxy_resolver_mojo_
->SetPacScript(
453 pac_script
, callback
.callback()));
454 EXPECT_EQ(ERR_PAC_SCRIPT_TERMINATED
, callback
.GetResult(ERR_IO_PENDING
));
457 TEST_F(ProxyResolverMojoTest
, SetPacScript_SuccessThenDisconnect
) {
458 mojo_proxy_resolver_factory_
.AddFuturePacScriptAction(
459 0, SetPacScriptAction::ReturnResult(OK
));
460 mojo_proxy_resolver_factory_
.AddFuturePacScriptAction(
461 0, SetPacScriptAction::Disconnect());
462 mojo_proxy_resolver_factory_
.AddFuturePacScriptAction(
463 1, SetPacScriptAction::ReturnResult(ERR_FAILED
));
465 scoped_refptr
<ProxyResolverScriptData
> pac_script(
466 ProxyResolverScriptData::FromUTF8(kScriptData
));
467 TestCompletionCallback callback
;
468 EXPECT_EQ(OK
, callback
.GetResult(proxy_resolver_mojo_
->SetPacScript(
469 pac_script
, callback
.callback())));
470 EXPECT_EQ(kScriptData
,
471 mojo_proxy_resolver_factory_
.GetMockResolver().pac_script_data());
475 scoped_refptr
<ProxyResolverScriptData
> pac_script(
476 ProxyResolverScriptData::FromUTF8(kScriptData2
));
477 TestCompletionCallback callback
;
478 EXPECT_EQ(ERR_IO_PENDING
, proxy_resolver_mojo_
->SetPacScript(
479 pac_script
, callback
.callback()));
480 EXPECT_EQ(ERR_PAC_SCRIPT_TERMINATED
, callback
.GetResult(ERR_IO_PENDING
));
484 scoped_refptr
<ProxyResolverScriptData
> pac_script(
485 ProxyResolverScriptData::FromUTF8(kScriptData2
));
486 TestCompletionCallback callback
;
487 EXPECT_EQ(ERR_IO_PENDING
, proxy_resolver_mojo_
->SetPacScript(
488 pac_script
, callback
.callback()));
489 EXPECT_EQ(ERR_FAILED
, callback
.GetResult(ERR_IO_PENDING
));
492 // The service should have been recreated on the last SetPacScript call.
493 EXPECT_EQ(2, mojo_proxy_resolver_factory_
.num_create_calls());
496 TEST_F(ProxyResolverMojoTest
, SetPacScript_Cancel
) {
497 mojo_proxy_resolver_factory_
.AddFuturePacScriptAction(
498 0, SetPacScriptAction::ReturnResult(OK
));
500 scoped_refptr
<ProxyResolverScriptData
> pac_script(
501 ProxyResolverScriptData::FromUTF8(kScriptData
));
502 TestCompletionCallback callback
;
503 EXPECT_EQ(ERR_IO_PENDING
, proxy_resolver_mojo_
->SetPacScript(
504 pac_script
, callback
.callback()));
505 proxy_resolver_mojo_
->CancelSetPacScript();
507 // The Mojo request is still made.
508 mojo_proxy_resolver_factory_
.GetMockResolver().WaitForNextRequest();
511 TEST_F(ProxyResolverMojoTest
, SetPacScript_CancelAndSetAgain
) {
512 mojo_proxy_resolver_factory_
.AddFuturePacScriptAction(
513 0, SetPacScriptAction::ReturnResult(ERR_FAILED
));
514 mojo_proxy_resolver_factory_
.AddFuturePacScriptAction(
515 0, SetPacScriptAction::ReturnResult(ERR_UNEXPECTED
));
517 scoped_refptr
<ProxyResolverScriptData
> pac_script(
518 ProxyResolverScriptData::FromUTF8(kScriptData
));
519 TestCompletionCallback callback1
;
520 EXPECT_EQ(ERR_IO_PENDING
, proxy_resolver_mojo_
->SetPacScript(
521 pac_script
, callback1
.callback()));
522 proxy_resolver_mojo_
->CancelSetPacScript();
524 TestCompletionCallback callback2
;
525 EXPECT_EQ(ERR_IO_PENDING
, proxy_resolver_mojo_
->SetPacScript(
526 pac_script
, callback2
.callback()));
527 EXPECT_EQ(ERR_UNEXPECTED
, callback2
.GetResult(ERR_IO_PENDING
));
530 TEST_F(ProxyResolverMojoTest
, GetProxyForURL
) {
531 mojo_proxy_resolver_factory_
.AddFutureGetProxyAction(
532 0, GetProxyForUrlAction::ReturnServers(
533 GURL(kExampleUrl
), ProxyServersFromPacString("DIRECT")));
536 scoped_ptr
<Request
> request(MakeRequest(GURL(kExampleUrl
)));
537 EXPECT_EQ(ERR_IO_PENDING
, request
->Resolve());
538 EXPECT_EQ(OK
, request
->WaitForResult());
540 EXPECT_EQ("DIRECT", request
->results().ToPacString());
543 TEST_F(ProxyResolverMojoTest
, GetProxyForURL_WithoutSetPacScript
) {
544 scoped_ptr
<Request
> request(MakeRequest(GURL(kExampleUrl
)));
545 EXPECT_EQ(ERR_PAC_SCRIPT_TERMINATED
, request
->Resolve());
548 TEST_F(ProxyResolverMojoTest
, GetProxyForURL_LoadState
) {
549 mojo_proxy_resolver_factory_
.AddFutureGetProxyAction(
550 0, GetProxyForUrlAction::SendLoadStateChanged(GURL(kExampleUrl
)));
553 scoped_ptr
<Request
> request(MakeRequest(GURL(kExampleUrl
)));
554 EXPECT_EQ(ERR_IO_PENDING
, request
->Resolve());
555 EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL
, request
->load_state());
556 while (request
->load_state() == LOAD_STATE_RESOLVING_PROXY_FOR_URL
)
557 base::RunLoop().RunUntilIdle();
558 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST_IN_PROXY_SCRIPT
, request
->load_state());
559 mojo_proxy_resolver_factory_
.GetMockResolver().ClearBlockedClients();
560 EXPECT_EQ(ERR_PAC_SCRIPT_TERMINATED
, request
->WaitForResult());
563 TEST_F(ProxyResolverMojoTest
, GetProxyForURL_MultipleResults
) {
564 static const char kPacString
[] =
565 "PROXY foo1:80;DIRECT;SOCKS foo2:1234;"
566 "SOCKS5 foo3:1080;HTTPS foo4:443;QUIC foo6:8888";
567 mojo_proxy_resolver_factory_
.AddFutureGetProxyAction(
568 0, GetProxyForUrlAction::ReturnServers(
569 GURL(kExampleUrl
), ProxyServersFromPacString(kPacString
)));
572 scoped_ptr
<Request
> request(MakeRequest(GURL(kExampleUrl
)));
573 EXPECT_EQ(ERR_IO_PENDING
, request
->Resolve());
574 EXPECT_EQ(OK
, request
->WaitForResult());
576 EXPECT_EQ(kPacString
, request
->results().ToPacString());
579 TEST_F(ProxyResolverMojoTest
, GetProxyForURL_Error
) {
580 mojo_proxy_resolver_factory_
.AddFutureGetProxyAction(
581 0, GetProxyForUrlAction::ReturnError(GURL(kExampleUrl
), ERR_UNEXPECTED
));
584 scoped_ptr
<Request
> request(MakeRequest(GURL(kExampleUrl
)));
585 EXPECT_EQ(ERR_IO_PENDING
, request
->Resolve());
586 EXPECT_EQ(ERR_UNEXPECTED
, request
->WaitForResult());
588 EXPECT_TRUE(request
->results().is_empty());
591 TEST_F(ProxyResolverMojoTest
, GetProxyForURL_Cancel
) {
592 mojo_proxy_resolver_factory_
.AddFutureGetProxyAction(
593 0, GetProxyForUrlAction::WaitForClientDisconnect(GURL(kExampleUrl
)));
596 scoped_ptr
<Request
> request(MakeRequest(GURL(kExampleUrl
)));
597 EXPECT_EQ(ERR_IO_PENDING
, request
->Resolve());
600 // The Mojo request is still made.
601 mojo_proxy_resolver_factory_
.GetMockResolver().WaitForNextRequest();
604 TEST_F(ProxyResolverMojoTest
, GetProxyForURL_MultipleRequests
) {
605 mojo_proxy_resolver_factory_
.AddFutureGetProxyAction(
606 0, GetProxyForUrlAction::ReturnServers(
607 GURL(kExampleUrl
), ProxyServersFromPacString("DIRECT")));
608 mojo_proxy_resolver_factory_
.AddFutureGetProxyAction(
609 0, GetProxyForUrlAction::ReturnServers(
610 GURL("https://www.chromium.org"),
611 ProxyServersFromPacString("HTTPS foo:443")));
614 scoped_ptr
<Request
> request1(MakeRequest(GURL(kExampleUrl
)));
615 EXPECT_EQ(ERR_IO_PENDING
, request1
->Resolve());
616 scoped_ptr
<Request
> request2(MakeRequest(GURL("https://www.chromium.org")));
617 EXPECT_EQ(ERR_IO_PENDING
, request2
->Resolve());
619 EXPECT_EQ(OK
, request1
->WaitForResult());
620 EXPECT_EQ(OK
, request2
->WaitForResult());
622 EXPECT_EQ("DIRECT", request1
->results().ToPacString());
623 EXPECT_EQ("HTTPS foo:443", request2
->results().ToPacString());
626 TEST_F(ProxyResolverMojoTest
, GetProxyForURL_Disconnect
) {
627 mojo_proxy_resolver_factory_
.AddFutureGetProxyAction(
628 0, GetProxyForUrlAction::Disconnect(GURL(kExampleUrl
)));
629 mojo_proxy_resolver_factory_
.AddFutureGetProxyAction(
630 1, GetProxyForUrlAction::ReturnServers(
631 GURL(kExampleUrl
), ProxyServersFromPacString("DIRECT")));
634 scoped_ptr
<Request
> request(MakeRequest(GURL(kExampleUrl
)));
635 EXPECT_EQ(ERR_IO_PENDING
, request
->Resolve());
636 EXPECT_EQ(ERR_PAC_SCRIPT_TERMINATED
, request
->WaitForResult());
637 EXPECT_TRUE(request
->results().is_empty());
641 // Calling GetProxyForURL without first setting the pac script should fail.
642 scoped_ptr
<Request
> request(MakeRequest(GURL(kExampleUrl
)));
643 EXPECT_EQ(ERR_PAC_SCRIPT_TERMINATED
, request
->Resolve());
648 scoped_ptr
<Request
> request(MakeRequest(GURL(kExampleUrl
)));
649 EXPECT_EQ(ERR_IO_PENDING
, request
->Resolve());
650 EXPECT_EQ(OK
, request
->WaitForResult());
651 EXPECT_EQ("DIRECT", request
->results().ToPacString());
654 EXPECT_EQ(2, mojo_proxy_resolver_factory_
.num_create_calls());
657 TEST_F(ProxyResolverMojoTest
, GetProxyForURL_ClientClosed
) {
658 mojo_proxy_resolver_factory_
.AddFutureGetProxyAction(
659 0, GetProxyForUrlAction::DropRequest(GURL(kExampleUrl
)));
662 scoped_ptr
<Request
> request1(MakeRequest(GURL(kExampleUrl
)));
663 EXPECT_EQ(ERR_IO_PENDING
, request1
->Resolve());
665 EXPECT_EQ(ERR_PAC_SCRIPT_TERMINATED
, request1
->WaitForResult());
666 EXPECT_EQ(1, mojo_proxy_resolver_factory_
.num_create_calls());
669 TEST_F(ProxyResolverMojoTest
, DisconnectAndFailCreate
) {
670 mojo_proxy_resolver_factory_
.AddFutureGetProxyAction(
671 0, GetProxyForUrlAction::Disconnect(GURL(kExampleUrl
)));
675 scoped_ptr
<Request
> request(MakeRequest(GURL(kExampleUrl
)));
676 EXPECT_EQ(ERR_IO_PENDING
, request
->Resolve());
677 EXPECT_EQ(ERR_PAC_SCRIPT_TERMINATED
, request
->WaitForResult());
678 EXPECT_TRUE(request
->results().is_empty());
681 // The service should attempt to create a new connection, but that should
684 scoped_refptr
<ProxyResolverScriptData
> pac_script(
685 ProxyResolverScriptData::FromUTF8(kScriptData
));
686 TestCompletionCallback callback
;
687 mojo_proxy_resolver_factory_
.FailNextCreate();
688 EXPECT_EQ(ERR_PAC_SCRIPT_TERMINATED
,
689 callback
.GetResult(proxy_resolver_mojo_
->SetPacScript(
690 pac_script
, callback
.callback())));
693 // A third attempt should succeed.
696 EXPECT_EQ(3, mojo_proxy_resolver_factory_
.num_create_calls());
699 TEST_F(ProxyResolverMojoTest
, DisconnectAndReconnectInCallback
) {
700 mojo_proxy_resolver_factory_
.AddFutureGetProxyAction(
701 0, GetProxyForUrlAction::Disconnect(GURL(kExampleUrl
)));
702 mojo_proxy_resolver_factory_
.AddFutureGetProxyAction(
703 1, GetProxyForUrlAction::ReturnServers(
704 GURL(kExampleUrl
), ProxyServersFromPacString("DIRECT")));
706 // In this first resolve request, the Mojo service is disconnected causing the
707 // request to return ERR_PAC_SCRIPT_TERMINATED. In the request callback, form
708 // a new connection to a Mojo resolver service by calling SetPacScript().
711 TestCompletionCallback resolve_callback
;
712 TestCompletionCallback pac_callback
;
713 ProxyResolver::RequestHandle handle
;
715 int error
= proxy_resolver_mojo_
->GetProxyForURL(
716 GURL(kExampleUrl
), &results
,
717 base::Bind(&ProxyResolverMojoTest::RunCallbackAndSetPacScript
,
718 base::Unretained(this), resolve_callback
.callback(),
719 pac_callback
.callback(), 1),
721 EXPECT_EQ(ERR_IO_PENDING
, error
);
722 EXPECT_EQ(ERR_PAC_SCRIPT_TERMINATED
, resolve_callback
.WaitForResult());
723 EXPECT_EQ(OK
, pac_callback
.WaitForResult());
725 // Setting the PAC script above should have been successful and let us send a
727 scoped_ptr
<Request
> request(MakeRequest(GURL(kExampleUrl
)));
728 EXPECT_EQ(ERR_IO_PENDING
, request
->Resolve());
729 EXPECT_EQ(OK
, request
->WaitForResult());
730 EXPECT_EQ("DIRECT", request
->results().ToPacString());
732 EXPECT_EQ(2, mojo_proxy_resolver_factory_
.num_create_calls());