Beispiel #1
0
    def testUpdateIssueWithIssueGeneratorReopen(self, mock_create_bug_fn,
                                                mock_update_bug_fn,
                                                mock_get_merged_issue):
        issue_id = 12345
        issue = Issue({
            'status': 'Fixed',
            'summary': 'summary',
            'description': 'description',
            'projectId': 'chromium',
            'labels': [],
            'fieldValues': [],
            'state': 'open',
            'owner': {
                'name': '*****@*****.**'
            }
        })
        mock_get_merged_issue.return_value = issue

        test_issue_generator = TestIssueGenerator()
        monorail_util.UpdateIssueWithIssueGenerator(
            issue_id=issue_id,
            issue_generator=test_issue_generator,
            reopen=True)

        self.assertFalse(mock_create_bug_fn.called)
        mock_update_bug_fn.assert_called_once_with(
            issue, 'comment without previous tracking bug id.', 'chromium')
        issue = mock_update_bug_fn.call_args_list[0][0][0]
        self.assertEqual(['label1'], issue.labels)
        self.assertEqual(1, len(issue.field_values))
        self.assertEqual('Flaky-Test',
                         issue.field_values[0].to_dict()['fieldName'])
        self.assertEqual('suite.test',
                         issue.field_values[0].to_dict()['fieldValue'])
        self.assertEqual('Assigned', issue.status)
def _CreateIssueForFlake(issue_generator, target_flake, create_or_update_bug):
    """Creates a monorail bug for a single flake.

  This function is used to create bugs for detected flakes and flake analysis
  results.

  Args:
    create_or_update_bug (bool): True to create or update monorail bug,
      otherwise False. Should always look for existing bugs for flakes, even if
      cannot update the bug.
  """
    monorail_project = issue_generator.GetMonorailProject()

    # Re-uses an existing open bug if possible.
    issue_id = SearchOpenIssueIdForFlakyTest(target_flake.normalized_test_name,
                                             monorail_project)

    if not issue_id:
        # Reopens a recently closed bug if possible.
        issue_id = SearchRecentlyClosedIssueIdForFlakyTest(
            target_flake.normalized_test_name, monorail_project)

    if issue_id:
        logging.info('An existing issue %s was found, attach it to flake: %s.',
                     FlakeIssue.GetLinkForIssue(monorail_project, issue_id),
                     target_flake.key)
        _AssignIssueToFlake(issue_id, target_flake)

        if create_or_update_bug:
            monorail_util.UpdateIssueWithIssueGenerator(
                issue_id=issue_id,
                issue_generator=issue_generator,
                reopen=True)
        return issue_id

    if not create_or_update_bug:
        # No existing bug found, and cannot create bug, bail out.
        return None

    logging.info('No existing open issue was found, create a new one.')
    issue_id = monorail_util.CreateIssueWithIssueGenerator(
        issue_generator=issue_generator)

    if not issue_id:
        logging.warning('Failed to create monorail bug for flake: %s.',
                        target_flake.key)
        return None
    logging.info('%s was created for flake: %s.',
                 FlakeIssue.GetLinkForIssue(monorail_project, issue_id),
                 target_flake.key)
    _AssignIssueToFlake(issue_id, target_flake)
    return issue_id
Beispiel #3
0
    def testUpdateIssueWithIssueGeneratorAndRestoreSheriffLabel(
            self, mock_create_bug_fn, mock_update_bug_fn,
            mock_get_merged_issue, _):
        issue_id = 12345
        issue = Issue({
            'status': 'Available',
            'summary': 'summary',
            'description': 'description',
            'projectId': 'chromium',
            'labels': [],
            'fieldValues': [],
            'state': 'open',
        })
        mock_get_merged_issue.return_value = issue

        test_issue_generator = TestIssueGenerator()
        monorail_util.UpdateIssueWithIssueGenerator(
            issue_id=issue_id, issue_generator=test_issue_generator)

        self.assertFalse(mock_create_bug_fn.called)
        self.assertTrue(mock_update_bug_fn.called)
        self.assertEqual(['label1', 'Sheriff-Chromium'], issue.labels)
def _UpdateIssuesForFlakes(flake_groups_to_update_issue):
    """Updates monorail bugs.

  The issues have been updated when generating flake groups, so in this function
  directly updates the issues.

  Args:
    flake_groups_to_update_issue ([FlakeGroupByFlakeIssue]): A list of flake
      groups with bugs.
  """
    for flake_group in flake_groups_to_update_issue:
        try:
            if len(flake_group.flakes) == 1:
                # A single flake in group, updates the bug using this flake's info.
                issue_generator = FlakeDetectionIssueGenerator(
                    flake_group.flakes[0], flake_group.num_occurrences)
                issue_generator.SetPreviousTrackingBugId(
                    flake_group.previous_issue_id)
                monorail_util.UpdateIssueWithIssueGenerator(
                    issue_id=flake_group.flake_issue.issue_id,
                    issue_generator=issue_generator,
                    reopen=True)
            else:
                _UpdateFlakeIssueForFlakeGroup(flake_group)
            # Update FlakeIssue's last_updated_time_by_flake_detection property. This
            # property is only applicable to Flake Detection because Flake Detection
            # can update an issue at most once every 24 hours.
            flake_issue = flake_group.flake_issue
            flake_issue.last_updated_time_by_flake_detection = time_util.GetUTCNow(
            )
            flake_issue.last_updated_time_in_monorail = time_util.GetUTCNow()
            flake_issue.put()
        except HttpError as error:
            # Benign exceptions (HttpError 403) may happen when FindIt tries to
            # update an issue that it doesn't have permission to. Do not raise
            # exception so that the for loop can move on to create or update next
            # issues.
            logging.warning(
                'Failed to create or update issue due to error: %s', error)
