| OLD | NEW |
| 1 # Copyright 2016 The Chromium Authors. All rights reserved. | 1 # Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 from collections import namedtuple | 5 from collections import namedtuple |
| 6 | 6 |
| 7 # TODO(http://crbug.com/659346): We do call this code from various | 7 # TODO(http://crbug.com/659346): We do call this code from various |
| 8 # unittests, just not from culprit_test.py; so we need to add some extra | 8 # unittests, just not from culprit_test.py; so we need to add some extra |
| 9 # unittests there. | 9 # unittests there. |
| 10 class Culprit(namedtuple('Culprit', | 10 class Culprit(namedtuple('Culprit', |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 } | 85 } |
| 86 For results using git blame without a regression range: { | 86 For results using git blame without a regression range: { |
| 87 'found_suspects': True, | 87 'found_suspects': True, |
| 88 'has_regression_range': False, | 88 'has_regression_range': False, |
| 89 'solution': 'blame', | 89 'solution': 'blame', |
| 90 } | 90 } |
| 91 If nothing is found: { | 91 If nothing is found: { |
| 92 'found_suspects': False, | 92 'found_suspects': False, |
| 93 } | 93 } |
| 94 """ | 94 """ |
| 95 # TODO(http://crbug.com/644411): reformulate the JSON stuff so we | 95 # TODO(wrengr): will this auto-dropping of unnecessary fields cause |
| 96 # can drop fields which are empty; so that, in turn, we can get rid | 96 # any issues for JSON serialization? |
| 97 # of the NullCulprit class. | 97 result = {} |
| 98 return ( | 98 result['found'] = ( |
| 99 { | 99 bool(self.project) or |
| 100 'found': (bool(self.project) or | 100 bool(self.components) or |
| 101 bool(self.components) or | 101 bool(self.cls) or |
| 102 bool(self.cls) or | 102 bool(self.regression_range)) |
| 103 bool(self.regression_range)), | 103 if self.regression_range: |
| 104 'regression_range': self.regression_range, | 104 result['regression_range'] = self.regression_range |
| 105 'suspected_project': self.project, | 105 if self.project is not None: |
| 106 'suspected_components': self.components, | 106 result['suspected_project'] = self.project |
| 107 'suspected_cls': [cl.ToDict() for cl in self.cls], | 107 if self.components is not None: |
| 108 }, | 108 result['suspected_components'] = self.components |
| 109 { | 109 if self.cls is not None: |
| 110 'found_suspects': bool(self.cls), | 110 result['suspected_cls'] = [cl.ToDict() for cl in self.cls] |
| 111 'found_project': bool(self.project), | |
| 112 'found_components': bool(self.components), | |
| 113 'has_regression_range': bool(self.regression_range), | |
| 114 'solution': self.algorithm, | |
| 115 } | |
| 116 ) | |
| 117 | 111 |
| 112 tags = { |
| 113 'found_suspects': bool(self.cls), |
| 114 'has_regression_range': bool(self.regression_range), |
| 115 'found_project': bool(self.project), |
| 116 'found_components': bool(self.components), |
| 117 'solution': self.algorithm, |
| 118 } |
| 118 | 119 |
| 119 # TODO(http://crbug.com/659346): We do call this code from various | 120 return result, tags |
| 120 # unittests, just not from culprit_test.py; so we need to add some extra | |
| 121 # unittests there. | |
| 122 # TODO(http://crbug.com/659359): eliminate the need for this class. | |
| 123 class NullCulprit(object): # pragma: no cover | |
| 124 """The result of failing to identify the culprit of a crash report. | |
| 125 | |
| 126 This class serves as a helper so that we can avoid returning None. It | |
| 127 has all the same properties and methods as the Culprit class, but | |
| 128 returns the empty string, the empty list, or None, as appropriate. The | |
| 129 main difference compared to using Culprit with all those falsy values | |
| 130 is that the result of the ToDicts method is more minimalistic. | |
| 131 | |
| 132 Ideally we'd like to be able to refactor things to avoid the need | |
| 133 for this class. Mostly that means (1) refactoring the unittests to | |
| 134 allow ``Findit.FindCulprit`` to return None, and (2) reformulating | |
| 135 ``Culprit.ToDicts`` to create minimal dicts and reformulating the JSON | |
| 136 protocol to support that. | |
| 137 """ | |
| 138 __slots__ = () | |
| 139 | |
| 140 @property | |
| 141 def fields(self): | |
| 142 raise NotImplementedError() | |
| 143 | |
| 144 @property | |
| 145 def project(self): | |
| 146 return '' | |
| 147 | |
| 148 @property | |
| 149 def components(self): | |
| 150 return [] | |
| 151 | |
| 152 @property | |
| 153 def cls(self): | |
| 154 return [] | |
| 155 | |
| 156 @property | |
| 157 def regression_range(self): | |
| 158 return None | |
| 159 | |
| 160 @property | |
| 161 def algorithm(self): | |
| 162 return None | |
| 163 | |
| 164 def ToDicts(self): | |
| 165 return ( | |
| 166 {'found': False}, | |
| 167 {'found_suspects': False, | |
| 168 'has_regression_range': False} | |
| 169 ) | |
| OLD | NEW |