OLD | NEW |
---|---|
1 # Copyright 2014 The Chromium Authors. All rights reserved. | 1 # Copyright 2014 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 """ | 4 """ |
5 The Value hierarchy provides a way of representing the values measurements | 5 The Value hierarchy provides a way of representing the values measurements |
6 produce such that they can be merged across runs, grouped by page, and output | 6 produce such that they can be merged across runs, grouped by page, and output |
7 to different targets. | 7 to different targets. |
8 | 8 |
9 The core Value concept provides the basic functionality: | 9 The core Value concept provides the basic functionality: |
10 - association with a page, may be none | 10 - association with a page, may be none |
(...skipping 24 matching lines...) Expand all Loading... | |
35 # value is being interpreted actually affects the conversion. This is insane, | 35 # value is being interpreted actually affects the conversion. This is insane, |
36 # but there you have it. There are three contexts in which Values are converted | 36 # but there you have it. There are three contexts in which Values are converted |
37 # for use by buildbot, represented by these output-intent values. | 37 # for use by buildbot, represented by these output-intent values. |
38 PER_PAGE_RESULT_OUTPUT_CONTEXT = 'per-page-result-output-context' | 38 PER_PAGE_RESULT_OUTPUT_CONTEXT = 'per-page-result-output-context' |
39 COMPUTED_PER_PAGE_SUMMARY_OUTPUT_CONTEXT = 'merged-pages-result-output-context' | 39 COMPUTED_PER_PAGE_SUMMARY_OUTPUT_CONTEXT = 'merged-pages-result-output-context' |
40 SUMMARY_RESULT_OUTPUT_CONTEXT = 'summary-result-output-context' | 40 SUMMARY_RESULT_OUTPUT_CONTEXT = 'summary-result-output-context' |
41 | 41 |
42 class Value(object): | 42 class Value(object): |
43 """An abstract value produced by a telemetry page test. | 43 """An abstract value produced by a telemetry page test. |
44 """ | 44 """ |
45 def __init__(self, page, name, units, important, description): | 45 def __init__( |
46 self, page, name, units, important, description, higher_is_better=None): | |
46 """A generic Value object. | 47 """A generic Value object. |
47 | 48 |
48 Args: | 49 Args: |
49 page: A Page object, may be given as None to indicate that the value | 50 page: A Page object, may be given as None to indicate that the value |
50 represents results for multiple pages. | 51 represents results for multiple pages. |
51 name: A value name string, may contain a dot. Values from the same test | 52 name: A value name string, may contain a dot. Values from the same test |
52 with the same prefix before the dot may be considered to belong to | 53 with the same prefix before the dot may be considered to belong to |
53 the same chart. | 54 the same chart. |
54 units: A units string. | 55 units: A units string. |
55 important: Whether the value is "important". Causes the value to appear | 56 important: Whether the value is "important". Causes the value to appear |
56 by default in downstream UIs. | 57 by default in downstream UIs. |
57 description: A string explaining in human-understandable terms what this | 58 description: A string explaining in human-understandable terms what this |
58 value represents. | 59 value represents. |
60 higher_is_better: Whether a higher value is an improvement (True) or a | |
61 regression (False). None if unknown. | |
tonyg
2014/12/18 17:31:35
Thinking aloud here... not all Value subclasses ha
| |
59 """ | 62 """ |
60 self.page = page | 63 self.page = page |
61 self.name = name | 64 self.name = name |
62 self.units = units | 65 self.units = units |
63 self.important = important | 66 self.important = important |
64 self.description = description | 67 self.description = description |
68 self.higher_is_better = higher_is_better | |
65 | 69 |
66 def IsMergableWith(self, that): | 70 def IsMergableWith(self, that): |
67 return (self.units == that.units and | 71 return (self.units == that.units and |
68 type(self) == type(that) and | 72 type(self) == type(that) and |
69 self.important == that.important) | 73 self.important == that.important) |
70 | 74 |
71 @classmethod | 75 @classmethod |
72 def MergeLikeValuesFromSamePage(cls, values): | 76 def MergeLikeValuesFromSamePage(cls, values): |
73 """Combines the provided list of values into a single compound value. | 77 """Combines the provided list of values into a single compound value. |
74 | 78 |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
182 'units': self.units, | 186 'units': self.units, |
183 'important': self.important | 187 'important': self.important |
184 } | 188 } |
185 | 189 |
186 if self.description: | 190 if self.description: |
187 d['description'] = self.description | 191 d['description'] = self.description |
188 | 192 |
189 if self.page: | 193 if self.page: |
190 d['page_id'] = self.page.id | 194 d['page_id'] = self.page.id |
191 | 195 |
196 if self.higher_is_better is not None: | |
197 d['higher_is_better'] = self.higher_is_better | |
198 | |
192 return d | 199 return d |
193 | 200 |
194 def AsDictWithoutBaseClassEntries(self): | 201 def AsDictWithoutBaseClassEntries(self): |
195 full_dict = self.AsDict() | 202 full_dict = self.AsDict() |
196 base_dict_keys = set(self._AsDictImpl().keys()) | 203 base_dict_keys = set(self._AsDictImpl().keys()) |
197 | 204 |
198 # Extracts only entries added by the subclass. | 205 # Extracts only entries added by the subclass. |
199 return dict([(k, v) for (k, v) in full_dict.iteritems() | 206 return dict([(k, v) for (k, v) in full_dict.iteritems() |
200 if k not in base_dict_keys]) | 207 if k not in base_dict_keys]) |
201 | 208 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
265 d['description'] = None | 272 d['description'] = None |
266 | 273 |
267 page_id = value_dict.get('page_id', None) | 274 page_id = value_dict.get('page_id', None) |
268 if page_id: | 275 if page_id: |
269 d['page'] = page_dict[int(page_id)] | 276 d['page'] = page_dict[int(page_id)] |
270 else: | 277 else: |
271 d['page'] = None | 278 d['page'] = None |
272 | 279 |
273 d['important'] = False | 280 d['important'] = False |
274 | 281 |
282 if 'higher_is_better' in value_dict: | |
283 d['higher_is_better'] = value_dict['higher_is_better'] | |
284 | |
275 return d | 285 return d |
276 | 286 |
277 def ValueNameFromTraceAndChartName(trace_name, chart_name=None): | 287 def ValueNameFromTraceAndChartName(trace_name, chart_name=None): |
278 """Mangles a trace name plus optional chart name into a standard string. | 288 """Mangles a trace name plus optional chart name into a standard string. |
279 | 289 |
280 A value might just be a bareword name, e.g. numPixels. In that case, its | 290 A value might just be a bareword name, e.g. numPixels. In that case, its |
281 chart may be None. | 291 chart may be None. |
282 | 292 |
283 But, a value might also be intended for display with other values, in which | 293 But, a value might also be intended for display with other values, in which |
284 case the chart name indicates that grouping. So, you might have | 294 case the chart name indicates that grouping. So, you might have |
(...skipping 14 matching lines...) Expand all Loading... | |
299 whereas telemetry represents values with a chart_name.trace_name convention, | 309 whereas telemetry represents values with a chart_name.trace_name convention, |
300 where chart_name is optional. This convention is also used by chart_json. | 310 where chart_name is optional. This convention is also used by chart_json. |
301 | 311 |
302 This converts from the telemetry convention to the buildbot convention, | 312 This converts from the telemetry convention to the buildbot convention, |
303 returning a 2-tuple (measurement_name, trace_name). | 313 returning a 2-tuple (measurement_name, trace_name). |
304 """ | 314 """ |
305 if '.' in value_name: | 315 if '.' in value_name: |
306 return value_name.split('.', 1) | 316 return value_name.split('.', 1) |
307 else: | 317 else: |
308 return value_name, value_name | 318 return value_name, value_name |
OLD | NEW |