ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / tools / chrome_proxy / integration_tests / chrome_proxy_measurements.py
blob0261b14c45b891224ad341a0fb191f17d6ef25f2
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.
5 import base64
6 import logging
7 import urlparse
9 from integration_tests import chrome_proxy_metrics as metrics
10 from metrics import loading
11 from telemetry.core import exceptions
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 CustomizeBrowserOptions(self, options):
22 options.AppendExtraBrowserArgs('--enable-spdy-proxy-auth')
24 def WillNavigateToPage(self, page, tab):
25 tab.ClearCache(force=True)
27 def ValidateAndMeasurePage(self, page, tab, results):
28 # Wait for the load event.
29 tab.WaitForJavaScriptExpression('performance.timing.loadEventStart', 300)
30 loading.LoadingMetric().AddResults(tab, results)
33 class ChromeProxyDataSaving(page_test.PageTest):
34 """Chrome proxy data saving measurement."""
35 def __init__(self, *args, **kwargs):
36 super(ChromeProxyDataSaving, self).__init__(*args, **kwargs)
37 self._metrics = metrics.ChromeProxyMetric()
39 def CustomizeBrowserOptions(self, options):
40 options.AppendExtraBrowserArgs('--enable-spdy-proxy-auth')
42 def WillNavigateToPage(self, page, tab):
43 tab.ClearCache(force=True)
44 self._metrics.Start(page, tab)
46 def ValidateAndMeasurePage(self, page, tab, results):
47 # Wait for the load event.
48 tab.WaitForJavaScriptExpression('performance.timing.loadEventStart', 300)
49 self._metrics.Stop(page, tab)
50 self._metrics.AddResultsForDataSaving(tab, results)
53 class ChromeProxyValidation(page_test.PageTest):
54 """Base class for all chrome proxy correctness measurements."""
56 def __init__(self, restart_after_each_page=False):
57 super(ChromeProxyValidation, self).__init__(
58 needs_browser_restart_after_each_page=restart_after_each_page)
59 self._metrics = metrics.ChromeProxyMetric()
60 self._page = None
61 # Whether a timeout exception is expected during the test.
62 self._expect_timeout = False
64 def CustomizeBrowserOptions(self, options):
65 # Enable the chrome proxy (data reduction proxy).
66 options.AppendExtraBrowserArgs('--enable-spdy-proxy-auth')
68 def WillNavigateToPage(self, page, tab):
69 tab.ClearCache(force=True)
70 assert self._metrics
71 self._metrics.Start(page, tab)
73 def ValidateAndMeasurePage(self, page, tab, results):
74 self._page = page
75 # Wait for the load event.
76 tab.WaitForJavaScriptExpression('performance.timing.loadEventStart', 300)
77 assert self._metrics
78 self._metrics.Stop(page, tab)
79 self.AddResults(tab, results)
81 def AddResults(self, tab, results):
82 raise NotImplementedError
84 def StopBrowserAfterPage(self, browser, page): # pylint: disable=W0613
85 if hasattr(page, 'restart_after') and page.restart_after:
86 return True
87 return False
89 def RunNavigateSteps(self, page, tab):
90 # The redirect from safebrowsing causes a timeout. Ignore that.
91 try:
92 super(ChromeProxyValidation, self).RunNavigateSteps(page, tab)
93 if self._expect_timeout:
94 raise metrics.ChromeProxyMetricException, (
95 'Timeout was expected, but did not occur')
96 except exceptions.DevtoolsTargetCrashException, e:
97 if self._expect_timeout:
98 logging.warning('Navigation timeout on page %s',
99 page.name if page.name else page.url)
100 else:
101 raise e
104 class ChromeProxyHeaders(ChromeProxyValidation):
105 """Correctness measurement for response headers."""
107 def __init__(self):
108 super(ChromeProxyHeaders, self).__init__(restart_after_each_page=True)
110 def AddResults(self, tab, results):
111 self._metrics.AddResultsForHeaderValidation(tab, results)
114 class ChromeProxyBypass(ChromeProxyValidation):
115 """Correctness measurement for bypass responses."""
117 def __init__(self):
118 super(ChromeProxyBypass, self).__init__(restart_after_each_page=True)
120 def AddResults(self, tab, results):
121 self._metrics.AddResultsForBypass(tab, results)
124 class ChromeProxyCorsBypass(ChromeProxyValidation):
125 """Correctness measurement for bypass responses for CORS requests."""
127 def __init__(self):
128 super(ChromeProxyCorsBypass, self).__init__(restart_after_each_page=True)
130 def ValidateAndMeasurePage(self, page, tab, results):
131 # The test page sets window.xhrRequestCompleted to true when the XHR fetch
132 # finishes.
133 tab.WaitForJavaScriptExpression('window.xhrRequestCompleted', 300)
134 super(ChromeProxyCorsBypass,
135 self).ValidateAndMeasurePage(page, tab, results)
137 def AddResults(self, tab, results):
138 self._metrics.AddResultsForCorsBypass(tab, results)
141 class ChromeProxyBlockOnce(ChromeProxyValidation):
142 """Correctness measurement for block-once responses."""
144 def __init__(self):
145 super(ChromeProxyBlockOnce, self).__init__(restart_after_each_page=True)
147 def AddResults(self, tab, results):
148 self._metrics.AddResultsForBlockOnce(tab, results)
151 class ChromeProxySafebrowsingOn(ChromeProxyValidation):
152 """Correctness measurement for safebrowsing."""
154 def __init__(self):
155 super(ChromeProxySafebrowsingOn, self).__init__()
157 def WillNavigateToPage(self, page, tab):
158 super(ChromeProxySafebrowsingOn, self).WillNavigateToPage(page, tab)
159 self._expect_timeout = True
161 def AddResults(self, tab, results):
162 self._metrics.AddResultsForSafebrowsingOn(tab, results)
164 class ChromeProxySafebrowsingOff(ChromeProxyValidation):
165 """Correctness measurement for safebrowsing."""
167 def __init__(self):
168 super(ChromeProxySafebrowsingOff, self).__init__()
170 def AddResults(self, tab, results):
171 self._metrics.AddResultsForSafebrowsingOff(tab, results)
173 _FAKE_PROXY_AUTH_VALUE = 'aabbccdd3b7579186c1b0620614fdb1f0000ffff'
174 _TEST_SERVER = 'chromeproxy-test.appspot.com'
175 _TEST_SERVER_DEFAULT_URL = 'http://' + _TEST_SERVER + '/default'
178 # We rely on the chromeproxy-test server to facilitate some of the tests.
179 # The test server code is at <TBD location> and runs at _TEST_SERVER
181 # The test server allow request to override response status, headers, and
182 # body through query parameters. See GetResponseOverrideURL.
183 def GetResponseOverrideURL(url=_TEST_SERVER_DEFAULT_URL, respStatus=0,
184 respHeader="", respBody=""):
185 """ Compose the request URL with query parameters to override
186 the chromeproxy-test server response.
189 queries = []
190 if respStatus > 0:
191 queries.append('respStatus=%d' % respStatus)
192 if respHeader:
193 queries.append('respHeader=%s' % base64.b64encode(respHeader))
194 if respBody:
195 queries.append('respBody=%s' % base64.b64encode(respBody))
196 if len(queries) == 0:
197 return url
198 "&".join(queries)
199 # url has query already
200 if urlparse.urlparse(url).query:
201 return url + '&' + "&".join(queries)
202 else:
203 return url + '?' + "&".join(queries)
206 class ChromeProxyHTTPFallbackProbeURL(ChromeProxyValidation):
207 """Correctness measurement for proxy fallback.
209 In this test, the probe URL does not return 'OK'. Chrome is expected
210 to use the fallback proxy.
213 def __init__(self):
214 super(ChromeProxyHTTPFallbackProbeURL, self).__init__(
215 restart_after_each_page=True)
217 def CustomizeBrowserOptions(self, options):
218 super(ChromeProxyHTTPFallbackProbeURL,
219 self).CustomizeBrowserOptions(options)
220 # Use the test server probe URL which returns the response
221 # body as specified by respBody.
222 probe_url = GetResponseOverrideURL(respBody='not OK')
223 options.AppendExtraBrowserArgs(
224 '--data-reduction-proxy-secure-proxy-check-url=%s' % probe_url)
226 def AddResults(self, tab, results):
227 self._metrics.AddResultsForHTTPFallback(tab, results)
230 class ChromeProxyHTTPFallbackViaHeader(ChromeProxyValidation):
231 """Correctness measurement for proxy fallback.
233 In this test, the configured proxy is the chromeproxy-test server which
234 will send back a response without the expected Via header. Chrome is
235 expected to use the fallback proxy and add the configured proxy to the
236 bad proxy list.
239 def __init__(self):
240 super(ChromeProxyHTTPFallbackViaHeader, self).__init__(
241 restart_after_each_page=True)
243 def CustomizeBrowserOptions(self, options):
244 super(ChromeProxyHTTPFallbackViaHeader,
245 self).CustomizeBrowserOptions(options)
246 options.AppendExtraBrowserArgs('--ignore-certificate-errors')
247 options.AppendExtraBrowserArgs(
248 '--spdy-proxy-auth-origin=http://%s' % _TEST_SERVER)
250 def AddResults(self, tab, results):
251 self._metrics.AddResultsForHTTPFallback(tab, results)
254 class ChromeProxyClientVersion(ChromeProxyValidation):
255 """Correctness measurement for version directives in Chrome-Proxy header.
257 The test verifies that the version information provided in the Chrome-Proxy
258 request header overrides any version, if specified, that is provided in the
259 user agent string.
262 def __init__(self):
263 super(ChromeProxyClientVersion, self).__init__()
265 def CustomizeBrowserOptions(self, options):
266 super(ChromeProxyClientVersion,
267 self).CustomizeBrowserOptions(options)
268 options.AppendExtraBrowserArgs('--user-agent="Chrome/32.0.1700.99"')
270 def AddResults(self, tab, results):
271 self._metrics.AddResultsForClientVersion(tab, results)
274 class ChromeProxyClientType(ChromeProxyValidation):
275 """Correctness measurement for Chrome-Proxy header client type directives."""
277 def __init__(self):
278 super(ChromeProxyClientType, self).__init__(restart_after_each_page=True)
279 self._chrome_proxy_client_type = None
281 def AddResults(self, tab, results):
282 # Get the Chrome-Proxy client type from the first page in the page set, so
283 # that the client type value can be used to determine which of the later
284 # pages in the page set should be bypassed.
285 if not self._chrome_proxy_client_type:
286 client_type = self._metrics.GetClientTypeFromRequests(tab)
287 if client_type:
288 self._chrome_proxy_client_type = client_type
290 self._metrics.AddResultsForClientType(tab,
291 results,
292 self._chrome_proxy_client_type,
293 self._page.bypass_for_client_type)
296 class ChromeProxyLoFi(ChromeProxyValidation):
297 """Correctness measurement for Lo-Fi in Chrome-Proxy header."""
299 def __init__(self):
300 super(ChromeProxyLoFi, self).__init__(restart_after_each_page=True)
302 def CustomizeBrowserOptions(self, options):
303 super(ChromeProxyLoFi, self).CustomizeBrowserOptions(options)
304 options.AppendExtraBrowserArgs('--enable-data-reduction-proxy-lo-fi')
306 def AddResults(self, tab, results):
307 self._metrics.AddResultsForLoFi(tab, results)
310 class ChromeProxyHTTPToDirectFallback(ChromeProxyValidation):
311 """Correctness measurement for HTTP proxy fallback to direct."""
313 def __init__(self):
314 super(ChromeProxyHTTPToDirectFallback, self).__init__(
315 restart_after_each_page=True)
317 def CustomizeBrowserOptions(self, options):
318 super(ChromeProxyHTTPToDirectFallback,
319 self).CustomizeBrowserOptions(options)
320 # Set the primary proxy to something that will fail to be resolved so that
321 # this test will run using the HTTP fallback proxy.
322 options.AppendExtraBrowserArgs(
323 '--spdy-proxy-auth-origin=http://nonexistent.googlezip.net')
325 def WillNavigateToPage(self, page, tab):
326 super(ChromeProxyHTTPToDirectFallback, self).WillNavigateToPage(page, tab)
327 # Attempt to load a page through the nonexistent primary proxy in order to
328 # cause a proxy fallback, and have this test run starting from the HTTP
329 # fallback proxy.
330 tab.Navigate(_TEST_SERVER_DEFAULT_URL)
331 tab.WaitForJavaScriptExpression('performance.timing.loadEventStart', 300)
333 def AddResults(self, tab, results):
334 self._metrics.AddResultsForHTTPToDirectFallback(tab, results, _TEST_SERVER)
337 class ChromeProxyReenableAfterBypass(ChromeProxyValidation):
338 """Correctness measurement for re-enabling proxies after bypasses.
340 This test loads a page that causes all data reduction proxies to be bypassed
341 for 1 to 5 minutes, then waits 5 minutes and verifies that the proxy is no
342 longer bypassed.
345 def __init__(self):
346 super(ChromeProxyReenableAfterBypass, self).__init__(
347 restart_after_each_page=True)
349 def AddResults(self, tab, results):
350 self._metrics.AddResultsForReenableAfterBypass(
351 tab, results, self._page.bypass_seconds_min,
352 self._page.bypass_seconds_max)
355 class ChromeProxySmoke(ChromeProxyValidation):
356 """Smoke measurement for basic chrome proxy correctness."""
358 def __init__(self):
359 super(ChromeProxySmoke, self).__init__(restart_after_each_page=True)
361 def WillNavigateToPage(self, page, tab):
362 super(ChromeProxySmoke, self).WillNavigateToPage(page, tab)
364 def AddResults(self, tab, results):
365 # Map a page name to its AddResults func.
366 page_to_metrics = {
367 'header validation': [self._metrics.AddResultsForHeaderValidation],
368 'compression: image': [
369 self._metrics.AddResultsForHeaderValidation,
370 self._metrics.AddResultsForDataSaving,
372 'compression: javascript': [
373 self._metrics.AddResultsForHeaderValidation,
374 self._metrics.AddResultsForDataSaving,
376 'compression: css': [
377 self._metrics.AddResultsForHeaderValidation,
378 self._metrics.AddResultsForDataSaving,
380 'bypass': [self._metrics.AddResultsForBypass],
382 if not self._page.name in page_to_metrics:
383 raise page_test.MeasurementFailure(
384 'Invalid page name (%s) in smoke. Page name must be one of:\n%s' % (
385 self._page.name, page_to_metrics.keys()))
386 for add_result in page_to_metrics[self._page.name]:
387 add_result(tab, results)