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 5import numbers 6 7from telemetry import value as value_module 8from telemetry.value import list_of_scalar_values 9from telemetry.value import none_values 10 11 12class ScalarValue(value_module.Value): 13 def __init__(self, page, name, units, value, important=True, 14 description=None, none_value_reason=None): 15 """A single value (float or integer) result from a test. 16 17 A test that counts the number of DOM elements in a page might produce a 18 scalar value: 19 ScalarValue(page, 'num_dom_elements', 'count', num_elements) 20 """ 21 super(ScalarValue, self).__init__(page, name, units, important, description) 22 assert value is None or isinstance(value, numbers.Number) 23 none_values.ValidateNoneValueReason(value, none_value_reason) 24 self.value = value 25 self.none_value_reason = none_value_reason 26 27 def __repr__(self): 28 if self.page: 29 page_name = self.page.url 30 else: 31 page_name = None 32 return 'ScalarValue(%s, %s, %s, %s, important=%s, description=%s)' % ( 33 page_name, 34 self.name, 35 self.units, 36 self.value, 37 self.important, 38 self.description) 39 40 def GetBuildbotDataType(self, output_context): 41 if self._IsImportantGivenOutputIntent(output_context): 42 return 'default' 43 return 'unimportant' 44 45 def GetBuildbotValue(self): 46 # Buildbot's print_perf_results method likes to get lists for all values, 47 # even when they are scalar, so list-ize the return value. 48 return [self.value] 49 50 def GetRepresentativeNumber(self): 51 return self.value 52 53 def GetRepresentativeString(self): 54 return str(self.value) 55 56 @staticmethod 57 def GetJSONTypeName(): 58 return 'scalar' 59 60 def AsDict(self): 61 d = super(ScalarValue, self).AsDict() 62 d['value'] = self.value 63 64 if self.none_value_reason is not None: 65 d['none_value_reason'] = self.none_value_reason 66 67 return d 68 69 @staticmethod 70 def FromDict(value_dict, page_dict): 71 kwargs = value_module.Value.GetConstructorKwArgs(value_dict, page_dict) 72 kwargs['value'] = value_dict['value'] 73 74 if 'none_value_reason' in value_dict: 75 kwargs['none_value_reason'] = value_dict['none_value_reason'] 76 77 return ScalarValue(**kwargs) 78 79 @classmethod 80 def MergeLikeValuesFromSamePage(cls, values): 81 assert len(values) > 0 82 v0 = values[0] 83 return cls._MergeLikeValues(values, v0.page, v0.name) 84 85 @classmethod 86 def MergeLikeValuesFromDifferentPages(cls, values, 87 group_by_name_suffix=False): 88 assert len(values) > 0 89 v0 = values[0] 90 name = v0.name_suffix if group_by_name_suffix else v0.name 91 return cls._MergeLikeValues(values, None, name) 92 93 @classmethod 94 def _MergeLikeValues(cls, values, page, name): 95 v0 = values[0] 96 merged_value = [v.value for v in values] 97 none_value_reason = None 98 if None in merged_value: 99 merged_value = None 100 none_value_reason = none_values.MERGE_FAILURE_REASON 101 return list_of_scalar_values.ListOfScalarValues( 102 page, name, v0.units, merged_value, important=v0.important, 103 none_value_reason=none_value_reason) 104