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