Update V8 to version 4.7.42.
[chromium-blink-merge.git] / net / proxy / proxy_resolver_perftest.cc
blob939018150bb0c17d8a6bab8158c749fe1e3d8562
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/base_paths.h"
6 #include "base/compiler_specific.h"
7 #include "base/files/file_util.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/path_service.h"
10 #include "base/strings/string_util.h"
11 #include "base/test/perf_time_logger.h"
12 #include "net/base/net_errors.h"
13 #include "net/dns/mock_host_resolver.h"
14 #include "net/proxy/proxy_info.h"
15 #include "net/proxy/proxy_resolver.h"
16 #include "net/proxy/proxy_resolver_factory.h"
17 #include "net/proxy/proxy_resolver_v8.h"
18 #include "net/test/spawned_test_server/spawned_test_server.h"
19 #include "testing/gtest/include/gtest/gtest.h"
21 #if defined(OS_WIN)
22 #include "net/proxy/proxy_resolver_winhttp.h"
23 #elif defined(OS_MACOSX)
24 #include "net/proxy/proxy_resolver_mac.h"
25 #endif
27 namespace net {
29 namespace {
31 // This class holds the URL to use for resolving, and the expected result.
32 // We track the expected result in order to make sure the performance
33 // test is actually resolving URLs properly, otherwise the perf numbers
34 // are meaningless :-)
35 struct PacQuery {
36 const char* query_url;
37 const char* expected_result;
40 // Entry listing which PAC scripts to load, and which URLs to try resolving.
41 // |queries| should be terminated by {NULL, NULL}. A sentinel is used
42 // rather than a length, to simplify using initializer lists.
43 struct PacPerfTest {
44 const char* pac_name;
45 PacQuery queries[100];
47 // Returns the actual number of entries in |queries| (assumes NULL sentinel).
48 int NumQueries() const;
51 // List of performance tests.
52 static PacPerfTest kPerfTests[] = {
53 // This test uses an ad-blocker PAC script. This script is very heavily
54 // regular expression oriented, and has no dependencies on the current
55 // IP address, or DNS resolving of hosts.
56 { "no-ads.pac",
57 { // queries:
58 {"http://www.google.com", "DIRECT"},
59 {"http://www.imdb.com/photos/cmsicons/x", "PROXY 0.0.0.0:3421"},
60 {"http://www.imdb.com/x", "DIRECT"},
61 {"http://www.staples.com/", "DIRECT"},
62 {"http://www.staples.com/pixeltracker/x", "PROXY 0.0.0.0:3421"},
63 {"http://www.staples.com/pixel/x", "DIRECT"},
64 {"http://www.foobar.com", "DIRECT"},
65 {"http://www.foobarbaz.com/x/y/z", "DIRECT"},
66 {"http://www.testurl1.com/index.html", "DIRECT"},
67 {"http://www.testurl2.com", "DIRECT"},
68 {"https://www.sample/pirate/arrrrrr", "DIRECT"},
69 {NULL, NULL}
74 int PacPerfTest::NumQueries() const {
75 for (size_t i = 0; i < arraysize(queries); ++i) {
76 if (queries[i].query_url == NULL)
77 return i;
79 NOTREACHED(); // Bad definition.
80 return 0;
83 // The number of URLs to resolve when testing a PAC script.
84 const int kNumIterations = 500;
86 // Helper class to run through all the performance tests using the specified
87 // proxy resolver implementation.
88 class PacPerfSuiteRunner {
89 public:
90 // |resolver_name| is the label used when logging the results.
91 PacPerfSuiteRunner(ProxyResolverFactory* factory,
92 const std::string& resolver_name)
93 : factory_(factory),
94 resolver_name_(resolver_name),
95 test_server_(SpawnedTestServer::TYPE_HTTP,
96 SpawnedTestServer::kLocalhost,
97 base::FilePath(FILE_PATH_LITERAL(
98 "net/data/proxy_resolver_perftest"))) {}
100 void RunAllTests() {
101 ASSERT_TRUE(test_server_.Start());
102 for (size_t i = 0; i < arraysize(kPerfTests); ++i) {
103 const PacPerfTest& test_data = kPerfTests[i];
104 RunTest(test_data.pac_name,
105 test_data.queries,
106 test_data.NumQueries());
110 private:
111 void RunTest(const std::string& script_name,
112 const PacQuery* queries,
113 int queries_len) {
114 scoped_ptr<ProxyResolver> resolver;
115 if (!factory_->expects_pac_bytes()) {
116 GURL pac_url =
117 test_server_.GetURL(std::string("files/") + script_name);
118 int rv = factory_->CreateProxyResolver(
119 ProxyResolverScriptData::FromURL(pac_url), &resolver,
120 CompletionCallback(), nullptr);
121 EXPECT_EQ(OK, rv);
122 } else {
123 resolver = LoadPacScriptAndCreateResolver(script_name);
125 ASSERT_TRUE(resolver);
127 // Do a query to warm things up. In the case of internal-fetch proxy
128 // resolvers, the first resolve will be slow since it has to download
129 // the PAC script.
131 ProxyInfo proxy_info;
132 int result =
133 resolver->GetProxyForURL(GURL("http://www.warmup.com"), &proxy_info,
134 CompletionCallback(), NULL, BoundNetLog());
135 ASSERT_EQ(OK, result);
138 // Start the perf timer.
139 std::string perf_test_name = resolver_name_ + "_" + script_name;
140 base::PerfTimeLogger timer(perf_test_name.c_str());
142 for (int i = 0; i < kNumIterations; ++i) {
143 // Round-robin between URLs to resolve.
144 const PacQuery& query = queries[i % queries_len];
146 // Resolve.
147 ProxyInfo proxy_info;
148 int result =
149 resolver->GetProxyForURL(GURL(query.query_url), &proxy_info,
150 CompletionCallback(), NULL, BoundNetLog());
152 // Check that the result was correct. Note that ToPacString() and
153 // ASSERT_EQ() are fast, so they won't skew the results.
154 ASSERT_EQ(OK, result);
155 ASSERT_EQ(query.expected_result, proxy_info.ToPacString());
158 // Print how long the test ran for.
159 timer.Done();
162 // Read the PAC script from disk and initialize the proxy resolver with it.
163 scoped_ptr<ProxyResolver> LoadPacScriptAndCreateResolver(
164 const std::string& script_name) {
165 base::FilePath path;
166 PathService::Get(base::DIR_SOURCE_ROOT, &path);
167 path = path.AppendASCII("net");
168 path = path.AppendASCII("data");
169 path = path.AppendASCII("proxy_resolver_perftest");
170 path = path.AppendASCII(script_name);
172 // Try to read the file from disk.
173 std::string file_contents;
174 bool ok = base::ReadFileToString(path, &file_contents);
176 // If we can't load the file from disk, something is misconfigured.
177 LOG_IF(ERROR, !ok) << "Failed to read file: " << path.value();
178 if (!ok)
179 return nullptr;
181 // Load the PAC script into the ProxyResolver.
182 scoped_ptr<ProxyResolver> resolver;
183 int rv = factory_->CreateProxyResolver(
184 ProxyResolverScriptData::FromUTF8(file_contents), &resolver,
185 CompletionCallback(), nullptr);
186 EXPECT_EQ(OK, rv);
187 return resolver;
190 ProxyResolverFactory* factory_;
191 std::string resolver_name_;
192 SpawnedTestServer test_server_;
195 #if defined(OS_WIN)
196 TEST(ProxyResolverPerfTest, ProxyResolverWinHttp) {
197 ProxyResolverFactoryWinHttp factory;
198 PacPerfSuiteRunner runner(&factory, "ProxyResolverWinHttp");
199 runner.RunAllTests();
201 #elif defined(OS_MACOSX)
202 TEST(ProxyResolverPerfTest, ProxyResolverMac) {
203 ProxyResolverFactoryMac factory;
204 PacPerfSuiteRunner runner(&factory, "ProxyResolverMac");
205 runner.RunAllTests();
207 #endif
209 class MockJSBindings : public ProxyResolverV8::JSBindings {
210 public:
211 MockJSBindings() {}
213 void Alert(const base::string16& message) override { CHECK(false); }
215 bool ResolveDns(const std::string& host,
216 ResolveDnsOperation op,
217 std::string* output,
218 bool* terminate) override {
219 CHECK(false);
220 return false;
223 void OnError(int line_number, const base::string16& message) override {
224 CHECK(false);
228 class ProxyResolverV8Wrapper : public ProxyResolver {
229 public:
230 ProxyResolverV8Wrapper(scoped_ptr<ProxyResolverV8> resolver,
231 scoped_ptr<MockJSBindings> bindings)
232 : resolver_(resolver.Pass()), bindings_(bindings.Pass()) {}
234 int GetProxyForURL(const GURL& url,
235 ProxyInfo* results,
236 const CompletionCallback& /*callback*/,
237 RequestHandle* /*request*/,
238 const BoundNetLog& net_log) override {
239 return resolver_->GetProxyForURL(url, results, bindings_.get());
242 void CancelRequest(RequestHandle request) override { NOTREACHED(); }
244 LoadState GetLoadState(RequestHandle request) const override {
245 NOTREACHED();
246 return LOAD_STATE_IDLE;
249 private:
250 scoped_ptr<ProxyResolverV8> resolver_;
251 scoped_ptr<MockJSBindings> bindings_;
253 DISALLOW_COPY_AND_ASSIGN(ProxyResolverV8Wrapper);
256 class ProxyResolverV8Factory : public ProxyResolverFactory {
257 public:
258 ProxyResolverV8Factory() : ProxyResolverFactory(true) {}
259 int CreateProxyResolver(
260 const scoped_refptr<ProxyResolverScriptData>& pac_script,
261 scoped_ptr<ProxyResolver>* resolver,
262 const net::CompletionCallback& callback,
263 scoped_ptr<Request>* request) override {
264 scoped_ptr<ProxyResolverV8> v8_resolver;
265 scoped_ptr<MockJSBindings> js_bindings_(new MockJSBindings);
266 int result =
267 ProxyResolverV8::Create(pac_script, js_bindings_.get(), &v8_resolver);
268 if (result == OK) {
269 resolver->reset(
270 new ProxyResolverV8Wrapper(v8_resolver.Pass(), js_bindings_.Pass()));
272 return result;
275 private:
276 DISALLOW_COPY_AND_ASSIGN(ProxyResolverV8Factory);
279 TEST(ProxyResolverPerfTest, ProxyResolverV8) {
280 base::MessageLoop message_loop;
281 ProxyResolverV8Factory factory;
282 PacPerfSuiteRunner runner(&factory, "ProxyResolverV8");
283 runner.RunAllTests();
286 } // namespace
288 } // namespace net