aboutsummaryrefslogtreecommitdiff
path: root/tests/cli/llvmtestcase.py
blob: 0f29ce6fa5aca5d0574c876eeceadbfbd1cc6a16 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
"""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:
            self = args[0]
            self.maxDiff = None # So we can see large diffs between
                                # expected/actual
            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, commitMessage="Dummy commit"):
        filename = "filethatshouldntexist" + str(uuid4())
        cls.run_quietly(["touch", filename])
        try:
            cls.run_quietly(["git", "add", filename])
            cls.run_quietly(["git", "commit", "-m", commitMessage])
        except subprocess.CalledProcessError as exc:
            print("Command {} exited with error code {}:\n{}".format(
                exc.cmd, exc.returncode, exc.output))

    @classmethod
    def create_dummy_repo(cls, repopath, originpath=None):
        if originpath is not None:
            cls.run_quietly(["git", "clone", originpath, repopath])
        else:
            if not os.path.isdir(repopath):
                os.makedirs(repopath)

            with cd(repopath):
                cls.run_quietly(["git", "init"])

        with cd(repopath):
            cls.create_dummy_commit()

    @classmethod
    def add_worktree(cls, repopath, worktreepath, branch):
        with cd(repopath):
            cls.run_quietly(["git", "worktree", "add", worktreepath,
                             "-b", branch])

    @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 an llvm subcommand with the given args."""
        command = [cls.python, cls.script]

        command.append(subcommand)

        if len(args):
            command.extend(args)

        return command