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