error if change slave len for default's slave option
authorEmmanuel Garette <egarette@cadoles.com>
Thu, 19 Sep 2013 21:02:15 +0000 (23:02 +0200)
committerEmmanuel Garette <egarette@cadoles.com>
Thu, 19 Sep 2013 21:02:15 +0000 (23:02 +0200)
test/test_parsing_group.py
tiramisu/value.py

index 7b9dffe..7ecd860 100644 (file)
@@ -64,9 +64,9 @@ def test_make_dict_filter():
     config = Config(descr)
     config.read_write()
     subresult = {'numero_etab': None, 'nombre_interfaces': 1,
-              'serveur_ntp': [], 'mode_conteneur_actif': False,
-              'time_zone': 'Paris', 'nom_machine': 'eoleng',
-              'activer_proxy_client': False}
+                 'serveur_ntp': [], 'mode_conteneur_actif': False,
+                 'time_zone': 'Paris', 'nom_machine': 'eoleng',
+                 'activer_proxy_client': False}
     result = {}
     for key, value in subresult.items():
         result['general.' + key] = value
@@ -114,7 +114,6 @@ def test_iter_not_group():
     raises(TypeError, "list(config.iter_groups(group_type='family'))")
 
 
-
 def test_groups_with_master():
     ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
     netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True)
@@ -252,6 +251,22 @@ def test_values_with_master_and_slaves_master():
     assert cfg.ip_admin_eth0.netmask_admin_eth0 == []
 
 
+def test_values_with_master_and_slaves_master_error():
+    ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
+    netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True)
+    interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
+    interface1.impl_set_group_type(groups.master)
+    maconfig = OptionDescription('toto', '', [interface1])
+    cfg = Config(maconfig)
+    cfg.read_write()
+    cfg.ip_admin_eth0.ip_admin_eth0 = ["192.168.230.145", "192.168.230.145"]
+    raises(SlaveError, "cfg.ip_admin_eth0.netmask_admin_eth0 = ['255.255.255.0']")
+    raises(SlaveError, "cfg.ip_admin_eth0.netmask_admin_eth0 = ['255.255.255.0', '255.255.255.0', '255.255.255.0']")
+    cfg.ip_admin_eth0.netmask_admin_eth0 = ['255.255.255.0', '255.255.255.0']
+    raises(SlaveError, "cfg.ip_admin_eth0.netmask_admin_eth0 = ['255.255.255.0']")
+    raises(SlaveError, "cfg.ip_admin_eth0.netmask_admin_eth0 = ['255.255.255.0', '255.255.255.0', '255.255.255.0']")
+
+
 def test_values_with_master_owner():
     ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
     netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True)
index b600eb8..c6f0e76 100644 (file)
@@ -251,7 +251,7 @@ class Values(object):
         opt.impl_validate(value, self.context(),
                           'validator' in self.context().cfgimpl_get_settings())
         if opt.impl_is_multi() and not isinstance(value, Multi):
-            value = Multi(value, self.context, opt, path)
+            value = Multi(value, self.context, opt, path, setitem=True)
         self._setvalue(opt, path, value, force_permissive=force_permissive,
                        is_write=is_write)
 
@@ -369,11 +369,13 @@ class Multi(list):
     that support item notation for the values of multi options"""
     __slots__ = ('opt', 'path', 'context')
 
-    def __init__(self, value, context, opt, path, validate=True):
+    def __init__(self, value, context, opt, path, validate=True,
+                 setitem=False):
         """
         :param value: the Multi wraps a list value
         :param context: the home config that has the values
         :param opt: the option object that have this Multi value
+        :param setitem: only if set a value
         """
         self.opt = opt
         self.path = path
@@ -383,12 +385,12 @@ class Multi(list):
         if not isinstance(value, list):
             value = [value]
         if validate and self.opt.impl_get_multitype() == multitypes.slave:
-            value = self._valid_slave(value)
+            value = self._valid_slave(value, setitem)
         elif self.opt.impl_get_multitype() == multitypes.master:
             self._valid_master(value)
         super(Multi, self).__init__(value)
 
-    def _valid_slave(self, value):
+    def _valid_slave(self, value, setitem):
         #if slave, had values until master's one
         values = self.context().cfgimpl_get_values()
         masterp = self.context().cfgimpl_get_description().impl_get_path_by_opt(
@@ -396,8 +398,9 @@ class Multi(list):
         mastervalue = getattr(self.context(), masterp)
         masterlen = len(mastervalue)
         valuelen = len(value)
+        is_default_owner = not values._is_default_owner(self.path) or setitem
         if valuelen > masterlen or (valuelen < masterlen and
-                                    not values._is_default_owner(self.path)):
+                                    is_default_owner):
             raise SlaveError(_("invalid len for the slave: {0}"
                                " which has {1} as master").format(
                                    self.opt._name, masterp))