diff --git a/ChangeLog b/ChangeLog index 351b288..a8d7602 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +Sun Oct 26 08:50:38 2014 +0200 Emmanuel Garette + * if option is frozen with force_default_on_freeze property, owner + must be 'default' check property when tried to change owner + Sat Oct 25 22:48:08 2014 +0200 Emmanuel Garette * cannot add unvalaible consistency for an option * allow number as first letter of a domainname with netbios type diff --git a/test/test_freeze.py b/test/test_freeze.py index 4f47d16..9b0f71e 100644 --- a/test/test_freeze.py +++ b/test/test_freeze.py @@ -2,6 +2,7 @@ "frozen and hidden values" import autopath +from tiramisu.setting import owners from tiramisu.option import ChoiceOption, BoolOption, IntOption, FloatOption, \ StrOption, OptionDescription from tiramisu.config import Config @@ -52,6 +53,14 @@ def test_freeze_whole_config(): setting.remove('everything_frozen') conf.gc.dummy = True assert conf.gc.dummy is True + setting.append('everything_frozen') + owners.addowner("everythingfrozen") + prop = [] + try: + conf.cfgimpl_get_values().setowner(descr.gc.dummy, owners.everythingfrozen) + except PropertiesOptionError as err: + prop = err.proptype + assert 'frozen' in prop def test_freeze_one_option(): diff --git a/test/test_option_default.py b/test/test_option_default.py index b24d3f1..3eda6e4 100644 --- a/test/test_option_default.py +++ b/test/test_option_default.py @@ -1,7 +1,10 @@ "test all types of option default values for options, add new option in a descr" import autopath +from py.test import raises from tiramisu.config import Config +from tiramisu.setting import owners +from tiramisu.error import PropertiesOptionError, ConfigError from tiramisu.option import IntOption, FloatOption, StrOption, ChoiceOption, \ BoolOption, OptionDescription @@ -59,13 +62,21 @@ def test_force_default_on_freeze(): dummy2 = BoolOption('dummy2', 'doc dummy', default=True) group = OptionDescription('group', '', [dummy1, dummy2]) config = Config(group) + config.read_write() + owners.addowner("frozen") config.dummy1 = True config.dummy2 = False + assert config.getowner(dummy1) == owners.user + assert config.getowner(dummy2) == owners.user setting = config.cfgimpl_get_settings() setting[dummy1].append('frozen') setting[dummy2].append('frozen') assert config.dummy1 is False assert config.dummy2 is False + assert config.getowner(dummy1) == owners.default + assert config.getowner(dummy2) == owners.user + raises(ConfigError, "config.cfgimpl_get_values().setowner(dummy1, owners.frozen)") + raises(PropertiesOptionError, "config.cfgimpl_get_values().setowner(dummy2, owners.frozen)") def test_force_default_on_freeze_multi(): @@ -73,13 +84,21 @@ def test_force_default_on_freeze_multi(): dummy2 = BoolOption('dummy2', 'doc dummy', default=[True], multi=True) group = OptionDescription('group', '', [dummy1, dummy2]) config = Config(group) + config.read_write() + owners.addowner("frozenmulti") config.dummy1.append(True) config.dummy2.append(False) + assert config.getowner(dummy1) == owners.user + assert config.getowner(dummy2) == owners.user setting = config.cfgimpl_get_settings() setting[dummy1].append('frozen') setting[dummy2].append('frozen') assert config.dummy1 == [False] assert config.dummy2 == [True, False] + assert config.getowner(dummy1) == owners.default + assert config.getowner(dummy2) == owners.user + raises(ConfigError, "config.cfgimpl_get_values().setowner(dummy1, owners.frozenmulti)") + raises(PropertiesOptionError, "config.cfgimpl_get_values().setowner(dummy2, owners.frozenmulti)") def test_overrides_changes_option_value(): diff --git a/test/test_option_owner.py b/test/test_option_owner.py index 1880bc4..4b8fdb0 100644 --- a/test/test_option_owner.py +++ b/test/test_option_owner.py @@ -4,7 +4,7 @@ from py.test import raises from tiramisu.setting import owners from tiramisu.config import Config from tiramisu.option import ChoiceOption, BoolOption, IntOption, FloatOption, \ - StrOption, OptionDescription + StrOption, OptionDescription, SymLinkOption from tiramisu.error import ConfigError, ConstError, PropertiesOptionError @@ -106,3 +106,40 @@ def test_setowner_for_value(): cfg.cfgimpl_get_values().setowner(gcdummy, owners.new) assert cfg.getowner(gcdummy) == owners.new raises(TypeError, "cfg.cfgimpl_get_values().setowner(gcdummy, 'new')") + + +def test_setowner_read_only(): + gcdummy = BoolOption('dummy', 'dummy', default=False) + descr = OptionDescription('tiramisu', '', [gcdummy]) + cfg = Config(descr) + cfg.read_write() + assert cfg.dummy is False + assert cfg.getowner(gcdummy) == 'default' + owners.addowner("readonly") + cfg.dummy = False + assert cfg.getowner(gcdummy) == owners.user + cfg.read_only() + raises(PropertiesOptionError, + "cfg.cfgimpl_get_values().setowner(gcdummy, owners.readonly)") + assert cfg.getowner(gcdummy) == owners.user + + +def test_setowner_optiondescription(): + gcdummy = BoolOption('dummy', 'dummy', default=False) + descr1 = OptionDescription('tiramisu', '', [gcdummy]) + descr = OptionDescription('tiramisu', '', [descr1]) + cfg = Config(descr) + raises(ConfigError, 'cfg.cfgimpl_get_values().getowner(descr1)') + raises(ConfigError, 'cfg.cfgimpl_get_values().setowner(descr1, owners.user)') + + +def test_setowner_symlinkoption(): + gcdummy = BoolOption('dummy', 'dummy', default=False) + s = SymLinkOption('symdummy', gcdummy) + descr1 = OptionDescription('tiramisu', '', [gcdummy, s]) + descr = OptionDescription('tiramisu', '', [descr1]) + cfg = Config(descr) + assert cfg.cfgimpl_get_values().getowner(s) == owners.default + cfg.tiramisu.dummy = True + assert cfg.cfgimpl_get_values().getowner(s) == owners.user + raises(ConfigError, 'cfg.cfgimpl_get_values().setowner(s, owners.user)') diff --git a/tiramisu/value.py b/tiramisu/value.py index a6e30be..ef11389 100644 --- a/tiramisu/value.py +++ b/tiramisu/value.py @@ -22,7 +22,7 @@ from tiramisu.error import ConfigError, SlaveError, PropertiesOptionError from tiramisu.setting import owners, expires_time, undefined from tiramisu.autolib import carry_out_calculation from tiramisu.i18n import _ -from tiramisu.option import SymLinkOption, DynSymLinkOption +from tiramisu.option import SymLinkOption, DynSymLinkOption, Option class Values(object): @@ -350,11 +350,18 @@ class Values(object): def _getowner(self, opt, path, validate_properties=True, force_permissive=False, validate_meta=True): + if not isinstance(opt, Option) and not isinstance(opt, DynSymLinkOption): + raise ConfigError(_('owner only avalaible for an option')) + context = self._getcontext() + setting = context.cfgimpl_get_settings() + if 'frozen' in setting[opt] and \ + 'force_default_on_freeze' in setting[opt]: + return owners.default if validate_properties: self._getitem(opt, path, True, force_permissive, None, True) owner = self._p_.getowner(path, owners.default) if validate_meta: - meta = self._getcontext().cfgimpl_get_meta() + meta = context.cfgimpl_get_meta() if owner is owners.default and meta is not None: owner = meta.cfgimpl_get_values()._getowner(opt, path) return owner @@ -376,6 +383,11 @@ class Values(object): if self._getowner(opt, path) == owners.default: # pragma: optional cover raise ConfigError(_('no value for {0} cannot change owner to {1}' '').format(path, owner)) + self._getcontext().cfgimpl_get_settings().validate_properties(opt, + False, + True, + path) + self._p_.setowner(path, owner) def is_default_owner(self, opt, validate_properties=True,