| # Copyright 2016 The Chromium Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| from datetime import date |
| from datetime import timedelta |
| import os |
| import sys |
| |
| _ROOT_DIR = os.path.realpath(os.path.join(os.path.dirname(__file__), |
| os.path.pardir)) |
| _FIRST_PARTY_DIR = os.path.join(_ROOT_DIR, 'first_party') |
| sys.path.insert(1, _FIRST_PARTY_DIR) |
| |
| from local_libs import script_util |
| script_util.SetUpSystemPaths(_ROOT_DIR) |
| |
| from analysis.type_enums import CrashClient |
| from app.common.model.clusterfuzz_analysis import ClusterfuzzAnalysis |
| from app.common.model.cracas_crash_analysis import CracasCrashAnalysis |
| from app.common.model.fracas_crash_analysis import FracasCrashAnalysis |
| from app.common.model.uma_sampling_profiler_analysis import ( |
| UMASamplingProfilerAnalysis) |
| from libs.cache_decorator import GeneratorCached |
| from local_libs import local_iterator |
| from local_libs.local_cache import LocalCache |
| |
| |
| _DEFAULT_BATCH_SIZE = 1000 |
| _TODAY = date.today().strftime('%Y-%m-%d') |
| _A_YEAR_AGO = (date.today() - timedelta(days=365)).strftime('%Y-%m-%d') |
| _CLIENT_ID_TO_CLASS = {CrashClient.FRACAS: FracasCrashAnalysis, |
| CrashClient.CRACAS: CracasCrashAnalysis, |
| CrashClient.CLUSTERFUZZ: ClusterfuzzAnalysis, |
| CrashClient.UMA_SAMPLING_PROFILER: |
| UMASamplingProfilerAnalysis} |
| |
| |
| # TODO(crbug.com/662540): Add unittests. |
| def IterateCrashes(client_id, |
| app_id, |
| projection=None, |
| property_values=None, |
| start_date=_A_YEAR_AGO, |
| end_date=_TODAY, |
| batch_size=_DEFAULT_BATCH_SIZE, |
| batch_run=False): # pragma: no cover. |
| """Genrates query to query crashes and iterates crashes. |
| |
| Args: |
| client_id (CrashClient): One of the 3 supported clients - |
| CrashClient.FRACAS, CrashClient.CRACAS and CrashClient.CLUSTERFUZZ. |
| app_id (str): App engine app id. |
| projection (tuple or list): Operations return entities with only the |
| specified properties set. For example: |
| projection=[Article.title, Article.date] or |
| projection=['title', 'date'] fetches entities with just those two |
| fields set. Note, query can only project indexed properties. |
| property_values (dict): Property values to filter. |
| start_date (str): Only iterate testcases after this date including this |
| date, format '%Y-%m-%d'. |
| end_date (str): Only iterate testcases before this date excluding this date, |
| format '%Y-%m-%d'. |
| batch_size (int): The number of crashes to query at one time. |
| batch_run (bool): If True, iterate batches of crashes, if |
| False, iterate each crash. |
| |
| An example is available in crash_printer/print_crash.py. |
| """ |
| cls = _CLIENT_ID_TO_CLASS.get(client_id) |
| if property_values: |
| property_values = {getattr(cls, property_name): value for |
| property_name, value in property_values.iteritems()} |
| |
| query = script_util.GetFilterQuery( |
| cls.query(), cls.requested_time, start_date, end_date, |
| property_values=property_values) |
| |
| # According to https://goo.gl/5BgxQt, the query must be sorted by key |
| # to make a query with both ``IN`` operation and cursor. |
| query = query.order(-cls.requested_time, cls.key) |
| for crash in local_iterator.ScriptIterate( |
| query, app_id, projection=projection, |
| batch_size=batch_size, batch_run=batch_run): |
| yield crash |
| |
| |
| @GeneratorCached(LocalCache(), namespace='Crash-iterator') # pragma: no cover. |
| def CachedCrashIterator(client_id, app_id, |
| projection=None, |
| property_values=None, |
| start_date=_A_YEAR_AGO, end_date=_TODAY, |
| batch_size=_DEFAULT_BATCH_SIZE, batch_run=False): |
| """Genrates query to query crashes and iterates crashes. |
| |
| This iterator will check local cache first, if there is cache, iterate cached |
| values, else it will visit datastore of appengine app to yield data. |
| |
| Args: |
| client_id (CrashClient): One of the 3 supported clients - |
| CrashClient.FRACAS, CrashClient.CRACAS and CrashClient.CLUSTERFUZZ. |
| app_id (str): App engine app id. |
| projection (tuple or list): Operations return entities with only the |
| specified properties set. For example: |
| projection=[Article.title, Article.date] or |
| projection=['title', 'date'] fetches entities with just those two |
| fields set. Note, query can only project indexed properties. |
| property_values (dict): Property values to filter. |
| start_date (str): Only iterate testcases after this date including this |
| date, format '%Y-%m-%d'. |
| end_date (str): Only iterate testcases before this date excluding this date, |
| format '%Y-%m-%d'. |
| batch_size (int): The number of crashes to query at one time. |
| batch_run (bool): If True, iterate batches of crashes, if |
| False, iterate each crash. |
| |
| An example is available in crash_printer/print_crash.py. |
| """ |
| for crash in IterateCrashes(client_id, app_id, projection=projection, |
| property_values=property_values, |
| start_date=start_date, end_date=end_date, |
| batch_size=batch_size, batch_run=batch_run): |
| yield crash |