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_service_mojo.h"
9 #include "base/callback_helpers.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "net/base/load_flags.h"
13 #include "net/base/network_delegate_impl.h"
14 #include "net/base/test_completion_callback.h"
15 #include "net/dns/mock_host_resolver.h"
16 #include "net/log/net_log.h"
17 #include "net/proxy/dhcp_proxy_script_fetcher.h"
18 #include "net/proxy/in_process_mojo_proxy_resolver_factory.h"
19 #include "net/proxy/mock_proxy_script_fetcher.h"
20 #include "net/proxy/mojo_proxy_resolver_factory.h"
21 #include "net/proxy/proxy_config_service_fixed.h"
22 #include "net/proxy/proxy_service.h"
23 #include "net/test/event_waiter.h"
24 #include "testing/gtest/include/gtest/gtest.h"
31 const char kPacUrl
[] = "http://example.com/proxy.pac";
32 const char kSimplePacScript
[] =
33 "function FindProxyForURL(url, host) {\n"
34 " return 'PROXY foo:1234';\n"
36 const char kDnsResolvePacScript
[] =
37 "function FindProxyForURL(url, host) {\n"
38 " if (dnsResolveEx('example.com') != '1.2.3.4')\n"
40 " return 'QUIC bar:4321';\n"
42 const char kErrorPacScript
[] =
43 "function FindProxyForURL(url, host) {\n"
44 " throw new Error('test error');\n"
47 class TestNetworkDelegate
: public NetworkDelegateImpl
{
53 EventWaiter
<Event
>& event_waiter() { return event_waiter_
; }
55 void OnPACScriptError(int line_number
, const base::string16
& error
) override
;
58 EventWaiter
<Event
> event_waiter_
;
61 void TestNetworkDelegate::OnPACScriptError(int line_number
,
62 const base::string16
& error
) {
63 event_waiter_
.NotifyEvent(PAC_SCRIPT_ERROR
);
64 EXPECT_EQ(2, line_number
);
65 EXPECT_TRUE(base::UTF16ToUTF8(error
).find("test error") != std::string::npos
);
70 class ProxyServiceMojoTest
: public testing::Test
,
71 public MojoProxyResolverFactory
{
73 void SetUp() override
{
74 mock_host_resolver_
.rules()->AddRule("example.com", "1.2.3.4");
76 fetcher_
= new MockProxyScriptFetcher
;
77 proxy_service_
.reset(CreateProxyServiceUsingMojoFactory(
78 this, new ProxyConfigServiceFixed(
79 ProxyConfig::CreateFromCustomPacURL(GURL(kPacUrl
))),
80 fetcher_
, new DoNothingDhcpProxyScriptFetcher(), &mock_host_resolver_
,
81 nullptr /* NetLog* */, &network_delegate_
));
84 scoped_ptr
<base::ScopedClosureRunner
> CreateResolver(
85 const mojo::String
& pac_script
,
86 mojo::InterfaceRequest
<interfaces::ProxyResolver
> req
,
87 interfaces::HostResolverPtr host_resolver
,
88 interfaces::ProxyResolverErrorObserverPtr error_observer
,
89 interfaces::ProxyResolverFactoryRequestClientPtr client
) override
{
90 InProcessMojoProxyResolverFactory::GetInstance()->CreateResolver(
91 pac_script
, req
.Pass(), host_resolver
.Pass(), error_observer
.Pass(),
93 return make_scoped_ptr(
94 new base::ScopedClosureRunner(on_delete_closure_
.closure()));
97 TestNetworkDelegate network_delegate_
;
98 MockHostResolver mock_host_resolver_
;
99 MockProxyScriptFetcher
* fetcher_
; // Owned by |proxy_service_|.
100 scoped_ptr
<ProxyService
> proxy_service_
;
101 TestClosure on_delete_closure_
;
104 TEST_F(ProxyServiceMojoTest
, Basic
) {
106 TestCompletionCallback callback
;
107 EXPECT_EQ(ERR_IO_PENDING
,
108 proxy_service_
->ResolveProxy(GURL("http://foo"), LOAD_NORMAL
, &info
,
109 callback
.callback(), nullptr, nullptr,
112 // Proxy script fetcher should have a fetch triggered by the first
113 // |ResolveProxy()| request.
114 EXPECT_TRUE(fetcher_
->has_pending_request());
115 EXPECT_EQ(GURL(kPacUrl
), fetcher_
->pending_request_url());
116 fetcher_
->NotifyFetchCompletion(OK
, kSimplePacScript
);
118 EXPECT_EQ(OK
, callback
.WaitForResult());
119 EXPECT_EQ("PROXY foo:1234", info
.ToPacString());
120 EXPECT_EQ(0u, mock_host_resolver_
.num_resolve());
121 proxy_service_
.reset();
122 on_delete_closure_
.WaitForResult();
125 TEST_F(ProxyServiceMojoTest
, DnsResolution
) {
127 TestCompletionCallback callback
;
128 EXPECT_EQ(ERR_IO_PENDING
,
129 proxy_service_
->ResolveProxy(GURL("http://foo"), LOAD_NORMAL
, &info
,
130 callback
.callback(), nullptr, nullptr,
133 // Proxy script fetcher should have a fetch triggered by the first
134 // |ResolveProxy()| request.
135 EXPECT_TRUE(fetcher_
->has_pending_request());
136 EXPECT_EQ(GURL(kPacUrl
), fetcher_
->pending_request_url());
137 fetcher_
->NotifyFetchCompletion(OK
, kDnsResolvePacScript
);
139 EXPECT_EQ(OK
, callback
.WaitForResult());
140 EXPECT_EQ("QUIC bar:4321", info
.ToPacString());
141 EXPECT_EQ(1u, mock_host_resolver_
.num_resolve());
142 proxy_service_
.reset();
143 on_delete_closure_
.WaitForResult();
146 TEST_F(ProxyServiceMojoTest
, Error
) {
148 TestCompletionCallback callback
;
149 EXPECT_EQ(ERR_IO_PENDING
,
150 proxy_service_
->ResolveProxy(GURL("http://foo"), LOAD_NORMAL
, &info
,
151 callback
.callback(), nullptr, nullptr,
154 // Proxy script fetcher should have a fetch triggered by the first
155 // |ResolveProxy()| request.
156 EXPECT_TRUE(fetcher_
->has_pending_request());
157 EXPECT_EQ(GURL(kPacUrl
), fetcher_
->pending_request_url());
158 fetcher_
->NotifyFetchCompletion(OK
, kErrorPacScript
);
160 network_delegate_
.event_waiter().WaitForEvent(
161 TestNetworkDelegate::PAC_SCRIPT_ERROR
);