Example #1
0
    def load(self, state, raw, source):
        logger.debug('Parsing agenda from "{}"'.format(source))
        log.indent()
        try:
            if not isinstance(raw, dict):
                raise ConfigError(
                    'Invalid agenda, top level entry must be a dict')

            self._populate_and_validate_config(state, raw, source)
            sections = self._pop_sections(raw)
            global_workloads = self._pop_workloads(raw)
            if not global_workloads:
                msg = 'No jobs avaliable. Please ensure you have specified at '\
                      'least one workload to run.'
                raise ConfigError(msg)

            if raw:
                msg = 'Invalid top level agenda entry(ies): "{}"'
                raise ConfigError(msg.format('", "'.join(list(raw.keys()))))

            sect_ids, wkl_ids = self._collect_ids(sections, global_workloads)
            self._process_global_workloads(state, global_workloads, wkl_ids)
            self._process_sections(state, sections, sect_ids, wkl_ids)

            state.agenda = source

        except (ConfigError, SerializerSyntaxError) as e:
            raise ConfigError('Error in "{}":\n\t{}'.format(source, str(e)))
        finally:
            log.dedent()
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.items():
            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=state.generic_name,
                                     config_name=name,
                                     specific_name=state.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 = 'Unexpected 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.items():
            if name in state.specific_config[source]:
                state.seen_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 = 'Unexpected values for {}: {}'
            raise ConfigError(msg.format(state.specific_name,
                                         state.specific_config[source]))
    def add_configs(self, plugin_name, values, source):
        if self.is_global_alias(plugin_name):
            self.add_global_alias(plugin_name, values, source)
            return

        if source not in self.sources:
            msg = "Source '{}' has not been added to the plugin cache."
            raise RuntimeError(msg.format(source))

        if caseless_string(plugin_name) in ['global', 'config']:
            msg = '"{}" entry specified inside config/global section; If this is ' \
                  'defined in a config file, move the entry content into the top level'
            raise ConfigError(msg.format((plugin_name)))

        if (not self.loader.has_plugin(plugin_name)
                and plugin_name not in self.targets
                and plugin_name not in GENERIC_CONFIGS):
            msg = 'configuration provided for unknown plugin "{}"'
            raise ConfigError(msg.format(plugin_name))

        if not hasattr(values, 'items'):
            msg = 'Plugin configuration for "{}" not a dictionary ({} is {})'
            raise ConfigError(
                msg.format(plugin_name, repr(values), type(values)))

        for name, value in values.items():
            if (plugin_name not in GENERIC_CONFIGS
                    and name not in self.get_plugin_parameters(plugin_name)):
                msg = "'{}' is not a valid parameter for '{}'"
                raise ConfigError(msg.format(name, plugin_name))

            self.plugin_configs[plugin_name][source][name] = value
 def validate_parameters(self, params):
     if not params.get('resistor_values'):
         raise ConfigError('Mandatory parameter "resistor_values" is not set.')
     if params.get('labels'):
         if len(params.get('labels')) != len(params.get('resistor_values')):
             msg = 'Number of Energy Probe port labels does not match the number of resistor values.'
             raise ConfigError(msg)
Example #5
0
 def set_value(self, obj, value=None, check_mandatory=True):
     if self.deprecated:
         if value is not None:
             msg = 'Depreciated parameter supplied for "{}" in "{}". The value will be ignored.'
             logger.warning(msg.format(self.name, obj.name))
         return
     if value is None:
         if self.default is not None:
             value = self.kind(self.default)
         elif check_mandatory and self.mandatory:
             msg = 'No values specified for mandatory parameter "{}" in {}'
             raise ConfigError(msg.format(self.name, obj.name))
     else:
         try:
             value = self.kind(value)
         except (ValueError, TypeError):
             typename = get_type_name(self.kind)
             msg = 'Bad value "{}" for {}; must be {} {}'
             article = get_article(typename)
             raise ConfigError(msg.format(value, self.name, article, typename))
     if value is not None:
         self.validate_value(self.name, value)
     if self.merge and hasattr(obj, self.name):
         value = merge_config_values(getattr(obj, self.name), value)
     setattr(obj, self.name, value)
Example #6
0
 def _pop_sections(self, raw):
     sections = raw.pop("sections", [])
     if not isinstance(sections, list):
         raise ConfigError('Invalid entry "sections" - must be a list')
     for section in sections:
         if not hasattr(section, 'items'):
             raise ConfigError(
                 'Invalid section "{}" - must be a dict'.format(section))
     return sections
