コード例 #1
0
    def _AddAdditionalDetailsToBug(self, bug_id, alerts):
        """Adds additional data to the bug as a comment.

    Adds the link to /group_report and bug_id as well as the names of the bots
    that triggered the alerts, and a milestone label.

    Args:
      bug_id: Bug ID number.
      alerts: The Alert entities being associated with this bug.
    """
        base_url = '%s/group_report' % _GetServerURL()
        bug_page_url = '%s?bug_id=%s' % (base_url, bug_id)
        alerts_url = '%s?keys=%s' % (base_url, _UrlsafeKeys(alerts))
        comment = 'All graphs for this bug:\n  %s\n\n' % bug_page_url
        comment += 'Original alerts at time of bug-filing:\n  %s\n' % alerts_url

        bot_names = alert.GetBotNamesFromAlerts(alerts)
        if bot_names:
            comment += '\n\nBot(s) for this bug\'s original alert(s):\n\n'
            comment += '\n'.join(sorted(bot_names))
        else:
            comment += '\nCould not extract bot names from the list of alerts.'

        http = oauth2_decorator.decorator.http()
        service = issue_tracker_service.IssueTrackerService(http=http)
        service.AddBugComment(bug_id, comment)
コード例 #2
0
    def get(self):
        """The get handler method is called from a cron job.

    It expects no parameters and has no output. It checks all current bisect try
    jobs and send comments to an issue on the issue tracker if a bisect job has
    completed.
    """
        credentials = rietveld_service.Credentials(
            rietveld_service.GetDefaultRietveldConfig(),
            rietveld_service.PROJECTHOSTING_SCOPE)
        issue_tracker = issue_tracker_service.IssueTrackerService(
            additional_credentials=credentials)

        jobs_to_check = try_job.TryJob.query(
            try_job.TryJob.status == 'started').fetch()
        for job in jobs_to_check:
            try:
                if job.use_buildbucket:
                    logging.info('Checking job %s with Buildbucket job ID %s.',
                                 job.key.id(),
                                 getattr(job, 'buildbucket_job_id', None))
                else:
                    logging.info('Checking job %s with Rietveld issue ID %s.',
                                 job.key.id(),
                                 getattr(job, 'rietveld_issue_id', None))
                _CheckJob(job, issue_tracker)
            except Exception as e:  # pylint: disable=broad-except
                logging.error('Caught Exception %s: %s', type(e).__name__, e)
コード例 #3
0
 def _FetchBugs(self):
     http = oauth2_decorator.DECORATOR.http()
     issue_tracker = issue_tracker_service.IssueTrackerService(http=http)
     response = issue_tracker.List(q='opened-after:today-5',
                                   label='Type-Bug-Regression,Performance',
                                   sort='-id')
     return response.get('items', []) if response else []
コード例 #4
0
    def get(self):
        """The get handler method is called from a cron job.

    It expects no parameters and has no output. It checks all current bisect try
    jobs and send comments to an issue on the issue tracker if a bisect job has
    completed.
    """
        credentials = utils.ServiceAccountCredentials()
        issue_tracker = issue_tracker_service.IssueTrackerService(
            additional_credentials=credentials)

        # Set privilege so we can also fetch internal try_job entities.
        datastore_hooks.SetPrivilegedRequest()

        jobs_to_check = try_job.TryJob.query(
            try_job.TryJob.status.IN(['started', 'pending'])).fetch()
        all_successful = True

        for job in jobs_to_check:
            try:
                _CheckJob(job, issue_tracker)
            except Exception as e:  # pylint: disable=broad-except
                logging.error('Caught Exception %s: %s\n%s',
                              type(e).__name__, e, traceback.format_exc())
                all_successful = False

        if all_successful:
            utils.TickMonitoringCustomMetric('UpdateBugWithResults')
コード例 #5
0
 def testNewBug_Success_NewBugReturnsId(self):
     service = issue_tracker_service.IssueTrackerService()
     service._ExecuteRequest = mock.Mock(return_value={'id': 333})
     bug_id = service.NewBug('Bug title',
                             'body',
                             owner='*****@*****.**')
     self.assertEqual(1, service._ExecuteRequest.call_count)
     self.assertEqual(333, bug_id)
コード例 #6
0
 def testNewBug_Failure_NewBugReturnsNone(self):
     service = issue_tracker_service.IssueTrackerService()
     service._ExecuteRequest = mock.Mock(return_value={})
     bug_id = service.NewBug('Bug title',
                             'body',
                             owner='*****@*****.**')
     self.assertEqual(1, service._ExecuteRequest.call_count)
     self.assertIsNone(bug_id)
