# -*- coding: utf-8 -*- """theses tests are much more to test that config, option description, vs... **it's there** and answers via attribute access""" import weakref from .autopath import do_autopath do_autopath() from .config import config_type, get_config, value_list, global_owner import pytest from tiramisu import Config from tiramisu.config import SubConfig from tiramisu.i18n import _ from tiramisu import Config, IntOption, FloatOption, ChoiceOption, \ BoolOption, StrOption, SymLinkOption, 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(): gcoption = ChoiceOption('name', 'GC name', ('ref', 'framework'), 'ref') gcdummy = BoolOption('dummy', 'dummy', default=False) objspaceoption = ChoiceOption('objspace', 'Object space', ('std', 'thunk'), 'std') booloption = BoolOption('bool', 'Test boolean option', default=True) intoption = IntOption('int', 'Test int option', default=0) floatoption = FloatOption('float', 'Test float option', default=2.3) stroption = StrOption('str', 'Test string option', default="abc", properties=('mandatory', )) boolop = BoolOption('boolop', 'Test boolean option op', default=True, properties=('hidden',)) wantref_option = BoolOption('wantref', 'Test requires', default=False) wantref_option.impl_set_information('info', 'default value') wantframework_option = BoolOption('wantframework', 'Test requires', default=False) gcgroup = OptionDescription('gc', '', [gcoption, gcdummy, floatoption]) descr = OptionDescription('tiram', '', [gcgroup, booloption, objspaceoption, wantref_option, stroption, wantframework_option, intoption, boolop]) return descr @pytest.mark.asyncio async def test_base_config(config_type): """making a :class:`tiramisu.config.Config()` object and a :class:`tiramisu.option.OptionDescription()` object """ gcdummy = BoolOption('dummy', 'dummy', default=False) descr = OptionDescription('tiramisu', '', [gcdummy]) cfg = await Config(descr) cfg = await get_config(cfg, config_type) assert await cfg.option('dummy').value.get() is False #dmo = await cfg.unwrap_from_path('dummy') #assert dmo.impl_getname() == 'dummy' @pytest.mark.asyncio async def test_base_config_name(): gcdummy = BoolOption('dummy', 'dummy', default=False) descr = OptionDescription('tiramisu', '', [gcdummy]) cfg = await Config(descr, session_id='cfg') await cfg.config.name() == 'cfg' #raises(ValueError, "Config(descr, session_id='unvalid name')") # # #@pytest.mark.asyncio #async def test_not_config(): # assert raises(TypeError, "Config('str')") @pytest.mark.asyncio async def test_base_path(): gcdummy = BoolOption('dummy', 'dummy', default=False) descr = OptionDescription('tiramisu', '', [gcdummy]) await Config(descr) base = OptionDescription('config', '', [descr]) base with pytest.raises(ConfigError): await Config(base) @pytest.mark.asyncio async def test_base_config_force_permissive(): descr = make_description() cfg = await Config(descr) await cfg.property.read_write() await cfg.permissive.add('hidden') with pytest.raises(PropertiesOptionError): await cfg.option('boolop').value.get() assert await cfg.forcepermissive.option('boolop').value.get() is True @pytest.mark.asyncio async def test_base_config_in_a_tree(): # FIXME config_type = 'tiramisu' "how options are organized into a tree, see :ref:`tree`" descr = make_description() cfg = await Config(descr) cfg = await get_config(cfg, config_type) # await cfg.option('bool').value.set(False) # assert await cfg.option('gc.name').value.get() == 'ref' await cfg.option('gc.name').value.set('framework') assert await cfg.option('gc.name').value.get() == 'framework' # assert await cfg.option('objspace').value.get() == 'std' await cfg.option('objspace').value.set('thunk') assert await cfg.option('objspace').value.get() == 'thunk' # assert await cfg.option('gc.float').value.get() == 2.3 await cfg.option('gc.float').value.set(3.4) assert await cfg.option('gc.float').value.get() == 3.4 # assert await cfg.option('int').value.get() == 0 await cfg.option('int').value.set(123) assert await cfg.option('int').value.get() == 123 # assert await cfg.option('wantref').value.get() is False await cfg.option('wantref').value.set(True) assert await cfg.option('wantref').value.get() is True # assert await cfg.option('str').value.get() == 'abc' await cfg.option('str').value.set('def') assert await cfg.option('str').value.get() == 'def' # with pytest.raises(AttributeError): await cfg.option('gc.foo').value.get() ## cfg = await Config(descr) assert await cfg.option('bool').value.get() is True assert await cfg.option('gc.name').value.get() == 'ref' assert await cfg.option('wantframework').value.get() is False @pytest.mark.asyncio async def test_not_valid_properties(): with pytest.raises(AssertionError): stroption = StrOption('str', 'Test string option', default='abc', properties='mandatory') @pytest.mark.asyncio async def test_information_config(): descr = make_description() cfg = await Config(descr) string = 'some informations' # assert list(await cfg.information.list()) == [] await cfg.information.set('info', string) assert await cfg.information.get('info') == string assert list(await cfg.information.list()) == ['info'] # with pytest.raises(ValueError): await cfg.information.get('noinfo') assert await cfg.information.get('noinfo', 'default') == 'default' await cfg.information.reset('info') with pytest.raises(ValueError): await cfg.information.get('info') with pytest.raises(ValueError): await cfg.information.reset('noinfo') assert list(await cfg.information.list()) == [] @pytest.mark.asyncio async def test_information_option(): descr = make_description() cfg = await Config(descr) string = 'some informations' # list(await cfg.option('gc.name').information.list()) == [] await cfg.option('gc.name').information.set('info', string) assert await cfg.option('gc.name').information.get('info') == string list(await cfg.option('gc.name').information.list()) == ['info'] # with pytest.raises(ValueError): await cfg.option('gc.name').information.get('noinfo') assert await cfg.option('gc.name').information.get('noinfo', 'default') == 'default' await cfg.option('gc.name').information.reset('info') with pytest.raises(ValueError): await cfg.option('gc.name').information.get('info') with pytest.raises(ValueError): await cfg.option('gc.name').information.reset('noinfo') list(await cfg.option('gc.name').information.list()) == [] # assert await cfg.option('wantref').information.get('info') == 'default value' await cfg.option('wantref').information.set('info', 'default value') assert await cfg.option('wantref').information.get('info') == 'default value' await cfg.option('wantref').information.reset('info') assert await cfg.option('wantref').information.get('info') == 'default value' def to_tuple(val): ret = [] for v in val: t = [] for w in v: if isinstance(w, list): t.append(tuple(w)) else: t.append(w) ret.append(tuple(t)) return tuple(ret) @pytest.mark.asyncio async def test_get_modified_values(): g1 = IntOption('g1', '', 1) g2 = StrOption('g2', '', 'héhé') g3 = StrOption('g3', '', 'héhé') g4 = BoolOption('g4', '', True) g5 = StrOption('g5', '') g6 = StrOption('g6', '', multi=True) d1 = OptionDescription('od', '', [g1, g2, g3, g4, g5, g6]) root = OptionDescription('root', '', [d1]) cfg = await Config(root) assert to_tuple(await cfg.value.exportation()) == ((), (), (), ()) assert not await cfg.option('od.g5').option.ismulti() assert not await cfg.option('od.g5').option.issubmulti() await cfg.option('od.g5').value.set('yes') assert to_tuple(await cfg.value.exportation()) == (('od.g5',), (None,), ('yes',), ('user',)) await cfg.option('od.g4').value.set(False) assert to_tuple(await cfg.value.exportation()) == (('od.g5', 'od.g4'), (None, None), ('yes', False), ('user', 'user')) await cfg.option('od.g4').value.set(undefined) assert to_tuple(await cfg.value.exportation()) == (('od.g5', 'od.g4'), (None, None), ('yes', True), ('user', 'user')) await cfg.option('od.g4').value.reset() assert to_tuple(await cfg.value.exportation()) == (('od.g5',), (None,), ('yes',), ('user',)) assert await cfg.option('od.g6').option.ismulti() await cfg.option('od.g6').value.set([undefined]) assert to_tuple(await cfg.value.exportation()) == (('od.g5', 'od.g6'), (None, None), ('yes', (None,)), ('user', 'user')) await cfg.option('od.g6').value.set([]) assert to_tuple(await cfg.value.exportation()) == (('od.g5', 'od.g6'), (None, None), ('yes', tuple()), ('user', 'user')) await cfg.option('od.g6').value.set(['3']) assert to_tuple(await cfg.value.exportation()) == (('od.g5', 'od.g6'), (None, None), ('yes', ('3',)), ('user', 'user')) await cfg.option('od.g6').value.set([]) assert to_tuple(await cfg.value.exportation()) == (('od.g5', 'od.g6'), (None, None), ('yes', tuple()), ('user', 'user')) @pytest.mark.asyncio async def test_get_modified_values_not_modif(config_type): g1 = StrOption('g1', '', multi=True) d1 = OptionDescription('od', '', [g1]) root = OptionDescription('root', '', [d1]) cfg = await Config(root) cfg = await get_config(cfg, config_type) assert await cfg.option('od.g1').value.get() == [] value = await cfg.option('od.g1').value.get() value.append('val') assert await cfg.option('od.g1').value.get() == [] @pytest.mark.asyncio async def test_duplicated_option(): g1 = IntOption('g1', '', 1) g1 #in same OptionDescription with pytest.raises(ConflictError): d1 = OptionDescription('od', '', [g1, g1]) @pytest.mark.asyncio async def test_duplicated_option_diff_od(): g1 = IntOption('g1', '', 1) d1 = OptionDescription('od1', '', [g1]) #in different OptionDescription d2 = OptionDescription('od2', '', [g1, d1]) d2 with pytest.raises(ConflictError): await Config(d2) @pytest.mark.asyncio async def test_cannot_assign_value_to_option_description(): descr = make_description() cfg = await Config(descr) with pytest.raises(APIError): await cfg.option('gc').value.set(3) @pytest.mark.asyncio async def test_config_multi(config_type): i1 = IntOption('test1', '', multi=True) i2 = IntOption('test2', '', multi=True, default_multi=1) i3 = IntOption('test3', '', default=[2], multi=True, default_multi=1) od = OptionDescription('test', '', [i1, i2, i3]) cfg = await Config(od) cfg = await get_config(cfg, config_type) assert await cfg.option('test1').value.get() == [] assert await cfg.option('test2').value.get() == [] await cfg.option('test2').value.set([undefined]) assert await cfg.option('test2').value.get() == [1] assert await cfg.option('test3').value.get() == [2] await cfg.option('test3').value.set([undefined, undefined]) assert await cfg.option('test3').value.get() == [2, 1] @pytest.mark.asyncio async def test_prefix_error(): i1 = IntOption('test1', '') od = OptionDescription('test', '', [i1]) cfg = await Config(od) await cfg.property.read_write() await cfg.option('test1').value.set(1) try: await cfg.option('test1').value.set('yes') except Exception as err: assert str(err) == _('"{0}" is an invalid {1} for "{2}"').format('yes', _('integer'), 'test1') try: await cfg.option('test1').value.set('yes') except Exception as err: err.prefix = '' assert str(err) == _('invalid value') @pytest.mark.asyncio async def test_no_validation(): # FIXME config_type = 'tiramisu' i1 = IntOption('test1', '') od = OptionDescription('test', '', [i1]) config = await Config(od) await config.property.read_write() cfg = await get_config(config, config_type) await cfg.option('test1').value.set(1) with pytest.raises(ValueError): await cfg.option('test1').value.set('yes') assert await cfg.option('test1').value.get() == 1 await config.property.pop('validator') cfg = await get_config(config, config_type) await cfg.option('test1').value.set('yes') assert await cfg.option('test1').value.get() == 'yes' await cfg.property.add('validator') with pytest.raises(ValueError): await cfg.option('test1').value.get() await cfg.option('test1').value.reset() assert await cfg.option('test1').value.get() is None @pytest.mark.asyncio async def test_subconfig(): i = IntOption('i', '') o = OptionDescription('val', '', [i]) o2 = OptionDescription('val', '', [o]) cfg = await Config(o2) cfg with pytest.raises(TypeError): await SubConfig(i, weakref.ref(cfg)) @pytest.mark.asyncio async def test_config_subconfig(): 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]) cfg = await Config(od2, session_id='conf1') with pytest.raises(ConfigError): conf2 = await Config(od1, session_id='conf2') @pytest.mark.asyncio async def test_config_invalidsession(): i = IntOption('i', '') o = OptionDescription('val', '', [i]) o2 = OptionDescription('val', '', [o]) with pytest.raises(ValueError): await Config(o2, session_id=2) @pytest.mark.asyncio async def test_config_od_name(config_type): i = IntOption('i', '') s = SymLinkOption('s', i) o = OptionDescription('val', '', [i, s]) o2 = OptionDescription('val', '', [o]) cfg = await Config(o2) cfg = await get_config(cfg, config_type) assert await cfg.option('val.i').option.name() == 'i' assert await cfg.option('val.s').option.name() == 's' assert await cfg.option('val.s').option.name(follow_symlink=True) == 'i' @pytest.mark.asyncio async def test_config_od_type(config_type): i = IntOption('i', '') o = OptionDescription('val', '', [i]) o2 = OptionDescription('val', '', [o]) cfg = await Config(o2) cfg = await get_config(cfg, config_type) assert await cfg.option('val.i').option.type() == 'integer' @pytest.mark.asyncio async def test_config_default(config_type): i = IntOption('i', '', 8) o = OptionDescription('val', '', [i]) o2 = OptionDescription('val', '', [o]) cfg = await Config(o2) cfg = await get_config(cfg, config_type) assert await cfg.option('val.i').value.default() == 8 await cfg.option('val.i').value.set(9) assert await cfg.option('val.i').value.get() == 9 assert await cfg.option('val.i').value.default() == 8