def test_load_yaml_string(): d = ConfigTree() d.update(TEST_YAML_ONE, source='inline_test') assert d.test_section.test_key == 'test_value' assert d.test_section.test_key2 == 'test_value2' assert d.test_section2.test_key == 'test_value3'
def test_load_yaml_file(tmpdir): tmp_file = tmpdir.join('test_file.yaml') tmp_file.write(TEST_YAML_ONE) d = ConfigTree() d.update(str(tmp_file)) assert d.test_section.test_key == 'test_value' assert d.test_section.test_key2 == 'test_value2' assert d.test_section2.test_key == 'test_value3'
def test_update_dict(): d = ConfigTree(layers=['inner', 'outer']) d.update({ 'test_key': 'test_value', 'test_key2': 'test_value2' }, layer='inner') d.update({'test_key': 'test_value3'}, layer='outer') assert d.test_key == 'test_value3' assert d.test_key2 == 'test_value2'
def test_dictionary_style_access(): d = ConfigTree() d.update({'test_key': 'test_value', 'test_key2': 'test_value2'}) assert d['test_key'] == 'test_value' assert d['test_key2'] == 'test_value2' with pytest.raises(DuplicatedConfigurationError): d['test_key2'] = 'test_value3' assert d['test_key2'] == 'test_value2' assert d['test_key'] == 'test_value'
def test_single_layer(): d = ConfigTree() d.update({'test_key': 'test_value', 'test_key2': 'test_value2'}) assert d.test_key == 'test_value' assert d.test_key2 == 'test_value2' with pytest.raises(DuplicatedConfigurationError): d.test_key2 = 'test_value3' assert d.test_key2 == 'test_value2' assert d.test_key == 'test_value'
def test_source_metadata(): d = ConfigTree(layers=['inner', 'outer']) d.update({'test_key': 'test_value'}, layer='inner', source='initial_load') d.update({'test_key': 'test_value2'}, layer='outer', source='update') assert d.metadata('test_key') == [{ 'layer': 'inner', 'source': 'initial_load', 'value': 'test_value' }, { 'layer': 'outer', 'source': 'update', 'value': 'test_value2' }]
def _get_default_specification(): default_config_layers = [ 'base', 'component_configs', 'model_override', 'override' ] default_metadata = {'layer': 'base', 'source': 'vivarium_defaults'} model_specification = ConfigTree(layers=default_config_layers) model_specification.update(DEFAULT_PLUGINS, **default_metadata) model_specification.update({'components': None}) user_config_path = os.path.expanduser('~/vivarium.yaml') if os.path.exists(user_config_path): model_specification.configuration.update(user_config_path, layer='component_configs') return model_specification
def test_freeze(): config = ConfigTree( data={'configuration': { 'time': { 'start': { 'year': 2000 } } }}) config.freeze() with pytest.raises(ConfigurationError): config.update( data={'configuration': { 'time': { 'end': { 'year': 2001 } } }})
def test_retrieval_behavior(): layer_inner = 'inner' layer_middle = 'middle' layer_outer = 'outer' default_cfg_value = 'value_a' layer_list = [layer_inner, layer_middle, layer_outer] # update the ConfigTree layers in different order and verify that has no effect on # the values retrieved ("outer" is retrieved when no layer is specified regardless of # the initialization order for scenario in [layer_list, reversed(layer_list)]: cfg = ConfigTree(layers=layer_list) for layer in scenario: cfg.update({default_cfg_value: layer}, layer=layer) assert cfg.get_from_layer(default_cfg_value) == layer_outer assert cfg.get_from_layer(default_cfg_value, layer=layer_outer) == layer_outer assert cfg.get_from_layer(default_cfg_value, layer=layer_middle) == layer_middle assert cfg.get_from_layer(default_cfg_value, layer=layer_inner) == layer_inner
def test_repr_display(): expected_repr = '''\ Key1: override_2: value_ov_2 source: ov2_src override_1: value_ov_1 source: ov1_src base: value_base source: base_src''' # codifies the notion that repr() displays values from most to least overridden # regardless of initialization order layers = ['base', 'override_1', 'override_2'] cfg = ConfigTree(layers=layers) cfg.update({'Key1': 'value_ov_2'}, layer='override_2', source='ov2_src') cfg.update({'Key1': 'value_ov_1'}, layer='override_1', source='ov1_src') cfg.update({'Key1': 'value_base'}, layer='base', source='base_src') assert repr(cfg) == textwrap.dedent(expected_repr) cfg = ConfigTree(layers=layers) cfg.update({'Key1': 'value_base'}, layer='base', source='base_src') cfg.update({'Key1': 'value_ov_1'}, layer='override_1', source='ov1_src') cfg.update({'Key1': 'value_ov_2'}, layer='override_2', source='ov2_src') assert repr(cfg) == textwrap.dedent(expected_repr)
def test_update_dict_nested(): d = ConfigTree(layers=['inner', 'outer']) d.update( { 'test_container': { 'test_key': 'test_value', 'test_key2': 'test_value2' } }, layer='inner') with pytest.raises(DuplicatedConfigurationError): d.update({'test_container': { 'test_key': 'test_value3' }}, layer='inner') assert d.test_container.test_key == 'test_value' assert d.test_container.test_key2 == 'test_value2' d.update({'test_container': {'test_key2': 'test_value4'}}, layer='outer') assert d.test_container.test_key2 == 'test_value4'
def test_exception_on_source_for_missing_key(): d = ConfigTree(layers=['inner', 'outer']) d.update({'test_key': 'test_value'}, layer='inner', source='initial_load') with pytest.raises(ConfigurationKeyError): d.metadata('missing_key')
class PluginManager: def __init__(self, plugin_configuration=None): self._plugin_configuration = ConfigTree(DEFAULT_PLUGINS['plugins'], layers=['base', 'override']) self._plugin_configuration.update(plugin_configuration, source='initialization_args') self._plugins = {} def get_plugin(self, name): if name not in self._plugins: self._plugins[name] = self._get(name) return self._plugins[name]['controller'] def get_plugin_interface(self, name): if name not in self._plugins: self._plugins[name] = self._get(name) return self._plugins[name]['builder_interface'] def get_core_controllers(self): core_components = [ name for name in self._plugin_configuration['required'].keys() ] + list(_MANAGERS.keys()) return {name: self.get_plugin(name) for name in core_components} def get_core_interfaces(self): core_components = [ name for name in self._plugin_configuration['required'].keys() ] + list(_MANAGERS.keys()) return { name: self.get_plugin_interface(name) for name in core_components } def get_optional_controllers(self): return { name: self.get_plugin(name) for name in self._plugin_configuration['optional'].keys() } def get_optional_interfaces(self): return { name: self.get_plugin_interface(name) for name in self._plugin_configuration['optional'].keys() } def _get(self, name): if name not in self._plugins: self._plugins[name] = self._build_plugin(name) return self._plugins[name] def _build_plugin(self, name): plugin = self._lookup(name) try: controller = import_by_path(plugin['controller'])() except ValueError: raise PluginConfigurationError( f'Invalid plugin specification {plugin["controller"]}') if plugin['builder_interface'] is not None: try: interface = import_by_path( plugin['builder_interface'])(controller) except ValueError: raise PluginConfigurationError( f'Invalid plugin specification {plugin["builder_interface"]}' ) else: interface = None return {'controller': controller, 'builder_interface': interface} def _lookup(self, name): if name in self._plugin_configuration['required']: return self._plugin_configuration['required'][name] elif name in self._plugin_configuration['optional']: return self._plugin_configuration['optional'][name] elif name in _MANAGERS: return _MANAGERS[name] else: raise PluginConfigurationError(f'Plugin {name} not found.') def __repr__(self): return "PluginManager()"