mirror of
				https://github.com/ARM-software/workload-automation.git
				synced 2025-11-04 09:02:12 +00:00 
			
		
		
		
	Merge pull request #369 from setrofim/next
Fixing previous pull request.
This commit is contained in:
		@@ -629,7 +629,8 @@ class RunConfiguration(Configuration):
 | 
			
		||||
 | 
			
		||||
    name = "Run Configuration"
 | 
			
		||||
 | 
			
		||||
    # Metadata is separated out because it is not loaded into the auto generated config file
 | 
			
		||||
    # Metadata is separated out because it is not loaded into the auto
 | 
			
		||||
    # generated config file
 | 
			
		||||
    meta_data = [
 | 
			
		||||
        ConfigurationPoint('run_name', kind=str,
 | 
			
		||||
                           description='''
 | 
			
		||||
@@ -908,7 +909,8 @@ class JobSpec(Configuration):
 | 
			
		||||
        except NotFoundError:
 | 
			
		||||
            global_runtime_params = {}
 | 
			
		||||
        for source in plugin_cache.sources:
 | 
			
		||||
            runtime_parameters[source] = global_runtime_params[source]
 | 
			
		||||
            if source in global_runtime_params:
 | 
			
		||||
                runtime_parameters[source] = global_runtime_params[source]
 | 
			
		||||
 | 
			
		||||
        # Add runtime parameters from JobSpec
 | 
			
		||||
        for source, values in self.to_merge['runtime_parameters'].iteritems():
 | 
			
		||||
 
 | 
			
		||||
@@ -32,6 +32,7 @@ class ConfigParser(object):
 | 
			
		||||
 | 
			
		||||
    def load(self, state, raw, source, wrap_exceptions=True):  # pylint: disable=too-many-branches
 | 
			
		||||
        try:
 | 
			
		||||
            state.plugin_cache.add_source(source)
 | 
			
		||||
            if 'run_name' in raw:
 | 
			
		||||
                msg = '"run_name" can only be specified in the config '\
 | 
			
		||||
                      'section of an agenda'
 | 
			
		||||
 
 | 
			
		||||
@@ -181,47 +181,74 @@ class PluginCache(object):
 | 
			
		||||
        :rtype: A fully merged and validated configuration in the form of a
 | 
			
		||||
                obj_dict.
 | 
			
		||||
        """
 | 
			
		||||
        generic_config = copy(self.plugin_configs[generic_name])
 | 
			
		||||
        specific_config = copy(self.plugin_configs[specific_name])
 | 
			
		||||
        cfg_points = self.get_plugin_parameters(specific_name)
 | 
			
		||||
        ms = MergeState()
 | 
			
		||||
        ms.generic_name = generic_name
 | 
			
		||||
        ms.specific_name = specific_name
 | 
			
		||||
        ms.generic_config = copy(self.plugin_configs[generic_name])
 | 
			
		||||
        ms.specific_config = copy(self.plugin_configs[specific_name])
 | 
			
		||||
        ms.cfg_points = self.get_plugin_parameters(specific_name)
 | 
			
		||||
        sources = self.sources
 | 
			
		||||
        seen_specific_config = defaultdict(list)
 | 
			
		||||
 | 
			
		||||
        # set_value uses the 'name' attribute of the passed object in it error
 | 
			
		||||
        # messages, to ensure these messages make sense the name will have to be
 | 
			
		||||
        # changed several times during this function.
 | 
			
		||||
        final_config.name = specific_name
 | 
			
		||||
 | 
			
		||||
        # pylint: disable=too-many-nested-blocks
 | 
			
		||||
        for source in sources:
 | 
			
		||||
            try:
 | 
			
		||||
                if source in generic_config:
 | 
			
		||||
                    final_config.name = generic_name
 | 
			
		||||
                    for name, cfg_point in cfg_points.iteritems():
 | 
			
		||||
                        if name in generic_config[source]:
 | 
			
		||||
                            if name in seen_specific_config:
 | 
			
		||||
                                msg = ('"{generic_name}" configuration "{config_name}" has already been '
 | 
			
		||||
                                       'specified more specifically for {specific_name} in:\n\t\t{sources}')
 | 
			
		||||
                                msg = msg.format(generic_name=generic_name,
 | 
			
		||||
                                                 config_name=name,
 | 
			
		||||
                                                 specific_name=specific_name,
 | 
			
		||||
                                                 sources=", ".join(seen_specific_config[name]))
 | 
			
		||||
                                raise ConfigError(msg)
 | 
			
		||||
                            value = generic_config[source][name]
 | 
			
		||||
                            cfg_point.set_value(final_config, value, check_mandatory=False)
 | 
			
		||||
 | 
			
		||||
                if source in specific_config:
 | 
			
		||||
                    final_config.name = specific_name
 | 
			
		||||
                    for name, cfg_point in cfg_points.iteritems():
 | 
			
		||||
                        if name in specific_config[source]:
 | 
			
		||||
                            seen_specific_config[name].append(str(source))
 | 
			
		||||
                            value = specific_config[source][name]
 | 
			
		||||
                            cfg_point.set_value(final_config, value, check_mandatory=False)
 | 
			
		||||
 | 
			
		||||
                update_config_from_source(final_config, source, ms)
 | 
			
		||||
            except ConfigError as e:
 | 
			
		||||
                raise ConfigError('Error in "{}":\n\t{}'.format(source, str(e)))
 | 
			
		||||
 | 
			
		||||
        # Validate final configuration
 | 
			
		||||
        final_config.name = specific_name
 | 
			
		||||
        for cfg_point in cfg_points.itervalues():
 | 
			
		||||
        for cfg_point in ms.cfg_points.itervalues():
 | 
			
		||||
            cfg_point.validate(final_config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MergeState(object):
 | 
			
		||||
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        self.generic_name = None
 | 
			
		||||
        self.specific_name = None
 | 
			
		||||
        self.generic_config = None
 | 
			
		||||
        self.specific_config = None
 | 
			
		||||
        self.cfg_points = None
 | 
			
		||||
        self.seen_specific_config = defaultdict(list)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def update_config_from_source(final_config, source, state):
 | 
			
		||||
    if source in state.generic_config:
 | 
			
		||||
        final_config.name = state.generic_name
 | 
			
		||||
        for name, cfg_point in state.cfg_points.iteritems():
 | 
			
		||||
            if name in state.generic_config[source]:
 | 
			
		||||
                if name in state.seen_specific_config:
 | 
			
		||||
                    msg = ('"{generic_name}" configuration "{config_name}" has '
 | 
			
		||||
                            'already been specified more specifically for '
 | 
			
		||||
                            '{specific_name} in:\n\t\t{sources}')
 | 
			
		||||
                    seen_sources = state.seen_specific_config[name]
 | 
			
		||||
                    msg = msg.format(generic_name=generic_name,
 | 
			
		||||
                                        config_name=name,
 | 
			
		||||
                                        specific_name=specific_name,
 | 
			
		||||
                                        sources=", ".join(seen_sources))
 | 
			
		||||
                    raise ConfigError(msg)
 | 
			
		||||
                value = state.generic_config[source].pop(name)
 | 
			
		||||
                cfg_point.set_value(final_config, value, check_mandatory=False)
 | 
			
		||||
 | 
			
		||||
        if state.generic_config[source]:
 | 
			
		||||
            msg = 'Unexected values for {}: {}'
 | 
			
		||||
            raise ConfigError(msg.format(state.generic_name,
 | 
			
		||||
                                         state.generic_config[source]))
 | 
			
		||||
 | 
			
		||||
    if source in state.specific_config:
 | 
			
		||||
        final_config.name = state.specific_name
 | 
			
		||||
        for name, cfg_point in state.cfg_points.iteritems():
 | 
			
		||||
            if name in state.specific_config[source]:
 | 
			
		||||
                seen_state.specific_config[name].append(str(source))
 | 
			
		||||
                value = state.specific_config[source].pop(name)
 | 
			
		||||
                cfg_point.set_value(final_config, value, check_mandatory=False)
 | 
			
		||||
 | 
			
		||||
        if state.specific_config[source]:
 | 
			
		||||
            msg = 'Unexected values for {}: {}'
 | 
			
		||||
            raise ConfigError(msg.format(state.specific_name,
 | 
			
		||||
                                         state.specific_config[source]))
 | 
			
		||||
 
 | 
			
		||||
@@ -24,6 +24,35 @@ def get_target_descriptions(loader=pluginloader):
 | 
			
		||||
    return targets.values()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def instantiate_target(tdesc, params, connect=None):
 | 
			
		||||
    target_params = {p.name: p for p in tdesc.target_params}
 | 
			
		||||
    platform_params = {p.name: p for p in tdesc.platform_params}
 | 
			
		||||
    conn_params = {p.name: p for p in tdesc.conn_params}
 | 
			
		||||
 | 
			
		||||
    tp, pp, cp = {}, {}, {}
 | 
			
		||||
 | 
			
		||||
    for name, value in params.iteritems():
 | 
			
		||||
        if name in target_params:
 | 
			
		||||
            tp[name] = value
 | 
			
		||||
        elif name in platform_params:
 | 
			
		||||
            pp[name] = value
 | 
			
		||||
        elif name in conn_params:
 | 
			
		||||
            cp[name] = value
 | 
			
		||||
        else:
 | 
			
		||||
            msg = 'Unexpected parameter for {}: {}'
 | 
			
		||||
            raise ValueError(msg.format(tdesc.name, name))
 | 
			
		||||
 | 
			
		||||
    tp['platform'] = (tdesc.platform or Platform)(**pp)
 | 
			
		||||
    if cp:
 | 
			
		||||
        tp['connection_settings'] = cp
 | 
			
		||||
    if tdesc.connection:
 | 
			
		||||
        tp['conn_cls'] = tdesc.connection
 | 
			
		||||
    if connect is not None:
 | 
			
		||||
        tp['connect'] = connect
 | 
			
		||||
 | 
			
		||||
    return tdesc.target(**tp)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TargetDescription(object):
 | 
			
		||||
 | 
			
		||||
    def __init__(self, name, source, description=None, target=None, platform=None, 
 | 
			
		||||
@@ -86,6 +115,18 @@ COMMON_TARGET_PARAMS = [
 | 
			
		||||
              Please see ``devlab`` documentation for information on the available
 | 
			
		||||
              modules.
 | 
			
		||||
              '''),
 | 
			
		||||
    Parameter('load_default_modules', kind=bool, default=True,
 | 
			
		||||
              description='''
 | 
			
		||||
              A number of modules (e.g. for working with the cpufreq subsystem) are
 | 
			
		||||
              loaded by default when a Target is instantiated. Setting this to
 | 
			
		||||
              ``True`` would suppress that, ensuring that only the base Target
 | 
			
		||||
              interface is initialized.
 | 
			
		||||
 | 
			
		||||
              You may want to set this if there is a problem with one or more default
 | 
			
		||||
              modules on your platform (e.g. your device is unrooted and cpufreq is
 | 
			
		||||
              not accessible to unprivileged users), or if Target initialization is
 | 
			
		||||
              taking too long for your platform.
 | 
			
		||||
              '''),
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
COMMON_PLATFORM_PARAMS = [
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
from devlib import AndroidTarget
 | 
			
		||||
from devlib.exception import TargetError
 | 
			
		||||
from devlib.target import KernelConfig, KernelVersion, Cpuinfo
 | 
			
		||||
from devlib.utils.android import AndroidProperties
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TargetInfo(object):
 | 
			
		||||
@@ -21,8 +22,9 @@ class TargetInfo(object):
 | 
			
		||||
 | 
			
		||||
        if pod["target"] == "AndroidTarget":
 | 
			
		||||
            instance.screen_resolution = pod['screen_resolution']
 | 
			
		||||
            instance.prop = pod['prop']
 | 
			
		||||
            instance.prop = pod['android_id']
 | 
			
		||||
            instance.prop = AndroidProperties('')
 | 
			
		||||
            instance.prop._properties = pod['prop']
 | 
			
		||||
            instance.android_id = pod['android_id']
 | 
			
		||||
 | 
			
		||||
        return instance
 | 
			
		||||
 | 
			
		||||
@@ -72,7 +74,7 @@ class TargetInfo(object):
 | 
			
		||||
 | 
			
		||||
        if self.target == "AndroidTarget":
 | 
			
		||||
            pod['screen_resolution'] = self.screen_resolution
 | 
			
		||||
            pod['prop'] = self.prop
 | 
			
		||||
            pod['prop'] = self.prop._properties
 | 
			
		||||
            pod['android_id'] = self.android_id
 | 
			
		||||
 | 
			
		||||
        return pod
 | 
			
		||||
 
 | 
			
		||||
@@ -9,6 +9,8 @@ import sys
 | 
			
		||||
from wa.framework import signal
 | 
			
		||||
from wa.framework.exception import WorkerThreadError, ConfigError
 | 
			
		||||
from wa.framework.plugin import Parameter
 | 
			
		||||
from wa.framework.target.descriptor import (get_target_descriptions,
 | 
			
		||||
                                            instantiate_target)
 | 
			
		||||
from wa.framework.target.info import TargetInfo
 | 
			
		||||
from wa.framework.target.runtime_config import (SysfileValuesRuntimeConfig,
 | 
			
		||||
                                                HotplugRuntimeConfig,
 | 
			
		||||
@@ -41,54 +43,26 @@ class TargetManager(object):
 | 
			
		||||
                  """),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    DEVICE_MAPPING = {'test' : {'platform_name':'generic',
 | 
			
		||||
                               'target_name': 'android'},
 | 
			
		||||
                      'other':  {'platform_name':'test',
 | 
			
		||||
                                'target_name': 'linux'},
 | 
			
		||||
                      }
 | 
			
		||||
 | 
			
		||||
    runtime_config_cls = [
 | 
			
		||||
                            # order matters
 | 
			
		||||
                            SysfileValuesRuntimeConfig,
 | 
			
		||||
                            HotplugRuntimeConfig,
 | 
			
		||||
                            CpufreqRuntimeConfig,
 | 
			
		||||
                            CpuidleRuntimeConfig,
 | 
			
		||||
                          ]
 | 
			
		||||
        # order matters
 | 
			
		||||
        SysfileValuesRuntimeConfig,
 | 
			
		||||
        HotplugRuntimeConfig,
 | 
			
		||||
        CpufreqRuntimeConfig,
 | 
			
		||||
        CpuidleRuntimeConfig,
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    def __init__(self, name, parameters):
 | 
			
		||||
        self.name = name
 | 
			
		||||
        self.target_name = name
 | 
			
		||||
        self.target = None
 | 
			
		||||
        self.assistant = None
 | 
			
		||||
        self.target_name = None
 | 
			
		||||
        self.platform_name = None
 | 
			
		||||
        self.parameters = parameters
 | 
			
		||||
        self.disconnect = parameters.get('disconnect')
 | 
			
		||||
        self.info = TargetInfo()
 | 
			
		||||
 | 
			
		||||
        # Determine platform and target based on passed name
 | 
			
		||||
        self._parse_name()
 | 
			
		||||
        # Create target
 | 
			
		||||
        self._get_target()
 | 
			
		||||
        # Create an assistant to perform target specific configuration
 | 
			
		||||
        self._get_assistant()
 | 
			
		||||
 | 
			
		||||
        ### HERE FOR TESTING, WILL BE CALLED EXTERNALLY ###
 | 
			
		||||
        # Connect to device and retrieve details.
 | 
			
		||||
        # self.initialize()
 | 
			
		||||
        # self.add_parameters()
 | 
			
		||||
        # self.validate_parameters()
 | 
			
		||||
        # self.set_parameters()
 | 
			
		||||
 | 
			
		||||
    def initialize(self):
 | 
			
		||||
        self._init_target()
 | 
			
		||||
        self._init_assistant()
 | 
			
		||||
        self.runtime_configs = [cls(self.target) for cls in self.runtime_config_cls]
 | 
			
		||||
        # if self.parameters:
 | 
			
		||||
        # self.logger.info('Connecting to the device')
 | 
			
		||||
        with signal.wrap('TARGET_CONNECT'):
 | 
			
		||||
            self.target.connect()
 | 
			
		||||
            # self.info.load(self.target)
 | 
			
		||||
            # info_file = os.path.join(self.context.info_directory, 'target.json')
 | 
			
		||||
            # with open(info_file, 'w') as wfh:
 | 
			
		||||
            #     json.dump(self.info.to_pod(), wfh)
 | 
			
		||||
 | 
			
		||||
    def finalize(self):
 | 
			
		||||
        # self.logger.info('Disconnecting from the device')
 | 
			
		||||
@@ -108,10 +82,16 @@ class TargetManager(object):
 | 
			
		||||
                if any(parameter in name for parameter in cfg.supported_parameters):
 | 
			
		||||
                    cfg.add(name, self.parameters.pop(name))
 | 
			
		||||
 | 
			
		||||
    def validate_parameters(self):
 | 
			
		||||
    def get_target_info(self):
 | 
			
		||||
        return TargetInfo(self.target)
 | 
			
		||||
 | 
			
		||||
    def validate_runtime_parameters(self, params):
 | 
			
		||||
        for cfg in self.runtime_configs:
 | 
			
		||||
            cfg.validate()
 | 
			
		||||
 | 
			
		||||
    def merge_runtime_parameters(self, params):
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def set_parameters(self):
 | 
			
		||||
        for cfg in self.runtime_configs:
 | 
			
		||||
            cfg.set()
 | 
			
		||||
@@ -120,47 +100,25 @@ class TargetManager(object):
 | 
			
		||||
        for cfg in self.runtime_configs:
 | 
			
		||||
            cfg.clear()
 | 
			
		||||
 | 
			
		||||
    def _parse_name(self):
 | 
			
		||||
        # Try and get platform and target
 | 
			
		||||
        self.name = identifier(self.name.replace('-', '_'))
 | 
			
		||||
        if '_' in self.name:
 | 
			
		||||
            self.platform_name, self.target_name = self.name.split('_', 1)
 | 
			
		||||
        elif self.name in self.DEVICE_MAPPING:
 | 
			
		||||
            self.platform_name = self.DEVICE_MAPPING[self.name]['platform_name']
 | 
			
		||||
            self.target_name = self.DEVICE_MAPPING[self.name]['target_name']
 | 
			
		||||
        else:
 | 
			
		||||
            raise ConfigError('Unknown Device Specified {}'.format(self.name))
 | 
			
		||||
    def _init_target(self):
 | 
			
		||||
        target_map = {td.name: td for td in get_target_descriptions()}
 | 
			
		||||
        if self.target_name not in target_map:
 | 
			
		||||
            raise ValueError('Unknown Target: {}'.format(self.target_name))
 | 
			
		||||
        tdesc = target_map[self.target_name]
 | 
			
		||||
        self.target = instantiate_target(tdesc, self.parameters, connect=False)
 | 
			
		||||
        with signal.wrap('TARGET_CONNECT'):
 | 
			
		||||
            self.target.connect()
 | 
			
		||||
        self.target.setup()
 | 
			
		||||
 | 
			
		||||
    def _get_target(self):
 | 
			
		||||
        # Create a corresponding target and target-assistant
 | 
			
		||||
        if self.target_name == 'android':
 | 
			
		||||
            self.target = AndroidTarget()
 | 
			
		||||
        elif self.target_name == 'linux':
 | 
			
		||||
            self.target = LinuxTarget()  # pylint: disable=redefined-variable-type
 | 
			
		||||
        elif self.target_name == 'localLinux':
 | 
			
		||||
            self.target = LocalLinuxTarget()
 | 
			
		||||
        else:
 | 
			
		||||
            raise ConfigError('Unknown Target Specified {}'.format(self.target_name))
 | 
			
		||||
 | 
			
		||||
    def _get_assistant(self):
 | 
			
		||||
        # Create a corresponding target and target-assistant to help with platformy stuff?
 | 
			
		||||
        if self.target_name == 'android':
 | 
			
		||||
    def _init_assistant(self):
 | 
			
		||||
        # Create a corresponding target and target-assistant to help with
 | 
			
		||||
        # platformy stuff?
 | 
			
		||||
        if self.target.os == 'android':
 | 
			
		||||
            self.assistant = AndroidAssistant(self.target)
 | 
			
		||||
        elif self.target_name in ['linux', 'localLinux']:
 | 
			
		||||
        elif self.target.os == 'linux':
 | 
			
		||||
            self.assistant = LinuxAssistant(self.target)  # pylint: disable=redefined-variable-type
 | 
			
		||||
        else:
 | 
			
		||||
            raise ConfigError('Unknown Target Specified {}'.format(self.target_name))
 | 
			
		||||
 | 
			
		||||
    # def validate_runtime_parameters(self, parameters):
 | 
			
		||||
    #     for  name, value in parameters.iteritems():
 | 
			
		||||
    #         self.add_parameter(name, value)
 | 
			
		||||
    #     self.validate_parameters()
 | 
			
		||||
 | 
			
		||||
    # def set_runtime_parameters(self, parameters):
 | 
			
		||||
    #     # self.clear()
 | 
			
		||||
    #     for  name, value in parameters.iteritems():
 | 
			
		||||
    #         self.add_parameter(name, value)
 | 
			
		||||
    #     self.set_parameters()
 | 
			
		||||
            raise ValueError('Unknown Target OS: {}'.format(self.target.os))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class LinuxAssistant(object):
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user