tiramisu/tests/test_config.py
2022-01-09 19:10:09 +01:00

431 lines
17 KiB
Python

# -*- 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()
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.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()