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