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 from collections import namedtuple
      7 from os import path
      8 import search_related_commits
      9 import shutil
     10 from subprocess import Popen, PIPE, check_call
     11 import unittest
     12 
     13 
     14 TEST_CONFIG = {
     15   "GIT_REPO": "/tmp/test-v8-search-related-commits",
     16 }
     17 
     18 class TestSearchRelatedCommits(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 = """[turbofan] Sanitize language mode for javascript operators.
     41 
     42     R=mstarzinger (at] chromium.org
     43 
     44     Review URL: https://codereview.chromium.org/1084243005
     45 
     46     Cr-Commit-Position: refs/heads/master@{#28059}"""
     47     self._make_empty_commit(message)
     48 
     49     message = """[crankshaft] Do some stuff
     50 
     51     R=hablich (at] chromium.org
     52 
     53     Review URL: https://codereview.chromium.org/1084243007
     54 
     55     Cr-Commit-Position: refs/heads/master@{#28030}"""
     56 
     57     self._make_empty_commit(message)
     58 
     59   def tearDown(self):
     60     if path.exists(self.base_dir):
     61       shutil.rmtree(self.base_dir)
     62 
     63   def _assert_correct_standard_result(
     64       self, result, all_commits, hash_of_first_commit):
     65     self.assertEqual(len(result), 1, "Master commit not found")
     66     self.assertTrue(
     67         result.get(hash_of_first_commit),
     68         "Master commit is wrong")
     69 
     70     self.assertEqual(
     71         len(result[hash_of_first_commit]),
     72         1,
     73         "Child commit not found")
     74     self.assertEqual(
     75         all_commits[2],
     76         result[hash_of_first_commit][0],
     77         "Child commit wrong")
     78 
     79   def _get_commits(self):
     80     commits = self._execute_git(
     81         ["log", "--format=%H", "--reverse"]).splitlines()
     82     return commits
     83 
     84   def _make_empty_commit(self, message):
     85     self._execute_git(["commit", "--allow-empty", "-m", message])
     86 
     87   def testSearchByCommitPosition(self):
     88     message = """Revert of some stuff.
     89     > Cr-Commit-Position: refs/heads/master@{#28059}
     90     R=mstarzinger (at] chromium.org
     91 
     92     Review URL: https://codereview.chromium.org/1084243005
     93 
     94     Cr-Commit-Position: refs/heads/master@{#28088}"""
     95 
     96     self._make_empty_commit(message)
     97 
     98     commits = self._get_commits()
     99     hash_of_first_commit = commits[0]
    100 
    101     result = search_related_commits.search_all_related_commits(
    102         self.base_dir, hash_of_first_commit, "HEAD", None)
    103 
    104     self._assert_correct_standard_result(result, commits, hash_of_first_commit)
    105 
    106   def testSearchByTitle(self):
    107     message = """Revert of some stuff.
    108     > [turbofan] Sanitize language mode for javascript operators.
    109     > Cr-Commit-Position: refs/heads/master@{#289}
    110     R=mstarzinger (at] chromium.org
    111 
    112     Review URL: https://codereview.chromium.org/1084243005
    113 
    114     Cr-Commit-Position: refs/heads/master@{#28088}"""
    115 
    116     self._make_empty_commit(message)
    117 
    118     commits = self._get_commits()
    119     hash_of_first_commit = commits[0]
    120 
    121     result = search_related_commits.search_all_related_commits(
    122         self.base_dir, hash_of_first_commit, "HEAD", None)
    123 
    124     self._assert_correct_standard_result(result, commits, hash_of_first_commit)
    125 
    126   def testSearchByHash(self):
    127     commits = self._get_commits()
    128     hash_of_first_commit = commits[0]
    129 
    130     message = """Revert of some stuff.
    131     > [turbofan] Sanitize language mode for javascript operators.
    132     > Reverting """ + hash_of_first_commit + """
    133     > R=mstarzinger (at] chromium.org
    134 
    135     Review URL: https://codereview.chromium.org/1084243005
    136 
    137     Cr-Commit-Position: refs/heads/master@{#28088}"""
    138 
    139     self._make_empty_commit(message)
    140 
    141     #Fetch again for an update
    142     commits = self._get_commits()
    143     hash_of_first_commit = commits[0]
    144 
    145     result = search_related_commits.search_all_related_commits(
    146         self.base_dir,
    147         hash_of_first_commit,
    148         "HEAD",
    149         None)
    150 
    151     self._assert_correct_standard_result(result, commits, hash_of_first_commit)
    152 
    153   def testConsiderSeparator(self):
    154     commits = self._get_commits()
    155     hash_of_first_commit = commits[0]
    156 
    157     # Related commits happen before separator so it is not a hit
    158     message = """Revert of some stuff: Not a hit
    159     > [turbofan] Sanitize language mode for javascript operators.
    160     > Reverting """ + hash_of_first_commit + """
    161     > R=mstarzinger (at] chromium.org
    162 
    163     Review URL: https://codereview.chromium.org/1084243005
    164 
    165     Cr-Commit-Position: refs/heads/master@{#28088}"""
    166     self._make_empty_commit(message)
    167 
    168     # Related commits happen before and after separator so it is a hit
    169     commit_pos_of_master = "27088"
    170     message = """Implement awesome feature: Master commit
    171 
    172     Review URL: https://codereview.chromium.org/1084243235
    173 
    174     Cr-Commit-Position: refs/heads/master@{#""" + commit_pos_of_master + "}"
    175     self._make_empty_commit(message)
    176 
    177     # Separator commit
    178     message = """Commit which is the origin of the branch
    179 
    180     Review URL: https://codereview.chromium.org/1084243456
    181 
    182     Cr-Commit-Position: refs/heads/master@{#28173}"""
    183     self._make_empty_commit(message)
    184 
    185     # Filler commit
    186     message = "Some unrelated commit: Not a hit"
    187     self._make_empty_commit(message)
    188 
    189     # Related commit after separator: a hit
    190     message = "Patch r" + commit_pos_of_master +""" done
    191 
    192     Review URL: https://codereview.chromium.org/1084243235
    193 
    194     Cr-Commit-Position: refs/heads/master@{#29567}"""
    195     self._make_empty_commit(message)
    196 
    197     #Fetch again for an update
    198     commits = self._get_commits()
    199     hash_of_first_commit = commits[0]
    200     hash_of_hit = commits[3]
    201     hash_of_separator = commits[4]
    202     hash_of_child_hit = commits[6]
    203 
    204     result = search_related_commits.search_all_related_commits(
    205         self.base_dir,
    206         hash_of_first_commit,
    207         "HEAD",
    208         hash_of_separator)
    209 
    210     self.assertTrue(result.get(hash_of_hit), "Hit not found")
    211     self.assertEqual(len(result), 1, "More than one hit found")
    212     self.assertEqual(
    213         len(result.get(hash_of_hit)),
    214         1,
    215         "More than one child hit found")
    216     self.assertEqual(
    217         result.get(hash_of_hit)[0],
    218         hash_of_child_hit,
    219         "Wrong commit found")
    220 
    221   def testPrettyPrint(self):
    222     message = """Revert of some stuff.
    223     > [turbofan] Sanitize language mode for javascript operators.
    224     > Cr-Commit-Position: refs/heads/master@{#289}
    225     R=mstarzinger (at] chromium.org
    226 
    227     Review URL: https://codereview.chromium.org/1084243005
    228 
    229     Cr-Commit-Position: refs/heads/master@{#28088}"""
    230 
    231     self._make_empty_commit(message)
    232 
    233     commits = self._get_commits()
    234     hash_of_first_commit = commits[0]
    235     OptionsStruct = namedtuple(
    236         "OptionsStruct",
    237         "git_dir of until all prettyprint separator verbose")
    238     options = OptionsStruct(
    239         git_dir= self.base_dir,
    240         of= [hash_of_first_commit],
    241         until= [commits[2]],
    242         all= True,
    243         prettyprint= True,
    244         separator = None,
    245         verbose=False)
    246     output = []
    247     for current_line in search_related_commits.main(options):
    248       output.append(current_line)
    249 
    250     self.assertIs(len(output), 2, "Not exactly two entries written")
    251     self.assertTrue(output[0].startswith("+"), "Master entry not marked with +")
    252     self.assertTrue(output[1].startswith("| "), "Child entry not marked with |")
    253 
    254   def testNothingFound(self):
    255     commits = self._get_commits()
    256 
    257     self._execute_git(["commit", "--allow-empty", "-m", "A"])
    258     self._execute_git(["commit", "--allow-empty", "-m", "B"])
    259     self._execute_git(["commit", "--allow-empty", "-m", "C"])
    260     self._execute_git(["commit", "--allow-empty", "-m", "D"])
    261 
    262     hash_of_first_commit = commits[0]
    263     result = search_related_commits.search_all_related_commits(
    264         self.base_dir,
    265         hash_of_first_commit,
    266         "HEAD",
    267         None)
    268 
    269     self.assertEqual(len(result), 0, "Results found where none should be.")
    270 
    271 
    272 if __name__ == "__main__":
    273   #import sys;sys.argv = ['', 'Test.testName']
    274    unittest.main()
    275