| """Command line interface tests for llvm.py push. |
| |
| Note that although this uses the unittest framework, it does *not* contain unit |
| tests. |
| |
| """ |
| |
| import shutil |
| import os |
| import subprocess |
| import unittest |
| |
| from tempfile import mkdtemp |
| from uuid import uuid4 |
| |
| from linaropy.cd import cd |
| from linaropy.git.clone import Clone |
| from llvmtestcase import LLVMTestCase, require_command_arg, debug |
| |
| |
| class Testllvmpush(LLVMTestCase): |
| |
| @classmethod |
| def llvm_push(cls, *args, **kwargs): |
| return cls.command_with_defaults("push", *args, **kwargs) |
| |
| @classmethod |
| def get_origin_path(cls, subproj): |
| return os.path.join(cls.origins, subproj) |
| |
| @classmethod |
| def get_clone_path(cls, subproj): |
| return os.path.join(cls.repos, subproj) |
| |
| @classmethod |
| def setUpClass(cls): |
| """Create the file structure and environment for testing llvm push.""" |
| cls.all_repos = ("llvm", "clang", "compiler-rt", "lld", "lldb", |
| "libcxx", "libcxxabi", "libunwind", "test-suite") |
| |
| cls.origins = mkdtemp() |
| cls.repos = mkdtemp() |
| cls.llvm_root = mkdtemp() |
| |
| cls.user = "llvm-developer" |
| |
| # Create dummy repos - one origin that we will push to, and one clone |
| # that we will create worktrees from |
| for reponame in cls.all_repos: |
| origin = cls.get_origin_path(reponame) |
| cls.create_dummy_repo(origin) |
| |
| clone = cls.get_clone_path(reponame) |
| cls.create_dummy_repo( |
| clone, "file://{}@{}".format(cls.user, origin)) |
| |
| @classmethod |
| def tearDownClass(cls): |
| shutil.rmtree(cls.origins) |
| shutil.rmtree(cls.repos) |
| |
| @classmethod |
| def setUp(cls): |
| cls.env = os.path.join(cls.llvm_root, "env" + str(uuid4())) |
| cls.llvm_src = os.path.join(cls.env, "llvm") |
| |
| # Create LLVM worktree |
| cls.branch = "br" + str(uuid4()) |
| cls.add_worktree(cls.get_clone_path("llvm"), cls.llvm_src, |
| cls.branch) |
| |
| @classmethod |
| def tearDown(cls): |
| # Clean up the directories where we might have added subprojects. |
| # This isn't 100% clean, because we don't clean up the repos between |
| # tests (so any branches will remain), but it's good enough for the |
| # current tests. |
| for subprojdir in (os.path.join(cls.llvm_src, "projects"), |
| os.path.join(cls.llvm_src, "tools")): |
| if os.path.isdir(subprojdir): |
| shutil.rmtree(subprojdir) |
| os.makedirs(subprojdir) |
| |
| # Run prune on the original repos, to remove any dangling worktrees. |
| for reponame in cls.all_repos: |
| repopath = cls.get_clone_path(reponame) |
| with cd(repopath): |
| cls.run_quietly(["git", "worktree", "prune"]) |
| |
| @require_command_arg("--source-dir") |
| def test_source_dir_ir_compulsory(self): |
| """Test that we get an error if we don't pass the source dir.""" |
| self.run_with_output(self.llvm_push()) |
| |
| def test_push(self): |
| with cd(self.llvm_src): |
| self.create_dummy_commit("Test llvm push") |
| |
| enabled = ["clang", "lld"] |
| |
| for subproj in enabled: |
| worktreePath = os.path.join(self.llvm_src, "tools", subproj) |
| self.add_worktree(self.get_clone_path(subproj), |
| worktreePath, |
| self.branch) |
| with cd(worktreePath): |
| self.create_dummy_commit("Test {} push".format(subproj)) |
| |
| pushed = self.run_with_output( |
| self.llvm_push("--source-dir", self.llvm_src)) |
| remote_branch = "linaro-local/{}/{}".format(self.user, self.branch) |
| |
| self.assertRegex( |
| pushed, "(.*\n)*Pushed to {}(.*\n)*".format(remote_branch)) |
| |
| for subproj in self.all_repos: |
| origin = self.get_origin_path(subproj) |
| |
| with cd(origin): |
| if subproj == "llvm" or subproj in enabled: |
| output = self.run_with_output(["git", "log", "--oneline", |
| "-1", remote_branch]) |
| |
| self.assertRegex( |
| output, ".*Test {} push.*".format(subproj)) |
| else: |
| with self.assertRaises(subprocess.CalledProcessError) as context: |
| output = self.run_with_output( |
| ["git", "log", "--oneline", "-1", remote_branch]) |
| |
| self.assertRegex( |
| str(context.exception.output), |
| "(.*\n)*.*unknown revision or path not in the working tree(.*\n)*") |
| |
| def test_push_mismatched_branches(self): |
| with cd(self.llvm_src): |
| self.create_dummy_commit("Test llvm push") |
| |
| enabled = ["clang", "lld"] |
| |
| for subproj in enabled: |
| branch = self.branch |
| |
| # Move only lld to a different branch |
| if subproj == "lld": |
| branch = branch + "-different" |
| |
| worktreePath = os.path.join(self.llvm_src, "tools", subproj) |
| self.add_worktree(self.get_clone_path(subproj), |
| worktreePath, |
| branch) |
| with cd(worktreePath): |
| self.create_dummy_commit("Test {} push".format(subproj)) |
| |
| with self.assertRaises(subprocess.CalledProcessError) as context: |
| output = self.run_with_output( |
| self.llvm_push("--source-dir", self.llvm_src)) |
| |
| # Check that we error out because lld is on a different branch |
| self.assertRegex(str(context.exception.output), |
| "(.*\n)*.*lld is on branch {}, but should be on {}".format( |
| self.branch + "-different", self.branch)) |
| |
| # Check that we haven't pushed llvm or clang either, even if they're on |
| # the same branch |
| remote_branch = "linaro-local/{}/{}".format(self.user, self.branch) |
| |
| for subproj in ["llvm", "clang"]: |
| with cd(self.get_origin_path(subproj)): |
| with self.assertRaises(subprocess.CalledProcessError) as context: |
| self.run_with_output(["git", "log", "--oneline", "-1", |
| remote_branch]) |
| |
| self.assertRegex( |
| str(context.exception.output), |
| "(.*\n)*.*unknown revision or path not in the working tree(.*\n)*") |