[DevTools] Remove forwarded connections counting
[chromium-blink-merge.git] / tools / chrome_proxy / integration_tests / chrome_proxy_metrics_unittest.py
blobb18ef5ed332e4ad6f792f4c6b3069788b811e062
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 integration_tests import chrome_proxy_metrics as metrics
9 from integration_tests import network_metrics_unittest as network_unittest
10 from telemetry.unittest_util import test_page_test_results
12 TEST_EXTRA_VIA_HEADER = '1.1 EXTRA_VIA_HEADER'
14 # Timeline events used in tests.
15 # An HTML not via proxy.
16 EVENT_HTML_DIRECT = network_unittest.NetworkMetricTest.MakeNetworkTimelineEvent(
17 url='http://test.html1',
18 response_headers={
19 'Content-Type': 'text/html',
20 'Content-Length': str(len(network_unittest.HTML_BODY)),
22 body=network_unittest.HTML_BODY)
24 # An HTML via proxy.
25 EVENT_HTML_PROXY_VIA = (
26 network_unittest.NetworkMetricTest.MakeNetworkTimelineEvent(
27 url='http://test.html2',
28 response_headers={
29 'Content-Type': 'text/html',
30 'Content-Encoding': 'gzip',
31 'X-Original-Content-Length': str(len(network_unittest.HTML_BODY)),
32 'Via': '1.1 ' + metrics.CHROME_PROXY_VIA_HEADER,
34 body=network_unittest.HTML_BODY,
35 remote_port=443))
37 # An HTML via proxy with extra header.
38 EVENT_HTML_PROXY_EXTRA_VIA = (
39 network_unittest.NetworkMetricTest.MakeNetworkTimelineEvent(
40 url='http://test.html2',
41 response_headers={
42 'Content-Type': 'text/html',
43 'Content-Encoding': 'gzip',
44 'X-Original-Content-Length': str(len(network_unittest.HTML_BODY)),
45 'Via': '1.1 ' + metrics.CHROME_PROXY_VIA_HEADER + ", " +
46 TEST_EXTRA_VIA_HEADER,
48 body=network_unittest.HTML_BODY,
49 remote_port=443))
51 # An HTML via the HTTP fallback proxy.
52 EVENT_HTML_PROXY_VIA_HTTP_FALLBACK = (
53 network_unittest.NetworkMetricTest.MakeNetworkTimelineEvent(
54 url='http://test.html2',
55 response_headers={
56 'Content-Type': 'text/html',
57 'Content-Encoding': 'gzip',
58 'X-Original-Content-Length': str(len(network_unittest.HTML_BODY)),
59 'Via': '1.1 ' + metrics.CHROME_PROXY_VIA_HEADER,
61 body=network_unittest.HTML_BODY,
62 remote_port=80))
64 # An image via proxy with Via header.
65 EVENT_IMAGE_PROXY_VIA = (
66 network_unittest.NetworkMetricTest.MakeNetworkTimelineEvent(
67 url='http://test.image',
68 response_headers={
69 'Content-Type': 'image/jpeg',
70 'Content-Encoding': 'gzip',
71 'X-Original-Content-Length': str(network_unittest.IMAGE_OCL),
72 'Via': '1.1 ' + metrics.CHROME_PROXY_VIA_HEADER,
74 body=base64.b64encode(network_unittest.IMAGE_BODY),
75 base64_encoded_body=True,
76 remote_port=443))
78 # An image via the HTTP fallback proxy.
79 EVENT_IMAGE_PROXY_VIA_HTTP_FALLBACK = (
80 network_unittest.NetworkMetricTest.MakeNetworkTimelineEvent(
81 url='http://test.image',
82 response_headers={
83 'Content-Type': 'image/jpeg',
84 'Content-Encoding': 'gzip',
85 'X-Original-Content-Length': str(network_unittest.IMAGE_OCL),
86 'Via': '1.1 ' + metrics.CHROME_PROXY_VIA_HEADER,
88 body=base64.b64encode(network_unittest.IMAGE_BODY),
89 base64_encoded_body=True,
90 remote_port=80))
92 # An image via proxy with Via header and it is cached.
93 EVENT_IMAGE_PROXY_CACHED = (
94 network_unittest.NetworkMetricTest.MakeNetworkTimelineEvent(
95 url='http://test.image',
96 response_headers={
97 'Content-Type': 'image/jpeg',
98 'Content-Encoding': 'gzip',
99 'X-Original-Content-Length': str(network_unittest.IMAGE_OCL),
100 'Via': '1.1 ' + metrics.CHROME_PROXY_VIA_HEADER,
102 body=base64.b64encode(network_unittest.IMAGE_BODY),
103 base64_encoded_body=True,
104 served_from_cache=True))
106 # An image fetched directly.
107 EVENT_IMAGE_DIRECT = (
108 network_unittest.NetworkMetricTest.MakeNetworkTimelineEvent(
109 url='http://test.image',
110 response_headers={
111 'Content-Type': 'image/jpeg',
112 'Content-Encoding': 'gzip',
114 body=base64.b64encode(network_unittest.IMAGE_BODY),
115 base64_encoded_body=True))
117 # A safe-browsing malware response.
118 EVENT_MALWARE_PROXY = (
119 network_unittest.NetworkMetricTest.MakeNetworkTimelineEvent(
120 url='http://test.malware',
121 response_headers={
122 'X-Malware-Url': '1',
123 'Via': '1.1 ' + metrics.CHROME_PROXY_VIA_HEADER,
124 'Location': 'http://test.malware',
126 status=307))
128 # An HTML via proxy with the Via header.
129 EVENT_IMAGE_BYPASS = (
130 network_unittest.NetworkMetricTest.MakeNetworkTimelineEvent(
131 url='http://test.image',
132 response_headers={
133 'Chrome-Proxy': 'bypass=1',
134 'Content-Type': 'text/html',
135 'Via': '1.1 ' + metrics.CHROME_PROXY_VIA_HEADER,
137 status=502))
139 # An image fetched directly.
140 EVENT_IMAGE_DIRECT = (
141 network_unittest.NetworkMetricTest.MakeNetworkTimelineEvent(
142 url='http://test.image',
143 response_headers={
144 'Content-Type': 'image/jpeg',
145 'Content-Encoding': 'gzip',
147 body=base64.b64encode(network_unittest.IMAGE_BODY),
148 base64_encoded_body=True))
151 class ChromeProxyMetricTest(unittest.TestCase):
153 _test_proxy_info = {}
155 def _StubGetProxyInfo(self, info):
156 def stub(unused_tab, unused_url=''): # pylint: disable=W0613
157 return ChromeProxyMetricTest._test_proxy_info
158 metrics.GetProxyInfoFromNetworkInternals = stub
159 ChromeProxyMetricTest._test_proxy_info = info
161 def testChromeProxyResponse(self):
162 # An https non-proxy response.
163 resp = metrics.ChromeProxyResponse(
164 network_unittest.NetworkMetricTest.MakeNetworkTimelineEvent(
165 url='https://test.url',
166 response_headers={
167 'Content-Type': 'text/html',
168 'Content-Length': str(len(network_unittest.HTML_BODY)),
169 'Via': 'some other via',
171 body=network_unittest.HTML_BODY))
172 self.assertFalse(resp.ShouldHaveChromeProxyViaHeader())
173 self.assertFalse(resp.HasChromeProxyViaHeader())
174 self.assertTrue(resp.IsValidByViaHeader())
176 # A proxied JPEG image response
177 resp = metrics.ChromeProxyResponse(
178 network_unittest.NetworkMetricTest.MakeNetworkTimelineEvent(
179 url='http://test.image',
180 response_headers={
181 'Content-Type': 'image/jpeg',
182 'Content-Encoding': 'gzip',
183 'Via': '1.1 ' + metrics.CHROME_PROXY_VIA_HEADER,
184 'X-Original-Content-Length': str(network_unittest.IMAGE_OCL),
186 body=base64.b64encode(network_unittest.IMAGE_BODY),
187 base64_encoded_body=True))
188 self.assertTrue(resp.ShouldHaveChromeProxyViaHeader())
189 self.assertTrue(resp.HasChromeProxyViaHeader())
190 self.assertTrue(resp.IsValidByViaHeader())
192 def testChromeProxyMetricForDataSaving(self):
193 metric = metrics.ChromeProxyMetric()
194 events = [
195 EVENT_HTML_DIRECT,
196 EVENT_HTML_PROXY_VIA,
197 EVENT_IMAGE_PROXY_CACHED,
198 EVENT_IMAGE_DIRECT]
199 metric.SetEvents(events)
201 self.assertTrue(len(events), len(list(metric.IterResponses(None))))
202 results = test_page_test_results.TestPageTestResults(self)
204 metric.AddResultsForDataSaving(None, results)
205 results.AssertHasPageSpecificScalarValue('resources_via_proxy', 'count', 2)
206 results.AssertHasPageSpecificScalarValue('resources_from_cache', 'count', 1)
207 results.AssertHasPageSpecificScalarValue('resources_direct', 'count', 2)
209 # Passing in zero responses should cause a failure.
210 metric.SetEvents([])
211 no_responses_exception = False
212 try:
213 metric.AddResultsForDataSaving(None, results)
214 except metrics.ChromeProxyMetricException:
215 no_responses_exception = True
216 self.assertTrue(no_responses_exception)
218 def testChromeProxyMetricForHeaderValidation(self):
219 metric = metrics.ChromeProxyMetric()
220 metric.SetEvents([
221 EVENT_HTML_DIRECT,
222 EVENT_HTML_PROXY_VIA,
223 EVENT_IMAGE_PROXY_CACHED,
224 EVENT_IMAGE_DIRECT])
226 results = test_page_test_results.TestPageTestResults(self)
228 missing_via_exception = False
229 try:
230 metric.AddResultsForHeaderValidation(None, results)
231 except metrics.ChromeProxyMetricException:
232 missing_via_exception = True
233 # Only the HTTP image response does not have a valid Via header.
234 self.assertTrue(missing_via_exception)
236 # Two events with valid Via headers.
237 metric.SetEvents([
238 EVENT_HTML_PROXY_VIA,
239 EVENT_IMAGE_PROXY_CACHED])
240 metric.AddResultsForHeaderValidation(None, results)
241 results.AssertHasPageSpecificScalarValue('checked_via_header', 'count', 2)
243 # Passing in zero responses should cause a failure.
244 metric.SetEvents([])
245 no_responses_exception = False
246 try:
247 metric.AddResultsForHeaderValidation(None, results)
248 except metrics.ChromeProxyMetricException:
249 no_responses_exception = True
250 self.assertTrue(no_responses_exception)
252 def testChromeProxyMetricForExtraViaHeader(self):
253 metric = metrics.ChromeProxyMetric()
254 metric.SetEvents([EVENT_HTML_DIRECT,
255 EVENT_HTML_PROXY_EXTRA_VIA])
256 results = test_page_test_results.TestPageTestResults(self)
257 metric.AddResultsForExtraViaHeader(None, results, TEST_EXTRA_VIA_HEADER)
258 # The direct page should not count an extra via header, but should also not
259 # throw an exception.
260 results.AssertHasPageSpecificScalarValue('extra_via_header', 'count', 1)
262 metric.SetEvents([EVENT_HTML_PROXY_VIA])
263 exception_occurred = False
264 try:
265 metric.AddResultsForExtraViaHeader(None, results, TEST_EXTRA_VIA_HEADER)
266 except metrics.ChromeProxyMetricException:
267 exception_occurred = True
268 # The response had the chrome proxy via header, but not the extra expected
269 # via header.
270 self.assertTrue(exception_occurred)
272 def testChromeProxyMetricForBypass(self):
273 metric = metrics.ChromeProxyMetric()
274 metric.SetEvents([
275 EVENT_HTML_DIRECT,
276 EVENT_HTML_PROXY_VIA,
277 EVENT_IMAGE_PROXY_CACHED,
278 EVENT_IMAGE_DIRECT])
279 results = test_page_test_results.TestPageTestResults(self)
281 bypass_exception = False
282 try:
283 metric.AddResultsForBypass(None, results)
284 except metrics.ChromeProxyMetricException:
285 bypass_exception = True
286 # Two of the first three events have Via headers.
287 self.assertTrue(bypass_exception)
289 # Use directly fetched image only. It is treated as bypassed.
290 metric.SetEvents([EVENT_IMAGE_DIRECT])
291 metric.AddResultsForBypass(None, results)
292 results.AssertHasPageSpecificScalarValue('bypass', 'count', 1)
294 # Passing in zero responses should cause a failure.
295 metric.SetEvents([])
296 no_responses_exception = False
297 try:
298 metric.AddResultsForBypass(None, results)
299 except metrics.ChromeProxyMetricException:
300 no_responses_exception = True
301 self.assertTrue(no_responses_exception)
303 def testChromeProxyMetricForCorsBypass(self):
304 metric = metrics.ChromeProxyMetric()
305 metric.SetEvents([EVENT_HTML_PROXY_VIA,
306 EVENT_IMAGE_BYPASS,
307 EVENT_IMAGE_DIRECT])
308 results = test_page_test_results.TestPageTestResults(self)
309 metric.AddResultsForCorsBypass(None, results)
310 results.AssertHasPageSpecificScalarValue('cors_bypass', 'count', 1)
312 # Passing in zero responses should cause a failure.
313 metric.SetEvents([])
314 no_responses_exception = False
315 try:
316 metric.AddResultsForCorsBypass(None, results)
317 except metrics.ChromeProxyMetricException:
318 no_responses_exception = True
319 self.assertTrue(no_responses_exception)
321 def testChromeProxyMetricForBlockOnce(self):
322 metric = metrics.ChromeProxyMetric()
323 metric.SetEvents([EVENT_HTML_DIRECT,
324 EVENT_IMAGE_PROXY_VIA])
325 results = test_page_test_results.TestPageTestResults(self)
326 metric.AddResultsForBlockOnce(None, results)
327 results.AssertHasPageSpecificScalarValue('eligible_responses', 'count', 2)
328 results.AssertHasPageSpecificScalarValue('bypass', 'count', 1)
330 metric.SetEvents([EVENT_HTML_DIRECT,
331 EVENT_IMAGE_DIRECT])
332 exception_occurred = False
333 try:
334 metric.AddResultsForBlockOnce(None, results)
335 except metrics.ChromeProxyMetricException:
336 exception_occurred = True
337 # The second response was over direct, but was expected via proxy.
338 self.assertTrue(exception_occurred)
340 # Passing in zero responses should cause a failure.
341 metric.SetEvents([])
342 no_responses_exception = False
343 try:
344 metric.AddResultsForBlockOnce(None, results)
345 except metrics.ChromeProxyMetricException:
346 no_responses_exception = True
347 self.assertTrue(no_responses_exception)
349 def testChromeProxyMetricForSafebrowsingOn(self):
350 metric = metrics.ChromeProxyMetric()
351 metric.SetEvents([EVENT_MALWARE_PROXY])
352 results = test_page_test_results.TestPageTestResults(self)
354 metric.AddResultsForSafebrowsingOn(None, results)
355 results.AssertHasPageSpecificScalarValue(
356 'safebrowsing', 'timeout responses', 1)
358 # Clear results and metrics to test no response for safebrowsing
359 results = test_page_test_results.TestPageTestResults(self)
360 metric.SetEvents([])
361 metric.AddResultsForSafebrowsingOn(None, results)
362 results.AssertHasPageSpecificScalarValue(
363 'safebrowsing', 'timeout responses', 1)
365 def testChromeProxyMetricForHTTPFallback(self):
366 metric = metrics.ChromeProxyMetric()
367 metric.SetEvents([EVENT_HTML_PROXY_VIA_HTTP_FALLBACK,
368 EVENT_IMAGE_PROXY_VIA_HTTP_FALLBACK])
369 results = test_page_test_results.TestPageTestResults(self)
370 metric.AddResultsForHTTPFallback(None, results)
371 results.AssertHasPageSpecificScalarValue('via_fallback', 'count', 2)
373 metric.SetEvents([EVENT_HTML_PROXY_VIA,
374 EVENT_IMAGE_PROXY_VIA])
375 exception_occurred = False
376 try:
377 metric.AddResultsForHTTPFallback(None, results)
378 except metrics.ChromeProxyMetricException:
379 exception_occurred = True
380 # The responses came through the SPDY proxy, but were expected through the
381 # HTTP fallback proxy.
382 self.assertTrue(exception_occurred)
384 # Passing in zero responses should cause a failure.
385 metric.SetEvents([])
386 no_responses_exception = False
387 try:
388 metric.AddResultsForHTTPFallback(None, results)
389 except metrics.ChromeProxyMetricException:
390 no_responses_exception = True
391 self.assertTrue(no_responses_exception)
393 def testChromeProxyMetricForHTTPToDirectFallback(self):
394 metric = metrics.ChromeProxyMetric()
395 metric.SetEvents([EVENT_HTML_PROXY_VIA_HTTP_FALLBACK,
396 EVENT_HTML_DIRECT,
397 EVENT_IMAGE_DIRECT])
398 results = test_page_test_results.TestPageTestResults(self)
399 metric.AddResultsForHTTPToDirectFallback(None, results, 'test.html2')
400 results.AssertHasPageSpecificScalarValue('via_fallback', 'count', 1)
401 results.AssertHasPageSpecificScalarValue('bypass', 'count', 2)
403 metric.SetEvents([EVENT_HTML_PROXY_VIA,
404 EVENT_HTML_DIRECT])
405 exception_occurred = False
406 try:
407 metric.AddResultsForHTTPToDirectFallback(None, results, 'test.html2')
408 except metrics.ChromeProxyMetricException:
409 exception_occurred = True
410 # The first response was expected through the HTTP fallback proxy.
411 self.assertTrue(exception_occurred)
413 metric.SetEvents([EVENT_HTML_PROXY_VIA_HTTP_FALLBACK,
414 EVENT_HTML_PROXY_VIA_HTTP_FALLBACK,
415 EVENT_IMAGE_PROXY_VIA_HTTP_FALLBACK])
416 exception_occurred = False
417 try:
418 metric.AddResultsForHTTPToDirectFallback(None, results, 'test.html2')
419 except metrics.ChromeProxyMetricException:
420 exception_occurred = True
421 # All but the first response were expected to be over direct.
422 self.assertTrue(exception_occurred)
424 metric.SetEvents([EVENT_HTML_DIRECT,
425 EVENT_HTML_DIRECT,
426 EVENT_IMAGE_DIRECT])
427 exception_occurred = False
428 try:
429 metric.AddResultsForHTTPToDirectFallback(None, results, 'test.html2')
430 except metrics.ChromeProxyMetricException:
431 exception_occurred = True
432 # The first response was expected through the HTTP fallback proxy.
433 self.assertTrue(exception_occurred)
435 # Passing in zero responses should cause a failure.
436 metric.SetEvents([])
437 no_responses_exception = False
438 try:
439 metric.AddResultsForHTTPToDirectFallback(None, results, 'test.html2')
440 except metrics.ChromeProxyMetricException:
441 no_responses_exception = True
442 self.assertTrue(no_responses_exception)