1# 2# Copyright OpenEmbedded Contributors 3# 4# SPDX-License-Identifier: GPL-2.0-only 5# 6 7import 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 70 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 75