From 3601bea50533d4ba06fafac16664183cdb250ab0 Mon Sep 17 00:00:00 2001 From: Diana Picus Date: Mon, 29 May 2017 11:26:18 +0200 Subject: Factor out common test primitives. NFCI. Create an LLVMTestCase class that will contain common helpers for writing tests for llvm.py subcommands. Change-Id: Ie1fe9dad9c9aeb9eb673726c80077d26739c0697 --- tests/cli/llvmtestcase.py | 106 +++++++++++++++++++++++++++++++++++++ tests/cli/testllvmprojects.py | 119 ++++++------------------------------------ 2 files changed, 122 insertions(+), 103 deletions(-) create mode 100644 tests/cli/llvmtestcase.py diff --git a/tests/cli/llvmtestcase.py b/tests/cli/llvmtestcase.py new file mode 100644 index 0000000..b2fc765 --- /dev/null +++ b/tests/cli/llvmtestcase.py @@ -0,0 +1,106 @@ +"""Common TestCase used for testing llvm.py subcommands.""" + +import shutil +import os +import subprocess +import unittest + +from tempfile import mkdtemp +from uuid import uuid4 + +from linaropy.cd import cd + + +# TODO: move this somewhere more public (maybe linaropy?) +def debug(test): + """ + Decorator that dumps the output of any subprocess.CalledProcessError + exception. Use this to decorate a test function when you can't tell what the + problem is. + """ + def wrapper(*args, **kwargs): + # Catch any exceptions so we can dump all the output + try: + test(*args, **kwargs) + except subprocess.CalledProcessError as exc: + print("Error in {}:".format(test.__name__)) + print("Command {} exited with error code {}:\n{}".format( + exc.cmd, exc.returncode, exc.output)) + return wrapper + + +class LLVMTestCase(unittest.TestCase): + python = "python3" + script = os.path.join("scripts", "llvm.py") + + @classmethod + def create_dummy_commit(cls): + filename = "filethatshouldntexist" + cls.run_quietly(["touch", filename]) + cls.run_quietly(["git", "add", filename]) + cls.run_quietly(["git", "commit", "-m", "Dummy commit"]) + + @classmethod + def create_dummy_repo(cls, repopath): + if not os.path.isdir(repopath): + os.makedirs(repopath) + + with cd(repopath): + cls.run_quietly(["git", "init"]) + cls.create_dummy_commit() + + @classmethod + def add_worktree(cls, repopath, worktreepath, branch): + with cd(repopath): + cls.run_quietly(["git", "worktree", "add", worktreepath, + "-b", branch]) + + @classmethod + def get_subproj_repo(cls, subproj): + return os.path.join(cls.repos, subproj) + + @staticmethod + def run_with_output(*args, **kwargs): + """Helper for running a command and capturing stdout and stderr""" + kwargs["stderr"] = subprocess.STDOUT + return str(subprocess.check_output(*args, **kwargs), 'utf-8') + + @staticmethod + def run_quietly(*args, **kwargs): + """ + Helper for running a command and ignoring stdout and stderr. Exceptions + are still thrown if something goes wrong + """ + kwargs["stdout"] = subprocess.DEVNULL + kwargs["stderr"] = subprocess.DEVNULL + return subprocess.check_call(*args, **kwargs) + + @classmethod + def command_with_defaults(cls, subcommand, *args, **kwargs): + """ + Build a list representing a llvm subcommand with the given + args. Unless otherwise specified in kwargs, this uses the values for + repos and env that it finds in cls. + """ + command = [cls.python, cls.script] + + repos = cls.repos + if "repos" in kwargs: + repos = kwargs["repos"] + if repos: + command.append("--repos") + command.append(repos) + + env = cls.env + if "env" in kwargs: + env = kwargs["env"] + if env: + command.append("--env") + command.append(env) + + command.append(subcommand) + + if len(args): + command.extend(args) + + return command diff --git a/tests/cli/testllvmprojects.py b/tests/cli/testllvmprojects.py index c0c1f26..394f3ac 100644 --- a/tests/cli/testllvmprojects.py +++ b/tests/cli/testllvmprojects.py @@ -14,101 +14,14 @@ from tempfile import mkdtemp from uuid import uuid4 from linaropy.cd import cd +from llvmtestcase import LLVMTestCase -# TODO: move this somewhere more public (maybe linaropy?) -def debug(test): - """ - Decorator that dumps the output of any subprocess.CalledProcessError - exception. Use this to decorate a test function when you can't tell what the - problem is. - """ - def wrapper(*args, **kwargs): - # Catch any exceptions so we can dump all the output - try: - test(*args, **kwargs) - except subprocess.CalledProcessError as exc: - print("Error in {}:".format(test.__name__)) - print("Command {} exited with error code {}:\n{}".format( - exc.cmd, exc.returncode, exc.output)) - return wrapper - - -class Testllvmprojs(unittest.TestCase): - python = "python3" - script = os.path.join("scripts", "llvm.py") - - @classmethod - def __create_dummy_commit(cls): - filename = "filethatshouldntexist" - cls.run_quietly(["touch", filename]) - cls.run_quietly(["git", "add", filename]) - cls.run_quietly(["git", "commit", "-m", "Dummy commit"]) - - @classmethod - def __create_dummy_repo(cls, repopath): - if not os.path.isdir(repopath): - os.makedirs(repopath) - - with cd(repopath): - cls.run_quietly(["git", "init"]) - cls.__create_dummy_commit() - - @classmethod - def __add_worktree(cls, repopath, worktreepath, branch): - with cd(repopath): - cls.run_quietly(["git", "worktree", "add", worktreepath, - "-b", branch]) - - @classmethod - def __get_subproj_repo(cls, subproj): - return os.path.join(cls.repos, subproj) - - @staticmethod - def run_with_output(*args, **kwargs): - """Helper for running a command and capturing stdout and stderr""" - kwargs["stderr"] = subprocess.STDOUT - return str(subprocess.check_output(*args, **kwargs), 'utf-8') - - @staticmethod - def run_quietly(*args, **kwargs): - """ - Helper for running a command and ignoring stdout and stderr. Exceptions - are still thrown if something goes wrong - """ - kwargs["stdout"] = subprocess.DEVNULL - kwargs["stderr"] = subprocess.DEVNULL - return subprocess.check_call(*args, **kwargs) +class Testllvmprojs(LLVMTestCase): @classmethod def llvm_projects(cls, *args, **kwargs): - """ - Build a list representing a llvm projects subcommand with the given - args. Unless otherwise specified in kwargs, this uses the values for - repos and env that it finds in cls. - """ - command = [cls.python, cls.script] - - repos = cls.repos - if "repos" in kwargs: - repos = kwargs["repos"] - if repos: - command.append("--repos") - command.append(repos) - - env = cls.env - if "env" in kwargs: - env = kwargs["env"] - if env: - command.append("--env") - command.append(env) - - command.append("projects") - - if len(args): - command.extend(args) - - return command + return cls.command_with_defaults("projects", *args, **kwargs) @classmethod def setUpClass(cls): @@ -121,7 +34,7 @@ class Testllvmprojs(unittest.TestCase): # Create dummy repos for reponame in cls.all_repos: - cls.__create_dummy_repo(cls.__get_subproj_repo(reponame)) + cls.create_dummy_repo(cls.get_subproj_repo(reponame)) @classmethod def tearDownClass(cls): @@ -134,8 +47,8 @@ class Testllvmprojs(unittest.TestCase): # Create LLVM worktree cls.branch = "br" + str(uuid4()) - cls.__add_worktree(cls.__get_subproj_repo("llvm"), cls.llvm_src, - cls.branch) + cls.add_worktree(cls.get_subproj_repo("llvm"), cls.llvm_src, + cls.branch) @classmethod def tearDown(cls): @@ -151,7 +64,7 @@ class Testllvmprojs(unittest.TestCase): # Run prune on the original repos, to remove any dangling worktrees. for reponame in cls.all_repos: - repopath = cls.__get_subproj_repo(reponame) + repopath = cls.get_subproj_repo(reponame) with cd(repopath): cls.run_quietly(["git", "worktree", "prune"]) @@ -305,11 +218,11 @@ class Testllvmprojs(unittest.TestCase): was added by our script or manually) or remove a subproject that doesn't exist. """ - self.__add_worktree(self.__get_subproj_repo("clang"), - os.path.join(self.llvm_src, "tools", "clang"), - self.branch) - self.__add_worktree( - self.__get_subproj_repo("compiler-rt"), + self.add_worktree(self.get_subproj_repo("clang"), + os.path.join(self.llvm_src, "tools", "clang"), + self.branch) + self.add_worktree( + self.get_subproj_repo("compiler-rt"), os.path.join(self.llvm_src, "projects", "compiler-rt"), self.branch) @@ -361,8 +274,8 @@ class Testllvmprojs(unittest.TestCase): # Try something a bit more complicated and make sure we're not touching # anything - self.__add_worktree( - self.__get_subproj_repo("lld"), + self.add_worktree( + self.get_subproj_repo("lld"), os.path.join(self.llvm_src, "tools", "lld"), self.branch) @@ -456,8 +369,8 @@ class Testllvmprojs(unittest.TestCase): # Create a separate environment new_env = mkdtemp() new_branch = "br" + str(uuid4()) - self.__add_worktree(self.__get_subproj_repo("llvm"), - os.path.join(new_env, "llvm"), new_branch) + self.add_worktree(self.get_subproj_repo("llvm"), + os.path.join(new_env, "llvm"), new_branch) # Check that we start with a clean slate in both the new environment and # the one that's already set up -- cgit v1.2.3