Home | History | Annotate | Download | only in test
      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:
     24   MockJSBindings() : my_ip_address_count(0), my_ip_address_ex_count(0) {}
     25 
     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 
     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 
     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 
     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 
     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 
     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 
     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:
     89   ProxyResolverV8WithMockBindings(MockJSBindings* mock_js_bindings) :
     90       ProxyResolverV8(mock_js_bindings, mock_js_bindings), mock_js_bindings_(mock_js_bindings) {
     91   }
     92 
     93   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 
    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 
    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 
    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 
    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 
    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 
    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 
    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.
    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.
    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.
    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.
    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 
    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.
    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.
    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.
    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
    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
    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
    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.
    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 
    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