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.
7 from telemetry
import value
as value_module
8 from telemetry
.value
import list_of_scalar_values
9 from telemetry
.value
import none_values
10 from telemetry
.value
import summarizable
13 class ScalarValue(summarizable
.SummarizableValue
):
14 def __init__(self
, page
, name
, units
, value
, important
=True,
15 description
=None, tir_label
=None,
16 none_value_reason
=None, improvement_direction
=None,
18 """A single value (float or integer) result from a test.
20 A test that counts the number of DOM elements in a page might produce a
22 ScalarValue(page, 'num_dom_elements', 'count', num_elements)
24 super(ScalarValue
, self
).__init
__(page
, name
, units
, important
, description
,
25 tir_label
, improvement_direction
,
27 assert value
is None or isinstance(value
, numbers
.Number
)
28 none_values
.ValidateNoneValueReason(value
, none_value_reason
)
30 self
.none_value_reason
= none_value_reason
34 page_name
= self
.page
.display_name
37 return ('ScalarValue(%s, %s, %s, %s, important=%s, description=%s, '
38 'tir_label=%s, improvement_direction=%s, grouping_keys=%s') % (
46 self
.improvement_direction
,
49 def GetBuildbotDataType(self
, output_context
):
50 if self
._IsImportantGivenOutputIntent
(output_context
):
54 def GetBuildbotValue(self
):
55 # Buildbot's print_perf_results method likes to get lists for all values,
56 # even when they are scalar, so list-ize the return value.
59 def GetRepresentativeNumber(self
):
62 def GetRepresentativeString(self
):
63 return str(self
.value
)
66 def GetJSONTypeName():
70 d
= super(ScalarValue
, self
).AsDict()
71 d
['value'] = self
.value
73 if self
.none_value_reason
is not None:
74 d
['none_value_reason'] = self
.none_value_reason
79 def FromDict(value_dict
, page_dict
):
80 kwargs
= value_module
.Value
.GetConstructorKwArgs(value_dict
, page_dict
)
82 # Infinity and NaN are left out of JSON for security reasons that do not
83 # apply to our use cases, so TBMv2 serializes them as strings,
84 # but TBMv1 doesn't support them.
85 if value_dict
['value'] in ['Infinity', '-Infinity', 'NaN']:
86 kwargs
['value'] = None
87 kwargs
['none_value_reason'] = 'value was ' + value_dict
['value']
89 kwargs
['value'] = value_dict
['value']
91 if 'improvement_direction' in value_dict
:
92 kwargs
['improvement_direction'] = value_dict
['improvement_direction']
93 if 'none_value_reason' in value_dict
:
94 kwargs
['none_value_reason'] = value_dict
['none_value_reason']
96 return ScalarValue(**kwargs
)
99 def MergeLikeValuesFromSamePage(cls
, values
):
100 assert len(values
) > 0
102 return cls
._MergeLikeValues
(values
, v0
.page
, v0
.name
, v0
.grouping_keys
)
105 def MergeLikeValuesFromDifferentPages(cls
, values
):
106 assert len(values
) > 0
108 return cls
._MergeLikeValues
(values
, None, v0
.name
, v0
.grouping_keys
)
111 def _MergeLikeValues(cls
, values
, page
, name
, grouping_keys
):
114 merged_value
= [v
.value
for v
in values
]
115 none_value_reason
= None
116 if None in merged_value
:
118 merged_none_values
= [v
for v
in values
if v
.value
is None]
119 none_value_reason
= (
120 none_values
.MERGE_FAILURE_REASON
+
121 ' None values: %s' % repr(merged_none_values
))
122 return list_of_scalar_values
.ListOfScalarValues(
123 page
, name
, v0
.units
, merged_value
, important
=v0
.important
,
124 description
=v0
.description
,
125 tir_label
=value_module
.MergedTirLabel(values
),
126 none_value_reason
=none_value_reason
,
127 improvement_direction
=v0
.improvement_direction
,
128 grouping_keys
=grouping_keys
)