From f4bf3dc3904f6dc6e8d4f0528b95298465d8552f Mon Sep 17 00:00:00 2001 From: Emmanuel Garette Date: Wed, 31 Oct 2018 08:00:19 +0100 Subject: [PATCH] add PathConfig --- test/test_cache.py | 8 +- test/test_choice_option.py | 5 + test/test_config.py | 5 + test/test_config_api.py | 5 + test/test_config_domain.py | 5 + test/test_config_ip.py | 5 + test/test_dereference.py | 7 +- test/test_duplicate_config.py | 7 +- test/test_dyn_optiondescription.py | 6 +- test/test_freeze.py | 5 + test/test_mandatory.py | 5 + test/test_masterslaves.py | 20 +- test/test_metaconfig.py | 54 +- test/test_option.py | 33 +- test/test_option_callback.py | 12 +- test/test_option_consistency.py | 5 + test/test_option_default.py | 5 + test/test_option_owner.py | 5 + test/test_option_setting.py | 89 +-- test/test_option_type.py | 5 + test/test_option_username.py | 6 + test/test_option_validator.py | 5 + test/test_option_with_special_name.py | 5 + test/test_pathconfig.py | 966 ++++++++++++++++++++++++++ test/test_permissive.py | 5 + test/test_requires.py | 20 +- test/test_slots.py | 20 + test/test_state.py | 5 + test/test_storage.py | 20 +- test/test_submulti.py | 4 + test/test_symlink.py | 22 +- tiramisu/__init__.py | 3 +- tiramisu/api.py | 170 +++-- tiramisu/autolib.py | 1 + tiramisu/config.py | 188 +++-- tiramisu/option/choiceoption.py | 2 +- tiramisu/storage/__init__.py | 5 +- 37 files changed, 1480 insertions(+), 258 deletions(-) create mode 100644 test/test_pathconfig.py diff --git a/test/test_cache.py b/test/test_cache.py index 0507e07..a821a89 100644 --- a/test/test_cache.py +++ b/test/test_cache.py @@ -1,4 +1,7 @@ # coding: utf-8 + +from time import sleep, time +from py.test import raises from .autopath import do_autopath do_autopath() @@ -11,10 +14,11 @@ from tiramisu.error import ConfigError, PropertiesOptionError from tiramisu.setting import groups from tiramisu import undefined, Params, ParamValue, ParamOption from tiramisu.api import TIRAMISU_VERSION +from tiramisu.storage import list_sessions -from time import sleep, time -from py.test import raises +def teardown_function(function): + assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__) global incr diff --git a/test/test_choice_option.py b/test/test_choice_option.py index 86fa792..3bf51ed 100644 --- a/test/test_choice_option.py +++ b/test/test_choice_option.py @@ -10,6 +10,11 @@ from tiramisu import Config from tiramisu.error import ConfigError from tiramisu import undefined, Params, ParamValue, ParamOption from tiramisu.api import TIRAMISU_VERSION +from tiramisu.storage import list_sessions + + +def teardown_function(function): + assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__) def return_val(val): diff --git a/test/test_config.py b/test/test_config.py index d67e8c4..e3393df 100644 --- a/test/test_config.py +++ b/test/test_config.py @@ -14,6 +14,11 @@ from tiramisu.i18n import _ from tiramisu import Config, IntOption, FloatOption, StrOption, ChoiceOption, \ BoolOption, UnicodeOption, OptionDescription, undefined from tiramisu.error import ConflictError, ConfigError, PropertiesOptionError, APIError +from tiramisu.storage import list_sessions + + +def teardown_function(function): + assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__) def make_description(): diff --git a/test/test_config_api.py b/test/test_config_api.py index bbf622d..9dbf9ab 100644 --- a/test/test_config_api.py +++ b/test/test_config_api.py @@ -9,6 +9,11 @@ from tiramisu import Config, IntOption, FloatOption, StrOption, ChoiceOption, \ PortOption, NetworkOption, NetmaskOption, BroadcastOption, \ DomainnameOption, OptionDescription from tiramisu.error import PropertiesOptionError +from tiramisu.storage import list_sessions + + +def teardown_function(function): + assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__) def make_description(): diff --git a/test/test_config_domain.py b/test/test_config_domain.py index b9a98e1..4de4438 100644 --- a/test/test_config_domain.py +++ b/test/test_config_domain.py @@ -8,6 +8,11 @@ from tiramisu import Config from tiramisu.option import DomainnameOption, EmailOption, URLOption, OptionDescription from tiramisu.error import ValueWarning from tiramisu.i18n import _ +from tiramisu.storage import list_sessions + + +def teardown_function(function): + assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__) def test_domainname(): diff --git a/test/test_config_ip.py b/test/test_config_ip.py index 6b8bc59..049c2ec 100644 --- a/test/test_config_ip.py +++ b/test/test_config_ip.py @@ -6,6 +6,11 @@ from py.test import raises from tiramisu import Config ,IPOption, NetworkOption, NetmaskOption, \ PortOption, BroadcastOption, OptionDescription from tiramisu.error import ValueWarning +from tiramisu.storage import list_sessions + + +def teardown_function(function): + assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__) def test_ip(): diff --git a/test/test_dereference.py b/test/test_dereference.py index 1030a67..8400db5 100644 --- a/test/test_dereference.py +++ b/test/test_dereference.py @@ -1,11 +1,16 @@ # coding: utf-8 from .autopath import do_autopath do_autopath() +import weakref from tiramisu import BoolOption, IntOption, StrOption, IPOption, NetmaskOption, \ SymLinkOption, OptionDescription, DynOptionDescription, submulti, \ Config, GroupConfig, MetaConfig, Params, ParamOption -import weakref +from tiramisu.storage import list_sessions + + +def teardown_function(function): + assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__) IS_DEREFABLE = True diff --git a/test/test_duplicate_config.py b/test/test_duplicate_config.py index 2ed0805..7721f1c 100644 --- a/test/test_duplicate_config.py +++ b/test/test_duplicate_config.py @@ -1,13 +1,18 @@ # coding: utf-8 from .autopath import do_autopath do_autopath() +from py.test import raises from tiramisu.setting import groups from tiramisu import Config, MetaConfig from tiramisu import ChoiceOption, BoolOption, IntOption, \ StrOption, OptionDescription from .test_state import _diff_opts, _diff_conf -from py.test import raises +from tiramisu.storage import list_sessions + + +def teardown_function(function): + assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__) def make_description(): diff --git a/test/test_dyn_optiondescription.py b/test/test_dyn_optiondescription.py index f4f5c68..8f1965b 100644 --- a/test/test_dyn_optiondescription.py +++ b/test/test_dyn_optiondescription.py @@ -1,6 +1,7 @@ # coding: utf-8 from .autopath import do_autopath do_autopath() +from py.test import raises from tiramisu.setting import groups, owners from tiramisu import BoolOption, StrOption, ChoiceOption, IPOption, \ @@ -10,8 +11,11 @@ from tiramisu import BoolOption, StrOption, ChoiceOption, IPOption, \ OptionDescription, DynOptionDescription, DynSymLinkOption, submulti, MasterSlaves, \ Config, Params, ParamOption, ParamValue from tiramisu.error import PropertiesOptionError, ConfigError, ConflictError +from tiramisu.storage import list_sessions -from py.test import raises + +def teardown_function(function): + assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__) def return_true(value, param=None, suffix=None): diff --git a/test/test_freeze.py b/test/test_freeze.py index f67c305..b157aed 100644 --- a/test/test_freeze.py +++ b/test/test_freeze.py @@ -10,6 +10,11 @@ from tiramisu import ChoiceOption, BoolOption, IntOption, FloatOption, \ StrOption, OptionDescription, SymLinkOption, MasterSlaves, Config, \ Params, ParamContext, ParamOption, ParamValue from tiramisu.error import PropertiesOptionError, ConfigError +from tiramisu.storage import list_sessions + + +def teardown_function(function): + assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__) def compare(calculated, expected): diff --git a/test/test_mandatory.py b/test/test_mandatory.py index 1d360f5..50cf498 100644 --- a/test/test_mandatory.py +++ b/test/test_mandatory.py @@ -9,6 +9,11 @@ from tiramisu import IntOption, StrOption, UnicodeOption, OptionDescription, \ SymLinkOption, MasterSlaves, undefined, Params, ParamOption from tiramisu.error import PropertiesOptionError, ConfigError from tiramisu.setting import groups +from tiramisu.storage import list_sessions + + +def teardown_function(function): + assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__) def make_description(): diff --git a/test/test_masterslaves.py b/test/test_masterslaves.py index f96eb08..1267843 100644 --- a/test/test_masterslaves.py +++ b/test/test_masterslaves.py @@ -1,14 +1,18 @@ # coding: utf-8 from .autopath import do_autopath do_autopath() +from py.test import raises from tiramisu.setting import groups, owners from tiramisu import ChoiceOption, BoolOption, IntOption, IPOption, NetmaskOption, \ StrOption, OptionDescription, MasterSlaves, Config from tiramisu.error import SlaveError, PropertiesOptionError, APIError, ConfigError from tiramisu.api import TIRAMISU_VERSION +from tiramisu.storage import list_sessions -from py.test import raises + +def teardown_function(function): + assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__) def compare(calculated, expected): @@ -133,9 +137,12 @@ def test_list_recursive(): group_names = [res.option.name() for res in result] assert group_names == ['general', 'interface1'] # - result = list(api.option.list(recursive=True)) + result = api.option.list(recursive=True) group_names = [res.option.name() for res in result] - assert group_names == ['numero_etab', 'nom_machine', 'nombre_interfaces', 'activer_proxy_client', 'mode_conteneur_actif', 'serveur_ntp', 'time_zone', 'ip_admin_eth0', 'netmask_admin_eth0'] + assert group_names == ['numero_etab', 'nom_machine', 'nombre_interfaces', + 'activer_proxy_client', 'mode_conteneur_actif', + 'serveur_ntp', 'time_zone', 'ip_admin_eth0', + 'netmask_admin_eth0'] result = list(api.option.list(recursive=True, type='optiondescription')) group_names = [res.option.name() for res in result] assert group_names == ['general', 'ip_admin_eth0', 'interface1', 'creole'] @@ -191,7 +198,12 @@ def test_iter_on_empty_group(): def test_iter_not_group(): api = Config(OptionDescription("name", "descr", [])) api.property.read_write() - raises(AssertionError, "list(api.option.list(type='optiondescription', group_type='family'))") + try: + list(api.option.list(type='optiondescription', group_type='family')) + except AssertionError: + pass + else: + raise Exception('must raise') def test_groups_with_master(): diff --git a/test/test_metaconfig.py b/test/test_metaconfig.py index 4f0607e..8cd3493 100644 --- a/test/test_metaconfig.py +++ b/test/test_metaconfig.py @@ -8,6 +8,12 @@ from tiramisu import IntOption, StrOption, NetworkOption, NetmaskOption, \ OptionDescription, MasterSlaves, Config, GroupConfig, MetaConfig, \ Params, ParamOption, ParamValue from tiramisu.error import ConfigError, ConflictError, PropertiesOptionError, SlaveError, APIError +from tiramisu.storage import list_sessions + + +def teardown_function(function): + assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__) + owners.addowner('meta1') owners.addowner('meta2') @@ -663,16 +669,16 @@ def test_meta_callback(): meta.property.read_write() assert meta.config('cfg').value.dict() == {'val3': 'yes', 'val2': 'val', 'val1': 'val', 'val5': 'yes', 'val4': 'val'} meta.config('cfg').option('val1').value.set('new') - #assert meta.config('cfg').value.dict() == {'val3': 'yes', 'val2': 'new', 'val1': 'new', 'val5': 'yes', 'val4': 'new'} - #meta.config('cfg').option('val1').value.reset() - #meta.option('val1').value.set('new') - #assert meta.config('cfg').value.dict() == {'val3': 'yes', 'val2': 'new', 'val1': 'new', 'val5': 'yes', 'val4': 'new'} - #meta.config('cfg').option('val4').value.set('new1') - #assert meta.config('cfg').value.dict() == {'val3': 'yes', 'val2': 'new', 'val1': 'new', 'val5': 'yes', 'val4': 'new1'} - #meta.config('cfg').option('val4').value.reset() - #meta.option('val4').value.set('new1') - #assert meta.config('cfg').value.dict() == {'val3': 'yes', 'val2': 'new', 'val1': 'new', 'val5': 'yes', 'val4': 'new1'} - #meta.option('val4').value.reset() + assert meta.config('cfg').value.dict() == {'val3': 'yes', 'val2': 'new', 'val1': 'new', 'val5': 'yes', 'val4': 'new'} + meta.config('cfg').option('val1').value.reset() + meta.option('val1').value.set('new') + assert meta.config('cfg').value.dict() == {'val3': 'yes', 'val2': 'new', 'val1': 'new', 'val5': 'yes', 'val4': 'new'} + meta.config('cfg').option('val4').value.set('new1') + assert meta.config('cfg').value.dict() == {'val3': 'yes', 'val2': 'new', 'val1': 'new', 'val5': 'yes', 'val4': 'new1'} + meta.config('cfg').option('val4').value.reset() + meta.option('val4').value.set('new1') + assert meta.config('cfg').value.dict() == {'val3': 'yes', 'val2': 'new', 'val1': 'new', 'val5': 'yes', 'val4': 'new1'} + meta.option('val4').value.reset() def test_meta_callback_slave(): @@ -875,35 +881,47 @@ def test_meta_properties_meta_set_value(): assert len(ret) == 2 assert isinstance(ret[0], PropertiesOptionError) assert isinstance(ret[1], PropertiesOptionError) - del(ret) + del ret[1] + del ret[0] + del ret ret = meta.value.set('netmask_admin_eth0', ['255.255.255.255'], force_default=True) assert len(ret) == 1 assert isinstance(ret[0], PropertiesOptionError) - del(ret) + del ret[0] + del ret ret = meta.value.set('netmask_admin_eth0', ['255.255.255.255'], force_dont_change_value=True) assert len(ret) == 3 assert isinstance(ret[0], PropertiesOptionError) assert isinstance(ret[1], PropertiesOptionError) assert isinstance(ret[2], PropertiesOptionError) - del(ret) + del ret[2] + del ret[1] + del ret[0] + del ret ret = meta.value.set('netmask_admin_eth0', ['255.255.255.255'], force_default_if_same=True) assert len(ret) == 1 assert isinstance(ret[0], PropertiesOptionError) - del(ret) + del ret[0] + del ret ret = meta.value.set('ip_admin_eth0', '255.255.255.255', only_config=True) assert len(ret) == 2 assert isinstance(ret[0], ValueError) assert isinstance(ret[1], ValueError) - del(ret) + del ret[1] + del ret[0] + del ret ret = meta.value.set('ip_admin_eth0', '255.255.255.255', force_default=True) assert len(ret) == 1 assert isinstance(ret[0], ValueError) - del(ret) + del ret[0] + del ret ret = meta.value.set('ip_admin_eth0', '255.255.255.255', force_dont_change_value=True) assert len(ret) == 1 assert isinstance(ret[0], ValueError) - del(ret) + del ret[0] + del ret ret = meta.value.set('ip_admin_eth0', '255.255.255.255', force_default_if_same=True) assert len(ret) == 1 assert isinstance(ret[0], ValueError) - del(ret) + del ret[0] + del ret diff --git a/test/test_option.py b/test/test_option.py index c4bc9aa..fbfbd13 100644 --- a/test/test_option.py +++ b/test/test_option.py @@ -9,6 +9,11 @@ from py.test import raises from tiramisu.error import APIError, ConfigError from tiramisu import IntOption, OptionDescription, Config from tiramisu.setting import groups +from tiramisu.storage import list_sessions + + +def teardown_function(function): + assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__) def a_func(): @@ -140,8 +145,18 @@ def test_optiondescription_list(): assert len(list(api.option('od').list('optiondescription', group_type=groups.notfamily1))) == 1 assert len(list(api.option('od.od').list('option'))) == 1 assert len(list(api.option('od.od2').list('option'))) == 1 - raises(AssertionError, "list(api.option('od').list('unknown'))") - raises(AssertionError, "list(api.option('od').list('option', group_type='toto'))") + try: + list(api.option('od').list('unknown')) + except AssertionError: + pass + else: + raise Exception('must raise') + try: + list(api.option('od').list('option', group_type='toto')) + except AssertionError: + pass + else: + raise Exception('must raise') def test_optiondescription_group(): @@ -158,8 +173,18 @@ def test_optiondescription_group(): assert len(list(api.option.list('optiondescription'))) == 2 assert len(list(api.option.list('optiondescription', group_type=groups.family))) == 1 assert len(list(api.option.list('optiondescription', group_type=groups.notfamily))) == 1 - raises(AssertionError, "list(api.option.list('unknown'))") - raises(AssertionError, "list(api.option.list('option', group_type='toto'))") + try: + list(api.option.list('unknown')) + except AssertionError: + pass + else: + raise Exception('must raise') + try: + list(api.option.list('option', group_type='toto')) + except AssertionError: + pass + else: + raise Exception('must raise') def test_optiondescription_group_redefined(): diff --git a/test/test_option_callback.py b/test/test_option_callback.py index 5c1e4ae..6b78f1c 100644 --- a/test/test_option_callback.py +++ b/test/test_option_callback.py @@ -12,6 +12,11 @@ from tiramisu import ChoiceOption, BoolOption, IntOption, FloatOption, \ from tiramisu.api import TIRAMISU_VERSION from tiramisu.error import PropertiesOptionError, ConflictError, SlaveError, ConfigError from tiramisu.i18n import _ +from tiramisu.storage import list_sessions + + +def teardown_function(function): + assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__) def return_val(): @@ -697,13 +702,12 @@ def test_consistency_master_and_slaves_master_mandatory_transitive(): maconfig = OptionDescription('rootconfig', '', [interface1, interface2]) api = Config(maconfig) api.property.read_write() - err = None try: api.option('val1.val1').value.get() except PropertiesOptionError as error: - err = error - assert err, 'should raises' - assert str(err) == str(_('cannot access to {0} "{1}" because "{2}" has {3} {4}').format('option', 'val1', 'val2', 'property', '"disabled"')) + assert str(error) == str(_('cannot access to {0} "{1}" because "{2}" has {3} {4}').format('option', 'val1', 'val2', 'property', '"disabled"')) + else: + raise Exception('must raises') raises(PropertiesOptionError, "api.option('val3.val3').value.get()") assert list(api.value.mandatory_warnings()) == [] diff --git a/test/test_option_consistency.py b/test/test_option_consistency.py index 84ff135..25392c9 100644 --- a/test/test_option_consistency.py +++ b/test/test_option_consistency.py @@ -10,6 +10,11 @@ from tiramisu import IPOption, NetworkOption, NetmaskOption, IntOption,\ from tiramisu.error import ConfigError, ValueWarning, PropertiesOptionError from tiramisu.api import TIRAMISU_VERSION import warnings +from tiramisu.storage import list_sessions + + +def teardown_function(function): + assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__) def return_value(value=None): diff --git a/test/test_option_default.py b/test/test_option_default.py index c9e13c6..72fd0f8 100644 --- a/test/test_option_default.py +++ b/test/test_option_default.py @@ -8,6 +8,11 @@ from tiramisu.setting import owners from tiramisu.error import PropertiesOptionError, ConfigError from tiramisu import IntOption, FloatOption, StrOption, ChoiceOption, \ BoolOption, OptionDescription, MasterSlaves, Config, undefined +from tiramisu.storage import list_sessions + + +def teardown_function(function): + assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__) def make_description(): diff --git a/test/test_option_owner.py b/test/test_option_owner.py index 4dfefc5..33ff5a7 100644 --- a/test/test_option_owner.py +++ b/test/test_option_owner.py @@ -7,6 +7,11 @@ from tiramisu.setting import owners, groups from tiramisu import ChoiceOption, BoolOption, IntOption, FloatOption, \ StrOption, OptionDescription, SymLinkOption, MasterSlaves, Config from tiramisu.error import ConfigError, ConstError, PropertiesOptionError, APIError +from tiramisu.storage import list_sessions + + +def teardown_function(function): + assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__) def make_description(): diff --git a/test/test_option_setting.py b/test/test_option_setting.py index 3118f92..86e10b1 100644 --- a/test/test_option_setting.py +++ b/test/test_option_setting.py @@ -10,7 +10,11 @@ from tiramisu.setting import owners, groups from tiramisu import ChoiceOption, BoolOption, IntOption, FloatOption, \ StrOption, OptionDescription, MasterSlaves, Config, undefined from tiramisu.error import PropertiesOptionError -from tiramisu.api import TIRAMISU_VERSION +from tiramisu.storage import list_sessions + + +def teardown_function(function): + assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__) def make_description(): @@ -458,12 +462,8 @@ def test_reset_properties_force_store_value(): api = Config(descr) assert api.property.exportation() == {} api.property.add('frozen') - if TIRAMISU_VERSION == 2: - assert api.property.exportation() == \ - {None: set(('frozen', 'cache', 'validator', 'warnings', 'expire'))} - else: - assert api.property.exportation() == \ - {None: set(('frozen', 'cache', 'validator', 'warnings'))} + assert api.property.exportation() == \ + {None: set(('frozen', 'cache', 'validator', 'warnings'))} api.property.reset() assert api.property.exportation() == {} api.option('gc.dummy').property.add('test') @@ -471,32 +471,17 @@ def test_reset_properties_force_store_value(): api.property.reset() assert api.property.exportation() == {'gc.dummy': set(('test', 'force_store_value'))} api.property.add('frozen') - if TIRAMISU_VERSION == 2: - assert api.property.exportation() == \ - {None: set(('frozen', 'validator', 'cache', 'warnings', 'expire')), - 'gc.dummy': set(('test', 'force_store_value'))} - else: - assert api.property.exportation() == \ - {None: set(('frozen', 'validator', 'cache', 'warnings')), - 'gc.dummy': set(('test', 'force_store_value'))} + assert api.property.exportation() == \ + {None: set(('frozen', 'validator', 'cache', 'warnings')), + 'gc.dummy': set(('test', 'force_store_value'))} api.property.add('frozen') - if TIRAMISU_VERSION == 2: - assert api.property.exportation() == \ - {None: set(('frozen', 'validator', 'cache', 'warnings', 'expire')), - 'gc.dummy': set(('test', 'force_store_value'))} - else: - assert api.property.exportation() == \ - {None: set(('frozen', 'validator', 'cache', 'warnings')), - 'gc.dummy': set(('test', 'force_store_value'))} + assert api.property.exportation() == \ + {None: set(('frozen', 'validator', 'cache', 'warnings')), + 'gc.dummy': set(('test', 'force_store_value'))} api.option('gc.dummy').property.add('test') - if TIRAMISU_VERSION == 2: - assert api.property.exportation() == \ - {None: set(('frozen', 'validator', 'cache', 'warnings', 'expire')), - 'gc.dummy': set(('test', 'force_store_value'))} - else: - assert api.property.exportation() == \ - {None: set(('frozen', 'validator', 'cache', 'warnings')), - 'gc.dummy': set(('test', 'force_store_value'))} + assert api.property.exportation() == \ + {None: set(('frozen', 'validator', 'cache', 'warnings')), + 'gc.dummy': set(('test', 'force_store_value'))} def test_set_modified_value(): @@ -511,12 +496,8 @@ def test_set_modified_value(): def test_pprint(): - if TIRAMISU_VERSION == 2: - msg_error = _("cannot access to {0} \"{1}\" because has {2} {3}") - msg_is_not = _('the value of "{0}" is not "{1}"') - else: - msg_error = _("cannot access to {0} \"{1}\" because has {2} {3}") - msg_is_not = _('the value of "{0}" is not {1}') + msg_error = _("cannot access to {0} \"{1}\" because has {2} {3}") + msg_is_not = _('the value of "{0}" is not {1}') msg_is = _('the value of "{0}" is "{1}"') properties = _('properties') prop = _('property') @@ -547,13 +528,10 @@ def test_pprint(): except PropertiesOptionError as error: err = error - if TIRAMISU_VERSION == 2: - list_disabled = 'disabled (' + display_list([msg_is.format('Test int option', '1'), msg_is.format('string2', 'string')]) + ')' - list_hidden = 'hidden (' + msg_is_not.format('Test int option', display_list([2, 3, 4], 'or')) + ')' - else: - list_disabled = '"disabled" (' + display_list([msg_is.format('Test int option', '1'), msg_is.format('string2', 'string')]) + ')' - list_hidden = '"hidden" (' + msg_is_not.format('Test int option', display_list([2, 3, 4], 'or', add_quote=True)) + ')' + list_disabled = '"disabled" (' + display_list([msg_is.format('Test int option', '1'), msg_is.format('string2', 'string')]) + ')' + list_hidden = '"hidden" (' + msg_is_not.format('Test int option', display_list([2, 3, 4], 'or', add_quote=True)) + ')' assert str(err) == _(msg_error.format('option', 'Test string option', properties, display_list([list_disabled, list_hidden]))) + del err err = None try: @@ -561,10 +539,7 @@ def test_pprint(): except PropertiesOptionError as error: err = error - if TIRAMISU_VERSION == 2: - assert str(err) == msg_error.format('optiondescription', 'options', prop, 'hidden (' + msg_is.format('Test int option', 1) + ')') - else: - assert str(err) == msg_error.format('optiondescription', 'options', prop, '"hidden" (' + msg_is.format('Test int option', 1) + ')') + assert str(err) == msg_error.format('optiondescription', 'options', prop, '"hidden" (' + msg_is.format('Test int option', 1) + ')') #err = None #try: @@ -574,12 +549,8 @@ def test_pprint(): #msg_1 = msg_is.format('string2', 'string') #msg_2 = msg_is.format('Test int option', 1) - #if TIRAMISU_VERSION == 2: - # msg_3 = msg_is_not.format('Test int option', display_list([2, 3, 4], 'or')) - # list_hidden = 'hidden (' + display_list([msg_2, msg_3, msg_1]) + ')' - #else: - # msg_3 = msg_is_not.format('Test int option', display_list([2, 3, 4], 'or', add_quote=True)) - # list_hidden = '"hidden" (' + display_list([msg_2, msg_3, msg_1]) + ')' + #msg_3 = msg_is_not.format('Test int option', display_list([2, 3, 4], 'or', add_quote=True)) + #list_hidden = '"hidden" (' + display_list([msg_2, msg_3, msg_1]) + ')' #assert str(err) == msg_error.format('option', 'val3', prop, list_hidden) @@ -589,10 +560,8 @@ def test_pprint(): except Exception as error: err = error - if TIRAMISU_VERSION == 2: - assert str(err) == msg_error.format('option', 'string', properties, display_list(['disabled', 'hidden'])) - else: - assert str(err) == msg_error.format('option', 'string', properties, display_list(['disabled', 'hidden'], add_quote=True)) + assert str(err) == msg_error.format('option', 'string', properties, display_list(['disabled', 'hidden'], add_quote=True)) + del err err = None try: @@ -600,7 +569,5 @@ def test_pprint(): except Exception as error: err = error - if TIRAMISU_VERSION == 2: - assert str(err) == msg_error.format('option', 'string3', prop, 'hidden') - else: - assert str(err) == msg_error.format('option', 'string3', prop, '"hidden"') + assert str(err) == msg_error.format('option', 'string3', prop, '"hidden"') + del err diff --git a/test/test_option_type.py b/test/test_option_type.py index 0a48273..ec4e03d 100644 --- a/test/test_option_type.py +++ b/test/test_option_type.py @@ -8,6 +8,11 @@ from py.test import raises from tiramisu import ChoiceOption, BoolOption, IntOption, FloatOption, \ PasswordOption, StrOption, DateOption, OptionDescription, Config from tiramisu.error import PropertiesOptionError +from tiramisu.storage import list_sessions + + +def teardown_function(function): + assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__) def make_description(): diff --git a/test/test_option_username.py b/test/test_option_username.py index d328385..4cf083b 100644 --- a/test/test_option_username.py +++ b/test/test_option_username.py @@ -5,6 +5,12 @@ do_autopath() from py.test import raises from tiramisu.option import UsernameOption +from tiramisu.storage import list_sessions + + +def teardown_function(function): + assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__) + def test_username(): UsernameOption('a', '', 'string') diff --git a/test/test_option_validator.py b/test/test_option_validator.py index 439910c..3a80325 100644 --- a/test/test_option_validator.py +++ b/test/test_option_validator.py @@ -8,6 +8,11 @@ from tiramisu import BoolOption, StrOption, OptionDescription, MasterSlaves, Con from tiramisu.setting import groups from tiramisu.error import ValueWarning, ConfigError from tiramisu.i18n import _ +from tiramisu.storage import list_sessions + + +def teardown_function(function): + assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__) msg_err = _('attention, "{0}" could be an invalid {1} for "{2}", {3}') diff --git a/test/test_option_with_special_name.py b/test/test_option_with_special_name.py index 462c3b5..70e95a9 100644 --- a/test/test_option_with_special_name.py +++ b/test/test_option_with_special_name.py @@ -6,6 +6,11 @@ from py.test import raises from tiramisu import BoolOption, OptionDescription, ChoiceOption,\ IntOption, FloatOption, StrOption, Config +from tiramisu.storage import list_sessions + + +def teardown_function(function): + assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__) def make_description(): diff --git a/test/test_pathconfig.py b/test/test_pathconfig.py new file mode 100644 index 0000000..67c1733 --- /dev/null +++ b/test/test_pathconfig.py @@ -0,0 +1,966 @@ +from .autopath import do_autopath +do_autopath() + +from py.test import raises + +from tiramisu.setting import groups, owners +from tiramisu import IntOption, StrOption, NetworkOption, NetmaskOption, \ + OptionDescription, MasterSlaves, Config, GroupConfig, PathConfig, \ + Params, ParamOption, ParamValue +from tiramisu.error import ConfigError, ConflictError, PropertiesOptionError, SlaveError, APIError +from tiramisu.storage import list_sessions + +owners.addowner('path1') +owners.addowner('path2') + + +def teardown_function(function): + assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__) + + +def return_value(value=None): + return value + + +def raise_exception(): + raise Exception('test') + + +def make_description(): + i1 = IntOption('i1', '') + i2 = IntOption('i2', '', default=1) + i3 = IntOption('i3', '') + i4 = IntOption('i4', '', default=2) + i5 = IntOption('i5', '', default=[2], multi=True) + i6 = IntOption('i6', '', properties=('disabled',)) + od1 = OptionDescription('od1', '', [i1, i2, i3, i4, i5, i6]) + od2 = OptionDescription('od2', '', [od1]) + return od2 + + +def make_description1(): + i1 = IntOption('i1', '') + i2 = IntOption('i2', '', default=1) + i3 = IntOption('i3', '') + i4 = IntOption('i4', '', default=2) + i5 = IntOption('i5', '', default=[2], multi=True) + i6 = IntOption('i6', '', properties=('disabled',)) + od1 = OptionDescription('od1', '', [i1, i2, i3, i4, i5, i6]) + od2 = OptionDescription('od2', '', [od1]) + return od2 + + +def make_description2(): + i1 = IntOption('i1', '') + i2 = IntOption('i2', '', default=1) + i3 = IntOption('i3', '') + i4 = IntOption('i4', '', default=2) + i5 = IntOption('i5', '', default=[2], multi=True) + i6 = IntOption('i6', '', properties=('disabled',)) + od1 = OptionDescription('od1', '', [i1, i2, i3, i4, i5, i6]) + od2 = OptionDescription('od2', '', [od1]) + return od2 + + +def make_description3(): + i1 = IntOption('i1', '') + i2 = IntOption('i2', '', default=1) + i3 = IntOption('i3', '') + i4 = IntOption('i4', '', default=2) + i5 = IntOption('i5', '', default=[2], multi=True) + i6 = IntOption('i6', '', properties=('disabled',)) + od1 = OptionDescription('od1', '', [i1, i2, i3, i4, i5, i6]) + od2 = OptionDescription('od2', '', [od1]) + return od2 + + +def make_pathconfig(double=False): + od1 = make_description() + od2 = make_description1() + od3 = make_description2() + conf1 = Config(od1, session_id='conf1') + conf2 = Config(od2, session_id='conf2') + path = PathConfig(od3, [conf1, conf2], session_id='path') + if double: + od4 = make_description3() + path.owner.set(owners.path2) + path = PathConfig(od4, [path], session_id='doublepath') + path.property.read_write() + path.owner.set(owners.path1) + return path + + +def test_unknown_config(): + path = make_pathconfig() + raises(ConfigError, "path.config('unknown')") + + +def test_none(): + path = make_pathconfig() + assert path.option('od1.i3').value.get() is path.config('conf1').option('od1.i3').value.get() is path.config('conf2').option('od1.i3').value.get() is None + assert path.option('od1.i3').owner.get() is path.config('conf1').option('od1.i3').owner.get() is path.config('conf2').option('od1.i3').owner.get() is owners.default + # + path.option('od1.i3').value.set(3) + assert path.option('od1.i3').value.get() == path.config('conf1').option('od1.i3').value.get() == path.config('conf2').option('od1.i3').value.get() == 3 + assert path.option('od1.i3').owner.get() is path.config('conf1').option('od1.i3').owner.get() is path.config('conf2').option('od1.i3').owner.get() is owners.path1 + # + path.config('conf1').option('od1.i3').value.set(2) + assert path.option('od1.i3').value.get() == path.config('conf2').option('od1.i3').value.get() == 3 + assert path.config('conf1').option('od1.i3').value.get() == 2 + assert path.option('od1.i3').owner.get() is path.config('conf2').option('od1.i3').owner.get() is owners.path1 + assert path.config('conf1').option('od1.i3').owner.get() is owners.user + # + path.option('od1.i3').value.set(4) + assert path.option('od1.i3').value.get() == path.config('conf2').option('od1.i3').value.get() == 4 + assert path.config('conf1').option('od1.i3').value.get() == 2 + assert path.option('od1.i3').owner.get() is path.config('conf2').option('od1.i3').owner.get() is owners.path1 + assert path.config('conf1').option('od1.i3').owner.get() is owners.user + # + path.option('od1.i3').value.reset() + assert path.option('od1.i3').value.get() is path.config('conf2').option('od1.i3').value.get() is None + assert path.config('conf1').option('od1.i3').value.get() == 2 + assert path.option('od1.i3').owner.get() is path.config('conf2').option('od1.i3').owner.get() is owners.default + assert path.config('conf1').option('od1.i3').owner.get() is owners.user + # + path.config('conf1').option('od1.i3').value.reset() + assert path.option('od1.i3').value.get() is path.config('conf1').option('od1.i3').value.get() is path.config('conf2').option('od1.i3').value.get() is None + assert path.option('od1.i3').owner.get() is path.config('conf1').option('od1.i3').owner.get() is path.config('conf2').option('od1.i3').owner.get() is owners.default + # + assert path.config(None).config.name() == path.config.name() + + +def test_reset(): + path = make_pathconfig() + assert path.option('od1.i2').value.get() == 1 + path.option('od1.i2').value.set(2) + path.config('conf1').option('od1.i2').value.set(3) + assert path.option('od1.i2').value.get() == 2 + assert path.config('conf1').option('od1.i2').value.get() == 3 + assert path.config('conf2').option('od1.i2').value.get() == 2 + path.config.reset() + assert path.option('od1.i2').value.get() == 1 + assert path.config('conf1').option('od1.i2').value.get() == 3 + assert path.config('conf2').option('od1.i2').value.get() == 1 + + +def test_default(): + path = make_pathconfig() + assert path.option('od1.i2').value.get() == path.config('conf1').option('od1.i2').value.get() == path.config('conf2').option('od1.i2').value.get() == 1 + assert path.option('od1.i2').owner.get() is path.config('conf1').option('od1.i2').owner.get() is path.config('conf2').option('od1.i2').owner.get() is owners.default + # + path.option('od1.i2').value.set(3) + assert path.option('od1.i2').value.get() == path.config('conf1').option('od1.i2').value.get() == path.config('conf2').option('od1.i2').value.get() == 3 + assert path.option('od1.i2').owner.get() is path.config('conf1').option('od1.i2').owner.get() is path.config('conf2').option('od1.i2').owner.get() is owners.path1 + # + path.config('conf1').option('od1.i2').value.set(2) + assert path.option('od1.i2').value.get() == path.config('conf2').option('od1.i2').value.get() == 3 + assert path.config('conf1').option('od1.i2').value.get() == 2 + assert path.option('od1.i2').owner.get() is path.config('conf2').option('od1.i2').owner.get() is owners.path1 + assert path.config('conf1').option('od1.i2').owner.get() is owners.user + # + path.option('od1.i2').value.set(4) + assert path.option('od1.i2').value.get() == path.config('conf2').option('od1.i2').value.get() == 4 + assert path.config('conf1').option('od1.i2').value.get() == 2 + assert path.option('od1.i2').owner.get() is path.config('conf2').option('od1.i2').owner.get() is owners.path1 + assert path.config('conf1').option('od1.i2').owner.get() is owners.user + # + path.option('od1.i2').value.reset() + assert path.option('od1.i2').value.get() == path.config('conf2').option('od1.i2').value.get() == 1 + assert path.config('conf1').option('od1.i2').value.get() == 2 + assert path.option('od1.i2').owner.get() is path.config('conf2').option('od1.i2').owner.get() is owners.default + assert path.config('conf1').option('od1.i2').owner.get() is owners.user + # + path.config('conf1').option('od1.i2').value.reset() + assert path.option('od1.i2').value.get() == path.config('conf1').option('od1.i2').value.get() == path.config('conf2').option('od1.i2').value.get() == 1 + assert path.option('od1.i2').owner.get() is path.config('conf1').option('od1.i2').owner.get() is path.config('conf2').option('od1.i2').owner.get() is owners.default + + +def test_contexts(): + path = make_pathconfig() + errors = path.value.set('od1.i2', 6, only_config=True) + assert path.option('od1.i2').value.get() == 1 + assert path.option('od1.i2').owner.get() == owners.default + assert path.config('conf1').option('od1.i2').value.get() == path.config('conf1').option('od1.i2').value.get() == 6 + assert path.config('conf1').option('od1.i2').owner.get() == path.config('conf1').option('od1.i2').owner.get() is owners.user + assert len(errors) == 0 + + +def test_find(): + path = make_pathconfig() + ret = list(path.option.find('i2')) + assert len(ret) == 1 + assert 1 == ret[0].value.get() + assert 1 == path.option.find('i2', first=True).value.get() + assert path.value.dict() == {'od1.i4': 2, 'od1.i1': None, 'od1.i3': None, + 'od1.i2': 1, 'od1.i5': [2]} + + +def test_path_path(): + path = make_pathconfig(double=True) + assert path.option('od1.i2').value.get() == path.config('path').option('od1.i2').value.get() == path.config('path.conf1').option('od1.i2').value.get() == path.config('path.conf2').option('od1.i2').value.get() == 1 + assert path.option('od1.i2').owner.get() is path.config('path').option('od1.i2').owner.get() is path.config('path.conf1').option('od1.i2').owner.get() is path.config('path.conf2').option('od1.i2').owner.get() is owners.default + # + path.option('od1.i2').value.set(3) + assert path.option('od1.i2').value.get() == path.config('path').option('od1.i2').value.get() == path.config('path.conf1').option('od1.i2').value.get() == path.config('path.conf2').option('od1.i2').value.get() == 3 + assert path.option('od1.i2').owner.get() is path.config('path').option('od1.i2').owner.get() is path.config('path.conf1').option('od1.i2').owner.get() is path.config('path.conf2').option('od1.i2').owner.get() is owners.path1 + # + path.config('path.conf1').option('od1.i2').value.set(2) + assert path.option('od1.i2').value.get() == path.config('path').option('od1.i2').value.get() == path.config('path.conf2').option('od1.i2').value.get() == 3 + assert path.config('path.conf1').option('od1.i2').value.get() == 2 + assert path.option('od1.i2').owner.get() is path.config('path').option('od1.i2').owner.get() is path.config('path.conf2').option('od1.i2').owner.get() is owners.path1 + assert path.config('path.conf1').option('od1.i2').owner.get() is owners.user + # + path.config('path').option('od1.i2').value.set(4) + assert path.option('od1.i2').value.get() == 3 + assert path.config('path').option('od1.i2').value.get() == path.config('path.conf2').option('od1.i2').value.get() == 4 + assert path.config('path.conf1').option('od1.i2').value.get() == 2 + assert path.option('od1.i2').owner.get() is owners.path1 + assert path.config('path').option('od1.i2').owner.get() is path.config('path.conf2').option('od1.i2').owner.get() is owners.path2 + assert path.config('path.conf1').option('od1.i2').owner.get() is owners.user + # + path.config('path').option('od1.i2').value.reset() + assert path.option('od1.i2').value.get() == path.config('path').option('od1.i2').value.get() == path.config('path.conf2').option('od1.i2').value.get() == 3 + assert path.config('path.conf1').option('od1.i2').value.get() == 2 + assert path.option('od1.i2').owner.get() is path.config('path').option('od1.i2').owner.get() is path.config('path.conf2').option('od1.i2').owner.get() is owners.path1 + assert path.config('path.conf1').option('od1.i2').owner.get() is owners.user + # + path.option('od1.i2').value.reset() + assert path.option('od1.i2').value.get() == path.config('path').option('od1.i2').value.get() == path.config('path.conf2').option('od1.i2').value.get() == 1 + assert path.config('path.conf1').option('od1.i2').value.get() == 2 + assert path.option('od1.i2').owner.get() is path.config('path').option('od1.i2').owner.get() is path.config('path.conf2').option('od1.i2').owner.get() is owners.default + assert path.config('path.conf1').option('od1.i2').owner.get() is owners.user + # + path.config('path.conf1').option('od1.i2').value.reset() + assert path.option('od1.i2').value.get() == path.config('path').option('od1.i2').value.get() == path.config('path.conf1').option('od1.i2').value.get() == path.config('path.conf2').option('od1.i2').value.get() == 1 + assert path.option('od1.i2').owner.get() is path.config('path').option('od1.i2').owner.get() is path.config('path.conf1').option('od1.i2').owner.get() is path.config('path.conf2').option('od1.i2').owner.get() is owners.default + + +def test_path_path_set(): + path = make_pathconfig(double=True) + errors1 = path.value.set('od1.i1', 7, only_config=True) + errors2 = path.value.set('od1.i6', 7, only_config=True) + assert len(errors1) == 0 + assert len(errors2) == 2 + conf1 = path.config('path.conf1')._config_bag.context + conf2 = path.config('path.conf2')._config_bag.context + assert path.config('path.conf1').option('od1.i1').value.get() == path.config('path.conf2').option('od1.i1').value.get() == 7 + # + dconfigs = [] + for conf in path.config.find('i1', value=7).config.list(): + dconfigs.append(conf._config_bag.context) + assert [conf1, conf2] == dconfigs + path.config('path.conf1').option('od1.i1').value.set(8) + # + dconfigs = [] + for conf in path.config.find('i1').config.list(): + dconfigs.append(conf._config_bag.context) + assert [conf1, conf2] == dconfigs + assert conf2 == list(path.config.find('i1', value=7).config.list())[0]._config_bag.context + assert conf1 == list(path.config.find('i1', value=8).config.list())[0]._config_bag.context + # + dconfigs = [] + for conf in path.config.find('i5', value=2).config.list(): + dconfigs.append(conf._config_bag.context) + assert [conf1, conf2] == dconfigs + # + raises(AttributeError, "path.config.find('i1', value=10)") + raises(AttributeError, "path.config.find('not', value=10)") + raises(AttributeError, "path.config.find('i6')") + raises(ValueError, "path.value.set('od1.i6', 7, only_config=True, force_default=True)") + raises(ValueError, "path.value.set('od1.i6', 7, only_config=True, force_default_if_same=True)") + raises(ValueError, "path.value.set('od1.i6', 7, only_config=True, force_dont_change_value=True)") + + +def test_not_path(): + i1 = IntOption('i1', '') + od1 = OptionDescription('od1', '', [i1]) + od2 = OptionDescription('od2', '', [od1]) + conf1 = Config(od2, session_id='conf1') + conf2 = Config(od2, session_id='conf2') + conf3 = Config(od2) + conf4 = Config(od2, session_id='conf4') + raises(TypeError, "GroupConfig(conf1)") + #same name + #raises(ConflictError, "GroupConfig([conf2, conf4], session_id='conf2')") + raises(ConflictError, "GroupConfig([conf2, conf2], session_id='conf8')") + grp = GroupConfig([conf1, conf2]) + raises(APIError, "grp.option('od1.i1').value.get()") + conf1, conf2 = grp.config.list() + errors = grp.value.set('od1.i1', 7) + assert len(errors) == 0 + assert grp.config('conf1').option('od1.i1').value.get() == grp.config('conf2').option('od1.i1').value.get() == 7 + assert grp.config('conf1').option('od1.i1').owner.get() is grp.config('conf2').option('od1.i1').owner.get() is owners.user + grp.option('od1.i1').value.reset() + assert grp.config('conf1').option('od1.i1').owner.get() is grp.config('conf2').option('od1.i1').owner.get() is owners.default + + +def test_group_find_firsts(): + i1 = IntOption('i1', '') + od1 = OptionDescription('od1', '', [i1]) + od2 = OptionDescription('od2', '', [od1]) + conf1 = Config(od2, session_id='conf1') + conf2 = Config(od2, session_id='conf2') + grp = GroupConfig([conf1, conf2]) + itr = grp.config.find('i1').config.list() + conf1._config_bag.context == next(itr)._config_bag.context + conf2._config_bag.context == next(itr)._config_bag.context + try: + next(itr) + except StopIteration: + pass + except: + raise Exception('no') + else: + raise Exception('no') + + +def test_group_group(): + i1 = IntOption('i1', '') + od1 = OptionDescription('od1', '', [i1]) + od2 = OptionDescription('od2', '', [od1]) + conf1 = Config(od2, session_id='conf9') + conf2 = Config(od2, session_id='conf10') + grp = GroupConfig([conf1, conf2], 'grp') + grp2 = GroupConfig([grp]) + errors = grp2.value.set('od1.i1', 2) + assert len(errors) == 0 + assert grp2.config('grp.conf9').option('od1.i1').value.get() == 2 + assert grp2.config('grp.conf9').option('od1.i1').owner.get() is owners.user + + +def test_path_unconsistent(): + i1 = IntOption('i1', '') + i2 = IntOption('i2', '', default=1) + i3 = IntOption('i3', '') + i4 = IntOption('i4', '', default=2) + od1 = OptionDescription('od1', '', [i1, i2, i3, i4]) + od2 = OptionDescription('od2', '', [od1]) + od3 = OptionDescription('od3', '', [od1]) + conf1 = Config(od2, session_id='conf1') + conf2 = Config(od2, session_id='conf2') + conf3 = Config(od2, session_id='conf3') + conf4 = Config(od3, session_id='conf4') + path = PathConfig(od2, [conf1, conf2]) + path.owner.set(owners.path1) + raises(TypeError, 'PathConfig(od2, "string")') + # same descr but conf1 already in path + raises(ValueError, "PathConfig(od2, [conf1, conf3])") + # not same descr + PathConfig(od2, [conf3, conf4]) + + +def test_path_master_slaves(): + ip_admin_eth0 = StrOption('ip_admin_eth0', "ip", multi=True) + netmask_admin_eth0 = StrOption('netmask_admin_eth0', "mask", multi=True, properties=('hidden',)) + interface1 = MasterSlaves('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + od = OptionDescription('root', '', [interface1]) + conf1 = Config(od, session_id='conf1') + conf2 = Config(od, session_id='conf2') + path = PathConfig(od, [conf1, conf2]) + path.property.read_only() + itr = path.config.find('ip_admin_eth0').config.list() + assert conf1._config_bag.context == next(itr)._config_bag.context + assert conf2._config_bag.context == next(itr)._config_bag.context + itr = path.config.find('netmask_admin_eth0').config.list() + assert conf1._config_bag.context == next(itr)._config_bag.context + assert conf2._config_bag.context == next(itr)._config_bag.context + path.property.read_write() + raises(AttributeError, "path.config.find('netmask_admin_eth0')") + itr = path.unrestraint.config.find('netmask_admin_eth0').config.list() + assert conf1._config_bag.context == next(itr)._config_bag.context + assert conf2._config_bag.context == next(itr)._config_bag.context + path.property.read_only() + itr = path.config.find('netmask_admin_eth0').config.list() + assert conf1._config_bag.context == next(itr)._config_bag.context + assert conf2._config_bag.context == next(itr)._config_bag.context + + +def test_path_master_slaves_value2(): + ip_admin_eth0 = StrOption('ip_admin_eth0', "ip", multi=True) + netmask_admin_eth0 = StrOption('netmask_admin_eth0', "mask", multi=True, properties=('hidden',)) + interface1 = MasterSlaves('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + od = OptionDescription('root', '', [interface1]) + conf1 = Config(od, session_id='conf1') + conf2 = Config(od, session_id='conf2') + path = PathConfig(od, [conf1, conf2], session_id="path") + path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.8']) + assert path.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None + #FIXME devrait raise ! assert path.config('conf1').option('ip_admin_eth0.ip_admin_eth0', 0).value.get() == None + # + path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.reset() + # + path.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1']) + assert path.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None + path.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set('255.255.255.0') + assert path.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == '255.255.255.0' + path.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set('255.255.0.0') + assert path.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == '255.255.0.0' + # + path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1']) + assert path.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None + + +def test_path_master_slaves_value_default(): + ip_admin_eth0 = StrOption('ip_admin_eth0', "ip", multi=True, default=['192.168.1.1']) + netmask_admin_eth0 = StrOption('netmask_admin_eth0', "mask", multi=True) + interface1 = MasterSlaves('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + od = OptionDescription('root', '', [interface1]) + conf1 = Config(od, session_id='conf1') + conf2 = Config(od, session_id='conf2') + path = PathConfig(od, [conf1, conf2]) + assert path.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None + # + path.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1']) + assert path.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None + # + path.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set('255.255.255.0') + assert path.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == '255.255.255.0' + # + path.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set('255.255.0.0') + assert path.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == '255.255.0.0' + # + path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1']) + assert path.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None + + +def test_path_master_slaves_owners(): + ip_admin_eth0 = StrOption('ip_admin_eth0', "ip", multi=True) + netmask_admin_eth0 = StrOption('netmask_admin_eth0', "mask", multi=True, properties=('hidden',)) + interface1 = MasterSlaves('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + od = OptionDescription('root', '', [interface1]) + conf1 = Config(od, session_id='conf1') + conf2 = Config(od, session_id='conf2') + path = PathConfig(od, [conf1, conf2]) + path.owner.set(owners.path1) + assert path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').owner.isdefault() + raises(SlaveError, "path.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).owner.isdefault()") + # + path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1']) + assert path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').owner.get() == owners.user + assert path.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).owner.isdefault() + # + path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.reset() + assert path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').owner.isdefault() + # + path.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1']) + assert path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').owner.get() == owners.path1 + assert path.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).owner.isdefault() + # + path.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set('255.255.255.0') + assert path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').owner.get() == owners.path1 + assert path.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).owner.get() == owners.path1 + # + path.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set('255.255.0.0') + assert path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').owner.get() == owners.path1 + assert path.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).owner.get() == owners.path1 + # + path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1']) + assert path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').owner.get() == owners.user + assert path.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).owner.get() == owners.default + + +def test_path_force_default(): + ip_admin_eth0 = StrOption('ip_admin_eth0', "ip", multi=True) + netmask_admin_eth0 = StrOption('netmask_admin_eth0', "mask", multi=True, properties=('hidden',)) + interface1 = MasterSlaves('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + od = OptionDescription('root', '', [interface1]) + conf1 = Config(od, session_id='conf1') + conf2 = Config(od, session_id='conf2') + path = PathConfig(od, [conf1, conf2]) + path.property.read_write() + path.owner.set('path1') + assert path.option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + assert path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + assert path.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + # + errors = path.value.set('ip_admin_eth0.ip_admin_eth0', ['192.168.1.1']) + assert len(errors) == 0 + assert path.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.1'] + assert path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.1'] + assert path.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.1'] + # + path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.2']) + assert path.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.1'] + assert path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.2'] + assert path.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.1'] + # + errors = path.value.set('ip_admin_eth0.ip_admin_eth0', ['192.168.1.3']) + assert len(errors) == 0 + assert path.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.3'] + assert path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.2'] + assert path.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.3'] + # + errors = path.value.set('ip_admin_eth0.ip_admin_eth0', ['192.168.1.4'], force_default=True) + assert len(errors) == 0 + assert path.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.4'] + assert path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.4'] + assert path.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.4'] + + +def test_path_force_dont_change_value(): + ip_admin_eth0 = StrOption('ip_admin_eth0', "ip", multi=True) + netmask_admin_eth0 = StrOption('netmask_admin_eth0', "mask", multi=True, properties=('hidden',)) + interface1 = MasterSlaves('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + od = OptionDescription('root', '', [interface1]) + conf1 = Config(od, session_id='conf1') + conf2 = Config(od, session_id='conf2') + path = PathConfig(od, [conf1, conf2]) + path.property.read_write() + path.owner.set('path1') + assert path.option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + assert path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + assert path.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.4']) + assert path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.4'] + assert path.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + assert path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user + assert path.config('conf2').option('ip_admin_eth0.ip_admin_eth0').owner.isdefault() + errors = path.value.set('ip_admin_eth0.ip_admin_eth0', ['192.168.1.4'], force_dont_change_value=True) + assert len(errors) == 0 + assert path.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.4'] + assert path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.4'] + assert path.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + assert path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user + assert path.config('conf2').option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user + + +def test_path_force_default_if_same(): + ip_admin_eth0 = StrOption('ip_admin_eth0', "ip", multi=True) + netmask_admin_eth0 = StrOption('netmask_admin_eth0', "mask", multi=True, properties=('hidden',)) + interface1 = MasterSlaves('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + od = OptionDescription('root', '', [interface1]) + conf1 = Config(od, session_id='conf1') + conf2 = Config(od, session_id='conf2') + path = PathConfig(od, [conf1, conf2]) + path.property.read_write() + path.owner.set('path1') + # + assert path.option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + assert path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + assert path.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + # + path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.4']) + assert path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.4'] + assert path.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + assert path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user + assert path.config('conf2').option('ip_admin_eth0.ip_admin_eth0').owner.isdefault() + errors = path.value.set('ip_admin_eth0.ip_admin_eth0', ['192.168.1.4'], force_default_if_same=True) + assert len(errors) == 0 + assert path.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.4'] + assert path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.4'] + assert path.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.4'] + assert path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.path1 + assert path.config('conf2').option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.path1 + # + path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.3']) + assert path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.3'] + assert path.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.4'] + assert path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user + assert path.config('conf2').option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.path1 + errors = path.value.set('ip_admin_eth0.ip_admin_eth0', ['192.168.1.5'], force_default_if_same=True) + assert len(errors) == 0 + assert path.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.5'] + assert path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.3'] + assert path.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.5'] + assert path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user + assert path.config('conf2').option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.path1 + + +def test_path_force_default_if_same_and_dont_change(): + ip_admin_eth0 = StrOption('ip_admin_eth0', "ip", multi=True) + netmask_admin_eth0 = StrOption('netmask_admin_eth0', "mask", multi=True, properties=('hidden',)) + interface1 = MasterSlaves('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + od = OptionDescription('root', '', [interface1]) + conf1 = Config(od, session_id='conf1') + conf2 = Config(od, session_id='conf2') + path = PathConfig(od, [conf1, conf2]) + path.property.read_write() + path.owner.set('path1') + # + assert path.option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + assert path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + assert path.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + # + path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.4']) + assert path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.4'] + assert path.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + assert path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user + assert path.config('conf2').option('ip_admin_eth0.ip_admin_eth0').owner.isdefault() + errors = path.value.set('ip_admin_eth0.ip_admin_eth0', ['192.168.1.4'], force_default_if_same=True, force_dont_change_value=True) + assert len(errors) == 0 + assert path.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.4'] + assert path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.4'] + assert path.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + assert path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.path1 + assert path.config('conf2').option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user + # + path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.3']) + assert path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.3'] + assert path.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + assert path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user + assert path.config('conf2').option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user + errors = path.value.set('ip_admin_eth0.ip_admin_eth0', ['192.168.1.5'], force_default_if_same=True, force_dont_change_value=True) + assert len(errors) == 0 + assert path.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.5'] + assert path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.3'] + assert path.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + assert path.config('conf1').option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user + assert path.config('conf2').option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user + + +def test_path_force_default_and_dont_change(): + ip_admin_eth0 = StrOption('ip_admin_eth0', "ip", multi=True) + netmask_admin_eth0 = StrOption('netmask_admin_eth0', "mask", multi=True, properties=('hidden',)) + interface1 = MasterSlaves('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + od = OptionDescription('root', '', [interface1]) + conf1 = Config(od, session_id='rconf1') + conf2 = Config(od, session_id='rconf2') + path = PathConfig(od, [conf1, conf2]) + path.property.read_write() + path.owner.set('path1') + raises(ValueError, "path.value.set('ip_admin_eth0.ip_admin_eth0', ['192.168.1.4'], force_default=True, force_dont_change_value=True)") + + +def test_path_properties_path(): + ip_admin_eth0 = NetworkOption('ip_admin_eth0', "ip", multi=True, default=['192.168.1.1']) + netmask_admin_eth0 = NetmaskOption('netmask_admin_eth0', "mask", multi=True, properties=('disabled',)) + netmask_admin_eth0.impl_add_consistency('network_netmask', ip_admin_eth0) + interface1 = MasterSlaves('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + od = OptionDescription('root', '', [interface1]) + conf1 = Config(od, session_id='conf1') + conf2 = Config(od, session_id='conf2') + conf1.property.read_write() + conf2.property.read_write() + path = PathConfig(od, [conf1, conf2]) + path.property.read_write() + assert path.config('conf1').value.dict() == {} + + +def test_path_exception_path(): + ip_admin_eth0 = NetworkOption('ip_admin_eth0', "ip", multi=True, default=['192.168.1.1']) + netmask_admin_eth0 = NetmaskOption('netmask_admin_eth0', "mask", multi=True, callback=raise_exception) + netmask_admin_eth0.impl_add_consistency('network_netmask', ip_admin_eth0) + interface1 = MasterSlaves('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + od = OptionDescription('root', '', [interface1]) + conf1 = Config(od, session_id='conf1') + conf2 = Config(od, session_id='conf2') + path = PathConfig(od, [conf1, conf2]) + path.property.read_write() + raises(Exception, "conf1.make_dict()") + + +def test_path_callback(): + val1 = StrOption('val1', "", 'val') + val2 = StrOption('val2', "", callback=return_value, callback_params=Params(ParamOption(val1))) + val3 = StrOption('val3', "", callback=return_value, callback_params=Params(ParamValue('yes'))) + val4 = StrOption('val4', "", callback=return_value, callback_params=Params(kwargs={'value': ParamOption(val1)})) + val5 = StrOption('val5', "", callback=return_value, callback_params=Params(kwargs={'value': ParamValue('yes')})) + maconfig = OptionDescription('rootconfig', '', [val1, val2, val3, val4, val5]) + cfg = Config(maconfig, session_id='cfg') + path = PathConfig(maconfig, [cfg]) + path.property.read_write() + assert path.config('cfg').value.dict() == {'val3': 'yes', 'val2': 'val', 'val1': 'val', 'val5': 'yes', 'val4': 'val'} + path.config('cfg').option('val1').value.set('new') + assert path.config('cfg').value.dict() == {'val3': 'yes', 'val2': 'new', 'val1': 'new', 'val5': 'yes', 'val4': 'new'} + path.config('cfg').option('val1').value.reset() + path.option('val1').value.set('new') + assert path.config('cfg').value.dict() == {'val3': 'yes', 'val2': 'new', 'val1': 'new', 'val5': 'yes', 'val4': 'new'} + path.config('cfg').option('val4').value.set('new1') + assert path.config('cfg').value.dict() == {'val3': 'yes', 'val2': 'new', 'val1': 'new', 'val5': 'yes', 'val4': 'new1'} + path.config('cfg').option('val4').value.reset() + path.option('val4').value.set('new1') + assert path.config('cfg').value.dict() == {'val3': 'yes', 'val2': 'new', 'val1': 'new', 'val5': 'yes', 'val4': 'new1'} + path.option('val4').value.reset() + + +def test_path_callback_slave(): + val = StrOption('val', "", default='val') + val1 = StrOption('val1', "", multi=True, callback=return_value, callback_params=Params(ParamOption(val))) + val3 = StrOption('val2', "", multi=True, callback=return_value, callback_params=Params(ParamOption(val1))) + val4 = StrOption('val3', "", multi=True, callback=return_value, callback_params=Params(ParamOption(val1))) + interface1 = MasterSlaves('val1', '', [val1, val3, val4]) + od = OptionDescription('root', '', [interface1]) + maconfig = OptionDescription('rootconfig', '', [val, interface1]) + cfg = Config(maconfig, session_id='cfg1') + path = PathConfig(maconfig, [cfg]) + path.property.read_write() + assert path.config('cfg1').value.dict() == {'val1.val2': ['val'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'} + path.config('cfg1').option('val').value.set('val1') + assert path.config('cfg1').value.dict() == {'val1.val2': ['val1'], 'val1.val1': ['val1'], 'val1.val3': ['val1'], 'val': 'val1'} + path.config('cfg1').option('val').value.reset() + path.option('val').value.set('val1') + assert path.config('cfg1').value.dict() == {'val1.val2': ['val1'], 'val1.val1': ['val1'], 'val1.val3': ['val1'], 'val': 'val1'} + path.option('val').value.reset() + path.config('cfg1').option('val1.val2', 0).value.set('val2') + assert path.config('cfg1').value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'} + path.config('cfg1').option('val1.val2', 0).value.reset() + assert path.config('cfg1').value.dict() == {'val1.val2': ['val'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'} + path.option('val1.val2', 0).value.set('val2') + assert path.config('cfg1').value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'} + path.config('cfg1').option('val1.val3', 0).value.set('val6') + assert path.config('cfg1').value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val'], 'val1.val3': ['val6'], 'val': 'val'} + path.option('val1.val2', 0).value.reset() + path.config('cfg1').option('val1.val3', 0).value.reset() + path.config('cfg1').option('val1.val1').value.set(['val3']) + assert path.config('cfg1').value.dict() == {'val1.val2': ['val3'], 'val1.val1': ['val3'], 'val1.val3': ['val3'], 'val': 'val'} + path.config('cfg1').option('val1.val1').value.reset() + assert path.config('cfg1').value.dict() == {'val1.val2': ['val'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'} + path.option('val1.val1').value.set(['val3']) + assert path.config('cfg1').value.dict() == {'val1.val2': ['val3'], 'val1.val1': ['val3'], 'val1.val3': ['val3'], 'val': 'val'} + path.config('cfg1').option('val1.val2', 0).value.set('val2') + assert path.config('cfg1').value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val3'], 'val1.val3': ['val3'], 'val': 'val'} + path.option('val1.val1').value.set(['val3', 'rah']) + assert path.config('cfg1').value.dict() == {'val1.val2': ['val2', 'rah'], 'val1.val1': ['val3', 'rah'], 'val1.val3': ['val3', 'rah'], 'val': 'val'} + path.option('val1.val1').value.pop(1) + path.option('val1.val1').value.set(['val4']) + assert path.config('cfg1').value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val4'], 'val1.val3': ['val4'], 'val': 'val'} + + +def test_meta_reset(): + ip_admin_eth0 = StrOption('ip_admin_eth0', "ip", multi=True) + netmask_admin_eth0 = StrOption('netmask_admin_eth0', "mask", multi=True, properties=('hidden',)) + interface1 = MasterSlaves('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + od0 = OptionDescription('root', '', [interface1]) + ip_admin_eth0 = StrOption('ip_admin_eth0', "ip", multi=True) + netmask_admin_eth0 = StrOption('netmask_admin_eth0', "mask", multi=True, properties=('hidden',)) + interface1 = MasterSlaves('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + od1 = OptionDescription('root', '', [interface1]) + ip_admin_eth0 = StrOption('ip_admin_eth0', "ip", multi=True) + netmask_admin_eth0 = StrOption('netmask_admin_eth0', "mask", multi=True, properties=('hidden',)) + interface1 = MasterSlaves('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + od2 = OptionDescription('root', '', [interface1]) + conf1 = Config(od0, session_id='conf1') + conf2 = Config(od1, session_id='conf2') + meta = PathConfig(od2, [conf1, conf2]) + meta.property.read_write() + meta.owner.set('path1') + assert meta.option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + assert meta.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + assert meta.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + errors = meta.value.set('ip_admin_eth0.ip_admin_eth0', ['192.168.1.1']) + assert len(errors) == 0 + assert meta.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.1'] + assert meta.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.1'] + assert meta.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.1'] + meta.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.2']) + assert meta.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.1'] + assert meta.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.2'] + assert meta.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.1'] + meta.option('ip_admin_eth0.ip_admin_eth0').value.reset(children=True) + assert meta.option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + assert meta.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + assert meta.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + + +def test_path_properties_path_copy(): + ip_admin_eth0 = NetworkOption('ip_admin_eth0', "ip", multi=True, default=['192.168.1.1']) + netmask_admin_eth0 = NetmaskOption('netmask_admin_eth0', "mask", multi=True, properties=('disabled',)) + interface0 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + ip_admin_eth0 = NetworkOption('ip_admin_eth0', "ip", multi=True, default=['192.168.1.1']) + netmask_admin_eth0 = NetmaskOption('netmask_admin_eth0', "mask", multi=True, properties=('disabled',)) + interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + ip_admin_eth0 = NetworkOption('ip_admin_eth0', "ip", multi=True, default=['192.168.1.1']) + netmask_admin_eth0 = NetmaskOption('netmask_admin_eth0', "mask", multi=True, properties=('disabled',)) + interface2 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + conf1 = Config(interface0, session_id='conf1') + conf2 = Config(interface1, session_id='conf2') + conf1.property.read_write() + conf2.property.read_write() + path = PathConfig(interface2, [conf1, conf2], session_id='path1') + path.property.read_write() + + conf3 = path.config('conf1').config.copy(session_id='conf3') + path2 = conf3.config.metaconfig() + assert path.config.name() == path2.config.name() + + assert path.config('conf1').value.dict() == {'ip_admin_eth0': ['192.168.1.1']} + assert path.config('conf2').value.dict() == {'ip_admin_eth0': ['192.168.1.1']} + assert path.config('conf3').value.dict() == {'ip_admin_eth0': ['192.168.1.1']} + path.option('ip_admin_eth0').value.set(['192.168.1.2']) + assert path.config('conf1').value.dict() == {'ip_admin_eth0': ['192.168.1.2']} + assert path.config('conf2').value.dict() == {'ip_admin_eth0': ['192.168.1.2']} + assert path.config('conf3').value.dict() == {'ip_admin_eth0': ['192.168.1.2']} + ret = path.value.set('ip_admin_eth0', ['192.168.1.3'], force_default_if_same=True) + assert path.config('conf1').value.dict() == {'ip_admin_eth0': ['192.168.1.3']} + assert path.config('conf2').value.dict() == {'ip_admin_eth0': ['192.168.1.3']} + assert path.config('conf3').value.dict() == {'ip_admin_eth0': ['192.168.1.3']} + + +def test_path_properties_path_deepcopy(): + ip_admin_eth0 = NetworkOption('ip_admin_eth0', "ip", multi=True, default=['192.168.1.1']) + netmask_admin_eth0 = NetmaskOption('netmask_admin_eth0', "mask", multi=True, + properties=('disabled',)) + interface0 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + ip_admin_eth0 = NetworkOption('ip_admin_eth0', "ip", multi=True, default=['192.168.1.1']) + netmask_admin_eth0 = NetmaskOption('netmask_admin_eth0', "mask", multi=True, + properties=('disabled',)) + interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + ip_admin_eth0 = NetworkOption('ip_admin_eth0', "ip", multi=True, default=['192.168.1.1']) + netmask_admin_eth0 = NetmaskOption('netmask_admin_eth0', "mask", multi=True, + properties=('disabled',)) + interface2 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + conf1 = Config(interface0, session_id='conf1') + conf2 = Config(interface1, session_id='conf2') + conf1.property.read_write() + conf2.property.read_write() + path = PathConfig(interface2, [conf1, conf2]) + path.permissive.set(frozenset({'hidden'})) + path.property.read_write() + + path2 = path.config('conf1').config.deepcopy(session_id='conf3') + assert path != path2 + assert path.permissive.get() == path2.permissive.get() + + assert path.config('conf1').value.dict() == {'ip_admin_eth0': ['192.168.1.1']} + assert path.config('conf2').value.dict() == {'ip_admin_eth0': ['192.168.1.1']} + assert path2.config('conf3').value.dict() == {'ip_admin_eth0': ['192.168.1.1']} + path.option('ip_admin_eth0').value.set(['192.168.1.2']) + assert path.config('conf1').value.dict() == {'ip_admin_eth0': ['192.168.1.2']} + assert path.config('conf2').value.dict() == {'ip_admin_eth0': ['192.168.1.2']} + assert path2.config('conf3').value.dict() == {'ip_admin_eth0': ['192.168.1.1']} + path.value.set('ip_admin_eth0', ['192.168.1.3'], force_default_if_same=True) + assert path.config('conf1').value.dict() == {'ip_admin_eth0': ['192.168.1.3']} + assert path.config('conf2').value.dict() == {'ip_admin_eth0': ['192.168.1.3']} + assert path2.config('conf3').value.dict() == {'ip_admin_eth0': ['192.168.1.1']} + + +def test_path_properties_subpath_deepcopy(): + ip_admin_eth0 = NetworkOption('ip_admin_eth0', "ip", multi=True, default=['192.168.1.1']) + netmask_admin_eth0 = NetmaskOption('netmask_admin_eth0', "mask", multi=True, + properties=('disabled',)) + interface0 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + ip_admin_eth0 = NetworkOption('ip_admin_eth0', "ip", multi=True, default=['192.168.1.1']) + netmask_admin_eth0 = NetmaskOption('netmask_admin_eth0', "mask", multi=True, + properties=('disabled',)) + interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + ip_admin_eth0 = NetworkOption('ip_admin_eth0', "ip", multi=True, default=['192.168.1.1']) + netmask_admin_eth0 = NetmaskOption('netmask_admin_eth0', "mask", multi=True, + properties=('disabled',)) + interface2 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + conf1 = Config(interface0, session_id='conf1') + conf1.property.read_write() + path1 = PathConfig(interface1, [conf1], session_id='path1') + path2 = PathConfig(interface2, [path1], session_id='path2') + path_copy = conf1.config.deepcopy(session_id='conf2', + metaconfig_prefix='copy_') + assert path_copy.config.name() == 'copy_path2' + assert path_copy.config('copy_path1').config.name() == 'copy_path1' + assert path_copy.config('copy_path1').config('conf2').config.name() == 'conf2' + + +def test_path_properties_subpath_deepcopy_owner(): + ip_admin_eth0 = NetworkOption('ip_admin_eth0', "ip") + netmask_admin_eth0 = NetmaskOption('netmask_admin_eth1', "mask") + interface0 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + ip_admin_eth0 = NetworkOption('ip_admin_eth1', "ip") + netmask_admin_eth0 = NetmaskOption('netmask_admin_eth0', "mask") + interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + ip_admin_eth0 = NetworkOption('ip_admin_eth0', "ip") + netmask_admin_eth0 = NetmaskOption('netmask_admin_eth0', "mask") + interface2 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + conf1 = Config(interface0, session_id='conf1') + conf1.owner.set('conf1_user') + conf1.property.read_write() + path1 = PathConfig(interface1, [conf1], session_id='path1') + path1.owner.set('path1_user') + path2 = PathConfig(interface2, [path1], session_id='path2') + path2.owner.set('path2_user') + # + conf1.option('ip_admin_eth0').value.set('192.168.0.1') + assert conf1.option('ip_admin_eth0').owner.get() == 'conf1_user' + path2.option('ip_admin_eth0').value.set('192.168.0.3') + assert path2.option('ip_admin_eth0').owner.get() == 'path2_user' + # + path2_copy = conf1.config.deepcopy(session_id='conf2', + metaconfig_prefix='copy_') + path2_copy.option('netmask_admin_eth0').value.set('255.255.255.255') + assert path2_copy.option('ip_admin_eth0').value.get() == '192.168.0.3' + assert path2_copy.option('ip_admin_eth0').owner.get() == 'path2_user' + assert path2_copy.option('netmask_admin_eth0').owner.get() == 'path2_user' + # + path1_copy = path2_copy.config('copy_path1') + path1_copy.option('netmask_admin_eth0').value.set('255.255.255.255') + # + conf2 = path1_copy.config('conf2') + conf2.owner.set('conf2_user') + conf2.option('netmask_admin_eth1').value.set('255.255.255.255') + assert conf2.option('netmask_admin_eth1').owner.get() == 'conf2_user' + assert conf2.option('ip_admin_eth0').value.get() == '192.168.0.1' + assert conf2.option('ip_admin_eth0').owner.get() == 'conf1_user' + + +def test_path_properties_path_set_value(): + ip_admin_eth0 = NetworkOption('ip_admin_eth1', "ip", multi=True, default=['192.168.1.1']) + netmask_admin_eth0 = NetmaskOption('netmask_admin_eth0', "mask", multi=True, properties=('disabled',)) + interface0 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + ip_admin_eth0 = NetworkOption('ip_admin_eth0', "ip", multi=True, default=['192.168.1.1']) + netmask_admin_eth0 = NetmaskOption('netmask_admin_eth1', "mask", multi=True, properties=('disabled',)) + interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + ip_admin_eth0 = NetworkOption('ip_admin_eth0', "ip", multi=True, default=['192.168.1.1']) + netmask_admin_eth0 = NetmaskOption('netmask_admin_eth0', "mask", multi=True, properties=('disabled',)) + interface2 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + conf1 = Config(interface0, session_id='conf1') + conf2 = Config(interface1, session_id='conf2') + conf1.property.read_write() + conf2.property.read_write() + path = PathConfig(interface2, [conf1, conf2]) + path.property.read_write() + assert path.config('conf2').value.dict() == {'ip_admin_eth0': ['192.168.1.1']} + ret = path.value.set('netmask_admin_eth0', ['255.255.255.255'], only_config=True) + assert len(ret) == 2 + assert isinstance(ret[0], PropertiesOptionError) + assert isinstance(ret[1], AttributeError) + del ret[1] + del ret[0] + del ret + ret = path.value.set('netmask_admin_eth0', ['255.255.255.255'], force_default=True) + assert len(ret) == 2 + assert isinstance(ret[0], AttributeError) + assert isinstance(ret[1], PropertiesOptionError) + del ret[1] + del ret[0] + del ret + ret = path.value.set('netmask_admin_eth0', ['255.255.255.255'], force_dont_change_value=True) + assert len(ret) == 3 + assert isinstance(ret[0], PropertiesOptionError) + assert isinstance(ret[1], AttributeError) + assert isinstance(ret[2], PropertiesOptionError) + del ret[2] + del ret[1] + del ret[0] + del ret + ret = path.value.set('netmask_admin_eth0', ['255.255.255.255'], force_default_if_same=True) + assert len(ret) == 2 + assert isinstance(ret[0], AttributeError) + assert isinstance(ret[1], PropertiesOptionError) + del ret[1] + del ret[0] + del ret + ret = path.value.set('ip_admin_eth0', '255.255.255.255', only_config=True) + assert len(ret) == 2 + assert isinstance(ret[0], AttributeError) + assert isinstance(ret[1], ValueError) + del ret[1] + del ret[0] + del ret + ret = path.value.set('ip_admin_eth0', '255.255.255.255', force_default=True) + assert len(ret) == 2 + assert isinstance(ret[0], AttributeError) + assert isinstance(ret[1], ValueError) + del ret[1] + del ret[0] + del ret + ret = path.value.set('ip_admin_eth0', '255.255.255.255', force_dont_change_value=True) + assert len(ret) == 2 + assert isinstance(ret[0], AttributeError) + assert isinstance(ret[1], ValueError) + del ret[1] + del ret[0] + del ret + ret = path.value.set('ip_admin_eth0', '255.255.255.255', force_default_if_same=True) + assert len(ret) == 2 + assert isinstance(ret[0], AttributeError) + assert isinstance(ret[1], ValueError) + del ret[1] + del ret[0] + del ret diff --git a/test/test_permissive.py b/test/test_permissive.py index 3e9ace8..c8aebe7 100644 --- a/test/test_permissive.py +++ b/test/test_permissive.py @@ -7,6 +7,11 @@ from py.test import raises from tiramisu import IntOption, UnicodeOption, OptionDescription, Config from tiramisu.error import PropertiesOptionError, ConfigError from tiramisu.api import TIRAMISU_VERSION +from tiramisu.storage import list_sessions, delete_session + + +def teardown_function(function): + assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__) def make_description(): diff --git a/test/test_requires.py b/test/test_requires.py index 7a9334d..1a17aad 100644 --- a/test/test_requires.py +++ b/test/test_requires.py @@ -11,6 +11,11 @@ from tiramisu import IPOption, OptionDescription, BoolOption, IntOption, StrOpti MasterSlaves, Config from tiramisu.error import PropertiesOptionError, RequirementError from py.test import raises +from tiramisu.storage import list_sessions, delete_session + + +def teardown_function(function): + assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__) def test_properties(): @@ -437,6 +442,8 @@ def test_requires_transitive_hidden_disabled_multiple(): except PropertiesOptionError as err: props = err.proptype assert set(props) == {'disabled', 'hidden'} + del props + # req = None try: api.option('ip_address_service_web').value.get() @@ -444,6 +451,8 @@ def test_requires_transitive_hidden_disabled_multiple(): req = err assert req, "ip_address_service_web should raise RequirementError" assert str(req) == str(_('cannot access to option "{}" because required option "{}" has {} {}').format('ip_address_service_web', 'activate_service_web', 'property', '"disabled"')) + del req + # api.permissive.set(frozenset()) try: api.option('ip_address_service_web').value.get() @@ -451,6 +460,7 @@ def test_requires_transitive_hidden_disabled_multiple(): req = err assert req, "ip_address_service_web should raise RequirementError" assert str(req) == str(_('cannot access to option "{}" because required option "{}" has {} {}').format('ip_address_service_web', 'activate_service_web', 'properties', '"disabled" and "hidden"')) + del req def test_requires_not_transitive(): @@ -950,7 +960,7 @@ def test_master_slave_requires(): api.option('ip_admin_eth0.netmask_admin_eth0', 1).value.set('255.255.255.255') assert api.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get() == '255.255.255.255' assert api.value.dict() == {'ip_admin_eth0.ip_admin_eth0': ['192.168.1.2', '192.168.1.2'], - 'ip_admin_eth0.netmask_admin_eth0': [None, '255.255.255.255']} + 'ip_admin_eth0.netmask_admin_eth0': [None, '255.255.255.255']} # api.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.2', '192.168.1.1']) assert api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() is None @@ -959,8 +969,11 @@ def test_master_slave_requires(): assert set(ret.keys()) == set(['ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0']) assert ret['ip_admin_eth0.ip_admin_eth0'] == ['192.168.1.2', '192.168.1.1'] assert len(ret['ip_admin_eth0.netmask_admin_eth0']) == 2 - assert ret['ip_admin_eth0.netmask_admin_eth0'][0] == None + assert ret['ip_admin_eth0.netmask_admin_eth0'][0] is None assert isinstance(ret['ip_admin_eth0.netmask_admin_eth0'][1], PropertiesOptionError) + del ret['ip_admin_eth0.netmask_admin_eth0'][1] + del ret['ip_admin_eth0.netmask_admin_eth0'][0] + del ret['ip_admin_eth0.netmask_admin_eth0'] # api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set('255.255.255.255') ret = api.value.dict() @@ -969,6 +982,9 @@ def test_master_slave_requires(): assert len(ret['ip_admin_eth0.netmask_admin_eth0']) == 2 assert ret['ip_admin_eth0.netmask_admin_eth0'][0] == '255.255.255.255' assert isinstance(ret['ip_admin_eth0.netmask_admin_eth0'][1], PropertiesOptionError) + del ret['ip_admin_eth0.netmask_admin_eth0'][1] + del ret['ip_admin_eth0.netmask_admin_eth0'][0] + del ret['ip_admin_eth0.netmask_admin_eth0'] def test_master_slave_requires_both(): diff --git a/test/test_slots.py b/test/test_slots.py index 1a9c5ae..47b049c 100644 --- a/test/test_slots.py +++ b/test/test_slots.py @@ -15,41 +15,61 @@ from tiramisu.option import ChoiceOption, BoolOption, IntOption, FloatOption,\ StrOption, SymLinkOption, UnicodeOption, IPOption, OptionDescription, \ PortOption, NetworkOption, NetmaskOption, DomainnameOption, EmailOption, \ URLOption, FilenameOption +from tiramisu.storage import list_sessions, delete_session + + +def teardown_function(function): + assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__) def test_slots_option(): c = ChoiceOption('a', '', ('a',)) raises(AttributeError, "c.x = 1") + del c c = BoolOption('a', '') raises(AttributeError, "c.x = 1") + del c c = IntOption('a', '') raises(AttributeError, "c.x = 1") + del c c = FloatOption('a', '') raises(AttributeError, "c.x = 1") + del c c = StrOption('a', '') raises(AttributeError, "c.x = 1") c = SymLinkOption('b', c) raises(AttributeError, "c.x = 1") + del c c = UnicodeOption('a', '') raises(AttributeError, "c.x = 1") + del c c = IPOption('a', '') raises(AttributeError, "c.x = 1") + del c c = OptionDescription('a', '', []) raises(AttributeError, "c.x = 1") + del c c = PortOption('a', '') raises(AttributeError, "c.x = 1") + del c c = NetworkOption('a', '') raises(AttributeError, "c.x = 1") + del c c = NetmaskOption('a', '') raises(AttributeError, "c.x = 1") + del c c = DomainnameOption('a', '') raises(AttributeError, "c.x = 1") + del c c = EmailOption('a', '') raises(AttributeError, "c.x = 1") + del c c = URLOption('a', '') raises(AttributeError, "c.x = 1") + del c c = FilenameOption('a', '') raises(AttributeError, "c.x = 1") + del c def test_slots_option_readonly(): diff --git a/test/test_state.py b/test/test_state.py index eb8013b..231b768 100644 --- a/test/test_state.py +++ b/test/test_state.py @@ -7,6 +7,11 @@ from tiramisu import Config from pickle import dumps from py.test import raises import sys +from tiramisu.storage import list_sessions + + +def teardown_function(function): + assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__) def _get_slots(opt): diff --git a/test/test_storage.py b/test/test_storage.py index 86b4fd2..c17e762 100644 --- a/test/test_storage.py +++ b/test/test_storage.py @@ -11,6 +11,10 @@ from tiramisu.setting import groups, owners from tiramisu.storage import list_sessions, delete_session +def teardown_function(function): + assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__) + + def test_non_persistent(): b = BoolOption('b', '') o = OptionDescription('od', '', [b]) @@ -22,9 +26,9 @@ def test_list(): o = OptionDescription('od', '', [b]) c = Config(o, session_id='test_non_persistent') c.option('b').value.set(True) - assert 'test_non_persistent' in list_sessions('config') + assert 'test_non_persistent' in list_sessions() del(c) - assert 'test_non_persistent' not in list_sessions('config') + assert 'test_non_persistent' not in list_sessions() def test_delete_not_persisten(): @@ -34,9 +38,9 @@ def test_delete_not_persisten(): Config(o, session_id='test_persistent', persistent=True) except: c = Config(o, session_id='not_test_persistent') - assert 'not_test_persistent' in list_sessions('all') + assert 'not_test_persistent' in list_sessions() del c - assert 'not_test_persistent' not in list_sessions('all') + assert 'not_test_persistent' not in list_sessions() # c = Config(o, session_id='not_test_persistent') raises(ValueError, "delete_session('not_test_persistent')") @@ -73,7 +77,7 @@ def test_list_sessions_persistent(): # storage is not persistent pass else: - assert 'test_persistent' in list_sessions('config') + assert 'test_persistent' in list_sessions() delete_session('test_persistent') @@ -86,9 +90,9 @@ def test_delete_session_persistent(): # storage is not persistent pass else: - assert 'test_persistent' in list_sessions('config') + assert 'test_persistent' in list_sessions() delete_session('test_persistent') - assert 'test_persistent' not in list_sessions('config') + assert 'test_persistent' not in list_sessions() def test_create_persistent_retrieve(): @@ -106,7 +110,7 @@ def test_create_persistent_retrieve(): del c c = Config(o, session_id='test_persistent', persistent=True) assert c.option('b').value.get() is True - assert 'test_persistent' in list_sessions('config') + assert 'test_persistent' in list_sessions() delete_session(c.config.name()) del c c = Config(o, session_id='test_persistent', persistent=True) diff --git a/test/test_submulti.py b/test/test_submulti.py index 935bf04..f0cb4a7 100644 --- a/test/test_submulti.py +++ b/test/test_submulti.py @@ -9,8 +9,12 @@ from tiramisu.setting import groups, owners from tiramisu import StrOption, IntOption, OptionDescription, submulti, MasterSlaves, Config, \ MetaConfig, undefined, Params, ParamOption from tiramisu.error import SlaveError +from tiramisu.storage import list_sessions +def teardown_function(function): + assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__) + def return_val(val=None): if val is None: diff --git a/test/test_symlink.py b/test/test_symlink.py index eaa701f..d92f0bf 100644 --- a/test/test_symlink.py +++ b/test/test_symlink.py @@ -1,4 +1,5 @@ # coding: utf-8 +from py.test import raises from .autopath import do_autopath do_autopath() @@ -7,8 +8,11 @@ from tiramisu import BoolOption, StrOption, SymLinkOption, \ from tiramisu.error import PropertiesOptionError, ConfigError from tiramisu.setting import groups, owners from tiramisu.api import TIRAMISU_VERSION +from tiramisu.storage import list_sessions -from py.test import raises + +def teardown_function(function): + assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__) def return_value(): @@ -60,7 +64,12 @@ def test_symlink_addproperties(): api = Config(descr) api.property.read_write() raises(TypeError, "api.option('c').property.add('new')") - raises(AssertionError, "api.option('c').property.reset()") + try: + api.option('c').property.reset() + except AssertionError: + pass + else: + raise Exception('must raise') def test_symlink_getpermissive(): @@ -73,14 +82,19 @@ def test_symlink_getpermissive(): api.option('c').permissive.get() == frozenset(['perm']) -def test_symlink_addpermissive(): +def test_symlink_addpermissives(): boolopt = BoolOption('b', '', default=True, properties=('test',)) linkopt = SymLinkOption("c", boolopt) descr = OptionDescription('opt', '', [boolopt, linkopt]) api = Config(descr) api.property.read_write() raises(TypeError, "api.option('c').permissive.set(frozenset(['new']))") - raises(AssertionError, "api.option('c').permissive.reset()") + try: + api.option('c').permissive.reset() + except AssertionError: + pass + else: + raise Exception('must raise') def test_symlink_getproperties(): diff --git a/tiramisu/__init__.py b/tiramisu/__init__.py index ff4a491..bd56efd 100644 --- a/tiramisu/__init__.py +++ b/tiramisu/__init__.py @@ -15,7 +15,7 @@ from .function import Params, ParamOption, ParamValue, ParamContext from .option import * from .error import APIError -from .api import Config, MetaConfig, GroupConfig +from .api import Config, MetaConfig, GroupConfig, PathConfig from .option import __all__ as all_options from .setting import owners, undefined @@ -25,6 +25,7 @@ allfuncs = ['Params', 'ParamValue', 'ParamContext', 'MetaConfig', + 'PathConfig', 'GroupConfig', 'Config', 'APIError', diff --git a/tiramisu/api.py b/tiramisu/api.py index 2aebdbe..a2c4a28 100644 --- a/tiramisu/api.py +++ b/tiramisu/api.py @@ -22,7 +22,7 @@ from typing import List, Any, Optional, Callable, Union, Dict from .error import APIError, ConfigError, SlaveError, PropertiesOptionError from .i18n import _ from .setting import ConfigBag, OptionBag, owners, groups, Undefined, undefined, FORBIDDEN_SET_PROPERTIES -from .config import KernelConfig, SubConfig, KernelGroupConfig, KernelMetaConfig +from .config import KernelConfig, SubConfig, KernelGroupConfig, KernelMetaConfig, KernelPathConfig from .option import ChoiceOption, OptionDescription @@ -227,14 +227,9 @@ class TiramisuOptionOption(CommonTiramisuOption): name, subconfig, option_bag): - cls._name = name - cls._subconfig = subconfig - cls._option_bag = option_bag - cls._get_option(cls) - option = option_bag.option - del cls._name - del cls._subconfig - del cls._option_bag + option = subconfig.cfgimpl_get_description().impl_getchild(name, + option_bag.config_bag, + subconfig.cfgimpl_get_path()) if option.impl_is_optiondescription(): return _TiramisuOptionOptionDescription(name=name, subconfig=subconfig, @@ -396,7 +391,8 @@ class TiramisuOptionInformation(CommonTiramisuOption): values = self._option_bag.config_bag.context.cfgimpl_get_values() values.set_information(key, value, path=path) - def reset(self, key): + def reset(self, + key): """Remove information""" path = self._option_bag.path values = self._option_bag.config_bag.context.cfgimpl_get_values() @@ -541,7 +537,7 @@ class TiramisuOptionValue(CommonTiramisuOption): types.append(_TiramisuOptionValueMaster) elif option.impl_is_master_slaves('slave'): types.append(_TiramisuOptionValueSlave) - if option_bag.config_bag.context.impl_type == 'meta': + if option_bag.config_bag.context.impl_type in ('meta', 'path'): # only if not an optiondescription types.insert(0, _TiramisuOptionValueMeta) if option_bag.config_bag.context.impl_type == 'group': @@ -657,6 +653,24 @@ class _TiramisuOptionDescription(_TiramisuOption): """Get type for an optiondescription (only for optiondescription)""" return self._get_option().impl_get_group_type() + def _filter(self, + opt, + subconfig): + if self._config_bag.properties: + name = opt.impl_getname() + path = subconfig._get_subpath(name) + option_bag = OptionBag() + option_bag.set_option(opt, + path, + None, + self._config_bag) + if opt.impl_is_optiondescription(): + self._subconfig.get_subconfig(name, + option_bag) + else: + subconfig.getattr(name, + option_bag) + def list(self, type='option', group_type=None): @@ -664,22 +678,6 @@ class _TiramisuOptionDescription(_TiramisuOption): assert type in ('all', 'option', 'optiondescription'), _('unknown list type {}').format(type) assert group_type is None or isinstance(group_type, groups.GroupType), \ _("unknown group_type: {0}").format(group_type) - def _filter(opt): - if self._config_bag.properties: - name = opt.impl_getname() - path = subconfig._get_subpath(name) - option_bag = OptionBag() - option_bag.set_option(opt, - path, - None, - self._config_bag) - if opt.impl_is_optiondescription(): - self._subconfig.get_subconfig(name, - option_bag) - else: - subconfig.getattr(name, - option_bag) - option = self._get_option() name = option.impl_getname() path = self._subconfig._get_subpath(name) @@ -692,7 +690,8 @@ class _TiramisuOptionDescription(_TiramisuOption): option_bag) for opt in option.impl_getchildren(self._config_bag): try: - subsubconfig = _filter(opt) + subsubconfig = self._filter(opt, + subconfig) except PropertiesOptionError: continue if opt.impl_is_optiondescription(): @@ -998,52 +997,64 @@ class TiramisuContextOption(TiramisuContext): return next(self._find(name, value, type)) return self._find(name, value, type) + def _filter(self, + opt): + if self._config_bag.properties: + name = opt.impl_getname() + option_bag = OptionBag() + option_bag.set_option(opt, + name, + None, + self._config_bag) + if opt.impl_is_optiondescription(): + self._config_bag.context.cfgimpl_get_settings().validate_properties(option_bag) + else: + self._config_bag.context.getattr(name, + option_bag) + def _walk(self, + option, + recursive, + type_, + group_type): + for opt in option.impl_getchildren(self._config_bag): + try: + subsubconfig = self._filter(opt) + except PropertiesOptionError: + continue + if opt.impl_is_optiondescription(): + if recursive: + for toption in self._walk(opt, + recursive, + type_, + group_type): + yield toption + if type_ == 'option' or (type_ == 'optiondescription' and \ + group_type and opt.impl_get_group_type() != group_type): + continue + elif type_ == 'optiondescription': + continue + path = opt.impl_getpath() + subconfig, name = self._config_bag.context.cfgimpl_get_home_by_path(path, + self._config_bag) + yield TiramisuOption(name, + path, + None, + subconfig, + self._config_bag) + def list(self, type='option', group_type=None, recursive=False): """List options (by default list only option)""" - def _filter(opt): - if self._config_bag.properties: - name = opt.impl_getname() - option_bag = OptionBag() - option_bag.set_option(opt, - name, - None, - self._config_bag) - if opt.impl_is_optiondescription(): - self._config_bag.context.cfgimpl_get_settings().validate_properties(option_bag) - else: - self._config_bag.context.getattr(name, - option_bag) - def _walk(option): - for opt in option.impl_getchildren(self._config_bag): - try: - subsubconfig = _filter(opt) - except PropertiesOptionError: - continue - if opt.impl_is_optiondescription(): - if recursive: - for toption in _walk(opt): - yield toption - if type == 'option' or (type == 'optiondescription' and \ - group_type and opt.impl_get_group_type() != group_type): - continue - elif type == 'optiondescription': - continue - path = opt.impl_getpath() - subconfig, name = self._config_bag.context.cfgimpl_get_home_by_path(path, - self._config_bag) - yield TiramisuOption(name, - path, - None, - subconfig, - self._config_bag) assert type in ('all', 'option', 'optiondescription'), _('unknown list type {}').format(type) assert group_type is None or isinstance(group_type, groups.GroupType), \ _("unknown group_type: {0}").format(group_type) option = self._config_bag.context.cfgimpl_get_description() - for toption in _walk(option): + for toption in self._walk(option, + recursive, + type, + group_type): yield toption @@ -1138,6 +1149,11 @@ class _TiramisuContextGroupConfig(TiramisuContext): return Config(config) +class _TiramisuContextPathConfig(_TiramisuContextGroupConfig, _TiramisuContextConfigReset): + """Actions to PathConfig""" + pass + + class _TiramisuContextMetaConfig(_TiramisuContextGroupConfig, _TiramisuContextConfigReset): """Actions to MetaConfig""" def new(self, @@ -1150,7 +1166,7 @@ class _TiramisuContextMetaConfig(_TiramisuContextGroupConfig, _TiramisuContextCo type_=type)) def pop(self, - session_id): + session_id): """Remove config from MetaConfig""" return Config(self._config_bag.context.pop_config(session_id=session_id)) @@ -1186,6 +1202,8 @@ class TiramisuAPI(TiramisuHelp): config = _TiramisuContextGroupConfig elif config_type == 'meta': config = _TiramisuContextMetaConfig + elif config_type == 'path': + config = _TiramisuContextPathConfig else: config = _TiramisuContextConfig return config(self._config_bag) @@ -1258,6 +1276,26 @@ class MetaConfig(TiramisuAPI): super().__init__(config) +class PathConfig(TiramisuAPI): + """MetaConfig object that enables us to handle the sub configuration's options""" + def __init__(self, + optiondescription: OptionDescription, + children: List[Config], + session_id: Optional[str]=None, + persistent: bool=False) -> None: + _children = [] + for child in children: + if isinstance(child, TiramisuAPI): + _children.append(child._config_bag.context) + else: + _children.append(child) + + config = KernelPathConfig(optiondescription, + _children, + session_id=session_id, + persistent=persistent) + super().__init__(config) + class GroupConfig(TiramisuAPI): """GroupConfig that enables us to access the Config""" diff --git a/tiramisu/autolib.py b/tiramisu/autolib.py index f8b8558..01e6ac4 100644 --- a/tiramisu/autolib.py +++ b/tiramisu/autolib.py @@ -300,4 +300,5 @@ def calculate(option, '').format(str(error), callback.__name__, option.impl_get_display_name()) + del error raise ConfigError(msg) diff --git a/tiramisu/config.py b/tiramisu/config.py index c2ce5af..9001baa 100644 --- a/tiramisu/config.py +++ b/tiramisu/config.py @@ -668,7 +668,7 @@ class _CommonConfig(SubConfig): metaconfig_prefix=None, child=None, deep=False): - assert isinstance(self, (KernelConfig, KernelMetaConfig)), _('cannot duplicate {}').format(self.__class__.__name__) + assert isinstance(self, (KernelConfig, KernelPathConfig)), _('cannot duplicate {}').format(self.__class__.__name__) if isinstance(self, KernelConfig): duplicated_config = KernelConfig(self._impl_descr, _duplicate=True, @@ -677,7 +677,7 @@ class _CommonConfig(SubConfig): force_settings=force_settings, persistent=persistent, storage=storage) - elif isinstance(self, KernelMetaConfig): + else: if session_id is None and metaconfig_prefix is not None: session_id = metaconfig_prefix + self.impl_getname() duplicated_config = KernelMetaConfig([], @@ -809,7 +809,7 @@ class KernelGroupConfig(_CommonConfig): resetted_opts=None): if resetted_opts is None: resetted_opts = [] - if isinstance(self, KernelMetaConfig): + if isinstance(self, KernelPathConfig): super().cfgimpl_reset_cache(option_bag, resetted_opts=copy(resetted_opts)) for child in self._impl_children: @@ -834,15 +834,15 @@ class KernelGroupConfig(_CommonConfig): for child in self._impl_children: cconfig_bag = config_bag.copy() cconfig_bag.context = child - try: - if isinstance(child, KernelGroupConfig): - ret.extend(child.set_value(path, - index, - value, - cconfig_bag, - only_config=only_config, - _commit=commit)) - else: + if isinstance(child, KernelGroupConfig): + ret.extend(child.set_value(path, + index, + value, + cconfig_bag, + only_config=only_config, + _commit=commit)) + else: + try: subconfig, name = child.cfgimpl_get_home_by_path(path, cconfig_bag) option = subconfig.cfgimpl_get_description().impl_getchild(name, @@ -856,16 +856,16 @@ class KernelGroupConfig(_CommonConfig): child.setattr(value, option_bag, _commit=commit) - except PropertiesOptionError as err: - ret.append(PropertiesOptionError(err._option_bag, - err.proptype, - err._settings, - err._opt_type, - err._requires, - err._name, - err._orig_opt)) - except (ValueError, SlaveError) as err: - ret.append(err) + except PropertiesOptionError as err: + ret.append(PropertiesOptionError(err._option_bag, + err.proptype, + err._settings, + err._opt_type, + err._requires, + err._name, + err._orig_opt)) + except (ValueError, SlaveError, AttributeError) as err: + ret.append(err) if _commit and self.impl_type != 'group': self.cfgimpl_get_values()._p_.commit() return ret @@ -885,7 +885,7 @@ class KernelGroupConfig(_CommonConfig): #so search only one time the option for all children if bypath is undefined and byname is not None and \ isinstance(self, - KernelMetaConfig): + KernelPathConfig): bypath = next(self.find(bytype=None, byvalue=undefined, byname=byname, @@ -954,47 +954,30 @@ class KernelGroupConfig(_CommonConfig): raise ConfigError(_('unknown config "{}"').format(name)) -class KernelMetaConfig(KernelGroupConfig): +class KernelPathConfig(KernelGroupConfig): __slots__ = tuple() - impl_type = 'meta' + impl_type = 'path' def __init__(self, + optiondescription, children, session_id=None, persistent=False, - optiondescription=None, storage=None, _duplicate=False): - descr = None - if optiondescription is not None: - if not _duplicate: - new_children = [] - for child_session_id in children: - assert isinstance(child_session_id, str), _('MetaConfig with optiondescription' - ' must have string has child, ' - 'not {}').format(child_session_id) - new_children.append(KernelConfig(optiondescription, - persistent=persistent, - session_id=child_session_id)) - children = new_children - descr = optiondescription + # FIXME _duplicate for child in children: if not isinstance(child, _CommonConfig): try: child = child._config except: - raise TypeError(_("metaconfig's children " - "should be config, not {0}" - ).format(type(child))) + raise TypeError(_("{}config's children " + "should be config, not {}" + ).format(self.impl_type, + type(child))) if child.cfgimpl_get_meta() is not None: - raise ValueError(_("child has already a metaconfig's")) - if descr is None: - descr = child.cfgimpl_get_description() - elif not descr is child.cfgimpl_get_description(): - raise ValueError(_('all config in metaconfig must ' - 'have the same optiondescription')) + raise ValueError(_("child has already a {}config's").format(self.impl_type)) child._impl_meta = weakref.ref(self) - properties, permissives, values, session_id = get_storages(self, session_id, persistent, @@ -1004,7 +987,7 @@ class KernelMetaConfig(KernelGroupConfig): self._impl_values = Values(values) super().__init__(children, session_id=session_id, - _descr=descr) + _descr=optiondescription) self._impl_build_all_caches() def set_value(self, @@ -1036,41 +1019,49 @@ class KernelMetaConfig(KernelGroupConfig): if force_default and force_dont_change_value: raise ValueError(_('force_default and force_dont_change_value' ' cannot be set together')) - opt = self.cfgimpl_get_description().impl_get_opt_by_path(path, - config_bag) + #opt = self.cfgimpl_get_description().impl_get_opt_by_path(path, + # config_bag) for child in self._impl_children: cconfig_bag = config_bag.copy() cconfig_bag.context = child - subconfig, name = child.cfgimpl_get_home_by_path(path, - cconfig_bag) - option = subconfig.cfgimpl_get_description().impl_getchild(name, - cconfig_bag, - child.cfgimpl_get_path()) - option_bag = OptionBag() - option_bag.set_option(option, - path, - index, - cconfig_bag) - if force_default_if_same: - if not child.cfgimpl_get_values()._p_.hasvalue(path): - child_value = undefined - else: - child_value = child.getattr(name, - option_bag) - if force_default or (force_default_if_same and value == child_value): - child.cfgimpl_get_values().reset(option_bag, - _commit=False) - continue - if force_dont_change_value: - try: + try: + subconfig, name = child.cfgimpl_get_home_by_path(path, + cconfig_bag) + option = subconfig.cfgimpl_get_description().impl_getchild(name, + cconfig_bag, + child.cfgimpl_get_path()) + option_bag = OptionBag() + option_bag.set_option(option, + path, + index, + cconfig_bag) + if force_default_if_same: + if not child.cfgimpl_get_values()._p_.hasvalue(path): + child_value = undefined + else: + child_value = child.getattr(name, + option_bag) + if force_default or (force_default_if_same and value == child_value): + child.cfgimpl_get_values().reset(option_bag, + _commit=False) + continue + if force_dont_change_value: child_value = child.getattr(name, option_bag) if value != child_value: child.setattr(child_value, option_bag, _commit=False) - except (PropertiesOptionError, ValueError, SlaveError) as err: - ret.append(err) + except PropertiesOptionError as err: + ret.append(PropertiesOptionError(err._option_bag, + err.proptype, + err._settings, + err._opt_type, + err._requires, + err._name, + err._orig_opt)) + except (ValueError, SlaveError, AttributeError) as err: + ret.append(err) try: subconfig, name = self.cfgimpl_get_home_by_path(path, @@ -1109,6 +1100,51 @@ class KernelMetaConfig(KernelGroupConfig): option_bag.config_bag.context = child child.cfgimpl_get_values().reset(option_bag) + +class KernelMetaConfig(KernelPathConfig): + __slots__ = tuple() + impl_type = 'meta' + + def __init__(self, + children, + session_id=None, + persistent=False, + optiondescription=None, + storage=None, + _duplicate=False): + descr = None + if optiondescription is not None: + if not _duplicate: + new_children = [] + for child_session_id in children: + assert isinstance(child_session_id, str), _('MetaConfig with optiondescription' + ' must have string has child, ' + 'not {}').format(child_session_id) + new_children.append(KernelConfig(optiondescription, + persistent=persistent, + session_id=child_session_id)) + children = new_children + descr = optiondescription + for child in children: + if not isinstance(child, _CommonConfig): + try: + child = child._config + except: + raise TypeError(_("{}config's children " + "should be config, not {}" + ).format(self.impl_type, + type(child))) + if descr is None: + descr = child.cfgimpl_get_description() + elif descr is not child.cfgimpl_get_description(): + raise ValueError(_('all config in metaconfig must ' + 'have the same optiondescription')) + super().__init__(descr, + children, + persistent=persistent, + storage=storage, + session_id=session_id) + def new_config(self, session_id, type_='config', diff --git a/tiramisu/option/choiceoption.py b/tiramisu/option/choiceoption.py index 33b0bd8..9a599c4 100644 --- a/tiramisu/option/choiceoption.py +++ b/tiramisu/option/choiceoption.py @@ -108,7 +108,7 @@ class ChoiceOption(Option): current_opt=undefined): values = self.impl_get_values(option_bag, current_opt=current_opt) - if values is not undefined and not value in values: + if values is not undefined and value not in values: if len(values) == 1: raise ValueError(_('only "{0}" is allowed' '').format(values[0])) diff --git a/tiramisu/storage/__init__.py b/tiramisu/storage/__init__.py index 1668b5f..b74a794 100644 --- a/tiramisu/storage/__init__.py +++ b/tiramisu/storage/__init__.py @@ -115,12 +115,9 @@ def get_default_settings_storages(): return properties, permissives -def list_sessions(type_): +def list_sessions(): """List all available session (persistent or not persistent) """ - #if type_ == 'option': - # return storage_option_type.get().list_sessions() - #else: return storage_type.get().list_sessions()