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.
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
13 # Timeline events used in tests.
14 # An HTML not via proxy.
15 EVENT_HTML_DIRECT
= network_unittest
.NetworkMetricTest
.MakeNetworkTimelineEvent(
16 url
='http://test.html1',
18 'Content-Type': 'text/html',
19 'Content-Length': str(len(network_unittest
.HTML_BODY
)),
21 body
=network_unittest
.HTML_BODY
)
24 EVENT_HTML_PROXY_VIA
= (
25 network_unittest
.NetworkMetricTest
.MakeNetworkTimelineEvent(
26 url
='http://test.html2',
28 'Content-Type': 'text/html',
29 'Content-Encoding': 'gzip',
30 'X-Original-Content-Length': str(len(network_unittest
.HTML_BODY
)),
31 'Via': '1.1 ' + metrics
.CHROME_PROXY_VIA_HEADER
,
33 body
=network_unittest
.HTML_BODY
,
36 # An HTML via the HTTP fallback proxy.
37 EVENT_HTML_PROXY_VIA_HTTP_FALLBACK
= (
38 network_unittest
.NetworkMetricTest
.MakeNetworkTimelineEvent(
39 url
='http://test.html2',
41 'Content-Type': 'text/html',
42 'Content-Encoding': 'gzip',
43 'X-Original-Content-Length': str(len(network_unittest
.HTML_BODY
)),
44 'Via': '1.1 ' + metrics
.CHROME_PROXY_VIA_HEADER
,
46 body
=network_unittest
.HTML_BODY
,
49 # An image via proxy with Via header.
50 EVENT_IMAGE_PROXY_VIA
= (
51 network_unittest
.NetworkMetricTest
.MakeNetworkTimelineEvent(
52 url
='http://test.image',
54 'Content-Type': 'image/jpeg',
55 'Content-Encoding': 'gzip',
56 'X-Original-Content-Length': str(network_unittest
.IMAGE_OCL
),
57 'Via': '1.1 ' + metrics
.CHROME_PROXY_VIA_HEADER
,
59 body
=base64
.b64encode(network_unittest
.IMAGE_BODY
),
60 base64_encoded_body
=True,
63 # An image via the HTTP fallback proxy.
64 EVENT_IMAGE_PROXY_VIA_HTTP_FALLBACK
= (
65 network_unittest
.NetworkMetricTest
.MakeNetworkTimelineEvent(
66 url
='http://test.image',
68 'Content-Type': 'image/jpeg',
69 'Content-Encoding': 'gzip',
70 'X-Original-Content-Length': str(network_unittest
.IMAGE_OCL
),
71 'Via': '1.1 ' + metrics
.CHROME_PROXY_VIA_HEADER
,
73 body
=base64
.b64encode(network_unittest
.IMAGE_BODY
),
74 base64_encoded_body
=True,
77 # An image via proxy with Via header and it is cached.
78 EVENT_IMAGE_PROXY_CACHED
= (
79 network_unittest
.NetworkMetricTest
.MakeNetworkTimelineEvent(
80 url
='http://test.image',
82 'Content-Type': 'image/jpeg',
83 'Content-Encoding': 'gzip',
84 'X-Original-Content-Length': str(network_unittest
.IMAGE_OCL
),
85 'Via': '1.1 ' + metrics
.CHROME_PROXY_VIA_HEADER
,
87 body
=base64
.b64encode(network_unittest
.IMAGE_BODY
),
88 base64_encoded_body
=True,
89 served_from_cache
=True))
91 # An image fetched directly.
92 EVENT_IMAGE_DIRECT
= (
93 network_unittest
.NetworkMetricTest
.MakeNetworkTimelineEvent(
94 url
='http://test.image',
96 'Content-Type': 'image/jpeg',
97 'Content-Encoding': 'gzip',
99 body
=base64
.b64encode(network_unittest
.IMAGE_BODY
),
100 base64_encoded_body
=True))
102 # A safe-browsing malware response.
103 EVENT_MALWARE_PROXY
= (
104 network_unittest
.NetworkMetricTest
.MakeNetworkTimelineEvent(
105 url
='http://test.malware',
107 'X-Malware-Url': '1',
108 'Via': '1.1 ' + metrics
.CHROME_PROXY_VIA_HEADER
,
109 'Location': 'http://test.malware',
113 # An HTML via proxy with the Via header.
114 EVENT_IMAGE_BYPASS
= (
115 network_unittest
.NetworkMetricTest
.MakeNetworkTimelineEvent(
116 url
='http://test.image',
118 'Chrome-Proxy': 'bypass=1',
119 'Content-Type': 'text/html',
120 'Via': '1.1 ' + metrics
.CHROME_PROXY_VIA_HEADER
,
124 # An image fetched directly.
125 EVENT_IMAGE_DIRECT
= (
126 network_unittest
.NetworkMetricTest
.MakeNetworkTimelineEvent(
127 url
='http://test.image',
129 'Content-Type': 'image/jpeg',
130 'Content-Encoding': 'gzip',
132 body
=base64
.b64encode(network_unittest
.IMAGE_BODY
),
133 base64_encoded_body
=True))
136 class ChromeProxyMetricTest(unittest
.TestCase
):
138 _test_proxy_info
= {}
140 def _StubGetProxyInfo(self
, info
):
141 def stub(unused_tab
, unused_url
=''): # pylint: disable=W0613
142 return ChromeProxyMetricTest
._test
_proxy
_info
143 metrics
.GetProxyInfoFromNetworkInternals
= stub
144 ChromeProxyMetricTest
._test
_proxy
_info
= info
146 def testChromeProxyResponse(self
):
147 # An https non-proxy response.
148 resp
= metrics
.ChromeProxyResponse(
149 network_unittest
.NetworkMetricTest
.MakeNetworkTimelineEvent(
150 url
='https://test.url',
152 'Content-Type': 'text/html',
153 'Content-Length': str(len(network_unittest
.HTML_BODY
)),
154 'Via': 'some other via',
156 body
=network_unittest
.HTML_BODY
))
157 self
.assertFalse(resp
.ShouldHaveChromeProxyViaHeader())
158 self
.assertFalse(resp
.HasChromeProxyViaHeader())
159 self
.assertTrue(resp
.IsValidByViaHeader())
161 # A proxied JPEG image response
162 resp
= metrics
.ChromeProxyResponse(
163 network_unittest
.NetworkMetricTest
.MakeNetworkTimelineEvent(
164 url
='http://test.image',
166 'Content-Type': 'image/jpeg',
167 'Content-Encoding': 'gzip',
168 'Via': '1.1 ' + metrics
.CHROME_PROXY_VIA_HEADER
,
169 'X-Original-Content-Length': str(network_unittest
.IMAGE_OCL
),
171 body
=base64
.b64encode(network_unittest
.IMAGE_BODY
),
172 base64_encoded_body
=True))
173 self
.assertTrue(resp
.ShouldHaveChromeProxyViaHeader())
174 self
.assertTrue(resp
.HasChromeProxyViaHeader())
175 self
.assertTrue(resp
.IsValidByViaHeader())
177 def testChromeProxyMetricForDataSaving(self
):
178 metric
= metrics
.ChromeProxyMetric()
181 EVENT_HTML_PROXY_VIA
,
182 EVENT_IMAGE_PROXY_CACHED
,
184 metric
.SetEvents(events
)
186 self
.assertTrue(len(events
), len(list(metric
.IterResponses(None))))
187 results
= test_page_test_results
.TestPageTestResults(self
)
189 metric
.AddResultsForDataSaving(None, results
)
190 results
.AssertHasPageSpecificScalarValue('resources_via_proxy', 'count', 2)
191 results
.AssertHasPageSpecificScalarValue('resources_from_cache', 'count', 1)
192 results
.AssertHasPageSpecificScalarValue('resources_direct', 'count', 2)
194 # Passing in zero responses should cause a failure.
196 no_responses_exception
= False
198 metric
.AddResultsForDataSaving(None, results
)
199 except metrics
.ChromeProxyMetricException
:
200 no_responses_exception
= True
201 self
.assertTrue(no_responses_exception
)
203 def testChromeProxyMetricForHeaderValidation(self
):
204 metric
= metrics
.ChromeProxyMetric()
207 EVENT_HTML_PROXY_VIA
,
208 EVENT_IMAGE_PROXY_CACHED
,
211 results
= test_page_test_results
.TestPageTestResults(self
)
213 missing_via_exception
= False
215 metric
.AddResultsForHeaderValidation(None, results
)
216 except metrics
.ChromeProxyMetricException
:
217 missing_via_exception
= True
218 # Only the HTTP image response does not have a valid Via header.
219 self
.assertTrue(missing_via_exception
)
221 # Two events with valid Via headers.
223 EVENT_HTML_PROXY_VIA
,
224 EVENT_IMAGE_PROXY_CACHED
])
225 metric
.AddResultsForHeaderValidation(None, results
)
226 results
.AssertHasPageSpecificScalarValue('checked_via_header', 'count', 2)
228 # Passing in zero responses should cause a failure.
230 no_responses_exception
= False
232 metric
.AddResultsForHeaderValidation(None, results
)
233 except metrics
.ChromeProxyMetricException
:
234 no_responses_exception
= True
235 self
.assertTrue(no_responses_exception
)
237 def testChromeProxyMetricForBypass(self
):
238 metric
= metrics
.ChromeProxyMetric()
241 EVENT_HTML_PROXY_VIA
,
242 EVENT_IMAGE_PROXY_CACHED
,
244 results
= test_page_test_results
.TestPageTestResults(self
)
246 bypass_exception
= False
248 metric
.AddResultsForBypass(None, results
)
249 except metrics
.ChromeProxyMetricException
:
250 bypass_exception
= True
251 # Two of the first three events have Via headers.
252 self
.assertTrue(bypass_exception
)
254 # Use directly fetched image only. It is treated as bypassed.
255 metric
.SetEvents([EVENT_IMAGE_DIRECT
])
256 metric
.AddResultsForBypass(None, results
)
257 results
.AssertHasPageSpecificScalarValue('bypass', 'count', 1)
259 # Passing in zero responses should cause a failure.
261 no_responses_exception
= False
263 metric
.AddResultsForBypass(None, results
)
264 except metrics
.ChromeProxyMetricException
:
265 no_responses_exception
= True
266 self
.assertTrue(no_responses_exception
)
268 def testChromeProxyMetricForCorsBypass(self
):
269 metric
= metrics
.ChromeProxyMetric()
270 metric
.SetEvents([EVENT_HTML_PROXY_VIA
,
273 results
= test_page_test_results
.TestPageTestResults(self
)
274 metric
.AddResultsForCorsBypass(None, results
)
275 results
.AssertHasPageSpecificScalarValue('cors_bypass', 'count', 1)
277 # Passing in zero responses should cause a failure.
279 no_responses_exception
= False
281 metric
.AddResultsForCorsBypass(None, results
)
282 except metrics
.ChromeProxyMetricException
:
283 no_responses_exception
= True
284 self
.assertTrue(no_responses_exception
)
286 def testChromeProxyMetricForBlockOnce(self
):
287 metric
= metrics
.ChromeProxyMetric()
288 metric
.SetEvents([EVENT_HTML_DIRECT
,
289 EVENT_IMAGE_PROXY_VIA
])
290 results
= test_page_test_results
.TestPageTestResults(self
)
291 metric
.AddResultsForBlockOnce(None, results
)
292 results
.AssertHasPageSpecificScalarValue('eligible_responses', 'count', 2)
293 results
.AssertHasPageSpecificScalarValue('bypass', 'count', 1)
295 metric
.SetEvents([EVENT_HTML_DIRECT
,
297 exception_occurred
= False
299 metric
.AddResultsForBlockOnce(None, results
)
300 except metrics
.ChromeProxyMetricException
:
301 exception_occurred
= True
302 # The second response was over direct, but was expected via proxy.
303 self
.assertTrue(exception_occurred
)
305 # Passing in zero responses should cause a failure.
307 no_responses_exception
= False
309 metric
.AddResultsForBlockOnce(None, results
)
310 except metrics
.ChromeProxyMetricException
:
311 no_responses_exception
= True
312 self
.assertTrue(no_responses_exception
)
314 def testChromeProxyMetricForSafebrowsingOn(self
):
315 metric
= metrics
.ChromeProxyMetric()
316 metric
.SetEvents([EVENT_MALWARE_PROXY
])
317 results
= test_page_test_results
.TestPageTestResults(self
)
319 metric
.AddResultsForSafebrowsingOn(None, results
)
320 results
.AssertHasPageSpecificScalarValue(
321 'safebrowsing', 'timeout responses', 1)
323 # Clear results and metrics to test no response for safebrowsing
324 results
= test_page_test_results
.TestPageTestResults(self
)
326 metric
.AddResultsForSafebrowsingOn(None, results
)
327 results
.AssertHasPageSpecificScalarValue(
328 'safebrowsing', 'timeout responses', 1)
330 def testChromeProxyMetricForHTTPFallback(self
):
331 metric
= metrics
.ChromeProxyMetric()
332 metric
.SetEvents([EVENT_HTML_PROXY_VIA_HTTP_FALLBACK
,
333 EVENT_IMAGE_PROXY_VIA_HTTP_FALLBACK
])
334 results
= test_page_test_results
.TestPageTestResults(self
)
335 metric
.AddResultsForHTTPFallback(None, results
)
336 results
.AssertHasPageSpecificScalarValue('via_fallback', 'count', 2)
338 metric
.SetEvents([EVENT_HTML_PROXY_VIA
,
339 EVENT_IMAGE_PROXY_VIA
])
340 exception_occurred
= False
342 metric
.AddResultsForHTTPFallback(None, results
)
343 except metrics
.ChromeProxyMetricException
:
344 exception_occurred
= True
345 # The responses came through the SPDY proxy, but were expected through the
346 # HTTP fallback proxy.
347 self
.assertTrue(exception_occurred
)
349 # Passing in zero responses should cause a failure.
351 no_responses_exception
= False
353 metric
.AddResultsForHTTPFallback(None, results
)
354 except metrics
.ChromeProxyMetricException
:
355 no_responses_exception
= True
356 self
.assertTrue(no_responses_exception
)
358 def testChromeProxyMetricForHTTPToDirectFallback(self
):
359 metric
= metrics
.ChromeProxyMetric()
360 metric
.SetEvents([EVENT_HTML_PROXY_VIA_HTTP_FALLBACK
,
363 results
= test_page_test_results
.TestPageTestResults(self
)
364 metric
.AddResultsForHTTPToDirectFallback(None, results
, 'test.html2')
365 results
.AssertHasPageSpecificScalarValue('via_fallback', 'count', 1)
366 results
.AssertHasPageSpecificScalarValue('bypass', 'count', 2)
368 metric
.SetEvents([EVENT_HTML_PROXY_VIA
,
370 exception_occurred
= False
372 metric
.AddResultsForHTTPToDirectFallback(None, results
, 'test.html2')
373 except metrics
.ChromeProxyMetricException
:
374 exception_occurred
= True
375 # The first response was expected through the HTTP fallback proxy.
376 self
.assertTrue(exception_occurred
)
378 metric
.SetEvents([EVENT_HTML_PROXY_VIA_HTTP_FALLBACK
,
379 EVENT_HTML_PROXY_VIA_HTTP_FALLBACK
,
380 EVENT_IMAGE_PROXY_VIA_HTTP_FALLBACK
])
381 exception_occurred
= False
383 metric
.AddResultsForHTTPToDirectFallback(None, results
, 'test.html2')
384 except metrics
.ChromeProxyMetricException
:
385 exception_occurred
= True
386 # All but the first response were expected to be over direct.
387 self
.assertTrue(exception_occurred
)
389 metric
.SetEvents([EVENT_HTML_DIRECT
,
392 exception_occurred
= False
394 metric
.AddResultsForHTTPToDirectFallback(None, results
, 'test.html2')
395 except metrics
.ChromeProxyMetricException
:
396 exception_occurred
= True
397 # The first response was expected through the HTTP fallback proxy.
398 self
.assertTrue(exception_occurred
)
400 # Passing in zero responses should cause a failure.
402 no_responses_exception
= False
404 metric
.AddResultsForHTTPToDirectFallback(None, results
, 'test.html2')
405 except metrics
.ChromeProxyMetricException
:
406 no_responses_exception
= True
407 self
.assertTrue(no_responses_exception
)