| #!/usr/bin/env python3 | 
 | # -*- coding: utf-8 -*- | 
 | # Copyright 2020 The ChromiumOS Authors. All rights reserved. | 
 | # Use of this source code is governed by a BSD-style license that can be | 
 | # found in the LICENSE file. | 
 |  | 
 | """Unit tests for git helper functions.""" | 
 |  | 
 |  | 
 | import os | 
 | import subprocess | 
 | import tempfile | 
 | import unittest | 
 | import unittest.mock as mock | 
 |  | 
 | import git | 
 |  | 
 |  | 
 | # These are unittests; protected access is OK to a point. | 
 | # pylint: disable=protected-access | 
 |  | 
 |  | 
 | class HelperFunctionsTest(unittest.TestCase): | 
 |     """Test class for updating LLVM hashes of packages.""" | 
 |  | 
 |     @mock.patch.object(os.path, "isdir", return_value=False) | 
 |     def testFailedToCreateBranchForInvalidDirectoryPath(self, mock_isdir): | 
 |         path_to_repo = "/invalid/path/to/repo" | 
 |         branch = "branch-name" | 
 |  | 
 |         # Verify the exception is raised when provided an invalid directory path. | 
 |         with self.assertRaises(ValueError) as err: | 
 |             git.CreateBranch(path_to_repo, branch) | 
 |  | 
 |         self.assertEqual( | 
 |             str(err.exception), | 
 |             "Invalid directory path provided: %s" % path_to_repo, | 
 |         ) | 
 |  | 
 |         mock_isdir.assert_called_once() | 
 |  | 
 |     @mock.patch.object(os.path, "isdir", return_value=True) | 
 |     @mock.patch.object(subprocess, "check_output", return_value=None) | 
 |     def testSuccessfullyCreatedBranch(self, mock_command_output, mock_isdir): | 
 |         path_to_repo = "/path/to/repo" | 
 |         branch = "branch-name" | 
 |  | 
 |         git.CreateBranch(path_to_repo, branch) | 
 |  | 
 |         mock_isdir.assert_called_once_with(path_to_repo) | 
 |  | 
 |         self.assertEqual(mock_command_output.call_count, 2) | 
 |  | 
 |     @mock.patch.object(os.path, "isdir", return_value=False) | 
 |     def testFailedToDeleteBranchForInvalidDirectoryPath(self, mock_isdir): | 
 |         path_to_repo = "/invalid/path/to/repo" | 
 |         branch = "branch-name" | 
 |  | 
 |         # Verify the exception is raised on an invalid repo path. | 
 |         with self.assertRaises(ValueError) as err: | 
 |             git.DeleteBranch(path_to_repo, branch) | 
 |  | 
 |         self.assertEqual( | 
 |             str(err.exception), | 
 |             "Invalid directory path provided: %s" % path_to_repo, | 
 |         ) | 
 |  | 
 |         mock_isdir.assert_called_once() | 
 |  | 
 |     @mock.patch.object(os.path, "isdir", return_value=True) | 
 |     @mock.patch.object(subprocess, "check_output", return_value=None) | 
 |     def testSuccessfullyDeletedBranch(self, mock_command_output, mock_isdir): | 
 |         path_to_repo = "/valid/path/to/repo" | 
 |         branch = "branch-name" | 
 |  | 
 |         git.DeleteBranch(path_to_repo, branch) | 
 |  | 
 |         mock_isdir.assert_called_once_with(path_to_repo) | 
 |  | 
 |         self.assertEqual(mock_command_output.call_count, 3) | 
 |  | 
 |     @mock.patch.object(os.path, "isdir", return_value=False) | 
 |     def testFailedToUploadChangesForInvalidDirectoryPath(self, mock_isdir): | 
 |         path_to_repo = "/some/path/to/repo" | 
 |         branch = "update-LLVM_NEXT_HASH-a123testhash3" | 
 |         commit_messages = ["Test message"] | 
 |  | 
 |         # Verify exception is raised when on an invalid repo path. | 
 |         with self.assertRaises(ValueError) as err: | 
 |             git.UploadChanges(path_to_repo, branch, commit_messages) | 
 |  | 
 |         self.assertEqual( | 
 |             str(err.exception), "Invalid path provided: %s" % path_to_repo | 
 |         ) | 
 |  | 
 |         mock_isdir.assert_called_once() | 
 |  | 
 |     @mock.patch.object(os.path, "isdir", return_value=True) | 
 |     @mock.patch.object(subprocess, "check_output") | 
 |     @mock.patch.object(tempfile, "NamedTemporaryFile") | 
 |     def testSuccessfullyUploadedChangesForReview( | 
 |         self, mock_tempfile, mock_commands, mock_isdir | 
 |     ): | 
 |  | 
 |         path_to_repo = "/some/path/to/repo" | 
 |         branch = "branch-name" | 
 |         commit_messages = ["Test message"] | 
 |         mock_tempfile.return_value.__enter__.return_value.name = "tmp" | 
 |  | 
 |         # A test CL generated by `repo upload`. | 
 |         mock_commands.side_effect = [ | 
 |             None, | 
 |             ( | 
 |                 "remote: https://chromium-review.googlesource." | 
 |                 "com/c/chromiumos/overlays/chromiumos-overlay/" | 
 |                 "+/193147 Fix stdout" | 
 |             ), | 
 |         ] | 
 |         change_list = git.UploadChanges(path_to_repo, branch, commit_messages) | 
 |  | 
 |         self.assertEqual(change_list.cl_number, 193147) | 
 |  | 
 |         mock_isdir.assert_called_once_with(path_to_repo) | 
 |  | 
 |         expected_command = [ | 
 |             "git", | 
 |             "commit", | 
 |             "-F", | 
 |             mock_tempfile.return_value.__enter__.return_value.name, | 
 |         ] | 
 |         self.assertEqual( | 
 |             mock_commands.call_args_list[0], | 
 |             mock.call(expected_command, cwd=path_to_repo), | 
 |         ) | 
 |  | 
 |         expected_cmd = [ | 
 |             "repo", | 
 |             "upload", | 
 |             "--yes", | 
 |             "--ne", | 
 |             "--no-verify", | 
 |             "--br=%s" % branch, | 
 |         ] | 
 |         self.assertEqual( | 
 |             mock_commands.call_args_list[1], | 
 |             mock.call( | 
 |                 expected_cmd, | 
 |                 stderr=subprocess.STDOUT, | 
 |                 cwd=path_to_repo, | 
 |                 encoding="utf-8", | 
 |             ), | 
 |         ) | 
 |  | 
 |         self.assertEqual( | 
 |             change_list.url, | 
 |             "https://chromium-review.googlesource.com/c/chromiumos/overlays/" | 
 |             "chromiumos-overlay/+/193147", | 
 |         ) | 
 |  | 
 |  | 
 | if __name__ == "__main__": | 
 |     unittest.main() |