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 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',
20 'Content-Type': 'text/html',
21 'Content-Length': str(len(network_unittest
.HTML_BODY
)),
23 body
=network_unittest
.HTML_BODY
)
26 EVENT_HTML_PROXY_VIA
= (
27 network_unittest
.NetworkMetricTest
.MakeNetworkTimelineEvent(
28 url
='http://test.html2',
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
,
38 # An HTML via proxy with extra header.
39 EVENT_HTML_PROXY_EXTRA_VIA
= (
40 network_unittest
.NetworkMetricTest
.MakeNetworkTimelineEvent(
41 url
='http://test.html2',
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
,
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',
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
,
65 # An image via proxy with Via header.
66 EVENT_IMAGE_PROXY_VIA
= (
67 network_unittest
.NetworkMetricTest
.MakeNetworkTimelineEvent(
68 url
='http://test.image',
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,
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',
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,
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',
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',
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',
123 'X-Malware-Url': '1',
124 'Via': '1.1 ' + common_metrics
.CHROME_PROXY_VIA_HEADER
,
125 'Location': 'http://test.malware',
129 # An HTML via proxy with the Via header.
130 EVENT_IMAGE_BYPASS
= (
131 network_unittest
.NetworkMetricTest
.MakeNetworkTimelineEvent(
132 url
='http://test.image',
134 'Chrome-Proxy': 'bypass=1',
135 'Content-Type': 'text/html',
136 'Via': '1.1 ' + common_metrics
.CHROME_PROXY_VIA_HEADER
,
140 # An image fetched directly.
141 EVENT_IMAGE_DIRECT
= (
142 network_unittest
.NetworkMetricTest
.MakeNetworkTimelineEvent(
143 url
='http://test.image',
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()
166 EVENT_HTML_PROXY_VIA
,
167 EVENT_IMAGE_PROXY_CACHED
,
170 results
= test_page_test_results
.TestPageTestResults(self
)
172 missing_via_exception
= False
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.
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.
189 no_responses_exception
= False
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
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
214 self
.assertTrue(exception_occurred
)
216 def testChromeProxyMetricForBypass(self
):
217 metric
= metrics
.ChromeProxyMetric()
220 EVENT_HTML_PROXY_VIA
,
221 EVENT_IMAGE_PROXY_CACHED
,
223 results
= test_page_test_results
.TestPageTestResults(self
)
225 bypass_exception
= False
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.
240 no_responses_exception
= False
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
,
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.
258 no_responses_exception
= False
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
,
276 exception_occurred
= False
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.
286 no_responses_exception
= False
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
)
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
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.
330 no_responses_exception
= False
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
,
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
,
349 exception_occurred
= False
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
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
,
371 exception_occurred
= False
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.
381 no_responses_exception
= False
383 metric
.AddResultsForHTTPToDirectFallback(None, results
, 'test.html2')
384 except common_metrics
.ChromeProxyMetricException
:
385 no_responses_exception
= True
386 self
.assertTrue(no_responses_exception
)