Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(445)

Side by Side Diff: appengine/findit/crash/culprit.py

Issue 2414523002: [Findit] Reorganizing findit_for_*.py (Closed)
Patch Set: Addressing the crash_config.fracas issue Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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
3 # found in the LICENSE file.
4
5 from collections import namedtuple
6
7 # TODO(wrengr): We do call this code from various unittests, just not
8 # from culprit_test.py; so we need to add some extra unittests there.
9 class Culprit(namedtuple('Culprit',
10 ['project', 'components', 'cls', 'regression_range', 'algorithm']
11 )): # pragma: no cover
12 """The result of successfully identifying the culprit of a crash report.
13
14 Args:
15 project (str): the most-suspected project
16 components (list of str): the suspected crbug components.
17 cls (list of ??): the suspected CLs.
18 regression_range (tuple): a pair of the last-good and first-bad versions.
19 algorithm (str): What algorithm was used to produce this object.
20 """
21 __slots__ = ()
22
23 @property
24 def fields(self):
25 return self._fields
26
27 # TODO(wrengr): better name for this method.
28 def ToDicts(self):
29 """Convert this object to a pair of anonymous dicts for JSON.
30
31 Returns:
32 (analysis_result_dict, tag_dict)
33 The analysis result is a dict like below:
34 {
35 # Indicate if Findit found any suspects_cls, project,
36 # components or regression_range.
37 "found": true,
38 "suspected_project": "chromium-v8", # Which project is most suspected.
39 "feedback_url": "https://.."
40 "suspected_cls": [
41 {
42 "revision": "commit-hash",
43 "url": "https://chromium.googlesource.com/chromium/src/+/...",
44 "review_url": "https://codereview.chromium.org/issue-number",
45 "project_path": "third_party/pdfium",
46 "author": "who@chromium.org",
47 "time": "2015-08-17 03:38:16",
48 "reason": "a plain string with '\n' as line break to expla..."
49 "reason": [('MinDistance', 1, 'minimum distance is 0.'),
50 ('TopFrame', 0.9, 'top frame is2nd frame.')],
51 "changed_files": [
52 {"file": "file_name1.cc",
53 "blame_url": "https://...",
54 "info": "minimum distance (LOC) 0, frame #2"},
55 {"file": "file_name2.cc",
56 "blame_url": "https://...",
57 "info": "minimum distance (LOC) 20, frame #4"},
58 ...
59 ],
60 "confidence": 0.60
61 },
62 ...,
63 ],
64 "regression_range": [ # Detected regression range.
65 "53.0.2765.0",
66 "53.0.2766.0"
67 ],
68 "suspected_components": [ # A list of crbug components to file bugs.
69 "Blink>JavaScript"
70 ]
71 }
72
73 The code review url might not always be available, because not all
74 commits go through code review. In that case, commit url should
75 be used instead.
76
77 The tag dict are allowed key/value pairs to tag the analysis result
78 for query and monitoring purpose on Findit side. For allowed keys,
79 please refer to crash_analysis.py and fracas_crash_analysis.py:
80 For results with normal culprit-finding algorithm: {
81 'found_suspects': True,
82 'has_regression_range': True,
83 'solution': 'core_algorithm',
84 }
85 For results using git blame without a regression range: {
86 'found_suspects': True,
87 'has_regression_range': False,
88 'solution': 'blame',
89 }
90 If nothing is found: {
91 'found_suspects': False,
92 }
93 """
94 # TODO(wrengr): reformulate the JSON stuff so we can drop fields which
95 # are empty; so that, in turn, we can get rid of the NullCulprit class.
96 return (
97 {
98 'found': (bool(self.project) or
99 bool(self.components) or
100 bool(self.cls) or
101 bool(self.regression_range)),
102 'regression_range': self.regression_range,
103 'suspected_project': self.project,
104 'suspected_components': self.components,
105 'suspected_cls': [cl.ToDict() for cl in self.cls],
106 },
107 {
108 'found_suspects': bool(self.cls),
109 'found_project': bool(self.project),
110 'found_components': bool(self.components),
111 'has_regression_range': bool(self.regression_range),
112 'solution': self.algorithm,
113 }
114 )
115
116
117 # TODO(wrengr): We do call this code from various unittests, just not
118 # from culprit_test.py; so we need to add some extra unittests there.
119 class NullCulprit(object): # pragma: no cover
Sharu Jiang 2016/10/25 18:31:44 How about let NullCulprit inherits Culprit and do
wrengr 2016/10/25 19:49:54 The big question here is whether the JSON encoding
120 """The result of failing to identify the culprit of a crash report.
121
122 This class serves as a helper so that we can avoid returning None. It
123 has all the same properties and methods as the Culprit class, but
124 returns the empty string, the empty list, or None, as appropriate. The
125 main difference compared to using Culprit with all those falsy values
126 is that the result of the ToDicts method is more minimalistic.
127
128 Ideally we'd like to be able to refactor things to avoid the need
129 for this class. Mostly that means (1) refactoring the unittests to
130 allow |Findit.FindCulprit| to return None, and (2) reformulating
131 |Culprit.ToDicts| to create minimal dicts and reformulating the JSON
132 protocol to support that.
133 """
134 __slots__ = ()
135
136 @property
137 def fields(self):
138 raise NotImplementedError()
139
140 @property
141 def project(self):
142 return ''
143
144 @property
145 def components(self):
146 return []
147
148 @property
149 def cls(self):
150 return []
151
152 @property
153 def regression_range(self):
154 # TODO(wrengr): this might should return a pair |(None, None)|
155 # instead. The desired API isn't fully specified...
156 return None
157
158 @property
159 def algorithm(self):
160 # TODO(wrengr): this might should return the empty string instead. The
161 # desired API isn't fully specified...
162 return None
163
164 def ToDicts(self):
165 return (
166 {'found': False},
167 {'found_suspects': False,
168 'has_regression_range': False}
169 )
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698