- add sources.
[platform/framework/web/crosswalk.git] / src / net / proxy / proxy_resolver_perftest.cc
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/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   virtual void Alert(const base::string16& message) OVERRIDE {
203     CHECK(false);
204   }
205
206   virtual bool ResolveDns(const std::string& host,
207                           ResolveDnsOperation op,
208                           std::string* output,
209                           bool* terminate) OVERRIDE {
210     CHECK(false);
211     return false;
212   }
213
214   virtual void OnError(int line_number,
215                        const base::string16& message) OVERRIDE {
216     CHECK(false);
217   }
218 };
219
220 TEST(ProxyResolverPerfTest, ProxyResolverV8) {
221   // This has to be done on the main thread.
222   net::ProxyResolverV8::RememberDefaultIsolate();
223
224   MockJSBindings js_bindings;
225   net::ProxyResolverV8 resolver;
226   resolver.set_js_bindings(&js_bindings);
227   PacPerfSuiteRunner runner(&resolver, "ProxyResolverV8");
228   runner.RunAllTests();
229 }