示例#1
0
def _UpdateSwarmingTaskEntity(master_name,
                              builder_name,
                              build_number,
                              step_name,
                              status=None,
                              task_id=None,
                              error=None,
                              classified_test_results=None,
                              parameters=None,
                              canonical_step_name=None,
                              created_ts=None,
                              started_ts=None,
                              completed_ts=None):
    task = WfSwarmingTask.Get(master_name, builder_name, build_number,
                              step_name)
    assert task
    task.status = status or task.status
    task.task_id = task_id or task.task_id
    task.error = error.ToSerializable() if error else task.error
    task.classified_test_results = task.GetClassifiedTestResults(
        classified_test_results or {}) or task.classified_test_results
    task.parameters = task.parameters or {}
    task.parameters.update(parameters or {})
    task.canonical_step_name = canonical_step_name or task.canonical_step_name
    task.created_time = task.created_time or time_util.DatetimeFromString(
        created_ts)
    task.started_time = task.started_time or time_util.DatetimeFromString(
        started_ts)
    task.completed_time = task.completed_time or time_util.DatetimeFromString(
        completed_ts)
    task.put()
示例#2
0
 def testDatetimeFromString(self):
   self.assertEqual(None, time_util.DatetimeFromString('None'))
   self.assertEqual(None, time_util.DatetimeFromString(None))
   iso_time_str = '2016-01-02T01:02:03.123456'
   iso_time_datetime = time_util.DatetimeFromString(iso_time_str)
   # Check that our function reverses datetime.isoformat
   self.assertEqual(iso_time_datetime.isoformat(), iso_time_str)
   self.assertEqual(iso_time_datetime, time_util.DatetimeFromString(
       iso_time_datetime))
   with self.assertRaises(ValueError):
     time_util.DatetimeFromString('Yesterday, at 5 o\'clock')
示例#3
0
def _ParseFlakeSwarmingTaskOutput(task_data, output_json, error, parameters):
    """Returns swarming task results as a FlakeswarmingTaskOutput object.

  Assumption: only 1 test was run in the Swarming task.
  """
    assert task_data

    iterations = parameters.iterations

    if output_json:
        # Gets the total numbers of runs and number of successful runs from
        # test results
        tries, successes = flake_test_results.GetCountsFromSwarmingRerun(
            output_json)

        if tries is None or successes is None:
            # Something went wrong preventing even a single test from being processed
            # which counts as an error.
            error = error or SwarmingTaskError.GenerateError(
                code=swarming_task_error.UNKNOWN)
            tries = None
            successes = None
        elif (tries == 1 and task_data['state'] == constants.STATE_COMPLETED
              and not task_data.get('failure')
              and not task_data.get('infra_failure')):
            # webkit_layout_tests special case: test results will be combined into
            # one if all results are the same.
            # Use iterations instead assuming the test repeated that many times.
            # Currently only do this if task completes successfully.
            tries = iterations
            successes = iterations * successes

        return FlakeSwarmingTaskOutput(
            completed_time=time_util.DatetimeFromString(
                task_data.get('completed_ts')),
            error=error,
            iterations=tries,
            pass_count=successes,
            started_time=time_util.DatetimeFromString(
                task_data.get('started_ts')),
            task_id=task_data['task_id'])
    else:
        return FlakeSwarmingTaskOutput(
            completed_time=time_util.DatetimeFromString(
                task_data.get('completed_ts')),
            error=error or
            SwarmingTaskError.GenerateError(code=swarming_task_error.UNKNOWN),
            iterations=None,
            pass_count=None,
            started_time=time_util.DatetimeFromString(
                task_data.get('started_ts')),
            task_id=task_data['task_id'])
示例#4
0
 def HandleGet(self):
     start_time = time_util.DatetimeFromString(
         self.request.get('start_time', None))
     end_time = time_util.DatetimeFromString(
         self.request.get('end_time', None))
     closure_counts = {}
     for tree_name in _MONITORED_TREES:
         start_time = start_time or _GetCurrentCheckingPointForTree(
             tree_name)
         all_statuses = _RetrieveTreeStatus(tree_name,
                                            start_time,
                                            end_time=end_time)
         closure_counts[tree_name] = _DetectTreeClosureForTree(
             tree_name, all_statuses)
     return {'data': closure_counts}
