| #!/usr/bin/env python |
| # Copyright 2015 the V8 project authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| from collections import namedtuple |
| from os import path |
| import search_related_commits |
| import shutil |
| from subprocess import Popen, PIPE, check_call |
| import unittest |
| |
| |
| TEST_CONFIG = { |
| "GIT_REPO": "/tmp/test-v8-search-related-commits", |
| } |
| |
| class TestSearchRelatedCommits(unittest.TestCase): |
| |
| base_dir = TEST_CONFIG["GIT_REPO"] |
| |
| def _execute_git(self, git_args): |
| |
| fullCommand = ["git", "-C", self.base_dir] + git_args |
| p = Popen(args=fullCommand, stdin=PIPE, |
| stdout=PIPE, stderr=PIPE) |
| output, err = p.communicate() |
| rc = p.returncode |
| if rc != 0: |
| raise Exception(err) |
| return output |
| |
| def setUp(self): |
| if path.exists(self.base_dir): |
| shutil.rmtree(self.base_dir) |
| |
| check_call(["git", "init", self.base_dir]) |
| |
| # Initial commit |
| message = """[turbofan] Sanitize language mode for javascript operators. |
| |
| R=mstarzinger@chromium.org |
| |
| Review URL: https://codereview.chromium.org/1084243005 |
| |
| Cr-Commit-Position: refs/heads/master@{#28059}""" |
| self._make_empty_commit(message) |
| |
| message = """[crankshaft] Do some stuff |
| |
| R=hablich@chromium.org |
| |
| Review URL: https://codereview.chromium.org/1084243007 |
| |
| Cr-Commit-Position: refs/heads/master@{#28030}""" |
| |
| self._make_empty_commit(message) |
| |
| def tearDown(self): |
| if path.exists(self.base_dir): |
| shutil.rmtree(self.base_dir) |
| |
| def _assert_correct_standard_result( |
| self, result, all_commits, hash_of_first_commit): |
| self.assertEqual(len(result), 1, "Master commit not found") |
| self.assertTrue( |
| result.get(hash_of_first_commit), |
| "Master commit is wrong") |
| |
| self.assertEqual( |
| len(result[hash_of_first_commit]), |
| 1, |
| "Child commit not found") |
| self.assertEqual( |
| all_commits[2], |
| result[hash_of_first_commit][0], |
| "Child commit wrong") |
| |
| def _get_commits(self): |
| commits = self._execute_git( |
| ["log", "--format=%H", "--reverse"]).splitlines() |
| return commits |
| |
| def _make_empty_commit(self, message): |
| self._execute_git(["commit", "--allow-empty", "-m", message]) |
| |
| def testSearchByCommitPosition(self): |
| message = """Revert of some stuff. |
| > Cr-Commit-Position: refs/heads/master@{#28059} |
| R=mstarzinger@chromium.org |
| |
| Review URL: https://codereview.chromium.org/1084243005 |
| |
| Cr-Commit-Position: refs/heads/master@{#28088}""" |
| |
| self._make_empty_commit(message) |
| |
| commits = self._get_commits() |
| hash_of_first_commit = commits[0] |
| |
| result = search_related_commits.search_all_related_commits( |
| self.base_dir, hash_of_first_commit, "HEAD", None) |
| |
| self._assert_correct_standard_result(result, commits, hash_of_first_commit) |
| |
| def testSearchByTitle(self): |
| message = """Revert of some stuff. |
| > [turbofan] Sanitize language mode for javascript operators. |
| > Cr-Commit-Position: refs/heads/master@{#289} |
| R=mstarzinger@chromium.org |
| |
| Review URL: https://codereview.chromium.org/1084243005 |
| |
| Cr-Commit-Position: refs/heads/master@{#28088}""" |
| |
| self._make_empty_commit(message) |
| |
| commits = self._get_commits() |
| hash_of_first_commit = commits[0] |
| |
| result = search_related_commits.search_all_related_commits( |
| self.base_dir, hash_of_first_commit, "HEAD", None) |
| |
| self._assert_correct_standard_result(result, commits, hash_of_first_commit) |
| |
| def testSearchByHash(self): |
| commits = self._get_commits() |
| hash_of_first_commit = commits[0] |
| |
| message = """Revert of some stuff. |
| > [turbofan] Sanitize language mode for javascript operators. |
| > Reverting """ + hash_of_first_commit + """ |
| > R=mstarzinger@chromium.org |
| |
| Review URL: https://codereview.chromium.org/1084243005 |
| |
| Cr-Commit-Position: refs/heads/master@{#28088}""" |
| |
| self._make_empty_commit(message) |
| |
| #Fetch again for an update |
| commits = self._get_commits() |
| hash_of_first_commit = commits[0] |
| |
| result = search_related_commits.search_all_related_commits( |
| self.base_dir, |
| hash_of_first_commit, |
| "HEAD", |
| None) |
| |
| self._assert_correct_standard_result(result, commits, hash_of_first_commit) |
| |
| def testConsiderSeparator(self): |
| commits = self._get_commits() |
| hash_of_first_commit = commits[0] |
| |
| # Related commits happen before separator so it is not a hit |
| message = """Revert of some stuff: Not a hit |
| > [turbofan] Sanitize language mode for javascript operators. |
| > Reverting """ + hash_of_first_commit + """ |
| > R=mstarzinger@chromium.org |
| |
| Review URL: https://codereview.chromium.org/1084243005 |
| |
| Cr-Commit-Position: refs/heads/master@{#28088}""" |
| self._make_empty_commit(message) |
| |
| # Related commits happen before and after separator so it is a hit |
| commit_pos_of_master = "27088" |
| message = """Implement awesome feature: Master commit |
| |
| Review URL: https://codereview.chromium.org/1084243235 |
| |
| Cr-Commit-Position: refs/heads/master@{#""" + commit_pos_of_master + "}" |
| self._make_empty_commit(message) |
| |
| # Separator commit |
| message = """Commit which is the origin of the branch |
| |
| Review URL: https://codereview.chromium.org/1084243456 |
| |
| Cr-Commit-Position: refs/heads/master@{#28173}""" |
| self._make_empty_commit(message) |
| |
| # Filler commit |
| message = "Some unrelated commit: Not a hit" |
| self._make_empty_commit(message) |
| |
| # Related commit after separator: a hit |
| message = "Patch r" + commit_pos_of_master +""" done |
| |
| Review URL: https://codereview.chromium.org/1084243235 |
| |
| Cr-Commit-Position: refs/heads/master@{#29567}""" |
| self._make_empty_commit(message) |
| |
| #Fetch again for an update |
| commits = self._get_commits() |
| hash_of_first_commit = commits[0] |
| hash_of_hit = commits[3] |
| hash_of_separator = commits[4] |
| hash_of_child_hit = commits[6] |
| |
| result = search_related_commits.search_all_related_commits( |
| self.base_dir, |
| hash_of_first_commit, |
| "HEAD", |
| hash_of_separator) |
| |
| self.assertTrue(result.get(hash_of_hit), "Hit not found") |
| self.assertEqual(len(result), 1, "More than one hit found") |
| self.assertEqual( |
| len(result.get(hash_of_hit)), |
| 1, |
| "More than one child hit found") |
| self.assertEqual( |
| result.get(hash_of_hit)[0], |
| hash_of_child_hit, |
| "Wrong commit found") |
| |
| def testPrettyPrint(self): |
| message = """Revert of some stuff. |
| > [turbofan] Sanitize language mode for javascript operators. |
| > Cr-Commit-Position: refs/heads/master@{#289} |
| R=mstarzinger@chromium.org |
| |
| Review URL: https://codereview.chromium.org/1084243005 |
| |
| Cr-Commit-Position: refs/heads/master@{#28088}""" |
| |
| self._make_empty_commit(message) |
| |
| commits = self._get_commits() |
| hash_of_first_commit = commits[0] |
| OptionsStruct = namedtuple( |
| "OptionsStruct", |
| "git_dir of until all prettyprint separator verbose") |
| options = OptionsStruct( |
| git_dir= self.base_dir, |
| of= [hash_of_first_commit], |
| until= [commits[2]], |
| all= True, |
| prettyprint= True, |
| separator = None, |
| verbose=False) |
| output = [] |
| for current_line in search_related_commits.main(options): |
| output.append(current_line) |
| |
| self.assertIs(len(output), 2, "Not exactly two entries written") |
| self.assertTrue(output[0].startswith("+"), "Master entry not marked with +") |
| self.assertTrue(output[1].startswith("| "), "Child entry not marked with |") |
| |
| def testNothingFound(self): |
| commits = self._get_commits() |
| |
| self._execute_git(["commit", "--allow-empty", "-m", "A"]) |
| self._execute_git(["commit", "--allow-empty", "-m", "B"]) |
| self._execute_git(["commit", "--allow-empty", "-m", "C"]) |
| self._execute_git(["commit", "--allow-empty", "-m", "D"]) |
| |
| hash_of_first_commit = commits[0] |
| result = search_related_commits.search_all_related_commits( |
| self.base_dir, |
| hash_of_first_commit, |
| "HEAD", |
| None) |
| |
| self.assertEqual(len(result), 0, "Results found where none should be.") |
| |
| |
| if __name__ == "__main__": |
| #import sys;sys.argv = ['', 'Test.testName'] |
| unittest.main() |