xref: /OK3568_Linux_fs/yocto/poky/meta/lib/oeqa/controllers/testtargetloader.py (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun#
2*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0-only
3*4882a593Smuzhiyun#
4*4882a593Smuzhiyun
5*4882a593Smuzhiyunimport types
6*4882a593Smuzhiyunimport bb
7*4882a593Smuzhiyunimport os
8*4882a593Smuzhiyun
9*4882a593Smuzhiyun# This class is responsible for loading a test target controller
10*4882a593Smuzhiyunclass TestTargetLoader:
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun    # Search oeqa.controllers module directory for and return a controller
13*4882a593Smuzhiyun    # corresponding to the given target name.
14*4882a593Smuzhiyun    # AttributeError raised if not found.
15*4882a593Smuzhiyun    # ImportError raised if a provided module can not be imported.
16*4882a593Smuzhiyun    def get_controller_module(self, target, bbpath):
17*4882a593Smuzhiyun        controllerslist = self.get_controller_modulenames(bbpath)
18*4882a593Smuzhiyun        bb.note("Available controller modules: %s" % str(controllerslist))
19*4882a593Smuzhiyun        controller = self.load_controller_from_name(target, controllerslist)
20*4882a593Smuzhiyun        return controller
21*4882a593Smuzhiyun
22*4882a593Smuzhiyun    # Return a list of all python modules in lib/oeqa/controllers for each
23*4882a593Smuzhiyun    # layer in bbpath
24*4882a593Smuzhiyun    def get_controller_modulenames(self, bbpath):
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun        controllerslist = []
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun        def add_controller_list(path):
29*4882a593Smuzhiyun            if not os.path.exists(os.path.join(path, '__init__.py')):
30*4882a593Smuzhiyun                bb.fatal('Controllers directory %s exists but is missing __init__.py' % path)
31*4882a593Smuzhiyun            files = sorted([f for f in os.listdir(path) if f.endswith('.py') and not f.startswith('_')])
32*4882a593Smuzhiyun            for f in files:
33*4882a593Smuzhiyun                module = 'oeqa.controllers.' + f[:-3]
34*4882a593Smuzhiyun                if module not in controllerslist:
35*4882a593Smuzhiyun                    controllerslist.append(module)
36*4882a593Smuzhiyun                else:
37*4882a593Smuzhiyun                    bb.warn("Duplicate controller module found for %s, only one added. Layers should create unique controller module names" % module)
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun        for p in bbpath:
40*4882a593Smuzhiyun            controllerpath = os.path.join(p, 'lib', 'oeqa', 'controllers')
41*4882a593Smuzhiyun            bb.debug(2, 'Searching for target controllers in %s' % controllerpath)
42*4882a593Smuzhiyun            if os.path.exists(controllerpath):
43*4882a593Smuzhiyun                add_controller_list(controllerpath)
44*4882a593Smuzhiyun        return controllerslist
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun    # Search for and return a controller from given target name and
47*4882a593Smuzhiyun    # set of module names.
48*4882a593Smuzhiyun    # Raise AttributeError if not found.
49*4882a593Smuzhiyun    # Raise ImportError if a provided module can not be imported
50*4882a593Smuzhiyun    def load_controller_from_name(self, target, modulenames):
51*4882a593Smuzhiyun        for name in modulenames:
52*4882a593Smuzhiyun            obj = self.load_controller_from_module(target, name)
53*4882a593Smuzhiyun            if obj:
54*4882a593Smuzhiyun                return obj
55*4882a593Smuzhiyun        raise AttributeError("Unable to load {0} from available modules: {1}".format(target, str(modulenames)))
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun    # Search for and return a controller or None from given module name
58*4882a593Smuzhiyun    def load_controller_from_module(self, target, modulename):
59*4882a593Smuzhiyun        obj = None
60*4882a593Smuzhiyun        # import module, allowing it to raise import exception
61*4882a593Smuzhiyun        module = __import__(modulename, globals(), locals(), [target])
62*4882a593Smuzhiyun        # look for target class in the module, catching any exceptions as it
63*4882a593Smuzhiyun        # is valid that a module may not have the target class.
64*4882a593Smuzhiyun        try:
65*4882a593Smuzhiyun            obj = getattr(module, target)
66*4882a593Smuzhiyun            if obj:
67*4882a593Smuzhiyun                from oeqa.targetcontrol import BaseTarget
68*4882a593Smuzhiyun                if( not issubclass(obj, BaseTarget)):
69*4882a593Smuzhiyun                    bb.warn("Target {0} found, but subclass is not BaseTarget".format(target))
70*4882a593Smuzhiyun        except:
71*4882a593Smuzhiyun            obj = None
72*4882a593Smuzhiyun        return obj
73