Upstream version 10.38.220.0
[platform/framework/web/crosswalk.git] / src / tools / chrome_proxy / integration_tests / chrome_proxy_measurements.py
1 # Copyright 2014 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 import base64
6 import logging
7 import urlparse
8
9 from integration_tests import chrome_proxy_metrics as metrics
10 from metrics import loading
11 from telemetry.core import util
12 from telemetry.page import page_test
13
14
15 class ChromeProxyLatency(page_test.PageTest):
16   """Chrome proxy latency measurement."""
17
18   def __init__(self, *args, **kwargs):
19     super(ChromeProxyLatency, self).__init__(*args, **kwargs)
20
21   def WillNavigateToPage(self, page, tab):
22     tab.ClearCache(force=True)
23
24   def ValidateAndMeasurePage(self, page, tab, results):
25     # Wait for the load event.
26     tab.WaitForJavaScriptExpression('performance.timing.loadEventStart', 300)
27     loading.LoadingMetric().AddResults(tab, results)
28
29
30 class ChromeProxyDataSaving(page_test.PageTest):
31   """Chrome proxy data daving measurement."""
32   def __init__(self, *args, **kwargs):
33     super(ChromeProxyDataSaving, self).__init__(*args, **kwargs)
34     self._metrics = metrics.ChromeProxyMetric()
35
36   def WillNavigateToPage(self, page, tab):
37     tab.ClearCache(force=True)
38     self._metrics.Start(page, tab)
39
40   def ValidateAndMeasurePage(self, page, tab, results):
41     # Wait for the load event.
42     tab.WaitForJavaScriptExpression('performance.timing.loadEventStart', 300)
43     self._metrics.Stop(page, tab)
44     self._metrics.AddResultsForDataSaving(tab, results)
45
46
47 class ChromeProxyValidation(page_test.PageTest):
48   """Base class for all chrome proxy correctness measurements."""
49
50   def __init__(self, restart_after_each_page=False):
51     super(ChromeProxyValidation, self).__init__(
52         needs_browser_restart_after_each_page=restart_after_each_page)
53     self._metrics = metrics.ChromeProxyMetric()
54     self._page = None
55     # Whether a timeout exception is expected during the test.
56     self._expect_timeout = False
57
58   def CustomizeBrowserOptions(self, options):
59     # Enable the chrome proxy (data reduction proxy).
60     options.AppendExtraBrowserArgs('--enable-spdy-proxy-auth')
61
62   def WillNavigateToPage(self, page, tab):
63     tab.ClearCache(force=True)
64     assert self._metrics
65     self._metrics.Start(page, tab)
66
67   def ValidateAndMeasurePage(self, page, tab, results):
68     self._page = page
69     # Wait for the load event.
70     tab.WaitForJavaScriptExpression('performance.timing.loadEventStart', 300)
71     assert self._metrics
72     self._metrics.Stop(page, tab)
73     self.AddResults(tab, results)
74
75   def AddResults(self, tab, results):
76     raise NotImplementedError
77
78   def StopBrowserAfterPage(self, browser, page):  # pylint: disable=W0613
79     if hasattr(page, 'restart_after') and page.restart_after:
80       return True
81     return False
82
83   def RunNavigateSteps(self, page, tab):
84     # The redirect from safebrowsing causes a timeout. Ignore that.
85     try:
86       super(ChromeProxyValidation, self).RunNavigateSteps(page, tab)
87     except util.TimeoutException, e:
88       if self._expect_timeout:
89         logging.warning('Navigation timeout on page %s',
90                         page.name if page.name else page.url)
91       else:
92         raise e
93
94
95 class ChromeProxyHeaders(ChromeProxyValidation):
96   """Correctness measurement for response headers."""
97
98   def __init__(self):
99     super(ChromeProxyHeaders, self).__init__(restart_after_each_page=True)
100
101   def AddResults(self, tab, results):
102     self._metrics.AddResultsForHeaderValidation(tab, results)
103
104
105 class ChromeProxyBypass(ChromeProxyValidation):
106   """Correctness measurement for bypass responses."""
107
108   def __init__(self):
109     super(ChromeProxyBypass, self).__init__(restart_after_each_page=True)
110
111   def AddResults(self, tab, results):
112     self._metrics.AddResultsForBypass(tab, results)
113
114
115 class ChromeProxySafebrowsing(ChromeProxyValidation):
116   """Correctness measurement for safebrowsing."""
117
118   def __init__(self):
119     super(ChromeProxySafebrowsing, self).__init__()
120
121   def WillNavigateToPage(self, page, tab):
122     super(ChromeProxySafebrowsing, self).WillNavigateToPage(page, tab)
123     self._expect_timeout = True
124
125   def AddResults(self, tab, results):
126     self._metrics.AddResultsForSafebrowsing(tab, results)
127
128
129 _FAKE_PROXY_AUTH_VALUE = 'aabbccdd3b7579186c1b0620614fdb1f0000ffff'
130 _TEST_SERVER = 'chromeproxy-test.appspot.com'
131 _TEST_SERVER_DEFAULT_URL = 'http://' + _TEST_SERVER + '/default'
132
133
134 # We rely on the chromeproxy-test server to facilitate some of the tests.
135 # The test server code is at <TBD location> and runs at _TEST_SERVER
136 #
137 # The test server allow request to override response status, headers, and
138 # body through query parameters. See GetResponseOverrideURL.
139 def GetResponseOverrideURL(url, respStatus=0, respHeader="", respBody=""):
140   """ Compose the request URL with query parameters to override
141   the chromeproxy-test server response.
142   """
143
144   queries = []
145   if respStatus > 0:
146     queries.append('respStatus=%d' % respStatus)
147   if respHeader:
148     queries.append('respHeader=%s' % base64.b64encode(respHeader))
149   if respBody:
150     queries.append('respBody=%s' % base64.b64encode(respBody))
151   if len(queries) == 0:
152     return url
153   "&".join(queries)
154   # url has query already
155   if urlparse.urlparse(url).query:
156     return url + '&' + "&".join(queries)
157   else:
158     return url + '?' + "&".join(queries)
159
160
161 class ChromeProxyHTTPFallbackProbeURL(ChromeProxyValidation):
162   """Correctness measurement for proxy fallback.
163
164   In this test, the probe URL does not return 'OK'. Chrome is expected
165   to use the fallback proxy.
166   """
167
168   def __init__(self):
169     super(ChromeProxyHTTPFallbackProbeURL, self).__init__()
170
171   def CustomizeBrowserOptions(self, options):
172     super(ChromeProxyHTTPFallbackProbeURL,
173           self).CustomizeBrowserOptions(options)
174     # Use the test server probe URL which returns the response
175     # body as specified by respBody.
176     probe_url = GetResponseOverrideURL(
177         _TEST_SERVER_DEFAULT_URL,
178         respBody='not OK')
179     options.AppendExtraBrowserArgs(
180         '--data-reduction-proxy-probe-url=%s' % probe_url)
181
182   def AddResults(self, tab, results):
183     self._metrics.AddResultsForHTTPFallback(tab, results)
184
185
186 # Depends on the fix of http://crbug.com/330342.
187 class ChromeProxyHTTPFallbackViaHeader(ChromeProxyValidation):
188   """Correctness measurement for proxy fallback.
189
190   In this test, the configured proxy is the chromeproxy-test server which
191   will send back a response without the expected Via header. Chrome is
192   expected to use the fallback proxy and add the configured proxy to the
193   bad proxy list.
194   """
195
196   def __init__(self):
197     super(ChromeProxyHTTPFallbackViaHeader, self).__init__()
198
199   def CustomizeBrowserOptions(self, options):
200     super(ChromeProxyHTTPFallbackViaHeader,
201           self).CustomizeBrowserOptions(options)
202     options.AppendExtraBrowserArgs('--ignore-certificate-errors')
203     options.AppendExtraBrowserArgs(
204         '--spdy-proxy-auth-origin=http://%s' % _TEST_SERVER)
205     options.AppendExtraBrowserArgs(
206         '--spdy-proxy-auth-value=%s' % _FAKE_PROXY_AUTH_VALUE)
207
208   def AddResults(self, tab, results):
209     proxies = [
210         _TEST_SERVER + ":80",
211         self._metrics.effective_proxies['fallback'],
212         self._metrics.effective_proxies['direct']]
213     bad_proxies = [_TEST_SERVER + ":80"]
214     self._metrics.AddResultsForHTTPFallback(tab, results, proxies, bad_proxies)
215
216
217 class ChromeProxyClientVersion(ChromeProxyValidation):
218   """Correctness measurement for version directives in Chrome-Proxy header.
219
220   The test verifies that the version information provided in the Chrome-Proxy
221   request header overrides any version, if specified, that is provided in the
222   user agent string.
223   """
224
225   def __init__(self):
226     super(ChromeProxyClientVersion, self).__init__()
227
228   def CustomizeBrowserOptions(self, options):
229     super(ChromeProxyClientVersion,
230           self).CustomizeBrowserOptions(options)
231     options.AppendExtraBrowserArgs('--user-agent="Chrome/32.0.1700.99"')
232
233   def AddResults(self, tab, results):
234     self._metrics.AddResultsForClientVersion(tab, results)
235
236
237 class ChromeProxySmoke(ChromeProxyValidation):
238   """Smoke measurement for basic chrome proxy correctness."""
239
240   def __init__(self):
241     super(ChromeProxySmoke, self).__init__()
242
243   def WillNavigateToPage(self, page, tab):
244     super(ChromeProxySmoke, self).WillNavigateToPage(page, tab)
245     if page.name == 'safebrowsing':
246       self._expect_timeout = True
247
248   def AddResults(self, tab, results):
249     # Map a page name to its AddResults func.
250     page_to_metrics = {
251         'header validation': [self._metrics.AddResultsForHeaderValidation],
252         'compression: image': [
253             self._metrics.AddResultsForHeaderValidation,
254             self._metrics.AddResultsForDataSaving,
255             ],
256         'compression: javascript': [
257             self._metrics.AddResultsForHeaderValidation,
258             self._metrics.AddResultsForDataSaving,
259             ],
260         'compression: css': [
261             self._metrics.AddResultsForHeaderValidation,
262             self._metrics.AddResultsForDataSaving,
263             ],
264         'bypass': [self._metrics.AddResultsForBypass],
265         'safebrowsing': [self._metrics.AddResultsForSafebrowsing],
266         }
267     if not self._page.name in page_to_metrics:
268       raise page_test.MeasurementFailure(
269           'Invalid page name (%s) in smoke. Page name must be one of:\n%s' % (
270           self._page.name, page_to_metrics.keys()))
271     for add_result in page_to_metrics[self._page.name]:
272       add_result(tab, results)