xref: /aosp_15_r20/external/toolchain-utils/llvm_tools/git_unittest.py (revision 760c253c1ed00ce9abd48f8546f08516e57485fe)
1#!/usr/bin/env python3
2# Copyright 2020 The ChromiumOS Authors
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""Unit tests for git helper functions."""
7
8import os
9import subprocess
10import tempfile
11import unittest
12from unittest import mock
13
14import git
15
16
17# These are unittests; protected access is OK to a point.
18# pylint: disable=protected-access
19
20EXAMPLE_GIT_SHA = "d46d9c1a23118e3943f43fe2dfc9f9c9c0b4aefe"
21
22
23class HelperFunctionsTest(unittest.TestCase):
24    """Test class for updating LLVM hashes of packages."""
25
26    def testIsFullGitSHASuccessCases(self):
27        shas = ("a" * 40, EXAMPLE_GIT_SHA)
28        for s in shas:
29            self.assertTrue(git.IsFullGitSHA(s), s)
30
31    def testIsFullGitSHAFailureCases(self):
32        shas = (
33            "",
34            "A" * 40,
35            "g" * 40,
36            EXAMPLE_GIT_SHA[1:],
37            EXAMPLE_GIT_SHA + "a",
38        )
39        for s in shas:
40            self.assertFalse(git.IsFullGitSHA(s), s)
41
42    @mock.patch.object(os.path, "isdir", return_value=False)
43    def testFailedToCreateBranchForInvalidDirectoryPath(self, mock_isdir):
44        path_to_repo = "/invalid/path/to/repo"
45        branch = "branch-name"
46
47        # Verify the exception is raised when provided an invalid directory
48        # path.
49        with self.assertRaises(ValueError) as err:
50            git.CreateBranch(path_to_repo, branch)
51
52        self.assertEqual(
53            str(err.exception),
54            "Invalid directory path provided: %s" % path_to_repo,
55        )
56
57        mock_isdir.assert_called_once()
58
59    @mock.patch.object(os.path, "isdir", return_value=True)
60    @mock.patch.object(subprocess, "check_output", return_value=None)
61    def testSuccessfullyCreatedBranch(self, mock_command_output, mock_isdir):
62        path_to_repo = "/path/to/repo"
63        branch = "branch-name"
64
65        git.CreateBranch(path_to_repo, branch)
66
67        mock_isdir.assert_called_once_with(path_to_repo)
68
69        self.assertEqual(mock_command_output.call_count, 2)
70
71    @mock.patch.object(os.path, "isdir", return_value=False)
72    def testFailedToDeleteBranchForInvalidDirectoryPath(self, mock_isdir):
73        path_to_repo = "/invalid/path/to/repo"
74        branch = "branch-name"
75
76        # Verify the exception is raised on an invalid repo path.
77        with self.assertRaises(ValueError) as err:
78            git.DeleteBranch(path_to_repo, branch)
79
80        self.assertEqual(
81            str(err.exception),
82            "Invalid directory path provided: %s" % path_to_repo,
83        )
84
85        mock_isdir.assert_called_once()
86
87    @mock.patch.object(os.path, "isdir", return_value=True)
88    @mock.patch.object(subprocess, "run", return_value=None)
89    def testSuccessfullyDeletedBranch(self, mock_command_output, mock_isdir):
90        path_to_repo = "/valid/path/to/repo"
91        branch = "branch-name"
92
93        git.DeleteBranch(path_to_repo, branch)
94
95        mock_isdir.assert_called_once_with(path_to_repo)
96
97        self.assertEqual(mock_command_output.call_count, 3)
98
99    @mock.patch.object(os.path, "isdir", return_value=False)
100    def testFailedToUploadChangesForInvalidDirectoryPath(self, mock_isdir):
101        path_to_repo = "/some/path/to/repo"
102        branch = "update-LLVM_NEXT_HASH-a123testhash3"
103
104        # Verify exception is raised when on an invalid repo path.
105        with self.assertRaises(ValueError) as err:
106            git.UploadChanges(path_to_repo, branch)
107
108        self.assertEqual(
109            str(err.exception), "Invalid path provided: %s" % path_to_repo
110        )
111
112        mock_isdir.assert_called_once()
113
114    @mock.patch.object(os.path, "isdir", return_value=True)
115    @mock.patch.object(subprocess, "check_output")
116    @mock.patch.object(tempfile, "NamedTemporaryFile")
117    def testSuccessfullyUploadedChangesForReview(
118        self, mock_tempfile, mock_commands, mock_isdir
119    ):
120        path_to_repo = "/some/path/to/repo"
121        branch = "branch-name"
122        commit_messages = ["Test message"]
123        mock_tempfile.return_value.__enter__.return_value.name = "tmp"
124
125        # A test CL generated by `repo upload`.
126        mock_commands.side_effect = [
127            None,
128            (
129                "remote: https://chromium-review.googlesource."
130                "com/c/chromiumos/overlays/chromiumos-overlay/"
131                "+/193147 Fix stdout"
132            ),
133        ]
134        git.CommitChanges(path_to_repo, commit_messages)
135        change_list = git.UploadChanges(path_to_repo, branch)
136
137        self.assertEqual(change_list.cl_number, 193147)
138
139        mock_isdir.assert_called_with(path_to_repo)
140
141        expected_command = [
142            "git",
143            "commit",
144            "-F",
145            mock_tempfile.return_value.__enter__.return_value.name,
146        ]
147        self.assertEqual(
148            mock_commands.call_args_list[0],
149            mock.call(expected_command, cwd=path_to_repo),
150        )
151
152        expected_cmd = [
153            "repo",
154            "upload",
155            "--yes",
156            "--ne",
157            "--no-verify",
158            "--br=%s" % branch,
159        ]
160        self.assertEqual(
161            mock_commands.call_args_list[1],
162            mock.call(
163                expected_cmd,
164                stderr=subprocess.STDOUT,
165                cwd=path_to_repo,
166                encoding="utf-8",
167            ),
168        )
169
170        self.assertEqual(
171            change_list.url,
172            "https://chromium-review.googlesource.com/c/chromiumos/overlays/"
173            "chromiumos-overlay/+/193147",
174        )
175
176
177if __name__ == "__main__":
178    unittest.main()
179