1685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com// Use of this source code is governed by a BSD-style license that can be 3685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com// found in the LICENSE file. 4685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com 5685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com#include "base/base_paths.h" 6685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com#include "base/file_util.h" 7685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com#include "base/path_service.h" 8685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com#include "base/perftimer.h" 9bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "base/string_util.h" 10bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "net/base/mock_host_resolver.h" 113ef45971cdc72a20db91e8bce37e16d669947e4arobertphillips@google.com#include "net/base/net_errors.h" 129ce78f26f529fd3e10a3eb4f044bc3f0037ead56djsollen@google.com#include "net/proxy/proxy_info.h" 13bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "net/proxy/proxy_resolver_js_bindings.h" 148c2ce5e8666e05e662d8bfcb8aaf89cdb34c3a0ehumper@google.com#include "net/proxy/proxy_resolver_v8.h" 15494c51acb7f414d5ff5e7ab617a7bc32becb6381robertphillips@google.com#include "net/test/test_server.h" 161c6d325f96b5b14e7b0c76680d6a15d6517d2eb6robertphillips@google.com#include "testing/gtest/include/gtest/gtest.h" 171c6d325f96b5b14e7b0c76680d6a15d6517d2eb6robertphillips@google.com 181c6d325f96b5b14e7b0c76680d6a15d6517d2eb6robertphillips@google.com#if defined(OS_WIN) 191c6d325f96b5b14e7b0c76680d6a15d6517d2eb6robertphillips@google.com#include "net/proxy/proxy_resolver_winhttp.h" 201c6d325f96b5b14e7b0c76680d6a15d6517d2eb6robertphillips@google.com#elif defined(OS_MACOSX) 211c6d325f96b5b14e7b0c76680d6a15d6517d2eb6robertphillips@google.com#include "net/proxy/proxy_resolver_mac.h" 221c6d325f96b5b14e7b0c76680d6a15d6517d2eb6robertphillips@google.com#endif 231c6d325f96b5b14e7b0c76680d6a15d6517d2eb6robertphillips@google.com 24bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com// This class holds the URL to use for resolving, and the expected result. 25bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com// We track the expected result in order to make sure the performance 26bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com// test is actually resolving URLs properly, otherwise the perf numbers 279df4d78e401f921b65012987f8d2049e9da5cef5robertphillips@google.com// are meaningless :-) 28bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comstruct PacQuery { 29bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com const char* query_url; 309011c23655acf4186fca1789daee7e94fc0bbe61reed@google.com const char* expected_result; 31ff0114918f0420778dfac164d810af08eadbac26reed@google.com}; 329011c23655acf4186fca1789daee7e94fc0bbe61reed@google.com 33b75bc072b3a26cafed919573412f7ca2fd8d0953skia.committer@gmail.com// Entry listing which PAC scripts to load, and which URLs to try resolving. 341c6d325f96b5b14e7b0c76680d6a15d6517d2eb6robertphillips@google.com// |queries| should be terminated by {NULL, NULL}. A sentinel is used 3552373f2a535a319f6b6d4a144e57491c5e56e311skia.committer@gmail.com// rather than a length, to simplify using initializer lists. 361c6d325f96b5b14e7b0c76680d6a15d6517d2eb6robertphillips@google.comstruct PacPerfTest { 371c6d325f96b5b14e7b0c76680d6a15d6517d2eb6robertphillips@google.com const char* pac_name; 381c6d325f96b5b14e7b0c76680d6a15d6517d2eb6robertphillips@google.com PacQuery queries[100]; 3952373f2a535a319f6b6d4a144e57491c5e56e311skia.committer@gmail.com 4052373f2a535a319f6b6d4a144e57491c5e56e311skia.committer@gmail.com // Returns the actual number of entries in |queries| (assumes NULL sentinel). 411c6d325f96b5b14e7b0c76680d6a15d6517d2eb6robertphillips@google.com int NumQueries() const; 421c6d325f96b5b14e7b0c76680d6a15d6517d2eb6robertphillips@google.com}; 431c6d325f96b5b14e7b0c76680d6a15d6517d2eb6robertphillips@google.com 441c6d325f96b5b14e7b0c76680d6a15d6517d2eb6robertphillips@google.com// List of performance tests. 459011c23655acf4186fca1789daee7e94fc0bbe61reed@google.comstatic PacPerfTest kPerfTests[] = { 46bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com // This test uses an ad-blocker PAC script. This script is very heavily 47494c51acb7f414d5ff5e7ab617a7bc32becb6381robertphillips@google.com // regular expression oriented, and has no dependencies on the current 484d1d95c61576960796347e1dd5006d878e9d2dc0djsollen@google.com // IP address, or DNS resolving of hosts. 49bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com { "no-ads.pac", 501e7ce9786525318f59d4c5a6efa6819c6ff9ab84reed@google.com { // queries: 51bb6529fbc4553260f434113a62a20af53c525649reed@google.com {"http://www.google.com", "DIRECT"}, 52bb6529fbc4553260f434113a62a20af53c525649reed@google.com {"http://www.imdb.com/photos/cmsicons/x", "PROXY 0.0.0.0:3421"}, 539011c23655acf4186fca1789daee7e94fc0bbe61reed@google.com {"http://www.imdb.com/x", "DIRECT"}, 54b75bc072b3a26cafed919573412f7ca2fd8d0953skia.committer@gmail.com {"http://www.staples.com/", "DIRECT"}, 55b75bc072b3a26cafed919573412f7ca2fd8d0953skia.committer@gmail.com {"http://www.staples.com/pixeltracker/x", "PROXY 0.0.0.0:3421"}, 568c2ce5e8666e05e662d8bfcb8aaf89cdb34c3a0ehumper@google.com {"http://www.staples.com/pixel/x", "DIRECT"}, 57a29024e9f900c5565340a27e925bca7d0f6ea8e1skia.committer@gmail.com {"http://www.foobar.com", "DIRECT"}, 58bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com {"http://www.foobarbaz.com/x/y/z", "DIRECT"}, 591c6d325f96b5b14e7b0c76680d6a15d6517d2eb6robertphillips@google.com {"http://www.testurl1.com/index.html", "DIRECT"}, 601c6d325f96b5b14e7b0c76680d6a15d6517d2eb6robertphillips@google.com {"http://www.testurl2.com", "DIRECT"}, 611c6d325f96b5b14e7b0c76680d6a15d6517d2eb6robertphillips@google.com {"https://www.sample/pirate/arrrrrr", "DIRECT"}, 629df4d78e401f921b65012987f8d2049e9da5cef5robertphillips@google.com {NULL, NULL} 639df4d78e401f921b65012987f8d2049e9da5cef5robertphillips@google.com }, 649df4d78e401f921b65012987f8d2049e9da5cef5robertphillips@google.com }, 65bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}; 66740de996d9e77a695864fdd8b89b4bd55f8d304asenorblanco@chromium.org 67bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comint PacPerfTest::NumQueries() const { 68bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com for (size_t i = 0; i < arraysize(queries); ++i) { 69cd2e444e946f5cfec4723f5bc46e9487d82e8e54djsollen@google.com if (queries[i].query_url == NULL) 709df4d78e401f921b65012987f8d2049e9da5cef5robertphillips@google.com return i; 719df4d78e401f921b65012987f8d2049e9da5cef5robertphillips@google.com } 721c6d325f96b5b14e7b0c76680d6a15d6517d2eb6robertphillips@google.com NOTREACHED(); // Bad definition. 731c6d325f96b5b14e7b0c76680d6a15d6517d2eb6robertphillips@google.com return 0; 749df4d78e401f921b65012987f8d2049e9da5cef5robertphillips@google.com} 759df4d78e401f921b65012987f8d2049e9da5cef5robertphillips@google.com 761c6d325f96b5b14e7b0c76680d6a15d6517d2eb6robertphillips@google.com// The number of URLs to resolve when testing a PAC script. 77935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.comconst int kNumIterations = 500; 78bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 79bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com// Helper class to run through all the performance tests using the specified 80bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com// proxy resolver implementation. 819df4d78e401f921b65012987f8d2049e9da5cef5robertphillips@google.comclass PacPerfSuiteRunner { 821c6d325f96b5b14e7b0c76680d6a15d6517d2eb6robertphillips@google.com public: 83ff0114918f0420778dfac164d810af08eadbac26reed@google.com // |resolver_name| is the label used when logging the results. 84ff0114918f0420778dfac164d810af08eadbac26reed@google.com PacPerfSuiteRunner(net::ProxyResolver* resolver, 85ff0114918f0420778dfac164d810af08eadbac26reed@google.com const std::string& resolver_name) 864c003748338174e594471cfe86ec1bcb53fda6fcreed@google.com : resolver_(resolver), 87935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com resolver_name_(resolver_name), 88ff0114918f0420778dfac164d810af08eadbac26reed@google.com test_server_(net::TestServer::TYPE_HTTP, 89bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com FilePath(FILE_PATH_LITERAL("net/data/proxy_resolver_perftest"))) { 90ff0114918f0420778dfac164d810af08eadbac26reed@google.com } 91bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 929df4d78e401f921b65012987f8d2049e9da5cef5robertphillips@google.com void RunAllTests() { 939df4d78e401f921b65012987f8d2049e9da5cef5robertphillips@google.com ASSERT_TRUE(test_server_.Start()); 949df4d78e401f921b65012987f8d2049e9da5cef5robertphillips@google.com for (size_t i = 0; i < arraysize(kPerfTests); ++i) { 959df4d78e401f921b65012987f8d2049e9da5cef5robertphillips@google.com const PacPerfTest& test_data = kPerfTests[i]; 969df4d78e401f921b65012987f8d2049e9da5cef5robertphillips@google.com RunTest(test_data.pac_name, 979df4d78e401f921b65012987f8d2049e9da5cef5robertphillips@google.com test_data.queries, 989df4d78e401f921b65012987f8d2049e9da5cef5robertphillips@google.com test_data.NumQueries()); 999df4d78e401f921b65012987f8d2049e9da5cef5robertphillips@google.com } 1009df4d78e401f921b65012987f8d2049e9da5cef5robertphillips@google.com } 1019df4d78e401f921b65012987f8d2049e9da5cef5robertphillips@google.com 1029df4d78e401f921b65012987f8d2049e9da5cef5robertphillips@google.com private: 1039df4d78e401f921b65012987f8d2049e9da5cef5robertphillips@google.com void RunTest(const std::string& script_name, 1049df4d78e401f921b65012987f8d2049e9da5cef5robertphillips@google.com const PacQuery* queries, 1059df4d78e401f921b65012987f8d2049e9da5cef5robertphillips@google.com int queries_len) { 1069df4d78e401f921b65012987f8d2049e9da5cef5robertphillips@google.com if (!resolver_->expects_pac_bytes()) { 107bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com GURL pac_url = 108bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com test_server_.GetURL(std::string("files/") + script_name); 109ff0114918f0420778dfac164d810af08eadbac26reed@google.com int rv = resolver_->SetPacScript( 110bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com net::ProxyResolverScriptData::FromURL(pac_url), NULL); 1119df4d78e401f921b65012987f8d2049e9da5cef5robertphillips@google.com EXPECT_EQ(net::OK, rv); 112ff0114918f0420778dfac164d810af08eadbac26reed@google.com } else { 113740de996d9e77a695864fdd8b89b4bd55f8d304asenorblanco@chromium.org LoadPacScriptIntoResolver(script_name); 1149df4d78e401f921b65012987f8d2049e9da5cef5robertphillips@google.com } 115bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 116bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com // Do a query to warm things up. In the case of internal-fetch proxy 117ff0114918f0420778dfac164d810af08eadbac26reed@google.com // resolvers, the first resolve will be slow since it has to download 118bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com // the PAC script. 119bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com { 120bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com net::ProxyInfo proxy_info; 121bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int result = resolver_->GetProxyForURL( 122bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com GURL("http://www.warmup.com"), &proxy_info, NULL, NULL, 123bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com net::BoundNetLog()); 124bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com ASSERT_EQ(net::OK, result); 1259df4d78e401f921b65012987f8d2049e9da5cef5robertphillips@google.com } 126bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 127740de996d9e77a695864fdd8b89b4bd55f8d304asenorblanco@chromium.org // Start the perf timer. 128bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com std::string perf_test_name = resolver_name_ + "_" + script_name; 129bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com PerfTimeLogger timer(perf_test_name.c_str()); 1309011c23655acf4186fca1789daee7e94fc0bbe61reed@google.com 131bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com for (int i = 0; i < kNumIterations; ++i) { 132bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com // Round-robin between URLs to resolve. 133bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com const PacQuery& query = queries[i % queries_len]; 134ff0114918f0420778dfac164d810af08eadbac26reed@google.com 1359011c23655acf4186fca1789daee7e94fc0bbe61reed@google.com // Resolve. 1369011c23655acf4186fca1789daee7e94fc0bbe61reed@google.com net::ProxyInfo proxy_info; 1379df4d78e401f921b65012987f8d2049e9da5cef5robertphillips@google.com int result = resolver_->GetProxyForURL(GURL(query.query_url), 138740de996d9e77a695864fdd8b89b4bd55f8d304asenorblanco@chromium.org &proxy_info, NULL, NULL, 139ff0114918f0420778dfac164d810af08eadbac26reed@google.com net::BoundNetLog()); 140935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com 141ff0114918f0420778dfac164d810af08eadbac26reed@google.com // Check that the result was correct. Note that ToPacString() and 142bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com // ASSERT_EQ() are fast, so they won't skew the results. 1439df4d78e401f921b65012987f8d2049e9da5cef5robertphillips@google.com ASSERT_EQ(net::OK, result); 1449df4d78e401f921b65012987f8d2049e9da5cef5robertphillips@google.com ASSERT_EQ(query.expected_result, proxy_info.ToPacString()); 145bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 146bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1478c2ce5e8666e05e662d8bfcb8aaf89cdb34c3a0ehumper@google.com // Print how long the test ran for. 1488c2ce5e8666e05e662d8bfcb8aaf89cdb34c3a0ehumper@google.com timer.Done(); 1498c2ce5e8666e05e662d8bfcb8aaf89cdb34c3a0ehumper@google.com } 1509df4d78e401f921b65012987f8d2049e9da5cef5robertphillips@google.com 1518c2ce5e8666e05e662d8bfcb8aaf89cdb34c3a0ehumper@google.com // Read the PAC script from disk and initialize the proxy resolver with it. 1529df4d78e401f921b65012987f8d2049e9da5cef5robertphillips@google.com void LoadPacScriptIntoResolver(const std::string& script_name) { 1538c2ce5e8666e05e662d8bfcb8aaf89cdb34c3a0ehumper@google.com FilePath path; 1548c2ce5e8666e05e662d8bfcb8aaf89cdb34c3a0ehumper@google.com PathService::Get(base::DIR_SOURCE_ROOT, &path); 1558c2ce5e8666e05e662d8bfcb8aaf89cdb34c3a0ehumper@google.com path = path.AppendASCII("net"); 1561e7ce9786525318f59d4c5a6efa6819c6ff9ab84reed@google.com path = path.AppendASCII("data"); 1571e7ce9786525318f59d4c5a6efa6819c6ff9ab84reed@google.com path = path.AppendASCII("proxy_resolver_perftest"); 158bb6529fbc4553260f434113a62a20af53c525649reed@google.com path = path.AppendASCII(script_name); 159bb6529fbc4553260f434113a62a20af53c525649reed@google.com 1601e7ce9786525318f59d4c5a6efa6819c6ff9ab84reed@google.com // Try to read the file from disk. 1611e7ce9786525318f59d4c5a6efa6819c6ff9ab84reed@google.com std::string file_contents; 1621e7ce9786525318f59d4c5a6efa6819c6ff9ab84reed@google.com bool ok = file_util::ReadFileToString(path, &file_contents); 1631e7ce9786525318f59d4c5a6efa6819c6ff9ab84reed@google.com 1641e7ce9786525318f59d4c5a6efa6819c6ff9ab84reed@google.com // If we can't load the file from disk, something is misconfigured. 1651e7ce9786525318f59d4c5a6efa6819c6ff9ab84reed@google.com LOG_IF(ERROR, !ok) << "Failed to read file: " << path.value(); 1661e7ce9786525318f59d4c5a6efa6819c6ff9ab84reed@google.com ASSERT_TRUE(ok); 1671e7ce9786525318f59d4c5a6efa6819c6ff9ab84reed@google.com 1681e7ce9786525318f59d4c5a6efa6819c6ff9ab84reed@google.com // Load the PAC script into the ProxyResolver. 1691e7ce9786525318f59d4c5a6efa6819c6ff9ab84reed@google.com int rv = resolver_->SetPacScript( 1701e7ce9786525318f59d4c5a6efa6819c6ff9ab84reed@google.com net::ProxyResolverScriptData::FromUTF8(file_contents), NULL); 1711e7ce9786525318f59d4c5a6efa6819c6ff9ab84reed@google.com EXPECT_EQ(net::OK, rv); 1721e7ce9786525318f59d4c5a6efa6819c6ff9ab84reed@google.com } 1731e7ce9786525318f59d4c5a6efa6819c6ff9ab84reed@google.com 1741e7ce9786525318f59d4c5a6efa6819c6ff9ab84reed@google.com net::ProxyResolver* resolver_; 1751e7ce9786525318f59d4c5a6efa6819c6ff9ab84reed@google.com std::string resolver_name_; 176bb6529fbc4553260f434113a62a20af53c525649reed@google.com net::TestServer test_server_; 177bb6529fbc4553260f434113a62a20af53c525649reed@google.com}; 1781e7ce9786525318f59d4c5a6efa6819c6ff9ab84reed@google.com 1791e7ce9786525318f59d4c5a6efa6819c6ff9ab84reed@google.com#if defined(OS_WIN) 1801e7ce9786525318f59d4c5a6efa6819c6ff9ab84reed@google.comTEST(ProxyResolverPerfTest, ProxyResolverWinHttp) { 1811e7ce9786525318f59d4c5a6efa6819c6ff9ab84reed@google.com net::ProxyResolverWinHttp resolver; 182bb6529fbc4553260f434113a62a20af53c525649reed@google.com PacPerfSuiteRunner runner(&resolver, "ProxyResolverWinHttp"); 183bb6529fbc4553260f434113a62a20af53c525649reed@google.com runner.RunAllTests(); 184bb6529fbc4553260f434113a62a20af53c525649reed@google.com} 185bb6529fbc4553260f434113a62a20af53c525649reed@google.com#elif defined(OS_MACOSX) 186bb6529fbc4553260f434113a62a20af53c525649reed@google.comTEST(ProxyResolverPerfTest, ProxyResolverMac) { 187bb6529fbc4553260f434113a62a20af53c525649reed@google.com net::ProxyResolverMac resolver; 188bb6529fbc4553260f434113a62a20af53c525649reed@google.com PacPerfSuiteRunner runner(&resolver, "ProxyResolverMac"); 189bb6529fbc4553260f434113a62a20af53c525649reed@google.com runner.RunAllTests(); 190bb6529fbc4553260f434113a62a20af53c525649reed@google.com} 191bb6529fbc4553260f434113a62a20af53c525649reed@google.com#endif 1921e7ce9786525318f59d4c5a6efa6819c6ff9ab84reed@google.com 1931e7ce9786525318f59d4c5a6efa6819c6ff9ab84reed@google.comTEST(ProxyResolverPerfTest, ProxyResolverV8) { 1941e7ce9786525318f59d4c5a6efa6819c6ff9ab84reed@google.com net::ProxyResolverJSBindings* js_bindings = 19536f4104a411facb6f8a7b4830e9235c2a1610265reed@google.com net::ProxyResolverJSBindings::CreateDefault( 19636f4104a411facb6f8a7b4830e9235c2a1610265reed@google.com new net::MockHostResolver, NULL); 19736f4104a411facb6f8a7b4830e9235c2a1610265reed@google.com 1980cd465fde832c0441cad1809ee7b18e50266e385reed@google.com net::ProxyResolverV8 resolver(js_bindings); 1990cd465fde832c0441cad1809ee7b18e50266e385reed@google.com PacPerfSuiteRunner runner(&resolver, "ProxyResolverV8"); 2008c2ce5e8666e05e662d8bfcb8aaf89cdb34c3a0ehumper@google.com runner.RunAllTests(); 2010cbcedc421fcbf653d1ceace58b14c07fed197a4humper@google.com} 2028c2ce5e8666e05e662d8bfcb8aaf89cdb34c3a0ehumper@google.com 2030cbcedc421fcbf653d1ceace58b14c07fed197a4humper@google.com