1#
2# SPDX-License-Identifier: MIT
3#
4# Enable other layers to have modules in the same named directory
5from pkgutil import extend_path
6__path__ = extend_path(__path__, __name__)
7
8# Borrowed from CalledProcessError
9
10class CommandError(Exception):
11    def __init__(self, retcode, cmd, output = None):
12        self.retcode = retcode
13        self.cmd = cmd
14        self.output = output
15    def __str__(self):
16        return "Command '%s' returned non-zero exit status %d with output: %s" % (self.cmd, self.retcode, self.output)
17
18def avoid_paths_in_environ(paths):
19    """
20        Searches for every path in os.environ['PATH']
21        if found remove it.
22
23        Returns new PATH without avoided PATHs.
24    """
25    import os
26
27    new_path = ''
28    for p in os.environ['PATH'].split(':'):
29       avoid = False
30       for pa in paths:
31           if pa in p:
32              avoid = True
33              break
34       if avoid:
35           continue
36
37       new_path = new_path + p + ':'
38
39    new_path = new_path[:-1]
40    return new_path
41
42def make_logger_bitbake_compatible(logger):
43    import logging
44
45    """
46        Bitbake logger redifines debug() in order to
47        set a level within debug, this breaks compatibility
48        with vainilla logging, so we neeed to redifine debug()
49        method again also add info() method with INFO + 1 level.
50    """
51    def _bitbake_log_debug(*args, **kwargs):
52        lvl = logging.DEBUG
53
54        if isinstance(args[0], int):
55            lvl = args[0]
56            msg = args[1]
57            args = args[2:]
58        else:
59            msg = args[0]
60            args = args[1:]
61
62        logger.log(lvl, msg, *args, **kwargs)
63
64    def _bitbake_log_info(msg, *args, **kwargs):
65        logger.log(logging.INFO + 1, msg, *args, **kwargs)
66
67    logger.debug = _bitbake_log_debug
68    logger.info = _bitbake_log_info
69
70    return logger
71
72def load_test_components(logger, executor):
73    import sys
74    import os
75    import importlib
76
77    from oeqa.core.context import OETestContextExecutor
78
79    components = {}
80
81    for path in sys.path:
82        base_dir = os.path.join(path, 'oeqa')
83        if os.path.exists(base_dir) and os.path.isdir(base_dir):
84            for file in os.listdir(base_dir):
85                comp_name = file
86                comp_context = os.path.join(base_dir, file, 'context.py')
87                if os.path.exists(comp_context):
88                    comp_plugin = importlib.import_module('oeqa.%s.%s' % \
89                            (comp_name, 'context'))
90                    try:
91                        if not issubclass(comp_plugin._executor_class,
92                                OETestContextExecutor):
93                            raise TypeError("Component %s in %s, _executor_class "\
94                                "isn't derived from OETestContextExecutor."\
95                                % (comp_name, comp_context))
96
97                        if comp_plugin._executor_class._script_executor \
98                                != executor:
99                            continue
100
101                        components[comp_name] = comp_plugin._executor_class()
102                    except AttributeError:
103                        raise AttributeError("Component %s in %s don't have "\
104                                "_executor_class defined." % (comp_name, comp_context))
105
106    return components
107