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

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

Issue 2663063007: [Predator] Switch from anonymous dict to CrashData. (Closed)
Patch Set: Rebase and fix delta test. Created 3 years, 10 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
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 from collections import defaultdict
6 from collections import namedtuple
5 import logging 7 import logging
6 from collections import namedtuple
7
8 from crash.stacktrace import Stacktrace
9 8
10 9
11 class CrashReport(namedtuple('CrashReport', 10 class _FrozenDict(dict):
12 ['crashed_version', 'signature', 'platform', 'stacktrace', 11 """An immutable ``dict`` (or some approximation thereof).
13 'regression_range'])): 12
14 """A reported crash we want to analyze. 13 The goal of this class is to render a ``dict`` hashable, so
14 that it can be used as a key in other ``dict``s, so that in
15 turn we can use our ``MemoizedFunction`` on functions taking
16 ``CrashReportWithDependencies`` as an argument.
17
18 For now, we simply define the ``__hash__`` method and assume clients
19 will not try to mutate instances after they have been stored as keys
20 in another ``dict``. In the future it may be worth taking further
21 steps to make it more difficult for clients to do such mutation.
22
23 N.B., the ``__init__`` method will clone the ``dict`` argument. There
24 doesn't seem to be an easy way around this.
25 """
26 def __hash__(self):
27 return hash(tuple(sorted(self.items())))
28
29
30 class CrashReport(namedtuple(
31 'CrashReport', ['crashed_version', 'signature', 'platform', 'stacktrace',
32 'regression_range', 'dependencies', 'dependency_rolls'])):
33 """A crash report with all information needed for analysis for clients.
15 34
16 This class comprises the inputs to the Predator library; as distinguished 35 This class comprises the inputs to the Predator library; as distinguished
17 from the Culprit class, which comprises the outputs/results of Predator's 36 from the Culprit class, which comprises the outputs/results of Predator's
18 analyses. N.B., the appengine clients conflate input and output into 37 analyses. N.B., the appengine clients conflate input and output into
19 a single CrashAnalysis(ndb.Model) class, but that's up to them; in 38 a single CrashAnalysis(ndb.Model) class, but that's up to them; in
20 the library we keep inputs and outputs entirely distinct. 39 the library we keep inputs and outputs entirely distinct.
21 40
22 Args: 41 Properties:
23 crashed_version (str): The version of Chrome in which the crash occurred. 42 crashed_version (str): The version of Chrome in which the crash occurred.
24 signature (str): The signature of the crash on the Chrome crash server. 43 signature (str): The signature of the crash on the Chrome crash server.
25 platform (str): The platform name; e.g., 'win', 'mac', 'linux', 'android', 44 platform (str): The platform affected by the crash; e.g., 'win',
26 'ios', etc. 45 'mac', 'linux', 'android', 'ios', etc.
27 stacktrace (Stacktrace): The stacktrace of the crash. N.B., this is 46 stacktrace (Stacktrace): The stacktrace of the crash. N.B., this is
28 an object generated by parsing the string containing the stack trace; 47 an object generated by parsing the string containing the stack trace;
29 we do not store the string itself. 48 we do not store the string itself.
30 regression_range (pair or None): a pair of the last-good and first-bad 49 regression_range (pair of str or None): a pair of ``last_good_version`` and
31 versions. N.B., because this is an input, it is up to clients 50 ``first_bad_version``. The regression_range can be ``None``.
32 to call ``DetectRegressionRange`` (or whatever else) in order to 51 dependencies (_FrozenDict): An immutable dict from dependency paths to
33 provide this information. In addition, while this class does 52 ``Dependency`` objects. The keys are all those deps which are
34 support storing ``None`` to indicate a missing regression range 53 used by both the ``crashed_version`` of the code, and at least
35 (because the ClusterFuzz client wants that feature), the 54 one frame in the ``stacktrace.crash_stack``.
36 CL-classifier doesn't actually support that so you won't get a 55 dependency_rolls (_FrozenDict) An immutable dict from dependency
37 very good Culprit. The Component- and project-classifiers do still 56 paths to ``DependencyRoll`` objects. The keys are all those
38 return some results at least. 57 dependencies which (1) occur in the regression range for the
58 ``platform`` where the crash occurred, (2) neither add nor delete
59 a dependency, and (3) are also keys of ``dependencies``.
39 """ 60 """
40 __slots__ = () 61 __slots__ = ()
41 62
42 def __new__(cls, crashed_version, signature, platform, stacktrace, 63 def __new__(cls, crashed_version, signature, platform, stacktrace,
43 regression_range): 64 regression_range, dependencies, dependency_rolls):
44 assert isinstance(stacktrace, Stacktrace), TypeError( 65 return super(CrashReport, cls).__new__(
45 'In the fourth argument to CrashReport constructor, ' 66 cls, crashed_version, signature, platform, stacktrace,
46 'expected Stacktrace object, but got %s object instead.' 67 tuple(regression_range) if regression_range else None,
47 % stacktrace.__class__.__name__) 68 _FrozenDict(dependencies) if dependencies else {},
48 69 _FrozenDict(dependency_rolls) if dependency_rolls else {})
49 if regression_range is None: # pragma: no cover
50 logging.warning('CrashReport.__init__: '
51 'Got ``None`` for the regression range.')
52 else:
53 # We must ensure that the regression range is immutable, both
54 # for semantic reasons and so that it is hashable as is required
55 # for memoization.
56 regression_range = tuple(regression_range)
57
58 return super(cls, CrashReport).__new__(
59 cls, crashed_version, signature, platform, stacktrace, regression_range)
OLDNEW
« no previous file with comments | « appengine/findit/crash/crash_pipeline.py ('k') | appengine/findit/crash/crash_report_with_dependencies.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698