Index: tools/chrome_proxy/integration_tests/chrome_proxy_metrics.py |
diff --git a/tools/chrome_proxy/integration_tests/chrome_proxy_metrics.py b/tools/chrome_proxy/integration_tests/chrome_proxy_metrics.py |
index f21e3d8f3ed72c42adeeb8bbba5beae1aa8de6f5..a3eb12d5177fb20710604708a0e97e93c251c95f 100644 |
--- a/tools/chrome_proxy/integration_tests/chrome_proxy_metrics.py |
+++ b/tools/chrome_proxy/integration_tests/chrome_proxy_metrics.py |
@@ -3,6 +3,7 @@ |
# found in the LICENSE file. |
import logging |
+import os |
import time |
from integration_tests import network_metrics |
@@ -18,7 +19,7 @@ CHROME_PROXY_VIA_HEADER = 'Chrome-Compression-Proxy' |
class ChromeProxyResponse(network_metrics.HTTPResponse): |
- """ Represents an HTTP response from a timeleine event.""" |
+ """ Represents an HTTP response from a timeline event.""" |
def __init__(self, event): |
super(ChromeProxyResponse, self).__init__(event) |
@@ -81,6 +82,7 @@ class ChromeProxyResponse(network_metrics.HTTPResponse): |
return True |
return False |
+ |
class ChromeProxyMetric(network_metrics.NetworkMetric): |
"""A Chrome proxy timeline metric.""" |
@@ -559,3 +561,88 @@ class ChromeProxyMetric(network_metrics.NetworkMetric): |
results.current_page, 'bypass', 'count', bypass_count)) |
results.AddValue(scalar.ScalarValue( |
results.current_page, 'via', 'count', via_count)) |
+ |
sclittle
2015/04/10 23:01:49
2 blank lines
Tom Bergan
2015/04/10 23:41:05
Done.
|
+class ChromeProxyVideoMetric(network_metrics.NetworkMetric): |
+ """A Chrome proxy video metric.""" |
sclittle
2015/04/10 23:01:50
Could you add a more detailed description of the c
Tom Bergan
2015/05/01 23:48:28
Done.
|
+ def __init__(self, tab): |
+ super(ChromeProxyVideoMetric, self).__init__() |
+ with open(os.path.join(os.path.dirname(__file__), 'videowrapper.js')) as f: |
+ js = f.read() |
+ tab.ExecuteJavaScript(js) |
+ |
+ def Start(self, page, tab): |
+ tab.ExecuteJavaScript('window.__chromeProxyCreateVideoWrappers()') |
+ self.videoMetrics = None |
+ super(ChromeProxyVideoMetric, self).Start(page, tab) |
+ |
+ def Stop(self, page, tab): |
+ tab.WaitForJavaScriptExpression('window.__chromeProxyVideoLoaded', 30) |
+ m = tab.EvaluateJavaScript('window.__chromeProxyVideoMetrics') |
+ # Now wait for the video to stop playing. |
sclittle
2015/04/10 23:01:50
nit: this code seems kinda dense, could you add so
Tom Bergan
2015/04/10 23:41:05
Done.
|
+ # Give it 2x the total duration to account for buffering. |
+ waitTime = 2 * m['video_duration'] |
+ tab.WaitForJavaScriptExpression('window.__chromeProxyVideoEnded', waitTime) |
+ # Load the final metrics. |
+ m = tab.EvaluateJavaScript('window.__chromeProxyVideoMetrics') |
+ self.videoMetrics = m |
+ # Cast this to an integer as it is often approximate (for an unknown reason) |
+ m['video_duration'] = int(m['video_duration']) |
+ super(ChromeProxyVideoMetric, self).Stop(page, tab) |
+ |
+ def ResponseFromEvent(self, event): |
+ return ChromeProxyResponse(event) |
+ |
+ def AddResults(self, tab, results): |
+ raise NotImplementedError |
+ |
+ def AddResultsForProxied(self, tab, results): |
+ return self._AddResultsShared('proxied', tab, results) |
sclittle
2015/04/10 23:01:49
This 'proxied' string is used in a bunch of places
Tom Bergan
2015/04/10 23:41:05
Done.
|
+ |
+ def AddResultsForDirect(self, tab, results): |
+ return self._AddResultsShared('direct', tab, results) |
+ |
+ def _AddResultsShared(self, kind, tab, results): |
+ def err(s): |
+ raise ChromeProxyMetricException, s |
+ |
+ # Should have played the video. |
+ if not self.videoMetrics['ready']: |
+ err('%s: video not played' % kind) |
+ |
+ # Should have an HTTP response for the video. |
+ wantContentType = 'video/webm' if kind == 'proxied' else 'video/mp4' |
+ found = False |
+ for r in self.IterResponses(tab): |
+ resp = r.response |
+ if kind == 'direct' and r.HasChromeProxyViaHeader(): |
+ err('%s: page has proxied Via header' % kind) |
+ if resp.GetHeader('Content-Type') != wantContentType: |
+ continue |
+ if found: |
+ err('%s: multiple video responses' % kind) |
+ found = True |
sclittle
2015/04/10 23:01:50
nit: again, code seems kinda dense; adding some bl
Tom Bergan
2015/05/01 23:48:28
Done.
|
+ cl = resp.GetHeader('Content-Length') |
+ xocl = resp.GetHeader('X-Original-Content-Length') |
+ if cl != None: |
+ self.videoMetrics['content_length_header'] = int(cl) |
+ if xocl != None: |
+ self.videoMetrics['x_original_content_length_header'] = int(xocl) |
+ # Should have CL always. |
+ if cl == None: |
+ err('%s: missing ContentLength' % kind) |
+ # Proxied: should have CL < XOCL |
+ # Direct: should not have XOCL |
+ if kind == 'proxied': |
+ if xocl == None or int(cl) >= int(xocl): |
+ err('%s: bigger response (%s > %s)' % (kind, str(cl), str(xocl))) |
+ else: |
+ if xocl != None: |
+ err('%s: has XOriginalContentLength' % kind) |
+ |
+ if not found: |
+ err('%s: missing video response' % kind) |
+ |
+ # Finally, add all the metrics to the results. |
+ for (k,v) in self.videoMetrics.iteritems(): |
+ k = "%s_%s" % (k, kind) |
+ results.AddValue(scalar.ScalarValue(results.current_page, k, "", v)) |
sclittle
2015/04/10 23:01:49
Could you just call results.AddValue(...) inline a
Tom Bergan
2015/05/01 23:48:28
This dict is used by ChromeProxyVideoValidation (i
|