Example #7
0
 def set(self, name, value, check_mandatory=True):
     if name not in self.configuration:
         raise ConfigError('Unknown {} configuration "{}"'.format(self.name,
                                                                  name))
     try:
         self.configuration[name].set_value(self, value,
                                            check_mandatory=check_mandatory)
     except (TypeError, ValueError, ConfigError) as e:
         msg = 'Invalid value "{}" for "{}": {}'
         raise ConfigError(msg.format(value, name, e))
Example #8
0
 def validate_allowed_values(self, name, value):
     if 'list' in str(self.kind):
         for v in value:
             if v not in self.allowed_values:
                 msg = 'Invalid value {} for {} in {}; must be in {}'
                 raise ConfigError(msg.format(v, self.name, name, self.allowed_values))
     else:
         if value not in self.allowed_values:
             msg = 'Invalid value {} for {} in {}; must be in {}'
             raise ConfigError(msg.format(value, self.name, name, self.allowed_values))
Example #9
0
 def _get_oid(self):
     columns = ['{}s.oid'.format(self.kind)]
     tables = ['{}s'.format(self.kind)]
     conditions = ['runs.run_uuid = \'{}\''.format(self.run_uuid)]
     oid = self._read_db(columns, tables, conditions, as_dict=False)
     if not oid:
         raise ConfigError('No matching run entries found for run_uuid {}'.format(self.run_uuid))
     if len(oid) > 1:
         raise ConfigError('Multiple entries found for run_uuid: {}'.format(self.run_uuid))
     return oid[0][0]
Example #10
0
    def load(self, state, raw, source, wrap_exceptions=True):  # pylint: disable=too-many-branches
        logger.debug('Parsing config from "{}"'.format(source))
        log.indent()
        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'
                raise ConfigError(msg)

            if 'id' in raw:
                raise ConfigError('"id" cannot be set globally')

            merge_augmentations(raw)

            # Get WA core configuration
            for cfg_point in state.settings.configuration.values():
                value = pop_aliased_param(cfg_point, raw)
                if value is not None:
                    logger.debug('Setting meta "{}" to "{}"'.format(
                        cfg_point.name, value))
                    state.settings.set(cfg_point.name, value)

            # Get run specific configuration
            for cfg_point in state.run_config.configuration.values():
                value = pop_aliased_param(cfg_point, raw)
                if value is not None:
                    logger.debug('Setting run "{}" to "{}"'.format(
                        cfg_point.name, value))
                    state.run_config.set(cfg_point.name, value)

            # Get global job spec configuration
            for cfg_point in JobSpec.configuration.values():
                value = pop_aliased_param(cfg_point, raw)
                if value is not None:
                    logger.debug('Setting global "{}" to "{}"'.format(
                        cfg_point.name, value))
                    state.jobs_config.set_global_value(cfg_point.name, value)

            for name, values in raw.items():
                # Assume that all leftover config is for a plug-in or a global
                # alias it is up to PluginCache to assert this assumption
                logger.debug('Caching "{}" with "{}"'.format(
                    identifier(name), values))
                state.plugin_cache.add_configs(identifier(name), values,
                                               source)

        except ConfigError as e:
            if wrap_exceptions:
                raise ConfigError('Error in "{}":\n{}'.format(source, str(e)))
            else:
                raise e
        finally:
            log.dedent()
Example #11
0
def _load_file(filepath, error_name):
    if not os.path.isfile(filepath):
        raise ValueError("{} does not exist".format(filepath))
    try:
        raw = read_pod(filepath)
        includes = _process_includes(raw, filepath, error_name)
    except SerializerSyntaxError as e:
        raise ConfigError('Error parsing {} {}: {}'.format(
            error_name, filepath, e))
    if not isinstance(raw, dict):
        message = '{} does not contain a valid {} structure; top level must be a dict.'
        raise ConfigError(message.format(filepath, error_name))
    return raw, includes
