blob: 574ce5a7d472811a1ef3044ea6ce75088c529d7c [file] [log] [blame]
#!/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
<add some background about this conversion for the reviewers>
"""
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()