def testGetActionSettings(self):
     self.assertEqual(
         {
             'cr_notification_build_threshold': 2,
             'cr_notification_latency_limit_minutes': 30,
             'revert_compile_culprit': True,
         }, waterfall_config.GetActionSettings())
示例#2
0
def CanAutoCreateRevert(culprit, parameters):
    """Checks if Findit can auto create a revert.

  Args:
    culprit (Basestring): Urlsafe key for the suspected cl.
    parameters (CulpritActionParameters): Parameters to run culprit action
      pipelines.

  Findit can auto create a revert if:
    1. Auto create revert for test is turned on;
    2. The number of reverts in past 24 hours is less than the daily limit;
    3. The culprit is also being suspected by the heuristic analysis.
  """
    heuristic_cls = parameters.heuristic_cls
    if culprit not in heuristic_cls:
        return False

    action_settings = waterfall_config.GetActionSettings()
    # Auto revert has been turned off.
    if not bool(action_settings.get('auto_create_revert')):
        return False

    auto_create_revert_daily_threshold_test = action_settings.get(
        'auto_create_revert_daily_threshold_test',
        _DEFAULT_AUTO_CREATE_REVERT_DAILY_THRESHOLD_TEST)
    # Auto revert has exceeded daily limit.
    if _GetDailyNumberOfRevertedCulprits(
            auto_create_revert_daily_threshold_test
    ) >= auto_create_revert_daily_threshold_test:
        logging.info(
            'Auto reverts for test culprits on %s has met daily limit.',
            time_util.FormatDatetime(time_util.GetUTCNow()))
        return False

    return True
 def run(self, master_name, builder_name, build_number, repo_name,
         revision):
     if waterfall_config.GetActionSettings().get('revert_compile_culprit',
                                                 False):
         return _RevertCulprit(master_name, builder_name, build_number,
                               repo_name, revision)
     return None
示例#4
0
def _CanCommitRevert(parameters, analysis_id, codereview_info):
    """Checks if an auto-created revert of a culprit can be committed.

  This function will call several different functions to check the culprit
  and/or revert from many different aspects and make the final decision.

  The criteria included so far are:
   + Revert is created by Findit;
   + Can the revert be committed in current analysis;
   + Was the change committed within time;
   + Was the change to be reverted authored by an auto-roller;
   + Are there other changes by the culprit's author depending on the culprit.
  """
    if not parameters.revert_status == constants.CREATED_BY_FINDIT:
        return False

    culprit = entity_util.GetEntityFromUrlsafeKey(parameters.cl_key)
    assert culprit

    action_settings = waterfall_config.GetActionSettings()
    culprit_commit_limit_hours = action_settings.get(
        'culprit_commit_limit_hours',
        constants.DEFAULT_CULPRIT_COMMIT_LIMIT_HOURS)

    return (_CanCommitRevertInAnalysis(parameters.cl_key, analysis_id)
            and git.ChangeCommittedWithinTime(culprit.revision,
                                              hours=culprit_commit_limit_hours)
            and not git.IsAuthoredByNoAutoRevertAccount(culprit.revision)
            and not gerrit.ExistCQedDependingChanges(codereview_info))
示例#5
0
def SendNotificationForCulprit(parameters):
    culprit = entity_util.GetEntityFromUrlsafeKey(parameters.cl_key)
    assert culprit

    revision = culprit.revision
    repo_name = culprit.repo_name

    force_notify = parameters.force_notify
    revert_status = parameters.revert_status
    sent = False
    should_send = False

    action_settings = waterfall_config.GetActionSettings()
    # Set some impossible default values to prevent notification by default.
    build_num_threshold = action_settings.get(
        'cr_notification_build_threshold', 100000)
    if _ShouldSendNotification(repo_name, revision, force_notify,
                               revert_status, build_num_threshold):
        should_send = True
        codereview_info = GetCodeReviewDataForACulprit(parameters.cl_key)
        sent = gerrit.SendNotificationForCulprit(parameters, codereview_info)

    MonitoringCulpritNotification(parameters.failure_type, 'culprit', sent,
                                  should_send)
    return sent
def GetRemainingPostAnalysisDailyBugUpdatesCount():
    """Returns how many FlakeIssue updates can be made by Flake Analyzer."""
    action_settings = waterfall_config.GetActionSettings()
    limit = action_settings.get(
        'max_flake_analysis_bug_updates_per_day',
        flake_constants.DEFAULT_MAX_BUG_UPDATES_PER_DAY)

    utc_one_day_ago = time_util.GetUTCNow() - datetime.timedelta(days=1)
    num_updated_issues_24h = FlakeIssue.query(
        FlakeIssue.last_updated_time_with_analysis_results > utc_one_day_ago
    ).count()

    return limit - num_updated_issues_24h
