Index: tools/telemetry/telemetry/value/histogram.py |
diff --git a/tools/telemetry/telemetry/value/histogram.py b/tools/telemetry/telemetry/value/histogram.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..a681cf26b6d112fb6c44655d3a1fd76d6f424682 |
--- /dev/null |
+++ b/tools/telemetry/telemetry/value/histogram.py |
@@ -0,0 +1,97 @@ |
+# Copyright (c) 2013 The Chromium Authors. All rights reserved. |
+# Use of this source code is governed by a BSD-style license that can be |
+# found in the LICENSE file. |
+import json |
+ |
+from telemetry import value as value_module |
+from telemetry.page import perf_tests_helper |
+ |
+class HistogramValueBucket(object): |
+ def __init__(self, low, high, count=0): |
+ self.low = low |
+ self.high = high |
+ self.count = count |
+ |
+ def ToJSONString(self): |
+ return '{%s}' % ', '.join([ |
+ '"low": %i' % self.low, |
+ '"high": %i' % self.high, |
+ '"count": %i' % self.count]) |
+ |
+class HistogramValue(value_module.Value): |
+ def __init__(self, page, name, units, |
+ raw_value=None, raw_value_json=None, important=True): |
+ super(HistogramValue, self).__init__(page, name, units, important) |
+ if raw_value_json: |
+ assert raw_value == None, 'Dont specify both raw_value and raw_value_json' |
+ raw_value = json.loads(raw_value_json) |
+ if raw_value: |
+ assert 'buckets' in raw_value |
+ assert isinstance(raw_value['buckets'], list) |
+ self.buckets = [] |
+ for bucket in raw_value['buckets']: |
+ self.buckets.append(HistogramValueBucket( |
+ low=bucket['low'], |
+ high=bucket['high'], |
+ count=bucket['count'])) |
+ else: |
+ self.buckets = [] |
+ |
+ def __repr__(self): |
+ if self.page: |
+ page_name = self.page.url |
+ else: |
+ page_name = None |
+ return 'HistogramValue(%s, %s, %s, raw_json_string="%s", important=%s)' % ( |
+ page_name, |
+ self.name, self.units, |
+ self.ToJSONString(), |
+ self.important) |
+ |
+ def GetBuildbotDataType(self, output_context): |
+ if self._IsImportantGivenOutputIntent(output_context): |
+ return 'histogram' |
+ return 'unimportant-histogram' |
+ |
+ def GetBuildbotValue(self): |
+ # More buildbot insanity: perf_tests_results_helper requires the histogram |
+ # to be an array of size one. |
+ return [self.ToJSONString()] |
+ |
+ def ToJSONString(self): |
+ # This has to hand-JSONify the histogram to ensure the order of keys |
+ # produced is stable across different systems. |
+ # |
+ # This is done because the buildbot unittests are string equality |
+ # assertions. Thus, tests that contain histograms require stable |
+ # stringification of the histogram. |
+ # |
+ # Sigh, buildbot, Y U gotta be that way. |
+ return '{"buckets": [%s]}' % ( |
+ ', '.join([b.ToJSONString() for b in self.buckets])) |
+ |
+ def GetRepresentativeNumber(self): |
+ (mean, _) = perf_tests_helper.GeomMeanAndStdDevFromHistogram( |
+ self.ToJSONString()) |
+ return mean |
+ |
+ def GetRepresentativeString(self): |
+ return self.GetBuildbotValue() |
+ |
+ @classmethod |
+ def MergeLikeValuesFromSamePage(cls, values): |
+ assert len(values) > 0 |
+ v0 = values[0] |
+ return HistogramValue( |
+ v0.page, v0.name, v0.units, |
+ raw_value_json=v0.ToJSONString(), |
+ important=v0.important) |
+ |
+ @classmethod |
+ def MergeLikeValuesFromDifferentPages(cls, values, |
+ group_by_name_suffix=False): |
+ # Histograms cannot be merged across pages, at least for now. It should be |
+ # theoretically possible, just requires more work. Instead, return None. |
+ # This signals to the merging code that the data is unmergable and it will |
+ # cope accordingly. |
+ return None |