| import os |
| import unittest |
| import uuid |
| |
| from sh import git |
| from unittest.mock import MagicMock, call |
| |
| from linaropy.cd import cd |
| from linaropy.proj import Proj |
| from linaropy.git.clone import Clone |
| from linaropy.git.worktree import Worktree |
| |
| from modules.llvm import LLVMSourceConfig, LLVMSubproject |
| |
| |
| class TestLLVMSourceConfig(unittest.TestCase): |
| testdirprefix = "SourceConfigUT" |
| |
| def __create_dummy_commit(self): |
| filename = "file" + str(uuid.uuid4()) |
| open(filename, "a").close() |
| git("add", filename) |
| git("commit", "-m", "Branches without commits confuse git") |
| |
| def __create_dummy_repo(self, path): |
| if not os.path.exists(path): |
| os.makedirs(path) |
| |
| with cd(path): |
| git("init") |
| self.__create_dummy_commit() |
| |
| def __get_subproj_repo_path(self, subproj): |
| return os.path.join(self.originalLLVM.repodir, "..", subproj + "-repo") |
| |
| def __get_subproj_repo(self, subproj): |
| return Clone(self.proj, self.__get_subproj_repo_path(subproj)) |
| |
| def setUp(self): |
| # We're going to create a hierarchy with [llvm|clang|whatever]-repo |
| # containing dummy repos, and llvm-copy containing a worktree of |
| # llvm-repo |
| self.proj = Proj(prefix=TestLLVMSourceConfig.testdirprefix) |
| path = os.path.join(self.proj.projdir, "llvm-repo") |
| self.__create_dummy_repo(path) |
| self.originalLLVM = Clone(self.proj, path) |
| |
| subprojs = LLVMSubproject.get_all_subprojects() |
| for subproj in list(subprojs.keys()): |
| repo = self.__get_subproj_repo_path(subproj) |
| self.__create_dummy_repo(repo) |
| |
| self.temporaryLLVMbranch = "a-branch" |
| self.temporaryLLVM = Worktree.create( |
| self.proj, self.originalLLVM, os.path.join( |
| self.proj.projdir, "llvm-copy"), self.temporaryLLVMbranch) |
| |
| def tearDown(self): |
| self.proj.cleanup() |
| |
| def test_get_path(self): |
| sourcePath = self.temporaryLLVM.repodir |
| config = LLVMSourceConfig(self.proj, sourcePath) |
| self.assertEqual(config.get_path(), sourcePath) |
| |
| def test_detect_enabled_all(self): |
| subprojs = LLVMSubproject.get_all_subprojects() |
| sourcePath = self.temporaryLLVM.repodir |
| |
| for subproj in subprojs: |
| path = subprojs[subproj].get_cmake_path(sourcePath) |
| worktree = Worktree.create( |
| self.proj, |
| self.__get_subproj_repo(subproj), |
| path, |
| self.temporaryLLVMbranch) |
| self.assertTrue(os.path.isdir(path), "Failed to create worktree") |
| |
| config = LLVMSourceConfig(self.proj, sourcePath) |
| enabled = config.get_enabled_subprojects() |
| |
| self.assertEqual(set(subprojs), set(enabled), |
| "Expected %s but detected only %s" % |
| (str(set(subprojs)), str(enabled))) |
| |
| def test_detect_enabled_none(self): |
| sourcePath = self.temporaryLLVM.repodir |
| |
| path = os.path.join(sourcePath, "unrelated") |
| os.makedirs(path) |
| |
| path = os.path.join(sourcePath, "wrong", "place", "for", "lld") |
| os.makedirs(path) |
| |
| path = os.path.join(sourcePath, "projects", "clang") |
| os.makedirs(path) |
| |
| path = os.path.join(sourcePath, "tools", "libcxx") |
| os.makedirs(path) |
| |
| config = LLVMSourceConfig(self.proj, sourcePath) |
| enabled = config.get_enabled_subprojects() |
| |
| self.assertEqual( |
| enabled, |
| [], |
| "Detected unexpected projects %s" % str(enabled) |
| ) |
| |
| def test_detect_enabled_some(self): |
| sourcePath = self.temporaryLLVM.repodir |
| subprojs = LLVMSubproject.get_all_subprojects() |
| |
| for subproj in ["lld", "libcxxabi", "clang"]: |
| path = subprojs[subproj].get_cmake_path(sourcePath) |
| worktree = Worktree.create( |
| self.proj, |
| self.__get_subproj_repo(subproj), |
| path, |
| self.temporaryLLVMbranch) |
| self.assertTrue(os.path.isdir(path), "Failed to create worktree") |
| |
| config = LLVMSourceConfig(self.proj, sourcePath) |
| enabled = config.get_enabled_subprojects() |
| |
| self.assertTrue("lld" in enabled, "Failed to detect lld") |
| self.assertTrue("clang" in enabled, "Failed to detect clang") |
| self.assertTrue("libcxxabi" in enabled, |
| "Failed to detect libcxxabi") |
| |
| def test_detect_enabled_not_worktree(self): |
| sourcePath = self.temporaryLLVM.repodir |
| subprojs = LLVMSubproject.get_all_subprojects() |
| |
| path = subprojs["compiler-rt"].get_cmake_path(sourcePath) |
| os.makedirs(path) |
| |
| config = LLVMSourceConfig(self.proj, sourcePath) |
| with self.assertRaises(EnvironmentError) as context: |
| config.get_enabled_subprojects() |
| |
| self.assertRegex( |
| str(context.exception), |
| ".*compiler-rt is not a worktree.*" |
| ) |
| |
| def test_detect_enabled_wrong_branch(self): |
| sourcePath = self.temporaryLLVM.repodir |
| subprojs = LLVMSubproject.get_all_subprojects() |
| |
| path = subprojs["compiler-rt"].get_cmake_path(sourcePath) |
| branch = "different-than-" + self.temporaryLLVMbranch |
| worktree = Worktree.create( |
| self.proj, |
| self.__get_subproj_repo("compiler-rt"), |
| path, |
| branch) |
| self.assertTrue(os.path.isdir(path), "Failed to create worktree") |
| |
| config = LLVMSourceConfig(self.proj, sourcePath) |
| with self.assertRaises(EnvironmentError) as context: |
| config.get_enabled_subprojects() |
| |
| self.assertRegex(str(context.exception), |
| "compiler-rt is on branch {}, but should be on {}".format(branch, |
| self.temporaryLLVMbranch)) |
| |
| def test_add_invalid_subproject(self): |
| config = LLVMSourceConfig(self.proj, self.temporaryLLVM.repodir) |
| subproj = "not-an-llvm-subproject" |
| subprojPath = self.originalLLVM.repodir # Dummy path |
| |
| with self.assertRaises(ValueError) as context: |
| config.update({subproj : Clone(self.proj, subprojPath)}) |
| |
| self.assertRegex(str(context.exception), |
| "Unknown llvm subproject %s" % subproj) |
| |
| def test_add_each_subproject(self): |
| sourcePath = self.temporaryLLVM.repodir |
| |
| config = LLVMSourceConfig(self.proj, sourcePath) |
| |
| subprojs = LLVMSubproject.get_all_subprojects() |
| for subproj in subprojs: |
| expectedPath = subprojs[subproj].get_cmake_path(sourcePath) |
| config.update({subproj : self.__get_subproj_repo(subproj)}) |
| self.assertTrue(os.path.isdir(expectedPath), |
| "Failed to add subproject %s" % subproj) |
| |
| def test_add_all_subprojects(self): |
| sourcePath = self.temporaryLLVM.repodir |
| |
| config = LLVMSourceConfig(self.proj, sourcePath) |
| |
| to_add = {} |
| subprojs = LLVMSubproject.get_all_subprojects() |
| |
| for subproj in subprojs: |
| to_add[subproj] = self.__get_subproj_repo(subproj) |
| |
| config.update(to_add) |
| |
| for subproj in subprojs: |
| expectedPath = subprojs[subproj].get_cmake_path(sourcePath) |
| self.assertTrue(os.path.isdir(expectedPath), |
| "Failed to add subproject %s" % subproj) |
| |
| def test_add_some_subprojects(self): |
| sourcePath = self.temporaryLLVM.repodir |
| |
| config = LLVMSourceConfig(self.proj, sourcePath) |
| |
| to_add = {} |
| to_add["clang"] = self.__get_subproj_repo("clang") |
| to_add["compiler-rt"] = self.__get_subproj_repo("compiler-rt") |
| |
| config.update(to_add) |
| |
| subprojs = LLVMSubproject.get_all_subprojects() |
| self.assertTrue( |
| os.path.isdir(subprojs["clang"].get_cmake_path(sourcePath)), |
| "Failed to add subproject clang") |
| self.assertTrue( |
| os.path.isdir(subprojs["compiler-rt"].get_cmake_path(sourcePath)), |
| "Failed to add subproject compiler-rt") |
| |
| def test_add_existing_subprojects(self): |
| sourcePath = self.temporaryLLVM.repodir |
| |
| config = LLVMSourceConfig(self.proj, sourcePath) |
| |
| subprojs = LLVMSubproject.get_all_subprojects() |
| existingPath = subprojs["lldb"].get_cmake_path(sourcePath) |
| Worktree.create( |
| self.proj, |
| self.__get_subproj_repo("lldb"), |
| existingPath, |
| self.temporaryLLVMbranch) |
| |
| config.update({ "lldb" : self.__get_subproj_repo("lldb")}) |
| |
| # If we got this far, we're probably ok, but let's be pedantic and check |
| # that the subproject is still there |
| self.assertTrue(os.path.isdir(existingPath), |
| "Existing subproject vanished") |
| |
| def test_add_subproject_existing_branch(self): |
| """ |
| Test that we can add a subproject that already has the branch that LLVM |
| is on. This can happen for instance if we have added and then removed |
| the subproject and now we're trying to add it again. |
| """ |
| sourcePath = self.temporaryLLVM.repodir |
| |
| config = LLVMSourceConfig(self.proj, sourcePath) |
| |
| clangRepo = self.__get_subproj_repo("clang") |
| with cd(clangRepo.repodir): |
| # Make sure that the branch that LLVM is on already exists in the |
| # clang repo as well. |
| git("checkout", "-b", self.temporaryLLVMbranch) |
| self.__create_dummy_commit() |
| git("checkout", "master") |
| |
| config.update( { "clang" : clangRepo }) |
| |
| subprojs = LLVMSubproject.get_all_subprojects() |
| path = subprojs["clang"].get_cmake_path(sourcePath) |
| self.assertTrue(os.path.isdir(path), "Failed to add subproject") |
| |
| def test_add_subproject_not_a_worktree(self): |
| """ |
| Test that we can't update a config to include a subproject that exists |
| but is not a worktree. |
| """ |
| sourcePath = self.temporaryLLVM.repodir |
| branch = "different-than-" + self.temporaryLLVMbranch |
| |
| config = LLVMSourceConfig(self.proj, sourcePath) |
| |
| subprojs = LLVMSubproject.get_all_subprojects() |
| existingPath = subprojs["lldb"].get_cmake_path(sourcePath) |
| os.makedirs(existingPath) |
| |
| with self.assertRaises(EnvironmentError) as context: |
| config.update({ "lldb" : self.__get_subproj_repo("lldb")}) |
| |
| self.assertRegex(str(context.exception), |
| "{} is not a worktree.*" |
| .format(existingPath)) |
| |
| # If we got this far, we're probably ok, but let's be pedantic and check |
| # that the subproject is still there |
| self.assertTrue(os.path.isdir(existingPath), |
| "Existing subproject vanished") |
| |
| def test_add_subproject_wrong_branch(self): |
| """ |
| Test that we can't update a config to include a subproject that exists |
| but is on the wrong branch. |
| """ |
| sourcePath = self.temporaryLLVM.repodir |
| branch = "different-than-" + self.temporaryLLVMbranch |
| |
| config = LLVMSourceConfig(self.proj, sourcePath) |
| |
| subprojs = LLVMSubproject.get_all_subprojects() |
| existingPath = subprojs["lldb"].get_cmake_path(sourcePath) |
| Worktree.create( |
| self.proj, |
| self.__get_subproj_repo("lldb"), |
| existingPath, |
| branch) |
| |
| with self.assertRaises(EnvironmentError) as context: |
| config.update({ "lldb" : self.__get_subproj_repo("lldb")}) |
| |
| self.assertRegex(str(context.exception), |
| "lldb is on branch {}, but should be on {}.*" |
| .format(branch, self.temporaryLLVMbranch)) |
| |
| # If we got this far, we're probably ok, but let's be pedantic and check |
| # that the subproject is still there |
| self.assertTrue(os.path.isdir(existingPath), |
| "Existing subproject vanished") |
| |
| def test_remove_subproject(self): |
| sourcePath = self.temporaryLLVM.repodir |
| |
| subprojs = LLVMSubproject.get_all_subprojects() |
| |
| lldPath = subprojs["lld"].get_cmake_path(sourcePath) |
| lldWorktree = Worktree.create( |
| self.proj, |
| self.__get_subproj_repo("lld"), |
| lldPath, |
| self.temporaryLLVMbranch) |
| |
| clangPath = subprojs["clang"].get_cmake_path(sourcePath) |
| clangWorktree = Worktree.create( |
| self.proj, |
| self.__get_subproj_repo("clang"), |
| clangPath, |
| self.temporaryLLVMbranch) |
| |
| config = LLVMSourceConfig(self.proj, sourcePath) |
| config.update(remove=["lld"]) |
| |
| self.assertFalse(os.path.isdir(lldPath), "Failed to remove subproject") |
| self.assertTrue(os.path.isdir(clangPath), "Removed sibling subproject") |
| |
| def test_remove_some_subprojects(self): |
| sourcePath = self.temporaryLLVM.repodir |
| |
| subprojs = LLVMSubproject.get_all_subprojects() |
| |
| for subproj in ["clang", "compiler-rt", "lld", "lldb", "libunwind"]: |
| path = subprojs[subproj].get_cmake_path(sourcePath) |
| worktree = Worktree.create( |
| self.proj, |
| self.__get_subproj_repo(subproj), |
| path, |
| self.temporaryLLVMbranch) |
| |
| config = LLVMSourceConfig(self.proj, sourcePath) |
| config.update(remove=["compiler-rt", "lld"]) |
| |
| for subproj in ["compiler-rt", "lld"]: |
| path = subprojs[subproj].get_cmake_path(sourcePath) |
| self.assertFalse( |
| os.path.isdir(path), |
| "Failed to remove subproject") |
| |
| for subproj in ["clang", "lldb", "libunwind"]: |
| path = subprojs[subproj].get_cmake_path(sourcePath) |
| self.assertTrue(os.path.isdir(path), "Removed sibling subproject") |
| |
| def test_remove_all_subprojects(self): |
| sourcePath = self.temporaryLLVM.repodir |
| |
| subprojs = LLVMSubproject.get_all_subprojects() |
| |
| for subproj in list(subprojs.keys()): |
| path = subprojs[subproj].get_cmake_path(sourcePath) |
| worktree = Worktree.create( |
| self.proj, |
| self.__get_subproj_repo(subproj), |
| path, |
| self.temporaryLLVMbranch) |
| self.assertTrue(os.path.isdir(path), "Failed to create worktree") |
| |
| config = LLVMSourceConfig(self.proj, sourcePath) |
| config.update(remove=list(subprojs.keys())) |
| |
| for subproj in list(subprojs.keys()): |
| path = subprojs[subproj].get_cmake_path(sourcePath) |
| self.assertFalse( |
| os.path.isdir(path), |
| "Failed to remove subproject") |
| |
| def test_remove_each_subproject(self): |
| sourcePath = self.temporaryLLVM.repodir |
| |
| subprojs = LLVMSubproject.get_all_subprojects() |
| |
| for subproj in list(subprojs.keys()): |
| path = subprojs[subproj].get_cmake_path(sourcePath) |
| worktree = Worktree.create( |
| self.proj, |
| self.__get_subproj_repo(subproj), |
| path, |
| self.temporaryLLVMbranch) |
| self.assertTrue(os.path.isdir(path), "Failed to create worktree") |
| |
| config = LLVMSourceConfig(self.proj, sourcePath) |
| |
| for subproj in list(subprojs.keys()): |
| config.update(remove=[subproj]) |
| |
| for subproj in list(subprojs.keys()): |
| path = subprojs[subproj].get_cmake_path(sourcePath) |
| self.assertFalse( |
| os.path.isdir(path), |
| "Failed to remove subproject") |
| |
| def test_remove_duplicates(self): |
| sourcePath = self.temporaryLLVM.repodir |
| |
| subprojs = LLVMSubproject.get_all_subprojects() |
| |
| for subproj in ["clang", "compiler-rt", "lld", "lldb", "libunwind"]: |
| path = subprojs[subproj].get_cmake_path(sourcePath) |
| worktree = Worktree.create( |
| self.proj, |
| self.__get_subproj_repo(subproj), |
| path, |
| self.temporaryLLVMbranch) |
| |
| config = LLVMSourceConfig(self.proj, sourcePath) |
| config.update(remove=["compiler-rt", "lld", "lld", "compiler-rt"]) |
| |
| for subproj in ["compiler-rt", "lld"]: |
| path = subprojs[subproj].get_cmake_path(sourcePath) |
| self.assertFalse( |
| os.path.isdir(path), |
| "Failed to remove subproject") |
| |
| for subproj in ["clang", "lldb", "libunwind"]: |
| path = subprojs[subproj].get_cmake_path(sourcePath) |
| self.assertTrue(os.path.isdir(path), "Removed sibling subproject") |
| |
| def test_remove_invalid_subproject(self): |
| sourcePath = self.temporaryLLVM.repodir |
| config = LLVMSourceConfig(self.proj, sourcePath) |
| |
| subproj = "not-an-llvm-subproject" |
| |
| with self.assertRaises(ValueError) as context: |
| config.update(remove=[subproj]) |
| |
| self.assertRegex(str(context.exception), |
| "Unknown llvm subproject %s" % subproj) |
| |
| def test_remove_inexistent_subproject(self): |
| sourcePath = self.temporaryLLVM.repodir |
| |
| subprojs = LLVMSubproject.get_all_subprojects() |
| |
| lldPath = subprojs["lld"].get_cmake_path(sourcePath) |
| lldWorktree = Worktree.create( |
| self.proj, |
| self.__get_subproj_repo("lld"), |
| lldPath, |
| self.temporaryLLVMbranch) |
| |
| clangPath = subprojs["clang"].get_cmake_path(sourcePath) |
| |
| config = LLVMSourceConfig(self.proj, sourcePath) |
| config.update(remove=["clang"]) |
| |
| self.assertFalse( |
| os.path.isdir(clangPath), |
| "Failed to remove subproject") |
| self.assertTrue(os.path.isdir(lldPath), "Removed sibling subproject") |
| |
| def test_add_after_remove(self): |
| sourcePath = self.temporaryLLVM.repodir |
| |
| subprojs = LLVMSubproject.get_all_subprojects() |
| lldbRepo = self.__get_subproj_repo("lldb") |
| |
| config = LLVMSourceConfig(self.proj, sourcePath) |
| |
| config.update({"lldb" : lldbRepo}) |
| self.assertTrue( |
| os.path.isdir(subprojs["lldb"].get_cmake_path(sourcePath)), |
| "Failed to add lldb") |
| |
| config.update(remove=["lldb"]) |
| self.assertFalse( |
| os.path.isdir(subprojs["lldb"].get_cmake_path(sourcePath)), |
| "Failed to remove lldb") |
| |
| config.update({"lldb" : lldbRepo }) |
| self.assertTrue( |
| os.path.isdir(subprojs["lldb"].get_cmake_path(sourcePath)), |
| "Failed to add lldb") |
| |
| def test_mixed_adds_removes(self): |
| sourcePath = self.temporaryLLVM.repodir |
| |
| subprojs = LLVMSubproject.get_all_subprojects() |
| |
| for subproj in ["clang", "compiler-rt", "lld", "lldb", "libunwind"]: |
| path = subprojs[subproj].get_cmake_path(sourcePath) |
| worktree = Worktree.create( |
| self.proj, |
| self.__get_subproj_repo(subproj), |
| path, |
| self.temporaryLLVMbranch) |
| |
| config = LLVMSourceConfig(self.proj, sourcePath) |
| config.update({ |
| "libcxx" : self.__get_subproj_repo("libcxx"), |
| "libcxxabi" : self.__get_subproj_repo("libcxxabi")}, |
| ["compiler-rt", "lld"]) |
| |
| for subproj in ["libcxx", "libcxxabi"]: |
| path = subprojs[subproj].get_cmake_path(sourcePath) |
| self.assertTrue(os.path.isdir(path), "Failed to add subproject") |
| |
| for subproj in ["compiler-rt", "lld"]: |
| path = subprojs[subproj].get_cmake_path(sourcePath) |
| self.assertFalse( |
| os.path.isdir(path), |
| "Failed to remove subproject") |
| |
| for subproj in ["clang", "lldb", "libunwind"]: |
| path = subprojs[subproj].get_cmake_path(sourcePath) |
| self.assertTrue(os.path.isdir(path), "Removed sibling subproject") |
| |
| def test_simultaneous_add_remove(self): |
| sourcePath = self.temporaryLLVM.repodir |
| subprojs = LLVMSubproject.get_all_subprojects() |
| |
| clangRepo = self.__get_subproj_repo("clang") |
| lldRepo = self.__get_subproj_repo("lld") |
| libunwindRepo = self.__get_subproj_repo("libunwind") |
| |
| config = LLVMSourceConfig(self.proj, sourcePath) |
| with self.assertRaises(ValueError) as context: |
| config.update( |
| { "clang" : clangRepo, "lld" : lldRepo, "libunwind" : |
| libunwindRepo}, ["libcxx", "lld", "libcxxabi"]) |
| |
| self.assertEqual(str(context.exception), |
| "Can't add and remove lld at the same time") |
| |
| # Make sure we didn't add any of the others either |
| for subproj in ["clang", "libunwind"]: |
| path = subprojs[subproj].get_cmake_path(sourcePath) |
| self.assertFalse( |
| os.path.isdir(path), |
| "Incorrectly added subproject") |
| |
| # TODO: test with a different dictionary than the default one (not |
| # necessarily containing subprojects - it can contain "potato", "banana" and |
| # "gazpacho" for all we care); in fact, it would probably be best to move the |
| # existing tests to that... |
| |
| # TODO: test that CMake gets our layout |
| |
| def test_for_each_enabled(self): |
| sourcePath = self.temporaryLLVM.repodir |
| |
| config = LLVMSourceConfig(self.proj, sourcePath) |
| |
| logPath = unittest.mock.MagicMock() |
| config.for_each_enabled(logPath) |
| |
| logPath.assert_called_with(self.temporaryLLVM.repodir) |
| |
| subprojs = config.subprojs |
| enabled = ["clang", "compiler-rt", "lld", "lldb", "libunwind"] |
| calls = [] |
| |
| for subproj in enabled: |
| path = subprojs[subproj].get_cmake_path(sourcePath) |
| worktree = Worktree.create( |
| self.proj, |
| self.__get_subproj_repo(subproj), |
| path, |
| self.temporaryLLVMbranch) |
| calls.append(call(path)) # Expect our mock to be called with path |
| |
| logPath = unittest.mock.MagicMock() |
| config.for_each_enabled(logPath) |
| |
| logPath.assert_has_calls(calls, any_order=True) |
| |
| def test_for_each_enabled_error(self): |
| """Test that we rethrow exceptions correctly.""" |
| sourcePath = self.temporaryLLVM.repodir |
| |
| config = LLVMSourceConfig(self.proj, sourcePath) |
| subprojs = config.subprojs |
| enabled = ["clang", "compiler-rt", "lld", "lldb", "libunwind"] |
| |
| for subproj in enabled: |
| path = subprojs[subproj].get_cmake_path(sourcePath) |
| worktree = Worktree.create( |
| self.proj, |
| self.__get_subproj_repo(subproj), |
| path, |
| self.temporaryLLVMbranch) |
| |
| def throw(projPath): |
| if "lld" in projPath: |
| raise ValueError("An error has been!!1") |
| |
| with self.assertRaises(RuntimeError) as context: |
| config.for_each_enabled(throw) |
| self.assertRegex(str(context.exception), |
| "Error while processing lld(.*\n)*") |
| self.assertRegex(str(context.exception.__cause__), |
| "An error has been!!1(.*\n)*") |
| |
| def test_for_each_subproj(self): |
| sourcePath = self.temporaryLLVM.repodir |
| |
| config = LLVMSourceConfig(self.proj, sourcePath) |
| |
| subprojs = config.subprojs |
| enabled = ["clang", "compiler-rt", "lld", "lldb", "libunwind"] |
| calls = [] |
| |
| for subproj in enabled: |
| # Make sure subproj looks enabled |
| path = subprojs[subproj].get_cmake_path(sourcePath) |
| worktree = Worktree.create( |
| self.proj, |
| self.__get_subproj_repo(subproj), |
| path, |
| self.temporaryLLVMbranch) |
| # Expect our mock to be called with the proper subproj and |
| # enabled == True |
| calls.append(call(subprojs[subproj], True)) |
| |
| for subproj in set(subprojs.keys()) - set(enabled): |
| # Expect our mock to be called with the proper subproj and |
| # enabled == False |
| calls.append(call(subprojs[subproj], False)) |
| |
| try: |
| action = MagicMock() |
| config.for_each_subproj(action) |
| except: |
| print("Exception during test?! ") |
| |
| action.assert_has_calls(calls, any_order=True) |
| |
| def test_for_each_subproj_error(self): |
| """Test that we rethrow exceptions correctly.""" |
| sourcePath = self.temporaryLLVM.repodir |
| |
| config = LLVMSourceConfig(self.proj, sourcePath) |
| subprojs = config.subprojs |
| enabled = ["clang", "compiler-rt", "lld", "lldb", "libunwind"] |
| |
| for subproj in enabled: |
| path = subprojs[subproj].get_cmake_path(sourcePath) |
| worktree = Worktree.create( |
| self.proj, |
| self.__get_subproj_repo(subproj), |
| path, |
| self.temporaryLLVMbranch) |
| |
| def throw_enabled(subproj, enabled): |
| # Throw for one of the enabled projects (e.g. lld) |
| if "lld" in subproj.cmake_path: |
| raise ValueError("An error has been!!1") |
| |
| def throw_disabled(subproj, enabled): |
| # Throw for one of the disabled projects (e.g. libcxx) |
| if "libcxx" in subproj.cmake_path: |
| raise ValueError("An error has been!!1") |
| |
| with self.assertRaises(RuntimeError) as context: |
| config.for_each_subproj(throw_enabled) |
| self.assertRegex(str(context.exception), |
| "Error while processing lld(.*\n)*") |
| self.assertRegex(str(context.exception.__cause__), |
| "An error has been!!1(.*\n)*") |
| |
| with self.assertRaises(RuntimeError) as context: |
| config.for_each_subproj(throw_disabled) |
| self.assertRegex(str(context.exception), |
| "Error while processing libcxx(.*\n)*") |
| self.assertRegex(str(context.exception.__cause__), |
| "An error has been!!1(.*\n)*") |
| |
| |
| if __name__ == "__main__": |
| unittest.main() |