示例#5
0
 def commit_attempt_func(cl, message):
     matches = _COMMIT_ATTEMPT_REGEX.match(message['text'])
     if not matches:
         return
     timestamp = time_util.DatetimeFromString(message['date'])
     committer = message['sender']
     patchset_id = str(message['patchset'])
     cl.AddCqAttempt(patchset_id, committer, timestamp)
示例#6
0
def _CreateTreeStatus(tree_status_entry):
    """Creates a TreeStatus model based on the given json data."""
    return TreeStatus(
        time=time_util.DatetimeFromString(tree_status_entry['date']),
        message=tree_status_entry['message'],
        state=tree_status_entry['general_state'],
        username=tree_status_entry['username'],
    )
示例#7
0
 def patchset_reverted_to_issue_func(cl, message):
     matches = _PATCHSET_REVERTED_TO_ISSUE_REGEX.match(message['text'])
     if not matches:
         return
     patchset_id = str(message['patchset'])
     issue_url = matches.group('issueurl')
     url_parts = issue_url.split('/')
     # Support both https://host/1234 and https://host/1234/
     change_id = url_parts[-1] or url_parts[-2]
     reverter = message['sender']
     timestamp = time_util.DatetimeFromString(message['date'])
     revert_cl = self.GetClDetails(change_id)
     revert = cl_info.Revert(patchset_id, revert_cl, reverter,
                             timestamp)
     cl.reverts.append(revert)
示例#8
0
 def patchset_to_revision_func(cl, message):
     matches_cq = _PATCHSET_TO_REVISION_REGEX.match(message['text'])
     matches_manual = _PATCHSET_TO_REVISION_MANUAL_REGEX.match(
         message['text'])
     matches_any = matches_cq or matches_manual
     if not matches_any:
         return
     patchset_id = str(message.get('patchset'))
     revision = matches_any.group('revision')
     timestamp = time_util.DatetimeFromString(message['date'])
     commit = cl_info.Commit(patchset_id, revision, [], timestamp)
     cl.commits.append(commit)
     if matches_manual:
         committer = message['sender']
         # When a patch is manually landed, there is no cq attempt, but since
         # we care about when action was taken, we take the timing of the commit
         # itself as the commit attempt timestamp.
         cl.AddCqAttempt(patchset_id, committer, timestamp)
示例#9
0
    def _ParseClInfo(self, data, cl):
        def patchset_to_revision_func(cl, message):
            matches_cq = _PATCHSET_TO_REVISION_REGEX.match(message['text'])
            matches_manual = _PATCHSET_TO_REVISION_MANUAL_REGEX.match(
                message['text'])
            matches_any = matches_cq or matches_manual
            if not matches_any:
                return
            patchset_id = str(message.get('patchset'))
            revision = matches_any.group('revision')
            timestamp = time_util.DatetimeFromString(message['date'])
            commit = cl_info.Commit(patchset_id, revision, [], timestamp)
            cl.commits.append(commit)
            if matches_manual:
                committer = message['sender']
                # When a patch is manually landed, there is no cq attempt, but since
                # we care about when action was taken, we take the timing of the commit
                # itself as the commit attempt timestamp.
                cl.AddCqAttempt(patchset_id, committer, timestamp)

        def patchset_reverted_to_issue_func(cl, message):
            matches = _PATCHSET_REVERTED_TO_ISSUE_REGEX.match(message['text'])
            if not matches:
                return
            patchset_id = str(message['patchset'])
            issue_url = matches.group('issueurl')
            url_parts = issue_url.split('/')
            # Support both https://host/1234 and https://host/1234/
            change_id = url_parts[-1] or url_parts[-2]
            reverter = message['sender']
            timestamp = time_util.DatetimeFromString(message['date'])
            revert_cl = self.GetClDetails(change_id)
            revert = cl_info.Revert(patchset_id, revert_cl, reverter,
                                    timestamp)
            cl.reverts.append(revert)

        def commit_attempt_func(cl, message):
            matches = _COMMIT_ATTEMPT_REGEX.match(message['text'])
            if not matches:
                return
            timestamp = time_util.DatetimeFromString(message['date'])
            committer = message['sender']
            patchset_id = str(message['patchset'])
            cl.AddCqAttempt(patchset_id, committer, timestamp)

        details_funcs = [
            patchset_to_revision_func,
            patchset_reverted_to_issue_func,
            commit_attempt_func,
        ]

        # Sort by timestamp
        messages = sorted(
            data['messages'],
            key=lambda x: time_util.DatetimeFromString(x.get('date')))
        for message in messages:
            for f in details_funcs:
                f(cl, message)
        cl.closed = data['closed']
        cl.cc = data['cc']
        cl.reviewers = data['reviewers']
        cl.auto_revert_off = codereview.IsAutoRevertOff(data['description'])
        cl.owner_email = data['owner_email']
        return cl