示例#7
0
def UnderLimitForAutorevert():
    """Returns True if currently under the limit for autoreverts."""
    action_settings = waterfall_config.GetActionSettings()

    # Do not auto commit revert if not configured to do so.
    limit = action_settings.get('auto_commit_revert_daily_threshold_flake')

    query = MasterFlakeAnalysis.query(
        MasterFlakeAnalysis.autorevert_submission_time >=
        time_util.GetMostRecentUTCMidnight(),
        MasterFlakeAnalysis.has_submitted_autorevert == True)

    return query.count(limit) < limit
示例#8
0
    def testNonAdminCouldTurnOffAutoCommit(self, _):
        self.mock_current_user(user_email='*****@*****.**', is_admin=False)

        params = {
            'xsrf_token': 'token',
            'auto_commit_revert': 'false',
            'update_reason': 'reason',
        }

        response = self.test_app.post('/trooper?format=json', params=params)
        redirect_url = '/trooper'
        self.assertTrue(
            response.headers.get('Location', '').endswith(redirect_url))
        self.assertFalse(
            waterfall_config.GetActionSettings().get('auto_commit_revert'))
示例#9
0
  def HandleGet(self):
    action_settings = waterfall_config.GetActionSettings()
    auto_commit_revert_is_on = action_settings.get('auto_commit_revert', False)

    code_coverage_settings = waterfall_config.GetCodeCoverageSettings()
    code_coverage_is_on = (
        code_coverage_settings.get('serve_presubmit_coverage_data', False))

    return {
        'template': 'trooper.html',
        'data': {
            'is_admin': users.is_current_user_admin(),
            'auto_commit_revert_on': auto_commit_revert_is_on,
            'code_coverage_on': code_coverage_is_on,
        }
    }
示例#10
0
    def testAdminCouldTurnOnAutoCommit(self, _):
        self.mock_current_user(user_email='*****@*****.**', is_admin=True)
        self.UpdateUnitTestConfigSettings('action_settings',
                                          {'auto_commit_revert': False})

        params = {
            'xsrf_token': 'token',
            'auto_commit_revert': 'true',
            'update_reason': 'reason',
            'format': 'json',
        }

        response = self.test_app.post('/trooper', params=params, status=302)
        self.assertTrue(
            response.headers.get('Location', '').endswith('/trooper'))
        self.assertTrue(
            waterfall_config.GetActionSettings().get('auto_commit_revert'))
示例#11
0
def UnderDailyLimit():
    # TODO(crbug.com/942222): Distinguish between Flake Analyzer and Flake
    # Detection bug operations.
    action_settings = waterfall_config.GetActionSettings()
    daily_bug_limit = action_settings.get(
        'max_flake_detection_bug_updates_per_day',
        flake_constants.DEFAULT_MAX_BUG_UPDATES_PER_DAY)
    query = master_flake_analysis.MasterFlakeAnalysis.query(
        master_flake_analysis.MasterFlakeAnalysis.request_time >=
        time_util.GetMostRecentUTCMidnight())
    bugs_filed_today = 0

    more = True
    cursor = None
    while more:
        results, cursor, more = query.fetch_page(100, start_cursor=cursor)
        for result in results:
            if result.has_attempted_filing and result.bug_id:
                bugs_filed_today += 1

    return bugs_filed_today < daily_bug_limit
示例#12
0
 def testGetActionSettings(self):
     self.assertEqual(
         {
             'auto_commit_revert':
             True,
             'auto_create_revert':
             True,
             'cr_notification_build_threshold':
             2,
             'cr_notification_latency_limit_minutes':
             30,
             'cr_notification_should_notify_flake_culprit':
             True,
             'culprit_commit_limit_hours':
             24,
             'auto_commit_revert_daily_threshold_compile':
             4,
             'auto_create_revert_daily_threshold_compile':
             10,
             'auto_commit_revert_daily_threshold_test':
             4,
             'auto_create_revert_daily_threshold_test':
             10,
             'auto_create_revert_daily_threshold_flake':
             10,
             'auto_commit_revert_daily_threshold_flake':
             4,
             'rotations_url':
             ('https://rota-ng.appspot.com/legacy/all_rotations.js'),
             'max_flake_detection_bug_updates_per_day':
             30,
             'max_flake_analysis_bug_updates_per_day':
             30,
             'minimum_confidence_to_update_endpoints':
             0.7,
             'minimum_confidence_to_revert_flake_culprit':
             1.0,
         }, waterfall_config.GetActionSettings())
