histogram.py revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
1# Copyright 2013 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. 4import json 5 6from telemetry import value as value_module 7from telemetry import perf_tests_helper 8 9class HistogramValueBucket(object): 10 def __init__(self, low, high, count=0): 11 self.low = low 12 self.high = high 13 self.count = count 14 15 def ToJSONString(self): 16 return '{%s}' % ', '.join([ 17 '"low": %i' % self.low, 18 '"high": %i' % self.high, 19 '"count": %i' % self.count]) 20 21class HistogramValue(value_module.Value): 22 def __init__(self, page, name, units, 23 raw_value=None, raw_value_json=None, important=True): 24 super(HistogramValue, self).__init__(page, name, units, important) 25 if raw_value_json: 26 assert raw_value == None, 'Dont specify both raw_value and raw_value_json' 27 raw_value = json.loads(raw_value_json) 28 if raw_value: 29 assert 'buckets' in raw_value 30 assert isinstance(raw_value['buckets'], list) 31 self.buckets = [] 32 for bucket in raw_value['buckets']: 33 self.buckets.append(HistogramValueBucket( 34 low=bucket['low'], 35 high=bucket['high'], 36 count=bucket['count'])) 37 else: 38 self.buckets = [] 39 40 def __repr__(self): 41 if self.page: 42 page_name = self.page.url 43 else: 44 page_name = None 45 return 'HistogramValue(%s, %s, %s, raw_json_string="%s", important=%s)' % ( 46 page_name, 47 self.name, self.units, 48 self.ToJSONString(), 49 self.important) 50 51 def GetBuildbotDataType(self, output_context): 52 if self._IsImportantGivenOutputIntent(output_context): 53 return 'histogram' 54 return 'unimportant-histogram' 55 56 def GetBuildbotValue(self): 57 # More buildbot insanity: perf_tests_results_helper requires the histogram 58 # to be an array of size one. 59 return [self.ToJSONString()] 60 61 def ToJSONString(self): 62 # This has to hand-JSONify the histogram to ensure the order of keys 63 # produced is stable across different systems. 64 # 65 # This is done because the buildbot unittests are string equality 66 # assertions. Thus, tests that contain histograms require stable 67 # stringification of the histogram. 68 # 69 # Sigh, buildbot, Y U gotta be that way. 70 return '{"buckets": [%s]}' % ( 71 ', '.join([b.ToJSONString() for b in self.buckets])) 72 73 def GetRepresentativeNumber(self): 74 (mean, _) = perf_tests_helper.GeomMeanAndStdDevFromHistogram( 75 self.ToJSONString()) 76 return mean 77 78 def GetRepresentativeString(self): 79 return self.GetBuildbotValue() 80 81 @classmethod 82 def MergeLikeValuesFromSamePage(cls, values): 83 assert len(values) > 0 84 v0 = values[0] 85 return HistogramValue( 86 v0.page, v0.name, v0.units, 87 raw_value_json=v0.ToJSONString(), 88 important=v0.important) 89 90 @classmethod 91 def MergeLikeValuesFromDifferentPages(cls, values, 92 group_by_name_suffix=False): 93 # Histograms cannot be merged across pages, at least for now. It should be 94 # theoretically possible, just requires more work. Instead, return None. 95 # This signals to the merging code that the data is unmergable and it will 96 # cope accordingly. 97 return None 98