1#!/usr/bin/env python 2# Copyright 2015 the V8 project authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6import mergeinfo 7import shutil 8import unittest 9 10from collections import namedtuple 11from os import path 12from subprocess import Popen, PIPE, check_call 13 14TEST_CONFIG = { 15 "GIT_REPO": "/tmp/test-v8-search-related-commits", 16} 17 18class TestMergeInfo(unittest.TestCase): 19 20 base_dir = TEST_CONFIG["GIT_REPO"] 21 22 def _execute_git(self, git_args): 23 24 fullCommand = ["git", "-C", self.base_dir] + git_args 25 p = Popen(args=fullCommand, stdin=PIPE, 26 stdout=PIPE, stderr=PIPE) 27 output, err = p.communicate() 28 rc = p.returncode 29 if rc != 0: 30 raise Exception(err) 31 return output 32 33 def setUp(self): 34 if path.exists(self.base_dir): 35 shutil.rmtree(self.base_dir) 36 37 check_call(["git", "init", self.base_dir]) 38 39 # Initial commit 40 message = '''Initial commit''' 41 42 self._make_empty_commit(message) 43 44 def tearDown(self): 45 if path.exists(self.base_dir): 46 shutil.rmtree(self.base_dir) 47 48 def _assert_correct_standard_result( 49 self, result, all_commits, hash_of_first_commit): 50 self.assertEqual(len(result), 1, "Master commit not found") 51 self.assertTrue( 52 result.get(hash_of_first_commit), 53 "Master commit is wrong") 54 55 self.assertEqual( 56 len(result[hash_of_first_commit]), 57 1, 58 "Child commit not found") 59 self.assertEqual( 60 all_commits[2], 61 result[hash_of_first_commit][0], 62 "Child commit wrong") 63 64 def _get_commits(self): 65 commits = self._execute_git( 66 ["log", "--format=%H", "--reverse"]).splitlines() 67 return commits 68 69 def _make_empty_commit(self, message): 70 self._execute_git(["commit", "--allow-empty", "-m", message]) 71 return self._get_commits()[-1] 72 73 def testCanDescribeCommit(self): 74 commits = self._get_commits() 75 hash_of_first_commit = commits[0] 76 77 result = mergeinfo.describe_commit( 78 self.base_dir, 79 hash_of_first_commit).splitlines() 80 81 self.assertEqual( 82 result[0], 83 'commit ' + hash_of_first_commit) 84 85 def testCanDescribeCommitSingleLine(self): 86 commits = self._get_commits() 87 hash_of_first_commit = commits[0] 88 89 result = mergeinfo.describe_commit( 90 self.base_dir, 91 hash_of_first_commit, True).splitlines() 92 93 self.assertEqual( 94 str(result[0]), 95 str(hash_of_first_commit[0:7]) + ' Initial commit') 96 97 def testSearchFollowUpCommits(self): 98 commits = self._get_commits() 99 hash_of_first_commit = commits[0] 100 101 message = 'Follow-up commit of ' + hash_of_first_commit 102 self._make_empty_commit(message) 103 self._make_empty_commit(message) 104 self._make_empty_commit(message) 105 commits = self._get_commits() 106 message = 'Not related commit' 107 self._make_empty_commit(message) 108 109 followups = mergeinfo.get_followup_commits( 110 self.base_dir, 111 hash_of_first_commit) 112 self.assertEqual(set(followups), set(commits[1:])) 113 114 def testSearchMerges(self): 115 self._execute_git(['branch', 'test']) 116 self._execute_git(['checkout', 'master']) 117 message = 'real initial commit' 118 self._make_empty_commit(message) 119 commits = self._get_commits() 120 hash_of_first_commit = commits[0] 121 122 self._execute_git(['checkout', 'test']) 123 message = 'Not related commit' 124 self._make_empty_commit(message) 125 126 # This should be found 127 message = 'Merge ' + hash_of_first_commit 128 hash_of_hit = self._make_empty_commit(message) 129 130 # This should be ignored 131 message = 'Cr-Branched-From: ' + hash_of_first_commit 132 hash_of_ignored = self._make_empty_commit(message) 133 134 self._execute_git(['checkout', 'master']) 135 136 followups = mergeinfo.get_followup_commits( 137 self.base_dir, 138 hash_of_first_commit) 139 140 # Check if follow ups and merges are not overlapping 141 self.assertEqual(len(followups), 0) 142 143 message = 'Follow-up commit of ' + hash_of_first_commit 144 hash_of_followup = self._make_empty_commit(message) 145 146 merges = mergeinfo.get_merge_commits(self.base_dir, hash_of_first_commit) 147 # Check if follow up is ignored 148 self.assertTrue(hash_of_followup not in merges) 149 150 # Check for proper return of merges 151 self.assertTrue(hash_of_hit in merges) 152 self.assertTrue(hash_of_ignored not in merges) 153 154 def testIsLkgr(self): 155 commits = self._get_commits() 156 hash_of_first_commit = commits[0] 157 self._make_empty_commit('This one is the lkgr head') 158 self._execute_git(['branch', 'remotes/origin/lkgr']) 159 hash_of_not_lkgr = self._make_empty_commit('This one is not yet lkgr') 160 161 self.assertTrue(mergeinfo.is_lkgr( 162 self.base_dir, hash_of_first_commit)) 163 self.assertFalse(mergeinfo.is_lkgr( 164 self.base_dir, hash_of_not_lkgr)) 165 166 def testShowFirstCanary(self): 167 commits = self._get_commits() 168 hash_of_first_commit = commits[0] 169 170 self.assertEqual(mergeinfo.get_first_canary( 171 self.base_dir, hash_of_first_commit), 'No Canary coverage') 172 173 self._execute_git(['branch', 'remotes/origin/chromium/2345']) 174 self._execute_git(['branch', 'remotes/origin/chromium/2346']) 175 176 self.assertEqual(mergeinfo.get_first_canary( 177 self.base_dir, hash_of_first_commit), '2345') 178 179if __name__ == "__main__": 180 unittest.main() 181