def testCommit(self): commit = cl_info.Commit(self.patchset_id, self.revision, self.parent_revisions, self.timestamp) self.assertEqual({ 'patchset_id': self.patchset_id, 'revision': self.revision, 'parent_revisions': self.parent_revisions, 'timestamp': self.formatted_ts }, commit.serialize())
def testClInfo(self): def hours(h): return datetime.timedelta(hours=h) cl = cl_info.ClInfo(self.server, self.change_id) # Adding two attempts with the same timestamp to cover the codepath that # checks that the timestamp is different. cl.AddCqAttempt(self.patchset_id, self.email, self.timestamp) cl.AddCqAttempt(self.patchset_id, self.email, self.timestamp) cl.AddCqAttempt( self.patchset_id, self.email, self.timestamp + datetime.timedelta(hours=1)) commit_1 = cl_info.Commit(self.patchset_id, self.revision, self.parent_revisions, self.timestamp + hours(1)) cl.commits.append(commit_1) self.assertEqual(commit_1, cl.GetCommitInfoByRevision(self.revision)) self.assertIsNone(cl.GetCommitInfoByRevision('randomrevision')) self.assertEqual(self.patchset_id, cl.GetPatchsetIdByRevision(self.revision)) cl.commits.append( cl_info.Commit('3000', 'ef1234', [], self.timestamp + hours(2))) self.assertEqual('3000', cl.GetPatchsetIdByRevision('ef1234')) self.assertIsNone(cl.GetPatchsetIdByRevision('deadc0de')) revert_cl_1 = cl_info.ClInfo(self.server, 'revert1') revert_cl_1.commits.append( cl_info.Commit('r1p1', '007c0de', [], self.timestamp + hours(3))) revert1 = cl_info.Revert(self.patchset_id, revert_cl_1, '*****@*****.**', self.timestamp + hours(3)) cl.reverts.append(revert1) self.assertEqual( '007c0de', cl.GetRevertCLsByRevision(self.revision)[0] .reverting_cl.commits[0].revision) self.assertEqual([], cl.GetRevertCLsByRevision('ef1234')) self.assertIsNone(cl.GetRevertCLsByRevision('deadc0de'))
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)
from common import constants from handlers import check_reverted_cls from infra_api_clients.codereview import cl_info from infra_api_clients.codereview import codereview_util from infra_api_clients.codereview.gerrit import Gerrit from libs import time_util from model import revert_cl_status from model.base_suspected_cl import RevertCL from model.wf_suspected_cl import WfSuspectedCL from services import git from waterfall.test import wf_testcase _MOCKED_FINDIT_REVERTING_CL = cl_info.ClInfo('codereview.chromium.org', '456') _MOCKED_FINDIT_REVERTING_CL.commits = [ cl_info.Commit('1001', 'e5f6a7b8', [], datetime(2017, 3, 15, 1, 10)) ] _MOCKED_FINDIT_REVERTING_CL.commit_attempts = { '1001': cl_info.CommitAttempt('1001', '*****@*****.**', datetime(2017, 3, 15, 0, 7)), } _MOCKED_FINDIT_REVERTED_CL_INFO = cl_info.ClInfo('codereview.chromium.org', '123') _MOCKED_FINDIT_REVERTED_CL_INFO.commits = [ cl_info.Commit('1000', 'a1b2c3d4', [], 1) ] _MOCKED_FINDIT_REVERTED_CL_INFO.reverts = [ cl_info.Revert('1000', _MOCKED_FINDIT_REVERTING_CL, constants.DEFAULT_SERVICE_ACCOUNT, datetime(2017, 3, 15, 1, 9))
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