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 def testChromeProxyMetricForHeaderValidation(self
):
195 metric
= metrics
.ChromeProxyMetric()
198 EVENT_HTML_PROXY_VIA
,
199 EVENT_IMAGE_PROXY_CACHED
,
202 results
= test_page_test_results
.TestPageTestResults(self
)
204 missing_via_exception
= False
206 metric
.AddResultsForHeaderValidation(None, results
)
207 except metrics
.ChromeProxyMetricException
:
208 missing_via_exception
= True
209 # Only the HTTP image response does not have a valid Via header.
210 self
.assertTrue(missing_via_exception
)
212 # Two events with valid Via headers.
214 EVENT_HTML_PROXY_VIA
,
215 EVENT_IMAGE_PROXY_CACHED
])
216 metric
.AddResultsForHeaderValidation(None, results
)
217 results
.AssertHasPageSpecificScalarValue('checked_via_header', 'count', 2)
219 def testChromeProxyMetricForBypass(self
):
220 metric
= metrics
.ChromeProxyMetric()
223 EVENT_HTML_PROXY_VIA
,
224 EVENT_IMAGE_PROXY_CACHED
,
226 results
= test_page_test_results
.TestPageTestResults(self
)
228 bypass_exception
= False
230 metric
.AddResultsForBypass(None, results
)
231 except metrics
.ChromeProxyMetricException
:
232 bypass_exception
= True
233 # Two of the first three events have Via headers.
234 self
.assertTrue(bypass_exception
)
236 # Use directly fetched image only. It is treated as bypassed.
237 metric
.SetEvents([EVENT_IMAGE_DIRECT
])
238 metric
.AddResultsForBypass(None, results
)
239 results
.AssertHasPageSpecificScalarValue('bypass', 'count', 1)
241 def testChromeProxyMetricForCorsBypass(self
):
242 metric
= metrics
.ChromeProxyMetric()
243 metric
.SetEvents([EVENT_HTML_PROXY_VIA
,
246 results
= test_page_test_results
.TestPageTestResults(self
)
247 metric
.AddResultsForCorsBypass(None, results
)
248 results
.AssertHasPageSpecificScalarValue('cors_bypass', 'count', 1)
250 def testChromeProxyMetricForBlockOnce(self
):
251 metric
= metrics
.ChromeProxyMetric()
252 metric
.SetEvents([EVENT_HTML_DIRECT
,
253 EVENT_IMAGE_PROXY_VIA
])
254 results
= test_page_test_results
.TestPageTestResults(self
)
255 metric
.AddResultsForBlockOnce(None, results
)
256 results
.AssertHasPageSpecificScalarValue('eligible_responses', 'count', 2)
257 results
.AssertHasPageSpecificScalarValue('bypass', 'count', 1)
259 metric
.SetEvents([EVENT_HTML_DIRECT
,
261 exception_occurred
= False
263 metric
.AddResultsForBlockOnce(None, results
)
264 except metrics
.ChromeProxyMetricException
:
265 exception_occurred
= True
266 # The second response was over direct, but was expected via proxy.
267 self
.assertTrue(exception_occurred
)
269 def testChromeProxyMetricForSafebrowsingOn(self
):
270 metric
= metrics
.ChromeProxyMetric()
271 metric
.SetEvents([EVENT_MALWARE_PROXY
])
272 results
= test_page_test_results
.TestPageTestResults(self
)
274 metric
.AddResultsForSafebrowsingOn(None, results
)
275 results
.AssertHasPageSpecificScalarValue(
276 'safebrowsing', 'timeout responses', 1)
278 # Clear results and metrics to test no response for safebrowsing
279 results
= test_page_test_results
.TestPageTestResults(self
)
281 metric
.AddResultsForSafebrowsingOn(None, results
)
282 results
.AssertHasPageSpecificScalarValue(
283 'safebrowsing', 'timeout responses', 1)
285 def testChromeProxyMetricForHTTPFallback(self
):
286 metric
= metrics
.ChromeProxyMetric()
287 metric
.SetEvents([EVENT_HTML_PROXY_VIA_HTTP_FALLBACK
,
288 EVENT_IMAGE_PROXY_VIA_HTTP_FALLBACK
])
289 results
= test_page_test_results
.TestPageTestResults(self
)
290 metric
.AddResultsForHTTPFallback(None, results
)
291 results
.AssertHasPageSpecificScalarValue('via_fallback', 'count', 2)
293 metric
.SetEvents([EVENT_HTML_PROXY_VIA
,
294 EVENT_IMAGE_PROXY_VIA
])
295 exception_occurred
= False
297 metric
.AddResultsForHTTPFallback(None, results
)
298 except metrics
.ChromeProxyMetricException
:
299 exception_occurred
= True
300 # The responses came through the SPDY proxy, but were expected through the
301 # HTTP fallback proxy.
302 self
.assertTrue(exception_occurred
)
304 def testChromeProxyMetricForHTTPToDirectFallback(self
):
305 metric
= metrics
.ChromeProxyMetric()
306 metric
.SetEvents([EVENT_HTML_PROXY_VIA_HTTP_FALLBACK
,
309 results
= test_page_test_results
.TestPageTestResults(self
)
310 metric
.AddResultsForHTTPToDirectFallback(None, results
, 'test.html2')
311 results
.AssertHasPageSpecificScalarValue('via_fallback', 'count', 1)
312 results
.AssertHasPageSpecificScalarValue('bypass', 'count', 2)
314 metric
.SetEvents([EVENT_HTML_PROXY_VIA
,
316 exception_occurred
= False
318 metric
.AddResultsForHTTPToDirectFallback(None, results
, 'test.html2')
319 except metrics
.ChromeProxyMetricException
:
320 exception_occurred
= True
321 # The first response was expected through the HTTP fallback proxy.
322 self
.assertTrue(exception_occurred
)
324 metric
.SetEvents([EVENT_HTML_PROXY_VIA_HTTP_FALLBACK
,
325 EVENT_HTML_PROXY_VIA_HTTP_FALLBACK
,
326 EVENT_IMAGE_PROXY_VIA_HTTP_FALLBACK
])
327 exception_occurred
= False
329 metric
.AddResultsForHTTPToDirectFallback(None, results
, 'test.html2')
330 except metrics
.ChromeProxyMetricException
:
331 exception_occurred
= True
332 # All but the first response were expected to be over direct.
333 self
.assertTrue(exception_occurred
)
335 metric
.SetEvents([EVENT_HTML_DIRECT
,
338 exception_occurred
= False
340 metric
.AddResultsForHTTPToDirectFallback(None, results
, 'test.html2')
341 except metrics
.ChromeProxyMetricException
:
342 exception_occurred
= True
343 # The first response was expected through the HTTP fallback proxy.
344 self
.assertTrue(exception_occurred
)