# -*- 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, event_loop 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, delete_session from tiramisu.error import ConflictError, ConfigError, PropertiesOptionError, APIError from tiramisu.storage import list_sessions 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]) async with await Config(descr) as cfg: 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' assert not await list_sessions() @pytest.mark.asyncio async def test_base_config_name(): gcdummy = BoolOption('dummy', 'dummy', default=False) descr = OptionDescription('tiramisu', '', [gcdummy]) async with await Config(descr, session_id='cfg') as cfg: await cfg.session.id() == 'cfg' #raises(ValueError, "Config(descr, session_id='unvalid name')") assert not await list_sessions() # # #@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]) async with await Config(descr) as cfg: base = OptionDescription('config', '', [descr]) with pytest.raises(ConfigError): async with await Config(base, session_id='error'): pass await delete_session('error') assert not await list_sessions() @pytest.mark.asyncio async def test_base_config_force_permissive(): descr = make_description() async with await Config(descr) as cfg: 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 assert not await list_sessions() @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() async with await Config(descr) as cfg: 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() ## async with await Config(descr) as cfg: 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 assert not await list_sessions() @pytest.mark.asyncio async def test_not_valid_properties(): with pytest.raises(AssertionError): stroption = StrOption('str', 'Test string option', default='abc', properties='mandatory') assert not await list_sessions() @pytest.mark.asyncio async def test_information_config(): descr = make_description() async with await Config(descr) as cfg: string = 'some informations' # assert list(await cfg.information.list()) == ['doc'] await cfg.information.set('info', string) assert await cfg.information.get('info') == string assert set(await cfg.information.list()) == {'doc', '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()) == ['doc'] assert not await list_sessions() @pytest.mark.asyncio async def test_information_option(): descr = make_description() async with await Config(descr) as cfg: string = 'some informations' # assert list(await cfg.option('gc.name').information.list()) == ['doc'] await cfg.option('gc.name').information.set('info', string) assert await cfg.option('gc.name').information.get('info') == string assert set(await cfg.option('gc.name').information.list()) == {'doc', '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') assert list(await cfg.option('gc.name').information.list()) == ['doc'] # 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' assert not await list_sessions() @pytest.mark.asyncio async def test_information_optiondescription(): descr = make_description() async with await Config(descr) as cfg: string = 'some informations' # assert list(await cfg.option('gc').information.list()) == ['doc'] await cfg.option('gc').information.set('info', string) assert await cfg.option('gc').information.get('info') == string assert set(await cfg.option('gc').information.list()) == {'doc', 'info'} # with pytest.raises(ValueError): await cfg.option('gc').information.get('noinfo') assert await cfg.option('gc').information.get('noinfo', 'default') == 'default' await cfg.option('gc').information.reset('info') with pytest.raises(ValueError): await cfg.option('gc').information.get('info') with pytest.raises(ValueError): await cfg.option('gc').information.reset('noinfo') assert list(await cfg.option('gc').information.list()) == ['doc'] assert not await list_sessions() def compare(val1, val2): assert len(val1[0]) == len(val2[0]) for idx1, val_1 in enumerate(val1[0]): idx2 = val2[0].index(val_1) assert val1[0][idx1] == val2[0][idx2] assert val1[1][idx1] == val2[1][idx2] if isinstance(val2[2][idx2], tuple): assert val2[2][idx2] == tuple(val1[2][idx1]) else: assert val2[2][idx2] == val1[2][idx1] assert val1[3][idx1] == val2[3][idx2] @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]) async with await Config(root) as cfg: compare(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') compare(await cfg.value.exportation(), (('od.g5',), (None,), ('yes',), ('user',))) await cfg.option('od.g4').value.set(False) compare(await cfg.value.exportation(), (('od.g5', 'od.g4'), (None, None), ('yes', False), ('user', 'user'))) await cfg.option('od.g4').value.set(undefined) compare(await cfg.value.exportation(), (('od.g5', 'od.g4'), (None, None), ('yes', True), ('user', 'user'))) await cfg.option('od.g4').value.reset() compare(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]) compare(await cfg.value.exportation(), (('od.g5', 'od.g6'), (None, None), ('yes', (None,)), ('user', 'user'))) await cfg.option('od.g6').value.set([]) compare(await cfg.value.exportation(), (('od.g5', 'od.g6'), (None, None), ('yes', tuple()), ('user', 'user'))) await cfg.option('od.g6').value.set(['3']) compare(await cfg.value.exportation(), (('od.g5', 'od.g6'), (None, None), ('yes', ('3',)), ('user', 'user'))) await cfg.option('od.g6').value.set([]) compare(await cfg.value.exportation(), (('od.g5', 'od.g6'), (None, None), ('yes', tuple()), ('user', 'user'))) assert not await list_sessions() @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]) async with await Config(root) as cfg: 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() == [] assert not await list_sessions() @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]) assert not await list_sessions() @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, session_id='error') await delete_session('error') assert not await list_sessions() @pytest.mark.asyncio async def test_cannot_assign_value_to_option_description(): descr = make_description() async with await Config(descr) as cfg: with pytest.raises(APIError): await cfg.option('gc').value.set(3) assert not await list_sessions() @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]) async with await Config(od) as cfg: 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] assert not await list_sessions() @pytest.mark.asyncio async def test_prefix_error(): i1 = IntOption('test1', '') od = OptionDescription('test', '', [i1]) async with await Config(od) as cfg: 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') assert not await list_sessions() @pytest.mark.asyncio async def test_no_validation(): # FIXME config_type = 'tiramisu' i1 = IntOption('test1', '') od = OptionDescription('test', '', [i1]) async with await Config(od) as config: 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 assert not await list_sessions() @pytest.mark.asyncio async def test_subconfig(): i = IntOption('i', '') o = OptionDescription('val', '', [i]) o2 = OptionDescription('val', '', [o]) async with await Config(o2) as cfg: cfg with pytest.raises(TypeError): await SubConfig(i, weakref.ref(cfg)) assert not await list_sessions() @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]) async with await Config(od2, session_id='conf1') as cfg: with pytest.raises(ConfigError): conf2 = await Config(od1, session_id='conf2') await delete_session('conf2') assert not await list_sessions() @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) assert not await list_sessions() @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]) async with await Config(o2) as cfg: 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' assert not await list_sessions() @pytest.mark.asyncio async def test_config_od_type(config_type): i = IntOption('i', '') o = OptionDescription('val', '', [i]) o2 = OptionDescription('val', '', [o]) async with await Config(o2) as cfg: cfg = await get_config(cfg, config_type) assert await cfg.option('val').option.type() == 'optiondescription' assert await cfg.option('val.i').option.type() == 'integer' assert not await list_sessions() @pytest.mark.asyncio async def test_config_default(config_type): i = IntOption('i', '', 8) o = OptionDescription('val', '', [i]) o2 = OptionDescription('val', '', [o]) async with await Config(o2) as cfg: 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 assert not await list_sessions()