| 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 import logging | 6 import logging |
| 7 import re | 7 import re |
| 8 | 8 |
| 9 from crash.classifier import Classifier | 9 from crash.occurrence import RankByOccurrence |
| 10 | 10 |
| 11 | 11 |
| 12 # TODO(wrengr): write coverage tests the old version was lacking. | 12 # TODO(wrengr): write coverage tests the old version was lacking. |
| 13 class Component(namedtuple('Component', | 13 class Component(namedtuple('Component', |
| 14 ['component_name', 'path_regex', 'function_regex'])): # pragma: no cover | 14 ['component_name', 'path_regex', 'function_regex'])): # pragma: no cover |
| 15 """A representation of a "component" in Chromium. | 15 """A representation of a "component" in Chromium. |
| 16 | 16 |
| 17 For example: 'Blink>DOM' or 'Blink>HTML'. Notably, a component knows | 17 For example: 'Blink>DOM' or 'Blink>HTML'. Notably, a component knows |
| 18 how to identify itself. Hence, given a stack frame or change list | 18 how to identify itself. Hence, given a stack frame or change list |
| 19 or whatever, we ask the Component whether it matches that frame, | 19 or whatever, we ask the Component whether it matches that frame, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 31 if not self.path_regex.match(frame.dep_path + frame.file_path): | 31 if not self.path_regex.match(frame.dep_path + frame.file_path): |
| 32 return False | 32 return False |
| 33 | 33 |
| 34 # We interpret function_regex=None to mean the regex that matches | 34 # We interpret function_regex=None to mean the regex that matches |
| 35 # everything. | 35 # everything. |
| 36 if not self.function_regex: | 36 if not self.function_regex: |
| 37 return True | 37 return True |
| 38 return self.function_regex.match(frame.function) | 38 return self.function_regex.match(frame.function) |
| 39 | 39 |
| 40 | 40 |
| 41 class ComponentClassifier(Classifier): | 41 class ComponentClassifier(object): |
| 42 """Determines the component of a crash. | 42 """Determines the component of a crash. |
| 43 | 43 |
| 44 For example: ['Blink>DOM', 'Blink>HTML']. | 44 For example: ['Blink>DOM', 'Blink>HTML']. |
| 45 """ | 45 """ |
| 46 | 46 |
| 47 def __init__(self, components, top_n): | 47 def __init__(self, components, top_n): |
| 48 """Build a classifier for components. | 48 """Build a classifier for components. |
| 49 | 49 |
| 50 Args: | 50 Args: |
| 51 components (list of crash.component.Component): the components to | 51 components (list of crash.component.Component): the components to |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 def Classify(self, results, crash_stack): | 83 def Classify(self, results, crash_stack): |
| 84 """Classifies project of a crash. | 84 """Classifies project of a crash. |
| 85 | 85 |
| 86 Args: | 86 Args: |
| 87 results (list of Result): Culprit results. | 87 results (list of Result): Culprit results. |
| 88 crash_stack (CallStack): The callstack that caused the crash. | 88 crash_stack (CallStack): The callstack that caused the crash. |
| 89 | 89 |
| 90 Returns: | 90 Returns: |
| 91 List of top 2 components. | 91 List of top 2 components. |
| 92 """ | 92 """ |
| 93 return self._Classify(results, crash_stack, self.top_n, 2) | 93 # If |results| are available, we use the components from there since |
| 94 # they're more reliable than the ones from the |crash_stack|. |
| 95 if results: |
| 96 classes = map(self.GetClassFromResult, results[:self.top_n]) |
| 97 else: |
| 98 classes = map(self.GetClassFromStackFrame, crash_stack[:self.top_n]) |
| 99 |
| 100 return RankByOccurrence(classes, 2) |
| OLD | NEW |