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

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

Issue 2518663002: Converting various classes to namedtuples (Closed)
Patch Set: addressing nits Created 4 years 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
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 import logging 5 import logging
6 from collections import defaultdict 6 from collections import defaultdict
7 from collections import namedtuple
7 8
8 from common import chrome_dependency_fetcher 9 from common import chrome_dependency_fetcher
9 from crash import crash_util 10 from crash import crash_util
10 from crash.results import MatchResults 11 from crash.results import MatchResults
11 from crash.scorers.aggregated_scorer import AggregatedScorer 12 from crash.scorers.aggregated_scorer import AggregatedScorer
12 from crash.scorers.min_distance import MinDistance 13 from crash.scorers.min_distance import MinDistance
13 from crash.scorers.top_frame_index import TopFrameIndex 14 from crash.scorers.top_frame_index import TopFrameIndex
14 from crash.stacktrace import CallStack 15 from crash.stacktrace import CallStack
15 from crash.stacktrace import Stacktrace 16 from crash.stacktrace import Stacktrace
16 from lib.gitiles.diff import ChangeType 17 from lib.gitiles.diff import ChangeType
17 18
18 # TODO(http://crbug.com/661822): convert this into a namedtuple. 19 class ChangelistClassifier(namedtuple('ChangelistClassifier',
19 class ChangelistClassifier(object): 20 ['repository', 'top_n_frames', 'top_n_results', 'confidence_threshold'])):
20 def __init__(self, repository, 21 __slots__ = ()
22
23 def __new__(cls, repository,
21 top_n_frames, top_n_results=3, confidence_threshold=0.999): 24 top_n_frames, top_n_results=3, confidence_threshold=0.999):
22 """Args: 25 """Args:
23 repository (Repository): the Git repository for getting CLs to classify. 26 repository (Repository): the Git repository for getting CLs to classify.
24 top_n_frames (int): how many frames of each callstack to look at. 27 top_n_frames (int): how many frames of each callstack to look at.
25 top_n_results (int): maximum number of results to return. 28 top_n_results (int): maximum number of results to return.
26 confidence_threshold (float): In [0,1], above which we only return 29 confidence_threshold (float): In [0,1], above which we only return
27 the first result. 30 the first result.
28 """ 31 """
29 self._repository = repository 32 return super(cls, ChangelistClassifier).__new__(cls,
30 self.top_n_frames = top_n_frames 33 repository, top_n_frames, top_n_results, confidence_threshold)
31 self.top_n_results = top_n_results
32 self.confidence_threshold = confidence_threshold
33 34
34 def __str__(self): # pragma: no cover 35 def __str__(self): # pragma: no cover
35 return ('%s(top_n_frames=%d, top_n_results=%d, confidence_threshold=%g)' 36 return ('%s(top_n_frames=%d, top_n_results=%d, confidence_threshold=%g)'
36 % (self.__class__.__name__, 37 % (self.__class__.__name__,
37 self.top_n_frames, 38 self.top_n_frames,
38 self.top_n_results, 39 self.top_n_results,
39 self.confidence_threshold)) 40 self.confidence_threshold))
40 41
41 def __call__(self, report): 42 def __call__(self, report):
42 """Finds changelists suspected of being responsible for the crash report. 43 """Finds changelists suspected of being responsible for the crash report.
(...skipping 22 matching lines...) Expand all
65 for stack in report.stacktrace]) 66 for stack in report.stacktrace])
66 67
67 # We are only interested in the deps in crash stack (the callstack that 68 # We are only interested in the deps in crash stack (the callstack that
68 # caused the crash). 69 # caused the crash).
69 # TODO(wrengr): we may want to receive the crash deps as an argument, 70 # TODO(wrengr): we may want to receive the crash deps as an argument,
70 # so that when this method is called via Findit.FindCulprit, we avoid 71 # so that when this method is called via Findit.FindCulprit, we avoid
71 # doing redundant work creating it. 72 # doing redundant work creating it.
72 stack_deps = GetDepsInCrashStack( 73 stack_deps = GetDepsInCrashStack(
73 report.stacktrace.crash_stack, 74 report.stacktrace.crash_stack,
74 chrome_dependency_fetcher.ChromeDependencyFetcher( 75 chrome_dependency_fetcher.ChromeDependencyFetcher(
75 self._repository).GetDependency(report.crashed_version, 76 self.repository).GetDependency(report.crashed_version,
76 report.platform)) 77 report.platform))
77 78
78 # Get dep and file to changelogs, stack_info and blame dicts. 79 # Get dep and file to changelogs, stack_info and blame dicts.
79 dep_rolls = chrome_dependency_fetcher.ChromeDependencyFetcher( 80 dep_rolls = chrome_dependency_fetcher.ChromeDependencyFetcher(
80 self._repository).GetDependencyRollsDict( 81 self.repository).GetDependencyRollsDict(
81 last_good_version, first_bad_version, report.platform) 82 last_good_version, first_bad_version, report.platform)
82 83
83 # Regression of a dep added/deleted (old_revision/new_revision is None) can 84 # Regression of a dep added/deleted (old_revision/new_revision is None) can
84 # not be known for sure and this case rarely happens, so just filter them 85 # not be known for sure and this case rarely happens, so just filter them
85 # out. 86 # out.
86 regression_deps_rolls = {} 87 regression_deps_rolls = {}
87 for dep_path, dep_roll in dep_rolls.iteritems(): 88 for dep_path, dep_roll in dep_rolls.iteritems():
88 if not dep_roll.old_revision or not dep_roll.new_revision: 89 if not dep_roll.old_revision or not dep_roll.new_revision:
89 logging.info('Skip %s denpendency %s', 90 logging.info('Skip %s denpendency %s',
90 'added' if dep_roll.new_revision else 'deleted', dep_path) 91 'added' if dep_roll.new_revision else 'deleted', dep_path)
91 continue 92 continue
92 regression_deps_rolls[dep_path] = dep_roll 93 regression_deps_rolls[dep_path] = dep_roll
93 94
94 dep_to_file_to_changelogs, ignore_cls = GetChangeLogsForFilesGroupedByDeps( 95 dep_to_file_to_changelogs, ignore_cls = GetChangeLogsForFilesGroupedByDeps(
95 regression_deps_rolls, stack_deps, self._repository) 96 regression_deps_rolls, stack_deps, self.repository)
96 dep_to_file_to_stack_infos = GetStackInfosForFilesGroupedByDeps( 97 dep_to_file_to_stack_infos = GetStackInfosForFilesGroupedByDeps(
97 stacktrace, stack_deps) 98 stacktrace, stack_deps)
98 99
99 # TODO: argument order is inconsistent from others. Repository should 100 # TODO: argument order is inconsistent from others. Repository should
100 # be last argument. 101 # be last argument.
101 results = FindMatchResults(dep_to_file_to_changelogs, 102 results = FindMatchResults(dep_to_file_to_changelogs,
102 dep_to_file_to_stack_infos, 103 dep_to_file_to_stack_infos,
103 stack_deps, self._repository, ignore_cls) 104 stack_deps, self.repository, ignore_cls)
104 if not results: 105 if not results:
105 return [] 106 return []
106 107
107 # TODO(wrengr): we should be able to do this map/filter/sort in one pass. 108 # TODO(wrengr): we should be able to do this map/filter/sort in one pass.
108 # Set result.confidence, result.reasons and result.changed_files. 109 # Set result.confidence, result.reasons and result.changed_files.
109 aggregated_scorer = AggregatedScorer([TopFrameIndex(), MinDistance()]) 110 aggregated_scorer = AggregatedScorer([TopFrameIndex(), MinDistance()])
110 map(aggregated_scorer.Score, results) 111 map(aggregated_scorer.Score, results)
111 112
112 # Filter all the 0 confidence results. 113 # Filter all the 0 confidence results.
113 results = filter(lambda r: r.confidence != 0, results) 114 results = filter(lambda r: r.confidence != 0, results)
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 repository.repo_url = stack_deps[dep].repo_url 302 repository.repo_url = stack_deps[dep].repo_url
302 blame = repository.GetBlame(touched_file_path, 303 blame = repository.GetBlame(touched_file_path,
303 stack_deps[dep].revision) 304 stack_deps[dep].revision)
304 305
305 # Generate/update each result(changelog) in changelogs, blame is used 306 # Generate/update each result(changelog) in changelogs, blame is used
306 # to calculate distance between touched lines and crashed lines in file. 307 # to calculate distance between touched lines and crashed lines in file.
307 match_results.GenerateMatchResults( 308 match_results.GenerateMatchResults(
308 touched_file_path, dep, stack_infos, changelogs, blame) 309 touched_file_path, dep, stack_infos, changelogs, blame)
309 310
310 return match_results.values() 311 return match_results.values()
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698