| 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 import copy | 5 import copy |
| 6 import json |
| 6 import logging | 7 import logging |
| 7 | 8 |
| 8 from google.appengine.ext import ndb | 9 from google.appengine.ext import ndb |
| 9 | 10 |
| 10 from common import appengine_util | 11 from common import appengine_util |
| 11 from common import chrome_dependency_fetcher | 12 from common import chrome_dependency_fetcher |
| 12 from common import constants | 13 from common import constants |
| 13 from crash.crash_report import CrashReport | 14 from crash.crash_report import CrashReport |
| 14 from lib import time_util | 15 from lib import time_util |
| 15 from model import analysis_status | 16 from model import analysis_status |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 210 self._repository).GetDependency( | 211 self._repository).GetDependency( |
| 211 model.crashed_version, | 212 model.crashed_version, |
| 212 model.platform), | 213 model.platform), |
| 213 model.signature) | 214 model.signature) |
| 214 if not stacktrace: | 215 if not stacktrace: |
| 215 logging.warning('Failed to parse the stacktrace %s', model.stack_trace) | 216 logging.warning('Failed to parse the stacktrace %s', model.stack_trace) |
| 216 return None | 217 return None |
| 217 | 218 |
| 218 return stacktrace | 219 return stacktrace |
| 219 | 220 |
| 221 def ProcessResultForPublishing(self, result, key): |
| 222 """Client specific processing of result data for publishing.""" |
| 223 raise NotImplementedError() |
| 224 |
| 225 def GetPublishableResult(self, crash_identifiers, analysis): |
| 226 """Convert a culprit result into a publishable result for client. |
| 227 |
| 228 Note, this function must be called by a concrete subclass of CrashAnalysis |
| 229 which implements the ProcessResultForPublishing method. |
| 230 |
| 231 Args: |
| 232 crash_identifiers (dict): Dict containing identifiers that can uniquely |
| 233 identify CrashAnalysis entity. |
| 234 analysis (CrashAnalysis model): Model containing culprit result and other |
| 235 analysis information. |
| 236 |
| 237 Returns: |
| 238 A dict of the given ``crash_identifiers``, this model's |
| 239 ``client_id``, and a publishable version of this model's ``result``. |
| 240 """ |
| 241 result = copy.deepcopy(analysis.result) |
| 242 if result.get('found') and 'suspected_cls' in result: |
| 243 for cl in result['suspected_cls']: |
| 244 cl['confidence'] = round(cl['confidence'], 2) |
| 245 cl.pop('reason', None) |
| 246 |
| 247 result = self.ProcessResultForPublishing(result, analysis.key.urlsafe()) |
| 248 logging.info('Publish result:\n%s', |
| 249 json.dumps(result, indent=4, sort_keys=True)) |
| 250 return { |
| 251 'crash_identifiers': crash_identifiers, |
| 252 'client_id': self.client_id, |
| 253 'result': result, |
| 254 } |
| 255 |
| 220 # TODO(wrengr): This is only called by ``CrashAnalysisPipeline.run``; | 256 # TODO(wrengr): This is only called by ``CrashAnalysisPipeline.run``; |
| 221 # we should be able to adjust things so that we only need to take in | 257 # we should be able to adjust things so that we only need to take in |
| 222 # ``crash_identifiers``, or a CrashReport, rather than taking in the | 258 # ``crash_identifiers``, or a CrashReport, rather than taking in the |
| 223 # whole model. And/or, we should just inline this there. | 259 # whole model. And/or, we should just inline this there. |
| 224 # TODO(http://crbug.com/659346): coverage tests for this class, not | 260 # TODO(http://crbug.com/659346): coverage tests for this class, not |
| 225 # just for FinditForFracas. | 261 # just for FinditForFracas. |
| 226 def FindCulprit(self, model): # pragma: no cover | 262 def FindCulprit(self, model): # pragma: no cover |
| 227 """Given a CrashAnalysis ndb.Model, return a Culprit.""" | 263 """Given a CrashAnalysis ndb.Model, return a Culprit.""" |
| 228 stacktrace = self.ParseStacktrace(model) | 264 stacktrace = self.ParseStacktrace(model) |
| 229 if stacktrace is None: | 265 if stacktrace is None: |
| 230 return None | 266 return None |
| 231 | 267 |
| 232 return self._predator.FindCulprit(CrashReport( | 268 return self._predator.FindCulprit(CrashReport( |
| 233 crashed_version = model.crashed_version, | 269 crashed_version = model.crashed_version, |
| 234 signature = model.signature, | 270 signature = model.signature, |
| 235 platform = model.platform, | 271 platform = model.platform, |
| 236 stacktrace = stacktrace, | 272 stacktrace = stacktrace, |
| 237 regression_range = model.regression_range)) | 273 regression_range = model.regression_range)) |
| OLD | NEW |