Extend the enterprise policy for SSL overrides to the "danger" command
[chromium-blink-merge.git] / tools / chrome_proxy / integration_tests / chrome_proxy_measurements.py
blobfba1d99bfcfbc76684104e6ef6ae5db7cf97576b
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 common.chrome_proxy_measurements import ChromeProxyValidation
10 from integration_tests import chrome_proxy_metrics as metrics
11 from metrics import loading
12 from telemetry.core import exceptions
13 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)
20 self._metrics = metrics.ChromeProxyMetric()
22 def CustomizeBrowserOptions(self, options):
23 options.AppendExtraBrowserArgs('--enable-spdy-proxy-auth')
25 def WillNavigateToPage(self, page, tab):
26 tab.ClearCache(force=True)
28 def ValidateAndMeasurePage(self, page, tab, results):
29 # Wait for the load event.
30 tab.WaitForJavaScriptExpression('performance.timing.loadEventStart', 300)
31 self._metrics.AddResultsForLatency(tab, results)
34 class ChromeProxyDataSaving(page_test.PageTest):
35 """Chrome proxy data saving measurement."""
36 def __init__(self, *args, **kwargs):
37 super(ChromeProxyDataSaving, self).__init__(*args, **kwargs)
38 self._metrics = metrics.ChromeProxyMetric()
40 def CustomizeBrowserOptions(self, options):
41 options.AppendExtraBrowserArgs('--enable-spdy-proxy-auth')
43 def WillNavigateToPage(self, page, tab):
44 tab.ClearCache(force=True)
45 self._metrics.Start(page, tab)
47 def ValidateAndMeasurePage(self, page, tab, results):
48 # Wait for the load event.
49 tab.WaitForJavaScriptExpression('performance.timing.loadEventStart', 300)
50 self._metrics.Stop(page, tab)
51 self._metrics.AddResultsForDataSaving(tab, results)
54 class ChromeProxyHeaders(ChromeProxyValidation):
55 """Correctness measurement for response headers."""
57 def __init__(self):
58 super(ChromeProxyHeaders, self).__init__(
59 restart_after_each_page=True,
60 metrics=metrics.ChromeProxyMetric())
62 def AddResults(self, tab, results):
63 self._metrics.AddResultsForHeaderValidation(tab, results)
66 class ChromeProxyBypass(ChromeProxyValidation):
67 """Correctness measurement for bypass responses."""
69 def __init__(self):
70 super(ChromeProxyBypass, self).__init__(
71 restart_after_each_page=True,
72 metrics=metrics.ChromeProxyMetric())
74 def AddResults(self, tab, results):
75 self._metrics.AddResultsForBypass(tab, results)
78 class ChromeProxyCorsBypass(ChromeProxyValidation):
79 """Correctness measurement for bypass responses for CORS requests."""
81 def __init__(self):
82 super(ChromeProxyCorsBypass, self).__init__(
83 restart_after_each_page=True,
84 metrics=metrics.ChromeProxyMetric())
86 def ValidateAndMeasurePage(self, page, tab, results):
87 # The test page sets window.xhrRequestCompleted to true when the XHR fetch
88 # finishes.
89 tab.WaitForJavaScriptExpression('window.xhrRequestCompleted', 300)
90 super(ChromeProxyCorsBypass,
91 self).ValidateAndMeasurePage(page, tab, results)
93 def AddResults(self, tab, results):
94 self._metrics.AddResultsForCorsBypass(tab, results)
97 class ChromeProxyBlockOnce(ChromeProxyValidation):
98 """Correctness measurement for block-once responses."""
100 def __init__(self):
101 super(ChromeProxyBlockOnce, self).__init__(
102 restart_after_each_page=True,
103 metrics=metrics.ChromeProxyMetric())
105 def AddResults(self, tab, results):
106 self._metrics.AddResultsForBlockOnce(tab, results)
109 class ChromeProxySafebrowsingOn(ChromeProxyValidation):
110 """Correctness measurement for safebrowsing."""
112 def __init__(self):
113 super(ChromeProxySafebrowsingOn, self).__init__(
114 metrics=metrics.ChromeProxyMetric())
116 def WillNavigateToPage(self, page, tab):
117 super(ChromeProxySafebrowsingOn, self).WillNavigateToPage(page, tab)
118 self._expect_timeout = True
120 def AddResults(self, tab, results):
121 self._metrics.AddResultsForSafebrowsingOn(tab, results)
123 class ChromeProxySafebrowsingOff(ChromeProxyValidation):
124 """Correctness measurement for safebrowsing."""
126 def __init__(self):
127 super(ChromeProxySafebrowsingOff, self).__init__(
128 metrics=metrics.ChromeProxyMetric())
130 def AddResults(self, tab, results):
131 self._metrics.AddResultsForSafebrowsingOff(tab, results)
133 _FAKE_PROXY_AUTH_VALUE = 'aabbccdd3b7579186c1b0620614fdb1f0000ffff'
134 _TEST_SERVER = 'chromeproxy-test.appspot.com'
135 _TEST_SERVER_DEFAULT_URL = 'http://' + _TEST_SERVER + '/default'
138 # We rely on the chromeproxy-test server to facilitate some of the tests.
139 # The test server code is at <TBD location> and runs at _TEST_SERVER
141 # The test server allow request to override response status, headers, and
142 # body through query parameters. See GetResponseOverrideURL.
143 def GetResponseOverrideURL(url=_TEST_SERVER_DEFAULT_URL, respStatus=0,
144 respHeader="", respBody=""):
145 """ Compose the request URL with query parameters to override
146 the chromeproxy-test server response.
149 queries = []
150 if respStatus > 0:
151 queries.append('respStatus=%d' % respStatus)
152 if respHeader:
153 queries.append('respHeader=%s' % base64.b64encode(respHeader))
154 if respBody:
155 queries.append('respBody=%s' % base64.b64encode(respBody))
156 if len(queries) == 0:
157 return url
158 "&".join(queries)
159 # url has query already
160 if urlparse.urlparse(url).query:
161 return url + '&' + "&".join(queries)
162 else:
163 return url + '?' + "&".join(queries)
166 class ChromeProxyHTTPFallbackProbeURL(ChromeProxyValidation):
167 """Correctness measurement for proxy fallback.
169 In this test, the probe URL does not return 'OK'. Chrome is expected
170 to use the fallback proxy.
173 def __init__(self):
174 super(ChromeProxyHTTPFallbackProbeURL, self).__init__(
175 restart_after_each_page=True,
176 metrics=metrics.ChromeProxyMetric())
178 def CustomizeBrowserOptions(self, options):
179 super(ChromeProxyHTTPFallbackProbeURL,
180 self).CustomizeBrowserOptions(options)
181 # Set the secure proxy check URL to the google.com favicon, which will be
182 # interpreted as a secure proxy check failure since the response body is not
183 # "OK". The google.com favicon is used because it will load reliably fast,
184 # and there have been problems with chromeproxy-test.appspot.com being slow
185 # and causing tests to flake.
186 options.AppendExtraBrowserArgs(
187 '--data-reduction-proxy-secure-proxy-check-url='
188 'http://www.google.com/favicon.ico')
190 def AddResults(self, tab, results):
191 self._metrics.AddResultsForHTTPFallback(tab, results)
194 class ChromeProxyHTTPFallbackViaHeader(ChromeProxyValidation):
195 """Correctness measurement for proxy fallback.
197 In this test, the configured proxy is the chromeproxy-test server which
198 will send back a response without the expected Via header. Chrome is
199 expected to use the fallback proxy and add the configured proxy to the
200 bad proxy list.
203 def __init__(self):
204 super(ChromeProxyHTTPFallbackViaHeader, self).__init__(
205 restart_after_each_page=True,
206 metrics=metrics.ChromeProxyMetric())
208 def CustomizeBrowserOptions(self, options):
209 super(ChromeProxyHTTPFallbackViaHeader,
210 self).CustomizeBrowserOptions(options)
211 options.AppendExtraBrowserArgs('--ignore-certificate-errors')
212 options.AppendExtraBrowserArgs(
213 '--spdy-proxy-auth-origin=http://%s' % _TEST_SERVER)
215 def AddResults(self, tab, results):
216 self._metrics.AddResultsForHTTPFallback(tab, results)
219 class ChromeProxyClientVersion(ChromeProxyValidation):
220 """Correctness measurement for version directives in Chrome-Proxy header.
222 The test verifies that the version information provided in the Chrome-Proxy
223 request header overrides any version, if specified, that is provided in the
224 user agent string.
227 def __init__(self):
228 super(ChromeProxyClientVersion, self).__init__(
229 metrics=metrics.ChromeProxyMetric())
231 def CustomizeBrowserOptions(self, options):
232 super(ChromeProxyClientVersion,
233 self).CustomizeBrowserOptions(options)
234 options.AppendExtraBrowserArgs('--user-agent="Chrome/32.0.1700.99"')
236 def AddResults(self, tab, results):
237 self._metrics.AddResultsForClientVersion(tab, results)
240 class ChromeProxyClientType(ChromeProxyValidation):
241 """Correctness measurement for Chrome-Proxy header client type directives."""
243 def __init__(self):
244 super(ChromeProxyClientType, self).__init__(
245 restart_after_each_page=True,
246 metrics=metrics.ChromeProxyMetric())
247 self._chrome_proxy_client_type = None
249 def AddResults(self, tab, results):
250 # Get the Chrome-Proxy client type from the first page in the page set, so
251 # that the client type value can be used to determine which of the later
252 # pages in the page set should be bypassed.
253 if not self._chrome_proxy_client_type:
254 client_type = self._metrics.GetClientTypeFromRequests(tab)
255 if client_type:
256 self._chrome_proxy_client_type = client_type
258 self._metrics.AddResultsForClientType(tab,
259 results,
260 self._chrome_proxy_client_type,
261 self._page.bypass_for_client_type)
264 class ChromeProxyLoFi(ChromeProxyValidation):
265 """Correctness measurement for Lo-Fi in Chrome-Proxy header."""
267 def __init__(self):
268 super(ChromeProxyLoFi, self).__init__(restart_after_each_page=True,
269 metrics=metrics.ChromeProxyMetric())
271 def CustomizeBrowserOptions(self, options):
272 super(ChromeProxyLoFi, self).CustomizeBrowserOptions(options)
273 options.AppendExtraBrowserArgs('--enable-data-reduction-proxy-lo-fi')
275 def AddResults(self, tab, results):
276 self._metrics.AddResultsForLoFi(tab, results)
278 class ChromeProxyExpDirective(ChromeProxyValidation):
279 """Correctness measurement for experiment directives in Chrome-Proxy header.
281 This test verifies that "exp=test" in the Chrome-Proxy request header
282 causes a bypass on the experiment test page.
285 def __init__(self):
286 super(ChromeProxyExpDirective, self).__init__(
287 restart_after_each_page=True,
288 metrics=metrics.ChromeProxyMetric())
290 def CustomizeBrowserOptions(self, options):
291 super(ChromeProxyExpDirective, self).CustomizeBrowserOptions(options)
292 options.AppendExtraBrowserArgs('--data-reduction-proxy-experiment=test')
294 def AddResults(self, tab, results):
295 self._metrics.AddResultsForBypass(tab, results)
298 class ChromeProxyHTTPToDirectFallback(ChromeProxyValidation):
299 """Correctness measurement for HTTP proxy fallback to direct."""
301 def __init__(self):
302 super(ChromeProxyHTTPToDirectFallback, self).__init__(
303 restart_after_each_page=True,
304 metrics=metrics.ChromeProxyMetric())
306 def CustomizeBrowserOptions(self, options):
307 super(ChromeProxyHTTPToDirectFallback,
308 self).CustomizeBrowserOptions(options)
309 # Set the primary proxy to something that will fail to be resolved so that
310 # this test will run using the HTTP fallback proxy.
311 options.AppendExtraBrowserArgs(
312 '--spdy-proxy-auth-origin=http://nonexistent.googlezip.net')
314 def WillNavigateToPage(self, page, tab):
315 super(ChromeProxyHTTPToDirectFallback, self).WillNavigateToPage(page, tab)
316 # Attempt to load a page through the nonexistent primary proxy in order to
317 # cause a proxy fallback, and have this test run starting from the HTTP
318 # fallback proxy.
319 tab.Navigate(_TEST_SERVER_DEFAULT_URL)
320 tab.WaitForJavaScriptExpression('performance.timing.loadEventStart', 300)
322 def AddResults(self, tab, results):
323 self._metrics.AddResultsForHTTPToDirectFallback(tab, results, _TEST_SERVER)
326 class ChromeProxyReenableAfterBypass(ChromeProxyValidation):
327 """Correctness measurement for re-enabling proxies after bypasses.
329 This test loads a page that causes all data reduction proxies to be bypassed
330 for 1 to 5 minutes, then waits 5 minutes and verifies that the proxy is no
331 longer bypassed.
334 def __init__(self):
335 super(ChromeProxyReenableAfterBypass, self).__init__(
336 restart_after_each_page=True,
337 metrics=metrics.ChromeProxyMetric())
339 def AddResults(self, tab, results):
340 self._metrics.AddResultsForReenableAfterBypass(
341 tab, results, self._page.bypass_seconds_min,
342 self._page.bypass_seconds_max)
345 class ChromeProxySmoke(ChromeProxyValidation):
346 """Smoke measurement for basic chrome proxy correctness."""
348 def __init__(self):
349 super(ChromeProxySmoke, self).__init__(restart_after_each_page=True,
350 metrics=metrics.ChromeProxyMetric())
352 def WillNavigateToPage(self, page, tab):
353 super(ChromeProxySmoke, self).WillNavigateToPage(page, tab)
355 def AddResults(self, tab, results):
356 # Map a page name to its AddResults func.
357 page_to_metrics = {
358 'header validation': [self._metrics.AddResultsForHeaderValidation],
359 'compression: image': [
360 self._metrics.AddResultsForHeaderValidation,
361 self._metrics.AddResultsForDataSaving,
363 'compression: javascript': [
364 self._metrics.AddResultsForHeaderValidation,
365 self._metrics.AddResultsForDataSaving,
367 'compression: css': [
368 self._metrics.AddResultsForHeaderValidation,
369 self._metrics.AddResultsForDataSaving,
371 'bypass': [self._metrics.AddResultsForBypass],
373 if not self._page.name in page_to_metrics:
374 raise page_test.MeasurementFailure(
375 'Invalid page name (%s) in smoke. Page name must be one of:\n%s' % (
376 self._page.name, page_to_metrics.keys()))
377 for add_result in page_to_metrics[self._page.name]:
378 add_result(tab, results)