#!/usr/bin/env vpython3 """Tests for split_cl.""" import os import sys import unittest from unittest import mock sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) import split_cl class SplitClTest(unittest.TestCase): def testAddUploadedByGitClSplitToDescription(self): description = """Convert use of X to Y in $directory """ footers = 'Bug: 12345' added_line = 'This CL was uploaded by git cl split.' # Description without footers self.assertEqual( split_cl.AddUploadedByGitClSplitToDescription(description), description + added_line) # Description with footers self.assertEqual( split_cl.AddUploadedByGitClSplitToDescription(description + footers), description + added_line + '\n\n' + footers) def testFormatDescriptionOrComment(self): description = "Converted use of X to Y in $directory." # One directory self.assertEqual( split_cl.FormatDescriptionOrComment(description, ["foo"]), "Converted use of X to Y in foo.", ) # Many directories self.assertEqual( split_cl.FormatDescriptionOrComment(description, ["foo", "bar"]), "Converted use of X to Y in ['foo', 'bar'].", ) def GetDirectoryBaseName(self, file_path): return os.path.basename(os.path.dirname(file_path)) def MockSuggestOwners(self, paths, exclude=None): if not paths: return ["superowner"] return self.GetDirectoryBaseName(paths[0]).split(",") def MockIsFile(self, file_path): if os.path.basename(file_path) == "OWNERS": return "owner" in self.GetDirectoryBaseName(file_path) return True @mock.patch("os.path.isfile") def testSelectReviewersForFiles(self, mock_is_file): mock_is_file.side_effect = self.MockIsFile owners_client = mock.Mock(SuggestOwners=self.MockSuggestOwners, EVERYONE="*") cl = mock.Mock(owners_client=owners_client) files = [("M", os.path.join("foo", "owner1,owner2", "a.txt")), ("M", os.path.join("foo", "owner1,owner2", "b.txt")), ("M", os.path.join("bar", "owner1,owner2", "c.txt")), ("M", os.path.join("bax", "owner2", "d.txt")), ("M", os.path.join("baz", "owner3", "e.txt"))] files_split_by_reviewers = split_cl.SelectReviewersForFiles( cl, "author", files, 0) self.assertEqual(3, len(files_split_by_reviewers.keys())) info1 = files_split_by_reviewers[tuple(["owner1", "owner2"])] self.assertEqual(info1.files, [("M", os.path.join("foo", "owner1,owner2", "a.txt")), ("M", os.path.join("foo", "owner1,owner2", "b.txt")), ("M", os.path.join("bar", "owner1,owner2", "c.txt"))]) self.assertEqual(info1.owners_directories, ["foo/owner1,owner2", "bar/owner1,owner2"]) info2 = files_split_by_reviewers[tuple(["owner2"])] self.assertEqual(info2.files, [("M", os.path.join("bax", "owner2", "d.txt"))]) self.assertEqual(info2.owners_directories, ["bax/owner2"]) info3 = files_split_by_reviewers[tuple(["owner3"])] self.assertEqual(info3.files, [("M", os.path.join("baz", "owner3", "e.txt"))]) self.assertEqual(info3.owners_directories, ["baz/owner3"]) class UploadClTester: """Sets up test environment for testing split_cl.UploadCl()""" def __init__(self, test): self.mock_git_branches = self.StartPatcher("git_common.branches", test) self.mock_git_branches.return_value = [] self.mock_git_current_branch = self.StartPatcher( "git_common.current_branch", test) self.mock_git_current_branch.return_value = "branch_to_upload" self.mock_git_run = self.StartPatcher("git_common.run", test) self.mock_temporary_file = self.StartPatcher( "gclient_utils.temporary_file", test) self.mock_temporary_file( ).__enter__.return_value = "temporary_file0" self.mock_file_writer = self.StartPatcher("gclient_utils.FileWrite", test) def StartPatcher(self, target, test): patcher = mock.patch(target) test.addCleanup(patcher.stop) return patcher.start() def DoUploadCl(self, directories, files, reviewers, cmd_upload): split_cl.UploadCl("branch_to_upload", "upstream_branch", directories, files, "description", None, reviewers, mock.Mock(), cmd_upload, True, True, "topic", os.path.sep) def testUploadCl(self): """Tests commands run by UploadCl.""" upload_cl_tester = self.UploadClTester(self) directories = ["dir0"] files = [("M", os.path.join("bar", "a.cc")), ("D", os.path.join("foo", "b.cc"))] reviewers = {"reviewer1@gmail.com", "reviewer2@gmail.com"} mock_cmd_upload = mock.Mock() upload_cl_tester.DoUploadCl(directories, files, reviewers, mock_cmd_upload) abs_repository_path = os.path.abspath(os.path.sep) mock_git_run = upload_cl_tester.mock_git_run self.assertEqual(mock_git_run.call_count, 4) mock_git_run.assert_has_calls([ mock.call("checkout", "-t", "upstream_branch", "-b", "branch_to_upload_dir0_split"), mock.call("rm", os.path.join(abs_repository_path, "foo", "b.cc")), mock.call("checkout", "branch_to_upload", "--", os.path.join(abs_repository_path, "bar", "a.cc")), mock.call("commit", "-F", "temporary_file0") ]) expected_upload_args = [ "-f", "-r", "reviewer1@gmail.com,reviewer2@gmail.com", "--cq-dry-run", "--send-mail", "--enable-auto-submit", "--topic=topic" ] mock_cmd_upload.assert_called_once_with(expected_upload_args) def testDontUploadClIfBranchAlreadyExists(self): """Tests that a CL is not uploaded if split branch already exists""" upload_cl_tester = self.UploadClTester(self) upload_cl_tester.mock_git_branches.return_value = [ "branch0", "branch_to_upload_dir0_split" ] directories = ["dir0"] files = [("M", os.path.join("bar", "a.cc")), ("D", os.path.join("foo", "b.cc"))] reviewers = {"reviewer1@gmail.com"} mock_cmd_upload = mock.Mock() upload_cl_tester.DoUploadCl(directories, files, reviewers, mock_cmd_upload) upload_cl_tester.mock_git_run.assert_not_called() mock_cmd_upload.assert_not_called() @mock.patch("gclient_utils.AskForData") def testCheckDescriptionBugLink(self, mock_ask_for_data): # Description contains bug link. self.assertTrue(split_cl.CheckDescriptionBugLink("Bug:1234")) self.assertEqual(mock_ask_for_data.call_count, 0) # Description does not contain bug link. User does not enter 'y' when # prompted. mock_ask_for_data.reset_mock() mock_ask_for_data.return_value = "m" self.assertFalse(split_cl.CheckDescriptionBugLink("Description")) self.assertEqual(mock_ask_for_data.call_count, 1) # Description does not contain bug link. User enters 'y' when prompted. mock_ask_for_data.reset_mock() mock_ask_for_data.return_value = "y" self.assertTrue(split_cl.CheckDescriptionBugLink("Description")) self.assertEqual(mock_ask_for_data.call_count, 1) if __name__ == '__main__': unittest.main()