add test test_validator_params_value_values_kwargs_empty

This commit is contained in:
Emmanuel Garette 2017-01-26 21:40:08 +01:00
parent 7b0a9891e2
commit 85857ea781
2 changed files with 57 additions and 35 deletions

View File

@ -81,6 +81,10 @@ def value_values_index2(value, values, index, auto=False):
value == 'val2' and values == ['val1', 'val2'] and index == 'val'): value == 'val2' and values == ['val1', 'val2'] and index == 'val'):
raise ValueError('error') raise ValueError('error')
def value_empty(value, empty, values):
if not value == 'val' or empty is not False and not values == ['val']:
raise ValueError('error')
def test_validator(): def test_validator():
opt1 = StrOption('opt1', '', validator=return_true, default='val') opt1 = StrOption('opt1', '', validator=return_true, default='val')
@ -176,6 +180,24 @@ def test_validator_params_value_values_notmulti():
raises(TypeError, "opt1 = StrOption('opt1', '', validator=value_values, default='val')") raises(TypeError, "opt1 = StrOption('opt1', '', validator=value_values, default='val')")
def test_validator_params_value_values_kwargs_empty():
v = BoolOption('v', '', default=False)
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip reseau autorise", multi=True, default=["ip"])
netmask_admin_eth0 = StrOption('netmask_admin_eth0',
"masque du sous-reseau",
multi=True,
validator=value_empty,
validator_params={'': ((v, False),)})
interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
interface1.impl_set_group_type(groups.master)
root = OptionDescription('root', '', [v, interface1])
cfg = Config(root)
assert cfg.ip_admin_eth0.ip_admin_eth0 == ['ip']
cfg.ip_admin_eth0.netmask_admin_eth0[0] = 'val'
#cfg.ip_admin_eth0.ip_admin_eth0.append('val')
#cfg.ip_admin_eth0.netmask_admin_eth0[1] = 'val2'
def test_validator_params_value_values_kwargs(): def test_validator_params_value_values_kwargs():
v = BoolOption('v', '', default=False) v = BoolOption('v', '', default=False)
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip reseau autorise", multi=True, default=["ip"]) ip_admin_eth0 = StrOption('ip_admin_eth0', "ip reseau autorise", multi=True, default=["ip"])

View File

