Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / net / proxy / proxy_service_mojo_unittest.cc
blob171f89be8c42f10555272e153014c0d7001d0b38
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"
7 #include <algorithm>
8 #include <string>
10 #include "base/callback_helpers.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/values.h"
14 #include "net/base/load_flags.h"
15 #include "net/base/network_delegate_impl.h"
16 #include "net/base/test_completion_callback.h"
17 #include "net/dns/mock_host_resolver.h"
18 #include "net/log/net_log.h"
19 #include "net/log/test_net_log.h"
20 #include "net/log/test_net_log_entry.h"
21 #include "net/proxy/dhcp_proxy_script_fetcher.h"
22 #include "net/proxy/in_process_mojo_proxy_resolver_factory.h"
23 #include "net/proxy/mock_proxy_script_fetcher.h"
24 #include "net/proxy/mojo_proxy_resolver_factory.h"
25 #include "net/proxy/proxy_config_service_fixed.h"
26 #include "net/proxy/proxy_service.h"
27 #include "net/test/event_waiter.h"
28 #include "testing/gmock/include/gmock/gmock.h"
29 #include "testing/gtest/include/gtest/gtest.h"
30 #include "url/gurl.h"
32 namespace net {
34 namespace {
36 const char kPacUrl[] = "http://example.com/proxy.pac";
37 const char kSimplePacScript[] =
38 "function FindProxyForURL(url, host) {\n"
39 " return 'PROXY foo:1234';\n"
40 "}";
41 const char kDnsResolvePacScript[] =
42 "function FindProxyForURL(url, host) {\n"
43 " if (dnsResolveEx('example.com') != '1.2.3.4')\n"
44 " return 'DIRECT';\n"
45 " return 'QUIC bar:4321';\n"
46 "}";
47 const char kThrowingPacScript[] =
48 "function FindProxyForURL(url, host) {\n"
49 " alert('alert: ' + host);\n"
50 " throw new Error('error: ' + url);\n"
51 "}";
52 const char kThrowingOnLoadPacScript[] =
53 "function FindProxyForURL(url, host) {}\n"
54 "alert('alert: foo');\n"
55 "throw new Error('error: http://foo');";
57 class TestNetworkDelegate : public NetworkDelegateImpl {
58 public:
59 enum Event {
60 PAC_SCRIPT_ERROR,
63 EventWaiter<Event>& event_waiter() { return event_waiter_; }
65 void OnPACScriptError(int line_number, const base::string16& error) override;
67 private:
68 EventWaiter<Event> event_waiter_;
71 void TestNetworkDelegate::OnPACScriptError(int line_number,
72 const base::string16& error) {
73 event_waiter_.NotifyEvent(PAC_SCRIPT_ERROR);
74 EXPECT_EQ(3, line_number);
75 EXPECT_TRUE(base::UTF16ToUTF8(error).find("error: http://foo") !=
76 std::string::npos);
79 void CheckCapturedNetLogEntries(const TestNetLogEntry::List& entries) {
80 ASSERT_GT(entries.size(), 2u);
81 size_t i = 0;
82 // ProxyService records its own NetLog entries, so skip forward until the
83 // expected event type.
84 while (i < entries.size() &&
85 entries[i].type != NetLog::TYPE_PAC_JAVASCRIPT_ALERT) {
86 i++;
88 ASSERT_LT(i, entries.size());
89 std::string message;
90 ASSERT_TRUE(entries[i].GetStringValue("message", &message));
91 EXPECT_EQ("alert: foo", message);
92 ASSERT_FALSE(entries[i].params->HasKey("line_number"));
94 while (i < entries.size() &&
95 entries[i].type != NetLog::TYPE_PAC_JAVASCRIPT_ERROR) {
96 i++;
98 message.clear();
99 ASSERT_TRUE(entries[i].GetStringValue("message", &message));
100 EXPECT_THAT(message, testing::HasSubstr("error: http://foo"));
101 int line_number = 0;
102 ASSERT_TRUE(entries[i].GetIntegerValue("line_number", &line_number));
103 EXPECT_EQ(3, line_number);
106 class LoggingMockHostResolver : public MockHostResolver {
107 public:
108 int Resolve(const RequestInfo& info,
109 RequestPriority priority,
110 AddressList* addresses,
111 const CompletionCallback& callback,
112 RequestHandle* out_req,
113 const BoundNetLog& net_log) override {
114 net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB);
115 return MockHostResolver::Resolve(info, priority, addresses, callback,
116 out_req, net_log);
120 } // namespace
122 class ProxyServiceMojoTest : public testing::Test,
123 public MojoProxyResolverFactory {
124 protected:
125 void SetUp() override {
126 mock_host_resolver_.rules()->AddRule("example.com", "1.2.3.4");
128 fetcher_ = new MockProxyScriptFetcher;
129 proxy_service_.reset(CreateProxyServiceUsingMojoFactory(
130 this, new ProxyConfigServiceFixed(
131 ProxyConfig::CreateFromCustomPacURL(GURL(kPacUrl))),
132 fetcher_, new DoNothingDhcpProxyScriptFetcher(), &mock_host_resolver_,
133 &net_log_, &network_delegate_));
136 scoped_ptr<base::ScopedClosureRunner> CreateResolver(
137 const mojo::String& pac_script,
138 mojo::InterfaceRequest<interfaces::ProxyResolver> req,
139 interfaces::ProxyResolverFactoryRequestClientPtr client) override {
140 InProcessMojoProxyResolverFactory::GetInstance()->CreateResolver(
141 pac_script, req.Pass(), client.Pass());
142 return make_scoped_ptr(
143 new base::ScopedClosureRunner(on_delete_closure_.closure()));
146 TestNetworkDelegate network_delegate_;
147 LoggingMockHostResolver mock_host_resolver_;
148 MockProxyScriptFetcher* fetcher_; // Owned by |proxy_service_|.
149 TestNetLog net_log_;
150 scoped_ptr<ProxyService> proxy_service_;
151 TestClosure on_delete_closure_;
154 TEST_F(ProxyServiceMojoTest, Basic) {
155 ProxyInfo info;
156 TestCompletionCallback callback;
157 EXPECT_EQ(ERR_IO_PENDING,
158 proxy_service_->ResolveProxy(GURL("http://foo"), LOAD_NORMAL, &info,
159 callback.callback(), nullptr, nullptr,
160 BoundNetLog()));
162 // Proxy script fetcher should have a fetch triggered by the first
163 // |ResolveProxy()| request.
164 EXPECT_TRUE(fetcher_->has_pending_request());
165 EXPECT_EQ(GURL(kPacUrl), fetcher_->pending_request_url());
166 fetcher_->NotifyFetchCompletion(OK, kSimplePacScript);
168 EXPECT_EQ(OK, callback.WaitForResult());
169 EXPECT_EQ("PROXY foo:1234", info.ToPacString());
170 EXPECT_EQ(0u, mock_host_resolver_.num_resolve());
171 proxy_service_.reset();
172 on_delete_closure_.WaitForResult();
175 TEST_F(ProxyServiceMojoTest, DnsResolution) {
176 ProxyInfo info;
177 TestCompletionCallback callback;
178 BoundTestNetLog bound_net_log;
179 EXPECT_EQ(ERR_IO_PENDING,
180 proxy_service_->ResolveProxy(GURL("http://foo"), LOAD_NORMAL, &info,
181 callback.callback(), nullptr, nullptr,
182 bound_net_log.bound()));
184 // Proxy script fetcher should have a fetch triggered by the first
185 // |ResolveProxy()| request.
186 EXPECT_TRUE(fetcher_->has_pending_request());
187 EXPECT_EQ(GURL(kPacUrl), fetcher_->pending_request_url());
188 fetcher_->NotifyFetchCompletion(OK, kDnsResolvePacScript);
190 EXPECT_EQ(OK, callback.WaitForResult());
191 EXPECT_EQ("QUIC bar:4321", info.ToPacString());
192 EXPECT_EQ(1u, mock_host_resolver_.num_resolve());
193 proxy_service_.reset();
194 on_delete_closure_.WaitForResult();
196 TestNetLogEntry::List entries;
197 bound_net_log.GetEntries(&entries);
198 // There should be one entry with type TYPE_HOST_RESOLVER_IMPL_JOB.
199 EXPECT_EQ(1, std::count_if(entries.begin(), entries.end(),
200 [](const TestNetLogEntry& entry) {
201 return entry.type ==
202 NetLog::TYPE_HOST_RESOLVER_IMPL_JOB;
203 }));
206 TEST_F(ProxyServiceMojoTest, Error) {
207 ProxyInfo info;
208 TestCompletionCallback callback;
209 BoundTestNetLog bound_net_log;
210 EXPECT_EQ(ERR_IO_PENDING,
211 proxy_service_->ResolveProxy(GURL("http://foo"), LOAD_NORMAL, &info,
212 callback.callback(), nullptr, nullptr,
213 bound_net_log.bound()));
215 // Proxy script fetcher should have a fetch triggered by the first
216 // |ResolveProxy()| request.
217 EXPECT_TRUE(fetcher_->has_pending_request());
218 EXPECT_EQ(GURL(kPacUrl), fetcher_->pending_request_url());
219 fetcher_->NotifyFetchCompletion(OK, kThrowingPacScript);
221 network_delegate_.event_waiter().WaitForEvent(
222 TestNetworkDelegate::PAC_SCRIPT_ERROR);
224 EXPECT_EQ(OK, callback.WaitForResult());
225 EXPECT_EQ("DIRECT", info.ToPacString());
226 EXPECT_EQ(0u, mock_host_resolver_.num_resolve());
228 TestNetLogEntry::List entries;
229 bound_net_log.GetEntries(&entries);
230 CheckCapturedNetLogEntries(entries);
231 entries.clear();
232 net_log_.GetEntries(&entries);
233 CheckCapturedNetLogEntries(entries);
236 TEST_F(ProxyServiceMojoTest, ErrorOnInitialization) {
237 ProxyInfo info;
238 TestCompletionCallback callback;
239 EXPECT_EQ(ERR_IO_PENDING,
240 proxy_service_->ResolveProxy(GURL("http://foo"), LOAD_NORMAL, &info,
241 callback.callback(), nullptr, nullptr,
242 BoundNetLog()));
244 // Proxy script fetcher should have a fetch triggered by the first
245 // |ResolveProxy()| request.
246 EXPECT_TRUE(fetcher_->has_pending_request());
247 EXPECT_EQ(GURL(kPacUrl), fetcher_->pending_request_url());
248 fetcher_->NotifyFetchCompletion(OK, kThrowingOnLoadPacScript);
250 network_delegate_.event_waiter().WaitForEvent(
251 TestNetworkDelegate::PAC_SCRIPT_ERROR);
253 EXPECT_EQ(OK, callback.WaitForResult());
254 EXPECT_EQ("DIRECT", info.ToPacString());
255 EXPECT_EQ(0u, mock_host_resolver_.num_resolve());
257 TestNetLogEntry::List entries;
258 net_log_.GetEntries(&entries);
259 CheckCapturedNetLogEntries(entries);
262 } // namespace net