Home | History | Annotate | Download | only in release
      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 
      6 import mergeinfo
      7 import shutil
      8 import unittest
      9 
     10 from collections import namedtuple
     11 from os import path
     12 from subprocess import Popen, PIPE, check_call
     13 
     14 TEST_CONFIG = {
     15   "GIT_REPO": "/tmp/test-v8-search-related-commits",
     16 }
     17 
     18 class 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 _update_origin(self):
     34     # Fetch from origin to get/update the origin/master branch
     35     self._execute_git(['fetch', 'origin'])
     36 
     37   def setUp(self):
     38     if path.exists(self.base_dir):
     39       shutil.rmtree(self.base_dir)
     40 
     41     check_call(["git", "init", self.base_dir])
     42 
     43     # Add fake remote with name 'origin'
     44     self._execute_git(['remote', 'add', 'origin', self.base_dir])
     45 
     46     # Initial commit
     47     message = '''Initial commit'''
     48 
     49     self._make_empty_commit(message)
     50 
     51   def tearDown(self):
     52     if path.exists(self.base_dir):
     53       shutil.rmtree(self.base_dir)
     54 
     55   def _assert_correct_standard_result(
     56       self, result, all_commits, hash_of_first_commit):
     57     self.assertEqual(len(result), 1, "Master commit not found")
     58     self.assertTrue(
     59         result.get(hash_of_first_commit),
     60         "Master commit is wrong")
     61 
     62     self.assertEqual(
     63         len(result[hash_of_first_commit]),
     64         1,
     65         "Child commit not found")
     66     self.assertEqual(
     67         all_commits[2],
     68         result[hash_of_first_commit][0],
     69         "Child commit wrong")
     70 
     71   def _get_commits(self):
     72     commits = self._execute_git(
     73         ["log", "--format=%H", "--reverse"]).splitlines()
     74     return commits
     75 
     76   def _get_branches(self, hash):
     77     return mergeinfo.get_branches_for_commit(self.base_dir, hash)
     78 
     79   def _make_empty_commit(self, message):
     80     self._execute_git(["commit", "--allow-empty", "-m", message])
     81     self._update_origin()
     82     return self._get_commits()[-1]
     83 
     84   def testCanDescribeCommit(self):
     85     commits = self._get_commits()
     86     hash_of_first_commit = commits[0]
     87 
     88     result = mergeinfo.describe_commit(
     89         self.base_dir,
     90         hash_of_first_commit).splitlines()
     91 
     92     self.assertEqual(
     93         result[0],
     94         'commit ' + hash_of_first_commit)
     95 
     96   def testCanDescribeCommitSingleLine(self):
     97     commits = self._get_commits()
     98     hash_of_first_commit = commits[0]
     99 
    100     result = mergeinfo.describe_commit(
    101         self.base_dir,
    102         hash_of_first_commit, True).splitlines()
    103 
    104     self.assertEqual(
    105         str(result[0]),
    106         str(hash_of_first_commit[0:7]) + ' Initial commit')
    107 
    108   def testSearchFollowUpCommits(self):
    109     commits = self._get_commits()
    110     hash_of_first_commit = commits[0]
    111 
    112     message = 'Follow-up commit of '  + hash_of_first_commit
    113     self._make_empty_commit(message)
    114     self._make_empty_commit(message)
    115     self._make_empty_commit(message)
    116     commits = self._get_commits()
    117     message = 'Not related commit'
    118     self._make_empty_commit(message)
    119 
    120     followups = mergeinfo.get_followup_commits(
    121         self.base_dir,
    122         hash_of_first_commit)
    123     self.assertEqual(set(followups), set(commits[1:]))
    124 
    125   def testSearchMerges(self):
    126     self._execute_git(['branch', 'test'])
    127     self._execute_git(['checkout', 'master'])
    128     message = 'real initial commit'
    129     self._make_empty_commit(message)
    130     commits = self._get_commits()
    131     hash_of_first_commit = commits[0]
    132 
    133     self._execute_git(['checkout', 'test'])
    134     message = 'Not related commit'
    135     self._make_empty_commit(message)
    136 
    137     # This should be found
    138     message = 'Merge '  + hash_of_first_commit
    139     hash_of_hit = self._make_empty_commit(message)
    140 
    141     # This should be ignored
    142     message = 'Cr-Branched-From: '  + hash_of_first_commit
    143     hash_of_ignored = self._make_empty_commit(message)
    144 
    145     self._execute_git(['checkout', 'master'])
    146 
    147     followups = mergeinfo.get_followup_commits(
    148         self.base_dir,
    149         hash_of_first_commit)
    150 
    151     # Check if follow ups and merges are not overlapping
    152     self.assertEqual(len(followups), 0)
    153 
    154     message = 'Follow-up commit of '  + hash_of_first_commit
    155     hash_of_followup = self._make_empty_commit(message)
    156 
    157     merges = mergeinfo.get_merge_commits(self.base_dir, hash_of_first_commit)
    158     # Check if follow up is ignored
    159     self.assertTrue(hash_of_followup not in merges)
    160 
    161     # Check for proper return of merges
    162     self.assertTrue(hash_of_hit in merges)
    163     self.assertTrue(hash_of_ignored not in merges)
    164 
    165   def testIsLkgr(self):
    166     commits = self._get_commits()
    167     hash_of_first_commit = commits[0]
    168     self._make_empty_commit('This one is the lkgr head')
    169     self._execute_git(['branch', 'remotes/origin/lkgr'])
    170     hash_of_not_lkgr = self._make_empty_commit('This one is not yet lkgr')
    171 
    172     branches = self._get_branches(hash_of_first_commit);
    173     self.assertTrue(mergeinfo.is_lkgr(branches))
    174     branches = self._get_branches(hash_of_not_lkgr);
    175     self.assertFalse(mergeinfo.is_lkgr(branches))
    176 
    177   def testShowFirstCanary(self):
    178     commits = self._get_commits()
    179     hash_of_first_commit = commits[0]
    180 
    181     branches = self._get_branches(hash_of_first_commit);
    182     self.assertEqual(mergeinfo.get_first_canary(branches), 'No Canary coverage')
    183 
    184     self._execute_git(['branch', 'remotes/origin/chromium/2345'])
    185     self._execute_git(['branch', 'remotes/origin/chromium/2346'])
    186 
    187     branches = self._get_branches(hash_of_first_commit);
    188     self.assertEqual(mergeinfo.get_first_canary(branches), '2345')
    189 
    190   def testFirstV8Version(self):
    191     commits = self._get_commits()
    192     hash_of_first_commit = commits[0]
    193 
    194     self._execute_git(['branch', 'remotes/origin/chromium/2345'])
    195     self._execute_git(['branch', 'remotes/origin/chromium/2346'])
    196     branches = self._get_branches(hash_of_first_commit);
    197     self.assertEqual(mergeinfo.get_first_v8_version(branches), '--')
    198 
    199     self._execute_git(['branch', 'remotes/origin/5.7.1'])
    200     self._execute_git(['branch', 'remotes/origin/5.8.1'])
    201     branches = self._get_branches(hash_of_first_commit);
    202     self.assertEqual(mergeinfo.get_first_v8_version(branches), '5.7.1')
    203 
    204     self._execute_git(['branch', 'remotes/origin/5.6.1'])
    205     branches = self._get_branches(hash_of_first_commit);
    206     self.assertEqual(mergeinfo.get_first_v8_version(branches), '5.6.1')
    207 
    208 if __name__ == "__main__":
    209    unittest.main()
    210