コード例 #7
0
ファイル: file_bug.py プロジェクト: tigerqiu712/catapult
    def _CreateBug(self, summary, description, labels, components,
                   urlsafe_keys):
        """Creates a bug, associates it with the alerts, sends a HTML response.

    Args:
      summary: The new bug summary string.
      description: The new bug description string.
      labels: List of label strings for the new bug.
      components: List of component strings for the new bug.
      urlsafe_keys: Comma-separated alert keys in urlsafe format.
    """
        alert_keys = [ndb.Key(urlsafe=k) for k in urlsafe_keys.split(',')]
        alerts = ndb.get_multi(alert_keys)

        if not description:
            description = 'See the link to graphs below.'

        milestone_label = _MilestoneLabel(alerts)
        if milestone_label:
            labels.append(milestone_label)

        # Only project members (@chromium.org accounts) can be owners of bugs.
        owner = self.request.get('owner')
        if owner and not owner.endswith('@chromium.org'):
            self.RenderHtml(
                'bug_result.html',
                {'error': 'Owner email address must end with @chromium.org.'})
            return

        http = oauth2_decorator.DECORATOR.http()
        service = issue_tracker_service.IssueTrackerService(http=http)

        bug_id = service.NewBug(summary,
                                description,
                                labels=labels,
                                components=components,
                                owner=owner)
        if not bug_id:
            self.RenderHtml('bug_result.html',
                            {'error': 'Error creating bug!'})
            return

        bug_data.Bug(id=bug_id).put()
        for alert_entity in alerts:
            alert_entity.bug_id = bug_id
        ndb.put_multi(alerts)

        comment_body = _AdditionalDetails(bug_id, alerts)
        service.AddBugComment(bug_id, comment_body)

        template_params = {'bug_id': bug_id}
        if all(k.kind() == 'Anomaly' for k in alert_keys):
            bisect_result = auto_bisect.StartNewBisectForBug(bug_id)
            if 'error' in bisect_result:
                template_params['bisect_error'] = bisect_result['error']
            else:
                template_params.update(bisect_result)
        self.RenderHtml('bug_result.html', template_params)
コード例 #8
0
 def testAddBugComment_Basic(self):
     service = issue_tracker_service.IssueTrackerService()
     service._MakeCommentRequest = mock.Mock()
     self.assertTrue(service.AddBugComment(12345, 'The comment'))
     self.assertEqual(1, service._MakeCommentRequest.call_count)
     service._MakeCommentRequest.assert_called_with(12345, {
         'updates': {},
         'content': 'The comment'
     })
コード例 #9
0
ファイル: auto_triage.py プロジェクト: stevenjb/catapult
    def _CommentOnRecoveredBug(cls, bug_id):
        """Adds a comment and close the bug on Issue tracker."""
        bug = ndb.Key('Bug', bug_id).get()
        if bug.status != bug_data.BUG_STATUS_OPENED:
            return
        bug.status = bug_data.BUG_STATUS_RECOVERED
        bug.put()
        comment = cls._RecoveredBugComment(bug_id)

        issue_tracker = issue_tracker_service.IssueTrackerService(
            additional_credentials=utils.ServiceAccountCredentials())
        issue_tracker.AddBugComment(bug_id, comment)
コード例 #10
0
 def testMakeCommentRequest_UserDoesNotExist_RetryMakeCommentRequest(self):
     service = issue_tracker_service.IssueTrackerService()
     error_content = {
         'error': {
             'message': 'The user does not exist',
             'code': 404
         }
     }
     service._ExecuteRequest = mock.Mock(side_effect=errors.HttpError(
         mock.Mock(
             return_value={'status': 404}), json.dumps(error_content)))
     service.AddBugComment(12345, 'The comment', owner='*****@*****.**')
     self.assertEqual(2, service._ExecuteRequest.call_count)
コード例 #11
0
 def testNewBug_UsesExpectedParams(self):
     service = issue_tracker_service.IssueTrackerService()
     service._MakeCreateRequest = mock.Mock()
     service.NewBug('Bug title', 'body', owner='*****@*****.**')
     service._MakeCreateRequest.assert_called_with({
         'title': 'Bug title',
         'summary': 'Bug title',
         'description': 'body',
         'labels': [],
         'status': 'Assigned',
         'owner': {
             'name': '*****@*****.**'
         },
     })
コード例 #12
0
 def testAddBugComment_MergeBug(self):
     service = issue_tracker_service.IssueTrackerService()
     service._MakeCommentRequest = mock.Mock()
     self.assertTrue(service.AddBugComment(12345, 'Dupe',
                                           merge_issue=54321))
     self.assertEqual(1, service._MakeCommentRequest.call_count)
     service._MakeCommentRequest.assert_called_with(
         12345, {
             'updates': {
                 'status': 'Duplicate',
                 'mergedInto': 54321,
             },
             'content': 'Dupe'
         })
コード例 #13
0
  def _CommentOnRecoveredBug(cls, bug_id):
    """Adds a comment and close the bug on Issue tracker."""
    bug = ndb.Key('Bug', bug_id).get()
    if bug.status != bug_data.BUG_STATUS_OPENED:
      return
    bug.status = bug_data.BUG_STATUS_RECOVERED
    bug.put()
    comment = cls._RecoveredBugComment(bug_id)

    credentials = rietveld_service.Credentials(
        rietveld_service.GetDefaultRietveldConfig(),
        rietveld_service.PROJECTHOSTING_SCOPE)
    issue_tracker = issue_tracker_service.IssueTrackerService(
        additional_credentials=credentials)
    issue_tracker.AddBugComment(bug_id, comment)
