multi, None and validation
authorEmmanuel Garette <egarette@cadoles.com>
Fri, 10 May 2013 20:32:42 +0000 (22:32 +0200)
committerEmmanuel Garette <egarette@cadoles.com>
Fri, 10 May 2013 20:34:07 +0000 (22:34 +0200)
test/test_config_domain.py
test/test_option_consistency.py
tiramisu/option.py
tiramisu/setting.py
tiramisu/value.py

index a491350..da04235 100644 (file)
@@ -10,6 +10,7 @@ def test_domainname():
     e = DomainnameOption('e', '', "toto.com")
     od = OptionDescription('a', '', [d, e])
     c = Config(od)
+    c.read_write()
     c.d = 'toto.com'
     raises(ValueError, "c.d = 'toto'")
     c.d = 'toto3.com'
@@ -25,6 +26,7 @@ def test_domainname_netbios():
     e = DomainnameOption('e', '', "toto", type_='netbios')
     od = OptionDescription('a', '', [d, e])
     c = Config(od)
+    c.read_write()
     raises(ValueError, "c.d = 'toto.com'")
     c.d = 'toto'
     raises(ValueError, "c.d = 'domainnametoolong'")
@@ -35,6 +37,7 @@ def test_domainname_hostname():
     e = DomainnameOption('e', '', "toto", type_='hostname')
     od = OptionDescription('a', '', [d, e])
     c = Config(od)
+    c.read_write()
     raises(ValueError, "c.d = 'toto.com'")
     c.d = 'toto'
     c.d = 'domainnametoolong'
index 23905c4..d273c66 100644 (file)
@@ -1,7 +1,7 @@
 import autopath
 from py.test import raises
 
-from tiramisu.setting import owners
+from tiramisu.setting import owners, groups
 from tiramisu.config import Config
 from tiramisu.option import IPOption, NetworkOption, NetmaskOption, IntOption,\
     OptionDescription
@@ -85,7 +85,13 @@ def test_consistency_network_netmask():
     raises(ValueError, "c.a = '192.168.1.1'")
 
 
-#FIXME pas de multi si pas de multi en maitre
+def test_consistency_ip_netmask_error_multi():
+    a = IPOption('a', '', multi=True)
+    b = NetmaskOption('b', '')
+    od = OptionDescription('od', '', [a, b])
+    raises(ValueError, "b.impl_add_consistency('ip_netmask', a)")
+
+
 def test_consistency_ip_netmask_multi():
     a = IPOption('a', '', multi=True)
     b = NetmaskOption('b', '', multi=True)
@@ -112,3 +118,33 @@ def test_consistency_network_netmask_multi():
     c.a = ['192.168.1.0']
     c.b = ['255.255.255.0']
     raises(ValueError, "c.a = ['192.168.1.1']")
