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.
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
15 class ChromeProxyLatency(page_test.PageTest):
16 """Chrome proxy latency measurement."""
18 def __init__(self, *args, **kwargs):
19 super(ChromeProxyLatency, self).__init__(*args, **kwargs)
21 def WillNavigateToPage(self, page, tab):
22 tab.ClearCache(force=True)
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)
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()
36 def WillNavigateToPage(self, page, tab):
37 tab.ClearCache(force=True)
38 self._metrics.Start(page, tab)
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)
47 class ChromeProxyValidation(page_test.PageTest):
48 """Base class for all chrome proxy correctness measurements."""
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()
55 # Whether a timeout exception is expected during the test.
56 self._expect_timeout = False
58 def CustomizeBrowserOptions(self, options):
59 # Enable the chrome proxy (data reduction proxy).
60 options.AppendExtraBrowserArgs('--enable-spdy-proxy-auth')
62 def WillNavigateToPage(self, page, tab):
63 tab.ClearCache(force=True)
65 self._metrics.Start(page, tab)
67 def ValidateAndMeasurePage(self, page, tab, results):
69 # Wait for the load event.
70 tab.WaitForJavaScriptExpression('performance.timing.loadEventStart', 300)
72 self._metrics.Stop(page, tab)
73 self.AddResults(tab, results)
75 def AddResults(self, tab, results):
76 raise NotImplementedError
78 def StopBrowserAfterPage(self, browser, page): # pylint: disable=W0613
79 if hasattr(page, 'restart_after') and page.restart_after:
83 def RunNavigateSteps(self, page, tab):
84 # The redirect from safebrowsing causes a timeout. Ignore that.
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)
95 class ChromeProxyHeaders(ChromeProxyValidation):
96 """Correctness measurement for response headers."""
99 super(ChromeProxyHeaders, self).__init__(restart_after_each_page=True)
101 def AddResults(self, tab, results):
102 self._metrics.AddResultsForHeaderValidation(tab, results)
105 class ChromeProxyBypass(ChromeProxyValidation):
106 """Correctness measurement for bypass responses."""
109 super(ChromeProxyBypass, self).__init__(restart_after_each_page=True)
111 def AddResults(self, tab, results):
112 self._metrics.AddResultsForBypass(tab, results)
115 class ChromeProxySafebrowsing(ChromeProxyValidation):
116 """Correctness measurement for safebrowsing."""
119 super(ChromeProxySafebrowsing, self).__init__()
121 def WillNavigateToPage(self, page, tab):
122 super(ChromeProxySafebrowsing, self).WillNavigateToPage(page, tab)
123 self._expect_timeout = True
125 def AddResults(self, tab, results):
126 self._metrics.AddResultsForSafebrowsing(tab, results)
129 _FAKE_PROXY_AUTH_VALUE = 'aabbccdd3b7579186c1b0620614fdb1f0000ffff'
130 _TEST_SERVER = 'chromeproxy-test.appspot.com'
131 _TEST_SERVER_DEFAULT_URL = 'http://' + _TEST_SERVER + '/default'
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
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.
146 queries.append('respStatus=%d' % respStatus)
148 queries.append('respHeader=%s' % base64.b64encode(respHeader))
150 queries.append('respBody=%s' % base64.b64encode(respBody))
151 if len(queries) == 0:
154 # url has query already
155 if urlparse.urlparse(url).query:
156 return url + '&' + "&".join(queries)
158 return url + '?' + "&".join(queries)
161 class ChromeProxyHTTPFallbackProbeURL(ChromeProxyValidation):
162 """Correctness measurement for proxy fallback.
164 In this test, the probe URL does not return 'OK'. Chrome is expected
165 to use the fallback proxy.
169 super(ChromeProxyHTTPFallbackProbeURL, self).__init__()
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,
179 options.AppendExtraBrowserArgs(
180 '--data-reduction-proxy-probe-url=%s' % probe_url)
182 def AddResults(self, tab, results):
183 self._metrics.AddResultsForHTTPFallback(tab, results)
186 # Depends on the fix of http://crbug.com/330342.
187 class ChromeProxyHTTPFallbackViaHeader(ChromeProxyValidation):
188 """Correctness measurement for proxy fallback.
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
197 super(ChromeProxyHTTPFallbackViaHeader, self).__init__()
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)
208 def AddResults(self, tab, results):
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)
217 class ChromeProxyClientVersion(ChromeProxyValidation):
218 """Correctness measurement for version directives in Chrome-Proxy header.
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
226 super(ChromeProxyClientVersion, self).__init__()
228 def CustomizeBrowserOptions(self, options):
229 super(ChromeProxyClientVersion,
230 self).CustomizeBrowserOptions(options)
231 options.AppendExtraBrowserArgs('--user-agent="Chrome/32.0.1700.99"')
233 def AddResults(self, tab, results):
234 self._metrics.AddResultsForClientVersion(tab, results)
237 class ChromeProxySmoke(ChromeProxyValidation):
238 """Smoke measurement for basic chrome proxy correctness."""
241 super(ChromeProxySmoke, self).__init__()
243 def WillNavigateToPage(self, page, tab):
244 super(ChromeProxySmoke, self).WillNavigateToPage(page, tab)
245 if page.name == 'safebrowsing':
246 self._expect_timeout = True
248 def AddResults(self, tab, results):
249 # Map a page name to its AddResults func.
251 'header validation': [self._metrics.AddResultsForHeaderValidation],
252 'compression: image': [
253 self._metrics.AddResultsForHeaderValidation,
254 self._metrics.AddResultsForDataSaving,
256 'compression: javascript': [
257 self._metrics.AddResultsForHeaderValidation,
258 self._metrics.AddResultsForDataSaving,
260 'compression: css': [
261 self._metrics.AddResultsForHeaderValidation,
262 self._metrics.AddResultsForDataSaving,
264 'bypass': [self._metrics.AddResultsForBypass],
265 'safebrowsing': [self._metrics.AddResultsForSafebrowsing],
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)