1 // Copyright (c) 2012 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 "base/compiler_specific.h"
6 #include "base/file_util.h"
7 #include "base/path_service.h"
8 #include "base/string_util.h"
9 #include "base/stringprintf.h"
10 #include "base/utf_string_conversions.h"
11 #include "googleurl/src/gurl.h"
12 #include "net/base/net_errors.h"
13 #include "net/base/net_log_unittest.h"
14 #include "net/proxy/proxy_info.h"
15 #include "net/proxy/proxy_resolver_js_bindings.h"
16 #include "net/proxy/proxy_resolver_v8.h"
17 #include "testing/gtest/include/gtest/gtest.h"
22 // Javascript bindings for ProxyResolverV8, which returns mock values.
23 // Each time one of the bindings is called into, we push the input into a
24 // list, for later verification.
25 class MockJSBindings
: public ProxyResolverJSBindings
{
27 MockJSBindings() : my_ip_address_count(0), my_ip_address_ex_count(0) {}
29 virtual void Alert(const string16
& message
) OVERRIDE
{
30 VLOG(1) << "PAC-alert: " << message
; // Helpful when debugging.
31 alerts
.push_back(UTF16ToUTF8(message
));
34 virtual bool MyIpAddress(std::string
* ip_address
) OVERRIDE
{
35 my_ip_address_count
++;
36 *ip_address
= my_ip_address_result
;
37 return !my_ip_address_result
.empty();
40 virtual bool MyIpAddressEx(std::string
* ip_address_list
) OVERRIDE
{
41 my_ip_address_ex_count
++;
42 *ip_address_list
= my_ip_address_ex_result
;
43 return !my_ip_address_ex_result
.empty();
46 virtual bool DnsResolve(const std::string
& host
, std::string
* ip_address
)
48 dns_resolves
.push_back(host
);
49 *ip_address
= dns_resolve_result
;
50 return !dns_resolve_result
.empty();
53 virtual bool DnsResolveEx(const std::string
& host
,
54 std::string
* ip_address_list
) OVERRIDE
{
55 dns_resolves_ex
.push_back(host
);
56 *ip_address_list
= dns_resolve_ex_result
;
57 return !dns_resolve_ex_result
.empty();
60 virtual void OnError(int line_number
, const string16
& message
) OVERRIDE
{
61 // Helpful when debugging.
62 VLOG(1) << "PAC-error: [" << line_number
<< "] " << message
;
64 errors
.push_back(UTF16ToUTF8(message
));
65 errors_line_number
.push_back(line_number
);
68 virtual void Shutdown() OVERRIDE
{}
70 // Mock values to return.
71 std::string my_ip_address_result
;
72 std::string my_ip_address_ex_result
;
73 std::string dns_resolve_result
;
74 std::string dns_resolve_ex_result
;
76 // Inputs we got called with.
77 std::vector
<std::string
> alerts
;
78 std::vector
<std::string
> errors
;
79 std::vector
<int> errors_line_number
;
80 std::vector
<std::string
> dns_resolves
;
81 std::vector
<std::string
> dns_resolves_ex
;
82 int my_ip_address_count
;
83 int my_ip_address_ex_count
;
86 // This is the same as ProxyResolverV8, but it uses mock bindings in place of
87 // the default bindings, and has a helper function to load PAC scripts from
89 class ProxyResolverV8WithMockBindings
: public ProxyResolverV8
{
91 ProxyResolverV8WithMockBindings() : ProxyResolverV8(new MockJSBindings()) {}
93 MockJSBindings
* mock_js_bindings() const {
94 return reinterpret_cast<MockJSBindings
*>(js_bindings());
97 // Initialize with the PAC script data at |filename|.
98 int SetPacScriptFromDisk(const char* filename
) {
100 PathService::Get(base::DIR_SOURCE_ROOT
, &path
);
101 path
= path
.AppendASCII("net");
102 path
= path
.AppendASCII("data");
103 path
= path
.AppendASCII("proxy_resolver_v8_unittest");
104 path
= path
.AppendASCII(filename
);
106 // Try to read the file from disk.
107 std::string file_contents
;
108 bool ok
= file_util::ReadFileToString(path
, &file_contents
);
110 // If we can't load the file from disk, something is misconfigured.
112 LOG(ERROR
) << "Failed to read file: " << path
.value();
113 return ERR_UNEXPECTED
;
116 // Load the PAC script into the ProxyResolver.
117 return SetPacScript(ProxyResolverScriptData::FromUTF8(file_contents
),
118 CompletionCallback());
122 // Doesn't really matter what these values are for many of the tests.
123 const GURL
kQueryUrl("http://www.google.com");
127 TEST(ProxyResolverV8Test
, Direct
) {
128 ProxyResolverV8WithMockBindings resolver
;
129 int result
= resolver
.SetPacScriptFromDisk("direct.js");
130 EXPECT_EQ(OK
, result
);
132 ProxyInfo proxy_info
;
133 CapturingBoundNetLog log
;
134 result
= resolver
.GetProxyForURL(
135 kQueryUrl
, &proxy_info
, CompletionCallback(), NULL
, log
.bound());
137 EXPECT_EQ(OK
, result
);
138 EXPECT_TRUE(proxy_info
.is_direct());
140 EXPECT_EQ(0U, resolver
.mock_js_bindings()->alerts
.size());
141 EXPECT_EQ(0U, resolver
.mock_js_bindings()->errors
.size());
143 net::CapturingNetLog::CapturedEntryList entries
;
144 log
.GetEntries(&entries
);
145 // No bindings were called, so no log entries.
146 EXPECT_EQ(0u, entries
.size());
149 TEST(ProxyResolverV8Test
, ReturnEmptyString
) {
150 ProxyResolverV8WithMockBindings resolver
;
151 int result
= resolver
.SetPacScriptFromDisk("return_empty_string.js");
152 EXPECT_EQ(OK
, result
);
154 ProxyInfo proxy_info
;
155 result
= resolver
.GetProxyForURL(
156 kQueryUrl
, &proxy_info
, CompletionCallback(), NULL
, BoundNetLog());
158 EXPECT_EQ(OK
, result
);
159 EXPECT_TRUE(proxy_info
.is_direct());
161 EXPECT_EQ(0U, resolver
.mock_js_bindings()->alerts
.size());
162 EXPECT_EQ(0U, resolver
.mock_js_bindings()->errors
.size());
165 TEST(ProxyResolverV8Test
, Basic
) {
166 ProxyResolverV8WithMockBindings resolver
;
167 int result
= resolver
.SetPacScriptFromDisk("passthrough.js");
168 EXPECT_EQ(OK
, result
);
170 // The "FindProxyForURL" of this PAC script simply concatenates all of the
171 // arguments into a pseudo-host. The purpose of this test is to verify that
172 // the correct arguments are being passed to FindProxyForURL().
174 ProxyInfo proxy_info
;
175 result
= resolver
.GetProxyForURL(GURL("http://query.com/path"), &proxy_info
,
176 CompletionCallback(), NULL
, BoundNetLog());
177 EXPECT_EQ(OK
, result
);
178 EXPECT_EQ("http.query.com.path.query.com:80",
179 proxy_info
.proxy_server().ToURI());
182 ProxyInfo proxy_info
;
183 int result
= resolver
.GetProxyForURL(
184 GURL("ftp://query.com:90/path"), &proxy_info
, CompletionCallback(),
185 NULL
, BoundNetLog());
186 EXPECT_EQ(OK
, result
);
187 // Note that FindProxyForURL(url, host) does not expect |host| to contain
189 EXPECT_EQ("ftp.query.com.90.path.query.com:80",
190 proxy_info
.proxy_server().ToURI());
192 EXPECT_EQ(0U, resolver
.mock_js_bindings()->alerts
.size());
193 EXPECT_EQ(0U, resolver
.mock_js_bindings()->errors
.size());
196 // We call this so we'll have code coverage of the function and valgrind will
197 // make sure nothing bad happens.
199 // NOTE: This is here instead of in its own test so that we'll be calling it
200 // after having done something, in hopes it won't be a no-op.
201 resolver
.PurgeMemory();
204 TEST(ProxyResolverV8Test
, BadReturnType
) {
205 // These are the filenames of PAC scripts which each return a non-string
206 // types for FindProxyForURL(). They should all fail with
207 // ERR_PAC_SCRIPT_FAILED.
208 static const char* const filenames
[] = {
209 "return_undefined.js",
211 "return_function.js",
213 // TODO(eroman): Should 'null' be considered equivalent to "DIRECT" ?
217 for (size_t i
= 0; i
< arraysize(filenames
); ++i
) {
218 ProxyResolverV8WithMockBindings resolver
;
219 int result
= resolver
.SetPacScriptFromDisk(filenames
[i
]);
220 EXPECT_EQ(OK
, result
);
222 ProxyInfo proxy_info
;
223 result
= resolver
.GetProxyForURL(
224 kQueryUrl
, &proxy_info
, CompletionCallback(), NULL
, BoundNetLog());
226 EXPECT_EQ(ERR_PAC_SCRIPT_FAILED
, result
);
228 MockJSBindings
* bindings
= resolver
.mock_js_bindings();
229 EXPECT_EQ(0U, bindings
->alerts
.size());
230 ASSERT_EQ(1U, bindings
->errors
.size());
231 EXPECT_EQ("FindProxyForURL() did not return a string.",
232 bindings
->errors
[0]);
233 EXPECT_EQ(-1, bindings
->errors_line_number
[0]);
237 // Try using a PAC script which defines no "FindProxyForURL" function.
238 TEST(ProxyResolverV8Test
, NoEntryPoint
) {
239 ProxyResolverV8WithMockBindings resolver
;
240 int result
= resolver
.SetPacScriptFromDisk("no_entrypoint.js");
241 EXPECT_EQ(ERR_PAC_SCRIPT_FAILED
, result
);
243 ProxyInfo proxy_info
;
244 result
= resolver
.GetProxyForURL(
245 kQueryUrl
, &proxy_info
, CompletionCallback(), NULL
, BoundNetLog());
247 EXPECT_EQ(ERR_FAILED
, result
);
250 // Try loading a malformed PAC script.
251 TEST(ProxyResolverV8Test
, ParseError
) {
252 ProxyResolverV8WithMockBindings resolver
;
253 int result
= resolver
.SetPacScriptFromDisk("missing_close_brace.js");
254 EXPECT_EQ(ERR_PAC_SCRIPT_FAILED
, result
);
256 ProxyInfo proxy_info
;
257 result
= resolver
.GetProxyForURL(
258 kQueryUrl
, &proxy_info
, CompletionCallback(), NULL
, BoundNetLog());
260 EXPECT_EQ(ERR_FAILED
, result
);
262 MockJSBindings
* bindings
= resolver
.mock_js_bindings();
263 EXPECT_EQ(0U, bindings
->alerts
.size());
265 // We get one error during compilation.
266 ASSERT_EQ(1U, bindings
->errors
.size());
268 EXPECT_EQ("Uncaught SyntaxError: Unexpected end of input",
269 bindings
->errors
[0]);
270 EXPECT_EQ(0, bindings
->errors_line_number
[0]);
273 // Run a PAC script several times, which has side-effects.
274 TEST(ProxyResolverV8Test
, SideEffects
) {
275 ProxyResolverV8WithMockBindings resolver
;
276 int result
= resolver
.SetPacScriptFromDisk("side_effects.js");
278 // The PAC script increments a counter each time we invoke it.
279 for (int i
= 0; i
< 3; ++i
) {
280 ProxyInfo proxy_info
;
281 result
= resolver
.GetProxyForURL(
282 kQueryUrl
, &proxy_info
, CompletionCallback(), NULL
, BoundNetLog());
283 EXPECT_EQ(OK
, result
);
284 EXPECT_EQ(base::StringPrintf("sideffect_%d:80", i
),
285 proxy_info
.proxy_server().ToURI());
288 // Reload the script -- the javascript environment should be reset, hence
289 // the counter starts over.
290 result
= resolver
.SetPacScriptFromDisk("side_effects.js");
291 EXPECT_EQ(OK
, result
);
293 for (int i
= 0; i
< 3; ++i
) {
294 ProxyInfo proxy_info
;
295 result
= resolver
.GetProxyForURL(
296 kQueryUrl
, &proxy_info
, CompletionCallback(), NULL
, BoundNetLog());
297 EXPECT_EQ(OK
, result
);
298 EXPECT_EQ(base::StringPrintf("sideffect_%d:80", i
),
299 proxy_info
.proxy_server().ToURI());
303 // Execute a PAC script which throws an exception in FindProxyForURL.
304 TEST(ProxyResolverV8Test
, UnhandledException
) {
305 ProxyResolverV8WithMockBindings resolver
;
306 int result
= resolver
.SetPacScriptFromDisk("unhandled_exception.js");
307 EXPECT_EQ(OK
, result
);
309 ProxyInfo proxy_info
;
310 result
= resolver
.GetProxyForURL(
311 kQueryUrl
, &proxy_info
, CompletionCallback(), NULL
, BoundNetLog());
313 EXPECT_EQ(ERR_PAC_SCRIPT_FAILED
, result
);
315 MockJSBindings
* bindings
= resolver
.mock_js_bindings();
316 EXPECT_EQ(0U, bindings
->alerts
.size());
317 ASSERT_EQ(1U, bindings
->errors
.size());
318 EXPECT_EQ("Uncaught ReferenceError: undefined_variable is not defined",
319 bindings
->errors
[0]);
320 EXPECT_EQ(3, bindings
->errors_line_number
[0]);
323 TEST(ProxyResolverV8Test
, ReturnUnicode
) {
324 ProxyResolverV8WithMockBindings resolver
;
325 int result
= resolver
.SetPacScriptFromDisk("return_unicode.js");
326 EXPECT_EQ(OK
, result
);
328 ProxyInfo proxy_info
;
329 result
= resolver
.GetProxyForURL(
330 kQueryUrl
, &proxy_info
, CompletionCallback(), NULL
, BoundNetLog());
332 // The result from this resolve was unparseable, because it
334 EXPECT_EQ(ERR_PAC_SCRIPT_FAILED
, result
);
337 // Test the PAC library functions that we expose in the JS environment.
338 TEST(ProxyResolverV8Test
, JavascriptLibrary
) {
339 ProxyResolverV8WithMockBindings resolver
;
340 int result
= resolver
.SetPacScriptFromDisk("pac_library_unittest.js");
341 EXPECT_EQ(OK
, result
);
343 ProxyInfo proxy_info
;
344 result
= resolver
.GetProxyForURL(
345 kQueryUrl
, &proxy_info
, CompletionCallback(), NULL
, BoundNetLog());
347 // If the javascript side of this unit-test fails, it will throw a javascript
348 // exception. Otherwise it will return "PROXY success:80".
349 EXPECT_EQ(OK
, result
);
350 EXPECT_EQ("success:80", proxy_info
.proxy_server().ToURI());
352 EXPECT_EQ(0U, resolver
.mock_js_bindings()->alerts
.size());
353 EXPECT_EQ(0U, resolver
.mock_js_bindings()->errors
.size());
356 // Try resolving when SetPacScriptByData() has not been called.
357 TEST(ProxyResolverV8Test
, NoSetPacScript
) {
358 ProxyResolverV8WithMockBindings resolver
;
360 ProxyInfo proxy_info
;
362 // Resolve should fail, as we are not yet initialized with a script.
363 int result
= resolver
.GetProxyForURL(
364 kQueryUrl
, &proxy_info
, CompletionCallback(), NULL
, BoundNetLog());
365 EXPECT_EQ(ERR_FAILED
, result
);
368 result
= resolver
.SetPacScriptFromDisk("direct.js");
369 EXPECT_EQ(OK
, result
);
371 // Resolve should now succeed.
372 result
= resolver
.GetProxyForURL(
373 kQueryUrl
, &proxy_info
, CompletionCallback(), NULL
, BoundNetLog());
374 EXPECT_EQ(OK
, result
);
376 // Clear it, by initializing with an empty string.
377 resolver
.SetPacScript(
378 ProxyResolverScriptData::FromUTF16(string16()), CompletionCallback());
380 // Resolve should fail again now.
381 result
= resolver
.GetProxyForURL(
382 kQueryUrl
, &proxy_info
, CompletionCallback(), NULL
, BoundNetLog());
383 EXPECT_EQ(ERR_FAILED
, result
);
385 // Load a good script once more.
386 result
= resolver
.SetPacScriptFromDisk("direct.js");
387 EXPECT_EQ(OK
, result
);
388 result
= resolver
.GetProxyForURL(
389 kQueryUrl
, &proxy_info
, CompletionCallback(), NULL
, BoundNetLog());
390 EXPECT_EQ(OK
, result
);
392 EXPECT_EQ(0U, resolver
.mock_js_bindings()->alerts
.size());
393 EXPECT_EQ(0U, resolver
.mock_js_bindings()->errors
.size());
396 // Test marshalling/un-marshalling of values between C++/V8.
397 TEST(ProxyResolverV8Test
, V8Bindings
) {
398 ProxyResolverV8WithMockBindings resolver
;
399 MockJSBindings
* bindings
= resolver
.mock_js_bindings();
400 bindings
->dns_resolve_result
= "127.0.0.1";
401 int result
= resolver
.SetPacScriptFromDisk("bindings.js");
402 EXPECT_EQ(OK
, result
);
404 ProxyInfo proxy_info
;
405 result
= resolver
.GetProxyForURL(
406 kQueryUrl
, &proxy_info
, CompletionCallback(), NULL
, BoundNetLog());
408 EXPECT_EQ(OK
, result
);
409 EXPECT_TRUE(proxy_info
.is_direct());
411 EXPECT_EQ(0U, resolver
.mock_js_bindings()->errors
.size());
413 // Alert was called 5 times.
414 ASSERT_EQ(5U, bindings
->alerts
.size());
415 EXPECT_EQ("undefined", bindings
->alerts
[0]);
416 EXPECT_EQ("null", bindings
->alerts
[1]);
417 EXPECT_EQ("undefined", bindings
->alerts
[2]);
418 EXPECT_EQ("[object Object]", bindings
->alerts
[3]);
419 EXPECT_EQ("exception from calling toString()", bindings
->alerts
[4]);
421 // DnsResolve was called 8 times, however only 2 of those were string
422 // parameters. (so 6 of them failed immediately).
423 ASSERT_EQ(2U, bindings
->dns_resolves
.size());
424 EXPECT_EQ("", bindings
->dns_resolves
[0]);
425 EXPECT_EQ("arg1", bindings
->dns_resolves
[1]);
427 // MyIpAddress was called two times.
428 EXPECT_EQ(2, bindings
->my_ip_address_count
);
430 // MyIpAddressEx was called once.
431 EXPECT_EQ(1, bindings
->my_ip_address_ex_count
);
433 // DnsResolveEx was called 2 times.
434 ASSERT_EQ(2U, bindings
->dns_resolves_ex
.size());
435 EXPECT_EQ("is_resolvable", bindings
->dns_resolves_ex
[0]);
436 EXPECT_EQ("foobar", bindings
->dns_resolves_ex
[1]);
439 // Test calling a binding (myIpAddress()) from the script's global scope.
440 // http://crbug.com/40026
441 TEST(ProxyResolverV8Test
, BindingCalledDuringInitialization
) {
442 ProxyResolverV8WithMockBindings resolver
;
444 int result
= resolver
.SetPacScriptFromDisk("binding_from_global.js");
445 EXPECT_EQ(OK
, result
);
447 MockJSBindings
* bindings
= resolver
.mock_js_bindings();
449 // myIpAddress() got called during initialization of the script.
450 EXPECT_EQ(1, bindings
->my_ip_address_count
);
452 ProxyInfo proxy_info
;
453 result
= resolver
.GetProxyForURL(
454 kQueryUrl
, &proxy_info
, CompletionCallback(), NULL
, BoundNetLog());
456 EXPECT_EQ(OK
, result
);
457 EXPECT_FALSE(proxy_info
.is_direct());
458 EXPECT_EQ("127.0.0.1:80", proxy_info
.proxy_server().ToURI());
460 // Check that no other bindings were called.
461 EXPECT_EQ(0U, bindings
->errors
.size());
462 ASSERT_EQ(0U, bindings
->alerts
.size());
463 ASSERT_EQ(0U, bindings
->dns_resolves
.size());
464 EXPECT_EQ(0, bindings
->my_ip_address_ex_count
);
465 ASSERT_EQ(0U, bindings
->dns_resolves_ex
.size());
468 // Try loading a PAC script that ends with a comment and has no terminal
469 // newline. This should not cause problems with the PAC utility functions
470 // that we add to the script's environment.
471 // http://crbug.com/22864
472 TEST(ProxyResolverV8Test
, EndsWithCommentNoNewline
) {
473 ProxyResolverV8WithMockBindings resolver
;
474 int result
= resolver
.SetPacScriptFromDisk("ends_with_comment.js");
475 EXPECT_EQ(OK
, result
);
477 ProxyInfo proxy_info
;
478 result
= resolver
.GetProxyForURL(
479 kQueryUrl
, &proxy_info
, CompletionCallback(), NULL
, BoundNetLog());
481 EXPECT_EQ(OK
, result
);
482 EXPECT_FALSE(proxy_info
.is_direct());
483 EXPECT_EQ("success:80", proxy_info
.proxy_server().ToURI());
486 // Try loading a PAC script that ends with a statement and has no terminal
487 // newline. This should not cause problems with the PAC utility functions
488 // that we add to the script's environment.
489 // http://crbug.com/22864
490 TEST(ProxyResolverV8Test
, EndsWithStatementNoNewline
) {
491 ProxyResolverV8WithMockBindings resolver
;
492 int result
= resolver
.SetPacScriptFromDisk(
493 "ends_with_statement_no_semicolon.js");
494 EXPECT_EQ(OK
, result
);
496 ProxyInfo proxy_info
;
497 result
= resolver
.GetProxyForURL(
498 kQueryUrl
, &proxy_info
, CompletionCallback(), NULL
, BoundNetLog());
500 EXPECT_EQ(OK
, result
);
501 EXPECT_FALSE(proxy_info
.is_direct());
502 EXPECT_EQ("success:3", proxy_info
.proxy_server().ToURI());
505 // Test the return values from myIpAddress(), myIpAddressEx(), dnsResolve(),
506 // dnsResolveEx(), isResolvable(), isResolvableEx(), when the the binding
507 // returns empty string (failure). This simulates the return values from
508 // those functions when the underlying DNS resolution fails.
509 TEST(ProxyResolverV8Test
, DNSResolutionFailure
) {
510 ProxyResolverV8WithMockBindings resolver
;
511 int result
= resolver
.SetPacScriptFromDisk("dns_fail.js");
512 EXPECT_EQ(OK
, result
);
514 ProxyInfo proxy_info
;
515 result
= resolver
.GetProxyForURL(
516 kQueryUrl
, &proxy_info
, CompletionCallback(), NULL
, BoundNetLog());
518 EXPECT_EQ(OK
, result
);
519 EXPECT_FALSE(proxy_info
.is_direct());
520 EXPECT_EQ("success:80", proxy_info
.proxy_server().ToURI());
523 TEST(ProxyResolverV8Test
, DNSResolutionOfInternationDomainName
) {
524 ProxyResolverV8WithMockBindings resolver
;
525 int result
= resolver
.SetPacScriptFromDisk("international_domain_names.js");
526 EXPECT_EQ(OK
, result
);
528 // Execute FindProxyForURL().
529 ProxyInfo proxy_info
;
530 result
= resolver
.GetProxyForURL(
531 kQueryUrl
, &proxy_info
, CompletionCallback(), NULL
, BoundNetLog());
533 EXPECT_EQ(OK
, result
);
534 EXPECT_TRUE(proxy_info
.is_direct());
536 // Check that the international domain name was converted to punycode
537 // before passing it onto the bindings layer.
538 MockJSBindings
* bindings
= resolver
.mock_js_bindings();
540 ASSERT_EQ(1u, bindings
->dns_resolves
.size());
541 EXPECT_EQ("xn--bcher-kva.ch", bindings
->dns_resolves
[0]);
543 ASSERT_EQ(1u, bindings
->dns_resolves_ex
.size());
544 EXPECT_EQ("xn--bcher-kva.ch", bindings
->dns_resolves_ex
[0]);
547 // Test that when resolving a URL which contains an IPv6 string literal, the
548 // brackets are removed from the host before passing it down to the PAC script.
549 // If we don't do this, then subsequent calls to dnsResolveEx(host) will be
550 // doomed to fail since it won't correspond with a valid name.
551 TEST(ProxyResolverV8Test
, IPv6HostnamesNotBracketed
) {
552 ProxyResolverV8WithMockBindings resolver
;
553 int result
= resolver
.SetPacScriptFromDisk("resolve_host.js");
554 EXPECT_EQ(OK
, result
);
556 ProxyInfo proxy_info
;
557 result
= resolver
.GetProxyForURL(
558 GURL("http://[abcd::efff]:99/watsupdawg"), &proxy_info
,
559 CompletionCallback(), NULL
, BoundNetLog());
561 EXPECT_EQ(OK
, result
);
562 EXPECT_TRUE(proxy_info
.is_direct());
564 // We called dnsResolveEx() exactly once, by passing through the "host"
565 // argument to FindProxyForURL(). The brackets should have been stripped.
566 ASSERT_EQ(1U, resolver
.mock_js_bindings()->dns_resolves_ex
.size());
567 EXPECT_EQ("abcd::efff", resolver
.mock_js_bindings()->dns_resolves_ex
[0]);