示例#13
0
def CanAutoCommitRevertByFindit():
    """Checks if the revert can be auto committed by Findit.

  The revert can be committed if:
    1. Auto revert and Auto commit is turned on;
    2. The number of commits of reverts in past 24 hours is less than the
      daily limit;
    3. Culprit author has not landed another change yet.
  """
    action_settings = waterfall_config.GetActionSettings()
    if (not bool(action_settings.get('auto_commit_revert'))
            or not bool(action_settings.get('auto_create_revert'))):
        return False

    auto_commit_revert_daily_threshold_test = action_settings.get(
        'auto_commit_revert_daily_threshold_test',
        _DEFAULT_AUTO_COMMIT_REVERT_DAILY_THRESHOLD_TEST)
    if _GetDailyNumberOfCommits(auto_commit_revert_daily_threshold_test
                                ) >= auto_commit_revert_daily_threshold_test:
        logging.info('Auto commits on %s has met daily limit.',
                     time_util.FormatDatetime(time_util.GetUTCNow()))
        return False
    return True
示例#14
0
  def _UpdateActionSettings(self, auto_commit_revert_is_on, user, message):
    """Updates the action settings.

    Args:
      auto_commit_revert_is_on (bool): Whether the auto commit revert feature is
                                       turned on.
      user: User who initiated the update.
      message: The update message.

    Returns:
      A bool indicates whether the update is successful.
    """
    action_settings = waterfall_config.GetActionSettings()
    if auto_commit_revert_is_on == action_settings.get('auto_commit_revert'):
      return False

    updated_action_settings = copy.deepcopy(action_settings)
    updated_action_settings['auto_commit_revert'] = auto_commit_revert_is_on
    return wf_config.FinditConfig.Get().Update(
        user,
        acl.IsPrivilegedUser(user.email(), users.is_current_user_admin()),
        message=message,
        action_settings=updated_action_settings)
示例#15
0
    def run(self,
            master_name,
            builder_name,
            build_number,
            repo_name,
            revision,
            force_notify,
            revert_status=None):

        # This information is not needed at the moment.
        # TODO(robertocn): Remove these arguments if we won't need them for
        # notifications once auto-revert is enabled.
        _build_information = [master_name, builder_name, build_number]

        if revert_status == create_revert_cl_pipeline.CREATED_BY_FINDIT:
            # Already notified when revert, bail out.
            return False

        if revert_status == create_revert_cl_pipeline.CREATED_BY_SHERIFF:
            force_notify = True

        action_settings = waterfall_config.GetActionSettings()
        # Set some impossible default values to prevent notification by default.
        build_num_threshold = action_settings.get(
            'cr_notification_build_threshold', 100000)

        culprit_info = suspected_cl_util.GetCulpritInfo(repo_name, revision)
        commit_position = culprit_info['commit_position']
        review_server_host = culprit_info['review_server_host']
        review_change_id = culprit_info['review_change_id']

        if not _ShouldSendNotification(repo_name, revision,
                                       build_num_threshold, force_notify):
            return False
        return _SendNotificationForCulprit(repo_name, revision,
                                           commit_position, review_server_host,
                                           review_change_id, revert_status)
示例#16
0
def CanAutoCreateRevert():
  """Checks if Findit can auto create a revert.

  Findit can auto create a revert if both of below are True:
    1. Auto create revert for compile is turned on;
    2. The number of reverts in past 24 hours is less than the daily limit.
  """
  action_settings = waterfall_config.GetActionSettings()
  # Auto revert has been turned off.
  if not bool(action_settings.get('auto_create_revert')):
    return False

  auto_create_revert_daily_threshold_compile = action_settings.get(
      'auto_create_revert_daily_threshold_compile',
      _DEFAULT_AUTO_CREATE_REVERT_DAILY_THRESHOLD_COMPILE)
  # Auto revert has exceeded daily limit.
  if _GetDailyNumberOfRevertedCulprits(
      auto_create_revert_daily_threshold_compile
  ) >= auto_create_revert_daily_threshold_compile:
    logging.info('Auto reverts for compile culprits on %s has met daily limit.',
                 time_util.FormatDatetime(time_util.GetUTCNow()))
    return False

  return True
