can mix inversed and non inversed requires

This commit is contained in:
Emmanuel Garette 2017-01-12 19:52:03 +01:00
parent 18d6976183
commit 01b7fc873e
3 changed files with 46 additions and 19 deletions

View file

@ -1,3 +1,6 @@
Thu Jan 12 19:49:41 2017 +0200 Emmanuel Garette <egarette@cadoles.com>
* can mix inversed and non inversed requires
Wed Jan 11 22:56:30 2017 +0200 Emmanuel Garette <egarette@cadoles.com> Wed Jan 11 22:56:30 2017 +0200 Emmanuel Garette <egarette@cadoles.com>
* copy the context in carry_out_calculation * copy the context in carry_out_calculation

View file

@ -595,8 +595,35 @@ def test_requires_requirement_append():
def test_requires_different_inverse(): def test_requires_different_inverse():
a = BoolOption('activate_service', '', True) a = BoolOption('activate_service', '', True)
a b = IPOption('ip_address_service', '', requires=[
raises(ValueError, "IPOption('ip_address_service', '', requires=[{'option': a, 'expected': True, 'action': 'disabled', 'inverse': True}, {'option': a, 'expected': True, 'action': 'disabled', 'inverse': False}])") {'option': a, 'expected': True, 'action': 'disabled', 'inverse': True},
{'option': a, 'expected': True, 'action': 'disabled', 'inverse': False}])
od = OptionDescription('service', '', [a, b])
c = Config(od)
c.read_write()
raises(PropertiesOptionError, 'c.ip_address_service')
c.activate_service = False
raises(PropertiesOptionError, 'c.ip_address_service')
def test_requires_different_inverse_unicode():
a = BoolOption('activate_service', '', True)
d = StrOption('activate_other_service', '', 'val2')
b = IPOption('ip_address_service', '', requires=[
{'option': a, 'expected': True, 'action': 'disabled', 'inverse': True},
{'option': d, 'expected': 'val1', 'action': 'disabled', 'inverse': False}])
od = OptionDescription('service', '', [a, d, b])
c = Config(od)
c.read_write()
assert c.ip_address_service == None
c.activate_service = False
raises(PropertiesOptionError, 'c.ip_address_service')
c.activate_service = True
assert c.ip_address_service == None
c.activate_other_service = 'val1'
raises(PropertiesOptionError, 'c.ip_address_service')
c.activate_service = False
raises(PropertiesOptionError, 'c.ip_address_service')
def test_requires_recursive_path(): def test_requires_recursive_path():

View file

@ -27,7 +27,7 @@ from ..i18n import _
from ..setting import log, undefined, debug from ..setting import log, undefined, debug
from ..autolib import carry_out_calculation from ..autolib import carry_out_calculation
from ..error import (ConfigError, ValueWarning, PropertiesOptionError, from ..error import (ConfigError, ValueWarning, PropertiesOptionError,
display_list) display_list)
from ..storage import get_storages_option from ..storage import get_storages_option
from . import MasterSlaves from . import MasterSlaves
@ -885,7 +885,7 @@ def validate_requires_arg(multi, requires, name):
the description of the requires dictionary the description of the requires dictionary
""" """
ret_requires = {} ret_requires = {}
config_action = {} config_action = set()
# 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
@ -938,32 +938,29 @@ def validate_requires_arg(multi, requires, name):
if expected is not None: if expected is not None:
err = option._validate(expected) err = option._validate(expected)
if err: if err:
raise ValueError(_('malformed requirements second argument ' raise ValueError(_('malformed requirements expected value '
'must be valid for option {0}' 'must be valid for option {0}'
': {1}').format(name, err)) ': {1}').format(name, err))
if action in config_action: config_action.add(action)
if inverse != config_action[action]: # pragma: optional cover
raise ValueError(_("inconsistency in action types"
" for option: {0}"
" action: {1}").format(name, action))
else:
config_action[action] = inverse
if action not in ret_requires: if action not in ret_requires:
ret_requires[action] = {} ret_requires[action] = {}
if option not in ret_requires[action]: if option not in ret_requires[action]:
ret_requires[action][option] = (option, [expected], action, ret_requires[action][option] = {}
inverse, transitive, same_action) if inverse not in ret_requires[action][option]:
ret_requires[action][option][inverse] = (option, [expected], action,
inverse, transitive, same_action)
else: else:
ret_requires[action][option][1].append(expected) ret_requires[action][option][inverse][1].append(expected)
# transform dict to tuple # transform dict to tuple
ret = [] ret = []
for opt_requires in ret_requires.values(): for opt_requires in ret_requires.values():
ret_action = [] ret_action = []
for require in opt_requires.values(): for requires in opt_requires.values():
ret_action.append((require[0], tuple(require[1]), require[2], for require in requires.values():
require[3], require[4], require[5])) ret_action.append((require[0], tuple(require[1]), require[2],
require[3], require[4], require[5]))
ret.append(tuple(ret_action)) ret.append(tuple(ret_action))
return frozenset(config_action.keys()), tuple(ret) return frozenset(config_action), tuple(ret)
class SymLinkOption(OnlyOption): class SymLinkOption(OnlyOption):