コード例 #14
0
 def testMakeCommentRequest_IssueDeleted_ReturnsTrue(self):
     service = issue_tracker_service.IssueTrackerService()
     error_content = {
         'error': {
             'message': 'User is not allowed to view this issue 12345',
             'code': 403
         }
     }
     service._ExecuteRequest = mock.Mock(side_effect=errors.HttpError(
         mock.Mock(
             return_value={'status': 403}), json.dumps(error_content)))
     comment_posted = service.AddBugComment(12345,
                                            'The comment',
                                            owner='*****@*****.**')
     self.assertEqual(1, service._ExecuteRequest.call_count)
     self.assertEqual(True, comment_posted)
コード例 #15
0
 def testAddBugComment_WithOptionalParameters(self):
     service = issue_tracker_service.IssueTrackerService()
     service._MakeCommentRequest = mock.Mock()
     self.assertTrue(
         service.AddBugComment(12345,
                               'Some other comment',
                               status='Fixed',
                               labels=['Foo'],
                               cc_list=['*****@*****.**']))
     self.assertEqual(1, service._MakeCommentRequest.call_count)
     service._MakeCommentRequest.assert_called_with(
         12345, {
             'updates': {
                 'status': 'Fixed',
                 'cc': ['*****@*****.**'],
                 'labels': ['Foo'],
             },
             'content': 'Some other comment'
         })
コード例 #16
0
def PerformBisect(bisect_job):
  """Starts the bisect job.

  This creates a patch, uploads it, then tells Rietveld to try the patch.

  TODO(qyearsley): If we want to use other tryservers sometimes in the future,
  then we need to have some way to decide which one to use. This could
  perhaps be passed as part of the bisect bot name, or guessed from the bisect
  bot name.

  Args:
    bisect_job: A TryJob entity.

  Returns:
    A dictionary containing the result; if successful, this dictionary contains
    the field "issue_id" and "issue_url", otherwise it contains "error".

  Raises:
    AssertionError: Bot or config not set as expected.
    request_handler.InvalidInputError: Some property of the bisect job
        is invalid.
  """
  assert bisect_job.bot and bisect_job.config
  if not bisect_job.key:
    bisect_job.put()

  if bisect_job.use_buildbucket:
    result = _PerformBuildbucketBisect(bisect_job)
  else:
    result = _PerformLegacyBisect(bisect_job)
  if 'error' in result:
    bisect_job.run_count += 1
    bisect_job.SetFailed()
    comment = 'Bisect job failed to kick off'
  elif result.get('issue_url'):
    comment = 'Started bisect job %s' % result['issue_url']
  else:
    comment = 'Started bisect job: %s' % result
  if bisect_job.bug_id:
    issue_tracker = issue_tracker_service.IssueTrackerService(
        additional_credentials=utils.ServiceAccountCredentials())
    issue_tracker.AddBugComment(bisect_job.bug_id, comment, send_email=False)
  return result
コード例 #17
0
    def get(self):
        """The get handler method is called from a cron job.

    It expects no parameters and has no output. It checks all current bisect try
    jobs and send comments to an issue on the issue tracker if a bisect job has
    completed.
    """
        credentials = rietveld_service.Credentials(
            rietveld_service.GetDefaultRietveldConfig(),
            rietveld_service.PROJECTHOSTING_SCOPE)
        issue_tracker = issue_tracker_service.IssueTrackerService(
            additional_credentials=credentials)

        # Set privilege so we can also fetch internal try_job entities.
        datastore_hooks.SetPrivilegedRequest()

        jobs_to_check = try_job.TryJob.query(
            try_job.TryJob.status == 'started').fetch()
        all_successful = True
        for job in jobs_to_check:
            try:
                if job.use_buildbucket:
                    logging.info('Checking job %s with Buildbucket job ID %s.',
                                 job.key.id(),
                                 getattr(job, 'buildbucket_job_id', None))
                else:
                    logging.info('Checking job %s with Rietveld issue ID %s.',
                                 job.key.id(),
                                 getattr(job, 'rietveld_issue_id', None))
                _CheckJob(job, issue_tracker)
            except Exception as e:  # pylint: disable=broad-except
                logging.error('Caught Exception %s: %s\n%s',
                              type(e).__name__, e, traceback.format_exc())
                all_successful = False
        if all_successful:
            utils.TickMonitoringCustomMetric('UpdateBugWithResults')
コード例 #18
0
 def testAddBugComment_WithNoBug_ReturnsFalse(self):
     service = issue_tracker_service.IssueTrackerService()
     service._MakeCommentRequest = mock.Mock()
     self.assertFalse(service.AddBugComment(None, 'Some comment'))
     self.assertFalse(service.AddBugComment(-1, 'Some comment'))
コード例 #19
0
 def testAddBugComment_Error(self, mock_logging_error):
     service = issue_tracker_service.IssueTrackerService()
     service._ExecuteRequest = mock.Mock(return_value=None)
     self.assertFalse(service.AddBugComment(12345, 'My bug comment'))
     self.assertEqual(1, service._ExecuteRequest.call_count)
     self.assertEqual(1, mock_logging_error.call_count)