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