Example #12
0
def _collect_valid_id(entry_id, seen_ids, entry_type):
    if entry_id is None:
        return
    entry_id = str(entry_id)
    if entry_id in seen_ids:
        raise ConfigError('Duplicate {} ID "{}".'.format(entry_type, entry_id))
    # "-" is reserved for joining section and workload IDs
    if "-" in entry_id:
        msg = 'Invalid {} ID "{}"; IDs cannot contain a "-"'
        raise ConfigError(msg.format(entry_type, entry_id))
    if entry_id == "global":
        msg = 'Invalid {} ID "global"; is a reserved ID'
        raise ConfigError(msg.format(entry_type))
    seen_ids.add(entry_id)
 def set_runtime_parameters(self, parameters):
     for name, value in parameters.items():
         cfg = self.get_config_for_name(name)
         if cfg is None:
             msg = 'Unsupported runtime parameter: "{}"'
             raise ConfigError(msg.format(name))
         cfg.set_runtime_parameter(name, value)
Example #14
0
 def validate(self):
     super(Youtube, self).validate()
     self.gui.uiauto_params['video_source'] = self.video_source
     self.gui.uiauto_params['search_term'] = self.search_term
     # Make sure search term is set if video source is 'search'
     if (self.video_source == 'search') and not self.search_term:
         raise ConfigError("Param 'search_term' must be specified when video source is 'search'")
Example #15
0
    def initialize(self, context):
        if not self.target.is_rooted and self.as_root:
            raise ConfigError(
                'The target is not rooted, cannot run poller as root.')
        host_poller = context.get_resource(
            Executable(self, self.target.abi, "poller"))
        target_poller = self.target.install(host_poller)

        expanded_paths = []
        for path in self.files:
            if "*" in path:
                for p in self.target.list_directory(path):
                    expanded_paths.append(p)
            else:
                expanded_paths.append(path)
        self.files = expanded_paths
        if not self.labels:
            self.labels = self._generate_labels()

        self.target_output_path = self.target.path.join(
            self.target.working_directory, 'poller.csv')
        self.target_log_path = self.target.path.join(
            self.target.working_directory, 'poller.log')
        marker_option = ''
        if self.align_with_ftrace:
            marker_option = '-m'
            signal.connect(self._adjust_timestamps,
                           signal.AFTER_JOB_OUTPUT_PROCESSED)
        self.command = '{} -t {} {} -l {} {} > {} 2>{}'.format(
            target_poller, self.sample_interval * 1000, marker_option,
            ','.join(self.labels), ' '.join(self.files),
            self.target_output_path, self.target_log_path)
Example #16
0
    def __init__(self, target, **kwargs):
        if target.os == 'chromeos':
            if target.supports_android:
                target = target.android_container
            else:
                raise ConfigError('Target does not appear to support Android')

        super(ApkWorkload, self).__init__(target, **kwargs)

        if self.activity is not None and '.' not in self.activity:
            # If we're receiving just the activity name, it's taken relative to
            # the package namespace:
            self.activity = '.' + self.activity

        self.apk = PackageHandler(self,
                                  package_name=self.package_name,
                                  variant=self.variant,
                                  strict=self.strict,
                                  version=self.version
                                  or self.supported_versions,
                                  force_install=self.force_install,
                                  install_timeout=self.install_timeout,
                                  uninstall=self.uninstall,
                                  exact_abi=self.exact_abi,
                                  prefer_host_package=self.prefer_host_package,
                                  clear_data_on_reset=self.clear_data_on_reset,
                                  activity=self.activity,
                                  min_version=self.min_version,
                                  max_version=self.max_version)
Example #17
0
    def initialize(self, context):
        self.instruments = self.backend.get_instruments(self.target, context.run_output.metadir, **self.params)

        for instrument in self.instruments.values():
            if not (instrument.mode & CONTINUOUS):  # pylint: disable=superfluous-parens
                msg = '{} instrument does not support continuous measurement collection'
                raise ConfigError(msg.format(self.instrument))
            instrument.setup()

        for channel in self.channels or []:
            # Check that the expeccted channels exist.
            # If there are multiple Instruments, they were all constructed with
            # the same channels param, so check them all.
            for instrument in self.instruments.values():
                if not instrument.get_channels(channel):
                    raise ConfigError('No channels found for "{}"'.format(channel))
