| 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 json | 5 import json |
| 6 import logging | 6 import logging |
| 7 import os | 7 import os |
| 8 import pickle | 8 import pickle |
| 9 import subprocess | 9 import subprocess |
| 10 | 10 |
| 11 from crash_queries import crash_iterator | 11 from crash_queries import crash_iterator |
| 12 from crash_queries.delta_test import delta_util | 12 from crash_queries.delta_test import delta_util |
| 13 | 13 |
| 14 AZALEA_RESULTS_DIRECTORY = os.path.join(os.path.dirname(__file__), | 14 PREDATOR_RESULTS_DIRECTORY = os.path.join(os.path.dirname(__file__), |
| 15 'azalea_results') | 15 'predator_results') |
| 16 DELTA_TEST_DIRECTORY = os.path.dirname(__file__) | 16 DELTA_TEST_DIRECTORY = os.path.dirname(__file__) |
| 17 CRASH_FIELDS = ['crashed_version', 'stack_trace', 'signature', |
| 18 'platform', 'client_id', 'regression_range', |
| 19 'customized_data', 'historical_metadata'] |
| 17 | 20 |
| 18 | 21 |
| 19 class Delta(object): | 22 class Delta(object): |
| 20 """Stands for delta between two results. | 23 """Stands for delta between two results. |
| 21 | 24 |
| 22 Note, the 2 results should be the same kind and have the same structure. | 25 Note, the 2 results should be the same kind and have the same structure. |
| 23 """ | 26 """ |
| 24 | 27 |
| 25 def __init__(self, result1, result2, fields): | 28 def __init__(self, result1, result2, fields): |
| 26 self._result1 = result1 | 29 self._result1 = result1 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 96 continue | 99 continue |
| 97 | 100 |
| 98 result2 = set2[result_id] | 101 result2 = set2[result_id] |
| 99 delta = Delta(result1, result2, result1.fields) | 102 delta = Delta(result1, result2, result1.fields) |
| 100 if delta: | 103 if delta: |
| 101 deltas[result_id] = delta | 104 deltas[result_id] = delta |
| 102 | 105 |
| 103 return deltas | 106 return deltas |
| 104 | 107 |
| 105 | 108 |
| 106 def GetResults(crashes, client_id, git_hash, result_path, verbose=False): | 109 def GetResults(crashes, client_id, app_id, |
| 110 git_hash, result_path, verbose=False): |
| 107 """Returns an evaluator function to compute delta between 2 findit githashes. | 111 """Returns an evaluator function to compute delta between 2 findit githashes. |
| 108 | 112 |
| 109 Args: | 113 Args: |
| 110 crashes (list): A list of crash infos. | 114 crashes (list): A list of crash infos. |
| 111 client_id (str): Possible values - fracas/cracas/clustefuzz. | 115 client_id (str): Possible values - fracas/cracas/clustefuzz. |
| 116 app_id (str): Appengine app id to query. |
| 112 git_hash (str): A git hash of findit repository. | 117 git_hash (str): A git hash of findit repository. |
| 113 result_path (str): file path for subprocess to write results on. | 118 result_path (str): file path for subprocess to write results on. |
| 114 verbose (bool): If True, print all the findit results. | 119 verbose (bool): If True, print all the findit results. |
| 115 | 120 |
| 116 Return: | 121 Return: |
| 117 A dict mapping crash id to culprit for every crashes analyzed by | 122 A dict mapping crash id to culprit for every crashes analyzed by |
| 118 git_hash version. | 123 git_hash version. |
| 119 """ | 124 """ |
| 120 if not crashes: | 125 if not crashes: |
| 121 return {} | 126 return {} |
| 122 | 127 |
| 123 if verbose: | 128 if verbose: |
| 124 logging.info('\n\n***************************') | 129 logging.info('***************************') |
| 125 logging.info('Switching to git %s', git_hash) | 130 logging.info('Switching to git %s', git_hash) |
| 126 logging.info('***************************\n\n') | 131 logging.info('***************************\n\n') |
| 127 | 132 |
| 128 with open(os.devnull, 'w') as null_handle: | 133 with open(os.devnull, 'w') as null_handle: |
| 129 subprocess.check_call( | 134 subprocess.check_call( |
| 130 'cd %s; git checkout %s' % (DELTA_TEST_DIRECTORY, git_hash), | 135 'cd %s; git checkout %s' % (DELTA_TEST_DIRECTORY, git_hash), |
| 131 stdout=null_handle, | 136 stdout=null_handle, |
| 132 stderr=null_handle, | 137 stderr=null_handle, |
| 133 shell=True) | 138 shell=True) |
| 134 | 139 |
| 135 if not os.path.exists(result_path): | 140 if not os.path.exists(result_path): |
| 136 args = ['python', 'run-predator.py', result_path, '--client', client_id] | 141 args = ['python', 'run-predator.py', result_path, client_id, app_id] |
| 137 if verbose: | 142 if verbose: |
| 138 args.append('--verbose') | 143 args.append('--verbose') |
| 139 p = subprocess.Popen(args, stdin=subprocess.PIPE) | 144 p = subprocess.Popen(args, stdin=subprocess.PIPE) |
| 140 # TODO(katesonia): Cache crashes for crash_iterator and let subprocess read | 145 # TODO(katesonia): Cache crashes for crash_iterator and let subprocess read |
| 141 # corresponding cache file instead. | 146 # corresponding cache file instead. |
| 142 p.communicate(input=json.dumps(crashes)) | 147 p.communicate(input=json.dumps(crashes)) |
| 143 else: | 148 else: |
| 144 logging.info('\nLoading results from %s', result_path) | 149 logging.info('\nLoading results from %s', result_path) |
| 145 | 150 |
| 146 if not os.path.exists(result_path): | 151 if not os.path.exists(result_path): |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 178 deltas (dict): Mappings id to delta for each culprit value. | 183 deltas (dict): Mappings id to delta for each culprit value. |
| 179 crash_count (int): Total count of all the crashes. | 184 crash_count (int): Total count of all the crashes. |
| 180 """ | 185 """ |
| 181 head_branch_name = subprocess.check_output( | 186 head_branch_name = subprocess.check_output( |
| 182 ['git', 'rev-parse', '--abbrev-ref', 'HEAD']).replace('\n', '') | 187 ['git', 'rev-parse', '--abbrev-ref', 'HEAD']).replace('\n', '') |
| 183 try: | 188 try: |
| 184 deltas = {} | 189 deltas = {} |
| 185 crash_count = 0 | 190 crash_count = 0 |
| 186 for index, crashes in enumerate( | 191 for index, crashes in enumerate( |
| 187 crash_iterator.IterateCrashes(client_id, app_id, | 192 crash_iterator.IterateCrashes(client_id, app_id, |
| 193 fields=CRASH_FIELDS, |
| 188 property_values=property_values, | 194 property_values=property_values, |
| 189 start_date=start_date, | 195 start_date=start_date, |
| 190 end_date=end_date, | 196 end_date=end_date, |
| 191 batch_size=batch_size, | 197 batch_size=batch_size, |
| 192 batch_run=True)): | 198 batch_run=True)): |
| 193 | 199 |
| 194 results = [] | 200 results = [] |
| 195 for git_hash in [git_hash1, git_hash2]: | 201 for git_hash in [git_hash1, git_hash2]: |
| 196 result_path = os.path.join( | 202 result_path = os.path.join( |
| 197 AZALEA_RESULTS_DIRECTORY, delta_util.GenerateFileName( | 203 PREDATOR_RESULTS_DIRECTORY, delta_util.GenerateFileName( |
| 198 client_id, property_values, start_date, end_date, | 204 client_id, property_values, start_date, end_date, |
| 199 batch_size, index, git_hash)) | 205 batch_size, index, git_hash)) |
| 200 results.append(GetResults(crashes, client_id, git_hash, result_path, | 206 results.append(GetResults(crashes, client_id, app_id, |
| 207 git_hash, result_path, |
| 201 verbose=verbose)) | 208 verbose=verbose)) |
| 202 | 209 |
| 203 crash_count += len(crashes) | 210 crash_count += len(crashes) |
| 204 deltas.update(GetDeltasFromTwoSetsOfResults(*results)) | 211 deltas.update(GetDeltasFromTwoSetsOfResults(*results)) |
| 205 | 212 |
| 206 return deltas, crash_count | 213 return deltas, crash_count |
| 207 finally: | 214 finally: |
| 208 with open(os.devnull, 'w') as null_handle: | 215 with open(os.devnull, 'w') as null_handle: |
| 209 subprocess.check_call(['git', 'checkout', head_branch_name], | 216 subprocess.check_call(['git', 'checkout', head_branch_name], |
| 210 stdout=null_handle, | 217 stdout=null_handle, |
| 211 stderr=null_handle) | 218 stderr=null_handle) |
| OLD | NEW |