testimage: Implement custom target loading

This patch implements custom target loading for testimage, currently
missing due to major changes to the test framework.
Custom targets can be defined in various meta-layers, so we
need an extra path information in order to find them.
Any other additional info is retrieved as usual via the variables
TEST_TARGET and TEST_SUITES

(From OE-Core rev: 1dc8010afd71fe46fb28bb86fb7c07a5fbd3d7cf)

Signed-off-by: Juro Bystricky <juro.bystricky@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Juro Bystricky 2017-02-06 09:49:37 -08:00 committed by Richard Purdie
parent 124f689569
commit b1f99066bd
2 changed files with 72 additions and 4 deletions

View File

@ -238,7 +238,7 @@ def testimage_main(d):
# the robot dance
target = OERuntimeTestContextExecutor.getTarget(
d.getVar("TEST_TARGET"), None, d.getVar("TEST_TARGET_IP"),
d.getVar("TEST_TARGET"), d.getVar("BBPATH"), None, d.getVar("TEST_TARGET_IP"),
d.getVar("TEST_SERVER_IP"), **target_kwargs)
# test context

View File

@ -89,7 +89,7 @@ class OERuntimeTestContextExecutor(OETestContextExecutor):
help="Qemu boot configuration, only needed when target_type is QEMU.")
@staticmethod
def getTarget(target_type, logger, target_ip, server_ip, **kwargs):
def getTarget(target_type, target_modules_path, logger, target_ip, server_ip, **kwargs):
target = None
if target_type == 'simpleremote':
@ -97,11 +97,79 @@ class OERuntimeTestContextExecutor(OETestContextExecutor):
elif target_type == 'qemu':
target = OEQemuTarget(logger, target_ip, server_ip, **kwargs)
else:
# TODO: Implement custom target module loading
raise TypeError("target_type %s isn't supported" % target_type)
# Custom target module loading
try:
controller = OERuntimeTestContextExecutor.getControllerModule(target_type, target_modules_path)
target = controller(logger, target_ip, server_ip, **kwargs)
except ImportError as e:
raise TypeError("Failed to import %s from available controller modules" % target_type)
return target
# Search oeqa.controllers module directory for and return a controller
# corresponding to the given target name.
# AttributeError raised if not found.
# ImportError raised if a provided module can not be imported.
@staticmethod
def getControllerModule(target, target_modules_path):
controllerslist = OERuntimeTestContextExecutor._getControllerModulenames(target_modules_path)
controller = OERuntimeTestContextExecutor._loadControllerFromName(target, controllerslist)
return controller
# Return a list of all python modules in lib/oeqa/controllers for each
# layer in bbpath
@staticmethod
def _getControllerModulenames(target_modules_path):
controllerslist = []
def add_controller_list(path):
if not os.path.exists(os.path.join(path, '__init__.py')):
raise OSError('Controllers directory %s exists but is missing __init__.py' % path)
files = sorted([f for f in os.listdir(path) if f.endswith('.py') and not f.startswith('_')])
for f in files:
module = 'oeqa.controllers.' + f[:-3]
if module not in controllerslist:
controllerslist.append(module)
else:
raise RuntimeError("Duplicate controller module found for %s. Layers should create unique controller module names" % module)
extpath = target_modules_path.split(':')
for p in extpath:
controllerpath = os.path.join(p, 'lib', 'oeqa', 'controllers')
if os.path.exists(controllerpath):
add_controller_list(controllerpath)
return controllerslist
# Search for and return a controller from given target name and
# set of module names.
# Raise AttributeError if not found.
# Raise ImportError if a provided module can not be imported
@staticmethod
def _loadControllerFromName(target, modulenames):
for name in modulenames:
obj = OERuntimeTestContextExecutor._loadControllerFromModule(target, name)
if obj:
return obj
raise AttributeError("Unable to load {0} from available modules: {1}".format(target, str(modulenames)))
# Search for and return a controller or None from given module name
@staticmethod
def _loadControllerFromModule(target, modulename):
obj = None
# import module, allowing it to raise import exception
try:
module = __import__(modulename, globals(), locals(), [target])
except Exception as e:
return obj
# look for target class in the module, catching any exceptions as it
# is valid that a module may not have the target class.
try:
obj = getattr(module, target)
except:
obj = None
return obj
@staticmethod
def readPackagesManifest(manifest):
if not manifest or not os.path.exists(manifest):