Chromium Code Reviews| OLD | NEW |
|---|---|
| (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 import argparse | |
| 6 import functools | |
| 7 import logging | |
| 8 import json | |
| 9 import os | |
| 10 import sys | |
| 11 import threading | |
| 12 import traceback | |
| 13 | |
| 14 _SCRIPT_DIR = os.path.join(os.path.dirname(__file__), os.path.pardir, | |
| 15 os.path.pardir) | |
| 16 sys.path.insert(1, _SCRIPT_DIR) | |
| 17 | |
| 18 import script_util | |
| 19 script_util.SetUpSystemPaths() | |
| 20 | |
| 21 from common.chrome_dependency_fetcher import ChromeDependencyFetcher | |
| 22 from crash.crash_pipeline import FinditForClientID | |
| 23 from crash.crash_report import CrashReport | |
| 24 from crash.culprit import Culprit | |
| 25 from crash.detect_regression_range import DetectRegressionRange | |
| 26 from crash.findit_for_chromecrash import FinditForChromeCrash | |
| 27 from crash.type_enums import CrashClient | |
| 28 from crash_queries.delta_test import delta_util | |
| 29 from model.crash.crash_config import CrashConfig | |
| 30 import iterator | |
| 31 from lib.gitiles.local_git_repository import LocalGitRepository | |
| 32 import remote_api | |
| 33 | |
| 34 _FINDIT_FRACAS_FEEDBACK_URL_TEMPLATE = ( | |
| 35 'https://crash-frontend-dot-%s.appspot.com/' | |
|
stgao
2016/11/02 01:45:48
Why we have to set the module "crash-frontend" exp
Sharu Jiang
2016/11/11 23:10:26
Oops, testing purpose.
| |
| 36 'crash/fracas-result-feedback?key=%s') | |
| 37 | |
| 38 | |
| 39 def GetCrashConfigFromRemoteAPI(cls, app_id, **_): | |
|
stgao
2016/11/02 01:45:48
What's ``cls`` here?
Sharu Jiang
2016/11/11 23:10:26
It means the cls, since this is to replace class m
stgao
2016/11/14 21:34:12
Sorry, I still don't get it. Could we add a docstr
Sharu Jiang
2016/11/15 02:21:47
Sure, done.
| |
| 40 """Gets current crash config from datastore. | |
| 41 | |
| 42 The first parameter is to take the CrashConfig instance and bound method. | |
| 43 """ | |
| 44 remote_api.EnableRemoteApi(app_id) | |
| 45 # TODO(katesonia): Enable indexing by updated_ts and get the latest config. | |
| 46 version = cls._GetRootModel().query().get().current | |
| 47 for config in iterator.Iterate(cls.query(), app_id): | |
| 48 if config.key.id() == version: | |
| 49 return config | |
|
stgao
2016/11/02 01:45:49
Why we retrieve the latest version of config in th
Sharu Jiang
2016/11/11 23:10:26
CrashConfig.Get() failed and I cannot find a way t
stgao
2016/11/14 21:34:12
What failure it is? Why it failed? Can we fix it i
wrengr
2016/11/14 21:51:07
At the very least, there should be a comment (and
Sharu Jiang
2016/11/15 02:21:47
Traceback (most recent call last):
File "run-pre
| |
| 50 | |
| 51 return None | |
| 52 | |
| 53 | |
| 54 def StoreResults(crash, findit, app_id, id_to_culprits, lock, verbose=False): | |
| 55 """Stores findit result of crash into id_to_culprits dict.""" | |
| 56 try: | |
| 57 stacktrace = findit._stacktrace_parser.Parse( | |
| 58 crash['stack_trace'], | |
| 59 ChromeDependencyFetcher( | |
| 60 findit._repository).GetDependency( | |
| 61 crash['crashed_version'], | |
| 62 crash['platform'])) | |
| 63 if stacktrace: | |
| 64 culprit = findit._predator.FindCulprit(CrashReport( | |
| 65 crashed_version=crash['crashed_version'], | |
| 66 signature=crash['signature'], | |
| 67 platform=crash['platform'], | |
| 68 stacktrace=stacktrace, | |
| 69 regression_range=crash['regression_range'])) | |
| 70 else: | |
| 71 culprit = None | |
| 72 with lock: | |
| 73 id_to_culprits[crash['id']] = culprit | |
| 74 if verbose: | |
| 75 print '\n\nCrash:', _FINDIT_FRACAS_FEEDBACK_URL_TEMPLATE % (app_id, | |
| 76 crash['id']) | |
| 77 print json.dumps(culprit.ToDicts()[0] if culprit else {'found': False}, | |
| 78 indent=4, sort_keys=True) | |
| 79 except Exception: | |
| 80 id_to_culprits[crash['id']] = None | |
| 81 print 'Expection in crash %s', crash['id'] | |
| 82 print traceback.format_exc() | |
|
wrengr
2016/11/01 22:07:52
Shouldn't we throw an exception or return somethin
Sharu Jiang
2016/11/11 23:10:26
Done.
| |
| 83 | |
| 84 | |
| 85 def GetCulprits(crashes, client_id, app_id, verbose=False): | |
| 86 """Run predator analysis on crashes locally.""" | |
| 87 try: | |
| 88 origin_get = CrashConfig.Get | |
|
wrengr
2016/11/01 22:07:52
This line should be moved outside of the try block
Sharu Jiang
2016/11/11 23:10:26
Done.
| |
| 89 # Mock class method Get in CrashConfig. | |
| 90 CrashConfig.Get = functools.partial(GetCrashConfigFromRemoteAPI, | |
| 91 CrashConfig, app_id) | |
| 92 | |
| 93 findit = FinditForClientID(client_id, LocalGitRepository()) | |
| 94 id_to_culprits = {} | |
| 95 lock = threading.Lock() | |
| 96 tasks = [] | |
| 97 for crash in crashes: | |
| 98 crash['regression_range'] = DetectRegressionRange( | |
| 99 crash['historical_metadata']) | |
| 100 tasks.append({ | |
| 101 'function': StoreResults, | |
| 102 'args': [crash, findit, app_id, id_to_culprits, lock], | |
| 103 'kwargs': {'verbose': verbose} | |
| 104 }) | |
| 105 script_util.RunTasks(tasks) | |
| 106 return id_to_culprits | |
| 107 finally: | |
| 108 CrashConfig.Get = origin_get | |
| 109 | |
| 110 | |
| 111 def RunPredator(): | |
| 112 """Runs delta testing between 2 different Findit versions.""" | |
| 113 argparser = argparse.ArgumentParser( | |
| 114 description='Run azalea on a batch of crashes.') | |
|
stgao
2016/11/02 01:45:48
azalea
Sharu Jiang
2016/11/11 23:10:26
Done.
| |
| 115 argparser.add_argument('result_path', help='Path to store results') | |
| 116 argparser.add_argument('client', help=('Possible values are: fracas, cracas, ' | |
| 117 'clusterfuzz. Right now, only fracas ' | |
| 118 'is supported.')) | |
| 119 argparser.add_argument('app', help=('App engine id to get config from.')) | |
|
wrengr
2016/11/01 22:07:52
nit: unnecessary parentheses around the string.
Sharu Jiang
2016/11/11 23:10:26
Done.
| |
| 120 argparser.add_argument( | |
| 121 '--verbose', | |
| 122 '-v', | |
| 123 action='store_true', | |
| 124 default=False, | |
| 125 help='Print findit results.') | |
| 126 args = argparser.parse_args() | |
| 127 | |
| 128 crashes = json.loads(raw_input()) | |
| 129 if not crashes: | |
| 130 logging.error('Failed to get crashes info.') | |
| 131 return | |
| 132 | |
| 133 culprits = GetCulprits(crashes, args.client, args.app, args.verbose) | |
| 134 delta_util.FlushResult(culprits, args.result_path) | |
| 135 culprit_json = [c.ToDicts()[0] for c in culprits.itervalues()] | |
| 136 delta_util.FlushResult(culprit_json, | |
| 137 '%s.json' % args.result_path, | |
| 138 serializer=json) | |
| 139 | |
| 140 | |
| 141 if __name__ == '__main__': | |
| 142 # Disable the trivial loggings inside predator. | |
| 143 logging.basicConfig(level=logging.ERROR) | |
| 144 RunPredator() | |
| OLD | NEW |