Add ICU message format support
[chromium-blink-merge.git] / tools / chrome_proxy / integration_tests / chrome_proxy_metrics_unittest.py
blob3b2240bd9ce2ab0a64929d2628020c03fc271bc5
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 unittest
8 from common import chrome_proxy_metrics as common_metrics
9 from common import network_metrics_unittest as network_unittest
10 from integration_tests import chrome_proxy_metrics as metrics
11 from telemetry.testing import test_page_test_results
13 TEST_EXTRA_VIA_HEADER = '1.1 EXTRA_VIA_HEADER'
15 # Timeline events used in tests.
16 # An HTML not via proxy.
17 EVENT_HTML_DIRECT = network_unittest.NetworkMetricTest.MakeNetworkTimelineEvent(
18 url='http://test.html1',
19 response_headers={
20 'Content-Type': 'text/html',
21 'Content-Length': str(len(network_unittest.HTML_BODY)),
23 body=network_unittest.HTML_BODY)
25 # An HTML via proxy.
26 EVENT_HTML_PROXY_VIA = (
27 network_unittest.NetworkMetricTest.MakeNetworkTimelineEvent(
28 url='http://test.html2',
29 response_headers={
30 'Content-Type': 'text/html',
31 'Content-Encoding': 'gzip',
32 'X-Original-Content-Length': str(len(network_unittest.HTML_BODY)),
33 'Via': '1.1 ' + common_metrics.CHROME_PROXY_VIA_HEADER,
35 body=network_unittest.HTML_BODY,
36 remote_port=443))
38 # An HTML via proxy with extra header.
39 EVENT_HTML_PROXY_EXTRA_VIA = (
40 network_unittest.NetworkMetricTest.MakeNetworkTimelineEvent(
41 url='http://test.html2',
42 response_headers={
43 'Content-Type': 'text/html',
44 'Content-Encoding': 'gzip',
45 'X-Original-Content-Length': str(len(network_unittest.HTML_BODY)),
46 'Via': '1.1 ' + common_metrics.CHROME_PROXY_VIA_HEADER + ", " +
47 TEST_EXTRA_VIA_HEADER,
49 body=network_unittest.HTML_BODY,
50 remote_port=443))
52 # An HTML via the HTTP fallback proxy.
53 EVENT_HTML_PROXY_VIA_HTTP_FALLBACK = (
54 network_unittest.NetworkMetricTest.MakeNetworkTimelineEvent(
55 url='http://test.html2',
56 response_headers={
57 'Content-Type': 'text/html',
58 'Content-Encoding': 'gzip',
59 'X-Original-Content-Length': str(len(network_unittest.HTML_BODY)),
60 'Via': '1.1 ' + common_metrics.CHROME_PROXY_VIA_HEADER,
62 body=network_unittest.HTML_BODY,
63 remote_port=80))
65 # An image via proxy with Via header.
66 EVENT_IMAGE_PROXY_VIA = (
67 network_unittest.NetworkMetricTest.MakeNetworkTimelineEvent(
68 url='http://test.image',
69 response_headers={
70 'Content-Type': 'image/jpeg',
71 'Content-Encoding': 'gzip',
72 'X-Original-Content-Length': str(network_unittest.IMAGE_OCL),
73 'Via': '1.1 ' + common_metrics.CHROME_PROXY_VIA_HEADER,
75 body=base64.b64encode(network_unittest.IMAGE_BODY),
76 base64_encoded_body=True,
77 remote_port=443))
79 # An image via the HTTP fallback proxy.
80 EVENT_IMAGE_PROXY_VIA_HTTP_FALLBACK = (
81 network_unittest.NetworkMetricTest.MakeNetworkTimelineEvent(
82 url='http://test.image',
83 response_headers={
84 'Content-Type': 'image/jpeg',
85 'Content-Encoding': 'gzip',
86 'X-Original-Content-Length': str(network_unittest.IMAGE_OCL),
87 'Via': '1.1 ' + common_metrics.CHROME_PROXY_VIA_HEADER,
89 body=base64.b64encode(network_unittest.IMAGE_BODY),
90 base64_encoded_body=True,
91 remote_port=80))
93 # An image via proxy with Via header and it is cached.
94 EVENT_IMAGE_PROXY_CACHED = (
95 network_unittest.NetworkMetricTest.MakeNetworkTimelineEvent(
96 url='http://test.image',
97 response_headers={
98 'Content-Type': 'image/jpeg',
99 'Content-Encoding': 'gzip',
100 'X-Original-Content-Length': str(network_unittest.IMAGE_OCL),
101 'Via': '1.1 ' + common_metrics.CHROME_PROXY_VIA_HEADER,
103 body=base64.b64encode(network_unittest.IMAGE_BODY),
104 base64_encoded_body=True,
105 served_from_cache=True))
107 # An image fetched directly.
108 EVENT_IMAGE_DIRECT = (
109 network_unittest.NetworkMetricTest.MakeNetworkTimelineEvent(
110 url='http://test.image',
111 response_headers={
112 'Content-Type': 'image/jpeg',
113 'Content-Encoding': 'gzip',
115 body=base64.b64encode(network_unittest.IMAGE_BODY),
116 base64_encoded_body=True))
118 # A safe-browsing malware response.
119 EVENT_MALWARE_PROXY = (
120 network_unittest.NetworkMetricTest.MakeNetworkTimelineEvent(
121 url='http://test.malware',
122 response_headers={
123 'X-Malware-Url': '1',
124 'Via': '1.1 ' + common_metrics.CHROME_PROXY_VIA_HEADER,
125 'Location': 'http://test.malware',
127 status=307))
129 # An HTML via proxy with the Via header.
130 EVENT_IMAGE_BYPASS = (
131 network_unittest.NetworkMetricTest.MakeNetworkTimelineEvent(
132 url='http://test.image',
133 response_headers={
134 'Chrome-Proxy': 'bypass=1',
135 'Content-Type': 'text/html',
136 'Via': '1.1 ' + common_metrics.CHROME_PROXY_VIA_HEADER,
138 status=502))
140 # An image fetched directly.
141 EVENT_IMAGE_DIRECT = (
142 network_unittest.NetworkMetricTest.MakeNetworkTimelineEvent(
143 url='http://test.image',
144 response_headers={
145 'Content-Type': 'image/jpeg',
146 'Content-Encoding': 'gzip',
148 body=base64.b64encode(network_unittest.IMAGE_BODY),
149 base64_encoded_body=True))
152 class ChromeProxyMetricTest(unittest.TestCase):
154 _test_proxy_info = {}
156 def _StubGetProxyInfo(self, info):
157 def stub(unused_tab, unused_url=''): # pylint: disable=W0613
158 return ChromeProxyMetricTest._test_proxy_info
159 metrics.GetProxyInfoFromNetworkInternals = stub
160 ChromeProxyMetricTest._test_proxy_info = info
162 def testChromeProxyMetricForHeaderValidation(self):
163 metric = metrics.ChromeProxyMetric()
164 metric.SetEvents([
165 EVENT_HTML_DIRECT,
166 EVENT_HTML_PROXY_VIA,
167 EVENT_IMAGE_PROXY_CACHED,
168 EVENT_IMAGE_DIRECT])
170 results = test_page_test_results.TestPageTestResults(self)
172 missing_via_exception = False
173 try:
174 metric.AddResultsForHeaderValidation(None, results)
175 except common_metrics.ChromeProxyMetricException:
176 missing_via_exception = True
177 # Only the HTTP image response does not have a valid Via header.
178 self.assertTrue(missing_via_exception)
180 # Two events with valid Via headers.
181 metric.SetEvents([
182 EVENT_HTML_PROXY_VIA,
183 EVENT_IMAGE_PROXY_CACHED])
184 metric.AddResultsForHeaderValidation(None, results)
185 results.AssertHasPageSpecificScalarValue('checked_via_header', 'count', 2)
187 # Passing in zero responses should cause a failure.
188 metric.SetEvents([])
189 no_responses_exception = False
190 try:
191 metric.AddResultsForHeaderValidation(None, results)
192 except common_metrics.ChromeProxyMetricException:
193 no_responses_exception = True
194 self.assertTrue(no_responses_exception)
196 def testChromeProxyMetricForExtraViaHeader(self):
197 metric = metrics.ChromeProxyMetric()
198 metric.SetEvents([EVENT_HTML_DIRECT,
199 EVENT_HTML_PROXY_EXTRA_VIA])
200 results = test_page_test_results.TestPageTestResults(self)
201 metric.AddResultsForExtraViaHeader(None, results, TEST_EXTRA_VIA_HEADER)
202 # The direct page should not count an extra via header, but should also not
203 # throw an exception.
204 results.AssertHasPageSpecificScalarValue('extra_via_header', 'count', 1)
206 metric.SetEvents([EVENT_HTML_PROXY_VIA])
207 exception_occurred = False
208 try:
209 metric.AddResultsForExtraViaHeader(None, results, TEST_EXTRA_VIA_HEADER)
210 except common_metrics.ChromeProxyMetricException:
211 exception_occurred = True
212 # The response had the chrome proxy via header, but not the extra expected
213 # via header.
214 self.assertTrue(exception_occurred)
216 def testChromeProxyMetricForBypass(self):
217 metric = metrics.ChromeProxyMetric()
218 metric.SetEvents([
219 EVENT_HTML_DIRECT,
220 EVENT_HTML_PROXY_VIA,
221 EVENT_IMAGE_PROXY_CACHED,
222 EVENT_IMAGE_DIRECT])
223 results = test_page_test_results.TestPageTestResults(self)
225 bypass_exception = False
226 try:
227 metric.AddResultsForBypass(None, results)
228 except common_metrics.ChromeProxyMetricException:
229 bypass_exception = True
230 # Two of the first three events have Via headers.
231 self.assertTrue(bypass_exception)
233 # Use directly fetched image only. It is treated as bypassed.
234 metric.SetEvents([EVENT_IMAGE_DIRECT])
235 metric.AddResultsForBypass(None, results)
236 results.AssertHasPageSpecificScalarValue('bypass', 'count', 1)
238 # Passing in zero responses should cause a failure.
239 metric.SetEvents([])
240 no_responses_exception = False
241 try:
242 metric.AddResultsForBypass(None, results)
243 except common_metrics.ChromeProxyMetricException:
244 no_responses_exception = True
245 self.assertTrue(no_responses_exception)
247 def testChromeProxyMetricForCorsBypass(self):
248 metric = metrics.ChromeProxyMetric()
249 metric.SetEvents([EVENT_HTML_PROXY_VIA,
250 EVENT_IMAGE_BYPASS,
251 EVENT_IMAGE_DIRECT])
252 results = test_page_test_results.TestPageTestResults(self)
253 metric.AddResultsForCorsBypass(None, results)
254 results.AssertHasPageSpecificScalarValue('cors_bypass', 'count', 1)
256 # Passing in zero responses should cause a failure.
257 metric.SetEvents([])
258 no_responses_exception = False
259 try:
260 metric.AddResultsForCorsBypass(None, results)
261 except common_metrics.ChromeProxyMetricException:
262 no_responses_exception = True
263 self.assertTrue(no_responses_exception)
265 def testChromeProxyMetricForBlockOnce(self):
266 metric = metrics.ChromeProxyMetric()
267 metric.SetEvents([EVENT_HTML_DIRECT,
268 EVENT_IMAGE_PROXY_VIA])
269 results = test_page_test_results.TestPageTestResults(self)
270 metric.AddResultsForBlockOnce(None, results)
271 results.AssertHasPageSpecificScalarValue('eligible_responses', 'count', 2)
272 results.AssertHasPageSpecificScalarValue('bypass', 'count', 1)
274 metric.SetEvents([EVENT_HTML_DIRECT,
275 EVENT_IMAGE_DIRECT])
276 exception_occurred = False
277 try:
278 metric.AddResultsForBlockOnce(None, results)
279 except common_metrics.ChromeProxyMetricException:
280 exception_occurred = True
281 # The second response was over direct, but was expected via proxy.
282 self.assertTrue(exception_occurred)
284 # Passing in zero responses should cause a failure.
285 metric.SetEvents([])
286 no_responses_exception = False
287 try:
288 metric.AddResultsForBlockOnce(None, results)
289 except common_metrics.ChromeProxyMetricException:
290 no_responses_exception = True
291 self.assertTrue(no_responses_exception)
293 def testChromeProxyMetricForSafebrowsingOn(self):
294 metric = metrics.ChromeProxyMetric()
295 metric.SetEvents([EVENT_MALWARE_PROXY])
296 results = test_page_test_results.TestPageTestResults(self)
298 metric.AddResultsForSafebrowsingOn(None, results)
299 results.AssertHasPageSpecificScalarValue(
300 'safebrowsing', 'timeout responses', 1)
302 # Clear results and metrics to test no response for safebrowsing
303 results = test_page_test_results.TestPageTestResults(self)
304 metric.SetEvents([])
305 metric.AddResultsForSafebrowsingOn(None, results)
306 results.AssertHasPageSpecificScalarValue(
307 'safebrowsing', 'timeout responses', 1)
309 def testChromeProxyMetricForHTTPFallback(self):
310 metric = metrics.ChromeProxyMetric()
311 metric.SetEvents([EVENT_HTML_PROXY_VIA_HTTP_FALLBACK,
312 EVENT_IMAGE_PROXY_VIA_HTTP_FALLBACK])
313 results = test_page_test_results.TestPageTestResults(self)
314 metric.AddResultsForHTTPFallback(None, results)
315 results.AssertHasPageSpecificScalarValue('via_fallback', 'count', 2)
317 metric.SetEvents([EVENT_HTML_PROXY_VIA,
318 EVENT_IMAGE_PROXY_VIA])
319 exception_occurred = False
320 try:
321 metric.AddResultsForHTTPFallback(None, results)
322 except common_metrics.ChromeProxyMetricException:
323 exception_occurred = True
324 # The responses came through the SPDY proxy, but were expected through the
325 # HTTP fallback proxy.
326 self.assertTrue(exception_occurred)
328 # Passing in zero responses should cause a failure.
329 metric.SetEvents([])
330 no_responses_exception = False
331 try:
332 metric.AddResultsForHTTPFallback(None, results)
333 except common_metrics.ChromeProxyMetricException:
334 no_responses_exception = True
335 self.assertTrue(no_responses_exception)
337 def testChromeProxyMetricForHTTPToDirectFallback(self):
338 metric = metrics.ChromeProxyMetric()
339 metric.SetEvents([EVENT_HTML_PROXY_VIA_HTTP_FALLBACK,
340 EVENT_HTML_DIRECT,
341 EVENT_IMAGE_DIRECT])
342 results = test_page_test_results.TestPageTestResults(self)
343 metric.AddResultsForHTTPToDirectFallback(None, results, 'test.html2')
344 results.AssertHasPageSpecificScalarValue('via_fallback', 'count', 1)
345 results.AssertHasPageSpecificScalarValue('bypass', 'count', 2)
347 metric.SetEvents([EVENT_HTML_PROXY_VIA,
348 EVENT_HTML_DIRECT])
349 exception_occurred = False
350 try:
351 metric.AddResultsForHTTPToDirectFallback(None, results, 'test.html2')
352 except common_metrics.ChromeProxyMetricException:
353 exception_occurred = True
354 # The first response was expected through the HTTP fallback proxy.
355 self.assertTrue(exception_occurred)
357 metric.SetEvents([EVENT_HTML_PROXY_VIA_HTTP_FALLBACK,
358 EVENT_HTML_PROXY_VIA_HTTP_FALLBACK,
359 EVENT_IMAGE_PROXY_VIA_HTTP_FALLBACK])
360 exception_occurred = False
361 try:
362 metric.AddResultsForHTTPToDirectFallback(None, results, 'test.html2')
363 except common_metrics.ChromeProxyMetricException:
364 exception_occurred = True
365 # All but the first response were expected to be over direct.
366 self.assertTrue(exception_occurred)
368 metric.SetEvents([EVENT_HTML_DIRECT,
369 EVENT_HTML_DIRECT,
370 EVENT_IMAGE_DIRECT])
371 exception_occurred = False
372 try:
373 metric.AddResultsForHTTPToDirectFallback(None, results, 'test.html2')
374 except common_metrics.ChromeProxyMetricException:
375 exception_occurred = True
376 # The first response was expected through the HTTP fallback proxy.
377 self.assertTrue(exception_occurred)
379 # Passing in zero responses should cause a failure.
380 metric.SetEvents([])
381 no_responses_exception = False
382 try:
383 metric.AddResultsForHTTPToDirectFallback(None, results, 'test.html2')
384 except common_metrics.ChromeProxyMetricException:
385 no_responses_exception = True
386 self.assertTrue(no_responses_exception)