+
+
+def test_consistency_ip_netmask_multi_master():
+    a = IPOption('a', '', multi=True)
+    b = NetmaskOption('b', '', multi=True)
+    od = OptionDescription('a', '', [a, b])
+    od.impl_set_group_type(groups.master)
+    b.impl_add_consistency('ip_netmask', a)
+    c = Config(od)
+    c.a = ['192.168.1.1']
+    c.b = ['255.255.255.0']
+    c.a = ['192.168.1.2']
+    c.b = ['255.255.255.255']
+    c.b = ['255.255.255.0']
+    raises(ValueError, "c.a = ['192.168.1.0']")
+
+
+def test_consistency_network_netmask_multi_master():
+    a = NetworkOption('a', '', multi=True)
+    b = NetmaskOption('b', '', multi=True)
+    od = OptionDescription('a', '', [a, b])
+    od.impl_set_group_type(groups.master)
+    b.impl_add_consistency('network_netmask', a)
+    c = Config(od)
+    c.a = ['192.168.1.1']
+    c.b = ['255.255.255.255']
+    del(c.b)
+    c.a = ['192.168.1.0']
+    c.b = ['255.255.255.0']
+    raises(ValueError, "c.a = ['192.168.1.1']")
index a22f7d7..ad56a75 100644 (file)
@@ -239,6 +239,9 @@ class Option(BaseInformation):
         :param value: the option's value
         :param validate: if true enables ``self._validator`` validation
         """
+        if not validate:
+            return
+
         def _val_validator(val):
             callback_params = deepcopy(self._validator[1])
             callback_params.setdefault('', []).insert(0, val)
@@ -255,32 +258,32 @@ class Option(BaseInformation):
                 return True
             else:
                 return _val_validator(value)
+
         # generic calculation
         if context is not None:
             descr = context.cfgimpl_get_description()
-        if validate:
-            if not self._multi:
-                if value is not None and ((self._validator is not None and
-                                          not val_validator()) or
-                                          not self._validate(value)):
-                    raise ValueError(_("invalid value {0} for option {1}"
-                                       "").format(value, self._name))
+        if not self._multi:
+            if value is not None and ((self._validator is not None and
+                                       not val_validator()) or
+                                      not self._validate(value)):
+                raise ValueError(_("invalid value {0} for option {1}"
+                                   "").format(value, self._name))
+            if context is not None:
+                descr._valid_consistency(self, value, context, None)
+        else:
+            if not isinstance(value, list):
+                raise ValueError(_("invalid value {0} for option {1} "
+                                   "which must be a list").format(value,
+                                                                  self._name))
+            for index in range(0, len(value)):
+                val = value[index]
+                if val is not None and ((self._validator is not None and
+                                         not val_validator()) or
+                                        not self._validate(val)):
+                        raise ValueError(_("invalid value {0} for option {1}"
+                                           "").format(value, self._name))
                 if context is not None:
-                    descr._valid_consistency(self, value, context, None)
-            else:
-                if not isinstance(value, list):
-                    raise ValueError(_("invalid value {0} for option {1} "
-                                       "which must be a list").format(value,
-                                                                      self._name))
-                for index in range(0, len(value)):
-                    val = value[index]
-                    if val is not None and ((self._validator is not None and
-                                             not val_validator()) or
-                                            not self._validate(val)):
-                            raise ValueError(_("invalid value {0} for option {1}"
-                                               "").format(value, self._name))
-                    if context is not None:
-                        descr._valid_consistency(self, val, context, index)
+                    descr._valid_consistency(self, val, context, index)
 
     def impl_getdefault(self, default_multi=False):
         "accessing the default value"
@@ -330,10 +333,12 @@ class Option(BaseInformation):
             raise ValueError('consistency must be set with an option')
         if self is opt:
             raise ValueError('cannot add consistency with itself')
+        if self.impl_is_multi() != opt.impl_is_multi():
+            raise ValueError('options in consistency should be multi in two sides')
         func = '_cons_{}'.format(func)
         self._launch_consistency(func, self, self.impl_getdefault(), None, None, opt)
         self._consistencies.append((func, opt))
-        self.impl_validate(self.impl_getdefault(), None)
+        self.impl_validate(self.impl_getdefault())
 
     def _cons_not_equal(self, optname, value, value_):
         if value == value_:
index 9c3c313..65a98b5 100644 (file)
@@ -178,7 +178,7 @@ class Setting(object):
     def __init__(self, context):
         # properties attribute: the name of a property enables this property
         # key is None for global properties
-        self._properties = {None: set(('expire',))}
+        self._properties = {None: set(('expire', 'validator'))}
         # permissive properties
         self._permissives = {}
         # generic owner
index 24da71a..9367b39 100644 (file)
@@ -46,13 +46,13 @@ class Values(object):
         else:
             return opt.impl_getdefault()
 
-    def _get_value(self, opt):
+    def _get_value(self, opt, validate=True):
         "return value or default value if not set"
         #if no value
         if opt not in self._values:
             value = self._get_default(opt)
             if opt.impl_is_multi():
-                value = Multi(value, self.context, opt)
+                value = Multi(value, self.context, opt, validate)
         else:
             #if value
             value = self._values[opt][1]
@@ -64,7 +64,8 @@ class Values(object):
     def _reset(self, opt):
         if opt in self._values:
             setting = self.context.cfgimpl_get_settings()
-            opt.impl_validate(opt.impl_getdefault(), self.context, 'validator' in setting)
+            opt.impl_validate(opt.impl_getdefault(), self.context,
+                              'validator' in setting)
             self.context.cfgimpl_reset_cache()
             del(self._values[opt])
 
@@ -106,7 +107,7 @@ class Values(object):
     def _getitem(self, opt, validate, force_permissive, force_properties):
         # options with callbacks
         setting = self.context.cfgimpl_get_settings()
-        value = self._get_value(opt)
+        value = self._get_value(opt, validate)
         is_frozen = 'frozen' in setting[opt]
         if opt.impl_has_callback():
             #if value is set and :