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