1 // Copyright (c) 2010 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.
4
5 #define LOG_TAG "ProxyResolverTest"
6
7 #include <utils/Log.h>
8 #include "android_runtime/AndroidRuntime.h"
9 #include <string.h>
10
11 #include "proxy_test_script.h"
12 #include "proxy_resolver_v8.h"
13 #include "include/gtest/gtest.h"
14
15 using namespace android;
16 namespace net {
17 namespace {
18
19 // Javascript bindings for ProxyResolverV8, which returns mock values.
20 // Each time one of the bindings is called into, we push the input into a
21 // list, for later verification.
22 class MockJSBindings : public ProxyResolverJSBindings, public ProxyErrorListener {
23 public:
MockJSBindings()24 MockJSBindings() : my_ip_address_count(0), my_ip_address_ex_count(0) {}
25
MyIpAddress(std::string * ip_address)26 virtual bool MyIpAddress(std::string* ip_address) {
27 my_ip_address_count++;
28 *ip_address = my_ip_address_result;
29 return !my_ip_address_result.empty();
30 }
31
MyIpAddressEx(std::string * ip_address_list)32 virtual bool MyIpAddressEx(std::string* ip_address_list) {
33 my_ip_address_ex_count++;
34 *ip_address_list = my_ip_address_ex_result;
35 return !my_ip_address_ex_result.empty();
36 }
37
DnsResolve(const std::string & host,std::string * ip_address)38 virtual bool DnsResolve(const std::string& host, std::string* ip_address) {
39 dns_resolves.push_back(host);
40 *ip_address = dns_resolve_result;
41 return !dns_resolve_result.empty();
42 }
43
DnsResolveEx(const std::string & host,std::string * ip_address_list)44 virtual bool DnsResolveEx(const std::string& host,
45 std::string* ip_address_list) {
46 dns_resolves_ex.push_back(host);
47 *ip_address_list = dns_resolve_ex_result;
48 return !dns_resolve_ex_result.empty();
49 }
50
AlertMessage(String16 message)51 virtual void AlertMessage(String16 message) {
52 String8 m8(message);
53 std::string mstd(m8.string());
54
55 ALOGD("PAC-alert: %s\n", mstd.c_str()); // Helpful when debugging.
56 alerts.push_back(mstd);
57 }
58
ErrorMessage(const String16 message)59 virtual void ErrorMessage(const String16 message) {
60 String8 m8(message);
61 std::string mstd(m8.string());
62
63 ALOGD("PAC-error: %s\n", mstd.c_str()); // Helpful when debugging.
64 errors.push_back(mstd);
65 }
66
Shutdown()67 virtual void Shutdown() {}
68
69 // Mock values to return.
70 std::string my_ip_address_result;
71 std::string my_ip_address_ex_result;
72 std::string dns_resolve_result;
73 std::string dns_resolve_ex_result;
74
75 // Inputs we got called with.
76 std::vector<std::string> alerts;
77 std::vector<std::string> errors;
78 std::vector<std::string> dns_resolves;
79 std::vector<std::string> dns_resolves_ex;
80 int my_ip_address_count;
81 int my_ip_address_ex_count;
82 };
83
84 // This is the same as ProxyResolverV8, but it uses mock bindings in place of
85 // the default bindings, and has a helper function to load PAC scripts from
86 // disk.
87 class ProxyResolverV8WithMockBindings : public ProxyResolverV8 {
88 public:
ProxyResolverV8WithMockBindings(MockJSBindings * mock_js_bindings)89 ProxyResolverV8WithMockBindings(MockJSBindings* mock_js_bindings) :
90 ProxyResolverV8(mock_js_bindings, mock_js_bindings), mock_js_bindings_(mock_js_bindings) {
91 }
92
mock_js_bindings() const93 MockJSBindings* mock_js_bindings() const {
94 return mock_js_bindings_;
95 }
96
97 private:
98 MockJSBindings* mock_js_bindings_;
99 };
100
101 // Doesn't really matter what these values are for many of the tests.
102 const String16 kQueryUrl("http://www.google.com");
103 const String16 kQueryHost("www.google.com");
104 String16 kResults;
105
106 String16 currentPac;
107 #define SCRIPT(x) (currentPac = String16(x))
108
addString(std::vector<std::string> * list,std::string str)109 void addString(std::vector<std::string>* list, std::string str) {
110 if (str.compare(0, 6, "DIRECT") == 0) {
111 list->push_back("DIRECT");
112 } else if (str.compare(0, 6, "PROXY ") == 0) {
113 list->push_back(str.substr(6));
114 } else {
115 ALOGE("Unrecognized proxy string");
116 }
117 }
118
string16ToProxyList(String16 response)119 std::vector<std::string> string16ToProxyList(String16 response) {
120 std::vector<std::string> ret;
121 String8 response8(response);
122 std::string rstr(response8.string());
123 if (rstr.find(';') == std::string::npos) {
124 addString(&ret, rstr);
125 return ret;
126 }
127 char str[128];
128 rstr.copy(str, 0, rstr.length());
129 const char* pch = strtok(str, ";");
130
131 while (pch != NULL) {
132 // Skip leading whitespace
133 while ((*pch) == ' ') ++pch;
134 std::string pstring(pch);
135 addString(&ret, pstring);
136
137 pch = strtok(NULL, "; \t");
138 }
139
140 return ret;
141 }
142
StringPrintf(std::string str,int d)143 std::string StringPrintf(std::string str, int d) {
144 char buf[30];
145 sprintf(buf, str.c_str(), d);
146 return std::string(buf);
147 }
148
TEST(ProxyResolverV8Test,Direct)149 TEST(ProxyResolverV8Test, Direct) {
150 ProxyResolverV8WithMockBindings resolver(new MockJSBindings());
151 int result = resolver.SetPacScript(SCRIPT(DIRECT_JS));
152 EXPECT_EQ(OK, result);
153
154 result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);
155
156 EXPECT_EQ(OK, result);
157 std::vector<std::string> proxies = string16ToProxyList(kResults);
158 EXPECT_EQ(proxies.size(), 1U);
159 EXPECT_EQ("DIRECT",proxies[0]);
160
161 EXPECT_EQ(0U, resolver.mock_js_bindings()->alerts.size());
162 EXPECT_EQ(0U, resolver.mock_js_bindings()->errors.size());
163 }
164
TEST(ProxyResolverV8Test,ReturnEmptyString)165 TEST(ProxyResolverV8Test, ReturnEmptyString) {
166 ProxyResolverV8WithMockBindings resolver(new MockJSBindings());
167 int result = resolver.SetPacScript(SCRIPT(RETURN_EMPTY_STRING_JS));
168 EXPECT_EQ(OK, result);
169
170 result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);
171
172 EXPECT_EQ(OK, result);
173 std::vector<std::string> proxies = string16ToProxyList(kResults);
174 EXPECT_EQ(proxies.size(), 0U);
175
176 EXPECT_EQ(0U, resolver.mock_js_bindings()->alerts.size());
177 EXPECT_EQ(0U, resolver.mock_js_bindings()->errors.size());
178 }
179
TEST(ProxyResolverV8Test,Basic)180 TEST(ProxyResolverV8Test, Basic) {
181 ProxyResolverV8WithMockBindings resolver(new MockJSBindings());
182 int result = resolver.SetPacScript(SCRIPT(PASSTHROUGH_JS));
183 EXPECT_EQ(OK, result);
184
185 // The "FindProxyForURL" of this PAC script simply concatenates all of the
186 // arguments into a pseudo-host. The purpose of this test is to verify that
187 // the correct arguments are being passed to FindProxyForURL().
188 {
189 String16 queryUrl("http://query.com/path");
190 String16 queryHost("query.com");
191 result = resolver.GetProxyForURL(queryUrl, queryHost, &kResults);
192 EXPECT_EQ(OK, result);
193 std::vector<std::string> proxies = string16ToProxyList(kResults);
194 EXPECT_EQ(1U, proxies.size());
195 EXPECT_EQ("http.query.com.path.query.com", proxies[0]);
196 }
197 {
198 String16 queryUrl("ftp://query.com:90/path");
199 String16 queryHost("query.com");
200 int result = resolver.GetProxyForURL(queryUrl, queryHost, &kResults);
201
202 EXPECT_EQ(OK, result);
203 // Note that FindProxyForURL(url, host) does not expect |host| to contain
204 // the port number.
205 std::vector<std::string> proxies = string16ToProxyList(kResults);
206 EXPECT_EQ(1U, proxies.size());
207 EXPECT_EQ("ftp.query.com.90.path.query.com", proxies[0]);
208
209 EXPECT_EQ(0U, resolver.mock_js_bindings()->alerts.size());
210 EXPECT_EQ(0U, resolver.mock_js_bindings()->errors.size());
211 }
212
213 // We call this so we'll have code coverage of the function and valgrind will
214 // make sure nothing bad happens.
215 //
216 // NOTE: This is here instead of in its own test so that we'll be calling it
217 // after having done something, in hopes it won't be a no-op.
218 resolver.PurgeMemory();
219 }
220
TEST(ProxyResolverV8Test,BadReturnType)221 TEST(ProxyResolverV8Test, BadReturnType) {
222 // These are the files of PAC scripts which each return a non-string
223 // types for FindProxyForURL(). They should all fail with
224 // ERR_PAC_SCRIPT_FAILED.
225 static const String16 files[] = {
226 String16(RETURN_UNDEFINED_JS),
227 String16(RETURN_INTEGER_JS),
228 String16(RETURN_FUNCTION_JS),
229 String16(RETURN_OBJECT_JS),
230 String16(RETURN_NULL_JS)
231 };
232
233 for (size_t i = 0; i < 5; ++i) {
234 ProxyResolverV8WithMockBindings resolver(new MockJSBindings());
235 int result = resolver.SetPacScript(files[i]);
236 EXPECT_EQ(OK, result);
237
238 result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);
239
240 EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, result);
241
242 MockJSBindings* bindings = resolver.mock_js_bindings();
243 EXPECT_EQ(0U, bindings->alerts.size());
244 ASSERT_EQ(1U, bindings->errors.size());
245 EXPECT_EQ("FindProxyForURL() did not return a string.",
246 bindings->errors[0]);
247 }
248 }
249
250 // Try using a PAC script which defines no "FindProxyForURL" function.
TEST(ProxyResolverV8Test,NoEntryPoint)251 TEST(ProxyResolverV8Test, NoEntryPoint) {
252 ProxyResolverV8WithMockBindings resolver(new MockJSBindings());
253 int result = resolver.SetPacScript(SCRIPT(NO_ENTRYPOINT_JS));
254 EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, result);
255
256 result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);
257
258 EXPECT_EQ(ERR_FAILED, result);
259 }
260
261 // Try loading a malformed PAC script.
TEST(ProxyResolverV8Test,ParseError)262 TEST(ProxyResolverV8Test, ParseError) {
263 ProxyResolverV8WithMockBindings resolver(new MockJSBindings());
264 int result = resolver.SetPacScript(SCRIPT(MISSING_CLOSE_BRACE_JS));
265 EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, result);
266
267 result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);
268
269 EXPECT_EQ(ERR_FAILED, result);
270
271 MockJSBindings* bindings = resolver.mock_js_bindings();
272 EXPECT_EQ(0U, bindings->alerts.size());
273
274 // We get one error during compilation.
275 ASSERT_EQ(1U, bindings->errors.size());
276
277 EXPECT_EQ("Uncaught SyntaxError: Unexpected end of input",
278 bindings->errors[0]);
279 }
280
281 // Run a PAC script several times, which has side-effects.
TEST(ProxyResolverV8Test,SideEffects)282 TEST(ProxyResolverV8Test, SideEffects) {
283 ProxyResolverV8WithMockBindings resolver(new MockJSBindings());
284 int result = resolver.SetPacScript(SCRIPT(SIDE_EFFECTS_JS));
285
286 // The PAC script increments a counter each time we invoke it.
287 for (int i = 0; i < 3; ++i) {
288 result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);
289 EXPECT_EQ(OK, result);
290 std::vector<std::string> proxies = string16ToProxyList(kResults);
291 EXPECT_EQ(1U, proxies.size());
292 EXPECT_EQ(StringPrintf("sideffect_%d", i),
293 proxies[0]);
294 }
295
296 // Reload the script -- the javascript environment should be reset, hence
297 // the counter starts over.
298 result = resolver.SetPacScript(SCRIPT(SIDE_EFFECTS_JS));
299 EXPECT_EQ(OK, result);
300
301 for (int i = 0; i < 3; ++i) {
302 result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);
303 EXPECT_EQ(OK, result);
304 std::vector<std::string> proxies = string16ToProxyList(kResults);
305 EXPECT_EQ(1U, proxies.size());
306 EXPECT_EQ(StringPrintf("sideffect_%d", i),
307 proxies[0]);
308 }
309 }
310
311 // Execute a PAC script which throws an exception in FindProxyForURL.
TEST(ProxyResolverV8Test,UnhandledException)312 TEST(ProxyResolverV8Test, UnhandledException) {
313 ProxyResolverV8WithMockBindings resolver(new MockJSBindings());
314 int result = resolver.SetPacScript(SCRIPT(UNHANDLED_EXCEPTION_JS));
315 EXPECT_EQ(OK, result);
316
317 result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);
318
319 EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, result);
320
321 MockJSBindings* bindings = resolver.mock_js_bindings();
322 EXPECT_EQ(0U, bindings->alerts.size());
323 ASSERT_EQ(1U, bindings->errors.size());
324 EXPECT_EQ("Uncaught ReferenceError: undefined_variable is not defined",
325 bindings->errors[0]);
326 }
327
TEST(ProxyResolverV8Test,ReturnUnicode)328 TEST(ProxyResolverV8Test, ReturnUnicode) {
329 ProxyResolverV8WithMockBindings resolver(new MockJSBindings());
330 int result = resolver.SetPacScript(SCRIPT(RETURN_UNICODE_JS));
331 EXPECT_EQ(OK, result);
332
333 result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);
334
335 // The result from this resolve was unparseable, because it
336 // wasn't ASCII.
337 EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, result);
338 }
339
340 // Test the PAC library functions that we expose in the JS environmnet.
TEST(ProxyResolverV8Test,JavascriptLibrary)341 TEST(ProxyResolverV8Test, JavascriptLibrary) {
342 ALOGE("Javascript start");
343 ProxyResolverV8WithMockBindings resolver(new MockJSBindings());
344 int result = resolver.SetPacScript(SCRIPT(PAC_LIBRARY_UNITTEST_JS));
345 EXPECT_EQ(OK, result);
346
347 result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);
348
349 // If the javascript side of this unit-test fails, it will throw a javascript
350 // exception. Otherwise it will return "PROXY success:80".
351 EXPECT_EQ(OK, result);
352 std::vector<std::string> proxies = string16ToProxyList(kResults);
353 EXPECT_EQ(1U, proxies.size());
354 EXPECT_EQ("success:80", proxies[0]);
355
356 EXPECT_EQ(0U, resolver.mock_js_bindings()->alerts.size());
357 EXPECT_EQ(0U, resolver.mock_js_bindings()->errors.size());
358 }
359
360 // Try resolving when SetPacScriptByData() has not been called.
TEST(ProxyResolverV8Test,NoSetPacScript)361 TEST(ProxyResolverV8Test, NoSetPacScript) {
362 ProxyResolverV8WithMockBindings resolver(new MockJSBindings());
363
364
365 // Resolve should fail, as we are not yet initialized with a script.
366 int result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);
367 EXPECT_EQ(ERR_FAILED, result);
368
369 // Initialize it.
370 result = resolver.SetPacScript(SCRIPT(DIRECT_JS));
371 EXPECT_EQ(OK, result);
372
373 // Resolve should now succeed.
374 result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);
375 EXPECT_EQ(OK, result);
376
377 // Clear it, by initializing with an empty string.
378 resolver.SetPacScript(SCRIPT());
379
380 // Resolve should fail again now.
381 result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);
382 EXPECT_EQ(ERR_FAILED, result);
383
384 // Load a good script once more.
385 result = resolver.SetPacScript(SCRIPT(DIRECT_JS));
386 EXPECT_EQ(OK, result);
387 result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);
388 EXPECT_EQ(OK, result);
389
390 EXPECT_EQ(0U, resolver.mock_js_bindings()->alerts.size());
391 EXPECT_EQ(0U, resolver.mock_js_bindings()->errors.size());
392 }
393
394 // Test marshalling/un-marshalling of values between C++/V8.
TEST(ProxyResolverV8Test,V8Bindings)395 TEST(ProxyResolverV8Test, V8Bindings) {
396 ProxyResolverV8WithMockBindings resolver(new MockJSBindings());
397 MockJSBindings* bindings = resolver.mock_js_bindings();
398 bindings->dns_resolve_result = "127.0.0.1";
399 int result = resolver.SetPacScript(SCRIPT(BINDINGS_JS));
400 EXPECT_EQ(OK, result);
401
402 result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);
403
404 EXPECT_EQ(OK, result);
405 std::vector<std::string> proxies = string16ToProxyList(kResults);
406 EXPECT_EQ(1U, proxies.size());
407 EXPECT_EQ("DIRECT", proxies[0]);
408
409 EXPECT_EQ(0U, resolver.mock_js_bindings()->errors.size());
410
411 // Alert was called 5 times.
412 ASSERT_EQ(5U, bindings->alerts.size());
413 EXPECT_EQ("undefined", bindings->alerts[0]);
414 EXPECT_EQ("null", bindings->alerts[1]);
415 EXPECT_EQ("undefined", bindings->alerts[2]);
416 EXPECT_EQ("[object Object]", bindings->alerts[3]);
417 EXPECT_EQ("exception from calling toString()", bindings->alerts[4]);
418
419 // DnsResolve was called 8 times, however only 2 of those were string
420 // parameters. (so 6 of them failed immediately).
421 ASSERT_EQ(2U, bindings->dns_resolves.size());
422 EXPECT_EQ("", bindings->dns_resolves[0]);
423 EXPECT_EQ("arg1", bindings->dns_resolves[1]);
424
425 // MyIpAddress was called two times.
426 EXPECT_EQ(2, bindings->my_ip_address_count);
427
428 // MyIpAddressEx was called once.
429 EXPECT_EQ(1, bindings->my_ip_address_ex_count);
430
431 // DnsResolveEx was called 2 times.
432 ASSERT_EQ(2U, bindings->dns_resolves_ex.size());
433 EXPECT_EQ("is_resolvable", bindings->dns_resolves_ex[0]);
434 EXPECT_EQ("foobar", bindings->dns_resolves_ex[1]);
435 }
436
437 // Test calling a binding (myIpAddress()) from the script's global scope.
438 // http://crbug.com/40026
TEST(ProxyResolverV8Test,BindingCalledDuringInitialization)439 TEST(ProxyResolverV8Test, BindingCalledDuringInitialization) {
440 ProxyResolverV8WithMockBindings resolver(new MockJSBindings());
441
442 int result = resolver.SetPacScript(SCRIPT(BINDING_FROM_GLOBAL_JS));
443 EXPECT_EQ(OK, result);
444
445 MockJSBindings* bindings = resolver.mock_js_bindings();
446
447 // myIpAddress() got called during initialization of the script.
448 EXPECT_EQ(1, bindings->my_ip_address_count);
449
450 result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);
451
452 EXPECT_EQ(OK, result);
453 std::vector<std::string> proxies = string16ToProxyList(kResults);
454 EXPECT_EQ(1U, proxies.size());
455 EXPECT_NE("DIRECT", proxies[0]);
456 EXPECT_EQ("127.0.0.1:80", proxies[0]);
457
458 // Check that no other bindings were called.
459 EXPECT_EQ(0U, bindings->errors.size());
460 ASSERT_EQ(0U, bindings->alerts.size());
461 ASSERT_EQ(0U, bindings->dns_resolves.size());
462 EXPECT_EQ(0, bindings->my_ip_address_ex_count);
463 ASSERT_EQ(0U, bindings->dns_resolves_ex.size());
464 }
465
466 // Try loading a PAC script that ends with a comment and has no terminal
467 // newline. This should not cause problems with the PAC utility functions
468 // that we add to the script's environment.
469 // http://crbug.com/22864
TEST(ProxyResolverV8Test,EndsWithCommentNoNewline)470 TEST(ProxyResolverV8Test, EndsWithCommentNoNewline) {
471 ProxyResolverV8WithMockBindings resolver(new MockJSBindings());
472 int result = resolver.SetPacScript(SCRIPT(ENDS_WITH_COMMENT_JS));
473 EXPECT_EQ(OK, result);
474
475 result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);
476
477 EXPECT_EQ(OK, result);
478 std::vector<std::string> proxies = string16ToProxyList(kResults);
479 EXPECT_EQ(1U, proxies.size());
480 EXPECT_NE("DIRECT", proxies[0]);
481 EXPECT_EQ("success:80", proxies[0]);
482 }
483
484 // Try loading a PAC script that ends with a statement and has no terminal
485 // newline. This should not cause problems with the PAC utility functions
486 // that we add to the script's environment.
487 // http://crbug.com/22864
TEST(ProxyResolverV8Test,EndsWithStatementNoNewline)488 TEST(ProxyResolverV8Test, EndsWithStatementNoNewline) {
489 ProxyResolverV8WithMockBindings resolver(new MockJSBindings());
490 int result = resolver.SetPacScript(
491 SCRIPT(ENDS_WITH_STATEMENT_NO_SEMICOLON_JS));
492 EXPECT_EQ(OK, result);
493
494 result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);
495
496 EXPECT_EQ(OK, result);
497 std::vector<std::string> proxies = string16ToProxyList(kResults);
498 EXPECT_EQ(1U, proxies.size());
499 EXPECT_NE("DIRECT", proxies[0]);
500 EXPECT_EQ("success:3", proxies[0]);
501 }
502
503 // Test the return values from myIpAddress(), myIpAddressEx(), dnsResolve(),
504 // dnsResolveEx(), isResolvable(), isResolvableEx(), when the the binding
505 // returns empty string (failure). This simulates the return values from
506 // those functions when the underlying DNS resolution fails.
TEST(ProxyResolverV8Test,DNSResolutionFailure)507 TEST(ProxyResolverV8Test, DNSResolutionFailure) {
508 ProxyResolverV8WithMockBindings resolver(new MockJSBindings());
509 int result = resolver.SetPacScript(SCRIPT(DNS_FAIL_JS));
510 EXPECT_EQ(OK, result);
511
512 result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);
513
514 EXPECT_EQ(OK, result);
515 std::vector<std::string> proxies = string16ToProxyList(kResults);
516 EXPECT_EQ(1U, proxies.size());
517 EXPECT_NE("DIRECT", proxies[0]);
518 EXPECT_EQ("success:80", proxies[0]);
519 }
520
TEST(ProxyResolverV8Test,DNSResolutionOfInternationDomainName)521 TEST(ProxyResolverV8Test, DNSResolutionOfInternationDomainName) {
522 return;
523 ProxyResolverV8WithMockBindings resolver(new MockJSBindings());
524 int result = resolver.SetPacScript(String16(INTERNATIONAL_DOMAIN_NAMES_JS));
525 EXPECT_EQ(OK, result);
526
527 // Execute FindProxyForURL().
528 result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);
529
530 EXPECT_EQ(OK, result);
531 std::vector<std::string> proxies = string16ToProxyList(kResults);
532 EXPECT_EQ(1U, proxies.size());
533 EXPECT_EQ("DIRECT", proxies[0]);
534
535 // Check that the international domain name was converted to punycode
536 // before passing it onto the bindings layer.
537 MockJSBindings* bindings = resolver.mock_js_bindings();
538
539 ASSERT_EQ(1u, bindings->dns_resolves.size());
540 EXPECT_EQ("xn--bcher-kva.ch", bindings->dns_resolves[0]);
541
542 ASSERT_EQ(1u, bindings->dns_resolves_ex.size());
543 EXPECT_EQ("xn--bcher-kva.ch", bindings->dns_resolves_ex[0]);
544 }
545
546 } // namespace
547 } // namespace net
548