Evict resources from resource pool after timeout
[chromium-blink-merge.git] / net / proxy / proxy_resolver_factory_mojo_unittest.cc
blobd0fd4ec1e5910e4560e00b7d65a5f5311f8ac1e8
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_factory_mojo.h"
7 #include <list>
8 #include <map>
9 #include <queue>
10 #include <string>
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 "base/values.h"
18 #include "mojo/common/common_type_converters.h"
19 #include "net/base/load_states.h"
20 #include "net/base/net_errors.h"
21 #include "net/base/test_completion_callback.h"
22 #include "net/dns/host_resolver.h"
23 #include "net/log/test_net_log.h"
24 #include "net/proxy/mojo_proxy_resolver_factory.h"
25 #include "net/proxy/mojo_proxy_type_converters.h"
26 #include "net/proxy/proxy_info.h"
27 #include "net/proxy/proxy_resolver.h"
28 #include "net/proxy/proxy_resolver_error_observer.h"
29 #include "net/proxy/proxy_resolver_script_data.h"
30 #include "net/test/event_waiter.h"
31 #include "testing/gtest/include/gtest/gtest.h"
32 #include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h"
33 #include "url/gurl.h"
35 namespace net {
37 namespace {
39 const char kScriptData[] = "FooBarBaz";
40 const char kExampleUrl[] = "http://www.example.com";
42 struct CreateProxyResolverAction {
43 enum Action {
44 COMPLETE,
45 DROP_CLIENT,
46 DROP_RESOLVER,
47 DROP_BOTH,
48 WAIT_FOR_CLIENT_DISCONNECT,
49 MAKE_DNS_REQUEST,
52 static CreateProxyResolverAction ReturnResult(
53 const std::string& expected_pac_script,
54 Error error) {
55 CreateProxyResolverAction result;
56 result.expected_pac_script = expected_pac_script;
57 result.error = error;
58 return result;
61 static CreateProxyResolverAction DropClient(
62 const std::string& expected_pac_script) {
63 CreateProxyResolverAction result;
64 result.expected_pac_script = expected_pac_script;
65 result.action = DROP_CLIENT;
66 return result;
69 static CreateProxyResolverAction DropResolver(
70 const std::string& expected_pac_script) {
71 CreateProxyResolverAction result;
72 result.expected_pac_script = expected_pac_script;
73 result.action = DROP_RESOLVER;
74 return result;
77 static CreateProxyResolverAction DropBoth(
78 const std::string& expected_pac_script) {
79 CreateProxyResolverAction result;
80 result.expected_pac_script = expected_pac_script;
81 result.action = DROP_BOTH;
82 return result;
85 static CreateProxyResolverAction WaitForClientDisconnect(
86 const std::string& expected_pac_script) {
87 CreateProxyResolverAction result;
88 result.expected_pac_script = expected_pac_script;
89 result.action = WAIT_FOR_CLIENT_DISCONNECT;
90 return result;
93 static CreateProxyResolverAction MakeDnsRequest(
94 const std::string& expected_pac_script) {
95 CreateProxyResolverAction result;
96 result.expected_pac_script = expected_pac_script;
97 result.action = MAKE_DNS_REQUEST;
98 return result;
101 std::string expected_pac_script;
102 Action action = COMPLETE;
103 Error error = OK;
106 struct GetProxyForUrlAction {
107 enum Action {
108 COMPLETE,
109 // Drop the request by closing the reply channel.
110 DROP,
111 // Disconnect the service.
112 DISCONNECT,
113 // Wait for the client pipe to be disconnected.
114 WAIT_FOR_CLIENT_DISCONNECT,
115 // Make a DNS request.
116 MAKE_DNS_REQUEST,
119 GetProxyForUrlAction() {}
120 GetProxyForUrlAction(const GetProxyForUrlAction& old) {
121 action = old.action;
122 error = old.error;
123 expected_url = old.expected_url;
124 proxy_servers = old.proxy_servers.Clone();
127 static GetProxyForUrlAction ReturnError(const GURL& url, Error error) {
128 GetProxyForUrlAction result;
129 result.expected_url = url;
130 result.error = error;
131 return result;
134 static GetProxyForUrlAction ReturnServers(
135 const GURL& url,
136 const mojo::Array<interfaces::ProxyServerPtr>& proxy_servers) {
137 GetProxyForUrlAction result;
138 result.expected_url = url;
139 result.proxy_servers = proxy_servers.Clone();
140 return result;
143 static GetProxyForUrlAction DropRequest(const GURL& url) {
144 GetProxyForUrlAction result;
145 result.expected_url = url;
146 result.action = DROP;
147 return result;
150 static GetProxyForUrlAction Disconnect(const GURL& url) {
151 GetProxyForUrlAction result;
152 result.expected_url = url;
153 result.action = DISCONNECT;
154 return result;
157 static GetProxyForUrlAction WaitForClientDisconnect(const GURL& url) {
158 GetProxyForUrlAction result;
159 result.expected_url = url;
160 result.action = WAIT_FOR_CLIENT_DISCONNECT;
161 return result;
164 static GetProxyForUrlAction MakeDnsRequest(const GURL& url) {
165 GetProxyForUrlAction result;
166 result.expected_url = url;
167 result.action = MAKE_DNS_REQUEST;
168 return result;
171 Action action = COMPLETE;
172 Error error = OK;
173 mojo::Array<interfaces::ProxyServerPtr> proxy_servers;
174 GURL expected_url;
177 class MockMojoProxyResolver : public interfaces::ProxyResolver {
178 public:
179 MockMojoProxyResolver();
180 ~MockMojoProxyResolver() override;
182 void AddGetProxyAction(GetProxyForUrlAction action);
184 void WaitForNextRequest();
186 void ClearBlockedClients();
188 void AddConnection(mojo::InterfaceRequest<interfaces::ProxyResolver> req);
190 private:
191 // Overridden from interfaces::ProxyResolver:
192 void GetProxyForUrl(
193 const mojo::String& url,
194 interfaces::ProxyResolverRequestClientPtr client) override;
196 void WakeWaiter();
198 std::string pac_script_data_;
200 std::queue<GetProxyForUrlAction> get_proxy_actions_;
202 base::Closure quit_closure_;
204 ScopedVector<interfaces::ProxyResolverRequestClientPtr> blocked_clients_;
205 mojo::Binding<interfaces::ProxyResolver> binding_;
208 MockMojoProxyResolver::~MockMojoProxyResolver() {
209 EXPECT_TRUE(get_proxy_actions_.empty())
210 << "Actions remaining: " << get_proxy_actions_.size();
213 MockMojoProxyResolver::MockMojoProxyResolver() : binding_(this) {
216 void MockMojoProxyResolver::AddGetProxyAction(GetProxyForUrlAction action) {
217 get_proxy_actions_.push(action);
220 void MockMojoProxyResolver::WaitForNextRequest() {
221 base::RunLoop run_loop;
222 quit_closure_ = run_loop.QuitClosure();
223 run_loop.Run();
226 void MockMojoProxyResolver::WakeWaiter() {
227 if (!quit_closure_.is_null())
228 quit_closure_.Run();
229 quit_closure_.Reset();
232 void MockMojoProxyResolver::ClearBlockedClients() {
233 blocked_clients_.clear();
236 void MockMojoProxyResolver::AddConnection(
237 mojo::InterfaceRequest<interfaces::ProxyResolver> req) {
238 if (binding_.is_bound())
239 binding_.Close();
240 binding_.Bind(req.Pass());
243 void MockMojoProxyResolver::GetProxyForUrl(
244 const mojo::String& url,
245 interfaces::ProxyResolverRequestClientPtr client) {
246 ASSERT_FALSE(get_proxy_actions_.empty());
247 GetProxyForUrlAction action = get_proxy_actions_.front();
248 get_proxy_actions_.pop();
250 EXPECT_EQ(action.expected_url.spec(), url.To<std::string>());
251 client->Alert(url);
252 client->OnError(12345, url);
253 switch (action.action) {
254 case GetProxyForUrlAction::COMPLETE: {
255 client->ReportResult(action.error, action.proxy_servers.Pass());
256 break;
258 case GetProxyForUrlAction::DROP: {
259 client.reset();
260 break;
262 case GetProxyForUrlAction::DISCONNECT: {
263 binding_.Close();
264 break;
266 case GetProxyForUrlAction::WAIT_FOR_CLIENT_DISCONNECT: {
267 ASSERT_FALSE(client.WaitForIncomingResponse());
268 break;
270 case GetProxyForUrlAction::MAKE_DNS_REQUEST: {
271 interfaces::HostResolverRequestInfoPtr request(
272 interfaces::HostResolverRequestInfo::New());
273 request->host = url;
274 request->port = 12345;
275 interfaces::HostResolverRequestClientPtr dns_client;
276 mojo::GetProxy(&dns_client);
277 client->ResolveDns(request.Pass(), dns_client.Pass());
278 blocked_clients_.push_back(
279 new interfaces::ProxyResolverRequestClientPtr(client.Pass()));
280 break;
283 WakeWaiter();
286 class Request {
287 public:
288 Request(ProxyResolver* resolver, const GURL& url);
290 int Resolve();
291 void Cancel();
292 int WaitForResult();
294 int error() const { return error_; }
295 const ProxyInfo& results() const { return results_; }
296 LoadState load_state() { return resolver_->GetLoadState(handle_); }
297 BoundTestNetLog& net_log() { return net_log_; }
299 private:
300 ProxyResolver* resolver_;
301 const GURL url_;
302 ProxyInfo results_;
303 ProxyResolver::RequestHandle handle_;
304 int error_;
305 TestCompletionCallback callback_;
306 BoundTestNetLog net_log_;
309 Request::Request(ProxyResolver* resolver, const GURL& url)
310 : resolver_(resolver), url_(url), error_(0) {
313 int Request::Resolve() {
314 error_ = resolver_->GetProxyForURL(url_, &results_, callback_.callback(),
315 &handle_, net_log_.bound());
316 return error_;
319 void Request::Cancel() {
320 resolver_->CancelRequest(handle_);
323 int Request::WaitForResult() {
324 error_ = callback_.WaitForResult();
325 return error_;
328 class MockMojoProxyResolverFactory : public interfaces::ProxyResolverFactory {
329 public:
330 MockMojoProxyResolverFactory(
331 MockMojoProxyResolver* resolver,
332 mojo::InterfaceRequest<interfaces::ProxyResolverFactory> req);
333 ~MockMojoProxyResolverFactory() override;
335 void AddCreateProxyResolverAction(CreateProxyResolverAction action);
337 void WaitForNextRequest();
339 void ClearBlockedClients();
341 private:
342 // Overridden from interfaces::ProxyResolver:
343 void CreateResolver(
344 const mojo::String& pac_url,
345 mojo::InterfaceRequest<interfaces::ProxyResolver> request,
346 interfaces::ProxyResolverFactoryRequestClientPtr client) override;
348 void WakeWaiter();
350 MockMojoProxyResolver* resolver_;
351 std::queue<CreateProxyResolverAction> create_resolver_actions_;
353 base::Closure quit_closure_;
355 ScopedVector<interfaces::ProxyResolverFactoryRequestClientPtr>
356 blocked_clients_;
357 ScopedVector<mojo::InterfaceRequest<interfaces::ProxyResolver>>
358 blocked_resolver_requests_;
359 mojo::Binding<interfaces::ProxyResolverFactory> binding_;
362 MockMojoProxyResolverFactory::MockMojoProxyResolverFactory(
363 MockMojoProxyResolver* resolver,
364 mojo::InterfaceRequest<interfaces::ProxyResolverFactory> req)
365 : resolver_(resolver), binding_(this, req.Pass()) {
368 MockMojoProxyResolverFactory::~MockMojoProxyResolverFactory() {
369 EXPECT_TRUE(create_resolver_actions_.empty())
370 << "Actions remaining: " << create_resolver_actions_.size();
373 void MockMojoProxyResolverFactory::AddCreateProxyResolverAction(
374 CreateProxyResolverAction action) {
375 create_resolver_actions_.push(action);
378 void MockMojoProxyResolverFactory::WaitForNextRequest() {
379 base::RunLoop run_loop;
380 quit_closure_ = run_loop.QuitClosure();
381 run_loop.Run();
384 void MockMojoProxyResolverFactory::WakeWaiter() {
385 if (!quit_closure_.is_null())
386 quit_closure_.Run();
387 quit_closure_.Reset();
390 void MockMojoProxyResolverFactory::ClearBlockedClients() {
391 blocked_clients_.clear();
394 void MockMojoProxyResolverFactory::CreateResolver(
395 const mojo::String& pac_script,
396 mojo::InterfaceRequest<interfaces::ProxyResolver> request,
397 interfaces::ProxyResolverFactoryRequestClientPtr client) {
398 ASSERT_FALSE(create_resolver_actions_.empty());
399 CreateProxyResolverAction action = create_resolver_actions_.front();
400 create_resolver_actions_.pop();
402 EXPECT_EQ(action.expected_pac_script, pac_script.To<std::string>());
403 client->Alert(pac_script);
404 client->OnError(12345, pac_script);
405 switch (action.action) {
406 case CreateProxyResolverAction::COMPLETE: {
407 if (action.error == OK)
408 resolver_->AddConnection(request.Pass());
409 client->ReportResult(action.error);
410 break;
412 case CreateProxyResolverAction::DROP_CLIENT: {
413 // Save |request| so its pipe isn't closed.
414 blocked_resolver_requests_.push_back(
415 new mojo::InterfaceRequest<interfaces::ProxyResolver>(
416 request.Pass()));
417 break;
419 case CreateProxyResolverAction::DROP_RESOLVER: {
420 // Save |client| so its pipe isn't closed.
421 blocked_clients_.push_back(
422 new interfaces::ProxyResolverFactoryRequestClientPtr(client.Pass()));
423 break;
425 case CreateProxyResolverAction::DROP_BOTH: {
426 // Both |request| and |client| will be closed.
427 break;
429 case CreateProxyResolverAction::WAIT_FOR_CLIENT_DISCONNECT: {
430 ASSERT_FALSE(client.WaitForIncomingResponse());
431 break;
433 case CreateProxyResolverAction::MAKE_DNS_REQUEST: {
434 interfaces::HostResolverRequestInfoPtr request(
435 interfaces::HostResolverRequestInfo::New());
436 request->host = pac_script;
437 request->port = 12345;
438 interfaces::HostResolverRequestClientPtr dns_client;
439 mojo::GetProxy(&dns_client);
440 client->ResolveDns(request.Pass(), dns_client.Pass());
441 blocked_clients_.push_back(
442 new interfaces::ProxyResolverFactoryRequestClientPtr(client.Pass()));
443 break;
446 WakeWaiter();
449 void DeleteResolverFactoryRequestCallback(
450 scoped_ptr<ProxyResolverFactory::Request>* request,
451 const CompletionCallback& callback,
452 int result) {
453 ASSERT_TRUE(request);
454 EXPECT_TRUE(request->get());
455 request->reset();
456 callback.Run(result);
459 class MockHostResolver : public HostResolver {
460 public:
461 enum Event {
462 DNS_REQUEST,
465 // HostResolver overrides.
466 int Resolve(const RequestInfo& info,
467 RequestPriority priority,
468 AddressList* addresses,
469 const CompletionCallback& callback,
470 RequestHandle* request_handle,
471 const BoundNetLog& source_net_log) override {
472 waiter_.NotifyEvent(DNS_REQUEST);
473 return ERR_IO_PENDING;
475 int ResolveFromCache(const RequestInfo& info,
476 AddressList* addresses,
477 const BoundNetLog& source_net_log) override {
478 return ERR_DNS_CACHE_MISS;
480 void CancelRequest(RequestHandle req) override {}
481 HostCache* GetHostCache() override { return nullptr; }
483 EventWaiter<Event>& waiter() { return waiter_; }
485 private:
486 EventWaiter<Event> waiter_;
489 void CheckCapturedNetLogEntries(const std::string& expected_string,
490 const TestNetLogEntry::List& entries) {
491 ASSERT_EQ(2u, entries.size());
492 EXPECT_EQ(NetLog::TYPE_PAC_JAVASCRIPT_ALERT, entries[0].type);
493 std::string message;
494 ASSERT_TRUE(entries[0].GetStringValue("message", &message));
495 EXPECT_EQ(expected_string, message);
496 ASSERT_FALSE(entries[0].params->HasKey("line_number"));
497 message.clear();
498 EXPECT_EQ(NetLog::TYPE_PAC_JAVASCRIPT_ERROR, entries[1].type);
499 ASSERT_TRUE(entries[1].GetStringValue("message", &message));
500 EXPECT_EQ(expected_string, message);
501 int line_number = 0;
502 ASSERT_TRUE(entries[1].GetIntegerValue("line_number", &line_number));
503 EXPECT_EQ(12345, line_number);
506 } // namespace
508 class ProxyResolverFactoryMojoTest : public testing::Test,
509 public MojoProxyResolverFactory {
510 public:
511 void SetUp() override {
512 mock_proxy_resolver_factory_.reset(new MockMojoProxyResolverFactory(
513 &mock_proxy_resolver_, mojo::GetProxy(&factory_ptr_)));
514 proxy_resolver_factory_mojo_.reset(new ProxyResolverFactoryMojo(
515 this, &host_resolver_,
516 base::Callback<scoped_ptr<ProxyResolverErrorObserver>()>(), &net_log_));
519 scoped_ptr<Request> MakeRequest(const GURL& url) {
520 return make_scoped_ptr(new Request(proxy_resolver_mojo_.get(), url));
523 scoped_ptr<base::ScopedClosureRunner> CreateResolver(
524 const mojo::String& pac_script,
525 mojo::InterfaceRequest<interfaces::ProxyResolver> req,
526 interfaces::ProxyResolverFactoryRequestClientPtr client) override {
527 factory_ptr_->CreateResolver(pac_script, req.Pass(), client.Pass());
528 return make_scoped_ptr(
529 new base::ScopedClosureRunner(on_delete_callback_.closure()));
532 mojo::Array<interfaces::ProxyServerPtr> ProxyServersFromPacString(
533 const std::string& pac_string) {
534 ProxyInfo proxy_info;
535 proxy_info.UsePacString(pac_string);
537 return mojo::Array<interfaces::ProxyServerPtr>::From(
538 proxy_info.proxy_list().GetAll());
541 void CreateProxyResolver() {
542 mock_proxy_resolver_factory_->AddCreateProxyResolverAction(
543 CreateProxyResolverAction::ReturnResult(kScriptData, OK));
544 TestCompletionCallback callback;
545 scoped_refptr<ProxyResolverScriptData> pac_script(
546 ProxyResolverScriptData::FromUTF8(kScriptData));
547 scoped_ptr<ProxyResolverFactory::Request> request;
548 ASSERT_EQ(
550 callback.GetResult(proxy_resolver_factory_mojo_->CreateProxyResolver(
551 pac_script, &proxy_resolver_mojo_, callback.callback(), &request)));
552 EXPECT_TRUE(request);
553 ASSERT_TRUE(proxy_resolver_mojo_);
556 void DeleteProxyResolverCallback(const CompletionCallback& callback,
557 int result) {
558 proxy_resolver_mojo_.reset();
559 callback.Run(result);
562 MockHostResolver host_resolver_;
563 TestNetLog net_log_;
564 scoped_ptr<MockMojoProxyResolverFactory> mock_proxy_resolver_factory_;
565 interfaces::ProxyResolverFactoryPtr factory_ptr_;
566 scoped_ptr<ProxyResolverFactory> proxy_resolver_factory_mojo_;
568 MockMojoProxyResolver mock_proxy_resolver_;
569 scoped_ptr<ProxyResolver> proxy_resolver_mojo_;
570 TestClosure on_delete_callback_;
573 TEST_F(ProxyResolverFactoryMojoTest, CreateProxyResolver) {
574 CreateProxyResolver();
575 TestNetLogEntry::List entries;
576 net_log_.GetEntries(&entries);
577 CheckCapturedNetLogEntries(kScriptData, entries);
580 TEST_F(ProxyResolverFactoryMojoTest, CreateProxyResolver_Empty) {
581 TestCompletionCallback callback;
582 scoped_refptr<ProxyResolverScriptData> pac_script(
583 ProxyResolverScriptData::FromUTF8(""));
584 scoped_ptr<ProxyResolverFactory::Request> request;
585 EXPECT_EQ(
586 ERR_PAC_SCRIPT_FAILED,
587 callback.GetResult(proxy_resolver_factory_mojo_->CreateProxyResolver(
588 pac_script, &proxy_resolver_mojo_, callback.callback(), &request)));
589 EXPECT_FALSE(request);
592 TEST_F(ProxyResolverFactoryMojoTest, CreateProxyResolver_Url) {
593 TestCompletionCallback callback;
594 scoped_refptr<ProxyResolverScriptData> pac_script(
595 ProxyResolverScriptData::FromURL(GURL(kExampleUrl)));
596 scoped_ptr<ProxyResolverFactory::Request> request;
597 EXPECT_EQ(
598 ERR_PAC_SCRIPT_FAILED,
599 callback.GetResult(proxy_resolver_factory_mojo_->CreateProxyResolver(
600 pac_script, &proxy_resolver_mojo_, callback.callback(), &request)));
601 EXPECT_FALSE(request);
604 TEST_F(ProxyResolverFactoryMojoTest, CreateProxyResolver_Failed) {
605 mock_proxy_resolver_factory_->AddCreateProxyResolverAction(
606 CreateProxyResolverAction::ReturnResult(kScriptData,
607 ERR_PAC_STATUS_NOT_OK));
609 TestCompletionCallback callback;
610 scoped_refptr<ProxyResolverScriptData> pac_script(
611 ProxyResolverScriptData::FromUTF8(kScriptData));
612 scoped_ptr<ProxyResolverFactory::Request> request;
613 EXPECT_EQ(
614 ERR_PAC_STATUS_NOT_OK,
615 callback.GetResult(proxy_resolver_factory_mojo_->CreateProxyResolver(
616 pac_script, &proxy_resolver_mojo_, callback.callback(), &request)));
617 EXPECT_TRUE(request);
618 on_delete_callback_.WaitForResult();
620 // A second attempt succeeds.
621 CreateProxyResolver();
624 TEST_F(ProxyResolverFactoryMojoTest, CreateProxyResolver_BothDisconnected) {
625 mock_proxy_resolver_factory_->AddCreateProxyResolverAction(
626 CreateProxyResolverAction::DropBoth(kScriptData));
628 scoped_refptr<ProxyResolverScriptData> pac_script(
629 ProxyResolverScriptData::FromUTF8(kScriptData));
630 scoped_ptr<ProxyResolverFactory::Request> request;
631 TestCompletionCallback callback;
632 EXPECT_EQ(
633 ERR_PAC_SCRIPT_TERMINATED,
634 callback.GetResult(proxy_resolver_factory_mojo_->CreateProxyResolver(
635 pac_script, &proxy_resolver_mojo_, callback.callback(), &request)));
636 EXPECT_TRUE(request);
639 TEST_F(ProxyResolverFactoryMojoTest, CreateProxyResolver_ClientDisconnected) {
640 mock_proxy_resolver_factory_->AddCreateProxyResolverAction(
641 CreateProxyResolverAction::DropClient(kScriptData));
643 scoped_refptr<ProxyResolverScriptData> pac_script(
644 ProxyResolverScriptData::FromUTF8(kScriptData));
645 scoped_ptr<ProxyResolverFactory::Request> request;
646 TestCompletionCallback callback;
647 EXPECT_EQ(
648 ERR_PAC_SCRIPT_TERMINATED,
649 callback.GetResult(proxy_resolver_factory_mojo_->CreateProxyResolver(
650 pac_script, &proxy_resolver_mojo_, callback.callback(), &request)));
651 EXPECT_TRUE(request);
654 TEST_F(ProxyResolverFactoryMojoTest, CreateProxyResolver_ResolverDisconnected) {
655 mock_proxy_resolver_factory_->AddCreateProxyResolverAction(
656 CreateProxyResolverAction::DropResolver(kScriptData));
658 scoped_refptr<ProxyResolverScriptData> pac_script(
659 ProxyResolverScriptData::FromUTF8(kScriptData));
660 scoped_ptr<ProxyResolverFactory::Request> request;
661 TestCompletionCallback callback;
662 EXPECT_EQ(
663 ERR_PAC_SCRIPT_TERMINATED,
664 callback.GetResult(proxy_resolver_factory_mojo_->CreateProxyResolver(
665 pac_script, &proxy_resolver_mojo_, callback.callback(), &request)));
666 EXPECT_TRUE(request);
667 on_delete_callback_.WaitForResult();
670 TEST_F(ProxyResolverFactoryMojoTest,
671 CreateProxyResolver_ResolverDisconnected_DeleteRequestInCallback) {
672 mock_proxy_resolver_factory_->AddCreateProxyResolverAction(
673 CreateProxyResolverAction::DropResolver(kScriptData));
675 scoped_refptr<ProxyResolverScriptData> pac_script(
676 ProxyResolverScriptData::FromUTF8(kScriptData));
677 scoped_ptr<ProxyResolverFactory::Request> request;
678 TestCompletionCallback callback;
679 EXPECT_EQ(
680 ERR_PAC_SCRIPT_TERMINATED,
681 callback.GetResult(proxy_resolver_factory_mojo_->CreateProxyResolver(
682 pac_script, &proxy_resolver_mojo_,
683 base::Bind(&DeleteResolverFactoryRequestCallback, &request,
684 callback.callback()),
685 &request)));
686 on_delete_callback_.WaitForResult();
689 TEST_F(ProxyResolverFactoryMojoTest, CreateProxyResolver_Cancel) {
690 mock_proxy_resolver_factory_->AddCreateProxyResolverAction(
691 CreateProxyResolverAction::WaitForClientDisconnect(kScriptData));
693 scoped_refptr<ProxyResolverScriptData> pac_script(
694 ProxyResolverScriptData::FromUTF8(kScriptData));
695 scoped_ptr<ProxyResolverFactory::Request> request;
696 TestCompletionCallback callback;
697 EXPECT_EQ(ERR_IO_PENDING, proxy_resolver_factory_mojo_->CreateProxyResolver(
698 pac_script, &proxy_resolver_mojo_,
699 callback.callback(), &request));
700 ASSERT_TRUE(request);
701 request.reset();
703 // The Mojo request is still made.
704 mock_proxy_resolver_factory_->WaitForNextRequest();
705 on_delete_callback_.WaitForResult();
708 TEST_F(ProxyResolverFactoryMojoTest, CreateProxyResolver_DnsRequest) {
709 mock_proxy_resolver_factory_->AddCreateProxyResolverAction(
710 CreateProxyResolverAction::MakeDnsRequest(kScriptData));
712 scoped_refptr<ProxyResolverScriptData> pac_script(
713 ProxyResolverScriptData::FromUTF8(kScriptData));
714 scoped_ptr<ProxyResolverFactory::Request> request;
715 TestCompletionCallback callback;
716 EXPECT_EQ(ERR_IO_PENDING, proxy_resolver_factory_mojo_->CreateProxyResolver(
717 pac_script, &proxy_resolver_mojo_,
718 callback.callback(), &request));
719 ASSERT_TRUE(request);
720 host_resolver_.waiter().WaitForEvent(MockHostResolver::DNS_REQUEST);
721 mock_proxy_resolver_factory_->ClearBlockedClients();
722 callback.WaitForResult();
725 TEST_F(ProxyResolverFactoryMojoTest, GetProxyForURL) {
726 const GURL url(kExampleUrl);
727 mock_proxy_resolver_.AddGetProxyAction(GetProxyForUrlAction::ReturnServers(
728 url, ProxyServersFromPacString("DIRECT")));
729 CreateProxyResolver();
730 net_log_.Clear();
732 scoped_ptr<Request> request(MakeRequest(GURL(kExampleUrl)));
733 EXPECT_EQ(ERR_IO_PENDING, request->Resolve());
734 EXPECT_EQ(OK, request->WaitForResult());
736 EXPECT_EQ("DIRECT", request->results().ToPacString());
738 TestNetLogEntry::List entries;
739 net_log_.GetEntries(&entries);
740 CheckCapturedNetLogEntries(url.spec(), entries);
741 entries.clear();
742 request->net_log().GetEntries(&entries);
743 CheckCapturedNetLogEntries(url.spec(), entries);
746 TEST_F(ProxyResolverFactoryMojoTest, GetProxyForURL_MultipleResults) {
747 static const char kPacString[] =
748 "PROXY foo1:80;DIRECT;SOCKS foo2:1234;"
749 "SOCKS5 foo3:1080;HTTPS foo4:443;QUIC foo6:8888";
750 mock_proxy_resolver_.AddGetProxyAction(GetProxyForUrlAction::ReturnServers(
751 GURL(kExampleUrl), ProxyServersFromPacString(kPacString)));
752 CreateProxyResolver();
754 scoped_ptr<Request> request(MakeRequest(GURL(kExampleUrl)));
755 EXPECT_EQ(ERR_IO_PENDING, request->Resolve());
756 EXPECT_EQ(OK, request->WaitForResult());
758 EXPECT_EQ(kPacString, request->results().ToPacString());
761 TEST_F(ProxyResolverFactoryMojoTest, GetProxyForURL_Error) {
762 mock_proxy_resolver_.AddGetProxyAction(
763 GetProxyForUrlAction::ReturnError(GURL(kExampleUrl), ERR_UNEXPECTED));
764 CreateProxyResolver();
766 scoped_ptr<Request> request(MakeRequest(GURL(kExampleUrl)));
767 EXPECT_EQ(ERR_IO_PENDING, request->Resolve());
768 EXPECT_EQ(ERR_UNEXPECTED, request->WaitForResult());
770 EXPECT_TRUE(request->results().is_empty());
773 TEST_F(ProxyResolverFactoryMojoTest, GetProxyForURL_Cancel) {
774 mock_proxy_resolver_.AddGetProxyAction(
775 GetProxyForUrlAction::WaitForClientDisconnect(GURL(kExampleUrl)));
776 CreateProxyResolver();
778 scoped_ptr<Request> request(MakeRequest(GURL(kExampleUrl)));
779 EXPECT_EQ(ERR_IO_PENDING, request->Resolve());
780 request->Cancel();
782 // The Mojo request is still made.
783 mock_proxy_resolver_.WaitForNextRequest();
786 TEST_F(ProxyResolverFactoryMojoTest, GetProxyForURL_MultipleRequests) {
787 mock_proxy_resolver_.AddGetProxyAction(GetProxyForUrlAction::ReturnServers(
788 GURL(kExampleUrl), ProxyServersFromPacString("DIRECT")));
789 mock_proxy_resolver_.AddGetProxyAction(GetProxyForUrlAction::ReturnServers(
790 GURL("https://www.chromium.org"),
791 ProxyServersFromPacString("HTTPS foo:443")));
792 CreateProxyResolver();
794 scoped_ptr<Request> request1(MakeRequest(GURL(kExampleUrl)));
795 EXPECT_EQ(ERR_IO_PENDING, request1->Resolve());
796 scoped_ptr<Request> request2(MakeRequest(GURL("https://www.chromium.org")));
797 EXPECT_EQ(ERR_IO_PENDING, request2->Resolve());
799 EXPECT_EQ(OK, request1->WaitForResult());
800 EXPECT_EQ(OK, request2->WaitForResult());
802 EXPECT_EQ("DIRECT", request1->results().ToPacString());
803 EXPECT_EQ("HTTPS foo:443", request2->results().ToPacString());
806 TEST_F(ProxyResolverFactoryMojoTest, GetProxyForURL_Disconnect) {
807 mock_proxy_resolver_.AddGetProxyAction(
808 GetProxyForUrlAction::Disconnect(GURL(kExampleUrl)));
809 CreateProxyResolver();
811 scoped_ptr<Request> request(MakeRequest(GURL(kExampleUrl)));
812 EXPECT_EQ(ERR_IO_PENDING, request->Resolve());
813 EXPECT_EQ(ERR_PAC_SCRIPT_TERMINATED, request->WaitForResult());
814 EXPECT_TRUE(request->results().is_empty());
818 // Calling GetProxyForURL after a disconnect should fail.
819 scoped_ptr<Request> request(MakeRequest(GURL(kExampleUrl)));
820 EXPECT_EQ(ERR_PAC_SCRIPT_TERMINATED, request->Resolve());
824 TEST_F(ProxyResolverFactoryMojoTest, GetProxyForURL_ClientClosed) {
825 mock_proxy_resolver_.AddGetProxyAction(
826 GetProxyForUrlAction::DropRequest(GURL(kExampleUrl)));
827 CreateProxyResolver();
829 scoped_ptr<Request> request1(MakeRequest(GURL(kExampleUrl)));
830 EXPECT_EQ(ERR_IO_PENDING, request1->Resolve());
832 EXPECT_EQ(ERR_PAC_SCRIPT_TERMINATED, request1->WaitForResult());
835 TEST_F(ProxyResolverFactoryMojoTest, GetProxyForURL_DeleteInCallback) {
836 mock_proxy_resolver_.AddGetProxyAction(GetProxyForUrlAction::ReturnServers(
837 GURL(kExampleUrl), ProxyServersFromPacString("DIRECT")));
838 CreateProxyResolver();
840 ProxyInfo results;
841 TestCompletionCallback callback;
842 ProxyResolver::RequestHandle handle;
843 BoundNetLog net_log;
844 EXPECT_EQ(
846 callback.GetResult(proxy_resolver_mojo_->GetProxyForURL(
847 GURL(kExampleUrl), &results,
848 base::Bind(&ProxyResolverFactoryMojoTest::DeleteProxyResolverCallback,
849 base::Unretained(this), callback.callback()),
850 &handle, net_log)));
851 on_delete_callback_.WaitForResult();
854 TEST_F(ProxyResolverFactoryMojoTest,
855 GetProxyForURL_DeleteInCallbackFromDisconnect) {
856 mock_proxy_resolver_.AddGetProxyAction(
857 GetProxyForUrlAction::Disconnect(GURL(kExampleUrl)));
858 CreateProxyResolver();
860 ProxyInfo results;
861 TestCompletionCallback callback;
862 ProxyResolver::RequestHandle handle;
863 BoundNetLog net_log;
864 EXPECT_EQ(
865 ERR_PAC_SCRIPT_TERMINATED,
866 callback.GetResult(proxy_resolver_mojo_->GetProxyForURL(
867 GURL(kExampleUrl), &results,
868 base::Bind(&ProxyResolverFactoryMojoTest::DeleteProxyResolverCallback,
869 base::Unretained(this), callback.callback()),
870 &handle, net_log)));
871 on_delete_callback_.WaitForResult();
874 TEST_F(ProxyResolverFactoryMojoTest, GetProxyForURL_DnsRequest) {
875 mock_proxy_resolver_.AddGetProxyAction(
876 GetProxyForUrlAction::MakeDnsRequest(GURL(kExampleUrl)));
877 CreateProxyResolver();
879 scoped_ptr<Request> request(MakeRequest(GURL(kExampleUrl)));
880 EXPECT_EQ(ERR_IO_PENDING, request->Resolve());
881 EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, request->load_state());
883 host_resolver_.waiter().WaitForEvent(MockHostResolver::DNS_REQUEST);
884 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST_IN_PROXY_SCRIPT, request->load_state());
885 mock_proxy_resolver_.ClearBlockedClients();
886 request->WaitForResult();
889 TEST_F(ProxyResolverFactoryMojoTest, DeleteResolver) {
890 CreateProxyResolver();
891 proxy_resolver_mojo_.reset();
892 on_delete_callback_.WaitForResult();
894 } // namespace net