1
0
mirror of https://github.com/ARM-software/workload-automation.git synced 2025-02-21 20:38:57 +00:00

framework/configruation: fix mandatory workload parameters

PluginCache.get_plugin_config assumes that no more configuration is to
be processed, and therefore config is final. As such, it is validating
that mandatory parameters are set. This assumption is invalid for
workload_parameters, however, as those need to be resolved on per-spec
basis, and cannot be globally cached.

This commit adds a prameter for get_plugin_config that indicates whether
or not it should consider the config to be final.
This commit is contained in:
Sergei Trofimov 2017-09-19 15:56:12 +01:00
parent aec89a077e
commit c96181bed7
2 changed files with 19 additions and 15 deletions

View File

@ -272,12 +272,12 @@ class ConfigurationPoint(object):
value = merge_config_values(getattr(obj, self.name), value) value = merge_config_values(getattr(obj, self.name), value)
setattr(obj, self.name, value) setattr(obj, self.name, value)
def validate(self, obj): def validate(self, obj, check_mandatory=True):
value = getattr(obj, self.name, None) value = getattr(obj, self.name, None)
if value is not None: if value is not None:
self.validate_value(obj.name, value) self.validate_value(obj.name, value)
else: else:
if self.mandatory: if check_mandatory and self.mandatory:
msg = 'No value specified for mandatory parameter "{}" in {}.' msg = 'No value specified for mandatory parameter "{}" in {}.'
raise ConfigError(msg.format(self.name, obj.name)) raise ConfigError(msg.format(self.name, obj.name))
@ -928,7 +928,8 @@ class JobSpec(Configuration):
def merge_workload_parameters(self, plugin_cache): def merge_workload_parameters(self, plugin_cache):
# merge global generic and specific config # merge global generic and specific config
workload_params = plugin_cache.get_plugin_config(self.workload_name, workload_params = plugin_cache.get_plugin_config(self.workload_name,
generic_name="workload_parameters") generic_name="workload_parameters",
is_final=False)
cfg_points = plugin_cache.get_plugin_parameters(self.workload_name) cfg_points = plugin_cache.get_plugin_parameters(self.workload_name)
for source in self._sources: for source in self._sources:

View File

@ -99,7 +99,7 @@ class PluginCache(object):
def list_plugins(self, kind=None): def list_plugins(self, kind=None):
return self.loader.list_plugins(kind) return self.loader.list_plugins(kind)
def get_plugin_config(self, plugin_name, generic_name=None): def get_plugin_config(self, plugin_name, generic_name=None, is_final=True):
config = obj_dict(not_in_dict=['name']) config = obj_dict(not_in_dict=['name'])
config.name = plugin_name config.name = plugin_name
@ -120,7 +120,8 @@ class PluginCache(object):
else: else:
# A more complicated merge that involves priority of sources and # A more complicated merge that involves priority of sources and
# specificity # specificity
self._merge_using_priority_specificity(plugin_name, generic_name, config) self._merge_using_priority_specificity(plugin_name, generic_name,
config, is_final)
return config return config
@ -158,7 +159,7 @@ class PluginCache(object):
# pylint: disable=too-many-nested-blocks, too-many-branches # pylint: disable=too-many-nested-blocks, too-many-branches
def _merge_using_priority_specificity(self, specific_name, def _merge_using_priority_specificity(self, specific_name,
generic_name, final_config): generic_name, merged_config, is_final=True):
""" """
WA configuration can come from various sources of increasing priority, WA configuration can come from various sources of increasing priority,
as well as being specified in a generic and specific manner (e.g as well as being specified in a generic and specific manner (e.g
@ -175,13 +176,15 @@ class PluginCache(object):
In this situation it is not possible to know the end users intention In this situation it is not possible to know the end users intention
and WA will error. and WA will error.
:param generic_name: The name of the generic configuration
e.g ``device_config``
:param specific_name: The name of the specific configuration used :param specific_name: The name of the specific configuration used
e.g ``nexus10`` e.g ``nexus10``
:param cfg_point: A dict of ``ConfigurationPoint``s to be used when :param generic_name: The name of the generic configuration
merging configuration. keys=config point name, e.g ``device_config``
values=config point :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 :rtype: A fully merged and validated configuration in the form of a
obj_dict. obj_dict.
@ -197,18 +200,18 @@ class PluginCache(object):
# set_value uses the 'name' attribute of the passed object in it error # 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 # messages, to ensure these messages make sense the name will have to be
# changed several times during this function. # changed several times during this function.
final_config.name = specific_name merged_config.name = specific_name
for source in sources: for source in sources:
try: try:
update_config_from_source(final_config, source, ms) update_config_from_source(merged_config, source, ms)
except ConfigError as e: except ConfigError as e:
raise ConfigError('Error in "{}":\n\t{}'.format(source, str(e))) raise ConfigError('Error in "{}":\n\t{}'.format(source, str(e)))
# Validate final configuration # Validate final configuration
final_config.name = specific_name merged_config.name = specific_name
for cfg_point in ms.cfg_points.itervalues(): for cfg_point in ms.cfg_points.itervalues():
cfg_point.validate(final_config) cfg_point.validate(merged_config, check_mandatory=is_final)
class MergeState(object): class MergeState(object):