@ -32,7 +32,7 @@ from ..error import (ConfigError, ValueWarning, PropertiesOptionError,
from ..storage import get_storages_option from ..storage import get_storages_option
from . import MasterSlaves from . import MasterSlaves
if sys.version_info[0] >= 3: # pragma: optional cover if sys.version_info[0] >= 3: # pragma: no cover
xrange = range xrange = range
@ -47,49 +47,49 @@ allowed_const_list = ['_cons_not_equal']
def valid_name(name): def valid_name(name):
"an option's name is a str and does not start with 'impl' or 'cfgimpl'" "an option's name is a str and does not start with 'impl' or 'cfgimpl'"
if not isinstance(name, str): # pragma: optional cover if not isinstance(name, str):
return False return False
if re.match(name_regexp, name) is not None and \ if re.match(name_regexp, name) is not None and \
name not in forbidden_names and \ name not in forbidden_names and \
not name.startswith('impl_') and \ not name.startswith('impl_') and \
not name.startswith('cfgimpl_'): not name.startswith('cfgimpl_'):
return True return True
else: # pragma: optional cover else:
return False return False
def validate_callback(callback, callback_params, type_): def validate_callback(callback, callback_params, type_):
if not isinstance(callback, FunctionType): # pragma: optional cover if not isinstance(callback, FunctionType):
raise ValueError(_('{0} must be a function').format(type_)) raise ValueError(_('{0} must be a function').format(type_))
if callback_params is not None: if callback_params is not None:
if not isinstance(callback_params, dict): # pragma: optional cover if not isinstance(callback_params, dict):
raise ValueError(_('{0}_params must be a dict').format(type_)) raise ValueError(_('{0}_params must be a dict').format(type_))
for key, callbacks in callback_params.items(): for key, callbacks in callback_params.items():
if key != '' and len(callbacks) != 1: # pragma: optional cover if key != '' and len(callbacks) != 1:
raise ValueError(_("{0}_params with key {1} mustn't have " raise ValueError(_("{0}_params with key {1} mustn't have "
"length different to 1").format(type_, "length different to 1").format(type_,
key)) key))
if not isinstance(callbacks, tuple): # pragma: optional cover if not isinstance(callbacks, tuple):
raise ValueError(_('{0}_params must be tuple for key "{1}"' raise ValueError(_('{0}_params must be tuple for key "{1}"'
).format(type_, key)) ).format(type_, key))
for callbk in callbacks: for callbk in callbacks:
if isinstance(callbk, tuple): if isinstance(callbk, tuple):
if len(callbk) == 1: if len(callbk) == 1:
if callbk not in ((None,), ('index',)): # pragma: optional cover if callbk not in ((None,), ('index',)):
raise ValueError(_('{0}_params with length of ' raise ValueError(_('{0}_params with length of '
'tuple as 1 must only have ' 'tuple as 1 must only have '
'None as first value')) 'None as first value'))
elif len(callbk) != 2: # pragma: optional cover elif len(callbk) != 2:
raise ValueError(_('{0}_params must only have 1 or 2 ' raise ValueError(_('{0}_params must only have 1 or 2 '
'as length')) 'as length'))
else: else:
option, force_permissive = callbk option, force_permissive = callbk
if not isinstance(option, Option) and not \ if not isinstance(option, Option) and not \
isinstance(option, SymLinkOption): # pragma: optional cover isinstance(option, SymLinkOption):
raise ValueError(_('{}_params must have an option' raise ValueError(_('{}_params must have an option'
' not a {} for first argument' ' not a {} for first argument'
).format(type_, type(option))) ).format(type_, type(option)))
if force_permissive not in [True, False]: # pragma: optional cover if force_permissive not in [True, False]:
raise ValueError(_('{}_params must have a boolean' raise ValueError(_('{}_params must have a boolean'
' not a {} for second argument' ' not a {} for second argument'
).format(type_, type( ).format(type_, type(
@ -106,9 +106,9 @@ class Base(StorageBase):
callback_params=None, validator=None, validator_params=None, callback_params=None, validator=None, validator_params=None,
properties=None, warnings_only=False, extra=None, properties=None, warnings_only=False, extra=None,
allow_empty_list=undefined, session=None): allow_empty_list=undefined, session=None):
if not valid_name(name): # pragma: optional cover if not valid_name(name):
raise ValueError(_("invalid name: {0} for option").format(name)) raise ValueError(_("invalid name: {0} for option").format(name))
if not multi and default_multi is not None: # pragma: optional cover if not multi and default_multi is not None:
raise ValueError(_("default_multi is set whereas multi is False" raise ValueError(_("default_multi is set whereas multi is False"
" in option: {0}").format(name)) " in option: {0}").format(name))
if multi is True: if multi is True:
@ -134,7 +134,7 @@ class Base(StorageBase):
requires = undefined requires = undefined
if properties is None: if properties is None:
properties = tuple() properties = tuple()
if not isinstance(properties, tuple): # pragma: optional cover if not isinstance(properties, tuple):
raise TypeError(_('invalid properties type {0} for {1},' raise TypeError(_('invalid properties type {0} for {1},'
' must be a tuple').format( ' must be a tuple').format(
type(properties), type(properties),
@ -146,7 +146,7 @@ class Base(StorageBase):
validate_callback(validator, validator_params, 'validator') validate_callback(validator, validator_params, 'validator')
self._set_validator(validator, validator_params) self._set_validator(validator, validator_params)
self._set_has_dependency() self._set_has_dependency()
if calc_properties != frozenset([]) and properties is not tuple(): # pragma: optional cover if calc_properties != frozenset([]) and properties is not tuple():
set_forbidden_properties = calc_properties & set(properties) set_forbidden_properties = calc_properties & set(properties)
if set_forbidden_properties != frozenset(): if set_forbidden_properties != frozenset():
raise ValueError('conflict: properties already set in ' raise ValueError('conflict: properties already set in '
@ -207,7 +207,7 @@ class Base(StorageBase):
return getattr(self, '_has_dependency', False) return getattr(self, '_has_dependency', False)
def impl_set_callback(self, callback, callback_params=None, _init=False): def impl_set_callback(self, callback, callback_params=None, _init=False):
if callback is None and callback_params is not None: # pragma: optional cover if callback is None and callback_params is not None:
raise ValueError(_("params defined for a callback function but " raise ValueError(_("params defined for a callback function but "
"no callback defined" "no callback defined"
" yet for option {0}").format( " yet for option {0}").format(
@ -296,7 +296,7 @@ class BaseOption(Base):
""" """
try: try:
self._stated self._stated
except AttributeError: # pragma: optional cover except AttributeError:
raise SystemError(_('cannot serialize Option, ' raise SystemError(_('cannot serialize Option, '
'only in OptionDescription')) 'only in OptionDescription'))
if isinstance(self, SymLinkOption): if isinstance(self, SymLinkOption):
@ -335,7 +335,7 @@ class BaseOption(Base):
getattr(self, func)(descr, load=True) getattr(self, func)(descr, load=True)
try: try:
del(self._stated) del(self._stated)
except AttributeError: # pragma: optional cover except AttributeError:
pass pass
def __setstate__(self, state): def __setstate__(self, state):
@ -377,7 +377,7 @@ class BaseOption(Base):
pass pass
elif name != '_readonly': elif name != '_readonly':
is_readonly = self.impl_is_readonly() is_readonly = self.impl_is_readonly()
if is_readonly: # pragma: optional cover if is_readonly:
raise AttributeError(_("'{0}' ({1}) object attribute '{2}' is" raise AttributeError(_("'{0}' ({1}) object attribute '{2}' is"
" read-only").format( " read-only").format(
self.__class__.__name__, self.__class__.__name__,
@ -646,7 +646,7 @@ class Option(OnlyOption):
err = _is_not_unique(value) err = _is_not_unique(value)
if err: if err:
return err return err
if not isinstance(value, list): # pragma: optional cover if not isinstance(value, list):
return ValueError(_('invalid value "{0}" for "{1}" which' return ValueError(_('invalid value "{0}" for "{1}" which'
' must be a list').format( ' must be a list').format(
value, self.impl_get_display_name())) value, self.impl_get_display_name()))
@ -664,7 +664,7 @@ class Option(OnlyOption):
' in "{}"').format(value, ' in "{}"').format(value,
self.impl_get_display_name())) self.impl_get_display_name()))
return do_validation(value, force_index, force_submulti_index) return do_validation(value, force_index, force_submulti_index)
elif not isinstance(value, list): # pragma: optional cover elif not isinstance(value, list):
return ValueError(_('invalid value "{0}" for "{1}" which ' return ValueError(_('invalid value "{0}" for "{1}" which '
'must be a list').format(value, 'must be a list').format(value,
self.impl_getname())) self.impl_getname()))
@ -673,7 +673,7 @@ class Option(OnlyOption):
err = _is_not_unique(val) err = _is_not_unique(val)
if err: if err:
return err return err
if not isinstance(val, list): # pragma: optional cover if not isinstance(val, list):
return ValueError(_('invalid value "{0}" for "{1}" ' return ValueError(_('invalid value "{0}" for "{1}" '
'which must be a list of list' 'which must be a list of list'
'').format(val, '').format(val,
@ -732,7 +732,7 @@ class Option(OnlyOption):
for opt in other_opts: for opt in other_opts:
if opt.impl_is_submulti(): if opt.impl_is_submulti():
raise ConfigError(_('cannot add consistency with submulti option')) raise ConfigError(_('cannot add consistency with submulti option'))
if not isinstance(opt, Option): # pragma: optional cover if not isinstance(opt, Option):
raise ConfigError(_('consistency must be set with an option')) raise ConfigError(_('consistency must be set with an option'))
if opt._is_subdyn(): if opt._is_subdyn():
if dynod is None: if dynod is None:
@ -745,9 +745,9 @@ class Option(OnlyOption):
elif dynod is not None: elif dynod is not None:
raise ConfigError(_('almost one option in consistency is in a ' raise ConfigError(_('almost one option in consistency is in a '
'dynoptiondescription but not all')) 'dynoptiondescription but not all'))
if self is opt: # pragma: optional cover if self is opt:
raise ConfigError(_('cannot add consistency with itself')) raise ConfigError(_('cannot add consistency with itself'))
if is_multi != opt.impl_is_multi(): # pragma: optional cover if is_multi != opt.impl_is_multi():
raise ConfigError(_('every options in consistency must be ' raise ConfigError(_('every options in consistency must be '
'multi or none')) 'multi or none'))
if init: if init:
@ -764,7 +764,7 @@ class Option(OnlyOption):
:type other_opts: `list` of `tiramisu.option.Option` :type other_opts: `list` of `tiramisu.option.Option`
:param params: extra params (warnings_only and transitive are allowed) :param params: extra params (warnings_only and transitive are allowed)
""" """
if self.impl_is_readonly(): # pragma: optional cover if self.impl_is_readonly():
raise AttributeError(_("'{0}' ({1}) cannot add consistency, option is" raise AttributeError(_("'{0}' ({1}) cannot add consistency, option is"
" read-only").format( " read-only").format(
self.__class__.__name__, self.__class__.__name__,
@ -908,7 +908,7 @@ class Option(OnlyOption):
is_multi = self.impl_is_multi() is_multi = self.impl_is_multi()
default = self.impl_getdefault() default = self.impl_getdefault()
if (not is_multi and (default is not None or default_multi is not None)) or \ if (not is_multi and (default is not None or default_multi is not None)) or \
(is_multi and (default != [] or default_multi is not None)): # pragma: optional cover (is_multi and (default != [] or default_multi is not None)):
raise ValueError(_("default value not allowed if option: {0} " raise ValueError(_("default value not allowed if option: {0} "
"is calculated").format(self.impl_getname())) "is calculated").format(self.impl_getname()))
@ -928,13 +928,13 @@ def validate_requires_arg(multi, requires, name):
# start parsing all requires given by user (has dict) # start parsing all requires given by user (has dict)
# transforme it to a tuple # transforme it to a tuple
for require in requires: for require in requires:
if not isinstance(require, dict): # pragma: optional cover if not isinstance(require, dict):
raise ValueError(_("malformed requirements type for option:" raise ValueError(_("malformed requirements type for option:"
" {0}, must be a dict").format(name)) " {0}, must be a dict").format(name))
valid_keys = ('option', 'expected', 'action', 'inverse', 'transitive', valid_keys = ('option', 'expected', 'action', 'inverse', 'transitive',
'same_action') 'same_action')
unknown_keys = frozenset(require.keys()) - frozenset(valid_keys) unknown_keys = frozenset(require.keys()) - frozenset(valid_keys)
if unknown_keys != frozenset(): # pragma: optional cover if unknown_keys != frozenset():
raise ValueError(_('malformed requirements for option: {0}' raise ValueError(_('malformed requirements for option: {0}'
' unknown keys {1}, must only ' ' unknown keys {1}, must only '
'{2}').format(name, '{2}').format(name,
@ -949,24 +949,24 @@ def validate_requires_arg(multi, requires, name):
option = require['option'] option = require['option']
expected = require['expected'] expected = require['expected']
action = require['action'] action = require['action']
if action == 'force_store_value': # pragma: optional cover if action == 'force_store_value':
raise ValueError(_("malformed requirements for option: {0}" raise ValueError(_("malformed requirements for option: {0}"
" action cannot be force_store_value" " action cannot be force_store_value"
).format(name)) ).format(name))
inverse = require.get('inverse', False) inverse = require.get('inverse', False)
if inverse not in [True, False]: # pragma: optional cover if inverse not in [True, False]:
raise ValueError(_('malformed requirements for option: {0}' raise ValueError(_('malformed requirements for option: {0}'
' inverse must be boolean')) ' inverse must be boolean'))
transitive = require.get('transitive', True) transitive = require.get('transitive', True)
if transitive not in [True, False]: # pragma: optional cover if transitive not in [True, False]:
raise ValueError(_('malformed requirements for option: {0}' raise ValueError(_('malformed requirements for option: {0}'
' transitive must be boolean')) ' transitive must be boolean'))
same_action = require.get('same_action', True) same_action = require.get('same_action', True)
if same_action not in [True, False]: # pragma: optional cover if same_action not in [True, False]:
raise ValueError(_('malformed requirements for option: {0}' raise ValueError(_('malformed requirements for option: {0}'
' same_action must be boolean')) ' same_action must be boolean'))
if not isinstance(option, Option): # pragma: optional cover if not isinstance(option, Option):
raise ValueError(_('malformed requirements ' raise ValueError(_('malformed requirements '
'must be an option in option {0}').format(name)) 'must be an option in option {0}').format(name))
if not multi and option.impl_is_multi(): if not multi and option.impl_is_multi():
@ -1005,7 +1005,7 @@ class SymLinkOption(OnlyOption):
# __slots__ = ('_opt', '_state_opt') # __slots__ = ('_opt', '_state_opt')
def __init__(self, name, opt): def __init__(self, name, opt):
if not isinstance(opt, Option): # pragma: optional cover if not isinstance(opt, Option):
raise ValueError(_('malformed symlinkoption ' raise ValueError(_('malformed symlinkoption '
'must be an option ' 'must be an option '
'for symlink {0}').format(name)) 'for symlink {0}').format(name))