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

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

Issue 1861373003: [Findit] Initial code of findit for crash. Add scorers to apply heuristic rules. (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Fix nits and rebase Created 4 years, 8 months 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
« no previous file with comments | « appengine/findit/crash/findit_for_crash.py ('k') | appengine/findit/crash/scorers/__init__.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 _INFINITY = 1000
6
7
8 class Result(object):
9 """Represents findit culprit result."""
10
11 def __init__(self, changelog, dep_path, component,
12 confidence=None, reason=None):
13 self.changelog = changelog
14 self.dep_path = dep_path
15 self.component = component
16 self.confidence = confidence
17 self.reason = reason
18
19 self.file_to_stack_infos = {}
20
21 def ToDict(self):
22 return {
23 'url': self.changelog.commit_url,
24 'revision': self.changelog.revision,
25 'dep_path': self.dep_path,
26 'component': self.component,
27 'author': self.changelog.author_email,
28 'time': self.changelog.author_time,
29 'reason': self.reason,
30 'confidence': self.confidence,
31 }
32
33 def ToString(self):
34 if not self.file_to_stack_infos:
35 return ''
36
37 lines = []
38 for file_path, stack_infos in self.file_to_stack_infos.iteritems():
39 line_parts = []
40 for frame, _ in stack_infos:
41 line_parts.append('%s (#%d)' % (frame.function, frame.index))
42
43 lines.append('Changed file %s which crashed in %s' % (
44 file_path, ', '.join(line_parts)))
45
46 return '\n'.join(lines)
47
48 def __str__(self):
49 return self.ToString()
50
51
52 class MatchResult(Result):
53 """Represents findit culprit result got from match algorithm."""
54
55 def __init__(self, changelog, dep_path, component,
56 confidence=None, reason=None):
57 super(MatchResult, self).__init__(
58 changelog, dep_path, component, confidence, reason)
59
60 self.min_distance = _INFINITY
61
62 def Update(self, file_path, stack_infos, blame):
63 """Updates a match result with file path and its stack_infos and blame.
64
65 When a file_path is found both shown in stacktrace and touched by
66 the revision of this result, update result with the information of
67 this file.
68
69 Inserts the file path and its stack infos, and updates the min distance
70 if less distance is found between touched lines of this result and
71 crashed lines in the file path.
72
73 Args:
74 file_path (str): File path of the crashed file.
75 stack_infos (list): List of (StackFrame, callstack priority) tuples,
76 represents frames of this file and the callstack priorities of those
77 frames.
78 blame (Blame): Blame oject of this file.
79 """
80 self.file_to_stack_infos[file_path] = stack_infos
81
82 for region in blame:
83 if region.revision != self.changelog.revision:
84 continue
85
86 region_lines = range(region.start, region.start + region.count)
87
88 for frame, _ in stack_infos:
89 self.min_distance = min(self.min_distance, self._DistanceOfTwoRegions(
90 frame.crashed_line_numbers, region_lines))
91
92 def _DistanceOfTwoRegions(self, region1, region2):
93 if set(region1).intersection(set(region2)):
94 return 0
95
96 if region1[-1] < region2[0]:
97 return region2[0] - region1[-1]
98
99 return region1[0] - region2[-1]
100
101
102 class MatchResults(dict):
103 """A dict indexing MatchResult with its revision."""
104
105 def __init__(self, ignore_cls=None):
106 super(MatchResults, self).__init__()
107 self.ignore_cls = ignore_cls
108
109 def GenerateMatchResults(self, file_path, dep_path,
110 stack_infos, changelogs, blame):
111 """Generates match results.
112
113 Match results are generated based on newly found file path, its stack_infos,
114 and all the changelogs that touched this file in the dep in regression
115 ranges, those reverted changelogs should be ignored.
116
117 Args:
118 file_path (str): File path of the crashed file.
119 dep_path (str): Path of the dependency of the file.
120 stack_infos (list): List of (StackFrame, callstack priority) tuples,
121 represents frames of this file and the callstack priorities of those
122 frames.
123 changelogs (list): List of Changelog objects in the dep in regression
124 range which touched the file.
125 blame (Blame): Blame of the file.
126 """
127 for changelog in changelogs:
128 if self.ignore_cls and changelog.revision in self.ignore_cls:
129 continue
130
131 if changelog.revision not in self:
132 # TODO(katesonia): Enable component classifier later. Get it from
133 # file_path and dep_path.
134 component = ''
135 self[changelog.revision] = MatchResult(changelog, dep_path, component)
136
137 match_result = self[changelog.revision]
138
139 match_result.Update(file_path, stack_infos, blame)
OLDNEW
« no previous file with comments | « appengine/findit/crash/findit_for_crash.py ('k') | appengine/findit/crash/scorers/__init__.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698