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 3# found in the LICENSE file. 4 5from telemetry import value as value_module 6from telemetry.value import none_values 7 8 9class ListOfStringValues(value_module.Value): 10 def __init__(self, page, name, units, values, 11 important=True, description=None, none_value_reason=None, 12 same_page_merge_policy=value_module.CONCATENATE): 13 super(ListOfStringValues, self).__init__(page, name, units, important, 14 description) 15 if values is not None: 16 assert isinstance(values, list) 17 assert len(values) > 0 18 assert all(isinstance(v, basestring) for v in values) 19 none_values.ValidateNoneValueReason(values, none_value_reason) 20 self.values = values 21 self.none_value_reason = none_value_reason 22 self.same_page_merge_policy = same_page_merge_policy 23 24 def __repr__(self): 25 if self.page: 26 page_name = self.page.url 27 else: 28 page_name = None 29 if self.same_page_merge_policy == value_module.CONCATENATE: 30 merge_policy = 'CONCATENATE' 31 else: 32 merge_policy = 'PICK_FIRST' 33 return ('ListOfStringValues(%s, %s, %s, %s, ' + 34 'important=%s, description=%s, same_page_merge_policy=%s)') % ( 35 page_name, 36 self.name, 37 self.units, 38 repr(self.values), 39 self.important, 40 self.description, 41 merge_policy) 42 43 def GetBuildbotDataType(self, output_context): 44 if self._IsImportantGivenOutputIntent(output_context): 45 return 'default' 46 return 'unimportant' 47 48 def GetBuildbotValue(self): 49 return self.values 50 51 def GetRepresentativeNumber(self): 52 return None 53 54 def GetRepresentativeString(self): 55 return repr(self.values) 56 57 def IsMergableWith(self, that): 58 return (super(ListOfStringValues, self).IsMergableWith(that) and 59 self.same_page_merge_policy == that.same_page_merge_policy) 60 61 @staticmethod 62 def GetJSONTypeName(): 63 return 'list_of_string_values' 64 65 def AsDict(self): 66 d = super(ListOfStringValues, self).AsDict() 67 d['values'] = self.values 68 69 if self.none_value_reason is not None: 70 d['none_value_reason'] = self.none_value_reason 71 72 return d 73 74 @staticmethod 75 def FromDict(value_dict, page_dict): 76 kwargs = value_module.Value.GetConstructorKwArgs(value_dict, page_dict) 77 kwargs['values'] = value_dict['values'] 78 79 if 'none_value_reason' in value_dict: 80 kwargs['none_value_reason'] = value_dict['none_value_reason'] 81 82 return ListOfStringValues(**kwargs) 83 84 @classmethod 85 def MergeLikeValuesFromSamePage(cls, values): 86 assert len(values) > 0 87 v0 = values[0] 88 89 if v0.same_page_merge_policy == value_module.PICK_FIRST: 90 return ListOfStringValues( 91 v0.page, v0.name, v0.units, 92 values[0].values, 93 important=v0.important, 94 same_page_merge_policy=v0.same_page_merge_policy, 95 none_value_reason=v0.none_value_reason) 96 97 assert v0.same_page_merge_policy == value_module.CONCATENATE 98 return cls._MergeLikeValues(values, v0.page, v0.name) 99 100 @classmethod 101 def MergeLikeValuesFromDifferentPages(cls, values, 102 group_by_name_suffix=False): 103 assert len(values) > 0 104 v0 = values[0] 105 name = v0.name_suffix if group_by_name_suffix else v0.name 106 return cls._MergeLikeValues(values, None, name) 107 108 @classmethod 109 def _MergeLikeValues(cls, values, page, name): 110 v0 = values[0] 111 merged_values = [] 112 none_value_reason = None 113 for v in values: 114 if v.values is None: 115 merged_values = None 116 none_value_reason = none_values.MERGE_FAILURE_REASON 117 break 118 merged_values.extend(v.values) 119 return ListOfStringValues( 120 page, name, v0.units, 121 merged_values, 122 important=v0.important, 123 same_page_merge_policy=v0.same_page_merge_policy, 124 none_value_reason=none_value_reason) 125