blob: d57f6f57c523980992e9351d94e83d0b1ce5dd3b [file] [log] [blame]
# Copyright 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 import perf_tests_helper
class HistogramValueBucket(object):
def __init__(self, low, high, count=0):
self.low = low
self.high = high
self.count = count
def AsDict(self):
return {
'low': self.low,
'high': self.high,
'count': self.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()
def GetJSONTypeName(self):
return 'histogram'
def AsDict(self):
d = super(HistogramValue, self).AsDict()
d['buckets'] = [b.AsDict() for b in self.buckets]
return d
@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