Beispiel #5
0
    def testUpdateIssueWithIssueGeneratorWithPreviousTrackingId(
            self, mock_create_bug_fn, mock_update_bug_fn,
            mock_get_merged_issue):
        issue_id = 12345
        issue = Issue({
            'status': 'Available',
            'summary': 'summary',
            'description': 'description',
            'projectId': 'chromium',
            'labels': [],
            'fieldValues': [],
            'state': 'open',
        })
        mock_get_merged_issue.return_value = issue

        test_issue_generator = TestIssueGenerator()
        test_issue_generator.SetPreviousTrackingBugId(56789)
        monorail_util.UpdateIssueWithIssueGenerator(
            issue_id=issue_id, issue_generator=test_issue_generator)

        self.assertFalse(mock_create_bug_fn.called)
        mock_update_bug_fn.assert_called_once_with(
            issue, 'comment with previous tracking bug id: 56789.', 'chromium')
def _UpdateFlakeIssueForFlakeGroup(flake_group):
    """Updates an issue for a flake group.

  Args:
    flake_group (FlakeGroupByFlakeIssue): A flake group with an issue.

  Returns:
    Id of the issue that was eventually created or linked.
  """
    assert isinstance(flake_group, FlakeGroupByFlakeIssue), (
        'flake_group is not a FlakeGroupByFlakeIssue instance.')
    issue_generator = FlakeDetectionGroupIssueGenerator(
        flake_group.flakes,
        flake_group.num_occurrences,
        flake_issue=flake_group.flake_issue,
        flakes_with_same_occurrences=flake_group.flakes_with_same_occurrences)

    flake_issue = flake_group.flake_issue
    monorail_util.UpdateIssueWithIssueGenerator(
        issue_id=flake_issue.issue_id,
        issue_generator=issue_generator,
        reopen=True)
    return flake_issue.issue_id
def UpdateMonorailBugWithCulprit(analysis_urlsafe_key):
    """Updates a bug in monorail with the culprit of a MasterFlakeAnalsyis"""
    analysis = entity_util.GetEntityFromUrlsafeKey(analysis_urlsafe_key)
    assert analysis, 'Analysis {} missing unexpectedly!'.format(
        analysis_urlsafe_key)

    if not analysis.flake_key:  # pragma: no cover.
        logging.warning(
            'Analysis %s has no flake key. Bug updates should only be '
            'routed through Flake and FlakeIssue', analysis_urlsafe_key)
        return

    flake = analysis.flake_key.get()
    assert flake, 'Analysis\' associated Flake {} missing unexpectedly!'.format(
        analysis.flake_key)

    flake_urlsafe_key = flake.key.urlsafe()
    if flake.archived:
        logging.info(
            'Flake %s has been archived when flake analysis %s completes.',
            flake_urlsafe_key, analysis_urlsafe_key)
        return

    if not flake.flake_issue_key:  # pragma: no cover.
        logging.warning(
            'Flake %s has no flake_issue_key. Bug updates should only'
            ' be routed through Flake and FlakeIssue', flake_urlsafe_key)
        return

    flake_issue = flake.flake_issue_key.get()
    assert flake_issue, 'Flake issue {} missing unexpectedly!'.format(
        flake.flake_issue_key)

    # Only comment on the latest flake issue.
    flake_issue_to_update = flake_issue.GetMostUpdatedIssue()
    issue_link = FlakeIssue.GetLinkForIssue(
        flake_issue_to_update.monorail_project, flake_issue_to_update.issue_id)

    # Don't comment if the issue is closed.
    latest_merged_monorail_issue = monorail_util.GetMonorailIssueForIssueId(
        flake_issue_to_update.issue_id)
    if not latest_merged_monorail_issue or not latest_merged_monorail_issue.open:
        logging.info(
            'Skipping updating issue %s which is not accessible or closed',
            issue_link)
        return

    # Don't comment if there are existing updates by Findit to prevent spamming.
    if flake_issue_to_update.last_updated_time_with_analysis_results:
        logging.info(
            'Skipping updating issue %s as it has already been updated',
            issue_link)
        return

    # Don't comment if Findit has filled the daily quota of monorail updates.
    if flake_issue_util.GetRemainingPostAnalysisDailyBugUpdatesCount() <= 0:
        logging.info(
            'Skipping updating issue %s due to maximum daily bug limit being '
            'reached', issue_link)
        return

    # Comment with link to FlakeCulprit.
    monorail_util.UpdateIssueWithIssueGenerator(
        flake_issue_to_update.issue_id,
        issue_generator.FlakeAnalysisIssueGenerator(analysis))
    flake_issue_to_update.last_updated_time_with_analysis_results = (
        time_util.GetUTCNow())
    flake_issue_to_update.last_updated_time_in_monorail = time_util.GetUTCNow()
    flake_issue_to_update.put()

    monitoring.flake_analyses.increment({
        'result': 'culprit-identified',
        'action_taken': 'bug-updated',
        'reason': ''
    })