Example #18
0
    def package_record(self, args):
        if self.target.os != 'android' and self.target.os != 'chromeos':
            raise ConfigError('Target does not appear to be running Android')
        if self.target.os == 'chromeos' and not self.target.supports_android:
            raise ConfigError('Target does not appear to support Android')
        if args.clear:
            self.target.execute('pm clear {}'.format(args.package))
        self.logger.info('Starting {}'.format(args.package))
        cmd = 'monkey -p {} -c android.intent.category.LAUNCHER 1'
        self.target.execute(cmd.format(args.package))

        output_path, file_name = self._split_revent_location(args.output)
        revent_file = self.target.get_workpath(file_name)
        self.record(revent_file, '', output_path)
        msg = 'Recording is available at: \'{}\''
        self.logger.info(msg.format(os.path.join(output_path, file_name)))
Example #19
0
 def validate(self):
     if self.min_version and self.max_version:
         if version_tuple(self.min_version) > version_tuple(
                 self.max_version):
             msg = 'Cannot specify min version ({}) greater than max version ({})'
             raise ConfigError(
                 msg.format(self.min_version, self.max_version))
Example #20
0
    def execute(self, state, args):
        agenda = OrderedDict()
        agenda['config'] = OrderedDict(augmentations=[],
                                       iterations=args.iterations)
        agenda['workloads'] = []
        target_desc = None

        targets = {td.name: td for td in list_target_descriptions()}

        for name in args.plugins:
            if name in targets:
                if target_desc is not None:
                    raise ConfigError(
                        'Specifying multiple devices: {} and {}'.format(
                            target_desc.name, name))
                target_desc = targets[name]
                agenda['config']['device'] = name
                agenda['config'][
                    'device_config'] = target_desc.get_default_config()
                continue

            extcls = pluginloader.get_plugin_class(name)
            config = pluginloader.get_default_config(name)

            # Handle special case for EnergyInstrumentBackends
            if issubclass(extcls, EnergyInstrumentBackend):
                if 'energy_measurement' not in agenda['config'][
                        'augmentations']:
                    energy_config = pluginloader.get_default_config(
                        'energy_measurement')
                    agenda['config']['augmentations'].append(
                        'energy_measurement')
                    agenda['config']['energy_measurement'] = energy_config
                agenda['config']['energy_measurement'][
                    'instrument'] = extcls.name
                agenda['config']['energy_measurement'][
                    'instrument_parameters'] = config
            elif extcls.kind == 'workload':
                entry = OrderedDict()
                entry['name'] = extcls.name
                if name != extcls.name:
                    entry['label'] = name
                entry['params'] = config
                agenda['workloads'].append(entry)
            else:
                if extcls.kind in ('instrument', 'output_processor'):
                    if extcls.name not in agenda['config']['augmentations']:
                        agenda['config']['augmentations'].append(extcls.name)

                if extcls.name not in agenda['config']:
                    agenda['config'][extcls.name] = config

        if args.output:
            wfh = open(args.output, 'w')
        else:
            wfh = sys.stdout
        yaml.dump(agenda, wfh, indent=4, default_flow_style=False)
        if args.output:
            wfh.close()
Example #21
0
 def validate(self, ext):
     ext_params = set(p.name for p in ext.parameters)
     for param in self.params:
         if param not in ext_params:
             # Raising config error because aliases might have come through
             # the config.
             msg = 'Parameter {} (defined in alias {}) is invalid for {}'
             raise ConfigError(msg.format(param, self.name, ext.name))
 def set_param(obj, value, core, parameter):
     '''Method to store passed parameter if it is not already specified for that cpu'''
     cpus = resolve_unique_domain_cpus(core, obj.target)
     for cpu in cpus:
         if parameter in obj.config[cpu]:
             msg = 'Cannot set "{}" for core "{}"; Parameter for CPU{} has already been set'
             raise ConfigError(msg.format(parameter, core, cpu))
         obj.config[cpu][parameter] = value
Example #23
0
def _process_workload_entry(workload, seen_workload_ids, jobs_config):
    workload = _get_workload_entry(workload)
    workload = _construct_valid_entry(workload, seen_workload_ids, "wk",
                                      jobs_config)
    if "workload_name" not in workload:
        raise ConfigError('No workload name specified in entry {}'.format(
            workload['id']))
    return workload
Example #24
0
 def validate(self, obj, check_mandatory=True):
     value = getattr(obj, self.name, None)
     if value is not None:
         self.validate_value(obj.name, value)
     else:
         if check_mandatory and self.mandatory:
             msg = 'No value specified for mandatory parameter "{}" in {}.'
             raise ConfigError(msg.format(self.name, obj.name))
