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
5import sys
6import traceback
7
8from telemetry import value as value_module
9
10
11class FailureValue(value_module.Value):
12
13  def __init__(self, page, exc_info, description=None, tir_label=None,
14               grouping_keys=None):
15    """A value representing a failure when running the page.
16
17    Args:
18      page: The page where this failure occurs.
19      exc_info: The exception info (sys.exc_info()) corresponding to
20          this failure.
21    """
22    exc_type = exc_info[0].__name__
23    super(FailureValue, self).__init__(page, exc_type, '', True, description,
24                                       tir_label, grouping_keys)
25    self._exc_info = exc_info
26
27  @classmethod
28  def FromMessage(cls, page, message):
29    """Creates a failure value for a given string message.
30
31    Args:
32      page: The page where this failure occurs.
33      message: A string message describing the failure.
34    """
35    exc_info = cls._GetExcInfoFromMessage(message)
36    return FailureValue(page, exc_info)
37
38  @staticmethod
39  def _GetExcInfoFromMessage(message):
40    try:
41      raise Exception(message)
42    except Exception:
43      return sys.exc_info()
44
45  def __repr__(self):
46    if self.page:
47      page_name = self.page.display_name
48    else:
49      page_name = 'None'
50    return 'FailureValue(%s, %s)' % (
51        page_name, GetStringFromExcInfo(self._exc_info))
52
53  @property
54  def exc_info(self):
55    return self._exc_info
56
57  def GetBuildbotDataType(self, output_context):
58    return None
59
60  def GetBuildbotValue(self):
61    return None
62
63  def GetChartAndTraceNameForPerPageResult(self):
64    return None
65
66  def GetRepresentativeNumber(self):
67    return None
68
69  def GetRepresentativeString(self):
70    return None
71
72  @staticmethod
73  def GetJSONTypeName():
74    return 'failure'
75
76  def AsDict(self):
77    d = super(FailureValue, self).AsDict()
78    d['value'] = GetStringFromExcInfo(self.exc_info)
79    return d
80
81  @staticmethod
82  def FromDict(value_dict, page_dict):
83    kwargs = value_module.Value.GetConstructorKwArgs(value_dict, page_dict)
84    del kwargs['name']
85    del kwargs['units']
86    if 'important' in kwargs:
87      del kwargs['important']
88    kwargs['exc_info'] = FailureValue._GetExcInfoFromMessage(
89        value_dict['value'])
90
91    return FailureValue(**kwargs)
92
93  @classmethod
94  def MergeLikeValuesFromSamePage(cls, values):
95    assert False, 'Should not be called.'
96
97  @classmethod
98  def MergeLikeValuesFromDifferentPages(cls, values):
99    assert False, 'Should not be called.'
100
101def GetStringFromExcInfo(exc_info):
102  return ''.join(traceback.format_exception(*exc_info))
103