blob: f895c495cd93f56c3f28d8099eee57cc515e9b5c [file] [log] [blame]
Diana Picus3601bea2017-05-29 11:26:18 +02001"""Common TestCase used for testing llvm.py subcommands."""
2
3import shutil
4import os
5import subprocess
6import unittest
7
8from tempfile import mkdtemp
9from uuid import uuid4
10
11from linaropy.cd import cd
12
13
14# TODO: move this somewhere more public (maybe linaropy?)
15def debug(test):
16 """
17 Decorator that dumps the output of any subprocess.CalledProcessError
18 exception. Use this to decorate a test function when you can't tell what the
19 problem is.
20 """
21 def wrapper(*args, **kwargs):
22 # Catch any exceptions so we can dump all the output
23 try:
Diana Picus5fdc8922018-01-25 13:47:50 +010024 self = args[0]
25 self.maxDiff = None # So we can see large diffs between
26 # expected/actual
Diana Picus3601bea2017-05-29 11:26:18 +020027 test(*args, **kwargs)
28 except subprocess.CalledProcessError as exc:
29 print("Error in {}:".format(test.__name__))
30 print("Command {} exited with error code {}:\n{}".format(
31 exc.cmd, exc.returncode, exc.output))
32 return wrapper
33
34
Diana Picus9276b782018-01-24 14:40:46 +010035def require_command_arg(requiredArg):
36 """
37 Decorator that simplifies writing CLI tests that check that 'requiredArg' is
38 in fact required (i.e. that the command that we're testing will blow up if
39 we don't pass it the required argument).
40
41 Use this to decorate test functions, e.g:
42
43 @require_command_arg("--my-required-arg")
44 def test_my_required_arg_is_compulsory(self):
45 run_command_without_my_required_arg()
46 """
47 def decorate(test):
48 def wrapper(*args, **kwargs):
49 self = args[0]
50 with self.assertRaises(subprocess.CalledProcessError) as context:
51 test(*args, **kwargs)
52
53 self.assertRegex(str(context.exception.output),
54 "(.*\n)*the following arguments are required: {}(.*\n)*".format(requiredArg))
55 return wrapper
56 return decorate
57
58
Diana Picus3601bea2017-05-29 11:26:18 +020059class LLVMTestCase(unittest.TestCase):
60 python = "python3"
61 script = os.path.join("scripts", "llvm.py")
62
63 @classmethod
Diana Picusefc7bda2017-06-09 19:14:08 +020064 def create_dummy_commit(cls, commitMessage="Dummy commit"):
65 filename = "filethatshouldntexist" + str(uuid4())
Diana Picus3601bea2017-05-29 11:26:18 +020066 cls.run_quietly(["touch", filename])
Diana Picusefc7bda2017-06-09 19:14:08 +020067 try:
68 cls.run_quietly(["git", "add", filename])
69 cls.run_quietly(["git", "commit", "-m", commitMessage])
70 except subprocess.CalledProcessError as exc:
71 print("Command {} exited with error code {}:\n{}".format(
72 exc.cmd, exc.returncode, exc.output))
Diana Picus3601bea2017-05-29 11:26:18 +020073
74 @classmethod
Diana Picusefc7bda2017-06-09 19:14:08 +020075 def create_dummy_repo(cls, repopath, originpath=None):
76 if originpath is not None:
77 cls.run_quietly(["git", "clone", originpath, repopath])
78 else:
79 if not os.path.isdir(repopath):
80 os.makedirs(repopath)
81
82 with cd(repopath):
83 cls.run_quietly(["git", "init"])
Diana Picus3601bea2017-05-29 11:26:18 +020084
85 with cd(repopath):
Diana Picus3601bea2017-05-29 11:26:18 +020086 cls.create_dummy_commit()
87
88 @classmethod
89 def add_worktree(cls, repopath, worktreepath, branch):
90 with cd(repopath):
91 cls.run_quietly(["git", "worktree", "add", worktreepath,
92 "-b", branch])
93
Diana Picus3601bea2017-05-29 11:26:18 +020094 @staticmethod
95 def run_with_output(*args, **kwargs):
96 """Helper for running a command and capturing stdout and stderr"""
97 kwargs["stderr"] = subprocess.STDOUT
98 return str(subprocess.check_output(*args, **kwargs), 'utf-8')
99
100 @staticmethod
101 def run_quietly(*args, **kwargs):
102 """
103 Helper for running a command and ignoring stdout and stderr. Exceptions
104 are still thrown if something goes wrong
105 """
106 kwargs["stdout"] = subprocess.DEVNULL
107 kwargs["stderr"] = subprocess.DEVNULL
108 return subprocess.check_call(*args, **kwargs)
109
110 @classmethod
111 def command_with_defaults(cls, subcommand, *args, **kwargs):
Diana Picus9f756862017-12-20 10:35:08 +0100112 """Build a list representing an llvm subcommand with the given args."""
Diana Picus3601bea2017-05-29 11:26:18 +0200113 command = [cls.python, cls.script]
114
Diana Picus3601bea2017-05-29 11:26:18 +0200115 command.append(subcommand)
116
117 if len(args):
118 command.extend(args)
119
120 return command