Example #25
0
 def __init__(self, policy):
     if isinstance(policy, RebootPolicy):
         policy = policy.policy
     policy = policy.strip().lower().replace(' ', '_')
     if policy not in self.valid_policies:
         message = 'Invalid reboot policy {}; must be one of {}'.format(policy, ', '.join(self.valid_policies))
         raise ConfigError(message)
     self.policy = policy
Example #26
0
    def _merge_using_priority_specificity(self,
                                          specific_name,
                                          generic_name,
                                          merged_config,
                                          is_final=True):
        """
        WA configuration can come from various sources of increasing priority,
        as well as being specified in a generic and specific manner (e.g
        ``device_config`` and ``nexus10`` respectivly). WA has two rules for
        the priority of configuration:

            - Configuration from higher priority sources overrides
              configuration from lower priority sources.
            - More specific configuration overrides less specific configuration.

        There is a situation where these two rules come into conflict. When a
        generic configuration is given in config source of high priority and a
        specific configuration is given in a config source of lower priority.
        In this situation it is not possible to know the end users intention
        and WA will error.

        :param specific_name: The name of the specific configuration used
                              e.g ``nexus10``
        :param generic_name: The name of the generic configuration
                             e.g ``device_config``
        :param merge_config: A dict of ``ConfigurationPoint``s to be used when
                             merging configuration.  keys=config point name,
                             values=config point
        :param is_final: if ``True`` (the default) make sure that mandatory
                         parameters are set.

        :rtype: A fully merged and validated configuration in the form of a
                obj_dict.
        """
        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

        # 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.
        merged_config.name = specific_name

        for source in sources:
            try:
                update_config_from_source(merged_config, source, ms)
            except ConfigError as e:
                raise ConfigError('Error in "{}":\n\t{}'.format(
                    source, str(e)))

        # Validate final configuration
        merged_config.name = specific_name
        for cfg_point in ms.cfg_points.values():
            cfg_point.validate(merged_config, check_mandatory=is_final)
Example #27
0
    def __init__(self, target, **kwargs):
        if target.os == 'chromeos':
            if target.supports_android:
                target = target.android_container
            else:
                raise ConfigError('Target does not appear to support Android')

        super(UiautoWorkload, self).__init__(target, **kwargs)
        self.gui = UiAutomatorGUI(self)
    def validate_parameters(self):
        '''Method to validate parameters against each other'''
        for cpu in self.config:
            config = self.config[cpu]
            minf = config.get('min_frequency')
            maxf = config.get('max_frequency')
            freq = config.get('frequency')

            if freq and minf:
                msg = 'CPU{}: Can\'t set both cpu frequency and minimum frequency'
                raise ConfigError(msg.format(cpu))
            if freq and maxf:
                msg = 'CPU{}: Can\'t set both cpu frequency and maximum frequency'
                raise ConfigError(msg.format(cpu))

            if (maxf and minf) and self._resolve_freq(minf, cpu) > self._resolve_freq(maxf, cpu):
                msg = 'CPU{}: min_frequency "{}" cannot be greater than max_frequency "{}"'
                raise ConfigError(msg.format(cpu, minf, maxf))
    def set_num_cores(obj, value, core):
        cpus = resolve_cpus(core, obj.target)
        max_cores = len(cpus)
        value = integer(value)
        if value > max_cores:
            msg = 'Cannot set number of {}\'s to {}; max is {}'
            raise ValueError(msg.format(core, value, max_cores))

        msg = 'CPU{} Hotplugging already configured'
        # Set cpus to be enabled
        for cpu in cpus[:value]:
            if cpu in obj.num_cores:
                raise ConfigError(msg.format(cpu))
            obj.num_cores[cpu] = True
        # Set the remaining cpus to be disabled.
        for cpu in cpus[value:]:
            if cpu in obj.num_cores:
                raise ConfigError(msg.format(cpu))
            obj.num_cores[cpu] = False
Example #30
0
 def __init__(self, **kwargs):
     self.logger = logging.getLogger(self.name)
     self._modules = []
     self.capabilities = getattr(self.__class__, 'capabilities', [])
     for param in self.parameters:
         param.set_value(self, kwargs.get(param.name))
     for key in kwargs:
         if key not in self.parameters:
             message = 'Unexpected parameter "{}" for {}'
             raise ConfigError(message.format(key, self.name))