OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "base/base_paths.h" | |
6 #include "base/compiler_specific.h" | |
7 #include "base/files/file_util.h" | |
8 #include "base/path_service.h" | |
9 #include "base/strings/string_util.h" | |
10 #include "base/test/perf_time_logger.h" | |
11 #include "net/base/net_errors.h" | |
12 #include "net/dns/mock_host_resolver.h" | |
13 #include "net/proxy/proxy_info.h" | |
14 #include "net/proxy/proxy_resolver_v8.h" | |
15 #include "net/test/spawned_test_server/spawned_test_server.h" | |
16 #include "testing/gtest/include/gtest/gtest.h" | |
17 | |
18 #if defined(OS_WIN) | |
19 #include "net/proxy/proxy_resolver_winhttp.h" | |
20 #elif defined(OS_MACOSX) | |
21 #include "net/proxy/proxy_resolver_mac.h" | |
22 #endif | |
23 | |
24 // This class holds the URL to use for resolving, and the expected result. | |
25 // We track the expected result in order to make sure the performance | |
26 // test is actually resolving URLs properly, otherwise the perf numbers | |
27 // are meaningless :-) | |
28 struct PacQuery { | |
29 const char* query_url; | |
30 const char* expected_result; | |
31 }; | |
32 | |
33 // Entry listing which PAC scripts to load, and which URLs to try resolving. | |
34 // |queries| should be terminated by {NULL, NULL}. A sentinel is used | |
35 // rather than a length, to simplify using initializer lists. | |
36 struct PacPerfTest { | |
37 const char* pac_name; | |
38 PacQuery queries[100]; | |
39 | |
40 // Returns the actual number of entries in |queries| (assumes NULL sentinel). | |
41 int NumQueries() const; | |
42 }; | |
43 | |
44 // List of performance tests. | |
45 static PacPerfTest kPerfTests[] = { | |
46 // This test uses an ad-blocker PAC script. This script is very heavily | |
47 // regular expression oriented, and has no dependencies on the current | |
48 // IP address, or DNS resolving of hosts. | |
49 { "no-ads.pac", | |
50 { // queries: | |
51 {"http://www.google.com", "DIRECT"}, | |
52 {"http://www.imdb.com/photos/cmsicons/x", "PROXY 0.0.0.0:3421"}, | |
53 {"http://www.imdb.com/x", "DIRECT"}, | |
54 {"http://www.staples.com/", "DIRECT"}, | |
55 {"http://www.staples.com/pixeltracker/x", "PROXY 0.0.0.0:3421"}, | |
56 {"http://www.staples.com/pixel/x", "DIRECT"}, | |
57 {"http://www.foobar.com", "DIRECT"}, | |
58 {"http://www.foobarbaz.com/x/y/z", "DIRECT"}, | |
59 {"http://www.testurl1.com/index.html", "DIRECT"}, | |
60 {"http://www.testurl2.com", "DIRECT"}, | |
61 {"https://www.sample/pirate/arrrrrr", "DIRECT"}, | |
62 {NULL, NULL} | |
63 }, | |
64 }, | |
65 }; | |
66 | |
67 int PacPerfTest::NumQueries() const { | |
68 for (size_t i = 0; i < arraysize(queries); ++i) { | |
69 if (queries[i].query_url == NULL) | |
70 return i; | |
71 } | |
72 NOTREACHED(); // Bad definition. | |
73 return 0; | |
74 } | |
75 | |
76 // The number of URLs to resolve when testing a PAC script. | |
77 const int kNumIterations = 500; | |
78 | |
79 // Helper class to run through all the performance tests using the specified | |
80 // proxy resolver implementation. | |
81 class PacPerfSuiteRunner { | |
82 public: | |
83 // |resolver_name| is the label used when logging the results. | |
84 PacPerfSuiteRunner(net::ProxyResolver* resolver, | |
85 const std::string& resolver_name) | |
86 : resolver_(resolver), | |
87 resolver_name_(resolver_name), | |
88 test_server_( | |
89 net::SpawnedTestServer::TYPE_HTTP, | |
90 net::SpawnedTestServer::kLocalhost, | |
91 base::FilePath( | |
92 FILE_PATH_LITERAL("net/data/proxy_resolver_perftest"))) { | |
93 } | |
94 | |
95 void RunAllTests() { | |
96 ASSERT_TRUE(test_server_.Start()); | |
97 for (size_t i = 0; i < arraysize(kPerfTests); ++i) { | |
98 const PacPerfTest& test_data = kPerfTests[i]; | |
99 RunTest(test_data.pac_name, | |
100 test_data.queries, | |
101 test_data.NumQueries()); | |
102 } | |
103 } | |
104 | |
105 private: | |
106 void RunTest(const std::string& script_name, | |
107 const PacQuery* queries, | |
108 int queries_len) { | |
109 if (!resolver_->expects_pac_bytes()) { | |
110 GURL pac_url = | |
111 test_server_.GetURL(std::string("files/") + script_name); | |
112 int rv = resolver_->SetPacScript( | |
113 net::ProxyResolverScriptData::FromURL(pac_url), | |
114 net::CompletionCallback()); | |
115 EXPECT_EQ(net::OK, rv); | |
116 } else { | |
117 LoadPacScriptIntoResolver(script_name); | |
118 } | |
119 | |
120 // Do a query to warm things up. In the case of internal-fetch proxy | |
121 // resolvers, the first resolve will be slow since it has to download | |
122 // the PAC script. | |
123 { | |
124 net::ProxyInfo proxy_info; | |
125 int result = resolver_->GetProxyForURL( | |
126 GURL("http://www.warmup.com"), &proxy_info, net::CompletionCallback(), | |
127 NULL, net::BoundNetLog()); | |
128 ASSERT_EQ(net::OK, result); | |
129 } | |
130 | |
131 // Start the perf timer. | |
132 std::string perf_test_name = resolver_name_ + "_" + script_name; | |
133 base::PerfTimeLogger timer(perf_test_name.c_str()); | |
134 | |
135 for (int i = 0; i < kNumIterations; ++i) { | |
136 // Round-robin between URLs to resolve. | |
137 const PacQuery& query = queries[i % queries_len]; | |
138 | |
139 // Resolve. | |
140 net::ProxyInfo proxy_info; | |
141 int result = resolver_->GetProxyForURL( | |
142 GURL(query.query_url), &proxy_info, net::CompletionCallback(), NULL, | |
143 net::BoundNetLog()); | |
144 | |
145 // Check that the result was correct. Note that ToPacString() and | |
146 // ASSERT_EQ() are fast, so they won't skew the results. | |
147 ASSERT_EQ(net::OK, result); | |
148 ASSERT_EQ(query.expected_result, proxy_info.ToPacString()); | |
149 } | |
150 | |
151 // Print how long the test ran for. | |
152 timer.Done(); | |
153 } | |
154 | |
155 // Read the PAC script from disk and initialize the proxy resolver with it. | |
156 void LoadPacScriptIntoResolver(const std::string& script_name) { | |
157 base::FilePath path; | |
158 PathService::Get(base::DIR_SOURCE_ROOT, &path); | |
159 path = path.AppendASCII("net"); | |
160 path = path.AppendASCII("data"); | |
161 path = path.AppendASCII("proxy_resolver_perftest"); | |
162 path = path.AppendASCII(script_name); | |
163 | |
164 // Try to read the file from disk. | |
165 std::string file_contents; | |
166 bool ok = base::ReadFileToString(path, &file_contents); | |
167 | |
168 // If we can't load the file from disk, something is misconfigured. | |
169 LOG_IF(ERROR, !ok) << "Failed to read file: " << path.value(); | |
170 ASSERT_TRUE(ok); | |
171 | |
172 // Load the PAC script into the ProxyResolver. | |
173 int rv = resolver_->SetPacScript( | |
174 net::ProxyResolverScriptData::FromUTF8(file_contents), | |
175 net::CompletionCallback()); | |
176 EXPECT_EQ(net::OK, rv); | |
177 } | |
178 | |
179 net::ProxyResolver* resolver_; | |
180 std::string resolver_name_; | |
181 net::SpawnedTestServer test_server_; | |
182 }; | |
183 | |
184 #if defined(OS_WIN) | |
185 TEST(ProxyResolverPerfTest, ProxyResolverWinHttp) { | |
186 net::ProxyResolverWinHttp resolver; | |
187 PacPerfSuiteRunner runner(&resolver, "ProxyResolverWinHttp"); | |
188 runner.RunAllTests(); | |
189 } | |
190 #elif defined(OS_MACOSX) | |
191 TEST(ProxyResolverPerfTest, ProxyResolverMac) { | |
192 net::ProxyResolverMac resolver; | |
193 PacPerfSuiteRunner runner(&resolver, "ProxyResolverMac"); | |
194 runner.RunAllTests(); | |
195 } | |
196 #endif | |
197 | |
198 class MockJSBindings : public net::ProxyResolverV8::JSBindings { | |
199 public: | |
200 MockJSBindings() {} | |
201 | |
202 void Alert(const base::string16& message) override { CHECK(false); } | |
203 | |
204 bool ResolveDns(const std::string& host, | |
205 ResolveDnsOperation op, | |
206 std::string* output, | |
207 bool* terminate) override { | |
208 CHECK(false); | |
209 return false; | |
210 } | |
211 | |
212 void OnError(int line_number, const base::string16& message) override { | |
213 CHECK(false); | |
214 } | |
215 }; | |
216 | |
217 TEST(ProxyResolverPerfTest, ProxyResolverV8) { | |
218 net::ProxyResolverV8::EnsureIsolateCreated(); | |
219 | |
220 MockJSBindings js_bindings; | |
221 net::ProxyResolverV8 resolver; | |
222 resolver.set_js_bindings(&js_bindings); | |
223 PacPerfSuiteRunner runner(&resolver, "ProxyResolverV8"); | |
224 runner.RunAllTests(); | |
225 } | |
OLD | NEW |