示例#17
0
文件: gerrit.py 项目: xinghun61/infra
def RevertCulprit(urlsafe_key, build_id, build_failure_type, sample_step_name,
                  codereview_info):
    """Creates a revert of a culprit and adds reviewers.

  Args:
    urlsafe_key (str): Key to the ndb model.
    build_id (str): Id of the sample failed build.
    build_failure_type (int): Failure type: compile, test or flake.
    sample_step_name (str): Sample failed step in the failed build.
    codereview_info (dict): Code review information about the culprit.

  Returns:
    (int, string, string):
      - Status of the reverting;
      - change_id of the revert;
      - reason why revert is skipped if it is skipped.
  """

    culprit = entity_util.GetEntityFromUrlsafeKey(urlsafe_key)
    repo_name = culprit.repo_name
    revision = culprit.revision
    # 0. Gets information about this culprit.
    culprit_commit_position = codereview_info['commit_position']
    culprit_change_id = codereview_info['review_change_id']

    codereview = _GetCodeReview(codereview_info)
    print codereview

    if not codereview or not culprit_change_id:  # pragma: no cover
        logging.error('Failed to get change id for %s/%s', repo_name, revision)
        return services_constants.ERROR, None, None

    culprit_cl_info = codereview.GetClDetails(culprit_change_id)
    if not culprit_cl_info:  # pragma: no cover
        logging.error('Failed to get cl_info for %s/%s', repo_name, revision)
        return services_constants.ERROR, None, None

    # Checks if the culprit is a revert. If yes, bail out.
    if _IsCulpritARevert(culprit_cl_info):
        return (services_constants.SKIPPED, None,
                services_constants.CULPRIT_IS_A_REVERT)

    if culprit_cl_info.auto_revert_off:
        return services_constants.SKIPPED, None, services_constants.AUTO_REVERT_OFF

    # 1. Checks if a revert CL by sheriff has been created.
    reverts = culprit_cl_info.GetRevertCLsByRevision(revision)

    if reverts is None:  # pragma: no cover
        # if no reverts, reverts should be [], only when some error happens it will
        # be None.
        logging.error('Failed to find patchset_id for %s/%s' %
                      (repo_name, revision))
        return services_constants.ERROR, None, None

    findit_revert = None
    for revert in reverts:
        if _IsOwnerFindit(revert.reverting_user_email):
            findit_revert = revert
            break

    if reverts and not findit_revert:
        # Sheriff(s) created the revert CL(s).
        return (services_constants.CREATED_BY_SHERIFF, None,
                services_constants.REVERTED_BY_SHERIFF)

    revert_change_id = None
    if findit_revert:
        revert_change_id = findit_revert.reverting_cl.change_id

    # 2. Crreate revert CL.
    # TODO (chanli): Better handle cases where 2 analyses are trying to revert
    # at the same time.
    if not revert_change_id:
        revert_reason = culprit.GenerateRevertReason(build_id,
                                                     culprit_commit_position,
                                                     revision,
                                                     sample_step_name)
        if not revert_reason:  # pragma: no cover.
            logging.error('Failed to get the reason for revert culprit %s',
                          culprit.key.urlsafe() if culprit else '')
            return services_constants.ERROR, None, None
        bug_id = _GetBugIdForCulprit(culprit)
        revert_change_id = codereview.CreateRevert(
            revert_reason,
            culprit_change_id,
            culprit_cl_info.GetPatchsetIdByRevision(revision),
            bug_id=bug_id)

        if not revert_change_id:  # pragma: no cover
            return services_constants.ERROR, None, None

    # Save revert CL info and notification info to culprit.
    revert_cl = None
    if not culprit.revert_cl:
        revert_cl = RevertCL()
        revert_cl.revert_cl_url = codereview.GetCodeReviewUrl(revert_change_id)
        revert_cl.created_time = time_util.GetUTCNow()

    # 3. Add reviewers.
    # If Findit cannot commit the revert, add sheriffs as reviewers and ask them
    # to 'LGTM' and commit the revert.
    action_settings = waterfall_config.GetActionSettings()
    can_commit_revert = (action_settings.get('auto_commit_revert_compile')
                         if build_failure_type == failure_type.COMPILE else
                         action_settings.get('auto_commit_revert_test'))
    if not can_commit_revert:
        success = _AddReviewers(revision, culprit, codereview,
                                revert_change_id, False)
        if not success:  # pragma: no cover
            logging.error('Failed to add reviewers for revert of'
                          ' culprit %s/%s' % (repo_name, revision))
            return services_constants.ERROR, revert_cl, None
    return services_constants.CREATED_BY_FINDIT, revert_cl, None
示例#18
0
def IsAutorevertEnabled():
    action_settings = waterfall_config.GetActionSettings()
    return (action_settings.get('auto_commit_revert', False)
            and action_settings.get('auto_create_revert', False))
示例#19
0
def IsConfiguredToNotifyCulprits():
    action_settings = waterfall_config.GetActionSettings()
    return action_settings.get('cr_notification_should_notify_flake_culprit',
                               False)
示例#20
0
def GetMinimumConfidenceToNotifyCulprits():
    action_settings = waterfall_config.GetActionSettings()
    return action_settings.get(
        'minimum_confidence_to_update_endpoints',
        flake_constants.DEFAULT_MINIMUM_CONFIDENCE_SCORE_TO_UPDATE_ENDPOINTS)
示例#21
0
def GetMinimumConfidenceToUpdateEndpoints():
    return waterfall_config.GetActionSettings().get(
        'minimum_confidence_to_update_endpoints',
        flake_constants.DEFAULT_MINIMUM_CONFIDENCE_SCORE_TO_UPDATE_ENDPOINTS)