示例#10
0
  def _ParseClInfo(self, change_info, change_id):
    if not change_info:  # pragma: no cover
      return None
    result = cl_info.ClInfo(self._server_hostname, change_id)

    result.reviewers = [
        x['email']
        for x in change_info.get('reviewers', {}).get('REVIEWER', [])
    ]
    result.cc = [
        x['email'] for x in change_info.get('reviewers', {}).get('CC', [])
    ]
    result.closed = change_info['status'] == 'MERGED'
    result.owner_email = change_info['owner'].get('email')
    result.subject = change_info['subject']
    result.revert_of = change_info.get('revert_of')

    # If the status is merged, look at the commit details for the current
    # commit.
    if result.closed:  # pragma: no branch
      current_revision = change_info['current_revision']
      revision_info = change_info['revisions'][current_revision]
      patchset_id = revision_info['_number']
      commit_timestamp = time_util.DatetimeFromString(change_info['submitted'])
      revision_commit = revision_info['commit']
      parent_revisions = [c['commit'] for c in revision_commit['parents']
                         ] if revision_commit else []
      result.commits.append(
          cl_info.Commit(patchset_id, current_revision, parent_revisions,
                         commit_timestamp))

      # Detect manual commits.
      committer = revision_commit['committer']['email']
      if committer not in self.commit_bot_emails:
        result.AddCqAttempt(patchset_id, committer, commit_timestamp)

      result.description = revision_commit['message']

      # Checks for if the culprit owner has turned off auto revert.
      result.auto_revert_off = codereview.IsAutoRevertOff(result.description)

    # Saves information for each patch set.
    for revision, revision_info in change_info['revisions'].iteritems():
      patchset_id = revision_info['_number']
      commit_info = revision_info.get('commit') or {}
      parent_revisions = [c['commit'] for c in commit_info['parents']
                         ] if commit_info else []
      result.patchsets[revision] = cl_info.PatchSet(patchset_id, revision,
                                                    parent_revisions)

    # TO FIND COMMIT ATTEMPTS:
    # In messages look for "Patch Set 1: Commit-Queue+2"
    # or "Patch Set 4: Code-Review+1 Commit-Queue+2".
    cq_pattern = re.compile('^Patch Set \d+:( Code-Review..)? Commit-Queue\+2$')
    revert_tag = 'autogenerated:gerrit:revert'
    revert_pattern = re.compile(
        'Created a revert of this change as (?P<change_id>I[a-f\d]{40})')

    for message in change_info.get('messages', []):
      if cq_pattern.match(message['message'].splitlines()[0]):
        patchset_id = message['_revision_number']
        author = message['author']['email']
        timestamp = time_util.DatetimeFromString(message['date'])
        result.AddCqAttempt(patchset_id, author, timestamp)

      # TO FIND REVERT(S):
      if message.get('tag') == revert_tag:
        patchset_id = message['_revision_number']
        author = message['author']['email']
        timestamp = time_util.DatetimeFromString(message['date'])
        reverting_change_id = revert_pattern.match(
            message['message']).group('change_id')
        reverting_cl = self.GetClDetails(reverting_change_id)
        result.reverts.append(
            cl_info.Revert(patchset_id, reverting_cl, author, timestamp))
    return result