New Postgres storage

This commit is contained in:
Emmanuel Garette 2020-01-22 20:46:18 +01:00
parent 746fa0134f
commit 3bef45c9db
85 changed files with 10814 additions and 9262 deletions

View file

@ -1,4 +1,6 @@
# from json import dumps, loads # from json import dumps, loads
import asyncio
from os import environ
try: try:
from tiramisu_api import Config from tiramisu_api import Config
class TestConfig(Config): class TestConfig(Config):
@ -40,3 +42,44 @@ async def global_owner(config, config_type):
@pytest.fixture(params=PARAMS) @pytest.fixture(params=PARAMS)
def config_type(request): def config_type(request):
return request.param return request.param
LOOP = None
@pytest.fixture(scope='session')
def event_loop(request):
"""Create an instance of the default event loop for each test case."""
global LOOP
if LOOP is None:
LOOP = asyncio.get_event_loop_policy().new_event_loop()
return LOOP
async def _delete_sessions(meta):
if await meta.config.type() != 'config':
for conf in await meta.config.list():
await _delete_sessions(conf)
await meta.session.reset()
async def delete_sessions(confs):
if not isinstance(confs, list):
confs = [confs]
for conf in confs:
await _delete_sessions(conf)
if environ.get('TIRAMISU_STORAGE') == 'postgres':
async with confs[0]._config_bag.context.getconnection() as connection:
assert await connection.fetchrow('SELECT * FROM session') is None
assert await connection.fetchrow('SELECT * FROM value') is None
assert await connection.fetchrow('SELECT * FROM information') is None
assert await connection.fetchrow('SELECT * FROM property') is None
assert await connection.fetchrow('SELECT * FROM permissive') is None
elif environ.get('TIRAMISU_STORAGE') == 'sqlite3':
async with confs[0]._config_bag.context.getconnection() as connection:
assert await connection.select('SELECT * FROM session') is None
assert await connection.select('SELECT * FROM value') is None
assert await connection.select('SELECT * FROM information') is None
assert await connection.select('SELECT * FROM property') is None
assert await connection.select('SELECT * FROM permissive') is None
else:
from tiramisu import list_sessions
assert not await list_sessions()

View file

@ -10,17 +10,7 @@ from tiramisu import BoolOption, IPOption, IntOption, StrOption, OptionDescripti
list_sessions, default_storage, delete_session, calc_value list_sessions, default_storage, delete_session, calc_value
from tiramisu.error import ConfigError, PropertiesOptionError from tiramisu.error import ConfigError, PropertiesOptionError
from tiramisu.setting import groups from tiramisu.setting import groups
from .config import event_loop
def teardown_function(function):
if default_storage.is_persistent():
sessions = list_sessions()
if not sessions:
return
assert len(sessions) == 1
delete_session(sessions[0])
else:
assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__)
global incr global incr
@ -42,216 +32,225 @@ def make_description():
async def test_cache_config(): async def test_cache_config():
od1 = make_description() od1 = make_description()
assert od1.impl_already_build_caches() is False assert od1.impl_already_build_caches() is False
c = await Config(od1) async with await Config(od1) as cfg:
assert od1.impl_already_build_caches() is True assert od1.impl_already_build_caches() is True
c cfg
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_cache(): async def test_cache():
od1 = make_description() od1 = make_description()
cfg = await Config(od1) async with await Config(od1) as cfg:
values = cfg._config_bag.context._impl_values_cache values = cfg._config_bag.context._impl_values_cache
settings = cfg._config_bag.context._impl_properties_cache settings = cfg._config_bag.context._impl_properties_cache
await cfg.option('u1').value.get() await cfg.option('u1').value.get()
assert 'u1' in values.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings.get_cached() assert 'u1' in settings.get_cached()
await cfg.option('u2').value.get() await cfg.option('u2').value.get()
assert 'u1' in values.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings.get_cached() assert 'u1' in settings.get_cached()
assert 'u2' in values.get_cached() assert 'u2' in values.get_cached()
assert 'u2' in settings.get_cached() assert 'u2' in settings.get_cached()
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_cache_importation(): async def test_cache_importation():
od1 = make_description() od1 = make_description()
cfg = await Config(od1) async with await Config(od1) as cfg:
await cfg.option('u2').value.set(1) await cfg.option('u2').value.set(1)
export = await cfg.value.exportation() export = await cfg.value.exportation()
assert await cfg.value.dict() == {'u1': [], 'u2': 1, 'u3': []} assert await cfg.value.dict() == {'u1': [], 'u2': 1, 'u3': []}
await cfg.option('u2').value.set(2) await cfg.option('u2').value.set(2)
assert await cfg.value.dict() == {'u1': [], 'u2': 2, 'u3': []} assert await cfg.value.dict() == {'u1': [], 'u2': 2, 'u3': []}
await cfg.value.importation(export) await cfg.value.importation(export)
assert await cfg.value.dict() == {'u1': [], 'u2': 1, 'u3': []} assert await cfg.value.dict() == {'u1': [], 'u2': 1, 'u3': []}
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_cache_importation_property(): async def test_cache_importation_property():
od1 = make_description() od1 = make_description()
cfg = await Config(od1) async with await Config(od1) as cfg:
await cfg.option('u2').property.add('prop') await cfg.option('u2').property.add('prop')
export = await cfg.property.exportation() export = await cfg.property.exportation()
assert await cfg.option('u2').property.get() == {'prop'} assert await cfg.option('u2').property.get() == {'prop'}
await cfg.option('u2').property.add('prop2') await cfg.option('u2').property.add('prop2')
assert await cfg.option('u2').property.get() == {'prop', 'prop2'} assert await cfg.option('u2').property.get() == {'prop', 'prop2'}
await cfg.property.importation(export) await cfg.property.importation(export)
assert await cfg.option('u2').property.get() == {'prop'} assert await cfg.option('u2').property.get() == {'prop'}
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_cache_importation_permissive(): async def test_cache_importation_permissive():
od1 = make_description() od1 = make_description()
cfg = await Config(od1) async with await Config(od1) as cfg:
await cfg.option('u2').permissive.set(frozenset(['prop'])) await cfg.option('u2').permissive.set(frozenset(['prop']))
export = await cfg.permissive.exportation() export = await cfg.permissive.exportation()
assert await cfg.option('u2').permissive.get() == {'prop'} assert await cfg.option('u2').permissive.get() == {'prop'}
await cfg.option('u2').permissive.set(frozenset(['prop', 'prop2'])) await cfg.option('u2').permissive.set(frozenset(['prop', 'prop2']))
assert await cfg.option('u2').permissive.get() == {'prop', 'prop2'} assert await cfg.option('u2').permissive.get() == {'prop', 'prop2'}
await cfg.permissive.importation(export) await cfg.permissive.importation(export)
assert await cfg.option('u2').permissive.get() == {'prop'} assert await cfg.option('u2').permissive.get() == {'prop'}
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_cache_reset(): async def test_cache_reset():
od1 = make_description() od1 = make_description()
cfg = await Config(od1) async with await Config(od1) as cfg:
values = cfg._config_bag.context._impl_values_cache values = cfg._config_bag.context._impl_values_cache
settings = cfg._config_bag.context._impl_properties_cache settings = cfg._config_bag.context._impl_properties_cache
#when change a value #when change a value
await cfg.option('u1').value.get() await cfg.option('u1').value.get()
await cfg.option('u2').value.get() await cfg.option('u2').value.get()
assert 'u1' in values.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings.get_cached() assert 'u1' in settings.get_cached()
assert 'u2' in values.get_cached() assert 'u2' in values.get_cached()
assert 'u2' in settings.get_cached() assert 'u2' in settings.get_cached()
assert 'u1' in values.get_cached() assert 'u1' in values.get_cached()
settings.get_cached() settings.get_cached()
await cfg.option('u2').value.set(1) await cfg.option('u2').value.set(1)
assert 'u1' in values.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings.get_cached() assert 'u1' in settings.get_cached()
assert 'u2' in values.get_cached() assert 'u2' in values.get_cached()
assert 'u2' not in settings.get_cached() assert 'u2' not in settings.get_cached()
#when remove a value #when remove a value
await cfg.option('u1').value.get() await cfg.option('u1').value.get()
assert 'u1' in values.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings.get_cached() assert 'u1' in settings.get_cached()
await cfg.option('u2').value.reset() await cfg.option('u2').value.reset()
assert 'u1' in values.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings.get_cached() assert 'u1' in settings.get_cached()
assert 'u2' not in values.get_cached() assert 'u2' not in values.get_cached()
assert 'u2' not in settings.get_cached() assert 'u2' not in settings.get_cached()
#when add/del property #when add/del property
await cfg.option('u1').value.get() await cfg.option('u1').value.get()
assert 'u1' in values.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings.get_cached() assert 'u1' in settings.get_cached()
await cfg.option('u2').property.add('test') await cfg.option('u2').property.add('test')
assert 'u1' in values.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings.get_cached() assert 'u1' in settings.get_cached()
assert 'u2' not in values.get_cached() assert 'u2' not in values.get_cached()
assert 'u2' not in settings.get_cached() assert 'u2' not in settings.get_cached()
await cfg.option('u1').value.get() await cfg.option('u1').value.get()
assert 'u1' in values.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings.get_cached() assert 'u1' in settings.get_cached()
await cfg.option('u2').property.pop('test') await cfg.option('u2').property.pop('test')
assert 'u1' in values.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings.get_cached() assert 'u1' in settings.get_cached()
assert 'u2' not in values.get_cached() assert 'u2' not in values.get_cached()
assert 'u2' not in settings.get_cached() assert 'u2' not in settings.get_cached()
#when enable/disabled property #when enable/disabled property
await cfg.option('u1').value.get() await cfg.option('u1').value.get()
assert 'u1' in values.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings.get_cached() assert 'u1' in settings.get_cached()
await cfg.property.add('test') await cfg.property.add('test')
assert 'u1' not in values.get_cached() assert 'u1' not in values.get_cached()
assert 'u1' not in settings.get_cached() assert 'u1' not in settings.get_cached()
await cfg.option('u1').value.get() await cfg.option('u1').value.get()
assert 'u1' in values.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in values.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings.get_cached() assert 'u1' in settings.get_cached()
await cfg.property.pop('test') await cfg.property.pop('test')
assert 'u1' not in values.get_cached() assert 'u1' not in values.get_cached()
assert 'u1' not in settings.get_cached() assert 'u1' not in settings.get_cached()
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_cache_reset_multi(): async def test_cache_reset_multi():
od1 = make_description() od1 = make_description()
cfg = await Config(od1) async with await Config(od1) as cfg:
values = cfg._config_bag.context._impl_values_cache values = cfg._config_bag.context._impl_values_cache
settings = cfg._config_bag.context._impl_properties_cache settings = cfg._config_bag.context._impl_properties_cache
await cfg.option('u1').value.get() await cfg.option('u1').value.get()
await cfg.option('u3').value.get() await cfg.option('u3').value.get()
assert 'u1' in values.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings.get_cached() assert 'u1' in settings.get_cached()
assert 'u3' in values.get_cached() assert 'u3' in values.get_cached()
assert 'u3' in settings.get_cached() assert 'u3' in settings.get_cached()
#when change a value #when change a value
await cfg.option('u3').value.set([1]) await cfg.option('u3').value.set([1])
assert 'u1' in values.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings.get_cached() assert 'u1' in settings.get_cached()
assert 'u3' in values.get_cached() assert 'u3' in values.get_cached()
assert 'u3' not in settings.get_cached() assert 'u3' not in settings.get_cached()
#when append value #when append value
await cfg.option('u1').value.get() await cfg.option('u1').value.get()
await cfg.option('u3').value.get() await cfg.option('u3').value.get()
assert 'u1' in values.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings.get_cached() assert 'u1' in settings.get_cached()
assert 'u3' in values.get_cached() assert 'u3' in values.get_cached()
assert 'u3' in settings.get_cached() assert 'u3' in settings.get_cached()
await cfg.option('u3').value.set([1, 2]) await cfg.option('u3').value.set([1, 2])
assert 'u1' in values.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings.get_cached() assert 'u1' in settings.get_cached()
assert 'u3' in values.get_cached() assert 'u3' in values.get_cached()
assert 'u3' not in settings.get_cached() assert 'u3' not in settings.get_cached()
#when pop value #when pop value
await cfg.option('u1').value.get() await cfg.option('u1').value.get()
await cfg.option('u3').value.get() await cfg.option('u3').value.get()
assert 'u1' in values.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings.get_cached() assert 'u1' in settings.get_cached()
assert 'u3' in values.get_cached() assert 'u3' in values.get_cached()
assert 'u3' in settings.get_cached() assert 'u3' in settings.get_cached()
await cfg.option('u3').value.set([1]) await cfg.option('u3').value.set([1])
assert 'u1' in values.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings.get_cached() assert 'u1' in settings.get_cached()
assert 'u3' in values.get_cached() assert 'u3' in values.get_cached()
assert 'u3' not in settings.get_cached() assert 'u3' not in settings.get_cached()
#when remove a value #when remove a value
await cfg.option('u1').value.get() await cfg.option('u1').value.get()
assert 'u1' in values.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings.get_cached() assert 'u1' in settings.get_cached()
await cfg.option('u3').value.reset() await cfg.option('u3').value.reset()
assert 'u1' in values.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings.get_cached() assert 'u1' in settings.get_cached()
assert 'u3' not in values.get_cached() assert 'u3' not in values.get_cached()
assert 'u3' not in settings.get_cached() assert 'u3' not in settings.get_cached()
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_reset_cache(): async def test_reset_cache():
od1 = make_description() od1 = make_description()
cfg = await Config(od1) async with await Config(od1) as cfg:
values = cfg._config_bag.context._impl_values_cache values = cfg._config_bag.context._impl_values_cache
settings = cfg._config_bag.context._impl_properties_cache settings = cfg._config_bag.context._impl_properties_cache
await cfg.option('u1').value.get() await cfg.option('u1').value.get()
assert 'u1' in values.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings.get_cached() assert 'u1' in settings.get_cached()
await cfg.cache.reset() await cfg.cache.reset()
assert 'u1' not in values.get_cached() assert 'u1' not in values.get_cached()
assert 'u1' not in settings.get_cached() assert 'u1' not in settings.get_cached()
await cfg.option('u1').value.get() await cfg.option('u1').value.get()
await cfg.option('u2').value.get() await cfg.option('u2').value.get()
assert 'u1' in values.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings.get_cached() assert 'u1' in settings.get_cached()
assert 'u2' in values.get_cached() assert 'u2' in values.get_cached()
assert 'u2' in settings.get_cached() assert 'u2' in settings.get_cached()
await cfg.cache.reset() await cfg.cache.reset()
assert 'u1' not in values.get_cached() assert 'u1' not in values.get_cached()
assert 'u1' not in settings.get_cached() assert 'u1' not in settings.get_cached()
assert 'u2' not in values.get_cached() assert 'u2' not in values.get_cached()
assert 'u2' not in settings.get_cached() assert 'u2' not in settings.get_cached()
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_cache_not_cache(): async def test_cache_not_cache():
od1 = make_description() od1 = make_description()
cfg = await Config(od1) async with await Config(od1) as cfg:
values = cfg._config_bag.context._impl_values_cache values = cfg._config_bag.context._impl_values_cache
settings = cfg._config_bag.context._impl_properties_cache settings = cfg._config_bag.context._impl_properties_cache
await cfg.property.pop('cache') await cfg.property.pop('cache')
await cfg.option('u1').value.get() await cfg.option('u1').value.get()
assert 'u1' not in values.get_cached() assert 'u1' not in values.get_cached()
assert 'u1' not in settings.get_cached() assert 'u1' not in settings.get_cached()
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -260,47 +259,48 @@ async def test_cache_leadership():
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True) netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True)
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
od1 = OptionDescription('toto', '', [interface1]) od1 = OptionDescription('toto', '', [interface1])
cfg = await Config(od1) async with await Config(od1) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
values = cfg._config_bag.context._impl_values_cache values = cfg._config_bag.context._impl_values_cache
settings = cfg._config_bag.context._impl_properties_cache settings = cfg._config_bag.context._impl_properties_cache
assert values.get_cached() == {} assert values.get_cached() == {}
#assert settings.get_cached() == {} #assert settings.get_cached() == {}
# #
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.2']) await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.2'])
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get()
await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()
cache = values.get_cached() cache = values.get_cached()
assert set(cache.keys()) == set(['ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0']) assert set(cache.keys()) == set(['ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0'])
assert set(cache['ip_admin_eth0.ip_admin_eth0'].keys()) == set([None]) assert set(cache['ip_admin_eth0.ip_admin_eth0'].keys()) == set([None])
assert cache['ip_admin_eth0.ip_admin_eth0'][None][0] == ['192.168.1.2'] assert cache['ip_admin_eth0.ip_admin_eth0'][None][0] == ['192.168.1.2']
#assert set(cache['ip_admin_eth0.netmask_admin_eth0'].keys()) == set([None]) #assert set(cache['ip_admin_eth0.netmask_admin_eth0'].keys()) == set([None])
#assert cache['ip_admin_eth0.netmask_admin_eth0'][None][0] == [None] #assert cache['ip_admin_eth0.netmask_admin_eth0'][None][0] == [None]
#assert cache['ip_admin_eth0.netmask_admin_eth0'][0][0] is None #assert cache['ip_admin_eth0.netmask_admin_eth0'][0][0] is None
cache = settings.get_cached() cache = settings.get_cached()
assert set(cache.keys()) == set([None, 'ip_admin_eth0', 'ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0']) assert set(cache.keys()) == set([None, 'ip_admin_eth0', 'ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0'])
assert set(cache['ip_admin_eth0'].keys()) == set([None]) assert set(cache['ip_admin_eth0'].keys()) == set([None])
assert set(cache['ip_admin_eth0.ip_admin_eth0'].keys()) == set([None]) assert set(cache['ip_admin_eth0.ip_admin_eth0'].keys()) == set([None])
assert set(cache['ip_admin_eth0.netmask_admin_eth0'].keys()) == set([0, None]) assert set(cache['ip_admin_eth0.netmask_admin_eth0'].keys()) == set([0, None])
# #
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.2', '192.168.1.1']) await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.2', '192.168.1.1'])
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get()
await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()
await cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get() await cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get()
cache = values.get_cached() cache = values.get_cached()
assert set(cache.keys()) == set(['ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0']) assert set(cache.keys()) == set(['ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0'])
assert set(cache['ip_admin_eth0.ip_admin_eth0'].keys()) == set([None]) assert set(cache['ip_admin_eth0.ip_admin_eth0'].keys()) == set([None])
assert cache['ip_admin_eth0.ip_admin_eth0'][None][0] == ['192.168.1.2', '192.168.1.1'] assert cache['ip_admin_eth0.ip_admin_eth0'][None][0] == ['192.168.1.2', '192.168.1.1']
#assert set(cache['ip_admin_eth0.netmask_admin_eth0'].keys()) == set([None]) #assert set(cache['ip_admin_eth0.netmask_admin_eth0'].keys()) == set([None])
#assert cache['ip_admin_eth0.netmask_admin_eth0'][None][0] == [None, None] #assert cache['ip_admin_eth0.netmask_admin_eth0'][None][0] == [None, None]
#assert cache['ip_admin_eth0.netmask_admin_eth0'][0][0] is None #assert cache['ip_admin_eth0.netmask_admin_eth0'][0][0] is None
#assert cache['ip_admin_eth0.netmask_admin_eth0'][1][0] is None #assert cache['ip_admin_eth0.netmask_admin_eth0'][1][0] is None
cache = settings.get_cached() cache = settings.get_cached()
assert set(cache.keys()) == set([None, 'ip_admin_eth0', 'ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0']) assert set(cache.keys()) == set([None, 'ip_admin_eth0', 'ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0'])
assert set(cache['ip_admin_eth0'].keys()) == set([None]) assert set(cache['ip_admin_eth0'].keys()) == set([None])
assert set(cache['ip_admin_eth0.ip_admin_eth0'].keys()) == set([None]) assert set(cache['ip_admin_eth0.ip_admin_eth0'].keys()) == set([None])
assert set(cache['ip_admin_eth0.netmask_admin_eth0'].keys()) == set([None, 0, 1]) assert set(cache['ip_admin_eth0.netmask_admin_eth0'].keys()) == set([None, 0, 1])
#DEL, insert, ... #DEL, insert, ...
assert not await list_sessions()
def compare(calculated, expected): def compare(calculated, expected):
@ -320,63 +320,64 @@ async def test_cache_callback():
val4 = StrOption('val4', "", Calculation(calc_value, Params(ParamOption(val1)))) val4 = StrOption('val4', "", Calculation(calc_value, Params(ParamOption(val1))))
val5 = StrOption('val5', "", [Calculation(calc_value, Params(ParamValue('yes')))], multi=True) val5 = StrOption('val5', "", [Calculation(calc_value, Params(ParamValue('yes')))], multi=True)
od1 = OptionDescription('rootconfig', '', [val1, val2, val3, val4, val5]) od1 = OptionDescription('rootconfig', '', [val1, val2, val3, val4, val5])
cfg = await Config(od1) async with await Config(od1) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
await cfg.value.dict() await cfg.value.dict()
values = cfg._config_bag.context._impl_values_cache values = cfg._config_bag.context._impl_values_cache
settings = cfg._config_bag.context._impl_properties_cache settings = cfg._config_bag.context._impl_properties_cache
compare(values.get_cached(), {'val1': {None: ('val', None)}, compare(values.get_cached(), {'val1': {None: ('val', None)},
'val2': {None: ('val', None)}, 'val2': {None: ('val', None)},
'val3': {None: ('yes', None)}, 'val3': {None: ('yes', None)},
'val4': {None: ('val', None)}, 'val4': {None: ('val', None)},
'val5': {None: (['yes'], None)}}) 'val5': {None: (['yes'], None)}})
await cfg.option('val1').value.set('new') await cfg.option('val1').value.set('new')
compare(values.get_cached(), {'val3': {None: ('yes', None)}, compare(values.get_cached(), {'val3': {None: ('yes', None)},
'val1': {None: ('new', None)}, 'val1': {None: ('new', None)},
'val5': {None: (['yes'], None)}}) 'val5': {None: (['yes'], None)}})
await cfg.value.dict() await cfg.value.dict()
compare(values.get_cached(), {'val1': {None: ('new', None)}, compare(values.get_cached(), {'val1': {None: ('new', None)},
'val2': {None: ('new', None)}, 'val2': {None: ('new', None)},
'val3': {None: ('yes', None)}, 'val3': {None: ('yes', None)},
'val4': {None: ('new', None)}, 'val4': {None: ('new', None)},
'val5': {None: (['yes'], None)}}) 'val5': {None: (['yes'], None)}})
await cfg.option('val3').value.set('new2') await cfg.option('val3').value.set('new2')
compare(values.get_cached(), {'val1': {None: ('new', None)}, compare(values.get_cached(), {'val1': {None: ('new', None)},
'val2': {None: ('new', None)}, 'val2': {None: ('new', None)},
'val4': {None: ('new', None)}, 'val4': {None: ('new', None)},
'val1': {None: ('new', None)}, 'val1': {None: ('new', None)},
'val3': {None: ('new2', None, True)}, 'val3': {None: ('new2', None, True)},
'val5': {None: (['yes'], None)}}) 'val5': {None: (['yes'], None)}})
await cfg.value.dict() await cfg.value.dict()
compare(values.get_cached(), {'val1': {None: ('new', None)}, compare(values.get_cached(), {'val1': {None: ('new', None)},
'val2': {None: ('new', None)}, 'val2': {None: ('new', None)},
'val3': {None: ('new2', None)}, 'val3': {None: ('new2', None)},
'val4': {None: ('new', None)}, 'val4': {None: ('new', None)},
'val5': {None: (['yes'], None)}}) 'val5': {None: (['yes'], None)}})
await cfg.option('val4').value.set('new3') await cfg.option('val4').value.set('new3')
compare(values.get_cached(), {'val1': {None: ('new', None)}, compare(values.get_cached(), {'val1': {None: ('new', None)},
'val2': {None: ('new', None)}, 'val2': {None: ('new', None)},
'val3': {None: ('new2', None)}, 'val3': {None: ('new2', None)},
'val4': {None: ('new3', None, True)}, 'val4': {None: ('new3', None, True)},
'val5': {None: (['yes'], None)}}) 'val5': {None: (['yes'], None)}})
await cfg.value.dict() await cfg.value.dict()
compare(values.get_cached(), {'val1': {None: ('new', None)}, compare(values.get_cached(), {'val1': {None: ('new', None)},
'val2': {None: ('new', None)}, 'val2': {None: ('new', None)},
'val3': {None: ('new2', None)}, 'val3': {None: ('new2', None)},
'val4': {None: ('new3', None)}, 'val4': {None: ('new3', None)},
'val5': {None: (['yes'], None)}}) 'val5': {None: (['yes'], None)}})
await cfg.option('val5').value.set([undefined, 'new4']) await cfg.option('val5').value.set([undefined, 'new4'])
compare(values.get_cached(), {'val1': {None: ('new', None)}, compare(values.get_cached(), {'val1': {None: ('new', None)},
'val2': {None: ('new', None)}, 'val2': {None: ('new', None)},
'val3': {None: ('new2', None)}, 'val3': {None: ('new2', None)},
'val4': {None: ('new3', None)}, 'val4': {None: ('new3', None)},
'val5': {None: (['yes', 'new4'], None)}}) 'val5': {None: (['yes', 'new4'], None)}})
await cfg.value.dict() await cfg.value.dict()
compare(values.get_cached(), {'val1': {None: ('new', None)}, compare(values.get_cached(), {'val1': {None: ('new', None)},
'val2': {None: ('new', None)}, 'val2': {None: ('new', None)},
'val3': {None: ('new2', None)}, 'val3': {None: ('new2', None)},
'val4': {None: ('new3', None)}, 'val4': {None: ('new3', None)},
'val5': {None: (['yes', 'new4'], None)}}) 'val5': {None: (['yes', 'new4'], None)}})
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -385,51 +386,52 @@ async def test_cache_leader_and_followers():
val2 = StrOption('val2', "", multi=True) val2 = StrOption('val2', "", multi=True)
interface1 = Leadership('val1', '', [val1, val2]) interface1 = Leadership('val1', '', [val1, val2])
od1 = OptionDescription('rootconfig', '', [interface1]) od1 = OptionDescription('rootconfig', '', [interface1])
cfg = await Config(od1) async with await Config(od1) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
await cfg.value.dict() await cfg.value.dict()
global_props = ['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value'] global_props = ['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']
val1_props = [] val1_props = []
val1_val1_props = ['empty', 'unique'] val1_val1_props = ['empty', 'unique']
val1_val2_props = [] val1_val2_props = []
global_props = frozenset(global_props) global_props = frozenset(global_props)
val1_props = frozenset(val1_props) val1_props = frozenset(val1_props)
val1_val1_props = frozenset(val1_val1_props) val1_val1_props = frozenset(val1_val1_props)
val1_val2_props = frozenset(val1_val2_props) val1_val2_props = frozenset(val1_val2_props)
#None because no value #None because no value
idx_val2 = None idx_val2 = None
values = cfg._config_bag.context._impl_values_cache values = cfg._config_bag.context._impl_values_cache
settings = cfg._config_bag.context._impl_properties_cache settings = cfg._config_bag.context._impl_properties_cache
compare(settings.get_cached(), {None: {None: (global_props, None)}, compare(settings.get_cached(), {None: {None: (global_props, None)},
'val1': {None: (val1_props, None)}, 'val1': {None: (val1_props, None)},
'val1.val1': {None: (val1_val1_props, None)}, 'val1.val1': {None: (val1_val1_props, None)},
'val1.val2': {idx_val2: (val1_val2_props, None)}}) 'val1.val2': {idx_val2: (val1_val2_props, None)}})
# len is 0 so don't get any value # len is 0 so don't get any value
compare(values.get_cached(), {'val1.val1': {None: ([], None)}}) compare(values.get_cached(), {'val1.val1': {None: ([], None)}})
# #
await cfg.option('val1.val1').value.set([undefined]) await cfg.option('val1.val1').value.set([undefined])
val_val2_props = {idx_val2: (val1_val2_props, None), None: (set(), None)} val_val2_props = {idx_val2: (val1_val2_props, None), None: (set(), None)}
compare(settings.get_cached(), {None: {None: (set(global_props), None)}, compare(settings.get_cached(), {None: {None: (set(global_props), None)},
'val1.val1': {None: (val1_val1_props, None)}, 'val1.val1': {None: (val1_val1_props, None)},
'val1.val2': val_val2_props}) 'val1.val2': val_val2_props})
compare(values.get_cached(), {'val1.val1': {None: ([None], None, True)}}) compare(values.get_cached(), {'val1.val1': {None: ([None], None, True)}})
await cfg.value.dict() await cfg.value.dict()
#has value #has value
idx_val2 = 0 idx_val2 = 0
val_val2 = None val_val2 = None
val_val2_props = {idx_val2: (val1_val2_props, None), None: (set(), None)} val_val2_props = {idx_val2: (val1_val2_props, None), None: (set(), None)}
compare(settings.get_cached(), {None: {None: (global_props, None)}, compare(settings.get_cached(), {None: {None: (global_props, None)},
'val1': {None: (val1_props, None)}, 'val1': {None: (val1_props, None)},
'val1.val1': {None: (val1_val1_props, None)}, 'val1.val1': {None: (val1_val1_props, None)},
'val1.val2': val_val2_props}) 'val1.val2': val_val2_props})
compare(values.get_cached(), {'val1.val1': {None: ([None], None)}, compare(values.get_cached(), {'val1.val1': {None: ([None], None)},
'val1.val2': {idx_val2: (val_val2, None)}}) 'val1.val2': {idx_val2: (val_val2, None)}})
await cfg.option('val1.val1').value.set([undefined, undefined]) await cfg.option('val1.val1').value.set([undefined, undefined])
await cfg.value.dict() await cfg.value.dict()
await cfg.option('val1.val2', 1).value.set('oui') await cfg.option('val1.val2', 1).value.set('oui')
compare(settings.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)}}) compare(settings.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)}})
compare(values.get_cached(), {'val1.val2': {1: ('oui', None, True)}}) compare(values.get_cached(), {'val1.val2': {1: ('oui', None, True)}})
val1_val2_props = {0: (frozenset([]), None), 1: (frozenset([]), None)} val1_val2_props = {0: (frozenset([]), None), 1: (frozenset([]), None)}
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -438,32 +440,32 @@ async def test_cache_leader_callback():
val2 = StrOption('val2', "", Calculation(calc_value, Params(kwargs={'value': ParamOption(val1)})), multi=True) val2 = StrOption('val2', "", Calculation(calc_value, Params(kwargs={'value': ParamOption(val1)})), multi=True)
interface1 = Leadership('val1', '', [val1, val2]) interface1 = Leadership('val1', '', [val1, val2])
od1 = OptionDescription('rootconfig', '', [interface1]) od1 = OptionDescription('rootconfig', '', [interface1])
cfg = await Config(od1) async with await Config(od1) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
await cfg.value.dict() await cfg.value.dict()
global_props = ['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value'] global_props = ['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']
val1_props = [] val1_props = []
val1_val1_props = ['empty', 'unique'] val1_val1_props = ['empty', 'unique']
val1_val2_props = [] val1_val2_props = []
global_props = frozenset(global_props) global_props = frozenset(global_props)
val1_props = frozenset(val1_props) val1_props = frozenset(val1_props)
val1_val1_props = frozenset(val1_val1_props) val1_val1_props = frozenset(val1_val1_props)
val1_val2_props = frozenset(val1_val2_props) val1_val2_props = frozenset(val1_val2_props)
values = cfg._config_bag.context._impl_values_cache values = cfg._config_bag.context._impl_values_cache
settings = cfg._config_bag.context._impl_properties_cache settings = cfg._config_bag.context._impl_properties_cache
compare(settings.get_cached(), {None: {None: (global_props, None)}, compare(settings.get_cached(), {None: {None: (global_props, None)},
'val1': {None: (val1_props, None)}, 'val1': {None: (val1_props, None)},
'val1.val1': {None: (val1_val1_props, None)}, 'val1.val1': {None: (val1_val1_props, None)},
'val1.val2': {None: (val1_val2_props, None)}}) 'val1.val2': {None: (val1_val2_props, None)}})
compare(values.get_cached(), {'val1.val1': {None: ([], None)}}) compare(values.get_cached(), {'val1.val1': {None: ([], None)}})
await cfg.option('val1.val1').value.set([undefined]) await cfg.option('val1.val1').value.set([undefined])
compare(settings.get_cached(), {None: {None: (set(global_props), None)}, compare(settings.get_cached(), {None: {None: (set(global_props), None)},
'val1': {None: (set(), None, True)}, 'val1.val1': {None: (val1_val1_props, None)},
'val1.val1': {None: (val1_val1_props, None)}, 'val1.val2': {None: (val1_val2_props, None)}})
'val1.val2': {None: (val1_val2_props, None)}})
compare(values.get_cached(), {'val1.val1': {None: ([None], None, True)}}) compare(values.get_cached(), {'val1.val1': {None: ([None], None, True)}})
await cfg.value.dict() await cfg.value.dict()
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -475,48 +477,49 @@ async def test_cache_requires():
'expected': ParamValue(False), 'expected': ParamValue(False),
'default': ParamValue(None)})) 'default': ParamValue(None)}))
b = IPOption('ip_address_service', '', properties=(disabled_property,)) b = IPOption('ip_address_service', '', properties=(disabled_property,))
od = OptionDescription('service', '', [a, b]) od1 = OptionDescription('service', '', [a, b])
cfg = await Config(od) async with await Config(od1) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
values = cfg._config_bag.context._impl_values_cache values = cfg._config_bag.context._impl_values_cache
settings = cfg._config_bag.context._impl_properties_cache settings = cfg._config_bag.context._impl_properties_cache
assert values.get_cached() == {} assert values.get_cached() == {}
assert await cfg.option('ip_address_service').value.get() == None assert await cfg.option('ip_address_service').value.get() == None
compare(settings.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)}, compare(settings.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)},
'activate_service': {None: (set([]), None)}, 'activate_service': {None: (set([]), None)},
'ip_address_service': {None: (set([]), None)}}) 'ip_address_service': {None: (set([]), None)}})
compare(values.get_cached(), {'ip_address_service': {None: (None, None)}, compare(values.get_cached(), {'ip_address_service': {None: (None, None)},
'activate_service': {None: (True, None)}}) 'activate_service': {None: (True, None)}})
await cfg.value.dict() await cfg.value.dict()
compare(settings.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)}, compare(settings.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)},
'activate_service': {None: (set([]), None)}, 'activate_service': {None: (set([]), None)},
'ip_address_service': {None: (set([]), None)}}) 'ip_address_service': {None: (set([]), None)}})
compare(values.get_cached(), {'ip_address_service': {None: (None, None)}, compare(values.get_cached(), {'ip_address_service': {None: (None, None)},
'activate_service': {None: (True, None)}}) 'activate_service': {None: (True, None)}})
await cfg.option('ip_address_service').value.set('1.1.1.1') await cfg.option('ip_address_service').value.set('1.1.1.1')
compare(settings.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)}, compare(settings.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)},
'activate_service': {None: (set([]), None)}}) 'activate_service': {None: (set([]), None)}})
compare(values.get_cached(), {'activate_service': {None: (True, None)}, 'ip_address_service': {None: ('1.1.1.1', None, True)}}) compare(values.get_cached(), {'activate_service': {None: (True, None)}, 'ip_address_service': {None: ('1.1.1.1', None, True)}})
await cfg.value.dict() await cfg.value.dict()
compare(settings.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)}, compare(settings.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)},
'activate_service': {None: (set([]), None)}, 'activate_service': {None: (set([]), None)},
'ip_address_service': {None: (set([]), None)}}) 'ip_address_service': {None: (set([]), None)}})
compare(values.get_cached(), {'ip_address_service': {None: ('1.1.1.1', None)}, compare(values.get_cached(), {'ip_address_service': {None: ('1.1.1.1', None)},
'activate_service': {None: (True, None)}}) 'activate_service': {None: (True, None)}})
await cfg.option('activate_service').value.set(False) await cfg.option('activate_service').value.set(False)
compare(settings.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)}}) compare(settings.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)}})
compare(values.get_cached(), {'activate_service': {None: (False, None)}}) compare(values.get_cached(), {'activate_service': {None: (False, None)}})
await cfg.value.dict() await cfg.value.dict()
compare(settings.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)}, compare(settings.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)},
'activate_service': {None: (set([]), None)}, 'activate_service': {None: (set([]), None)},
'ip_address_service': {None: (set(['disabled']), None)}}) 'ip_address_service': {None: (set(['disabled']), None)}})
compare(values.get_cached(), {'activate_service': {None: (False, None)}}) compare(values.get_cached(), {'activate_service': {None: (False, None)}})
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -528,29 +531,30 @@ async def test_cache_global_properties():
'expected': ParamValue(False), 'expected': ParamValue(False),
'default': ParamValue(None)})) 'default': ParamValue(None)}))
b = IPOption('ip_address_service', '', properties=(disabled_property,)) b = IPOption('ip_address_service', '', properties=(disabled_property,))
od = OptionDescription('service', '', [a, b]) od1 = OptionDescription('service', '', [a, b])
cfg = await Config(od) async with await Config(od1) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
values = cfg._config_bag.context._impl_values_cache values = cfg._config_bag.context._impl_values_cache
settings = cfg._config_bag.context._impl_properties_cache settings = cfg._config_bag.context._impl_properties_cache
assert values.get_cached() == {} assert values.get_cached() == {}
assert await cfg.option('ip_address_service').value.get() == None assert await cfg.option('ip_address_service').value.get() == None
compare(settings.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)}, compare(settings.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)},
'activate_service': {None: (set([]), None)}, 'activate_service': {None: (set([]), None)},
'ip_address_service': {None: (set([]), None)}}) 'ip_address_service': {None: (set([]), None)}})
compare(values.get_cached(), {'ip_address_service': {None: (None, None)}, compare(values.get_cached(), {'ip_address_service': {None: (None, None)},
'activate_service': {None: (True, None)}}) 'activate_service': {None: (True, None)}})
await cfg.property.pop('disabled') await cfg.property.pop('disabled')
assert await cfg.option('ip_address_service').value.get() == None assert await cfg.option('ip_address_service').value.get() == None
compare(settings.get_cached(), {None: {None: (set(['cache', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)}, compare(settings.get_cached(), {None: {None: (set(['cache', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)},
'activate_service': {None: (set([]), None)}, 'activate_service': {None: (set([]), None)},
'ip_address_service': {None: (set([]), None)}}) 'ip_address_service': {None: (set([]), None)}})
await cfg.property.add('test') await cfg.property.add('test')
assert await cfg.option('ip_address_service').value.get() == None assert await cfg.option('ip_address_service').value.get() == None
compare(settings.get_cached(), {None: {None: (set(['cache', 'frozen', 'hidden', 'validator', 'warnings', 'test', 'force_store_value']), None)}, compare(settings.get_cached(), {None: {None: (set(['cache', 'frozen', 'hidden', 'validator', 'warnings', 'test', 'force_store_value']), None)},
'activate_service': {None: (set([]), None)}, 'activate_service': {None: (set([]), None)},
'ip_address_service': {None: (set([]), None)}}) 'ip_address_service': {None: (set([]), None)}})
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -558,19 +562,20 @@ async def test_callback_value_incr():
val1 = IntOption('val1', "", Calculation(return_incr), properties=('expire',)) val1 = IntOption('val1', "", Calculation(return_incr), properties=('expire',))
val2 = IntOption('val2', "", Calculation(calc_value, Params(ParamOption(val1)))) val2 = IntOption('val2', "", Calculation(calc_value, Params(ParamOption(val1))))
od1 = OptionDescription('rootconfig', '', [val1, val2]) od1 = OptionDescription('rootconfig', '', [val1, val2])
cfg = await Config(od1) async with await Config(od1) as cfg:
assert await cfg.cache.get_expiration_time() == 5 assert await cfg.cache.get_expiration_time() == 5
await cfg.cache.set_expiration_time(1) await cfg.cache.set_expiration_time(1)
assert await cfg.cache.get_expiration_time() == 1 assert await cfg.cache.get_expiration_time() == 1
await cfg.property.read_write() await cfg.property.read_write()
assert await cfg.option('val1').value.get() == 1 assert await cfg.option('val1').value.get() == 1
sleep(1) sleep(1)
assert await cfg.option('val2').value.get() == 1 assert await cfg.option('val2').value.get() == 1
sleep(1) sleep(1)
assert await cfg.option('val1').value.get() == 1 assert await cfg.option('val1').value.get() == 1
assert await cfg.option('val2').value.get() == 1 assert await cfg.option('val2').value.get() == 1
sleep(2) sleep(2)
assert await cfg.option('val1').value.get() == 2 assert await cfg.option('val1').value.get() == 2
assert await cfg.option('val2').value.get() == 2 assert await cfg.option('val2').value.get() == 2
assert await cfg.option('val1').value.get() == 2 assert await cfg.option('val1').value.get() == 2
assert await cfg.option('val2').value.get() == 2 assert await cfg.option('val2').value.get() == 2
assert not await list_sessions()

View file

@ -4,17 +4,13 @@ import pytest
from .autopath import do_autopath from .autopath import do_autopath
do_autopath() do_autopath()
from .config import config_type, get_config, value_list, global_owner from .config import config_type, get_config, value_list, global_owner, event_loop
from tiramisu import ChoiceOption, StrOption, OptionDescription, Config, owners, Calculation, \ from tiramisu import ChoiceOption, StrOption, OptionDescription, Config, owners, Calculation, \
undefined, Params, ParamValue, ParamOption, list_sessions undefined, Params, ParamValue, ParamOption, list_sessions
from tiramisu.error import ConfigError from tiramisu.error import ConfigError
def teardown_function(function):
assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__)
def return_val(val): def return_val(val):
return val return val
@ -35,101 +31,107 @@ def return_error(*args, **kwargs):
async def test_choiceoption(config_type): async def test_choiceoption(config_type):
choice = ChoiceOption('choice', '', values=('val1', 'val2')) choice = ChoiceOption('choice', '', values=('val1', 'val2'))
odesc = OptionDescription('od', '', [choice]) odesc = OptionDescription('od', '', [choice])
cfg = await Config(odesc) async with await Config(odesc) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
owner = await global_owner(cfg, config_type) owner = await global_owner(cfg, config_type)
assert await cfg.option('choice').owner.get() == owners.default assert await cfg.option('choice').owner.get() == owners.default
assert await cfg.option('choice').owner.isdefault() assert await cfg.option('choice').owner.isdefault()
# #
await cfg.option('choice').value.set('val1') await cfg.option('choice').value.set('val1')
assert await cfg.option('choice').owner.get() == owner assert await cfg.option('choice').owner.get() == owner
assert not await cfg.option('choice').owner.isdefault() assert not await cfg.option('choice').owner.isdefault()
# #
await cfg.option('choice').value.reset() await cfg.option('choice').value.reset()
assert await cfg.option('choice').owner.get() == owners.default assert await cfg.option('choice').owner.get() == owners.default
assert await cfg.option('choice').owner.isdefault() assert await cfg.option('choice').owner.isdefault()
# #
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('choice').value.set('no') await cfg.option('choice').value.set('no')
assert await cfg.option('choice').owner.get() == owners.default assert await cfg.option('choice').owner.get() == owners.default
assert await cfg.option('choice').owner.isdefault() assert await cfg.option('choice').owner.isdefault()
# #
assert value_list(await cfg.option('choice').value.list()) == ('val1', 'val2') assert value_list(await cfg.option('choice').value.list()) == ('val1', 'val2')
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_choiceoption_function(config_type): async def test_choiceoption_function(config_type):
choice = ChoiceOption('choice', '', values=Calculation(return_list)) choice = ChoiceOption('choice', '', values=Calculation(return_list))
odesc = OptionDescription('od', '', [choice]) odesc = OptionDescription('od', '', [choice])
cfg = await Config(odesc) async with await Config(odesc) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
owner = await global_owner(cfg, config_type) owner = await global_owner(cfg, config_type)
assert await cfg.option('choice').owner.isdefault() assert await cfg.option('choice').owner.isdefault()
# #
await cfg.option('choice').value.set('val1') await cfg.option('choice').value.set('val1')
assert await cfg.option('choice').owner.get() == owner assert await cfg.option('choice').owner.get() == owner
# #
await cfg.option('choice').value.reset() await cfg.option('choice').value.reset()
assert await cfg.option('choice').owner.isdefault() assert await cfg.option('choice').owner.isdefault()
# #
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('choice').value.set('no') await cfg.option('choice').value.set('no')
assert await cfg.option('choice').owner.isdefault() assert await cfg.option('choice').owner.isdefault()
# #
assert value_list(await cfg.option('choice').value.list()) == ('val1', 'val2') assert value_list(await cfg.option('choice').value.list()) == ('val1', 'val2')
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_choiceoption_function_error(): async def test_choiceoption_function_error():
choice = ChoiceOption('choice', '', values=Calculation(return_error)) choice = ChoiceOption('choice', '', values=Calculation(return_error))
odesc = OptionDescription('od', '', [choice]) odesc = OptionDescription('od', '', [choice])
cfg = await Config(odesc) async with await Config(odesc) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
with pytest.raises(ConfigError): with pytest.raises(ConfigError):
await cfg.option('choice').value.set('val1') await cfg.option('choice').value.set('val1')
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_choiceoption_function_error_args(): async def test_choiceoption_function_error_args():
choice = ChoiceOption('choice', '', values=Calculation(return_error, Params(ParamValue('val1')))) choice = ChoiceOption('choice', '', values=Calculation(return_error, Params(ParamValue('val1'))))
odesc = OptionDescription('od', '', [choice]) odesc = OptionDescription('od', '', [choice])
cfg = await Config(odesc) async with await Config(odesc) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
with pytest.raises(ConfigError): with pytest.raises(ConfigError):
await cfg.option('choice').value.set('val1') await cfg.option('choice').value.set('val1')
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_choiceoption_function_error_kwargs(): async def test_choiceoption_function_error_kwargs():
choice = ChoiceOption('choice', '', values=Calculation(return_error, Params(kwargs={'kwargs': ParamValue('val1')}))) choice = ChoiceOption('choice', '', values=Calculation(return_error, Params(kwargs={'kwargs': ParamValue('val1')})))
odesc = OptionDescription('od', '', [choice]) odesc = OptionDescription('od', '', [choice])
cfg = await Config(odesc) async with await Config(odesc) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
with pytest.raises(ConfigError): with pytest.raises(ConfigError):
await cfg.option('choice').value.set('val1') await cfg.option('choice').value.set('val1')
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_choiceoption_calc_function(config_type): async def test_choiceoption_calc_function(config_type):
choice = ChoiceOption('choice', "", values=Calculation(return_calc_list, Params(ParamValue('val1')))) choice = ChoiceOption('choice', "", values=Calculation(return_calc_list, Params(ParamValue('val1'))))
odesc = OptionDescription('od', '', [choice]) odesc = OptionDescription('od', '', [choice])
cfg = await Config(odesc) async with await Config(odesc) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
owner = await global_owner(cfg, config_type) owner = await global_owner(cfg, config_type)
assert await cfg.option('choice').owner.isdefault() assert await cfg.option('choice').owner.isdefault()
# #
await cfg.option('choice').value.set('val1') await cfg.option('choice').value.set('val1')
assert await cfg.option('choice').owner.get() == owner assert await cfg.option('choice').owner.get() == owner
# #
await cfg.option('choice').value.reset() await cfg.option('choice').value.reset()
assert await cfg.option('choice').owner.isdefault() assert await cfg.option('choice').owner.isdefault()
# #
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('choice').value.set('no') await cfg.option('choice').value.set('no')
assert await cfg.option('choice').owner.isdefault() assert await cfg.option('choice').owner.isdefault()
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -139,21 +141,22 @@ async def test_choiceoption_calc_opt_function(config_type):
"", "",
values=Calculation(return_calc_list, Params(ParamOption(str_)))) values=Calculation(return_calc_list, Params(ParamOption(str_))))
odesc = OptionDescription('od', '', [str_, choice]) odesc = OptionDescription('od', '', [str_, choice])
cfg = await Config(odesc) async with await Config(odesc) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
owner = await cfg.owner.get() owner = await cfg.owner.get()
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
assert await cfg.option('choice').owner.isdefault() assert await cfg.option('choice').owner.isdefault()
# #
await cfg.option('choice').value.set('val1') await cfg.option('choice').value.set('val1')
assert await cfg.option('choice').owner.get() == owner assert await cfg.option('choice').owner.get() == owner
# #
await cfg.option('choice').value.reset() await cfg.option('choice').value.reset()
assert await cfg.option('choice').owner.isdefault() assert await cfg.option('choice').owner.isdefault()
# #
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('choice').value.set('no') await cfg.option('choice').value.set('no')
assert await cfg.option('choice').owner.isdefault() assert await cfg.option('choice').owner.isdefault()
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -163,10 +166,11 @@ async def test_choiceoption_calc_opt_function_propertyerror():
"", "",
values=Calculation(return_calc_list, Params(ParamOption(str_)))) values=Calculation(return_calc_list, Params(ParamOption(str_))))
odesc = OptionDescription('od', '', [str_, choice]) odesc = OptionDescription('od', '', [str_, choice])
cfg = await Config(odesc) async with await Config(odesc) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
with pytest.raises(ConfigError): with pytest.raises(ConfigError):
await cfg.option('choice').value.set('no') await cfg.option('choice').value.set('no')
assert not await list_sessions()
#def test_choiceoption_calc_opt_multi_function(config_type): #def test_choiceoption_calc_opt_multi_function(config_type):
@ -186,31 +190,32 @@ async def test_choiceoption_calc_opt_multi_function():
values=Calculation(return_val, Params(ParamOption(str_))), values=Calculation(return_val, Params(ParamOption(str_))),
multi=True) multi=True)
odesc = OptionDescription('od', '', [str_, choice, ch2]) odesc = OptionDescription('od', '', [str_, choice, ch2])
cfg = await Config(odesc) async with await Config(odesc) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
owner = await cfg.owner.get() owner = await cfg.owner.get()
cfg = await get_config(cfg, config_type, True) cfg = await get_config(cfg, config_type, True)
assert await cfg.option('choice').owner.isdefault() assert await cfg.option('choice').owner.isdefault()
assert await cfg.option('choice').value.get() == [] assert await cfg.option('choice').value.get() == []
# #
await cfg.option('choice').value.set(['val1']) await cfg.option('choice').value.set(['val1'])
assert await cfg.option('choice').owner.get() == owner assert await cfg.option('choice').owner.get() == owner
# #
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('choice').value.set([undefined]) await cfg.option('choice').value.set([undefined])
# #
await cfg.option('choice').value.set(['val1']) await cfg.option('choice').value.set(['val1'])
assert await cfg.option('choice').owner.get() == owner assert await cfg.option('choice').owner.get() == owner
# #
await cfg.option('choice').value.reset() await cfg.option('choice').value.reset()
assert await cfg.option('choice').owner.isdefault() assert await cfg.option('choice').owner.isdefault()
# #
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('choice').value.set('no') await cfg.option('choice').value.set('no')
assert await cfg.option('choice').owner.isdefault() assert await cfg.option('choice').owner.isdefault()
# #
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('ch2').value.get() await cfg.option('ch2').value.get()
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -227,31 +232,32 @@ async def test_choiceoption_calc_opt_multi_function_kwargs(config_type):
values=Calculation(return_val, Params(kwargs={'val': ParamOption(str_)})), values=Calculation(return_val, Params(kwargs={'val': ParamOption(str_)})),
multi=True) multi=True)
odesc = OptionDescription('od', '', [str_, choice, ch2]) odesc = OptionDescription('od', '', [str_, choice, ch2])
cfg = await Config(odesc) async with await Config(odesc) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
owner = await cfg.owner.get() owner = await cfg.owner.get()
# FIXME cfg = await get_config(cfg, config_type) # FIXME cfg = await get_config(cfg, config_type)
assert await cfg.option('choice').owner.isdefault() assert await cfg.option('choice').owner.isdefault()
assert await cfg.option('choice').value.get() == [] assert await cfg.option('choice').value.get() == []
# #
await cfg.option('choice').value.set(['val1']) await cfg.option('choice').value.set(['val1'])
assert await cfg.option('choice').owner.get() == owner assert await cfg.option('choice').owner.get() == owner
# #
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('choice').value.set([undefined]) await cfg.option('choice').value.set([undefined])
# #
await cfg.option('choice').value.set(['val1']) await cfg.option('choice').value.set(['val1'])
assert await cfg.option('choice').owner.get() == owner assert await cfg.option('choice').owner.get() == owner
# #
await cfg.option('choice').value.reset() await cfg.option('choice').value.reset()
assert await cfg.option('choice').owner.isdefault() assert await cfg.option('choice').owner.isdefault()
# #
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('choice').value.set('no') await cfg.option('choice').value.set('no')
assert await cfg.option('choice').owner.isdefault() assert await cfg.option('choice').owner.isdefault()
# #
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('ch2').value.get() await cfg.option('ch2').value.get()
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -263,7 +269,8 @@ async def test_choiceoption_calc_not_list():
values=Calculation(return_val, Params(ParamOption(str_))), values=Calculation(return_val, Params(ParamOption(str_))),
multi=True) multi=True)
odesc = OptionDescription('od', '', [str_, choice]) odesc = OptionDescription('od', '', [str_, choice])
cfg = await Config(odesc) async with await Config(odesc) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
with pytest.raises(ConfigError): with pytest.raises(ConfigError):
await cfg.option('choice').value.set(['val1']) await cfg.option('choice').value.set(['val1'])
assert not await list_sessions()

View file

@ -6,22 +6,18 @@ import weakref
from .autopath import do_autopath from .autopath import do_autopath
do_autopath() do_autopath()
from .config import config_type, get_config, value_list, global_owner from .config import config_type, get_config, value_list, global_owner, event_loop
import pytest import pytest
from tiramisu import Config from tiramisu import Config
from tiramisu.config import SubConfig from tiramisu.config import SubConfig
from tiramisu.i18n import _ from tiramisu.i18n import _
from tiramisu import Config, IntOption, FloatOption, ChoiceOption, \ from tiramisu import Config, IntOption, FloatOption, ChoiceOption, \
BoolOption, StrOption, SymLinkOption, OptionDescription, undefined BoolOption, StrOption, SymLinkOption, OptionDescription, undefined, delete_session
from tiramisu.error import ConflictError, ConfigError, PropertiesOptionError, APIError from tiramisu.error import ConflictError, ConfigError, PropertiesOptionError, APIError
from tiramisu.storage import list_sessions 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(): def make_description():
gcoption = ChoiceOption('name', 'GC name', ('ref', 'framework'), 'ref') gcoption = ChoiceOption('name', 'GC name', ('ref', 'framework'), 'ref')
gcdummy = BoolOption('dummy', 'dummy', default=False) gcdummy = BoolOption('dummy', 'dummy', default=False)
@ -52,20 +48,22 @@ async def test_base_config(config_type):
""" """
gcdummy = BoolOption('dummy', 'dummy', default=False) gcdummy = BoolOption('dummy', 'dummy', default=False)
descr = OptionDescription('tiramisu', '', [gcdummy]) descr = OptionDescription('tiramisu', '', [gcdummy])
cfg = await Config(descr) async with await Config(descr) as cfg:
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
assert await cfg.option('dummy').value.get() is False assert await cfg.option('dummy').value.get() is False
#dmo = await cfg.unwrap_from_path('dummy') #dmo = await cfg.unwrap_from_path('dummy')
#assert dmo.impl_getname() == 'dummy' #assert dmo.impl_getname() == 'dummy'
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_base_config_name(): async def test_base_config_name():
gcdummy = BoolOption('dummy', 'dummy', default=False) gcdummy = BoolOption('dummy', 'dummy', default=False)
descr = OptionDescription('tiramisu', '', [gcdummy]) descr = OptionDescription('tiramisu', '', [gcdummy])
cfg = await Config(descr, session_id='cfg') async with await Config(descr, session_id='cfg') as cfg:
await cfg.config.name() == 'cfg' await cfg.session.id() == 'cfg'
#raises(ValueError, "Config(descr, session_id='unvalid name')") #raises(ValueError, "Config(descr, session_id='unvalid name')")
assert not await list_sessions()
# #
# #
#@pytest.mark.asyncio #@pytest.mark.asyncio
@ -77,22 +75,25 @@ async def test_base_config_name():
async def test_base_path(): async def test_base_path():
gcdummy = BoolOption('dummy', 'dummy', default=False) gcdummy = BoolOption('dummy', 'dummy', default=False)
descr = OptionDescription('tiramisu', '', [gcdummy]) descr = OptionDescription('tiramisu', '', [gcdummy])
await Config(descr) async with await Config(descr) as cfg:
base = OptionDescription('config', '', [descr]) base = OptionDescription('config', '', [descr])
base with pytest.raises(ConfigError):
with pytest.raises(ConfigError): async with await Config(base, session_id='error'):
await Config(base) pass
await delete_session('error')
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_base_config_force_permissive(): async def test_base_config_force_permissive():
descr = make_description() descr = make_description()
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
await cfg.permissive.add('hidden') await cfg.permissive.add('hidden')
with pytest.raises(PropertiesOptionError): with pytest.raises(PropertiesOptionError):
await cfg.option('boolop').value.get() await cfg.option('boolop').value.get()
assert await cfg.forcepermissive.option('boolop').value.get() is True assert await cfg.forcepermissive.option('boolop').value.get() is True
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -101,111 +102,115 @@ async def test_base_config_in_a_tree():
config_type = 'tiramisu' config_type = 'tiramisu'
"how options are organized into a tree, see :ref:`tree`" "how options are organized into a tree, see :ref:`tree`"
descr = make_description() descr = make_description()
cfg = await Config(descr) async with await Config(descr) as cfg:
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
# #
await cfg.option('bool').value.set(False) await cfg.option('bool').value.set(False)
# #
assert await cfg.option('gc.name').value.get() == 'ref' assert await cfg.option('gc.name').value.get() == 'ref'
await cfg.option('gc.name').value.set('framework') await cfg.option('gc.name').value.set('framework')
assert await cfg.option('gc.name').value.get() == 'framework' assert await cfg.option('gc.name').value.get() == 'framework'
# #
assert await cfg.option('objspace').value.get() == 'std' assert await cfg.option('objspace').value.get() == 'std'
await cfg.option('objspace').value.set('thunk') await cfg.option('objspace').value.set('thunk')
assert await cfg.option('objspace').value.get() == 'thunk' assert await cfg.option('objspace').value.get() == 'thunk'
# #
assert await cfg.option('gc.float').value.get() == 2.3 assert await cfg.option('gc.float').value.get() == 2.3
await cfg.option('gc.float').value.set(3.4) await cfg.option('gc.float').value.set(3.4)
assert await cfg.option('gc.float').value.get() == 3.4 assert await cfg.option('gc.float').value.get() == 3.4
# #
assert await cfg.option('int').value.get() == 0 assert await cfg.option('int').value.get() == 0
await cfg.option('int').value.set(123) await cfg.option('int').value.set(123)
assert await cfg.option('int').value.get() == 123 assert await cfg.option('int').value.get() == 123
# #
assert await cfg.option('wantref').value.get() is False assert await cfg.option('wantref').value.get() is False
await cfg.option('wantref').value.set(True) await cfg.option('wantref').value.set(True)
assert await cfg.option('wantref').value.get() is True assert await cfg.option('wantref').value.get() is True
# #
assert await cfg.option('str').value.get() == 'abc' assert await cfg.option('str').value.get() == 'abc'
await cfg.option('str').value.set('def') await cfg.option('str').value.set('def')
assert await cfg.option('str').value.get() == 'def' assert await cfg.option('str').value.get() == 'def'
# #
with pytest.raises(AttributeError): with pytest.raises(AttributeError):
await cfg.option('gc.foo').value.get() await cfg.option('gc.foo').value.get()
## ##
cfg = await Config(descr) async with await Config(descr) as cfg:
assert await cfg.option('bool').value.get() is True assert await cfg.option('bool').value.get() is True
assert await cfg.option('gc.name').value.get() == 'ref' assert await cfg.option('gc.name').value.get() == 'ref'
assert await cfg.option('wantframework').value.get() is False assert await cfg.option('wantframework').value.get() is False
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_not_valid_properties(): async def test_not_valid_properties():
with pytest.raises(AssertionError): with pytest.raises(AssertionError):
stroption = StrOption('str', 'Test string option', default='abc', properties='mandatory') stroption = StrOption('str', 'Test string option', default='abc', properties='mandatory')
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_information_config(): async def test_information_config():
descr = make_description() descr = make_description()
cfg = await Config(descr) async with await Config(descr) as cfg:
string = 'some informations' string = 'some informations'
# #
assert list(await cfg.information.list()) == [] assert list(await cfg.information.list()) == []
await cfg.information.set('info', string) await cfg.information.set('info', string)
assert await cfg.information.get('info') == string assert await cfg.information.get('info') == string
assert list(await cfg.information.list()) == ['info'] assert list(await cfg.information.list()) == ['info']
# #
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.information.get('noinfo') await cfg.information.get('noinfo')
assert await cfg.information.get('noinfo', 'default') == 'default' assert await cfg.information.get('noinfo', 'default') == 'default'
await cfg.information.reset('info') await cfg.information.reset('info')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.information.get('info') await cfg.information.get('info')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.information.reset('noinfo') await cfg.information.reset('noinfo')
assert list(await cfg.information.list()) == [] assert list(await cfg.information.list()) == []
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_information_option(): async def test_information_option():
descr = make_description() descr = make_description()
cfg = await Config(descr) async with await Config(descr) as cfg:
string = 'some informations' string = 'some informations'
# #
list(await cfg.option('gc.name').information.list()) == [] list(await cfg.option('gc.name').information.list()) == []
await cfg.option('gc.name').information.set('info', string) await cfg.option('gc.name').information.set('info', string)
assert await cfg.option('gc.name').information.get('info') == string assert await cfg.option('gc.name').information.get('info') == string
list(await cfg.option('gc.name').information.list()) == ['info'] list(await cfg.option('gc.name').information.list()) == ['info']
# #
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('gc.name').information.get('noinfo') await cfg.option('gc.name').information.get('noinfo')
assert await cfg.option('gc.name').information.get('noinfo', 'default') == 'default' assert await cfg.option('gc.name').information.get('noinfo', 'default') == 'default'
await cfg.option('gc.name').information.reset('info') await cfg.option('gc.name').information.reset('info')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('gc.name').information.get('info') await cfg.option('gc.name').information.get('info')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('gc.name').information.reset('noinfo') await cfg.option('gc.name').information.reset('noinfo')
list(await cfg.option('gc.name').information.list()) == [] list(await cfg.option('gc.name').information.list()) == []
# #
assert await cfg.option('wantref').information.get('info') == 'default value' assert await cfg.option('wantref').information.get('info') == 'default value'
await cfg.option('wantref').information.set('info', 'default value') await cfg.option('wantref').information.set('info', 'default value')
assert await cfg.option('wantref').information.get('info') == 'default value' assert await cfg.option('wantref').information.get('info') == 'default value'
await cfg.option('wantref').information.reset('info') await cfg.option('wantref').information.reset('info')
assert await cfg.option('wantref').information.get('info') == 'default value' assert await cfg.option('wantref').information.get('info') == 'default value'
assert not await list_sessions()
def to_tuple(val): def compare(val1, val2):
ret = [] assert len(val1[0]) == len(val2[0])
for v in val: for idx1, val_1 in enumerate(val1[0]):
t = [] idx2 = val2[0].index(val_1)
for w in v: assert val1[0][idx1] == val2[0][idx2]
if isinstance(w, list): assert val1[1][idx1] == val2[1][idx2]
t.append(tuple(w)) if isinstance(val2[2][idx2], tuple):
else: assert val2[2][idx2] == tuple(val1[2][idx1])
t.append(w) else:
ret.append(tuple(t)) assert val2[2][idx2] == val1[2][idx1]
return tuple(ret) assert val1[3][idx1] == val2[3][idx2]
@pytest.mark.asyncio @pytest.mark.asyncio
@ -218,27 +223,28 @@ async def test_get_modified_values():
g6 = StrOption('g6', '', multi=True) g6 = StrOption('g6', '', multi=True)
d1 = OptionDescription('od', '', [g1, g2, g3, g4, g5, g6]) d1 = OptionDescription('od', '', [g1, g2, g3, g4, g5, g6])
root = OptionDescription('root', '', [d1]) root = OptionDescription('root', '', [d1])
cfg = await Config(root) async with await Config(root) as cfg:
assert to_tuple(await cfg.value.exportation()) == ((), (), (), ()) compare(await cfg.value.exportation(), ((), (), (), ()))
assert not await cfg.option('od.g5').option.ismulti() assert not await cfg.option('od.g5').option.ismulti()
assert not await cfg.option('od.g5').option.issubmulti() assert not await cfg.option('od.g5').option.issubmulti()
await cfg.option('od.g5').value.set('yes') await cfg.option('od.g5').value.set('yes')
assert to_tuple(await cfg.value.exportation()) == (('od.g5',), (None,), ('yes',), ('user',)) compare(await cfg.value.exportation(), (('od.g5',), (None,), ('yes',), ('user',)))
await cfg.option('od.g4').value.set(False) 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')) compare(await cfg.value.exportation(), (('od.g5', 'od.g4'), (None, None), ('yes', False), ('user', 'user')))
await cfg.option('od.g4').value.set(undefined) 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')) compare(await cfg.value.exportation(), (('od.g5', 'od.g4'), (None, None), ('yes', True), ('user', 'user')))
await cfg.option('od.g4').value.reset() await cfg.option('od.g4').value.reset()
assert to_tuple(await cfg.value.exportation()) == (('od.g5',), (None,), ('yes',), ('user',)) compare(await cfg.value.exportation(), (('od.g5',), (None,), ('yes',), ('user',)))
assert await cfg.option('od.g6').option.ismulti() assert await cfg.option('od.g6').option.ismulti()
await cfg.option('od.g6').value.set([undefined]) 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')) compare(await cfg.value.exportation(), (('od.g5', 'od.g6'), (None, None), ('yes', (None,)), ('user', 'user')))
await cfg.option('od.g6').value.set([]) await cfg.option('od.g6').value.set([])
assert to_tuple(await cfg.value.exportation()) == (('od.g5', 'od.g6'), (None, None), ('yes', tuple()), ('user', 'user')) compare(await cfg.value.exportation(), (('od.g5', 'od.g6'), (None, None), ('yes', tuple()), ('user', 'user')))
await cfg.option('od.g6').value.set(['3']) 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')) compare(await cfg.value.exportation(), (('od.g5', 'od.g6'), (None, None), ('yes', ('3',)), ('user', 'user')))
await cfg.option('od.g6').value.set([]) await cfg.option('od.g6').value.set([])
assert to_tuple(await cfg.value.exportation()) == (('od.g5', 'od.g6'), (None, None), ('yes', tuple()), ('user', 'user')) compare(await cfg.value.exportation(), (('od.g5', 'od.g6'), (None, None), ('yes', tuple()), ('user', 'user')))
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -246,12 +252,13 @@ async def test_get_modified_values_not_modif(config_type):
g1 = StrOption('g1', '', multi=True) g1 = StrOption('g1', '', multi=True)
d1 = OptionDescription('od', '', [g1]) d1 = OptionDescription('od', '', [g1])
root = OptionDescription('root', '', [d1]) root = OptionDescription('root', '', [d1])
cfg = await Config(root) async with await Config(root) as cfg:
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
assert await cfg.option('od.g1').value.get() == [] assert await cfg.option('od.g1').value.get() == []
value = await cfg.option('od.g1').value.get() value = await cfg.option('od.g1').value.get()
value.append('val') value.append('val')
assert await cfg.option('od.g1').value.get() == [] assert await cfg.option('od.g1').value.get() == []
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -259,8 +266,9 @@ async def test_duplicated_option():
g1 = IntOption('g1', '', 1) g1 = IntOption('g1', '', 1)
g1 g1
#in same OptionDescription #in same OptionDescription
with pytest.raises(ConflictError): with pytest.raises(ConflictError):
d1 = OptionDescription('od', '', [g1, g1]) d1 = OptionDescription('od', '', [g1, g1])
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -270,16 +278,19 @@ async def test_duplicated_option_diff_od():
#in different OptionDescription #in different OptionDescription
d2 = OptionDescription('od2', '', [g1, d1]) d2 = OptionDescription('od2', '', [g1, d1])
d2 d2
with pytest.raises(ConflictError): with pytest.raises(ConflictError):
await Config(d2) await Config(d2, session_id='error')
await delete_session('error')
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_cannot_assign_value_to_option_description(): async def test_cannot_assign_value_to_option_description():
descr = make_description() descr = make_description()
cfg = await Config(descr) async with await Config(descr) as cfg:
with pytest.raises(APIError): with pytest.raises(APIError):
await cfg.option('gc').value.set(3) await cfg.option('gc').value.set(3)
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -288,33 +299,35 @@ async def test_config_multi(config_type):
i2 = IntOption('test2', '', multi=True, default_multi=1) i2 = IntOption('test2', '', multi=True, default_multi=1)
i3 = IntOption('test3', '', default=[2], multi=True, default_multi=1) i3 = IntOption('test3', '', default=[2], multi=True, default_multi=1)
od = OptionDescription('test', '', [i1, i2, i3]) od = OptionDescription('test', '', [i1, i2, i3])
cfg = await Config(od) async with await Config(od) as cfg:
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
assert await cfg.option('test1').value.get() == [] assert await cfg.option('test1').value.get() == []
assert await cfg.option('test2').value.get() == [] assert await cfg.option('test2').value.get() == []
await cfg.option('test2').value.set([undefined]) await cfg.option('test2').value.set([undefined])
assert await cfg.option('test2').value.get() == [1] assert await cfg.option('test2').value.get() == [1]
assert await cfg.option('test3').value.get() == [2] assert await cfg.option('test3').value.get() == [2]
await cfg.option('test3').value.set([undefined, undefined]) await cfg.option('test3').value.set([undefined, undefined])
assert await cfg.option('test3').value.get() == [2, 1] assert await cfg.option('test3').value.get() == [2, 1]
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_prefix_error(): async def test_prefix_error():
i1 = IntOption('test1', '') i1 = IntOption('test1', '')
od = OptionDescription('test', '', [i1]) od = OptionDescription('test', '', [i1])
cfg = await Config(od) async with await Config(od) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
await cfg.option('test1').value.set(1) await cfg.option('test1').value.set(1)
try: try:
await cfg.option('test1').value.set('yes') await cfg.option('test1').value.set('yes')
except Exception as err: except Exception as err:
assert str(err) == _('"{0}" is an invalid {1} for "{2}"').format('yes', _('integer'), 'test1') assert str(err) == _('"{0}" is an invalid {1} for "{2}"').format('yes', _('integer'), 'test1')
try: try:
await cfg.option('test1').value.set('yes') await cfg.option('test1').value.set('yes')
except Exception as err: except Exception as err:
err.prefix = '' err.prefix = ''
assert str(err) == _('invalid value') assert str(err) == _('invalid value')
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -323,22 +336,23 @@ async def test_no_validation():
config_type = 'tiramisu' config_type = 'tiramisu'
i1 = IntOption('test1', '') i1 = IntOption('test1', '')
od = OptionDescription('test', '', [i1]) od = OptionDescription('test', '', [i1])
config = await Config(od) async with await Config(od) as config:
await config.property.read_write() await config.property.read_write()
cfg = await get_config(config, config_type) cfg = await get_config(config, config_type)
await cfg.option('test1').value.set(1) await cfg.option('test1').value.set(1)
with pytest.raises(ValueError): 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') await cfg.option('test1').value.set('yes')
assert await cfg.option('test1').value.get() == 1 assert await cfg.option('test1').value.get() == 'yes'
await config.property.pop('validator') await cfg.property.add('validator')
cfg = await get_config(config, config_type) with pytest.raises(ValueError):
await cfg.option('test1').value.set('yes') await cfg.option('test1').value.get()
assert await cfg.option('test1').value.get() == 'yes' await cfg.option('test1').value.reset()
await cfg.property.add('validator') assert await cfg.option('test1').value.get() is None
with pytest.raises(ValueError): assert not await list_sessions()
await cfg.option('test1').value.get()
await cfg.option('test1').value.reset()
assert await cfg.option('test1').value.get() is None
@pytest.mark.asyncio @pytest.mark.asyncio
@ -346,10 +360,11 @@ async def test_subconfig():
i = IntOption('i', '') i = IntOption('i', '')
o = OptionDescription('val', '', [i]) o = OptionDescription('val', '', [i])
o2 = OptionDescription('val', '', [o]) o2 = OptionDescription('val', '', [o])
cfg = await Config(o2) async with await Config(o2) as cfg:
cfg cfg
with pytest.raises(TypeError): with pytest.raises(TypeError):
await SubConfig(i, weakref.ref(cfg)) await SubConfig(i, weakref.ref(cfg))
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -360,9 +375,11 @@ async def test_config_subconfig():
i4 = IntOption('i4', '', default=2) i4 = IntOption('i4', '', default=2)
od1 = OptionDescription('od1', '', [i1, i2, i3, i4]) od1 = OptionDescription('od1', '', [i1, i2, i3, i4])
od2 = OptionDescription('od2', '', [od1]) od2 = OptionDescription('od2', '', [od1])
cfg = await Config(od2, session_id='conf1') async with await Config(od2, session_id='conf1') as cfg:
with pytest.raises(ConfigError): with pytest.raises(ConfigError):
conf2 = await Config(od1, session_id='conf2') conf2 = await Config(od1, session_id='conf2')
await delete_session('conf2')
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -370,8 +387,9 @@ async def test_config_invalidsession():
i = IntOption('i', '') i = IntOption('i', '')
o = OptionDescription('val', '', [i]) o = OptionDescription('val', '', [i])
o2 = OptionDescription('val', '', [o]) o2 = OptionDescription('val', '', [o])
with pytest.raises(ValueError): with pytest.raises(ValueError):
await Config(o2, session_id=2) await Config(o2, session_id=2)
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -380,11 +398,12 @@ async def test_config_od_name(config_type):
s = SymLinkOption('s', i) s = SymLinkOption('s', i)
o = OptionDescription('val', '', [i, s]) o = OptionDescription('val', '', [i, s])
o2 = OptionDescription('val', '', [o]) o2 = OptionDescription('val', '', [o])
cfg = await Config(o2) async with await Config(o2) as cfg:
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
assert await cfg.option('val.i').option.name() == 'i' 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() == 's'
assert await cfg.option('val.s').option.name(follow_symlink=True) == 'i' assert await cfg.option('val.s').option.name(follow_symlink=True) == 'i'
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -392,9 +411,10 @@ async def test_config_od_type(config_type):
i = IntOption('i', '') i = IntOption('i', '')
o = OptionDescription('val', '', [i]) o = OptionDescription('val', '', [i])
o2 = OptionDescription('val', '', [o]) o2 = OptionDescription('val', '', [o])
cfg = await Config(o2) async with await Config(o2) as cfg:
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
assert await cfg.option('val.i').option.type() == 'integer' assert await cfg.option('val.i').option.type() == 'integer'
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -402,9 +422,10 @@ async def test_config_default(config_type):
i = IntOption('i', '', 8) i = IntOption('i', '', 8)
o = OptionDescription('val', '', [i]) o = OptionDescription('val', '', [i])
o2 = OptionDescription('val', '', [o]) o2 = OptionDescription('val', '', [o])
cfg = await Config(o2) async with await Config(o2) as cfg:
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
assert await cfg.option('val.i').value.default() == 8 assert await cfg.option('val.i').value.default() == 8
await cfg.option('val.i').value.set(9) await cfg.option('val.i').value.set(9)
assert await cfg.option('val.i').value.get() == 9 assert await cfg.option('val.i').value.get() == 9
assert await cfg.option('val.i').value.default() == 8 assert await cfg.option('val.i').value.default() == 8
assert not await list_sessions()

View file

@ -3,7 +3,7 @@ import pytest
from .autopath import do_autopath from .autopath import do_autopath
do_autopath() do_autopath()
from .config import config_type, get_config, value_list, global_owner from .config import config_type, get_config, value_list, global_owner, event_loop
from tiramisu import Config, IntOption, FloatOption, StrOption, ChoiceOption, \ from tiramisu import Config, IntOption, FloatOption, StrOption, ChoiceOption, \
BoolOption, FilenameOption, SymLinkOption, IPOption, \ BoolOption, FilenameOption, SymLinkOption, IPOption, \
@ -14,10 +14,10 @@ from tiramisu.storage import list_sessions
import warnings import warnings
def teardown_function(function): #def teardown_function(function):
# test_od_not_list emit a warnings because of doesn't create a Config # # test_od_not_list emit a warnings because of doesn't create a Config
with warnings.catch_warnings(record=True) as w: # with warnings.catch_warnings(record=True) as w:
assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__) # assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__)
def make_description(): def make_description():
@ -55,15 +55,17 @@ def _is_same_opt(opt1, opt2):
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_od_not_list(): async def test_od_not_list():
b = BoolOption('bool', '', multi=True) b = BoolOption('bool', '', multi=True)
with pytest.raises(AssertionError): with pytest.raises(AssertionError):
OptionDescription('od', '', b) OptionDescription('od', '', b)
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_str(): async def test_str():
descr = make_description() descr = make_description()
c = await Config(descr) async with await Config(descr) as cfg:
c # does not crash cfg # does not crash
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -74,20 +76,21 @@ async def test_make_dict(config_type):
BoolOption("a", "", default=False), BoolOption("a", "", default=False),
BoolOption("b", "", default=False, properties=('hidden',))]), BoolOption("b", "", default=False, properties=('hidden',))]),
IntOption("int", "", default=42)]) IntOption("int", "", default=42)])
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
await cfg.permissive.add('hidden') await cfg.permissive.add('hidden')
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
d = await cfg.value.dict() d = await cfg.value.dict()
assert d == {"s1.a": False, "int": 42} assert d == {"s1.a": False, "int": 42}
await cfg.option('int').value.set(43) await cfg.option('int').value.set(43)
await cfg.option('s1.a').value.set(True) await cfg.option('s1.a').value.set(True)
d = await cfg.value.dict() d = await cfg.value.dict()
assert d == {"s1.a": True, "int": 43} assert d == {"s1.a": True, "int": 43}
d2 = await cfg.value.dict(flatten=True) d2 = await cfg.value.dict(flatten=True)
assert d2 == {'a': True, 'int': 43} assert d2 == {'a': True, 'int': 43}
if config_type == 'tiramisu': if config_type == 'tiramisu':
assert await cfg.forcepermissive.value.dict() == {"s1.a": True, "s1.b": False, "int": 43} assert await cfg.forcepermissive.value.dict() == {"s1.a": True, "s1.b": False, "int": 43}
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -100,13 +103,14 @@ async def test_make_dict_with_disabled(config_type):
BoolOption("a", "", default=False), BoolOption("a", "", default=False),
BoolOption("b", "", default=False)], properties=('disabled',)), BoolOption("b", "", default=False)], properties=('disabled',)),
IntOption("int", "", default=42)]) IntOption("int", "", default=42)])
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_only() await cfg.property.read_only()
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
assert await cfg.value.dict() == {"s1.a": False, "int": 42} assert await cfg.value.dict() == {"s1.a": False, "int": 42}
if config_type == 'tiramisu': if config_type == 'tiramisu':
assert await cfg.forcepermissive.value.dict() == {"s1.a": False, "int": 42} assert await cfg.forcepermissive.value.dict() == {"s1.a": False, "int": 42}
assert await cfg.unrestraint.value.dict() == {"int": 42, "s1.a": False, "s1.b": False, "s2.a": False, "s2.b": False} assert await cfg.unrestraint.value.dict() == {"int": 42, "s1.a": False, "s1.b": False, "s2.a": False, "s2.b": False}
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -119,11 +123,12 @@ async def test_make_dict_with_disabled_in_callback(config_type):
BoolOption("a", "", default=False), BoolOption("a", "", default=False),
BoolOption("b", "", default=False)], properties=('disabled',)), BoolOption("b", "", default=False)], properties=('disabled',)),
IntOption("int", "", default=42)]) IntOption("int", "", default=42)])
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_only() await cfg.property.read_only()
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
d = await cfg.value.dict() d = await cfg.value.dict()
assert d == {"s1.a": False, "int": 42} assert d == {"s1.a": False, "int": 42}
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -138,282 +143,288 @@ async def test_make_dict_fullpath(config_type):
BoolOption("b", "", default=False)], properties=('disabled',)), BoolOption("b", "", default=False)], properties=('disabled',)),
IntOption("int", "", default=42)]), IntOption("int", "", default=42)]),
IntOption("introot", "", default=42)]) IntOption("introot", "", default=42)])
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_only() await cfg.property.read_only()
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
assert await cfg.value.dict() == {"opt.s1.a": False, "opt.int": 42, "introot": 42} assert await cfg.value.dict() == {"opt.s1.a": False, "opt.int": 42, "introot": 42}
if config_type == 'tiramisu': if config_type == 'tiramisu':
# FIXME # FIXME
assert await cfg.option('opt').value.dict() == {"s1.a": False, "int": 42} assert await cfg.option('opt').value.dict() == {"s1.a": False, "int": 42}
assert await cfg.value.dict(fullpath=True) == {"opt.s1.a": False, "opt.int": 42, "introot": 42} assert await cfg.value.dict(fullpath=True) == {"opt.s1.a": False, "opt.int": 42, "introot": 42}
if config_type == 'tiramisu': if config_type == 'tiramisu':
# FIXME # FIXME
assert await cfg.option('opt').value.dict(fullpath=True) == {"opt.s1.a": False, "opt.int": 42} assert await cfg.option('opt').value.dict(fullpath=True) == {"opt.s1.a": False, "opt.int": 42}
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_find_in_config(): async def test_find_in_config():
"finds option in config" "finds option in config"
descr = make_description() descr = make_description()
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_only() await cfg.property.read_only()
await cfg.permissive.add('hidden') await cfg.permissive.add('hidden')
ret = list(await cfg.option.find('dummy')) ret = list(await cfg.option.find('dummy'))
assert len(ret) == 1 assert len(ret) == 1
_is_same_opt(await ret[0].option.get(), await cfg.option('gc.dummy').option.get()) _is_same_opt(await ret[0].option.get(), await cfg.option('gc.dummy').option.get())
# #
ret_find = await cfg.option.find('dummy', first=True) ret_find = await cfg.option.find('dummy', first=True)
ret = await ret_find.option.get() ret = await ret_find.option.get()
_is_same_opt(ret, await cfg.option('gc.dummy').option.get()) _is_same_opt(ret, await cfg.option('gc.dummy').option.get())
# #
ret = list(await cfg.option.find('float')) ret = list(await cfg.option.find('float'))
assert len(ret) == 2 assert len(ret) == 2
_is_same_opt(await ret[0].option.get(), await cfg.option('gc.float').option.get()) _is_same_opt(await ret[0].option.get(), await cfg.option('gc.float').option.get())
_is_same_opt(await ret[1].option.get(), await cfg.option('float').option.get()) _is_same_opt(await ret[1].option.get(), await cfg.option('float').option.get())
# #
ret = await cfg.option.find('bool', first=True) ret = await cfg.option.find('bool', first=True)
_is_same_opt(await ret.option.get(), await cfg.option('gc.gc2.bool').option.get()) _is_same_opt(await ret.option.get(), await cfg.option('gc.gc2.bool').option.get())
ret = await cfg.option.find('bool', value=True, first=True) ret = await cfg.option.find('bool', value=True, first=True)
_is_same_opt(await ret.option.get(), await cfg.option('bool').option.get()) _is_same_opt(await ret.option.get(), await cfg.option('bool').option.get())
ret = await cfg.option.find('dummy', first=True) ret = await cfg.option.find('dummy', first=True)
_is_same_opt(await ret.option.get(), await cfg.option('gc.dummy').option.get()) _is_same_opt(await ret.option.get(), await cfg.option('gc.dummy').option.get())
ret = await cfg.option.find('float', first=True) ret = await cfg.option.find('float', first=True)
_is_same_opt(await ret.option.get(), await cfg.option('gc.float').option.get()) _is_same_opt(await ret.option.get(), await cfg.option('gc.float').option.get())
#FIXME cannot find an option without name #FIXME cannot find an option without name
#ret = await cfg.find(bytype=ChoiceOption) #ret = await cfg.find(bytype=ChoiceOption)
#assert len(ret) == 2 #assert len(ret) == 2
#_is_same_opt(ret[0], await cfg.unwrap_from_path('gc.name')) #_is_same_opt(ret[0], await cfg.unwrap_from_path('gc.name'))
#_is_same_opt(ret[1], await cfg.unwrap_from_path('objspace')) #_is_same_opt(ret[1], await cfg.unwrap_from_path('objspace'))
# #
#_is_same_opt(await cfg.find_first(bytype=ChoiceOption), await cfg.unwrap_from_path('gc.name')) #_is_same_opt(await cfg.find_first(bytype=ChoiceOption), await cfg.unwrap_from_path('gc.name'))
#ret = await cfg.find(byvalue='ref') #ret = await cfg.find(byvalue='ref')
#assert len(ret) == 1 #assert len(ret) == 1
#_is_same_opt(ret[0], await cfg.unwrap_from_path('gc.name')) #_is_same_opt(ret[0], await cfg.unwrap_from_path('gc.name'))
#_is_same_opt(await cfg.find_first(byvalue='ref'), await cfg.unwrap_from_path('gc.name')) #_is_same_opt(await cfg.find_first(byvalue='ref'), await cfg.unwrap_from_path('gc.name'))
# #
ret = list(await cfg.option.find('prop')) ret = list(await cfg.option.find('prop'))
assert len(ret) == 1 assert len(ret) == 1
_is_same_opt(await ret[0].option.get(), await cfg.option('gc.prop').option.get()) _is_same_opt(await ret[0].option.get(), await cfg.option('gc.prop').option.get())
# #
ret = list(await cfg.option.find('prop', value=None)) ret = list(await cfg.option.find('prop', value=None))
assert len(ret) == 1 assert len(ret) == 1
ret = list(await cfg.option.find('prop')) ret = list(await cfg.option.find('prop'))
assert len(ret) == 1 assert len(ret) == 1
_is_same_opt(await ret[0].option.get(), await cfg.option('gc.prop').option.get()) _is_same_opt(await ret[0].option.get(), await cfg.option('gc.prop').option.get())
# #
await cfg.property.read_write() await cfg.property.read_write()
with pytest.raises(AttributeError): with pytest.raises(AttributeError):
ret = await cfg.option.find('prop') ret = await cfg.option.find('prop')
assert await ret.option.get() assert await ret.option.get()
ret = list(await cfg.unrestraint.option.find(name='prop')) ret = list(await cfg.unrestraint.option.find(name='prop'))
assert len(ret) == 2 assert len(ret) == 2
_is_same_opt(await ret[0].option.get(), await cfg.unrestraint.option('gc.gc2.prop').option.get()) _is_same_opt(await ret[0].option.get(), await cfg.unrestraint.option('gc.gc2.prop').option.get())
_is_same_opt(await ret[1].option.get(), await cfg.forcepermissive.option('gc.prop').option.get()) _is_same_opt(await ret[1].option.get(), await cfg.forcepermissive.option('gc.prop').option.get())
# #
ret = list(await cfg.forcepermissive.option.find('prop')) ret = list(await cfg.forcepermissive.option.find('prop'))
assert len(ret) == 1 assert len(ret) == 1
_is_same_opt(await ret[0].option.get(), await cfg.forcepermissive.option('gc.prop').option.get()) _is_same_opt(await ret[0].option.get(), await cfg.forcepermissive.option('gc.prop').option.get())
# #
ret = await cfg.forcepermissive.option.find('prop', first=True) ret = await cfg.forcepermissive.option.find('prop', first=True)
_is_same_opt(await ret.option.get(), await cfg.forcepermissive.option('gc.prop').option.get()) _is_same_opt(await ret.option.get(), await cfg.forcepermissive.option('gc.prop').option.get())
# combinaison of filters # combinaison of filters
ret = list(await cfg.unrestraint.option.find('prop', type=BoolOption)) ret = list(await cfg.unrestraint.option.find('prop', type=BoolOption))
assert len(ret) == 1 assert len(ret) == 1
_is_same_opt(await ret[0].option.get(), await cfg.unrestraint.option('gc.gc2.prop').option.get()) _is_same_opt(await ret[0].option.get(), await cfg.unrestraint.option('gc.gc2.prop').option.get())
ret = await cfg.unrestraint.option.find('prop', type=BoolOption, first=True) ret = await cfg.unrestraint.option.find('prop', type=BoolOption, first=True)
_is_same_opt(await ret.option.get(), await cfg.unrestraint.option('gc.gc2.prop').option.get()) _is_same_opt(await ret.option.get(), await cfg.unrestraint.option('gc.gc2.prop').option.get())
# #
ret = list(await cfg.option.find('dummy', value=False)) ret = list(await cfg.option.find('dummy', value=False))
assert len(ret) == 1 assert len(ret) == 1
_is_same_opt(await ret[0].option.get(), await cfg.option('gc.dummy').option.get()) _is_same_opt(await ret[0].option.get(), await cfg.option('gc.dummy').option.get())
# #
ret = await cfg.option.find('dummy', value=False, first=True) ret = await cfg.option.find('dummy', value=False, first=True)
_is_same_opt(await ret.option.get(), await cfg.option('gc.dummy').option.get()) _is_same_opt(await ret.option.get(), await cfg.option('gc.dummy').option.get())
#subcfgig #subcfgig
ret = list(await cfg.option('gc').find('dummy')) ret = list(await cfg.option('gc').find('dummy'))
assert len(ret) == 1 assert len(ret) == 1
_is_same_opt(await ret[0].option.get(), await cfg.option('gc.dummy').option.get()) _is_same_opt(await ret[0].option.get(), await cfg.option('gc.dummy').option.get())
# #
ret = list(await cfg.option('gc').find('float')) ret = list(await cfg.option('gc').find('float'))
assert len(ret) == 1 assert len(ret) == 1
_is_same_opt(await ret[0].option.get(), await cfg.option('gc.float').option.get()) _is_same_opt(await ret[0].option.get(), await cfg.option('gc.float').option.get())
# #
ret = list(await cfg.option('gc').find('bool')) ret = list(await cfg.option('gc').find('bool'))
assert len(ret) == 1 assert len(ret) == 1
_is_same_opt(await ret[0].option.get(), await cfg.option('gc.gc2.bool').option.get()) _is_same_opt(await ret[0].option.get(), await cfg.option('gc.gc2.bool').option.get())
ret = await cfg.option('gc').find('bool', value=False, first=True) ret = await cfg.option('gc').find('bool', value=False, first=True)
_is_same_opt(await ret.option.get(), await cfg.option('gc.gc2.bool').option.get()) _is_same_opt(await ret.option.get(), await cfg.option('gc.gc2.bool').option.get())
# #
with pytest.raises(AttributeError): with pytest.raises(AttributeError):
ret = await cfg.option('gc').find('bool', value=True, first=True) ret = await cfg.option('gc').find('bool', value=True, first=True)
assert await ret.option.get() assert await ret.option.get()
# #
with pytest.raises(AttributeError): with pytest.raises(AttributeError):
ret = await cfg.option('gc').find('wantref') ret = await cfg.option('gc').find('wantref')
await ret.option.get() await ret.option.get()
# #
ret = list(await cfg.unrestraint.option('gc').find('prop')) ret = list(await cfg.unrestraint.option('gc').find('prop'))
assert len(ret) == 2 assert len(ret) == 2
_is_same_opt(await ret[0].option.get(), await cfg.unrestraint.option('gc.gc2.prop').option.get()) _is_same_opt(await ret[0].option.get(), await cfg.unrestraint.option('gc.gc2.prop').option.get())
_is_same_opt(await ret[1].option.get(), await cfg.forcepermissive.option('gc.prop').option.get()) _is_same_opt(await ret[1].option.get(), await cfg.forcepermissive.option('gc.prop').option.get())
# #
await cfg.property.read_only() await cfg.property.read_only()
ret = list(await cfg.option('gc').find('prop')) ret = list(await cfg.option('gc').find('prop'))
assert len(ret) == 1 assert len(ret) == 1
_is_same_opt(await ret[0].option.get(), await cfg.option('gc.prop').option.get()) _is_same_opt(await ret[0].option.get(), await cfg.option('gc.prop').option.get())
# not OptionDescription # not OptionDescription
with pytest.raises(AttributeError): with pytest.raises(AttributeError):
await cfg.option.find('gc', first=True) await cfg.option.find('gc', first=True)
with pytest.raises(AttributeError): with pytest.raises(AttributeError):
await cfg.option.find('gc2', first=True) await cfg.option.find('gc2', first=True)
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_find_multi(): async def test_find_multi():
b = BoolOption('bool', '', multi=True, properties=('notunique',)) b = BoolOption('bool', '', multi=True, properties=('notunique',))
o = OptionDescription('od', '', [b]) o = OptionDescription('od', '', [b])
cfg = await Config(o) async with await Config(o) as cfg:
# #
with pytest.raises(AttributeError): with pytest.raises(AttributeError):
list(await cfg.option.find('bool', value=True)) list(await cfg.option.find('bool', value=True))
with pytest.raises(AttributeError): with pytest.raises(AttributeError):
list(await cfg.option.find('bool', value=True, first=True)) list(await cfg.option.find('bool', value=True, first=True))
await cfg.option('bool').value.set([False]) await cfg.option('bool').value.set([False])
with pytest.raises(AttributeError): with pytest.raises(AttributeError):
list(await cfg.option.find('bool', value=True)) list(await cfg.option.find('bool', value=True))
with pytest.raises(AttributeError): with pytest.raises(AttributeError):
list(await cfg.option.find('bool', value=True, first=True)) list(await cfg.option.find('bool', value=True, first=True))
await cfg.option('bool').value.set([False, False]) await cfg.option('bool').value.set([False, False])
with pytest.raises(AttributeError): with pytest.raises(AttributeError):
list(await cfg.option.find('bool', value=True)) list(await cfg.option.find('bool', value=True))
with pytest.raises(AttributeError): with pytest.raises(AttributeError):
list(await cfg.option.find('bool', value=True, first=True)) list(await cfg.option.find('bool', value=True, first=True))
await cfg.option('bool').value.set([False, False, True]) await cfg.option('bool').value.set([False, False, True])
ret = list(await cfg.option.find('bool', value=True)) ret = list(await cfg.option.find('bool', value=True))
assert len(ret) == 1 assert len(ret) == 1
_is_same_opt(await ret[0].option.get(), b) _is_same_opt(await ret[0].option.get(), b)
ret = await cfg.option.find('bool', value=True, first=True) ret = await cfg.option.find('bool', value=True, first=True)
_is_same_opt(await ret.option.get(), b) _is_same_opt(await ret.option.get(), b)
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_does_not_find_in_config(): async def test_does_not_find_in_config():
descr = make_description() descr = make_description()
cfg = await Config(descr) async with await Config(descr) as cfg:
with pytest.raises(AttributeError): with pytest.raises(AttributeError):
list(await cfg.option.find('IDontExist')) list(await cfg.option.find('IDontExist'))
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_filename(config_type): async def test_filename(config_type):
a = FilenameOption('a', '') a = FilenameOption('a', '')
o = OptionDescription('o', '', [a]) o = OptionDescription('o', '', [a])
cfg = await Config(o) async with await Config(o) as cfg:
# FIXME cfg = await get_config(cfg, config_type) # FIXME cfg = await get_config(cfg, config_type)
await cfg.option('a').value.set('/') await cfg.option('a').value.set('/')
await cfg.option('a').value.set('/tmp') await cfg.option('a').value.set('/tmp')
await cfg.option('a').value.set('/tmp/') await cfg.option('a').value.set('/tmp/')
await cfg.option('a').value.set('/tmp/text.txt') await cfg.option('a').value.set('/tmp/text.txt')
await cfg.option('a').value.set('tmp') await cfg.option('a').value.set('tmp')
await cfg.option('a').value.set('tmp/') await cfg.option('a').value.set('tmp/')
await cfg.option('a').value.set('tmp/text.txt') await cfg.option('a').value.set('tmp/text.txt')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('a').value.set('/tmp/with space.txt') await cfg.option('a').value.set('/tmp/with space.txt')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('a').value.set('/tmp/with$.txt') await cfg.option('a').value.set('/tmp/with$.txt')
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_invalid_option(): async def test_invalid_option():
ChoiceOption('a', '', ('1', '2')) ChoiceOption('a', '', ('1', '2'))
with pytest.raises(TypeError): with pytest.raises(TypeError):
ChoiceOption('a', '', [1, 2]) ChoiceOption('a', '', [1, 2])
with pytest.raises(TypeError): with pytest.raises(TypeError):
ChoiceOption('a', '', 1) ChoiceOption('a', '', 1)
with pytest.raises(ValueError): with pytest.raises(ValueError):
ChoiceOption('a', '', (1,), 3) ChoiceOption('a', '', (1,), 3)
FloatOption('a', '') FloatOption('a', '')
with pytest.raises(ValueError): with pytest.raises(ValueError):
FloatOption('a', '', 'string') FloatOption('a', '', 'string')
StrOption('a', '') StrOption('a', '')
with pytest.raises(ValueError): with pytest.raises(ValueError):
StrOption('a', '', 1) StrOption('a', '', 1)
u = StrOption('a', '') u = StrOption('a', '')
SymLinkOption('a', u) SymLinkOption('a', u)
with pytest.raises(ValueError): with pytest.raises(ValueError):
SymLinkOption('a', 'string') SymLinkOption('a', 'string')
IPOption('a', '') IPOption('a', '')
with pytest.raises(ValueError): with pytest.raises(ValueError):
IPOption('a', '', 1) IPOption('a', '', 1)
with pytest.raises(ValueError): with pytest.raises(ValueError):
IPOption('a', '', 'string') IPOption('a', '', 'string')
PortOption('a', '') PortOption('a', '')
with pytest.raises(ValueError): with pytest.raises(ValueError):
PortOption('a', '', 'string') PortOption('a', '', 'string')
with pytest.raises(ValueError): with pytest.raises(ValueError):
PortOption('a', '', '11:12:13', allow_range=True) PortOption('a', '', '11:12:13', allow_range=True)
with pytest.raises(ValueError): with pytest.raises(ValueError):
PortOption('a', '', 11111111111111111111) PortOption('a', '', 11111111111111111111)
with pytest.raises(ValueError): with pytest.raises(ValueError):
PortOption('a', '', allow_zero=True, allow_wellknown=False, allow_registred=True, allow_private=False) PortOption('a', '', allow_zero=True, allow_wellknown=False, allow_registred=True, allow_private=False)
with pytest.raises(ValueError): with pytest.raises(ValueError):
PortOption('a', '', allow_zero=True, allow_wellknown=True, allow_registred=False, allow_private=True) PortOption('a', '', allow_zero=True, allow_wellknown=True, allow_registred=False, allow_private=True)
with pytest.raises(ValueError): with pytest.raises(ValueError):
PortOption('a', '', allow_zero=True, allow_wellknown=False, allow_registred=False, allow_private=True) PortOption('a', '', allow_zero=True, allow_wellknown=False, allow_registred=False, allow_private=True)
with pytest.raises(ValueError): with pytest.raises(ValueError):
PortOption('a', '', allow_zero=True, allow_wellknown=False, allow_registred=True, allow_private=True) PortOption('a', '', allow_zero=True, allow_wellknown=False, allow_registred=True, allow_private=True)
with pytest.raises(ValueError): with pytest.raises(ValueError):
PortOption('a', '', allow_zero=False, allow_wellknown=False, allow_registred=False, allow_private=False) PortOption('a', '', allow_zero=False, allow_wellknown=False, allow_registred=False, allow_private=False)
NetworkOption('a', '') NetworkOption('a', '')
with pytest.raises(ValueError): with pytest.raises(ValueError):
NetworkOption('a', '', 'string') NetworkOption('a', '', 'string')
NetmaskOption('a', '') NetmaskOption('a', '')
with pytest.raises(ValueError): with pytest.raises(ValueError):
NetmaskOption('a', '', 'string') NetmaskOption('a', '', 'string')
BroadcastOption('a', '') BroadcastOption('a', '')
with pytest.raises(ValueError): with pytest.raises(ValueError):
BroadcastOption('a', '', 'string') BroadcastOption('a', '', 'string')
DomainnameOption('a', '') DomainnameOption('a', '')
with pytest.raises(ValueError): with pytest.raises(ValueError):
DomainnameOption('a', '', 'string') DomainnameOption('a', '', 'string')
with pytest.raises(ValueError): with pytest.raises(ValueError):
DomainnameOption('a', '', type='string') DomainnameOption('a', '', type='string')
with pytest.raises(ValueError): with pytest.raises(ValueError):
DomainnameOption('a', '', allow_ip='string') DomainnameOption('a', '', allow_ip='string')
with pytest.raises(ValueError): with pytest.raises(ValueError):
DomainnameOption('a', '', allow_without_dot='string') DomainnameOption('a', '', allow_without_dot='string')
with pytest.raises(ValueError): with pytest.raises(ValueError):
DomainnameOption('a', '', 1) DomainnameOption('a', '', 1)
# #
ChoiceOption('a', '', (1,), multi=True, default_multi=1) ChoiceOption('a', '', (1,), multi=True, default_multi=1)
with pytest.raises(ValueError): with pytest.raises(ValueError):
ChoiceOption('a', '', (1,), default_multi=1) ChoiceOption('a', '', (1,), default_multi=1)
with pytest.raises(ValueError): with pytest.raises(ValueError):
ChoiceOption('a', '', (1,), multi=True, default=[1,], default_multi=2) ChoiceOption('a', '', (1,), multi=True, default=[1,], default_multi=2)
with pytest.raises(ValueError): with pytest.raises(ValueError):
FloatOption('a', '', multi=True, default_multi='string') FloatOption('a', '', multi=True, default_multi='string')
with pytest.raises(ValueError): with pytest.raises(ValueError):
StrOption('a', '', multi=True, default_multi=1) StrOption('a', '', multi=True, default_multi=1)
with pytest.raises(ValueError): with pytest.raises(ValueError):
IPOption('a', '', multi=True, default_multi=1) IPOption('a', '', multi=True, default_multi=1)
with pytest.raises(ValueError): with pytest.raises(ValueError):
IPOption('a', '', multi=True, default_multi='string') IPOption('a', '', multi=True, default_multi='string')
with pytest.raises(ValueError): with pytest.raises(ValueError):
PortOption('a', '', multi=True, default_multi='string') PortOption('a', '', multi=True, default_multi='string')
with pytest.raises(ValueError): with pytest.raises(ValueError):
PortOption('a', '', multi=True, default_multi='11:12:13', allow_range=True) PortOption('a', '', multi=True, default_multi='11:12:13', allow_range=True)
with pytest.raises(ValueError): with pytest.raises(ValueError):
PortOption('a', '', multi=True, default_multi=11111111111111111111) PortOption('a', '', multi=True, default_multi=11111111111111111111)
with pytest.raises(ValueError): with pytest.raises(ValueError):
NetworkOption('a', '', multi=True, default_multi='string') NetworkOption('a', '', multi=True, default_multi='string')
with pytest.raises(ValueError): with pytest.raises(ValueError):
NetmaskOption('a', '', multi=True, default_multi='string') NetmaskOption('a', '', multi=True, default_multi='string')
with pytest.raises(ValueError): with pytest.raises(ValueError):
BroadcastOption('a', '', multi=True, default_multi='string') BroadcastOption('a', '', multi=True, default_multi='string')
with pytest.raises(ValueError): with pytest.raises(ValueError):
DomainnameOption('a', '', multi=True, default_multi='string') DomainnameOption('a', '', multi=True, default_multi='string')
with pytest.raises(ValueError): with pytest.raises(ValueError):
DomainnameOption('a', '', multi=True, default_multi=1) DomainnameOption('a', '', multi=True, default_multi=1)
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -421,38 +432,40 @@ async def test_help():
stro = StrOption('s', '', multi=True) stro = StrOption('s', '', multi=True)
od1 = OptionDescription('o', '', [stro]) od1 = OptionDescription('o', '', [stro])
od2 = OptionDescription('o', '', [od1]) od2 = OptionDescription('o', '', [od1])
cfg = await Config(od2) async with await Config(od2) as cfg:
cfg.help(_display=False) cfg.help(_display=False)
cfg.config.help(_display=False) cfg.config.help(_display=False)
cfg.option.help(_display=False) cfg.option.help(_display=False)
cfg.option('o').help(_display=False) cfg.option('o').help(_display=False)
cfg.option('o.s').help(_display=False) cfg.option('o.s').help(_display=False)
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_config_reset(): async def test_config_reset():
descr = make_description() descr = make_description()
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.owner.set('test') await cfg.owner.set('test')
assert await cfg.owner.get() == 'test' assert await cfg.owner.get() == 'test'
assert not await cfg.option('gc.gc2.bool').value.get() assert not await cfg.option('gc.gc2.bool').value.get()
assert not await cfg.option('boolop').property.get() assert not await cfg.option('boolop').property.get()
assert not await cfg.option('boolop').permissive.get() assert not await cfg.option('boolop').permissive.get()
assert not await cfg.option('wantref').information.get('info', None) assert not await cfg.option('wantref').information.get('info', None)
# #
await cfg.option('gc.gc2.bool').value.set(True) await cfg.option('gc.gc2.bool').value.set(True)
await cfg.option('boolop').property.add('test') await cfg.option('boolop').property.add('test')
await cfg.option('float').permissive.set(frozenset(['test'])) await cfg.option('float').permissive.set(frozenset(['test']))
await cfg.option('wantref').information.set('info', 'info') await cfg.option('wantref').information.set('info', 'info')
assert await cfg.option('gc.gc2.bool').value.get() assert await cfg.option('gc.gc2.bool').value.get()
assert await cfg.option('boolop').property.get() assert await cfg.option('boolop').property.get()
assert await cfg.option('float').permissive.get() assert await cfg.option('float').permissive.get()
assert await cfg.option('wantref').information.get('info', None) assert await cfg.option('wantref').information.get('info', None)
# #
assert await cfg.owner.get() == 'test' assert await cfg.owner.get() == 'test'
await cfg.config.reset() await cfg.config.reset()
assert await cfg.owner.get() == 'test' assert await cfg.owner.get() == 'test'
assert not await cfg.option('gc.gc2.bool').value.get() assert not await cfg.option('gc.gc2.bool').value.get()
assert not await cfg.option('boolop').property.get() assert not await cfg.option('boolop').property.get()
assert not await cfg.option('float').permissive.get() assert not await cfg.option('float').permissive.get()
assert not await cfg.option('wantref').information.get('info', None) assert not await cfg.option('wantref').information.get('info', None)
assert not await list_sessions()

View file

@ -9,10 +9,7 @@ from tiramisu import Config, DomainnameOption, EmailOption, URLOption, OptionDes
from tiramisu.error import ValueWarning from tiramisu.error import ValueWarning
from tiramisu.i18n import _ from tiramisu.i18n import _
from tiramisu.storage import list_sessions from tiramisu.storage import list_sessions
from .config import event_loop
def teardown_function(function):
assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -22,86 +19,88 @@ async def test_domainname(config_type):
g = DomainnameOption('g', '', allow_ip=True) g = DomainnameOption('g', '', allow_ip=True)
h = DomainnameOption('h', '', allow_cidr_network=True) h = DomainnameOption('h', '', allow_cidr_network=True)
od = OptionDescription('a', '', [d, f, g, h]) od = OptionDescription('a', '', [d, f, g, h])
cfg = await Config(od) async with await Config(od) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
# #
await cfg.option('d').value.set('toto.com') await cfg.option('d').value.set('toto.com')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('d').value.set('toto') await cfg.option('d').value.set('toto')
await cfg.option('d').value.set('toto3.com') await cfg.option('d').value.set('toto3.com')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('d').value.set('toto_super.com') await cfg.option('d').value.set('toto_super.com')
await cfg.option('d').value.set('toto-.com') await cfg.option('d').value.set('toto-.com')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('d').value.set('toto..com') await cfg.option('d').value.set('toto..com')
# #
await cfg.option('f').value.set('toto.com') await cfg.option('f').value.set('toto.com')
await cfg.option('f').value.set('toto') await cfg.option('f').value.set('toto')
await cfg.option('f').value.set('domainnametoolongthathavemorethanmaximumsizeforatruedomainnamea') await cfg.option('f').value.set('domainnametoolongthathavemorethanmaximumsizeforatruedomainnamea')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('f').value.set('domainnametoolongthathavemorethanmaximumsizeforatruedomainnamean') await cfg.option('f').value.set('domainnametoolongthathavemorethanmaximumsizeforatruedomainnamean')
await cfg.option('f').value.set('domainnametoolongthathavemorethanmaximumsizeforatruedomainnamea.nd') await cfg.option('f').value.set('domainnametoolongthathavemorethanmaximumsizeforatruedomainnamea.nd')
await cfg.option('f').value.set('domainnametoolongthathavemorethanmaximumsizeforatruedomainnamea.nditsnoteasytogeneratesolongdomainnamewithoutrepeatdomainnameto.olongthathavemorethanmaximumsizeforatruedomainnameanditsnoteas.ytogeneratesolongdomainnamewithoutrepeatbutimnotabletodoitnowie') await cfg.option('f').value.set('domainnametoolongthathavemorethanmaximumsizeforatruedomainnamea.nditsnoteasytogeneratesolongdomainnamewithoutrepeatdomainnameto.olongthathavemorethanmaximumsizeforatruedomainnameanditsnoteas.ytogeneratesolongdomainnamewithoutrepeatbutimnotabletodoitnowie')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('d').value.set('domainnametoolongthathavemorethanmaximumsizeforatruedomainnamea.nditsnoteasytogeneratesolongdomainnamewithoutrepeatdomainnameto.olongthathavemorethanmaximumsizeforatruedomainnameanditsnoteas.ytogeneratesolongdomainnamewithoutrepeatbutimnotabletodoitnowien') await cfg.option('d').value.set('domainnametoolongthathavemorethanmaximumsizeforatruedomainnamea.nditsnoteasytogeneratesolongdomainnamewithoutrepeatdomainnameto.olongthathavemorethanmaximumsizeforatruedomainnameanditsnoteas.ytogeneratesolongdomainnamewithoutrepeatbutimnotabletodoitnowien')
await cfg.option('f').value.set('d') await cfg.option('f').value.set('d')
await cfg.option('f').value.set('d.t') await cfg.option('f').value.set('d.t')
# #
if config_type != 'tiramisu-api': if config_type != 'tiramisu-api':
# FIXME # FIXME
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('f').value.set('192.168.1.1') await cfg.option('f').value.set('192.168.1.1')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('f').value.set('192.168.1.0/24') await cfg.option('f').value.set('192.168.1.0/24')
# #
await cfg.option('g').value.set('toto.com') await cfg.option('g').value.set('toto.com')
await cfg.option('g').value.set('192.168.1.0') await cfg.option('g').value.set('192.168.1.0')
await cfg.option('g').value.set('192.168.1.29') await cfg.option('g').value.set('192.168.1.29')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('g').value.set('192.168.1.0/24') await cfg.option('g').value.set('192.168.1.0/24')
# #
await cfg.option('h').value.set('toto.com') await cfg.option('h').value.set('toto.com')
if config_type != 'tiramisu-api': if config_type != 'tiramisu-api':
# FIXME # FIXME
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('h').value.set('192.168.1.0') await cfg.option('h').value.set('192.168.1.0')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('h').value.set('192.168.1.29') await cfg.option('h').value.set('192.168.1.29')
# it's a network address # it's a network address
await cfg.option('h').value.set('192.168.1.0/24') await cfg.option('h').value.set('192.168.1.0/24')
# but not here # but not here
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('h').value.set('192.168.1.1/24') await cfg.option('h').value.set('192.168.1.1/24')
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_domainname_upper(config_type): async def test_domainname_upper(config_type):
d = DomainnameOption('d', '') d = DomainnameOption('d', '')
od = OptionDescription('a', '', [d]) od = OptionDescription('a', '', [d])
cfg = await Config(od) async with await Config(od) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
await cfg.option('d').value.set('toto.com') await cfg.option('d').value.set('toto.com')
msg = _('some characters are uppercase') msg = _('some characters are uppercase')
has_error = False has_error = False
try: try:
await cfg.option('d').value.set('TOTO.COM') await cfg.option('d').value.set('TOTO.COM')
except ValueError as err: except ValueError as err:
if config_type != 'tiramisu-api': if config_type != 'tiramisu-api':
# FIXME # FIXME
assert msg in str(err) assert msg in str(err)
has_error = True has_error = True
assert has_error is True assert has_error is True
has_error = False has_error = False
try: try:
await cfg.option('d').value.set('toTo.com') await cfg.option('d').value.set('toTo.com')
except ValueError as err: except ValueError as err:
if config_type != 'tiramisu-api': if config_type != 'tiramisu-api':
# FIXME # FIXME
assert msg in str(err) assert msg in str(err)
has_error = True has_error = True
assert has_error is True assert has_error is True
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -111,45 +110,46 @@ async def test_domainname_warning(config_type):
g = DomainnameOption('g', '', allow_ip=True, warnings_only=True) g = DomainnameOption('g', '', allow_ip=True, warnings_only=True)
od = OptionDescription('a', '', [d, f, g]) od = OptionDescription('a', '', [d, f, g])
warnings.simplefilter("always", ValueWarning) warnings.simplefilter("always", ValueWarning)
cfg = await Config(od) async with await Config(od) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
await cfg.option('d').value.set('toto.com') await cfg.option('d').value.set('toto.com')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('d').value.set('toto') await cfg.option('d').value.set('toto')
await cfg.option('d').value.set('toto3.com') await cfg.option('d').value.set('toto3.com')
if config_type != 'tiramisu-api': if config_type != 'tiramisu-api':
# FIXME # FIXME
with warnings.catch_warnings(record=True) as w:
await cfg.option('d').value.set('toto_super.com')
assert len(w) == 1
with warnings.catch_warnings(record=True) as w: with warnings.catch_warnings(record=True) as w:
await cfg.option('d').value.set('toto_super.com') await cfg.option('d').value.set('toto-.com')
assert len(w) == 1 assert len(w) == 0
with warnings.catch_warnings(record=True) as w: with pytest.raises(ValueError):
await cfg.option('d').value.set('toto-.com') await cfg.option('d').value.set('toto..com')
assert len(w) == 0 #
with pytest.raises(ValueError): await cfg.option('f').value.set('toto.com')
await cfg.option('d').value.set('toto..com') await cfg.option('f').value.set('toto')
# await cfg.option('f').value.set('domainnametoolongthathavemorethanmaximumsizeforatruedomainnamea')
await cfg.option('f').value.set('toto.com') with pytest.raises(ValueError):
await cfg.option('f').value.set('toto') await cfg.option('f').value.set('domainnametoolongthathavemorethanmaximumsizeforatruedomainnamean')
await cfg.option('f').value.set('domainnametoolongthathavemorethanmaximumsizeforatruedomainnamea') await cfg.option('f').value.set('domainnametoolongthathavemorethanmaximumsizeforatruedomainnamea.nd')
with pytest.raises(ValueError): await cfg.option('f').value.set('domainnametoolongthathavemorethanmaximumsizeforatruedomainnamea.nditsnoteasytogeneratesolongdomainnamewithoutrepeatdomainnameto.olongthathavemorethanmaximumsizeforatruedomainnameanditsnoteas.ytogeneratesolongdomainnamewithoutrepeatbutimnotabletodoitnowie')
await cfg.option('f').value.set('domainnametoolongthathavemorethanmaximumsizeforatruedomainnamean') if config_type != 'tiramisu-api':
await cfg.option('f').value.set('domainnametoolongthathavemorethanmaximumsizeforatruedomainnamea.nd') # FIXME
await cfg.option('f').value.set('domainnametoolongthathavemorethanmaximumsizeforatruedomainnamea.nditsnoteasytogeneratesolongdomainnamewithoutrepeatdomainnameto.olongthathavemorethanmaximumsizeforatruedomainnameanditsnoteas.ytogeneratesolongdomainnamewithoutrepeatbutimnotabletodoitnowie') with pytest.raises(ValueError):
if config_type != 'tiramisu-api': await cfg.option('f').value.set('domainnametoolongthathavemorethanmaximumsizeforatruedomainname.nditsnoteasytogeneratesolongdomainnamewithoutrepeatdomainnamet.olongthathavemorethanmaximumsizeforatruedomainnameanditsnotea.ytogeneratesolongdomainnamewithoutrepeatbutimnotabletodoitnowie.xxxx')
# FIXME await cfg.option('f').value.set('d')
with pytest.raises(ValueError): await cfg.option('f').value.set('d.t')
await cfg.option('f').value.set('domainnametoolongthathavemorethanmaximumsizeforatruedomainname.nditsnoteasytogeneratesolongdomainnamewithoutrepeatdomainnamet.olongthathavemorethanmaximumsizeforatruedomainnameanditsnotea.ytogeneratesolongdomainnamewithoutrepeatbutimnotabletodoitnowie.xxxx') #
await cfg.option('f').value.set('d') if config_type != 'tiramisu-api':
await cfg.option('f').value.set('d.t') # FIXME
# with pytest.raises(ValueError):
if config_type != 'tiramisu-api': await cfg.option('f').value.set('192.168.1.1')
# FIXME await cfg.option('g').value.set('toto.com')
with pytest.raises(ValueError): await cfg.option('g').value.set('192.168.1.0')
await cfg.option('f').value.set('192.168.1.1') await cfg.option('g').value.set('192.168.1.29')
await cfg.option('g').value.set('toto.com') assert not await list_sessions()
await cfg.option('g').value.set('192.168.1.0')
await cfg.option('g').value.set('192.168.1.29')
@pytest.mark.asyncio @pytest.mark.asyncio
@ -159,13 +159,14 @@ async def test_special_domain_name(config_type):
d = DomainnameOption('d', '') d = DomainnameOption('d', '')
e = DomainnameOption('e', '', type='netbios') e = DomainnameOption('e', '', type='netbios')
od = OptionDescription('a', '', [d, e]) od = OptionDescription('a', '', [d, e])
cfg = await Config(od) async with await Config(od) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
await cfg.option('d').value.set('1toto.com') await cfg.option('d').value.set('1toto.com')
await cfg.option('d').value.set('123toto.com') await cfg.option('d').value.set('123toto.com')
await cfg.option('e').value.set('toto') await cfg.option('e').value.set('toto')
await cfg.option('e').value.set('1toto') await cfg.option('e').value.set('1toto')
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -173,14 +174,15 @@ async def test_domainname_netbios(config_type):
d = DomainnameOption('d', '', type='netbios') d = DomainnameOption('d', '', type='netbios')
e = DomainnameOption('e', '', "toto", type='netbios') e = DomainnameOption('e', '', "toto", type='netbios')
od = OptionDescription('a', '', [d, e]) od = OptionDescription('a', '', [d, e])
cfg = await Config(od) async with await Config(od) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('d').value.set('toto.com') await cfg.option('d').value.set('toto.com')
await cfg.option('d').value.set('toto') await cfg.option('d').value.set('toto')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('d').value.set('domainnametoolong') await cfg.option('d').value.set('domainnametoolong')
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -188,70 +190,73 @@ async def test_domainname_hostname(config_type):
d = DomainnameOption('d', '', type='hostname') d = DomainnameOption('d', '', type='hostname')
e = DomainnameOption('e', '', "toto", type='hostname') e = DomainnameOption('e', '', "toto", type='hostname')
od = OptionDescription('a', '', [d, e]) od = OptionDescription('a', '', [d, e])
cfg = await Config(od) async with await Config(od) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('d').value.set('toto.com') await cfg.option('d').value.set('toto.com')
await cfg.option('d').value.set('toto') await cfg.option('d').value.set('toto')
await cfg.option('d').value.set('domainnametoolong') await cfg.option('d').value.set('domainnametoolong')
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_email(config_type): async def test_email(config_type):
e = EmailOption('e', '') e = EmailOption('e', '')
od = OptionDescription('a', '', [e]) od = OptionDescription('a', '', [e])
cfg = await Config(od) async with await Config(od) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
await cfg.option('e').value.set('foo-bar.baz@example.com') await cfg.option('e').value.set('foo-bar.baz@example.com')
await cfg.option('e').value.set('root@foo.com') await cfg.option('e').value.set('root@foo.com')
await cfg.option('e').value.set('root@domain') await cfg.option('e').value.set('root@domain')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('e').value.set(1) await cfg.option('e').value.set(1)
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('e').value.set('root') await cfg.option('e').value.set('root')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('e').value.set('root[]@domain') await cfg.option('e').value.set('root[]@domain')
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_url(config_type): async def test_url(config_type):
u = URLOption('u', '') u = URLOption('u', '')
od = OptionDescription('a', '', [u]) od = OptionDescription('a', '', [u])
cfg = await Config(od) async with await Config(od) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
await cfg.option('u').value.set('http://foo.com') await cfg.option('u').value.set('http://foo.com')
await cfg.option('u').value.set('https://foo.com') await cfg.option('u').value.set('https://foo.com')
await cfg.option('u').value.set('https://foo.com/') await cfg.option('u').value.set('https://foo.com/')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('u').value.set(1) await cfg.option('u').value.set(1)
if config_type != 'tiramisu-api': if config_type != 'tiramisu-api':
# FIXME # FIXME
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('u').value.set('ftp://foo.com') await cfg.option('u').value.set('ftp://foo.com')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('u').value.set('foo.com') await cfg.option('u').value.set('foo.com')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('u').value.set(':/foo.com') await cfg.option('u').value.set(':/foo.com')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('u').value.set('foo.com/http://') await cfg.option('u').value.set('foo.com/http://')
await cfg.option('u').value.set('https://foo.com/index.html') await cfg.option('u').value.set('https://foo.com/index.html')
await cfg.option('u').value.set('https://foo.com/index.html?var=value&var2=val2') await cfg.option('u').value.set('https://foo.com/index.html?var=value&var2=val2')
if config_type != 'tiramisu-api': if config_type != 'tiramisu-api':
# FIXME # FIXME
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('u').value.set('https://foo.com/index\\n.html') await cfg.option('u').value.set('https://foo.com/index\\n.html')
await cfg.option('u').value.set('https://foo.com:8443') await cfg.option('u').value.set('https://foo.com:8443')
await cfg.option('u').value.set('https://foo.com:8443/') await cfg.option('u').value.set('https://foo.com:8443/')
await cfg.option('u').value.set('https://foo.com:8443/index.html') await cfg.option('u').value.set('https://foo.com:8443/index.html')
if config_type != 'tiramisu-api': if config_type != 'tiramisu-api':
# FIXME # FIXME
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('u').value.set('https://foo.com:84438989') await cfg.option('u').value.set('https://foo.com:84438989')
await cfg.option('u').value.set('https://foo.com:8443/INDEX') await cfg.option('u').value.set('https://foo.com:8443/INDEX')
if config_type != 'tiramisu-api': if config_type != 'tiramisu-api':
# FIXME # FIXME
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('u').value.set('https://FOO.COM:8443') await cfg.option('u').value.set('https://FOO.COM:8443')
assert not await list_sessions()

View file

@ -1,6 +1,6 @@
from .autopath import do_autopath from .autopath import do_autopath
do_autopath() do_autopath()
from .config import config_type, get_config, value_list, global_owner from .config import config_type, get_config, value_list, global_owner, event_loop
import warnings import warnings
import pytest import pytest
@ -10,10 +10,6 @@ from tiramisu.error import ValueWarning
from tiramisu.storage import list_sessions from tiramisu.storage import list_sessions
def teardown_function(function):
assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__)
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_ip(config_type): async def test_ip(config_type):
a = IPOption('a', '') a = IPOption('a', '')
@ -21,37 +17,38 @@ async def test_ip(config_type):
d = IPOption('d', '', warnings_only=True, private_only=True) d = IPOption('d', '', warnings_only=True, private_only=True)
warnings.simplefilter("always", ValueWarning) warnings.simplefilter("always", ValueWarning)
od = OptionDescription('od', '', [a, b, d]) od = OptionDescription('od', '', [a, b, d])
cfg = await Config(od) async with await Config(od) as cfg:
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
await cfg.option('a').value.set('192.168.1.1') await cfg.option('a').value.set('192.168.1.1')
await cfg.option('a').value.set('192.168.1.0') await cfg.option('a').value.set('192.168.1.0')
await cfg.option('a').value.set('88.88.88.88') await cfg.option('a').value.set('88.88.88.88')
await cfg.option('a').value.set('0.0.0.0') await cfg.option('a').value.set('0.0.0.0')
if config_type != 'tiramisu-api': if config_type != 'tiramisu-api':
# FIXME # FIXME
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('a').value.set('255.255.255.0') await cfg.option('a').value.set('255.255.255.0')
await cfg.option('b').value.set('192.168.1.1') await cfg.option('b').value.set('192.168.1.1')
await cfg.option('b').value.set('192.168.1.0') await cfg.option('b').value.set('192.168.1.0')
if config_type != 'tiramisu-api': if config_type != 'tiramisu-api':
# FIXME # FIXME
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('b').value.set('88.88.88.88') await cfg.option('b').value.set('88.88.88.88')
await cfg.option('b').value.set('0.0.0.0') await cfg.option('b').value.set('0.0.0.0')
if config_type != 'tiramisu-api': if config_type != 'tiramisu-api':
# FIXME # FIXME
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('b').value.set('255.255.255.0') await cfg.option('b').value.set('255.255.255.0')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('a').value.set('333.0.1.20') await cfg.option('a').value.set('333.0.1.20')
if config_type != 'tiramisu-api': if config_type != 'tiramisu-api':
# FIXME # FIXME
with pytest.raises(ValueError): with pytest.raises(ValueError):
IPOption('a', 'ip', default='192.000.023.01') IPOption('a', 'ip', default='192.000.023.01')
with warnings.catch_warnings(record=True) as w: with warnings.catch_warnings(record=True) as w:
await cfg.option('d').value.set('88.88.88.88') await cfg.option('d').value.set('88.88.88.88')
assert len(w) == 1 assert len(w) == 1
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -60,26 +57,28 @@ async def test_ip_cidr():
c = IPOption('c', '', private_only=True) c = IPOption('c', '', private_only=True)
warnings.simplefilter("always", ValueWarning) warnings.simplefilter("always", ValueWarning)
od = OptionDescription('od', '', [b, c]) od = OptionDescription('od', '', [b, c])
cfg = await Config(od) async with await Config(od) as cfg:
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('b').value.set('192.168.1.1') await cfg.option('b').value.set('192.168.1.1')
await cfg.option('b').value.set('192.168.1.1/24') await cfg.option('b').value.set('192.168.1.1/24')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('b').value.set('192.168.1.1/32') await cfg.option('b').value.set('192.168.1.1/32')
# #
await cfg.option('c').value.set('192.168.1.1') await cfg.option('c').value.set('192.168.1.1')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('c').value.set('192.168.1.1/24') await cfg.option('c').value.set('192.168.1.1/24')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('c').value.set('192.168.1.1/32') await cfg.option('c').value.set('192.168.1.1/32')
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_ip_default(): async def test_ip_default():
a = IPOption('a', '', '88.88.88.88') a = IPOption('a', '', '88.88.88.88')
od = OptionDescription('od', '', [a]) od = OptionDescription('od', '', [a])
cfg = await Config(od) async with await Config(od) as cfg:
await cfg.option('a').value.get() == '88.88.88.88' await cfg.option('a').value.get() == '88.88.88.88'
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -89,18 +88,19 @@ async def test_ip_reserved(config_type):
c = IPOption('c', '', warnings_only=True) c = IPOption('c', '', warnings_only=True)
od = OptionDescription('od', '', [a, b, c]) od = OptionDescription('od', '', [a, b, c])
warnings.simplefilter("always", ValueWarning) warnings.simplefilter("always", ValueWarning)
cfg = await Config(od) async with await Config(od) as cfg:
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
if config_type != 'tiramisu-api': if config_type != 'tiramisu-api':
# FIXME # FIXME
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('a').value.set('240.94.1.1') await cfg.option('a').value.set('240.94.1.1')
await cfg.option('b').value.set('240.94.1.1') await cfg.option('b').value.set('240.94.1.1')
if config_type != 'tiramisu-api': if config_type != 'tiramisu-api':
# FIXME # FIXME
with warnings.catch_warnings(record=True) as w: with warnings.catch_warnings(record=True) as w:
await cfg.option('c').value.set('240.94.1.1') await cfg.option('c').value.set('240.94.1.1')
assert len(w) == 1 assert len(w) == 1
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -109,52 +109,54 @@ async def test_network(config_type):
b = NetworkOption('b', '', warnings_only=True) b = NetworkOption('b', '', warnings_only=True)
od = OptionDescription('od', '', [a, b]) od = OptionDescription('od', '', [a, b])
warnings.simplefilter("always", ValueWarning) warnings.simplefilter("always", ValueWarning)
cfg = await Config(od) async with await Config(od) as cfg:
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
await cfg.option('a').value.set('192.168.1.1') await cfg.option('a').value.set('192.168.1.1')
await cfg.option('a').value.set('192.168.1.0') await cfg.option('a').value.set('192.168.1.0')
await cfg.option('a').value.set('88.88.88.88') await cfg.option('a').value.set('88.88.88.88')
await cfg.option('a').value.set('0.0.0.0') await cfg.option('a').value.set('0.0.0.0')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('a').value.set(1) await cfg.option('a').value.set(1)
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('a').value.set('1.1.1.1.1') await cfg.option('a').value.set('1.1.1.1.1')
if config_type != 'tiramisu-api': if config_type != 'tiramisu-api':
# FIXME # FIXME
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('a').value.set('255.255.255.0') await cfg.option('a').value.set('255.255.255.0')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('a').value.set('192.168.001.0') await cfg.option('a').value.set('192.168.001.0')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('a').value.set('333.168.1.1') await cfg.option('a').value.set('333.168.1.1')
if config_type != 'tiramisu-api': if config_type != 'tiramisu-api':
# FIXME # FIXME
with warnings.catch_warnings(record=True) as w: with warnings.catch_warnings(record=True) as w:
await cfg.option('b').value.set('255.255.255.0') await cfg.option('b').value.set('255.255.255.0')
assert len(w) == 1 assert len(w) == 1
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_network_cidr(config_type): async def test_network_cidr(config_type):
a = NetworkOption('a', '', cidr=True) a = NetworkOption('a', '', cidr=True)
od = OptionDescription('od', '', [a]) od = OptionDescription('od', '', [a])
cfg = await Config(od) async with await Config(od) as cfg:
# FIXME cfg = await get_config(cfg, config_type) # FIXME cfg = await get_config(cfg, config_type)
await cfg.option('a').value.set('192.168.1.1/32') await cfg.option('a').value.set('192.168.1.1/32')
await cfg.option('a').value.set('192.168.1.0/24') await cfg.option('a').value.set('192.168.1.0/24')
await cfg.option('a').value.set('88.88.88.88/32') await cfg.option('a').value.set('88.88.88.88/32')
await cfg.option('a').value.set('0.0.0.0/0') await cfg.option('a').value.set('0.0.0.0/0')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('a').value.set('192.168.1.1') await cfg.option('a').value.set('192.168.1.1')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('a').value.set('192.168.1.1/24') await cfg.option('a').value.set('192.168.1.1/24')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('a').value.set('2001:db00::0/24') await cfg.option('a').value.set('2001:db00::0/24')
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_network_invalid(): async def test_network_invalid():
with pytest.raises(ValueError): with pytest.raises(ValueError):
NetworkOption('a', '', default='toto') NetworkOption('a', '', default='toto')
@ -162,46 +164,48 @@ async def test_network_invalid():
async def test_netmask(config_type): async def test_netmask(config_type):
a = NetmaskOption('a', '') a = NetmaskOption('a', '')
od = OptionDescription('od', '', [a]) od = OptionDescription('od', '', [a])
cfg = await Config(od) async with await Config(od) as cfg:
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('a').value.set('192.168.1.1.1') await cfg.option('a').value.set('192.168.1.1.1')
if config_type != 'tiramisu-api': if config_type != 'tiramisu-api':
# FIXME # FIXME
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('a').value.set('192.168.1.1') await cfg.option('a').value.set('192.168.1.1')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('a').value.set('192.168.1.0') await cfg.option('a').value.set('192.168.1.0')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('a').value.set('88.88.88.88') await cfg.option('a').value.set('88.88.88.88')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('a').value.set('255.255.255.000') await cfg.option('a').value.set('255.255.255.000')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('a').value.set(2) await cfg.option('a').value.set(2)
await cfg.option('a').value.set('0.0.0.0') await cfg.option('a').value.set('0.0.0.0')
await cfg.option('a').value.set('255.255.255.0') await cfg.option('a').value.set('255.255.255.0')
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_broadcast(config_type): async def test_broadcast(config_type):
a = BroadcastOption('a', '') a = BroadcastOption('a', '')
od = OptionDescription('od', '', [a]) od = OptionDescription('od', '', [a])
cfg = await Config(od) async with await Config(od) as cfg:
# FIXME cfg = await get_config(cfg, config_type) # FIXME cfg = await get_config(cfg, config_type)
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('a').value.set('192.168.1.255.1') await cfg.option('a').value.set('192.168.1.255.1')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('a').value.set('192.168.001.255') await cfg.option('a').value.set('192.168.001.255')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('a').value.set('192.168.0.300') await cfg.option('a').value.set('192.168.0.300')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('a').value.set(1) await cfg.option('a').value.set(1)
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('a').value.set(2) await cfg.option('a').value.set(2)
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('a').value.set('2001:db8::1') await cfg.option('a').value.set('2001:db8::1')
await cfg.option('a').value.set('0.0.0.0') await cfg.option('a').value.set('0.0.0.0')
await cfg.option('a').value.set('255.255.255.0') await cfg.option('a').value.set('255.255.255.0')
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -213,81 +217,82 @@ async def test_port(config_type):
e = PortOption('e', '', allow_zero=True, allow_private=True) e = PortOption('e', '', allow_zero=True, allow_private=True)
f = PortOption('f', '', allow_private=True) f = PortOption('f', '', allow_private=True)
od = OptionDescription('od', '', [a, b, c, d, e, f]) od = OptionDescription('od', '', [a, b, c, d, e, f])
cfg = await Config(od) async with await Config(od) as cfg:
# FIXME cfg = await get_config(cfg, config_type) # FIXME cfg = await get_config(cfg, config_type)
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('a').value.set('0') await cfg.option('a').value.set('0')
await cfg.option('a').value.set('1') await cfg.option('a').value.set('1')
await cfg.option('a').value.set('1023') await cfg.option('a').value.set('1023')
await cfg.option('a').value.set('1024') await cfg.option('a').value.set('1024')
await cfg.option('a').value.set('49151') await cfg.option('a').value.set('49151')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('a').value.set('49152') await cfg.option('a').value.set('49152')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('a').value.set('65535') await cfg.option('a').value.set('65535')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('a').value.set('65536') await cfg.option('a').value.set('65536')
await cfg.option('b').value.set('0') await cfg.option('b').value.set('0')
await cfg.option('b').value.set('1') await cfg.option('b').value.set('1')
await cfg.option('b').value.set('1023') await cfg.option('b').value.set('1023')
await cfg.option('b').value.set('1024') await cfg.option('b').value.set('1024')
await cfg.option('b').value.set('49151') await cfg.option('b').value.set('49151')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('b').value.set('49152') await cfg.option('b').value.set('49152')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('b').value.set('65535') await cfg.option('b').value.set('65535')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('b').value.set('65536') await cfg.option('b').value.set('65536')
await cfg.option('c').value.set('0') await cfg.option('c').value.set('0')
await cfg.option('c').value.set('1') await cfg.option('c').value.set('1')
await cfg.option('c').value.set('1023') await cfg.option('c').value.set('1023')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('c').value.set('1024') await cfg.option('c').value.set('1024')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('c').value.set('49151') await cfg.option('c').value.set('49151')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('c').value.set('49152') await cfg.option('c').value.set('49152')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('c').value.set('65535') await cfg.option('c').value.set('65535')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('c').value.set('65536') await cfg.option('c').value.set('65536')
await cfg.option('d').value.set('0') await cfg.option('d').value.set('0')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('d').value.set('1') await cfg.option('d').value.set('1')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('d').value.set('1023') await cfg.option('d').value.set('1023')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('d').value.set('1024') await cfg.option('d').value.set('1024')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('d').value.set('49151') await cfg.option('d').value.set('49151')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('d').value.set('49152') await cfg.option('d').value.set('49152')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('d').value.set('65535') await cfg.option('d').value.set('65535')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('d').value.set('65536') await cfg.option('d').value.set('65536')
await cfg.option('e').value.set('0') await cfg.option('e').value.set('0')
await cfg.option('e').value.set('1') await cfg.option('e').value.set('1')
await cfg.option('e').value.set('1023') await cfg.option('e').value.set('1023')
await cfg.option('e').value.set('1024') await cfg.option('e').value.set('1024')
await cfg.option('e').value.set('49151') await cfg.option('e').value.set('49151')
await cfg.option('e').value.set('49152') await cfg.option('e').value.set('49152')
await cfg.option('e').value.set('65535') await cfg.option('e').value.set('65535')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('f').value.set('0') await cfg.option('f').value.set('0')
await cfg.option('f').value.set('1') await cfg.option('f').value.set('1')
await cfg.option('f').value.set('1023') await cfg.option('f').value.set('1023')
await cfg.option('f').value.set('1024') await cfg.option('f').value.set('1024')
await cfg.option('f').value.set('49151') await cfg.option('f').value.set('49151')
await cfg.option('f').value.set('49152') await cfg.option('f').value.set('49152')
await cfg.option('f').value.set('65535') await cfg.option('f').value.set('65535')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('f').value.set('65536') await cfg.option('f').value.set('65536')
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -299,102 +304,103 @@ async def test_port_range(config_type):
e = PortOption('e', '', allow_range=True, allow_zero=True, allow_private=True) e = PortOption('e', '', allow_range=True, allow_zero=True, allow_private=True)
f = PortOption('f', '', allow_range=True, allow_private=True) f = PortOption('f', '', allow_range=True, allow_private=True)
od = OptionDescription('od', '', [a, b, c, d, e, f]) od = OptionDescription('od', '', [a, b, c, d, e, f])
cfg = await Config(od) async with await Config(od) as cfg:
# FIXME cfg = await get_config(cfg, config_type) # FIXME cfg = await get_config(cfg, config_type)
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('a').value.set('0') await cfg.option('a').value.set('0')
await cfg.option('a').value.set('1') await cfg.option('a').value.set('1')
await cfg.option('a').value.set('1023') await cfg.option('a').value.set('1023')
await cfg.option('a').value.set('1024') await cfg.option('a').value.set('1024')
await cfg.option('a').value.set('49151') await cfg.option('a').value.set('49151')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('a').value.set('49152') await cfg.option('a').value.set('49152')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('a').value.set('65535') await cfg.option('a').value.set('65535')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('a').value.set('65536') await cfg.option('a').value.set('65536')
await cfg.option('a').value.set('1:49151') await cfg.option('a').value.set('1:49151')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('a').value.set('0:49151') await cfg.option('a').value.set('0:49151')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('a').value.set('1:49152') await cfg.option('a').value.set('1:49152')
await cfg.option('b').value.set('0') await cfg.option('b').value.set('0')
await cfg.option('b').value.set('1') await cfg.option('b').value.set('1')
await cfg.option('b').value.set('1023') await cfg.option('b').value.set('1023')
await cfg.option('b').value.set('1024') await cfg.option('b').value.set('1024')
await cfg.option('b').value.set('49151') await cfg.option('b').value.set('49151')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('b').value.set('49152') await cfg.option('b').value.set('49152')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('b').value.set('65535') await cfg.option('b').value.set('65535')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('b').value.set('65536') await cfg.option('b').value.set('65536')
await cfg.option('b').value.set('0:49151') await cfg.option('b').value.set('0:49151')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('b').value.set('0:49152') await cfg.option('b').value.set('0:49152')
await cfg.option('c').value.set('0') await cfg.option('c').value.set('0')
await cfg.option('c').value.set('1') await cfg.option('c').value.set('1')
await cfg.option('c').value.set('1023') await cfg.option('c').value.set('1023')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('c').value.set('1024') await cfg.option('c').value.set('1024')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('c').value.set('49151') await cfg.option('c').value.set('49151')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('c').value.set('49152') await cfg.option('c').value.set('49152')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('c').value.set('65535') await cfg.option('c').value.set('65535')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('c').value.set('65536') await cfg.option('c').value.set('65536')
await cfg.option('c').value.set('0:1023') await cfg.option('c').value.set('0:1023')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('c').value.set('0:1024') await cfg.option('c').value.set('0:1024')
await cfg.option('d').value.set('0') await cfg.option('d').value.set('0')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('d').value.set('1') await cfg.option('d').value.set('1')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('d').value.set('1023') await cfg.option('d').value.set('1023')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('d').value.set('1024') await cfg.option('d').value.set('1024')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('d').value.set('49151') await cfg.option('d').value.set('49151')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('d').value.set('49152') await cfg.option('d').value.set('49152')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('d').value.set('65535') await cfg.option('d').value.set('65535')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('d').value.set('65536') await cfg.option('d').value.set('65536')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('d').value.set('0:0') await cfg.option('d').value.set('0:0')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('d').value.set('0:1') await cfg.option('d').value.set('0:1')
await cfg.option('e').value.set('0') await cfg.option('e').value.set('0')
await cfg.option('e').value.set('1') await cfg.option('e').value.set('1')
await cfg.option('e').value.set('1023') await cfg.option('e').value.set('1023')
await cfg.option('e').value.set('1024') await cfg.option('e').value.set('1024')
await cfg.option('e').value.set('49151') await cfg.option('e').value.set('49151')
await cfg.option('e').value.set('49152') await cfg.option('e').value.set('49152')
await cfg.option('e').value.set('65535') await cfg.option('e').value.set('65535')
await cfg.option('e').value.set('0:65535') await cfg.option('e').value.set('0:65535')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('e').value.set('0:65536') await cfg.option('e').value.set('0:65536')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('f').value.set('0') await cfg.option('f').value.set('0')
await cfg.option('f').value.set('1') await cfg.option('f').value.set('1')
await cfg.option('f').value.set('1023') await cfg.option('f').value.set('1023')
await cfg.option('f').value.set('1024') await cfg.option('f').value.set('1024')
await cfg.option('f').value.set('49151') await cfg.option('f').value.set('49151')
await cfg.option('f').value.set('49152') await cfg.option('f').value.set('49152')
await cfg.option('f').value.set('65535') await cfg.option('f').value.set('65535')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('f').value.set('65536') await cfg.option('f').value.set('65536')
await cfg.option('f').value.set('1:65535') await cfg.option('f').value.set('1:65535')
await cfg.option('f').value.set('3:4') await cfg.option('f').value.set('3:4')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('f').value.set('0:65535') await cfg.option('f').value.set('0:65535')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('f').value.set('4:3') await cfg.option('f').value.set('4:3')
assert not await list_sessions()

View file

@ -8,10 +8,7 @@ from tiramisu import BoolOption, IntOption, StrOption, IPOption, NetmaskOption,
SymLinkOption, OptionDescription, DynOptionDescription, submulti, \ SymLinkOption, OptionDescription, DynOptionDescription, submulti, \
Config, GroupConfig, MetaConfig, Params, ParamOption, Calculation Config, GroupConfig, MetaConfig, Params, ParamOption, Calculation
from tiramisu.storage import list_sessions from tiramisu.storage import list_sessions
from .config import event_loop
def teardown_function(function):
assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__)
IS_DEREFABLE = True IS_DEREFABLE = True
@ -25,40 +22,44 @@ def funcname(*args, **kwargs):
async def test_deref_storage(): async def test_deref_storage():
b = BoolOption('b', '') b = BoolOption('b', '')
o = OptionDescription('od', '', [b]) o = OptionDescription('od', '', [b])
c = await Config(o) async with await Config(o) as cfg:
w = weakref.ref(c._config_bag.context.cfgimpl_get_values()._p_) w = weakref.ref(cfg._config_bag.context.cfgimpl_get_values()._p_)
del(c) del cfg
assert w() is None assert w() is None
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_deref_value(): async def test_deref_value():
b = BoolOption('b', '') b = BoolOption('b', '')
o = OptionDescription('od', '', [b]) o = OptionDescription('od', '', [b])
c = await Config(o) async with await Config(o) as cfg:
w = weakref.ref(c._config_bag.context.cfgimpl_get_values()) w = weakref.ref(cfg._config_bag.context.cfgimpl_get_values())
del(c) del cfg
assert w() is None assert w() is None
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_deref_setting(): async def test_deref_setting():
b = BoolOption('b', '') b = BoolOption('b', '')
o = OptionDescription('od', '', [b]) o = OptionDescription('od', '', [b])
c = await Config(o) async with await Config(o) as cfg:
w = weakref.ref(c._config_bag.context.cfgimpl_get_settings()) w = weakref.ref(cfg._config_bag.context.cfgimpl_get_settings())
del(c) del cfg
assert w() is None assert w() is None
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_deref_config(): async def test_deref_config():
b = BoolOption('b', '') b = BoolOption('b', '')
o = OptionDescription('od', '', [b]) o = OptionDescription('od', '', [b])
c = await Config(o) async with await Config(o) as cfg:
w = weakref.ref(c) w = weakref.ref(cfg)
del(c) del cfg
assert w() is None assert w() is None
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -75,6 +76,7 @@ async def test_deref_option():
return return
del(o) del(o)
assert w() is None assert w() is None
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -88,6 +90,7 @@ async def test_deref_optiondescription():
assert w() is not None assert w() is not None
del(o) del(o)
assert w() is None assert w() is None
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -102,6 +105,7 @@ async def test_deref_option_cache():
assert w() is not None assert w() is not None
del(o) del(o)
assert w() is None assert w() is None
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -116,6 +120,7 @@ async def test_deref_optiondescription_cache():
assert w() is not None assert w() is not None
del(o) del(o)
assert w() is None assert w() is None
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -124,14 +129,15 @@ async def test_deref_option_config():
return return
b = BoolOption('b', '') b = BoolOption('b', '')
o = OptionDescription('od', '', [b]) o = OptionDescription('od', '', [b])
c = await Config(o) async with await Config(o) as cfg:
w = weakref.ref(b) w = weakref.ref(b)
del(b) del(b)
assert w() is not None assert w() is not None
del(o) del(o)
assert w() is not None assert w() is not None
del(c) del cfg
assert w() is None assert w() is None
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -140,14 +146,15 @@ async def test_deref_optiondescription_config():
return return
b = BoolOption('b', '') b = BoolOption('b', '')
o = OptionDescription('od', '', [b]) o = OptionDescription('od', '', [b])
c = await Config(o) async with await Config(o) as cfg:
w = weakref.ref(o) w = weakref.ref(o)
del(b) del(b)
assert w() is not None assert w() is not None
del(o) del(o)
assert w() is not None assert w() is not None
del(c) del cfg
assert w() is None assert w() is None
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -157,29 +164,30 @@ async def test_deref_validator():
a = StrOption('a', '', default='yes') a = StrOption('a', '', default='yes')
b = StrOption('b', '', validators=[Calculation(funcname, Params(ParamOption(a)))], default='val') b = StrOption('b', '', validators=[Calculation(funcname, Params(ParamOption(a)))], default='val')
od = OptionDescription('root', '', [a, b]) od = OptionDescription('root', '', [a, b])
cfg = await Config(od) async with await Config(od) as cfg:
w = weakref.ref(a) w = weakref.ref(a)
x = weakref.ref(b) x = weakref.ref(b)
y = weakref.ref(od) y = weakref.ref(od)
z = weakref.ref(cfg) z = weakref.ref(cfg)
assert w() is not None assert w() is not None
assert x() is not None assert x() is not None
assert w() is not None assert w() is not None
assert x() is not None assert x() is not None
del(a) del(a)
del(b) del(b)
assert w() is not None assert w() is not None
assert x() is not None assert x() is not None
assert w() is not None assert w() is not None
assert x() is not None assert x() is not None
del(od) del(od)
assert w() is not None assert w() is not None
assert x() is not None assert x() is not None
assert w() is not None assert w() is not None
assert x() is not None assert x() is not None
del(cfg) del cfg
assert y() is None assert y() is None
assert z() is None assert z() is None
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -189,29 +197,30 @@ async def test_deref_callback():
a = StrOption('a', "", 'val') a = StrOption('a', "", 'val')
b = StrOption('b', "", Calculation(funcname, Params((ParamOption(a),)))) b = StrOption('b', "", Calculation(funcname, Params((ParamOption(a),))))
od = OptionDescription('root', '', [a, b]) od = OptionDescription('root', '', [a, b])
cfg = await Config(od) async with await Config(od) as cfg:
w = weakref.ref(a) w = weakref.ref(a)
x = weakref.ref(b) x = weakref.ref(b)
y = weakref.ref(od) y = weakref.ref(od)
z = weakref.ref(cfg) z = weakref.ref(cfg)
assert w() is not None assert w() is not None
assert x() is not None assert x() is not None
assert w() is not None assert w() is not None
assert x() is not None assert x() is not None
del(a) del(a)
del(b) del(b)
assert w() is not None assert w() is not None
assert x() is not None assert x() is not None
assert w() is not None assert w() is not None
assert x() is not None assert x() is not None
del(od) del(od)
assert w() is not None assert w() is not None
assert x() is not None assert x() is not None
assert w() is not None assert w() is not None
assert x() is not None assert x() is not None
del(cfg) del cfg
assert y() is None assert y() is None
assert z() is None assert z() is None
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -221,29 +230,30 @@ async def test_deref_symlink():
a = BoolOption("a", "", default=False) a = BoolOption("a", "", default=False)
b = SymLinkOption("b", a) b = SymLinkOption("b", a)
od = OptionDescription('root', '', [a, b]) od = OptionDescription('root', '', [a, b])
cfg = await Config(od) async with await Config(od) as cfg:
w = weakref.ref(a) w = weakref.ref(a)
x = weakref.ref(b) x = weakref.ref(b)
y = weakref.ref(od) y = weakref.ref(od)
z = weakref.ref(cfg) z = weakref.ref(cfg)
assert w() is not None assert w() is not None
assert x() is not None assert x() is not None
assert w() is not None assert w() is not None
assert x() is not None assert x() is not None
del(a) del(a)
del(b) del(b)
assert w() is not None assert w() is not None
assert x() is not None assert x() is not None
assert w() is not None assert w() is not None
assert x() is not None assert x() is not None
del(od) del(od)
assert w() is not None assert w() is not None
assert x() is not None assert x() is not None
assert w() is not None assert w() is not None
assert x() is not None assert x() is not None
del(cfg) del cfg
assert y() is None assert y() is None
assert z() is None assert z() is None
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -254,27 +264,28 @@ async def test_deref_dyn():
b = StrOption('b', '') b = StrOption('b', '')
dod = DynOptionDescription('dod', '', [b], suffixes=Calculation(funcname, Params((ParamOption(a),)))) dod = DynOptionDescription('dod', '', [b], suffixes=Calculation(funcname, Params((ParamOption(a),))))
od = OptionDescription('od', '', [dod, a]) od = OptionDescription('od', '', [dod, a])
cfg = await Config(od) async with await Config(od) as cfg:
w = weakref.ref(a) w = weakref.ref(a)
x = weakref.ref(b) x = weakref.ref(b)
y = weakref.ref(od) y = weakref.ref(od)
z = weakref.ref(cfg) z = weakref.ref(cfg)
assert w() is not None assert w() is not None
assert x() is not None assert x() is not None
assert w() is not None assert w() is not None
assert x() is not None assert x() is not None
del(a) del(a)
del(b) del(b)
assert w() is not None assert w() is not None
assert x() is not None assert x() is not None
assert w() is not None assert w() is not None
assert x() is not None assert x() is not None
del(od) del(od)
del(dod) del(dod)
assert w() is not None assert w() is not None
assert x() is not None assert x() is not None
assert w() is not None assert w() is not None
assert x() is not None assert x() is not None
del(cfg) del cfg
assert y() is None assert y() is None
assert z() is None assert z() is None
assert not await list_sessions()

View file

@ -6,12 +6,8 @@ import pytest
from tiramisu.setting import groups from tiramisu.setting import groups
from tiramisu import Config, MetaConfig, ChoiceOption, BoolOption, IntOption, \ from tiramisu import Config, MetaConfig, ChoiceOption, BoolOption, IntOption, \
StrOption, OptionDescription, groups StrOption, OptionDescription, groups
from .test_state import _diff_opts, _diff_conf
from tiramisu.storage import list_sessions from tiramisu.storage import list_sessions
from .config import event_loop
def teardown_function(function):
assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__)
def make_description(): def make_description():
@ -47,52 +43,52 @@ def make_description():
return descr return descr
@pytest.mark.asyncio
async def test_copy():
cfg = await Config(make_description())
ncfg = await cfg.config.copy()
assert await cfg.option('creole.general.numero_etab').value.get() == None
await cfg.option('creole.general.numero_etab').value.set('oui')
assert await cfg.option('creole.general.numero_etab').value.get() == 'oui'
assert await ncfg.option('creole.general.numero_etab').value.get() == None
# _diff_opts(await cfg.cfgimpl_get_description(), nawait cfg.cfgimpl_get_description())
# _diff_conf(cfg, ncfg)
# await cfg.creole.general.numero_etab = 'oui'
# raises(AssertionError, "_diff_conf(cfg, ncfg)")
# nawait cfg.creole.general.numero_etab = 'oui'
# _diff_conf(cfg, ncfg)
def to_tuple(val): def to_tuple(val):
return tuple([tuple(v) for v in val]) return tuple([tuple(v) for v in val])
@pytest.mark.asyncio
async def test_copy():
od = make_description()
async with await Config(od) as cfg:
async with await cfg.config.copy() as ncfg:
assert await cfg.option('creole.general.numero_etab').value.get() == None
await cfg.option('creole.general.numero_etab').value.set('oui')
assert await cfg.option('creole.general.numero_etab').value.get() == 'oui'
assert await ncfg.option('creole.general.numero_etab').value.get() == None
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_copy_force_store_value(): async def test_copy_force_store_value():
descr = make_description() od = make_description()
conf = await Config(descr) async with await Config(od) as conf:
conf2 = await Config(descr) async with await Config(od) as conf2:
assert to_tuple(await conf.value.exportation()) == ((), (), (), ()) assert to_tuple(await conf.value.exportation()) == ((), (), (), ())
assert to_tuple(await conf2.value.exportation()) == ((), (), (), ()) assert to_tuple(await conf2.value.exportation()) == ((), (), (), ())
# #
await conf.property.read_write() await conf.property.read_write()
assert to_tuple(await conf.value.exportation()) == (('creole.general.wantref',), (None,), (False,), ('forced',)) assert to_tuple(await conf.value.exportation()) == (('creole.general.wantref',), (None,), (False,), ('forced',))
assert to_tuple(await conf2.value.exportation()) == ((), (), (), ()) assert to_tuple(await conf2.value.exportation()) == ((), (), (), ())
# #
await conf2.property.read_only() await conf2.property.read_only()
assert to_tuple(await conf.value.exportation()) == (('creole.general.wantref',), (None,), (False,), ('forced',)) assert to_tuple(await conf.value.exportation()) == (('creole.general.wantref',), (None,), (False,), ('forced',))
assert to_tuple(await conf2.value.exportation()) == (('creole.general.wantref',), (None,), (False,), ('forced',)) assert to_tuple(await conf2.value.exportation()) == (('creole.general.wantref',), (None,), (False,), ('forced',))
# #
await conf.option('creole.general.wantref').value.set(True) await conf.option('creole.general.wantref').value.set(True)
assert to_tuple(await conf.value.exportation()) == (('creole.general.wantref',), (None,), (True,), ('user',)) assert to_tuple(await conf.value.exportation()) == (('creole.general.wantref',), (None,), (True,), ('user',))
assert to_tuple(await conf2.value.exportation()) == (('creole.general.wantref',), (None,), (False,), ('forced',)) assert to_tuple(await conf2.value.exportation()) == (('creole.general.wantref',), (None,), (False,), ('forced',))
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_copy_force_store_value_metaconfig(): async def test_copy_force_store_value_metaconfig():
descr = make_description() descr = make_description()
meta = await MetaConfig([], optiondescription=descr) async with await MetaConfig([], optiondescription=descr) as meta:
conf = await meta.config.new(session_id='conf') async with await meta.config.new(session_id='conf') as conf:
assert await meta.property.get() == await conf.property.get() assert await meta.property.get() == await conf.property.get()
assert await meta.permissive.get() == await conf.permissive.get() assert await meta.permissive.get() == await conf.permissive.get()
await conf.property.read_write() await conf.property.read_write()
assert to_tuple(await conf.value.exportation()) == (('creole.general.wantref',), (None,), (False,), ('forced',)) assert to_tuple(await conf.value.exportation()) == (('creole.general.wantref',), (None,), (False,), ('forced',))
assert to_tuple(await meta.value.exportation()) == ((), (), (), ()) assert to_tuple(await meta.value.exportation()) == ((), (), (), ())
assert not await list_sessions()

File diff suppressed because it is too large Load diff

View file

@ -8,13 +8,10 @@ import pytest
from tiramisu.setting import owners, groups from tiramisu.setting import owners, groups
from tiramisu import ChoiceOption, BoolOption, IntOption, FloatOption, \ from tiramisu import ChoiceOption, BoolOption, IntOption, FloatOption, \
StrOption, OptionDescription, SymLinkOption, Leadership, Config, \ StrOption, OptionDescription, SymLinkOption, Leadership, Config, \
Calculation, Params, ParamOption, ParamValue, calc_value Calculation, Params, ParamOption, ParamValue, calc_value, delete_session
from tiramisu.error import PropertiesOptionError, ConfigError from tiramisu.error import PropertiesOptionError, ConfigError
from tiramisu.storage import list_sessions from tiramisu.storage import list_sessions
from .config import event_loop
def teardown_function(function):
assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__)
def compare(calculated, expected): def compare(calculated, expected):
@ -82,47 +79,49 @@ def return_val3(context, value):
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_freeze_whole_config(): async def test_freeze_whole_config():
descr = make_description_freeze() descr = make_description_freeze()
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
await cfg.property.add('everything_frozen') await cfg.property.add('everything_frozen')
assert await cfg.option('gc.dummy').value.get() is False assert await cfg.option('gc.dummy').value.get() is False
prop = [] prop = []
try: try:
await cfg.option('gc.dummy').value.set(True)
except PropertiesOptionError as err:
prop = err.proptype
assert 'frozen' in prop
assert await cfg.option('gc.dummy').value.get() is False
#
await cfg.property.pop('everything_frozen')
await cfg.option('gc.dummy').value.set(True) await cfg.option('gc.dummy').value.set(True)
except PropertiesOptionError as err: assert await cfg.option('gc.dummy').value.get() is True
prop = err.proptype #
assert 'frozen' in prop await cfg.property.add('everything_frozen')
assert await cfg.option('gc.dummy').value.get() is False owners.addowner("everythingfrozen2")
# prop = []
await cfg.property.pop('everything_frozen') try:
await cfg.option('gc.dummy').value.set(True) await cfg.option('gc.dummy').owner.set('everythingfrozen2')
assert await cfg.option('gc.dummy').value.get() is True except PropertiesOptionError as err:
# prop = err.proptype
await cfg.property.add('everything_frozen') assert 'frozen' in prop
owners.addowner("everythingfrozen2") assert not await list_sessions()
prop = []
try:
await cfg.option('gc.dummy').owner.set('everythingfrozen2')
except PropertiesOptionError as err:
prop = err.proptype
assert 'frozen' in prop
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_freeze_one_option(): async def test_freeze_one_option():
"freeze an option " "freeze an option "
descr = make_description_freeze() descr = make_description_freeze()
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
#freeze only one option #freeze only one option
await cfg.option('gc.dummy').property.add('frozen') await cfg.option('gc.dummy').property.add('frozen')
assert await cfg.option('gc.dummy').value.get() is False assert await cfg.option('gc.dummy').value.get() is False
prop = [] prop = []
try: try:
await cfg.option('gc.dummy').value.set(True) await cfg.option('gc.dummy').value.set(True)
except PropertiesOptionError as err: except PropertiesOptionError as err:
prop = err.proptype prop = err.proptype
assert 'frozen' in prop assert 'frozen' in prop
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -130,58 +129,62 @@ async def test_frozen_value():
"setattr a frozen value at the config level" "setattr a frozen value at the config level"
s = StrOption("string", "", default="string") s = StrOption("string", "", default="string")
descr = OptionDescription("options", "", [s]) descr = OptionDescription("options", "", [s])
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
await cfg.property.add('frozen') await cfg.property.add('frozen')
await cfg.option('string').property.add('frozen') await cfg.option('string').property.add('frozen')
prop = [] prop = []
try: try:
await cfg.option('string').value.set('egg') await cfg.option('string').value.set('egg')
except PropertiesOptionError as err: except PropertiesOptionError as err:
prop = err.proptype prop = err.proptype
assert 'frozen' in prop assert 'frozen' in prop
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_freeze(): async def test_freeze():
"freeze a whole configuration object" "freeze a whole configuration object"
descr = make_description_freeze() descr = make_description_freeze()
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
await cfg.property.add('frozen') await cfg.property.add('frozen')
await cfg.option('gc.name').property.add('frozen') await cfg.option('gc.name').property.add('frozen')
prop = [] prop = []
try: try:
await cfg.option('gc.name').value.set('framework') await cfg.option('gc.name').value.set('framework')
except PropertiesOptionError as err: except PropertiesOptionError as err:
prop = err.proptype prop = err.proptype
assert 'frozen' in prop assert 'frozen' in prop
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_freeze_multi(): async def test_freeze_multi():
descr = make_description_freeze() descr = make_description_freeze()
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
await cfg.property.add('frozen') await cfg.property.add('frozen')
await cfg.option('boolop').property.add('frozen') await cfg.option('boolop').property.add('frozen')
prop = [] prop = []
try: try:
await cfg.option('boolop').value.set([True]) await cfg.option('boolop').value.set([True])
except PropertiesOptionError as err: except PropertiesOptionError as err:
prop = err.proptype prop = err.proptype
assert 'frozen' in prop assert 'frozen' in prop
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_force_store_value(): async def test_force_store_value():
descr = make_description_freeze() descr = make_description_freeze()
cfg = await Config(descr) async with await Config(descr) as cfg:
compare(await cfg.value.exportation(), (('wantref', 'wantref2', 'wantref3'), (None, None, None), (False, False, (False,)), ('forced', 'forced', 'forced'))) compare(await cfg.value.exportation(), (('wantref', 'wantref2', 'wantref3'), (None, None, None), (False, False, (False,)), ('forced', 'forced', 'forced')))
await cfg.option('wantref').value.set(True) await cfg.option('wantref').value.set(True)
compare(await cfg.value.exportation(), (('wantref', 'wantref2', 'wantref3'), (None, None, None), (True, False, (False,)), ('user', 'forced', 'forced'))) compare(await cfg.value.exportation(), (('wantref', 'wantref2', 'wantref3'), (None, None, None), (True, False, (False,)), ('user', 'forced', 'forced')))
await cfg.option('wantref').value.reset() await cfg.option('wantref').value.reset()
compare(await cfg.value.exportation(), (('wantref', 'wantref2', 'wantref3'), (None, None, None), (False, False, (False,)), ('forced', 'forced', 'forced'))) compare(await cfg.value.exportation(), (('wantref', 'wantref2', 'wantref3'), (None, None, None), (False, False, (False,)), ('forced', 'forced', 'forced')))
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -189,8 +192,10 @@ async def test_force_store_value_leadership_follower():
b = IntOption('int', 'Test int option', multi=True) b = IntOption('int', 'Test int option', multi=True)
c = StrOption('str', 'Test string option', multi=True, properties=('force_store_value',)) c = StrOption('str', 'Test string option', multi=True, properties=('force_store_value',))
descr = Leadership("int", "", [b, c]) descr = Leadership("int", "", [b, c])
with pytest.raises(ConfigError): with pytest.raises(ConfigError):
cfg = await Config(descr) cfg = await Config(descr, session_id='error')
await delete_session('error')
assert not await list_sessions()
#@pytest.mark.asyncio #@pytest.mark.asyncio
@ -208,24 +213,27 @@ async def test_force_store_value_leadership_sub():
c = StrOption('str', 'Test string option', multi=True) c = StrOption('str', 'Test string option', multi=True)
descr = Leadership("int", "", [b, c]) descr = Leadership("int", "", [b, c])
odr = OptionDescription('odr', '', [descr]) odr = OptionDescription('odr', '', [descr])
cfg = await Config(odr) async with await Config(odr) as cfg:
compare(await cfg.value.exportation(), (('int.int',), (None,), (tuple(),), ('forced',))) compare(await cfg.value.exportation(), (('int.int',), (None,), (tuple(),), ('forced',)))
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_force_store_value_callback(): async def test_force_store_value_callback():
b = IntOption('int', 'Test int option', Calculation(return_val), properties=('force_store_value',)) b = IntOption('int', 'Test int option', Calculation(return_val), properties=('force_store_value',))
descr = OptionDescription("int", "", [b]) descr = OptionDescription("int", "", [b])
cfg = await Config(descr) async with await Config(descr) as cfg:
compare(await cfg.value.exportation(), (('int',), (None,), (1,), ('forced',))) compare(await cfg.value.exportation(), (('int',), (None,), (1,), ('forced',)))
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_force_store_value_callback_params(): async def test_force_store_value_callback_params():
b = IntOption('int', 'Test int option', Calculation(return_val2, Params(kwargs={'value': ParamValue(2)})), properties=('force_store_value',)) b = IntOption('int', 'Test int option', Calculation(return_val2, Params(kwargs={'value': ParamValue(2)})), properties=('force_store_value',))
descr = OptionDescription("int", "", [b]) descr = OptionDescription("int", "", [b])
cfg = await Config(descr) async with await Config(descr) as cfg:
compare(await cfg.value.exportation(), (('int',), (None,), (2,), ('forced',))) compare(await cfg.value.exportation(), (('int',), (None,), (2,), ('forced',)))
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -233,5 +241,6 @@ async def test_force_store_value_callback_params_with_opt():
a = IntOption('val1', "", 2) a = IntOption('val1', "", 2)
b = IntOption('int', 'Test int option', Calculation(return_val2, Params(kwargs={'value': ParamOption(a)})), properties=('force_store_value',)) b = IntOption('int', 'Test int option', Calculation(return_val2, Params(kwargs={'value': ParamOption(a)})), properties=('force_store_value',))
descr = OptionDescription("int", "", [a, b]) descr = OptionDescription("int", "", [a, b])
cfg = await Config(descr) async with await Config(descr) as cfg:
compare(await cfg.value.exportation(), (('int',), (None,), (2,), ('forced',))) compare(await cfg.value.exportation(), (('int',), (None,), (2,), ('forced',)))
assert not await list_sessions()

File diff suppressed because it is too large Load diff

View file

@ -11,10 +11,11 @@ from tiramisu import IntOption, StrOption, OptionDescription, \
from tiramisu.error import PropertiesOptionError, ConfigError from tiramisu.error import PropertiesOptionError, ConfigError
from tiramisu.setting import groups from tiramisu.setting import groups
from tiramisu.storage import list_sessions from tiramisu.storage import list_sessions
from .config import event_loop
def teardown_function(function): #def teardown_function(function):
assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__) # assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__)
def make_description(): def make_description():
@ -78,315 +79,332 @@ def make_description3():
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_mandatory_ro(): async def test_mandatory_ro():
descr = make_description() descr = make_description()
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_only() await cfg.property.read_only()
prop = [] prop = []
try: try:
await cfg.option('str1').value.get() await cfg.option('str1').value.get()
except PropertiesOptionError as err: except PropertiesOptionError as err:
prop = err.proptype prop = err.proptype
assert 'mandatory' in prop assert 'mandatory' in prop
await cfg.property.read_write() await cfg.property.read_write()
await cfg.option('str1').value.set('yes') await cfg.option('str1').value.set('yes')
await cfg.property.read_only() await cfg.property.read_only()
assert await cfg.option('str1').value.get() == 'yes' assert await cfg.option('str1').value.get() == 'yes'
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_mandatory_ro_dict(): async def test_mandatory_ro_dict():
descr = make_description() descr = make_description()
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_only() await cfg.property.read_only()
prop = [] prop = []
try: try:
await cfg.value.dict() await cfg.value.dict()
except PropertiesOptionError as err: except PropertiesOptionError as err:
prop = err.proptype prop = err.proptype
assert 'mandatory' in prop assert 'mandatory' in prop
await cfg.property.read_write() await cfg.property.read_write()
await cfg.option('str1').value.set('yes') await cfg.option('str1').value.set('yes')
await cfg.option('unicode2').value.set('yes') await cfg.option('unicode2').value.set('yes')
await cfg.property.read_only() await cfg.property.read_only()
try: try:
await cfg.value.dict() await cfg.value.dict()
except PropertiesOptionError as err: except PropertiesOptionError as err:
prop = err.proptype prop = err.proptype
assert 'mandatory' in prop assert 'mandatory' in prop
await cfg.property.read_write() await cfg.property.read_write()
await cfg.option('str3').value.set(['yes']) await cfg.option('str3').value.set(['yes'])
await cfg.property.read_only() await cfg.property.read_only()
assert await cfg.value.dict() == {'str': 'abc', 'str1': 'yes', 'str3': ['yes'], 'unicode2': 'yes'} assert await cfg.value.dict() == {'str': 'abc', 'str1': 'yes', 'str3': ['yes'], 'unicode2': 'yes'}
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_mandatory_rw(): async def test_mandatory_rw():
descr = make_description() descr = make_description()
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
# not mandatory in rw # not mandatory in rw
await cfg.option('str1').value.get() await cfg.option('str1').value.get()
await cfg.option('str1').value.set('yes') await cfg.option('str1').value.set('yes')
assert await cfg.option('str1').value.get() == 'yes' assert await cfg.option('str1').value.get() == 'yes'
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_mandatory_default(): async def test_mandatory_default():
descr = make_description() descr = make_description()
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_only() await cfg.property.read_only()
#not mandatory in rw #not mandatory in rw
await cfg.option('str').value.get()
await cfg.property.read_write()
await cfg.option('str').value.set('yes')
await cfg.property.read_only()
await cfg.option('str').value.get()
await cfg.property.read_write()
await cfg.option('str').value.set(None)
await cfg.property.read_only()
prop = []
try:
await cfg.option('str').value.get() await cfg.option('str').value.get()
except PropertiesOptionError as err: await cfg.property.read_write()
prop = err.proptype await cfg.option('str').value.set('yes')
assert 'mandatory' in prop await cfg.property.read_only()
await cfg.option('str').value.get()
await cfg.property.read_write()
await cfg.option('str').value.set(None)
await cfg.property.read_only()
prop = []
try:
await cfg.option('str').value.get()
except PropertiesOptionError as err:
prop = err.proptype
assert 'mandatory' in prop
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_mandatory_delete(): async def test_mandatory_delete():
descr = make_description() descr = make_description()
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_only() await cfg.property.read_only()
await cfg.option('str').value.get() await cfg.option('str').value.get()
try: try:
await cfg.option('str1').value.get() await cfg.option('str1').value.get()
except PropertiesOptionError as err: except PropertiesOptionError as err:
prop = err.proptype prop = err.proptype
assert 'mandatory' in prop assert 'mandatory' in prop
await cfg.property.read_write() await cfg.property.read_write()
await cfg.option('str1').value.set('yes') await cfg.option('str1').value.set('yes')
await cfg.property.read_only() await cfg.property.read_only()
assert await cfg.option('str1').value.get() == 'yes' assert await cfg.option('str1').value.get() == 'yes'
await cfg.property.pop('everything_frozen') await cfg.property.pop('everything_frozen')
prop = [] prop = []
try: try:
await cfg.option('str1').value.reset() await cfg.option('str1').value.reset()
except PropertiesOptionError as err: except PropertiesOptionError as err:
prop = err.proptype prop = err.proptype
assert 'mandatory' in prop assert 'mandatory' in prop
await cfg.option('str').value.reset() await cfg.option('str').value.reset()
assert await cfg.option('str1').value.get() == 'yes' assert await cfg.option('str1').value.get() == 'yes'
assert not await list_sessions()
#valeur vide : None, '', u'', ... #valeur vide : None, '', u'', ...
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_mandatory_none(): async def test_mandatory_none():
descr = make_description() descr = make_description()
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.option('str1').value.set(None) await cfg.option('str1').value.set(None)
assert await cfg.option('str1').owner.get() == 'user' assert await cfg.option('str1').owner.get() == 'user'
await cfg.property.read_only() await cfg.property.read_only()
prop = [] prop = []
try: try:
await cfg.option('str1').value.get() await cfg.option('str1').value.get()
except PropertiesOptionError as err: except PropertiesOptionError as err:
prop = err.proptype prop = err.proptype
assert 'mandatory' in prop assert 'mandatory' in prop
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_mandatory_empty(): async def test_mandatory_empty():
descr = make_description() descr = make_description()
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.option('str1').value.set('') await cfg.option('str1').value.set('')
assert await cfg.option('str1').owner.get() == 'user' assert await cfg.option('str1').owner.get() == 'user'
await cfg.property.read_only() await cfg.property.read_only()
prop = [] prop = []
try: try:
await cfg.option('str1').value.get() await cfg.option('str1').value.get()
except PropertiesOptionError as err: except PropertiesOptionError as err:
prop = err.proptype prop = err.proptype
assert 'mandatory' in prop assert 'mandatory' in prop
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_mandatory_multi_none(): async def test_mandatory_multi_none():
descr = make_description() descr = make_description()
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.option('str3').value.set([None]) await cfg.option('str3').value.set([None])
assert await cfg.option('str3').owner.get() == 'user' assert await cfg.option('str3').owner.get() == 'user'
await cfg.property.read_only() await cfg.property.read_only()
prop = [] prop = []
try: try:
await cfg.option('str3').value.get() await cfg.option('str3').value.get()
except PropertiesOptionError as err: except PropertiesOptionError as err:
prop = err.proptype prop = err.proptype
assert 'mandatory' in prop assert 'mandatory' in prop
await cfg.property.read_write() await cfg.property.read_write()
await cfg.option('str3').value.set(['yes', None]) await cfg.option('str3').value.set(['yes', None])
assert await cfg.option('str3').owner.get() == 'user' assert await cfg.option('str3').owner.get() == 'user'
await cfg.property.read_only() await cfg.property.read_only()
prop = [] prop = []
try: try:
await cfg.option('str3').value.get() await cfg.option('str3').value.get()
except PropertiesOptionError as err: except PropertiesOptionError as err:
prop = err.proptype prop = err.proptype
assert 'mandatory' in prop assert 'mandatory' in prop
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_mandatory_multi_empty(): async def test_mandatory_multi_empty():
descr = make_description() descr = make_description()
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.option('str3').value.set([]) await cfg.option('str3').value.set([])
assert await cfg.option('str3').owner.get() == 'user' assert await cfg.option('str3').owner.get() == 'user'
await cfg.property.read_only() await cfg.property.read_only()
prop = [] prop = []
try: try:
await cfg.option('str3').value.get() await cfg.option('str3').value.get()
except PropertiesOptionError as err: except PropertiesOptionError as err:
prop = err.proptype prop = err.proptype
assert 'mandatory' in prop assert 'mandatory' in prop
# #
await cfg.property.read_write() await cfg.property.read_write()
await cfg.option('str3').value.set(['']) await cfg.option('str3').value.set([''])
assert await cfg.option('str3').owner.get() == 'user' assert await cfg.option('str3').owner.get() == 'user'
await cfg.property.read_only() await cfg.property.read_only()
prop = [] prop = []
try: try:
await cfg.option('str3').value.get() await cfg.option('str3').value.get()
except PropertiesOptionError as err: except PropertiesOptionError as err:
prop = err.proptype prop = err.proptype
assert 'mandatory' in prop assert 'mandatory' in prop
# #
await cfg.property.read_write() await cfg.property.read_write()
await cfg.option('str3').value.set(['yes', '']) await cfg.option('str3').value.set(['yes', ''])
assert await cfg.option('str3').owner.get() == 'user' assert await cfg.option('str3').owner.get() == 'user'
await cfg.property.read_only() await cfg.property.read_only()
prop = [] prop = []
try: try:
await cfg.option('str3').value.get() await cfg.option('str3').value.get()
except PropertiesOptionError as err: except PropertiesOptionError as err:
prop = err.proptype prop = err.proptype
assert 'mandatory' in prop assert 'mandatory' in prop
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_mandatory_multi_append(): async def test_mandatory_multi_append():
descr = make_description() descr = make_description()
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.option('str3').value.set(['yes']) await cfg.option('str3').value.set(['yes'])
await cfg.property.read_write() await cfg.property.read_write()
ret = await cfg.option('str3').value.get() ret = await cfg.option('str3').value.get()
ret.append(None) ret.append(None)
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_mandatory_disabled(): async def test_mandatory_disabled():
descr = make_description() descr = make_description()
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.option('str1').value.get()
await cfg.option('str1').property.add('disabled')
await cfg.property.read_only()
pop = []
try:
await cfg.option('str1').value.get() await cfg.option('str1').value.get()
except PropertiesOptionError as err: await cfg.option('str1').property.add('disabled')
prop = err.proptype await cfg.property.read_only()
search_prop = {'disabled'} pop = []
assert set(prop) == search_prop try:
await cfg.option('str1').value.get()
except PropertiesOptionError as err:
prop = err.proptype
search_prop = {'disabled'}
assert set(prop) == search_prop
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_mandatory_unicode(): async def test_mandatory_unicode():
descr = make_description() descr = make_description()
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.option('unicode2').value.get()
await cfg.property.read_only()
prop = []
try:
await cfg.option('unicode2').value.get() await cfg.option('unicode2').value.get()
except PropertiesOptionError as err: await cfg.property.read_only()
prop = err.proptype prop = []
assert 'mandatory' in prop try:
await cfg.property.read_write() await cfg.option('unicode2').value.get()
await cfg.option('unicode2').value.set(u'') except PropertiesOptionError as err:
await cfg.property.read_only() prop = err.proptype
prop = [] assert 'mandatory' in prop
try: await cfg.property.read_write()
await cfg.option('unicode2').value.get() await cfg.option('unicode2').value.set(u'')
except PropertiesOptionError as err: await cfg.property.read_only()
prop = err.proptype prop = []
assert 'mandatory' in prop try:
await cfg.option('unicode2').value.get()
except PropertiesOptionError as err:
prop = err.proptype
assert 'mandatory' in prop
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_mandatory_warnings_ro(): async def test_mandatory_warnings_ro():
descr = make_description() descr = make_description()
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.option('str').value.set('') await cfg.option('str').value.set('')
await cfg.property.read_only() await cfg.property.read_only()
proc = [] proc = []
try: try:
await cfg.option('str').value.get() await cfg.option('str').value.get()
except PropertiesOptionError as err: except PropertiesOptionError as err:
prop = err.proptype prop = err.proptype
assert 'mandatory' in prop assert 'mandatory' in prop
assert list(await cfg.value.mandatory()) == ['str', 'str1', 'unicode2', 'str3'] assert list(await cfg.value.mandatory()) == ['str', 'str1', 'unicode2', 'str3']
await cfg.property.read_write() await cfg.property.read_write()
await cfg.option('str').value.set('a') await cfg.option('str').value.set('a')
await cfg.property.read_only() await cfg.property.read_only()
assert list(await cfg.value.mandatory()) == ['str1', 'unicode2', 'str3'] assert list(await cfg.value.mandatory()) == ['str1', 'unicode2', 'str3']
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_mandatory_warnings_rw(): async def test_mandatory_warnings_rw():
descr = make_description() descr = make_description()
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.option('str').value.set('') await cfg.option('str').value.set('')
await cfg.property.read_write() await cfg.property.read_write()
await cfg.option('str').value.get() await cfg.option('str').value.get()
assert list(await cfg.value.mandatory()) == ['str', 'str1', 'unicode2', 'str3'] assert list(await cfg.value.mandatory()) == ['str', 'str1', 'unicode2', 'str3']
await cfg.option('str').value.set('a') await cfg.option('str').value.set('a')
assert list(await cfg.value.mandatory()) == ['str1', 'unicode2', 'str3'] assert list(await cfg.value.mandatory()) == ['str1', 'unicode2', 'str3']
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_mandatory_warnings_disabled(): async def test_mandatory_warnings_disabled():
descr = make_description() descr = make_description()
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.option('str').value.set('') await cfg.option('str').value.set('')
await cfg.property.read_write() await cfg.property.read_write()
await cfg.option('str').value.get() await cfg.option('str').value.get()
assert set(await cfg.value.mandatory()) == {'str', 'str1', 'unicode2', 'str3'} assert set(await cfg.value.mandatory()) == {'str', 'str1', 'unicode2', 'str3'}
await cfg.option('str').property.add('disabled') await cfg.option('str').property.add('disabled')
assert set(await cfg.value.mandatory()) == {'str1', 'unicode2', 'str3'} assert set(await cfg.value.mandatory()) == {'str1', 'unicode2', 'str3'}
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_mandatory_warnings_hidden(): async def test_mandatory_warnings_hidden():
descr = make_description() descr = make_description()
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.option('str').value.set('') await cfg.option('str').value.set('')
await cfg.property.read_write() await cfg.property.read_write()
await cfg.permissive.add('hidden') await cfg.permissive.add('hidden')
await cfg.option('str').value.get() await cfg.option('str').value.get()
assert set(await cfg.value.mandatory()) == {'str', 'str1', 'unicode2', 'str3'} assert set(await cfg.value.mandatory()) == {'str', 'str1', 'unicode2', 'str3'}
await cfg.option('str').property.add('hidden') await cfg.option('str').property.add('hidden')
assert set(await cfg.value.mandatory()) == {'str', 'str1', 'unicode2', 'str3'} assert set(await cfg.value.mandatory()) == {'str', 'str1', 'unicode2', 'str3'}
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_mandatory_warnings_frozen(): async def test_mandatory_warnings_frozen():
descr = make_description() descr = make_description()
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.option('str').value.set('') await cfg.option('str').value.set('')
await cfg.property.read_write() await cfg.property.read_write()
await cfg.option('str').value.get() await cfg.option('str').value.get()
assert set(await cfg.value.mandatory()) == {'str', 'str1', 'unicode2', 'str3'} assert set(await cfg.value.mandatory()) == {'str', 'str1', 'unicode2', 'str3'}
await cfg.option('str').property.add('frozen') await cfg.option('str').property.add('frozen')
await cfg.property.read_only() await cfg.property.read_only()
assert set(await cfg.value.mandatory()) == {'str', 'str1', 'unicode2', 'str3'} assert set(await cfg.value.mandatory()) == {'str', 'str1', 'unicode2', 'str3'}
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -397,12 +415,13 @@ async def test_mandatory_leader():
multi=True) multi=True)
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
descr = OptionDescription('o', '', [interface1]) descr = OptionDescription('o', '', [interface1])
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_only() await cfg.property.read_only()
with pytest.raises(PropertiesOptionError): with pytest.raises(PropertiesOptionError):
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get()
with pytest.raises(PropertiesOptionError): with pytest.raises(PropertiesOptionError):
await cfg.value.dict() await cfg.value.dict()
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -413,8 +432,9 @@ async def test_mandatory_warnings_leader():
multi=True) multi=True)
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
descr = OptionDescription('o', '', [interface1]) descr = OptionDescription('o', '', [interface1])
cfg = await Config(descr) async with await Config(descr) as cfg:
assert list(await cfg.value.mandatory()) == ['ip_admin_eth0.ip_admin_eth0'] assert list(await cfg.value.mandatory()) == ['ip_admin_eth0.ip_admin_eth0']
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -424,45 +444,46 @@ async def test_mandatory_leader_empty():
multi=True) multi=True)
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
descr = OptionDescription('o', '', [interface1]) descr = OptionDescription('o', '', [interface1])
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
assert await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == [] assert await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
# #
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set([undefined]) await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set([undefined])
assert await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == [None] assert await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == [None]
assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None
await cfg.property.read_only() await cfg.property.read_only()
with pytest.raises(PropertiesOptionError): with pytest.raises(PropertiesOptionError):
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get()
with pytest.raises(PropertiesOptionError): with pytest.raises(PropertiesOptionError):
await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()
await cfg.property.read_write() await cfg.property.read_write()
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.reset()
assert await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
#
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set([''])
assert await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['']
assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None
await cfg.property.read_only()
with pytest.raises(PropertiesOptionError):
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get()
with pytest.raises(PropertiesOptionError):
await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()
await cfg.property.read_write()
#
await cfg.property.read_write()
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['ip'])
await cfg.property.read_only()
assert await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['ip']
assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None
#
await cfg.property.read_write()
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['ip2'])
await cfg.property.read_only()
with pytest.raises(PropertiesOptionError):
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.reset() await cfg.option('ip_admin_eth0.ip_admin_eth0').value.reset()
await cfg.property.read_write() assert await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.reset() #
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set([''])
assert await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['']
assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None
await cfg.property.read_only()
with pytest.raises(PropertiesOptionError):
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get()
with pytest.raises(PropertiesOptionError):
await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()
await cfg.property.read_write()
#
await cfg.property.read_write()
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['ip'])
await cfg.property.read_only()
assert await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['ip']
assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None
#
await cfg.property.read_write()
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['ip2'])
await cfg.property.read_only()
with pytest.raises(PropertiesOptionError):
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.reset()
await cfg.property.read_write()
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.reset()
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -472,22 +493,23 @@ async def test_mandatory_warnings_leader_empty():
multi=True) multi=True)
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
descr = OptionDescription('o', '', [interface1]) descr = OptionDescription('o', '', [interface1])
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set([undefined]) await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set([undefined])
assert await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == [None] assert await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == [None]
assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None
assert list(await cfg.value.mandatory()) == ['ip_admin_eth0.ip_admin_eth0'] assert list(await cfg.value.mandatory()) == ['ip_admin_eth0.ip_admin_eth0']
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.reset() await cfg.option('ip_admin_eth0.ip_admin_eth0').value.reset()
# #
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['']) await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set([''])
assert await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == [''] assert await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['']
assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None
assert list(await cfg.value.mandatory()) == ['ip_admin_eth0.ip_admin_eth0'] assert list(await cfg.value.mandatory()) == ['ip_admin_eth0.ip_admin_eth0']
# #
await cfg.property.read_write() await cfg.property.read_write()
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['ip']) await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['ip'])
assert list(await cfg.value.mandatory()) == [] assert list(await cfg.value.mandatory()) == []
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -497,33 +519,34 @@ async def test_mandatory_follower():
multi=True, properties=('mandatory', )) multi=True, properties=('mandatory', ))
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
descr = OptionDescription('o', '', [interface1]) descr = OptionDescription('o', '', [interface1])
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_only() await cfg.property.read_only()
assert await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == [] assert await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
assert await cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': [], assert await cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': [],
'ip_admin_eth0.netmask_admin_eth0': []} 'ip_admin_eth0.netmask_admin_eth0': []}
# #
await cfg.property.read_write() await cfg.property.read_write()
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['ip']) await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['ip'])
await cfg.property.read_only() await cfg.property.read_only()
assert await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['ip'] assert await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['ip']
with pytest.raises(PropertiesOptionError): with pytest.raises(PropertiesOptionError):
await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()
# #
await cfg.property.read_write() await cfg.property.read_write()
await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set('') await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set('')
await cfg.property.read_only() await cfg.property.read_only()
assert await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['ip'] assert await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['ip']
with pytest.raises(PropertiesOptionError): with pytest.raises(PropertiesOptionError):
await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()
# #
await cfg.property.read_write() await cfg.property.read_write()
await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set('ip') await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set('ip')
await cfg.property.read_only() await cfg.property.read_only()
assert await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['ip'] assert await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['ip']
assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == 'ip' assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == 'ip'
assert await cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': ['ip'], assert await cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': ['ip'],
'ip_admin_eth0.netmask_admin_eth0': ['ip']} 'ip_admin_eth0.netmask_admin_eth0': ['ip']}
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -533,27 +556,29 @@ async def test_mandatory_warnings_follower():
multi=True, properties=('mandatory', )) multi=True, properties=('mandatory', ))
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
descr = OptionDescription('o', '', [interface1]) descr = OptionDescription('o', '', [interface1])
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_only() await cfg.property.read_only()
assert await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == [] assert await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
# #
await cfg.property.read_write() await cfg.property.read_write()
assert list(await cfg.value.mandatory()) == [] assert list(await cfg.value.mandatory()) == []
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['ip']) await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['ip'])
assert list(await cfg.value.mandatory()) == ['ip_admin_eth0.netmask_admin_eth0'] assert list(await cfg.value.mandatory()) == ['ip_admin_eth0.netmask_admin_eth0']
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_mandatory_warnings_symlink(): async def test_mandatory_warnings_symlink():
descr = make_description_sym() descr = make_description_sym()
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.option('str').value.set('') await cfg.option('str').value.set('')
await cfg.property.read_write() await cfg.property.read_write()
await cfg.option('str').value.get() await cfg.option('str').value.get()
assert list(await cfg.value.mandatory()) == ['str', 'str1', 'str3'] assert list(await cfg.value.mandatory()) == ['str', 'str1', 'str3']
await cfg.option('str').property.add('frozen') await cfg.option('str').property.add('frozen')
await cfg.property.read_only() await cfg.property.read_only()
assert list(await cfg.value.mandatory()) == ['str', 'str1', 'str3'] assert list(await cfg.value.mandatory()) == ['str', 'str1', 'str3']
assert not await list_sessions()
#@pytest.mark.asyncio #@pytest.mark.asyncio
@ -569,10 +594,11 @@ async def test_mandatory_warnings_symlink():
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_mandatory_warnings_validate_empty(): async def test_mandatory_warnings_validate_empty():
descr = make_description2() descr = make_description2()
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.option('str').value.set('') await cfg.option('str').value.set('')
await cfg.property.read_only() await cfg.property.read_only()
assert list(await cfg.value.mandatory()) == ['str', 'str1', 'str3'] assert list(await cfg.value.mandatory()) == ['str', 'str1', 'str3']
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -590,16 +616,17 @@ async def test_mandatory_warnings_requires():
'no_condition_is_invalid': ParamValue(True)})) 'no_condition_is_invalid': ParamValue(True)}))
stroption3 = StrOption('str3', 'Test string option', multi=True, properties=(mandatory_property,)) stroption3 = StrOption('str3', 'Test string option', multi=True, properties=(mandatory_property,))
descr = OptionDescription('tiram', '', [stroption, stroption1, stroption2, stroption3]) descr = OptionDescription('tiram', '', [stroption, stroption1, stroption2, stroption3])
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.option('str').value.set('') await cfg.option('str').value.set('')
await cfg.property.read_write() await cfg.property.read_write()
await cfg.option('str').value.get() await cfg.option('str').value.get()
assert list(await cfg.value.mandatory()) == ['str', 'str1', 'unicode2'] assert list(await cfg.value.mandatory()) == ['str', 'str1', 'unicode2']
await cfg.property.read_only() await cfg.property.read_only()
assert list(await cfg.value.mandatory()) == ['str', 'str1', 'unicode2'] assert list(await cfg.value.mandatory()) == ['str', 'str1', 'unicode2']
await cfg.property.read_write() await cfg.property.read_write()
await cfg.option('str').value.set('yes') await cfg.option('str').value.set('yes')
assert list(await cfg.value.mandatory()) == ['str1', 'unicode2', 'str3'] assert list(await cfg.value.mandatory()) == ['str1', 'unicode2', 'str3']
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -616,12 +643,13 @@ async def test_mandatory_warnings_requires_leadership():
stroption2 = StrOption('str2', 'Test string option', multi=True, properties=(mandatory_property,)) stroption2 = StrOption('str2', 'Test string option', multi=True, properties=(mandatory_property,))
leadership = Leadership('leader', 'leadership', [stroption1, stroption2]) leadership = Leadership('leader', 'leadership', [stroption1, stroption2])
descr = OptionDescription('tiram', '', [stroption, leadership]) descr = OptionDescription('tiram', '', [stroption, leadership])
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.option('str').value.set('') await cfg.option('str').value.set('')
await cfg.option('leader.str1').value.set(['str']) await cfg.option('leader.str1').value.set(['str'])
assert list(await cfg.value.mandatory()) == ['str'] assert list(await cfg.value.mandatory()) == ['str']
await cfg.option('str').value.set('yes') await cfg.option('str').value.set('yes')
assert list(await cfg.value.mandatory()) == ['leader.str2'] assert list(await cfg.value.mandatory()) == ['leader.str2']
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -637,19 +665,21 @@ async def test_mandatory_warnings_requires_leadership_follower():
stroption2 = StrOption('str2', 'Test string option', multi=True, properties=(mandatory_property,)) stroption2 = StrOption('str2', 'Test string option', multi=True, properties=(mandatory_property,))
leadership = Leadership('leader', 'leadership', [stroption, stroption1, stroption2]) leadership = Leadership('leader', 'leadership', [stroption, stroption1, stroption2])
descr = OptionDescription('tiram', '', [leadership]) descr = OptionDescription('tiram', '', [leadership])
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.option('leader.str').value.set(['str']) await cfg.option('leader.str').value.set(['str'])
assert list(await cfg.value.mandatory()) == [] assert list(await cfg.value.mandatory()) == []
await cfg.option('leader.str1', 0).value.set('yes') await cfg.option('leader.str1', 0).value.set('yes')
assert list(await cfg.value.mandatory()) == ['leader.str2'] assert list(await cfg.value.mandatory()) == ['leader.str2']
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_mandatory_od_disabled(): async def test_mandatory_od_disabled():
descr = make_description() descr = make_description()
descr = OptionDescription('od', '', [descr]) descr = OptionDescription('od', '', [descr])
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_only() await cfg.property.read_only()
assert list(await cfg.value.mandatory()) == ['tiram.str1', 'tiram.unicode2', 'tiram.str3'] assert list(await cfg.value.mandatory()) == ['tiram.str1', 'tiram.unicode2', 'tiram.str3']
await cfg.option('tiram').property.add('disabled') await cfg.option('tiram').property.add('disabled')
assert list(await cfg.value.mandatory()) == [] assert list(await cfg.value.mandatory()) == []
assert not await list_sessions()

View file

@ -9,11 +9,7 @@ from tiramisu import IntOption, StrOption, NetworkOption, NetmaskOption, BoolOpt
valid_network_netmask, valid_not_equal valid_network_netmask, valid_not_equal
from tiramisu.error import ConfigError, ConflictError, PropertiesOptionError, LeadershipError, APIError from tiramisu.error import ConfigError, ConflictError, PropertiesOptionError, LeadershipError, APIError
from tiramisu.storage import list_sessions from tiramisu.storage import list_sessions
from .config import config_type, get_config from .config import config_type, get_config, delete_sessions, event_loop
def teardown_function(function):
assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__)
owners.addowner('config') owners.addowner('config')
@ -49,14 +45,14 @@ def make_description():
async def make_metaconfig(double=False): async def make_metaconfig(double=False):
od2 = make_description() od2 = make_description()
conf1 = await Config(od2, session_id='conf1') conf1 = await Config(od2, session_id='conf1', delete_old_session=True)
await conf1.property.read_write() await conf1.property.read_write()
conf2 = await Config(od2, session_id='conf2') conf2 = await Config(od2, session_id='conf2', delete_old_session=True)
await conf2.property.read_write() await conf2.property.read_write()
meta = await MetaConfig([conf1, conf2], session_id='meta') meta = await MetaConfig([conf1, conf2], session_id='meta', delete_old_session=True)
if double: if double:
await meta.owner.set(owners.meta2) await meta.owner.set(owners.meta2)
meta = await MetaConfig([meta], session_id='doublemeta') meta = await MetaConfig([meta], session_id='doublemeta', delete_old_session=True)
await meta.property.read_write() await meta.property.read_write()
await meta.owner.set(owners.meta1) await meta.owner.set(owners.meta1)
return meta return meta
@ -65,16 +61,18 @@ async def make_metaconfig(double=False):
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_unknown_config(): async def test_unknown_config():
meta = await make_metaconfig() meta = await make_metaconfig()
with pytest.raises(ConfigError): with pytest.raises(ConfigError):
await meta.config('unknown') await meta.config('unknown')
await delete_sessions(meta)
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_error_metaconfig(): async def test_error_metaconfig():
od2 = make_description() od2 = make_description()
conf1 = await Config(od2, session_id='conf1') conf1 = await Config(od2, session_id='conf1')
with pytest.raises(TypeError): with pytest.raises(TypeError):
await MetaConfig([await GroupConfig([conf1])], session_id='meta') await MetaConfig([await GroupConfig([conf1])], session_id='meta')
await delete_sessions(conf1)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -85,6 +83,7 @@ async def test_path():
assert await ret.config.path() == 'meta.conf1' assert await ret.config.path() == 'meta.conf1'
ret = await meta.config('conf2') ret = await meta.config('conf2')
assert await ret.config.path() == 'meta.conf2' assert await ret.config.path() == 'meta.conf2'
await delete_sessions(meta)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -120,6 +119,7 @@ async def test_none():
await conf1.option('od1.i3').value.reset() await conf1.option('od1.i3').value.reset()
assert await meta.option('od1.i3').value.get() is await conf1.option('od1.i3').value.get() is await conf2.option('od1.i3').value.get() is None assert await meta.option('od1.i3').value.get() is await conf1.option('od1.i3').value.get() is await conf2.option('od1.i3').value.get() is None
assert await meta.option('od1.i3').owner.get() is await conf1.option('od1.i3').owner.get() is await conf2.option('od1.i3').owner.get() is owners.default assert await meta.option('od1.i3').owner.get() is await conf1.option('od1.i3').owner.get() is await conf2.option('od1.i3').owner.get() is owners.default
await delete_sessions(meta)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -140,6 +140,7 @@ async def test_metaconfig_reset(config_type):
assert await meta.option('od1.i2').value.get() == 1 assert await meta.option('od1.i2').value.get() == 1
assert await conf1.option('od1.i2').value.get() == 3 assert await conf1.option('od1.i2').value.get() == 3
assert await conf2.option('od1.i2').value.get() == 1 assert await conf2.option('od1.i2').value.get() == 1
await delete_sessions(meta)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -175,6 +176,7 @@ async def test_default():
await conf1.option('od1.i2').value.reset() await conf1.option('od1.i2').value.reset()
assert await meta.option('od1.i2').value.get() == await conf1.option('od1.i2').value.get() == await conf2.option('od1.i2').value.get() == 1 assert await meta.option('od1.i2').value.get() == await conf1.option('od1.i2').value.get() == await conf2.option('od1.i2').value.get() == 1
assert await meta.option('od1.i2').owner.get() is await conf1.option('od1.i2').owner.get() is await conf2.option('od1.i2').owner.get() is owners.default assert await meta.option('od1.i2').owner.get() is await conf1.option('od1.i2').owner.get() is await conf2.option('od1.i2').owner.get() is owners.default
await delete_sessions(meta)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -187,6 +189,7 @@ async def test_contexts():
assert await meta.option('od1.i2').owner.get() == owners.default assert await meta.option('od1.i2').owner.get() == owners.default
assert await conf1.option('od1.i2').value.get() == await conf1.option('od1.i2').value.get() == 6 assert await conf1.option('od1.i2').value.get() == await conf1.option('od1.i2').value.get() == 6
assert await conf1.option('od1.i2').owner.get() == await conf1.option('od1.i2').owner.get() is owners.user assert await conf1.option('od1.i2').owner.get() == await conf1.option('od1.i2').owner.get() is owners.user
await delete_sessions(meta)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -199,6 +202,7 @@ async def test_find():
assert 1 == await ret.value.get() assert 1 == await ret.value.get()
assert await meta.value.dict() == {'od1.i4': 2, 'od1.i1': None, 'od1.i3': None, assert await meta.value.dict() == {'od1.i4': 2, 'od1.i1': None, 'od1.i3': None,
'od1.i2': 1, 'od1.i5': [2]} 'od1.i2': 1, 'od1.i5': [2]}
await delete_sessions(meta)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -243,6 +247,7 @@ async def test_meta_meta():
await conf1.option('od1.i2').value.reset() await conf1.option('od1.i2').value.reset()
assert await meta.option('od1.i2').value.get() == await meta1.option('od1.i2').value.get() == await conf1.option('od1.i2').value.get() == await conf2.option('od1.i2').value.get() == 1 assert await meta.option('od1.i2').value.get() == await meta1.option('od1.i2').value.get() == await conf1.option('od1.i2').value.get() == await conf2.option('od1.i2').value.get() == 1
assert await meta.option('od1.i2').owner.get() is await meta1.option('od1.i2').owner.get() is await conf1.option('od1.i2').owner.get() is await conf2.option('od1.i2').owner.get() is owners.default assert await meta.option('od1.i2').owner.get() is await meta1.option('od1.i2').owner.get() is await conf1.option('od1.i2').owner.get() is await conf2.option('od1.i2').owner.get() is owners.default
await delete_sessions(meta)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -252,6 +257,7 @@ async def test_meta_new_config():
assert len(list(await meta.config.list())) == 2 assert len(list(await meta.config.list())) == 2
await meta.config.new('newconf1') await meta.config.new('newconf1')
assert len(list(await meta.config.list())) == 3 assert len(list(await meta.config.list())) == 3
await delete_sessions(meta)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -261,6 +267,7 @@ async def test_meta_new_config_owner():
await meta.owner.set('meta') await meta.owner.set('meta')
await meta.config.new('newconf1') await meta.config.new('newconf1')
assert await meta.owner.get() == 'meta' assert await meta.owner.get() == 'meta'
await delete_sessions(meta)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -273,7 +280,8 @@ async def test_meta_new_metaconfig():
newconf2 = await newconf1.config('newconf2') newconf2 = await newconf1.config('newconf2')
await newconf2.config.new('newconf3') await newconf2.config.new('newconf3')
newconf3 = await newconf2.config('newconf3') newconf3 = await newconf2.config('newconf3')
assert await newconf3.config.name() == 'newconf3' assert await newconf3.session.id() == 'newconf3'
await delete_sessions(meta)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -298,29 +306,32 @@ async def test_meta_pop_config():
assert await newconf1.value.dict() == {'od1.i1': None, 'od1.i2': 1, 'od1.i3': None, 'od1.i4': 2, 'od1.i5': [2], 'od1.i6': None} assert await newconf1.value.dict() == {'od1.i1': None, 'od1.i2': 1, 'od1.i3': None, 'od1.i4': 2, 'od1.i5': [2], 'od1.i6': None}
# #
assert len(list(await meta.config.list())) == 2 assert len(list(await meta.config.list())) == 2
with pytest.raises(ConfigError): with pytest.raises(ConfigError):
await meta.config.pop('newconf1') await meta.config.pop('newconf1')
await delete_sessions([meta, newconf1])
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_meta_add_config(): async def test_meta_add_config():
od = make_description() od = make_description()
od2 = make_description() od2 = make_description()
meta = await MetaConfig(['name1', 'name2'], optiondescription=od) meta = await MetaConfig(['name1', 'name2'], optiondescription=od, delete_old_session=True)
await meta.option('od1.i1').value.set(2) await meta.option('od1.i1').value.set(2)
# #
assert len(list(await meta.config.list())) == 2 assert len(list(await meta.config.list())) == 2
config = await Config(od, session_id='new') config = await Config(od, session_id='new', delete_old_session=True)
assert await config.value.dict() == {'od1.i1': None, 'od1.i2': 1, 'od1.i3': None, 'od1.i4': 2, 'od1.i5': [2], 'od1.i6': None} assert await config.value.dict() == {'od1.i1': None, 'od1.i2': 1, 'od1.i3': None, 'od1.i4': 2, 'od1.i5': [2], 'od1.i6': None}
await meta.config.add(config) await meta.config.add(config)
# #
assert len(list(await meta.config.list())) == 3 assert len(list(await meta.config.list())) == 3
assert await config.value.dict() == {'od1.i1': 2, 'od1.i2': 1, 'od1.i3': None, 'od1.i4': 2, 'od1.i5': [2], 'od1.i6': None} assert await config.value.dict() == {'od1.i1': 2, 'od1.i2': 1, 'od1.i3': None, 'od1.i4': 2, 'od1.i5': [2], 'od1.i6': None}
# #
with pytest.raises(ConflictError): with pytest.raises(ConflictError):
await meta.config.add(config) await meta.config.add(config)
with pytest.raises(ValueError): newconfig = await Config(od2)
await meta.config.add(await Config(od2)) with pytest.raises(ValueError):
await meta.config.add(newconfig)
await delete_sessions([meta, newconfig])
@pytest.mark.asyncio @pytest.mark.asyncio
@ -333,6 +344,7 @@ async def test_meta_add_config_readd():
await meta.config.add(config) await meta.config.add(config)
await meta2.config.add(config) await meta2.config.add(config)
assert len(list(await config.config.parents())) == 2 assert len(list(await config.config.parents())) == 2
await delete_sessions([meta, meta2])
@pytest.mark.asyncio @pytest.mark.asyncio
@ -340,9 +352,10 @@ async def test_meta_new_config_wrong_name():
od = make_description() od = make_description()
meta = await MetaConfig(['name1', 'name2'], optiondescription=od) meta = await MetaConfig(['name1', 'name2'], optiondescription=od)
assert len(list(await meta.config.list())) == 2 assert len(list(await meta.config.list())) == 2
with pytest.raises(ConflictError): with pytest.raises(ConflictError):
await meta.config.new('name1') await meta.config.new('name1')
assert len(list(await meta.config.list())) == 2 assert len(list(await meta.config.list())) == 2
await delete_sessions(meta)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -382,18 +395,19 @@ async def test_meta_meta_set():
dconfigs.append(conf._config_bag.context) dconfigs.append(conf._config_bag.context)
assert [conf1._config_bag.context, conf2._config_bag.context] == dconfigs assert [conf1._config_bag.context, conf2._config_bag.context] == dconfigs
# #
with pytest.raises(AttributeError): with pytest.raises(AttributeError):
await meta.config.find('i1', value=10) await meta.config.find('i1', value=10)
with pytest.raises(AttributeError): with pytest.raises(AttributeError):
await meta.config.find('not', value=10) await meta.config.find('not', value=10)
with pytest.raises(AttributeError): with pytest.raises(AttributeError):
await meta.config.find('i6') await meta.config.find('i6')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await meta.value.set('od1.i6', 7, only_config=True, force_default=True) await meta.value.set('od1.i6', 7, only_config=True, force_default=True)
with pytest.raises(ValueError): with pytest.raises(ValueError):
await meta.value.set('od1.i6', 7, only_config=True, force_default_if_same=True) await meta.value.set('od1.i6', 7, only_config=True, force_default_if_same=True)
with pytest.raises(ValueError): with pytest.raises(ValueError):
await meta.value.set('od1.i6', 7, only_config=True, force_dont_change_value=True) await meta.value.set('od1.i6', 7, only_config=True, force_dont_change_value=True)
await delete_sessions(meta)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -405,15 +419,15 @@ async def test_not_meta():
conf2 = await Config(od2, session_id='conf2') conf2 = await Config(od2, session_id='conf2')
conf3 = await Config(od2) conf3 = await Config(od2)
conf4 = await Config(od2, session_id='conf4') conf4 = await Config(od2, session_id='conf4')
with pytest.raises(TypeError): with pytest.raises(TypeError):
await GroupConfig(conf1) await GroupConfig(conf1)
#same name #same name
#with pytest.raises(ConflictError): #with pytest.raises(ConflictError):
# GroupConfig([conf2, conf4], session_id='conf2')") # GroupConfig([conf2, conf4], session_id='conf2')")
with pytest.raises(ConflictError): with pytest.raises(ConflictError):
await GroupConfig([conf2, conf2], session_id='conf8') await GroupConfig([conf2, conf2], session_id='conf8')
grp = await GroupConfig([conf1, conf2]) grp = await GroupConfig([conf1, conf2])
with pytest.raises(APIError): with pytest.raises(APIError):
await grp.option('od1.i1').value.get() await grp.option('od1.i1').value.get()
conf1, conf2 = await grp.config.list() conf1, conf2 = await grp.config.list()
errors = await grp.value.set('od1.i1', 7) errors = await grp.value.set('od1.i1', 7)
@ -424,6 +438,7 @@ async def test_not_meta():
assert await conf1.option('od1.i1').owner.get() is await conf2.option('od1.i1').owner.get() is owners.user assert await conf1.option('od1.i1').owner.get() is await conf2.option('od1.i1').owner.get() is owners.user
await grp.option('od1.i1').value.reset() await grp.option('od1.i1').value.reset()
assert await conf1.option('od1.i1').owner.get() is await conf2.option('od1.i1').owner.get() is owners.default assert await conf1.option('od1.i1').owner.get() is await conf2.option('od1.i1').owner.get() is owners.default
await delete_sessions([conf1, conf2, conf3, conf4])
@pytest.mark.asyncio @pytest.mark.asyncio
@ -438,6 +453,7 @@ async def test_group_find_firsts():
newconf1, newconf2 = await grp.config.list() newconf1, newconf2 = await grp.config.list()
conf1._config_bag.context == newconf1._config_bag.context conf1._config_bag.context == newconf1._config_bag.context
conf2._config_bag.context == newconf2._config_bag.context conf2._config_bag.context == newconf2._config_bag.context
await delete_sessions([conf1, conf2])
@pytest.mark.asyncio @pytest.mark.asyncio
@ -454,6 +470,7 @@ async def test_group_group():
conf9 = await grp2.config('grp.conf9') conf9 = await grp2.config('grp.conf9')
assert await conf9.option('od1.i1').value.get() == 2 assert await conf9.option('od1.i1').value.get() == 2
assert await conf9.option('od1.i1').owner.get() is owners.user assert await conf9.option('od1.i1').owner.get() is owners.user
await delete_sessions([conf1, conf2, conf9])
@pytest.mark.asyncio @pytest.mark.asyncio
@ -472,6 +489,7 @@ async def test_group_group_path():
assert await newgrp.config.path() == 'conf9' assert await newgrp.config.path() == 'conf9'
newgrp = await grp2.config('grp.conf10') newgrp = await grp2.config('grp.conf10')
assert await newgrp.config.path() == 'conf10' assert await newgrp.config.path() == 'conf10'
await delete_sessions([conf1, conf2])
@pytest.mark.asyncio @pytest.mark.asyncio
@ -490,7 +508,7 @@ async def test_meta_unconsistent():
conf4 = await Config(od3, session_id='conf4') conf4 = await Config(od3, session_id='conf4')
meta = await MetaConfig([conf1, conf2]) meta = await MetaConfig([conf1, conf2])
await meta.owner.set(owners.meta1) await meta.owner.set(owners.meta1)
with pytest.raises(TypeError): with pytest.raises(TypeError):
await MetaConfig("string") await MetaConfig("string")
#same descr but conf1 already in meta #same descr but conf1 already in meta
assert len(list(await conf1.config.parents())) == 1 assert len(list(await conf1.config.parents())) == 1
@ -499,8 +517,9 @@ async def test_meta_unconsistent():
assert len(list(await conf1.config.parents())) == 2 assert len(list(await conf1.config.parents())) == 2
assert len(list(await conf3.config.parents())) == 1 assert len(list(await conf3.config.parents())) == 1
#not same descr #not same descr
with pytest.raises(ValueError): with pytest.raises(ValueError):
await MetaConfig([conf3, conf4]) await MetaConfig([conf3, conf4])
await delete_sessions([meta, new_meta, conf4])
@pytest.mark.asyncio @pytest.mark.asyncio
@ -524,7 +543,7 @@ async def test_meta_leadership():
assert conf1._config_bag.context == configs[0]._config_bag.context assert conf1._config_bag.context == configs[0]._config_bag.context
assert conf2._config_bag.context == configs[1]._config_bag.context assert conf2._config_bag.context == configs[1]._config_bag.context
await meta.property.read_write() await meta.property.read_write()
with pytest.raises(AttributeError): with pytest.raises(AttributeError):
await meta.config.find('netmask_admin_eth0') await meta.config.find('netmask_admin_eth0')
ret = await meta.unrestraint.config.find('netmask_admin_eth0') ret = await meta.unrestraint.config.find('netmask_admin_eth0')
configs = await ret.config.list() configs = await ret.config.list()
@ -535,6 +554,7 @@ async def test_meta_leadership():
configs = await ret.config.list() configs = await ret.config.list()
assert conf1._config_bag.context == configs[0]._config_bag.context assert conf1._config_bag.context == configs[0]._config_bag.context
assert conf2._config_bag.context == configs[1]._config_bag.context assert conf2._config_bag.context == configs[1]._config_bag.context
await delete_sessions(meta)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -548,7 +568,7 @@ async def test_meta_leadership_value():
meta = await MetaConfig([conf1, conf2], session_id="meta") meta = await MetaConfig([conf1, conf2], session_id="meta")
await conf1.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.8']) await conf1.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.8'])
assert await conf1.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None assert await conf1.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None
with pytest.raises(APIError): with pytest.raises(APIError):
await conf1.option('ip_admin_eth0.ip_admin_eth0', 0).value.get() await conf1.option('ip_admin_eth0.ip_admin_eth0', 0).value.get()
# #
await conf1.option('ip_admin_eth0.ip_admin_eth0').value.reset() await conf1.option('ip_admin_eth0.ip_admin_eth0').value.reset()
@ -568,7 +588,7 @@ async def test_meta_leadership_value():
# #
assert await conf1.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.1'] assert await conf1.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.1']
assert await conf1.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == '255.255.0.0' assert await conf1.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == '255.255.0.0'
await delete_sessions(meta)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -594,6 +614,7 @@ async def test_meta_leadership_value_default():
# #
await newconf1.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1']) await newconf1.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1'])
assert await newconf1.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == '255.255.0.0' assert await newconf1.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == '255.255.0.0'
await delete_sessions(meta)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -608,7 +629,7 @@ async def test_meta_leadership_owners():
await meta.owner.set(owners.meta1) await meta.owner.set(owners.meta1)
newconf1 = await meta.config('conf1') newconf1 = await meta.config('conf1')
assert await newconf1.option('ip_admin_eth0.ip_admin_eth0').owner.isdefault() assert await newconf1.option('ip_admin_eth0.ip_admin_eth0').owner.isdefault()
with pytest.raises(LeadershipError): with pytest.raises(LeadershipError):
await newconf1.option('ip_admin_eth0.netmask_admin_eth0', 0).owner.isdefault() await newconf1.option('ip_admin_eth0.netmask_admin_eth0', 0).owner.isdefault()
# #
await newconf1.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1']) await newconf1.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1'])
@ -633,6 +654,7 @@ async def test_meta_leadership_owners():
await newconf1.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1']) await newconf1.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1'])
assert await newconf1.option('ip_admin_eth0.ip_admin_eth0').owner.get() == owners.user assert await newconf1.option('ip_admin_eth0.ip_admin_eth0').owner.get() == owners.user
assert await newconf1.option('ip_admin_eth0.netmask_admin_eth0', 0).owner.get() == owners.meta1 assert await newconf1.option('ip_admin_eth0.netmask_admin_eth0', 0).owner.get() == owners.meta1
await delete_sessions(meta)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -674,6 +696,7 @@ async def test_meta_force_default():
assert await meta.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.4'] assert await meta.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.4']
assert await newconf1.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.4'] assert await newconf1.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.4']
assert await newconf2.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.4'] assert await newconf2.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.4']
await delete_sessions(meta)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -704,6 +727,7 @@ async def test_meta_force_dont_change_value():
assert await newconf2.option('ip_admin_eth0.ip_admin_eth0').value.get() == [] assert await newconf2.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
assert await newconf1.option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user assert await newconf1.option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user
assert await newconf2.option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user assert await newconf2.option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user
await delete_sessions(meta)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -749,6 +773,7 @@ async def test_meta_force_default_if_same():
assert await newconf2.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.5'] assert await newconf2.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.5']
assert await newconf1.option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user assert await newconf1.option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user
assert await newconf2.option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.meta1 assert await newconf2.option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.meta1
await delete_sessions(meta)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -794,6 +819,7 @@ async def test_meta_force_default_if_same_and_dont_change():
assert await newconf2.option('ip_admin_eth0.ip_admin_eth0').value.get() == [] assert await newconf2.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
assert await newconf1.option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user assert await newconf1.option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user
assert await newconf2.option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user assert await newconf2.option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user
await delete_sessions(meta)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -807,8 +833,9 @@ async def test_meta_force_default_and_dont_change():
meta = await MetaConfig([conf1, conf2]) meta = await MetaConfig([conf1, conf2])
await meta.property.read_write() await meta.property.read_write()
await meta.owner.set('meta1') await meta.owner.set('meta1')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await meta.value.set('ip_admin_eth0.ip_admin_eth0', ['192.168.1.4'], force_default=True, force_dont_change_value=True) await meta.value.set('ip_admin_eth0.ip_admin_eth0', ['192.168.1.4'], force_default=True, force_dont_change_value=True)
await delete_sessions(meta)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -825,6 +852,7 @@ async def test_meta_properties_meta():
await meta.property.read_write() await meta.property.read_write()
ret = await meta.config('conf1') ret = await meta.config('conf1')
assert await ret.value.dict() == {} assert await ret.value.dict() == {}
await delete_sessions(meta)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -837,8 +865,9 @@ async def test_meta_exception_meta():
conf2 = await Config(od, session_id='conf2') conf2 = await Config(od, session_id='conf2')
meta = await MetaConfig([conf1, conf2]) meta = await MetaConfig([conf1, conf2])
await meta.property.read_write() await meta.property.read_write()
with pytest.raises(Exception): with pytest.raises(Exception):
await conf1.make_dict() await conf1.make_dict()
await delete_sessions(meta)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -859,6 +888,7 @@ async def test_meta_properties_requires1():
await meta.option('opt1').value.set(True) await meta.option('opt1').value.set(True)
# #
await conf1.option('od2.opt2').value.set(False) await conf1.option('od2.opt2').value.set(False)
await delete_sessions(meta)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -884,6 +914,7 @@ async def test_meta_properties_requires_mandatory():
await conf1.option('eth0_method').value.set('dhcp') await conf1.option('eth0_method').value.set('dhcp')
await conf1.property.read_only() await conf1.property.read_only()
assert await conf1.value.dict(fullpath=True) == {'probes': True, 'eth0_method': 'dhcp', 'ip_address': '1.1.1.1', 'ip_eth0': '1.1.1.1', 'ip_gw': '1.1.1.2'} assert await conf1.value.dict(fullpath=True) == {'probes': True, 'eth0_method': 'dhcp', 'ip_address': '1.1.1.1', 'ip_eth0': '1.1.1.1', 'ip_gw': '1.1.1.2'}
await delete_sessions(meta)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -910,6 +941,7 @@ async def test_meta_callback():
await meta.option('val4').value.set('new1') await meta.option('val4').value.set('new1')
assert await newcfg.value.dict() == {'val3': 'yes', 'val2': 'new', 'val1': 'new', 'val5': 'yes', 'val4': 'new1'} assert await newcfg.value.dict() == {'val3': 'yes', 'val2': 'new', 'val1': 'new', 'val5': 'yes', 'val4': 'new1'}
await meta.option('val4').value.reset() await meta.option('val4').value.reset()
await delete_sessions(meta)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -969,6 +1001,7 @@ async def test_meta_callback_follower():
await meta.option('val1.val1').value.pop(1) await meta.option('val1.val1').value.pop(1)
await meta.option('val1.val1').value.set(['val4']) await meta.option('val1.val1').value.set(['val4'])
assert await conf1.value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val4'], 'val1.val3': ['val4'], 'val': 'val'} assert await conf1.value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val4'], 'val1.val3': ['val4'], 'val': 'val'}
await delete_sessions(meta)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -1000,6 +1033,7 @@ async def test_meta_reset():
assert await meta.option('ip_admin_eth0.ip_admin_eth0').value.get() == [] assert await meta.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
assert await newconf1.option('ip_admin_eth0.ip_admin_eth0').value.get() == [] assert await newconf1.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
assert await newconf2.option('ip_admin_eth0.ip_admin_eth0').value.get() == [] assert await newconf2.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
await delete_sessions(meta)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -1019,11 +1053,11 @@ async def test_meta_properties_meta_copy():
conf3 = await newconf1.config.copy(session_id='conf3') conf3 = await newconf1.config.copy(session_id='conf3')
# old fashion # old fashion
meta2 = await conf3.config.metaconfig() meta2 = await conf3.config.metaconfig()
assert await meta.config.name() == await meta2.config.name() assert await meta.session.id() == await meta2.session.id()
# new method # new method
meta2 = list(await conf3.config.parents()) meta2 = list(await conf3.config.parents())
assert len(meta2) == 1 assert len(meta2) == 1
assert await meta.config.name() == await meta2[0].config.name() assert await meta.session.id() == await meta2[0].session.id()
assert await newconf1.value.dict() == {'ip_admin_eth0': ['192.168.1.1']} assert await newconf1.value.dict() == {'ip_admin_eth0': ['192.168.1.1']}
assert await newconf2.value.dict() == {'ip_admin_eth0': ['192.168.1.1']} assert await newconf2.value.dict() == {'ip_admin_eth0': ['192.168.1.1']}
@ -1037,6 +1071,7 @@ async def test_meta_properties_meta_copy():
assert await newconf1.value.dict() == {'ip_admin_eth0': ['192.168.1.3']} assert await newconf1.value.dict() == {'ip_admin_eth0': ['192.168.1.3']}
assert await newconf2.value.dict() == {'ip_admin_eth0': ['192.168.1.3']} assert await newconf2.value.dict() == {'ip_admin_eth0': ['192.168.1.3']}
assert await newconf3.value.dict() == {'ip_admin_eth0': ['192.168.1.3']} assert await newconf3.value.dict() == {'ip_admin_eth0': ['192.168.1.3']}
await delete_sessions(meta)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -1071,6 +1106,7 @@ async def test_meta_properties_meta_deepcopy():
assert await newconf1.value.dict() == {'ip_admin_eth0': ['192.168.1.3']} assert await newconf1.value.dict() == {'ip_admin_eth0': ['192.168.1.3']}
assert await newconf2.value.dict() == {'ip_admin_eth0': ['192.168.1.3']} assert await newconf2.value.dict() == {'ip_admin_eth0': ['192.168.1.3']}
assert await newconf3.value.dict() == {'ip_admin_eth0': ['192.168.1.1']} assert await newconf3.value.dict() == {'ip_admin_eth0': ['192.168.1.1']}
await delete_sessions([meta, meta2])
@pytest.mark.asyncio @pytest.mark.asyncio
@ -1085,11 +1121,12 @@ async def test_meta_properties_submeta_deepcopy():
meta2 = await MetaConfig([meta1], session_id='meta2') meta2 = await MetaConfig([meta1], session_id='meta2')
meta_copy = await conf1.config.deepcopy(session_id='conf2', meta_copy = await conf1.config.deepcopy(session_id='conf2',
metaconfig_prefix='copy_') metaconfig_prefix='copy_')
assert await meta_copy.config.name() == 'copy_meta2' assert await meta_copy.session.id() == 'copy_meta2'
newcopy = await meta_copy.config('copy_meta1') newcopy = await meta_copy.config('copy_meta1')
assert await newcopy.config.name() == 'copy_meta1' assert await newcopy.session.id() == 'copy_meta1'
newcopy = await newcopy.config('conf2') newcopy = await newcopy.config('conf2')
assert await newcopy.config.name() == 'conf2' assert await newcopy.session.id() == 'conf2'
await delete_sessions([meta2, meta_copy])
@pytest.mark.asyncio @pytest.mark.asyncio
@ -1104,10 +1141,11 @@ async def test_meta_properties_deepcopy_meta():
meta2 = await MetaConfig([meta1], session_id='meta2') meta2 = await MetaConfig([meta1], session_id='meta2')
meta_copy = await meta1.config.deepcopy(session_id='meta3', meta_copy = await meta1.config.deepcopy(session_id='meta3',
metaconfig_prefix='copy_') metaconfig_prefix='copy_')
assert await meta_copy.config.name() == 'copy_meta2' assert await meta_copy.session.id() == 'copy_meta2'
newcopy = await meta_copy.config('meta3') newcopy = await meta_copy.config('meta3')
assert await newcopy.config.name() == 'meta3' assert await newcopy.session.id() == 'meta3'
assert list(await newcopy.config.list()) == [] assert list(await newcopy.config.list()) == []
await delete_sessions([meta2, meta_copy])
@pytest.mark.asyncio @pytest.mark.asyncio
@ -1149,6 +1187,7 @@ async def test_meta_properties_submeta_deepcopy_owner():
assert await conf2.option('netmask_admin_eth0').owner.get() == 'conf2_user' assert await conf2.option('netmask_admin_eth0').owner.get() == 'conf2_user'
assert await conf2.option('ip_admin_eth0').value.get() == '192.168.0.1' assert await conf2.option('ip_admin_eth0').value.get() == '192.168.0.1'
assert await conf2.option('ip_admin_eth0').owner.get() == 'conf1_user' assert await conf2.option('ip_admin_eth0').owner.get() == 'conf1_user'
await delete_sessions([meta1, meta2, conf2, meta2_copy])
@pytest.mark.asyncio @pytest.mark.asyncio
@ -1212,6 +1251,7 @@ async def test_meta_properties_meta_set_value():
assert isinstance(ret[0], ValueError) assert isinstance(ret[0], ValueError)
del ret[0] del ret[0]
del ret del ret
await delete_sessions(meta)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -1251,6 +1291,7 @@ async def test_metaconfig_force_metaconfig_on_freeze():
await cfg.option('dummy1').property.pop('frozen') await cfg.option('dummy1').property.pop('frozen')
assert await cfg.option('dummy1').value.get() == 'cfg' assert await cfg.option('dummy1').value.get() == 'cfg'
assert await cfg.option('dummy1').owner.get() == 'config' assert await cfg.option('dummy1').owner.get() == 'config'
await delete_sessions([meta1, meta2])
@pytest.mark.asyncio @pytest.mark.asyncio
@ -1318,6 +1359,7 @@ async def test_metaconfig_force_metaconfig_on_freeze_option():
await cfg.option('dummy1').property.pop('frozen') await cfg.option('dummy1').property.pop('frozen')
assert await cfg.option('dummy1').value.get() == 'cfg' assert await cfg.option('dummy1').value.get() == 'cfg'
assert await cfg.option('dummy1').owner.get() == 'config' assert await cfg.option('dummy1').owner.get() == 'config'
await delete_sessions([meta1, meta2])
@pytest.mark.asyncio @pytest.mark.asyncio
@ -1327,5 +1369,6 @@ async def test_meta_get_config():
await meta.config.new('meta1', type='metaconfig') await meta.config.new('meta1', type='metaconfig')
assert isinstance(await meta.config.get('meta1'), MetaConfig) assert isinstance(await meta.config.get('meta1'), MetaConfig)
assert isinstance(await meta.config.get('name1'), Config) assert isinstance(await meta.config.get('name1'), Config)
with pytest.raises(ConfigError): with pytest.raises(ConfigError):
await meta.config.get('unknown') await meta.config.get('unknown')
await delete_sessions(meta)

View file

@ -7,18 +7,15 @@ from tiramisu.setting import groups, owners
from tiramisu import IntOption, StrOption, NetworkOption, NetmaskOption, \ from tiramisu import IntOption, StrOption, NetworkOption, NetmaskOption, \
OptionDescription, Leadership, Config, GroupConfig, MixConfig, \ OptionDescription, Leadership, Config, GroupConfig, MixConfig, \
MetaConfig, Params, ParamOption, ParamValue, ParamSelfOption, Calculation, \ MetaConfig, Params, ParamOption, ParamValue, ParamSelfOption, Calculation, \
valid_network_netmask valid_network_netmask, delete_session
from tiramisu.error import ConfigError, ConflictError, PropertiesOptionError, LeadershipError, APIError from tiramisu.error import ConfigError, ConflictError, PropertiesOptionError, LeadershipError, APIError
from tiramisu.storage import list_sessions from tiramisu.storage import list_sessions
from .config import delete_sessions, event_loop
owners.addowner('mix1') owners.addowner('mix1')
owners.addowner('mix2') owners.addowner('mix2')
def teardown_function(function):
assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__)
def return_value(value=None): def return_value(value=None):
return value return value
@ -79,11 +76,11 @@ async def make_mixconfig(double=False):
od1 = make_description() od1 = make_description()
od2 = make_description1() od2 = make_description1()
od3 = make_description2() od3 = make_description2()
conf1 = await Config(od1, session_id='conf1') conf1 = await Config(od1, session_id='conf1', delete_old_session=True)
await conf1.property.read_write() await conf1.property.read_write()
conf2 = await Config(od2, session_id='conf2') conf2 = await Config(od2, session_id='conf2', delete_old_session=True)
await conf2.property.read_write() await conf2.property.read_write()
mix = await MixConfig(od3, [conf1, conf2], session_id='mix') mix = await MixConfig(od3, [conf1, conf2], session_id='mix', delete_old_session=True)
if double: if double:
od4 = make_description3() od4 = make_description3()
await mix.owner.set(owners.mix2) await mix.owner.set(owners.mix2)
@ -103,6 +100,7 @@ async def test_mix_name():
assert await ret.config.path() == 'doublemix.mix.conf1' assert await ret.config.path() == 'doublemix.mix.conf1'
ret = await mix.config('mix.conf2') ret = await mix.config('mix.conf2')
assert await ret.config.path() == 'doublemix.mix.conf2' assert await ret.config.path() == 'doublemix.mix.conf2'
await delete_sessions(mix)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -110,17 +108,20 @@ async def test_mix_not_group():
i1 = IntOption('i1', '') i1 = IntOption('i1', '')
od1 = OptionDescription('od1', '', [i1]) od1 = OptionDescription('od1', '', [i1])
od2 = OptionDescription('od2', '', [od1]) od2 = OptionDescription('od2', '', [od1])
conf1 = await Config(od2, session_id='conf1') async with await Config(od2, session_id='conf1') as conf1:
grp = await GroupConfig([conf1]) grp = await GroupConfig([conf1])
with pytest.raises(TypeError): with pytest.raises(TypeError):
await MixConfig(od2, [grp]) await MixConfig(od2, [grp], session_id='error')
await delete_session('error')
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_unknown_config(): async def test_unknown_config():
mix = await make_mixconfig() mix = await make_mixconfig()
with pytest.raises(ConfigError): with pytest.raises(ConfigError):
await mix.config('unknown') await mix.config('unknown')
await delete_sessions(mix)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -157,7 +158,8 @@ async def test_none():
assert await mix.option('od1.i3').value.get() is await newconf1.option('od1.i3').value.get() is await newconf2.option('od1.i3').value.get() is None assert await mix.option('od1.i3').value.get() is await newconf1.option('od1.i3').value.get() is await newconf2.option('od1.i3').value.get() is None
assert await mix.option('od1.i3').owner.get() is await newconf1.option('od1.i3').owner.get() is await newconf2.option('od1.i3').owner.get() is owners.default assert await mix.option('od1.i3').owner.get() is await newconf1.option('od1.i3').owner.get() is await newconf2.option('od1.i3').owner.get() is owners.default
# #
assert await mix.config.name() == await mix.config.name() assert await mix.session.id() == await mix.session.id()
await delete_sessions(mix)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -175,6 +177,7 @@ async def test_reset():
assert await mix.option('od1.i2').value.get() == 1 assert await mix.option('od1.i2').value.get() == 1
assert await newconf1.option('od1.i2').value.get() == 3 assert await newconf1.option('od1.i2').value.get() == 3
assert await newconf2.option('od1.i2').value.get() == 1 assert await newconf2.option('od1.i2').value.get() == 1
await delete_sessions(mix)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -210,6 +213,7 @@ async def test_default():
await newconf1.option('od1.i2').value.reset() await newconf1.option('od1.i2').value.reset()
assert await mix.option('od1.i2').value.get() == await newconf1.option('od1.i2').value.get() == await newconf2.option('od1.i2').value.get() == 1 assert await mix.option('od1.i2').value.get() == await newconf1.option('od1.i2').value.get() == await newconf2.option('od1.i2').value.get() == 1
assert await mix.option('od1.i2').owner.get() is await newconf1.option('od1.i2').owner.get() is await newconf2.option('od1.i2').owner.get() is owners.default assert await mix.option('od1.i2').owner.get() is await newconf1.option('od1.i2').owner.get() is await newconf2.option('od1.i2').owner.get() is owners.default
await delete_sessions(mix)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -222,6 +226,8 @@ async def test_contexts():
assert await newconf1.option('od1.i2').value.get() == await newconf1.option('od1.i2').value.get() == 6 assert await newconf1.option('od1.i2').value.get() == await newconf1.option('od1.i2').value.get() == 6
assert await newconf1.option('od1.i2').owner.get() == await newconf1.option('od1.i2').owner.get() is owners.user assert await newconf1.option('od1.i2').owner.get() == await newconf1.option('od1.i2').owner.get() is owners.user
assert len(errors) == 0 assert len(errors) == 0
await delete_sessions(mix)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -234,6 +240,7 @@ async def test_find():
assert 1 == await ret.value.get() assert 1 == await ret.value.get()
assert await mix.value.dict() == {'od1.i4': 2, 'od1.i1': None, 'od1.i3': None, assert await mix.value.dict() == {'od1.i4': 2, 'od1.i1': None, 'od1.i3': None,
'od1.i2': 1, 'od1.i5': [2]} 'od1.i2': 1, 'od1.i5': [2]}
await delete_sessions(mix)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -278,6 +285,7 @@ async def test_mix_mix():
await newconf1.option('od1.i2').value.reset() await newconf1.option('od1.i2').value.reset()
assert await mix.option('od1.i2').value.get() == await newmix.option('od1.i2').value.get() == await newconf1.option('od1.i2').value.get() == await newconf2.option('od1.i2').value.get() == 1 assert await mix.option('od1.i2').value.get() == await newmix.option('od1.i2').value.get() == await newconf1.option('od1.i2').value.get() == await newconf2.option('od1.i2').value.get() == 1
assert await mix.option('od1.i2').owner.get() is await newmix.option('od1.i2').owner.get() is await newconf1.option('od1.i2').owner.get() is await newconf2.option('od1.i2').owner.get() is owners.default assert await mix.option('od1.i2').owner.get() is await newmix.option('od1.i2').owner.get() is await newconf1.option('od1.i2').owner.get() is await newconf2.option('od1.i2').owner.get() is owners.default
await delete_sessions(mix)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -318,18 +326,19 @@ async def test_mix_mix_set():
dconfigs.append(conf._config_bag.context) dconfigs.append(conf._config_bag.context)
assert [conf1, conf2] == dconfigs assert [conf1, conf2] == dconfigs
# #
with pytest.raises(AttributeError): with pytest.raises(AttributeError):
await mix.config.find('i1', value=10) await mix.config.find('i1', value=10)
with pytest.raises(AttributeError): with pytest.raises(AttributeError):
await mix.config.find('not', value=10) await mix.config.find('not', value=10)
with pytest.raises(AttributeError): with pytest.raises(AttributeError):
await mix.config.find('i6') await mix.config.find('i6')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await mix.value.set('od1.i6', 7, only_config=True, force_default=True) await mix.value.set('od1.i6', 7, only_config=True, force_default=True)
with pytest.raises(ValueError): with pytest.raises(ValueError):
await mix.value.set('od1.i6', 7, only_config=True, force_default_if_same=True) await mix.value.set('od1.i6', 7, only_config=True, force_default_if_same=True)
with pytest.raises(ValueError): with pytest.raises(ValueError):
await mix.value.set('od1.i6', 7, only_config=True, force_dont_change_value=True) await mix.value.set('od1.i6', 7, only_config=True, force_dont_change_value=True)
await delete_sessions(mix)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -349,8 +358,9 @@ async def test_mix_unconsistent():
conf4 = await Config(od4, session_id='conf4') conf4 = await Config(od4, session_id='conf4')
mix = await MixConfig(od2, [conf1, conf2]) mix = await MixConfig(od2, [conf1, conf2])
await mix.owner.set(owners.mix1) await mix.owner.set(owners.mix1)
with pytest.raises(TypeError): with pytest.raises(TypeError):
await MixConfig(od2, "string") await MixConfig(od2, "string", session_id='error')
await delete_session('error')
# same descr but conf1 already in mix # same descr but conf1 already in mix
assert len(list(await conf1.config.parents())) == 1 assert len(list(await conf1.config.parents())) == 1
assert len(list(await conf3.config.parents())) == 0 assert len(list(await conf3.config.parents())) == 0
@ -358,7 +368,8 @@ async def test_mix_unconsistent():
assert len(list(await conf1.config.parents())) == 2 assert len(list(await conf1.config.parents())) == 2
assert len(list(await conf3.config.parents())) == 1 assert len(list(await conf3.config.parents())) == 1
# not same descr # not same descr
await MixConfig(od2, [conf3, conf4]) tmix = await MixConfig(od2, [conf3, conf4])
await delete_sessions([mix, conf3, conf4, tmix, new_mix])
@pytest.mark.asyncio @pytest.mark.asyncio
@ -382,7 +393,7 @@ async def test_mix_leadership():
assert conf1._config_bag.context == configs[0]._config_bag.context assert conf1._config_bag.context == configs[0]._config_bag.context
assert conf2._config_bag.context == configs[1]._config_bag.context assert conf2._config_bag.context == configs[1]._config_bag.context
await mix.property.read_write() await mix.property.read_write()
with pytest.raises(AttributeError): with pytest.raises(AttributeError):
await mix.config.find('netmask_admin_eth0') await mix.config.find('netmask_admin_eth0')
ret = await mix.unrestraint.config.find('netmask_admin_eth0') ret = await mix.unrestraint.config.find('netmask_admin_eth0')
configs = await ret.config.list() configs = await ret.config.list()
@ -395,6 +406,7 @@ async def test_mix_leadership():
assert len(configs) == 2 assert len(configs) == 2
assert conf1._config_bag.context == configs[0]._config_bag.context assert conf1._config_bag.context == configs[0]._config_bag.context
assert conf2._config_bag.context == configs[1]._config_bag.context assert conf2._config_bag.context == configs[1]._config_bag.context
await delete_sessions(mix)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -422,6 +434,7 @@ async def test_mix_leadership_value2():
# #
await newconf1.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1']) await newconf1.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1'])
assert await newconf1.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == '255.255.0.0' assert await newconf1.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == '255.255.0.0'
await delete_sessions(mix)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -447,6 +460,7 @@ async def test_mix_leadership_value_default():
# #
await newconf1.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1']) await newconf1.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1'])
assert await newconf1.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == '255.255.0.0' assert await newconf1.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == '255.255.0.0'
await delete_sessions(mix)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -461,7 +475,7 @@ async def test_mix_leadership_owners():
await mix.owner.set(owners.mix1) await mix.owner.set(owners.mix1)
newconf1 = await mix.config('conf1') newconf1 = await mix.config('conf1')
assert await newconf1.option('ip_admin_eth0.ip_admin_eth0').owner.isdefault() assert await newconf1.option('ip_admin_eth0.ip_admin_eth0').owner.isdefault()
with pytest.raises(LeadershipError): with pytest.raises(LeadershipError):
await newconf1.option('ip_admin_eth0.netmask_admin_eth0', 0).owner.isdefault() await newconf1.option('ip_admin_eth0.netmask_admin_eth0', 0).owner.isdefault()
# #
await newconf1.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1']) await newconf1.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1'])
@ -486,6 +500,7 @@ async def test_mix_leadership_owners():
await newconf1.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1']) await newconf1.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1'])
assert await newconf1.option('ip_admin_eth0.ip_admin_eth0').owner.get() == owners.user assert await newconf1.option('ip_admin_eth0.ip_admin_eth0').owner.get() == owners.user
assert await newconf1.option('ip_admin_eth0.netmask_admin_eth0', 0).owner.get() == owners.mix1 assert await newconf1.option('ip_admin_eth0.netmask_admin_eth0', 0).owner.get() == owners.mix1
await delete_sessions(mix)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -527,6 +542,7 @@ async def test_mix_force_default():
assert await mix.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.4'] assert await mix.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.4']
assert await newconf1.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.4'] assert await newconf1.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.4']
assert await newconf2.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.4'] assert await newconf2.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.4']
await delete_sessions(mix)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -557,6 +573,7 @@ async def test_mix_force_dont_change_value():
assert await newconf2.option('ip_admin_eth0.ip_admin_eth0').value.get() == [] assert await newconf2.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
assert await newconf1.option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user assert await newconf1.option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user
assert await newconf2.option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user assert await newconf2.option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user
await delete_sessions(mix)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -602,6 +619,7 @@ async def test_mix_force_default_if_same():
assert await newconf2.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.5'] assert await newconf2.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.5']
assert await newconf1.option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user assert await newconf1.option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user
assert await newconf2.option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.mix1 assert await newconf2.option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.mix1
await delete_sessions(mix)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -647,6 +665,8 @@ async def test_mix_force_default_if_same_and_dont_change():
assert await newconf2.option('ip_admin_eth0.ip_admin_eth0').value.get() == [] assert await newconf2.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
assert await newconf1.option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user assert await newconf1.option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user
assert await newconf2.option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user assert await newconf2.option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user
await delete_sessions(mix)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -660,8 +680,9 @@ async def test_mix_force_default_and_dont_change():
mix = await MixConfig(od, [conf1, conf2]) mix = await MixConfig(od, [conf1, conf2])
await mix.property.read_write() await mix.property.read_write()
await mix.owner.set('mix1') await mix.owner.set('mix1')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await mix.value.set('ip_admin_eth0.ip_admin_eth0', ['192.168.1.4'], force_default=True, force_dont_change_value=True) await mix.value.set('ip_admin_eth0.ip_admin_eth0', ['192.168.1.4'], force_default=True, force_dont_change_value=True)
await delete_sessions(mix)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -678,6 +699,7 @@ async def test_mix_properties_mix():
await mix.property.read_write() await mix.property.read_write()
newconf1 = await mix.config('conf1') newconf1 = await mix.config('conf1')
assert await newconf1.value.dict() == {} assert await newconf1.value.dict() == {}
await delete_sessions(mix)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -692,6 +714,8 @@ async def test_mix_exception_mix():
await mix.property.read_write() await mix.property.read_write()
with pytest.raises(ConfigError): with pytest.raises(ConfigError):
await conf1.value.dict() await conf1.value.dict()
await delete_sessions(mix)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -718,6 +742,7 @@ async def test_mix_callback():
await mix.option('val4').value.set('new1') await mix.option('val4').value.set('new1')
assert await newcfg.value.dict() == {'val3': 'yes', 'val2': 'new', 'val1': 'new', 'val5': 'yes', 'val4': 'new1'} assert await newcfg.value.dict() == {'val3': 'yes', 'val2': 'new', 'val1': 'new', 'val5': 'yes', 'val4': 'new1'}
await mix.option('val4').value.reset() await mix.option('val4').value.reset()
await delete_sessions(mix)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -778,6 +803,7 @@ async def test_mix_callback_follower():
await mix.option('val1.val1').value.pop(1) await mix.option('val1.val1').value.pop(1)
await mix.option('val1.val1').value.set(['val4']) await mix.option('val1.val1').value.set(['val4'])
assert await newcfg1.value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val4'], 'val1.val3': ['val4'], 'val': 'val'} assert await newcfg1.value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val4'], 'val1.val3': ['val4'], 'val': 'val'}
await delete_sessions(mix)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -796,27 +822,28 @@ async def test_meta_reset():
od2 = OptionDescription('root', '', [interface1]) od2 = OptionDescription('root', '', [interface1])
conf1 = await Config(od0, session_id='conf1') conf1 = await Config(od0, session_id='conf1')
conf2 = await Config(od1, session_id='conf2') conf2 = await Config(od1, session_id='conf2')
meta = await MixConfig(od2, [conf1, conf2]) mix = await MixConfig(od2, [conf1, conf2])
await meta.property.read_write() await mix.property.read_write()
await meta.owner.set('mix1') await mix.owner.set('mix1')
assert await meta.option('ip_admin_eth0.ip_admin_eth0').value.get() == [] assert await mix.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
newconf1 = await meta.config('conf1') newconf1 = await mix.config('conf1')
newconf2 = await meta.config('conf2') newconf2 = await mix.config('conf2')
assert await newconf1.option('ip_admin_eth0.ip_admin_eth0').value.get() == [] assert await newconf1.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
assert await newconf2.option('ip_admin_eth0.ip_admin_eth0').value.get() == [] assert await newconf2.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
errors = await meta.value.set('ip_admin_eth0.ip_admin_eth0', ['192.168.1.1']) errors = await mix.value.set('ip_admin_eth0.ip_admin_eth0', ['192.168.1.1'])
assert len(errors) == 0 assert len(errors) == 0
assert await meta.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.1'] assert await mix.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.1']
assert await newconf1.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.1'] assert await newconf1.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.1']
assert await newconf2.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.1'] assert await newconf2.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.1']
await newconf1.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.2']) await newconf1.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.2'])
assert await meta.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.1'] assert await mix.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.1']
assert await newconf1.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.2'] assert await newconf1.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.2']
assert await newconf2.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.1'] assert await newconf2.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.1']
await meta.value.reset('ip_admin_eth0.ip_admin_eth0') await mix.value.reset('ip_admin_eth0.ip_admin_eth0')
assert await meta.option('ip_admin_eth0.ip_admin_eth0').value.get() == [] assert await mix.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
assert await newconf1.option('ip_admin_eth0.ip_admin_eth0').value.get() == [] assert await newconf1.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
assert await newconf2.option('ip_admin_eth0.ip_admin_eth0').value.get() == [] assert await newconf2.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
await delete_sessions(mix)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -842,11 +869,11 @@ async def test_mix_properties_mix_copy():
newconf3 = await mix.config('conf3') newconf3 = await mix.config('conf3')
# old fashion # old fashion
mix2 = await conf3.config.metaconfig() mix2 = await conf3.config.metaconfig()
assert await mix.config.name() == await mix2.config.name() assert await mix.session.id() == await mix2.session.id()
# new method # new method
mix2 = list(await conf3.config.parents()) mix2 = list(await conf3.config.parents())
assert len(mix2) == 1 assert len(mix2) == 1
assert await mix.config.name() == await mix2[0].config.name() assert await mix.session.id() == await mix2[0].session.id()
newconf2 = await mix.config('conf2') newconf2 = await mix.config('conf2')
assert await newconf1.value.dict() == {'ip_admin_eth0': ['192.168.1.1']} assert await newconf1.value.dict() == {'ip_admin_eth0': ['192.168.1.1']}
@ -860,6 +887,7 @@ async def test_mix_properties_mix_copy():
assert await newconf1.value.dict() == {'ip_admin_eth0': ['192.168.1.3']} assert await newconf1.value.dict() == {'ip_admin_eth0': ['192.168.1.3']}
assert await conf2.value.dict() == {'ip_admin_eth0': ['192.168.1.3']} assert await conf2.value.dict() == {'ip_admin_eth0': ['192.168.1.3']}
assert await newconf3.value.dict() == {'ip_admin_eth0': ['192.168.1.3']} assert await newconf3.value.dict() == {'ip_admin_eth0': ['192.168.1.3']}
await delete_sessions(mix)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -902,6 +930,7 @@ async def test_mix_properties_mix_deepcopy():
assert await newconf1.value.dict() == {'ip_admin_eth0': ['192.168.1.3']} assert await newconf1.value.dict() == {'ip_admin_eth0': ['192.168.1.3']}
assert await newconf2.value.dict() == {'ip_admin_eth0': ['192.168.1.3']} assert await newconf2.value.dict() == {'ip_admin_eth0': ['192.168.1.3']}
assert await newconf3.value.dict() == {'ip_admin_eth0': ['192.168.1.1']} assert await newconf3.value.dict() == {'ip_admin_eth0': ['192.168.1.1']}
await delete_sessions([mix, mix2])
@pytest.mark.asyncio @pytest.mark.asyncio
@ -924,11 +953,12 @@ async def test_mix_properties_submix_deepcopy():
mix2 = await MixConfig(interface2, [mix1], session_id='mix2') mix2 = await MixConfig(interface2, [mix1], session_id='mix2')
mix_copy = await conf1.config.deepcopy(session_id='conf2', mix_copy = await conf1.config.deepcopy(session_id='conf2',
metaconfig_prefix='copy_') metaconfig_prefix='copy_')
assert await mix_copy.config.name() == 'copy_mix2' assert await mix_copy.session.id() == 'copy_mix2'
ret = await mix_copy.config('copy_mix1') ret1 = await mix_copy.config('copy_mix1')
assert await ret.config.name() == 'copy_mix1' assert await ret1.session.id() == 'copy_mix1'
ret = await mix_copy.config('copy_mix1.conf2') ret2 = await mix_copy.config('copy_mix1.conf2')
assert await ret.config.name() == 'conf2' assert await ret2.session.id() == 'conf2'
await delete_sessions([mix1, mix2, mix_copy, ret1, ret2])
@pytest.mark.asyncio @pytest.mark.asyncio
@ -971,6 +1001,7 @@ async def test_mix_properties_submix_deepcopy_owner():
assert await conf2.option('netmask_admin_eth1').owner.get() == 'conf2_user' assert await conf2.option('netmask_admin_eth1').owner.get() == 'conf2_user'
assert await conf2.option('ip_admin_eth0').value.get() == '192.168.0.1' assert await conf2.option('ip_admin_eth0').value.get() == '192.168.0.1'
assert await conf2.option('ip_admin_eth0').owner.get() == 'conf1_user' assert await conf2.option('ip_admin_eth0').owner.get() == 'conf1_user'
await delete_sessions([mix1, mix2, mix1_copy, mix2_copy])
@pytest.mark.asyncio @pytest.mark.asyncio
@ -1050,6 +1081,7 @@ async def test_mix_properties_mix_set_value():
del ret[1] del ret[1]
del ret[0] del ret[0]
del ret del ret
await delete_sessions(mix)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -1098,7 +1130,7 @@ async def test_mix_different_default():
assert await newconf2.value.dict() == {'ip_admin_eth1': ['192.168.1.2']} assert await newconf2.value.dict() == {'ip_admin_eth1': ['192.168.1.2']}
assert await newconf1.value.dict() == {'ip_admin_eth0': ['192.168.1.8']} assert await newconf1.value.dict() == {'ip_admin_eth0': ['192.168.1.8']}
# #
with pytest.raises(AttributeError): with pytest.raises(AttributeError):
await newsubmix1.option('ip_admin_eth0').value.set(['192.168.1.9']) await newsubmix1.option('ip_admin_eth0').value.set(['192.168.1.9'])
assert await mix.value.dict() == {'ip_admin_eth0': ['192.168.1.7']} assert await mix.value.dict() == {'ip_admin_eth0': ['192.168.1.7']}
assert await newsubmix2.value.dict() == {'ip_admin_eth0': ['192.168.1.8'], 'ip_admin_eth1': ['192.168.1.5']} assert await newsubmix2.value.dict() == {'ip_admin_eth0': ['192.168.1.8'], 'ip_admin_eth1': ['192.168.1.5']}
@ -1106,7 +1138,7 @@ async def test_mix_different_default():
assert await newconf2.value.dict() == {'ip_admin_eth1': ['192.168.1.2']} assert await newconf2.value.dict() == {'ip_admin_eth1': ['192.168.1.2']}
assert await newconf1.value.dict() == {'ip_admin_eth0': ['192.168.1.8']} assert await newconf1.value.dict() == {'ip_admin_eth0': ['192.168.1.8']}
# #
with pytest.raises(AttributeError): with pytest.raises(AttributeError):
await newconf2.option('ip_admin_eth0').value.set(['192.168.1.9']) await newconf2.option('ip_admin_eth0').value.set(['192.168.1.9'])
assert await mix.value.dict() == {'ip_admin_eth0': ['192.168.1.7']} assert await mix.value.dict() == {'ip_admin_eth0': ['192.168.1.7']}
assert await newsubmix2.value.dict() == {'ip_admin_eth0': ['192.168.1.8'], 'ip_admin_eth1': ['192.168.1.5']} assert await newsubmix2.value.dict() == {'ip_admin_eth0': ['192.168.1.8'], 'ip_admin_eth1': ['192.168.1.5']}
@ -1121,7 +1153,7 @@ async def test_mix_different_default():
assert await newconf2.value.dict() == {'ip_admin_eth1': ['192.168.1.2']} assert await newconf2.value.dict() == {'ip_admin_eth1': ['192.168.1.2']}
assert await newconf1.value.dict() == {'ip_admin_eth0': ['192.168.1.9']} assert await newconf1.value.dict() == {'ip_admin_eth0': ['192.168.1.9']}
# #
with pytest.raises(AttributeError): with pytest.raises(AttributeError):
await mix.option('ip_admin_eth1').value.set(['192.168.1.10']) await mix.option('ip_admin_eth1').value.set(['192.168.1.10'])
assert await mix.value.dict() == {'ip_admin_eth0': ['192.168.1.7']} assert await mix.value.dict() == {'ip_admin_eth0': ['192.168.1.7']}
assert await newsubmix2.value.dict() == {'ip_admin_eth0': ['192.168.1.8'], 'ip_admin_eth1': ['192.168.1.5']} assert await newsubmix2.value.dict() == {'ip_admin_eth0': ['192.168.1.8'], 'ip_admin_eth1': ['192.168.1.5']}
@ -1150,13 +1182,14 @@ async def test_mix_different_default():
assert await newconf2.value.dict() == {'ip_admin_eth1': ['192.168.1.12']} assert await newconf2.value.dict() == {'ip_admin_eth1': ['192.168.1.12']}
assert await newconf1.value.dict() == {'ip_admin_eth0': ['192.168.1.9']} assert await newconf1.value.dict() == {'ip_admin_eth0': ['192.168.1.9']}
# #
with pytest.raises(AttributeError): with pytest.raises(AttributeError):
await newconf1.option('ip_admin_eth1').value.set(['192.168.1.13']) await newconf1.option('ip_admin_eth1').value.set(['192.168.1.13'])
assert await mix.value.dict() == {'ip_admin_eth0': ['192.168.1.7']} assert await mix.value.dict() == {'ip_admin_eth0': ['192.168.1.7']}
assert await newsubmix2.value.dict() == {'ip_admin_eth0': ['192.168.1.8'], 'ip_admin_eth1': ['192.168.1.10']} assert await newsubmix2.value.dict() == {'ip_admin_eth0': ['192.168.1.8'], 'ip_admin_eth1': ['192.168.1.10']}
assert await newsubmix1.value.dict() == {'ip_admin_eth1': ['192.168.1.11']} assert await newsubmix1.value.dict() == {'ip_admin_eth1': ['192.168.1.11']}
assert await newconf2.value.dict() == {'ip_admin_eth1': ['192.168.1.12']} assert await newconf2.value.dict() == {'ip_admin_eth1': ['192.168.1.12']}
assert await newconf1.value.dict() == {'ip_admin_eth0': ['192.168.1.9']} assert await newconf1.value.dict() == {'ip_admin_eth0': ['192.168.1.9']}
await delete_sessions(mix)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -1210,6 +1243,7 @@ async def test_mix_different_default_reset():
assert await submix1.value.dict() == {'ip_admin_eth1': ['192.168.1.3']} assert await submix1.value.dict() == {'ip_admin_eth1': ['192.168.1.3']}
assert await conf2.value.dict() == {'ip_admin_eth1': ['192.168.1.2']} assert await conf2.value.dict() == {'ip_admin_eth1': ['192.168.1.2']}
assert await conf1.value.dict() == {'ip_admin_eth0': ['192.168.1.1']} assert await conf1.value.dict() == {'ip_admin_eth0': ['192.168.1.1']}
await delete_sessions(mix)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -1233,8 +1267,9 @@ async def test_mix_pop_config():
assert await newconf1.value.dict() == {'od1.i1': None, 'od1.i2': 1, 'od1.i3': None, 'od1.i4': 2, 'od1.i5': [2], 'od1.i6': None} assert await newconf1.value.dict() == {'od1.i1': None, 'od1.i2': 1, 'od1.i3': None, 'od1.i4': 2, 'od1.i5': [2], 'od1.i6': None}
# #
assert len(list(await mix.config.list())) == 1 assert len(list(await mix.config.list())) == 1
with pytest.raises(ConfigError): with pytest.raises(ConfigError):
await mix.config.pop('newconf1') await mix.config.pop('newconf1')
await delete_sessions([mix, newconf1])
@pytest.mark.asyncio @pytest.mark.asyncio
@ -1253,8 +1288,9 @@ async def test_mix_add_config():
assert len(list(await mix.config.list())) == 3 assert len(list(await mix.config.list())) == 3
assert await config.value.dict() == {'od1.i1': 2, 'od1.i2': 1, 'od1.i3': None, 'od1.i4': 2, 'od1.i5': [2], 'od1.i6': None} assert await config.value.dict() == {'od1.i1': 2, 'od1.i2': 1, 'od1.i3': None, 'od1.i4': 2, 'od1.i5': [2], 'od1.i6': None}
# #
with pytest.raises(ConflictError): with pytest.raises(ConflictError):
await mix.config.add(config) await mix.config.add(config)
await delete_sessions(mix)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -1267,6 +1303,7 @@ async def test_mix_add_config_readd():
await mix.config.add(config) await mix.config.add(config)
await mix2.config.add(config) await mix2.config.add(config)
assert len(list(await config.config.parents())) == 2 assert len(list(await config.config.parents())) == 2
await delete_sessions([mix, mix2])
@pytest.mark.asyncio @pytest.mark.asyncio
@ -1274,7 +1311,9 @@ async def test_meta_new_mixconfig():
od = make_description() od = make_description()
cfg = await Config(od, session_id='cfg1') cfg = await Config(od, session_id='cfg1')
meta = await MetaConfig([cfg]) meta = await MetaConfig([cfg])
assert isinstance(await meta.config.new('mixconfig', type="mixconfig"), MixConfig) mix = await meta.config.new('mixconfig', type="mixconfig")
assert isinstance(mix, MixConfig)
await delete_sessions(meta)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -1284,8 +1323,9 @@ async def test_meta_get_mixconfig():
meta = await MetaConfig([cfg]) meta = await MetaConfig([cfg])
await meta.config.new('mixconfig', type="mixconfig") await meta.config.new('mixconfig', type="mixconfig")
assert isinstance(await meta.config.get('mixconfig'), MixConfig) assert isinstance(await meta.config.get('mixconfig'), MixConfig)
with pytest.raises(ConfigError): with pytest.raises(ConfigError):
await meta.config.get('unknown') await meta.config.get('unknown')
newmix = await meta.config.get('mixconfig') newmix = await meta.config.get('mixconfig')
await newmix.config.add(await MixConfig(od, [], session_id='mixconfig2')) await newmix.config.add(await MixConfig(od, [], session_id='mixconfig2'))
assert isinstance(await newmix.config.get('mixconfig2'), MixConfig) assert isinstance(await newmix.config.get('mixconfig2'), MixConfig)
await delete_sessions(meta)

View file

@ -1,6 +1,7 @@
from tiramisu import IntOption, OptionDescription, MetaConfig from tiramisu import IntOption, OptionDescription, MetaConfig, list_sessions
from tiramisu.error import ConfigError from tiramisu.error import ConfigError
import pytest import pytest
from .config import delete_sessions, event_loop
async def make_metaconfig(): async def make_metaconfig():
@ -12,7 +13,7 @@ async def make_metaconfig():
i6 = IntOption('i6', '', properties=('disabled',)) i6 = IntOption('i6', '', properties=('disabled',))
od1 = OptionDescription('od1', '', [i1, i2, i3, i4, i5, i6]) od1 = OptionDescription('od1', '', [i1, i2, i3, i4, i5, i6])
od2 = OptionDescription('od2', '', [od1]) od2 = OptionDescription('od2', '', [od1])
return await MetaConfig([], optiondescription=od2, session_id='metacfg1') return await MetaConfig([], optiondescription=od2, session_id='metacfg1', delete_old_session=True)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -24,11 +25,12 @@ async def test_multi_parents_path():
""" """
metacfg1 = await make_metaconfig() metacfg1 = await make_metaconfig()
cfg1 = await metacfg1.config.new(type='config', session_id="cfg1") cfg1 = await metacfg1.config.new(type='config', session_id="cfg1")
metacfg2 = await MetaConfig([cfg1], session_id='metacfg2') metacfg2 = await MetaConfig([cfg1], session_id='metacfg2', delete_old_session=True)
# #
assert await metacfg1.config.path() == 'metacfg1' assert await metacfg1.config.path() == 'metacfg1'
assert await metacfg2.config.path() == 'metacfg2' assert await metacfg2.config.path() == 'metacfg2'
assert await cfg1.config.path() == 'metacfg2.metacfg1.cfg1' assert await cfg1.config.path() == 'metacfg2.metacfg1.cfg1'
await delete_sessions([metacfg1, metacfg2])
@pytest.mark.asyncio @pytest.mark.asyncio
@ -61,16 +63,15 @@ async def test_multi_parents_path_same():
deep = children[0] deep = children[0]
assert await deep.config.path() == 'test_metacfg3.test_metacfg1.test_metacfg2.test_cfg1' assert await deep.config.path() == 'test_metacfg3.test_metacfg1.test_metacfg2.test_cfg1'
assert await cfg1.option('od1.i1').value.get() == 1 assert await cfg1.option('od1.i1').value.get() == 1
del orideep await delete_sessions([metacfg1, orideep])
with pytest.raises(ConfigError):
await deep.config.path()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_multi_parents_value(): async def test_multi_parents_value():
metacfg1 = await make_metaconfig() metacfg1 = await make_metaconfig()
cfg1 = await metacfg1.config.new(type='config', session_id="cfg1") cfg1 = await metacfg1.config.new(type='config', session_id="cfg1")
metacfg2 = await MetaConfig([cfg1], session_id='metacfg2') metacfg2 = await MetaConfig([cfg1], session_id='metacfg2', delete_old_session=True)
# #
assert await cfg1.option('od1.i1').value.get() == None assert await cfg1.option('od1.i1').value.get() == None
assert await cfg1.option('od1.i2').value.get() == 1 assert await cfg1.option('od1.i2').value.get() == 1
@ -93,3 +94,4 @@ async def test_multi_parents_value():
assert await metacfg2.option('od1.i2').value.get() == 4 assert await metacfg2.option('od1.i2').value.get() == 4
assert await metacfg1.option('od1.i2').value.get() == 1 assert await metacfg1.option('od1.i2').value.get() == 1
assert await cfg1.option('od1.i2').value.get() == 4 assert await cfg1.option('od1.i2').value.get() == 4
await delete_sessions([metacfg1, metacfg2])

View file

@ -10,17 +10,13 @@ import warnings
from tiramisu.error import APIError, ConfigError from tiramisu.error import APIError, ConfigError
from tiramisu import IntOption, SymLinkOption, OptionDescription, Config, Calculation, groups, list_sessions from tiramisu import IntOption, SymLinkOption, OptionDescription, Config, Calculation, groups, list_sessions
from tiramisu.i18n import _ from tiramisu.i18n import _
from .config import event_loop
try: try:
groups.family groups.family
except: except:
groups.family = groups.GroupType('family') groups.family = groups.GroupType('family')
def teardown_function(function):
# some tests emit a warnings because of doesn't create a Config
with warnings.catch_warnings(record=True) as w:
assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__)
def a_func(): def a_func():
return None return None
@ -29,10 +25,10 @@ def a_func():
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_option_valid_name(): async def test_option_valid_name():
IntOption('test', '') IntOption('test', '')
with pytest.raises(ValueError): with pytest.raises(ValueError):
IntOption(1, "") IntOption(1, "")
i = IntOption("test1", "") i = IntOption("test1", "")
with pytest.raises(ValueError): with pytest.raises(ValueError):
SymLinkOption(1, i) SymLinkOption(1, i)
i = SymLinkOption("test1", i) i = SymLinkOption("test1", i)
@ -42,11 +38,11 @@ async def test_option_get_information():
description = "it's ok" description = "it's ok"
string = 'some informations' string = 'some informations'
i = IntOption('test', description) i = IntOption('test', description)
with pytest.raises(ValueError): with pytest.raises(ValueError):
i.impl_get_information('noinfo') i.impl_get_information('noinfo')
i.impl_set_information('info', string) i.impl_set_information('info', string)
assert i.impl_get_information('info') == string assert i.impl_get_information('info') == string
with pytest.raises(ValueError): with pytest.raises(ValueError):
i.impl_get_information('noinfo') i.impl_get_information('noinfo')
assert i.impl_get_information('noinfo', 'default') == 'default' assert i.impl_get_information('noinfo', 'default') == 'default'
assert i.impl_get_information('doc') == description assert i.impl_get_information('doc') == description
@ -58,15 +54,17 @@ async def test_option_get_information_config():
string = 'some informations' string = 'some informations'
i = IntOption('test', description) i = IntOption('test', description)
od = OptionDescription('od', '', [i]) od = OptionDescription('od', '', [i])
await Config(od) async with await Config(od) as cfg:
with pytest.raises(ValueError): pass
with pytest.raises(ValueError):
i.impl_get_information('noinfo') i.impl_get_information('noinfo')
with pytest.raises(AttributeError): with pytest.raises(AttributeError):
i.impl_set_information('info', string) i.impl_set_information('info', string)
with pytest.raises(ValueError): with pytest.raises(ValueError):
i.impl_get_information('noinfo') i.impl_get_information('noinfo')
assert i.impl_get_information('noinfo', 'default') == 'default' assert i.impl_get_information('noinfo', 'default') == 'default'
assert i.impl_get_information('doc') == description assert i.impl_get_information('doc') == description
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -76,12 +74,13 @@ async def test_option_get_information_default():
i = IntOption('test', description) i = IntOption('test', description)
i.impl_set_information('noinfo', 'optdefault') i.impl_set_information('noinfo', 'optdefault')
od = OptionDescription('od', '', [i]) od = OptionDescription('od', '', [i])
cfg = await Config(od) async with await Config(od) as cfg:
# #
assert await cfg.option('test').information.get('noinfo', 'falsedefault') == 'optdefault' assert await cfg.option('test').information.get('noinfo', 'falsedefault') == 'optdefault'
# #
await cfg.option('test').information.set('noinfo', 'notdefault') await cfg.option('test').information.set('noinfo', 'notdefault')
assert await cfg.option('test').information.get('noinfo', 'falsedefault') == 'notdefault' assert await cfg.option('test').information.get('noinfo', 'falsedefault') == 'notdefault'
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -91,16 +90,18 @@ async def test_option_get_information_config2():
i = IntOption('test', description) i = IntOption('test', description)
i.impl_set_information('info', string) i.impl_set_information('info', string)
od = OptionDescription('od', '', [i]) od = OptionDescription('od', '', [i])
await Config(od) async with await Config(od) as cfg:
with pytest.raises(ValueError): pass
with pytest.raises(ValueError):
i.impl_get_information('noinfo') i.impl_get_information('noinfo')
with pytest.raises(AttributeError): with pytest.raises(AttributeError):
i.impl_set_information('info', 'hello') i.impl_set_information('info', 'hello')
assert i.impl_get_information('info') == string assert i.impl_get_information('info') == string
with pytest.raises(ValueError): with pytest.raises(ValueError):
i.impl_get_information('noinfo') i.impl_get_information('noinfo')
assert i.impl_get_information('noinfo', 'default') == 'default' assert i.impl_get_information('noinfo', 'default') == 'default'
assert i.impl_get_information('doc') == description assert i.impl_get_information('doc') == description
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -110,10 +111,11 @@ async def test_optiondescription_get_information():
o = OptionDescription('test', description, []) o = OptionDescription('test', description, [])
o.impl_set_information('info', string) o.impl_set_information('info', string)
assert o.impl_get_information('info') == string assert o.impl_get_information('info') == string
with pytest.raises(ValueError): with pytest.raises(ValueError):
o.impl_get_information('noinfo') o.impl_get_information('noinfo')
assert o.impl_get_information('noinfo', 'default') == 'default' assert o.impl_get_information('noinfo', 'default') == 'default'
assert o.impl_get_information('doc') == description assert o.impl_get_information('doc') == description
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -121,9 +123,10 @@ async def test_option_isoptiondescription():
i = IntOption('test', '') i = IntOption('test', '')
od = OptionDescription('od', '', [i]) od = OptionDescription('od', '', [i])
od = OptionDescription('od', '', [od]) od = OptionDescription('od', '', [od])
cfg = await Config(od) async with await Config(od) as cfg:
assert await cfg.option('od').option.isoptiondescription() assert await cfg.option('od').option.isoptiondescription()
assert not await cfg.option('od.test').option.isoptiondescription() assert not await cfg.option('od.test').option.isoptiondescription()
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -132,9 +135,10 @@ async def test_option_double():
od = OptionDescription('od1', '', [i]) od = OptionDescription('od1', '', [i])
od = OptionDescription('od2', '', [od]) od = OptionDescription('od2', '', [od])
od = OptionDescription('od3', '', [od]) od = OptionDescription('od3', '', [od])
cfg = await Config(od) async with await Config(od) as cfg:
assert await cfg.option('od2.od1.test').value.get() is None assert await cfg.option('od2.od1.test').value.get() is None
assert await cfg.option('od2').option('od1').option('test').value.get() is None assert await cfg.option('od2').option('od1').option('test').value.get() is None
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -143,17 +147,18 @@ async def test_option_multi():
IntOption('test', '', multi=True, default_multi=1) IntOption('test', '', multi=True, default_multi=1)
IntOption('test', '', default=[1], multi=True, default_multi=1) IntOption('test', '', default=[1], multi=True, default_multi=1)
#add default_multi to not multi's option #add default_multi to not multi's option
with pytest.raises(ValueError): with pytest.raises(ValueError):
IntOption('test', '', default_multi=1) IntOption('test', '', default_multi=1)
#unvalid default_multi #unvalid default_multi
with pytest.raises(ValueError): with pytest.raises(ValueError):
IntOption('test', '', multi=True, default_multi='yes') IntOption('test', '', multi=True, default_multi='yes')
assert not await list_sessions()
#@pytest.mark.asyncio #@pytest.mark.asyncio
#async def test_option_multi_legacy(): #async def test_option_multi_legacy():
# #not default_multi with callback # #not default_multi with callback
# #with pytest.raises(ValueError): # #with pytest.raises(ValueError):
# IntOption('test', '', multi=True, default_multi=1, callback=a_func)") # IntOption('test', '', multi=True, default_multi=1, callback=a_func)")
@ -162,19 +167,20 @@ async def test_unknown_option():
i = IntOption('test', '') i = IntOption('test', '')
od1 = OptionDescription('od', '', [i]) od1 = OptionDescription('od', '', [i])
od2 = OptionDescription('od', '', [od1]) od2 = OptionDescription('od', '', [od1])
cfg = await Config(od2) async with await Config(od2) as cfg:
# test is an option, not an optiondescription # test is an option, not an optiondescription
with pytest.raises(TypeError): with pytest.raises(TypeError):
await cfg.option('od.test.unknown').value.get() await cfg.option('od.test.unknown').value.get()
# unknown is an unknown option # unknown is an unknown option
with pytest.raises(AttributeError): with pytest.raises(AttributeError):
await cfg.option('unknown').value.get() await cfg.option('unknown').value.get()
# unknown is an unknown option # unknown is an unknown option
with pytest.raises(AttributeError): with pytest.raises(AttributeError):
await cfg.option('od.unknown').value.get() await cfg.option('od.unknown').value.get()
# unknown is an unknown optiondescription # unknown is an unknown optiondescription
with pytest.raises(AttributeError): with pytest.raises(AttributeError):
await cfg.option('od.unknown.suboption').value.get() await cfg.option('od.unknown.suboption').value.get()
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -188,25 +194,26 @@ async def test_optiondescription_list():
od3.impl_set_group_type(groups.notfamily1) od3.impl_set_group_type(groups.notfamily1)
od2 = OptionDescription('od', '', [od1, od3]) od2 = OptionDescription('od', '', [od1, od3])
od4 = OptionDescription('od', '', [od2]) od4 = OptionDescription('od', '', [od2])
cfg = await Config(od4) async with await Config(od4) as cfg:
assert len(list(await cfg.option('od').list('option'))) == 0 assert len(list(await cfg.option('od').list('option'))) == 0
assert len(list(await cfg.option('od').list('optiondescription'))) == 2 assert len(list(await cfg.option('od').list('optiondescription'))) == 2
assert len(list(await cfg.option('od').list('optiondescription', group_type=groups.family))) == 1 assert len(list(await cfg.option('od').list('optiondescription', group_type=groups.family))) == 1
assert len(list(await cfg.option('od').list('optiondescription', group_type=groups.notfamily1))) == 1 assert len(list(await cfg.option('od').list('optiondescription', group_type=groups.notfamily1))) == 1
assert len(list(await cfg.option('od.od').list('option'))) == 1 assert len(list(await cfg.option('od.od').list('option'))) == 1
assert len(list(await cfg.option('od.od2').list('option'))) == 1 assert len(list(await cfg.option('od.od2').list('option'))) == 1
try: try:
list(await cfg.option('od').list('unknown')) list(await cfg.option('od').list('unknown'))
except AssertionError: except AssertionError:
pass pass
else: else:
raise Exception('must raise') raise Exception('must raise')
try: try:
list(await cfg.option('od').list('option', group_type='toto')) list(await cfg.option('od').list('option', group_type='toto'))
except AssertionError: except AssertionError:
pass pass
else: else:
raise Exception('must raise') raise Exception('must raise')
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -219,23 +226,24 @@ async def test_optiondescription_group():
od3 = OptionDescription('od2', '', [i2]) od3 = OptionDescription('od2', '', [i2])
od3.impl_set_group_type(groups.notfamily) od3.impl_set_group_type(groups.notfamily)
od2 = OptionDescription('od', '', [od1, od3]) od2 = OptionDescription('od', '', [od1, od3])
cfg = await Config(od2) async with await Config(od2) as cfg:
assert len(list(await cfg.option.list('option'))) == 0 assert len(list(await cfg.option.list('option'))) == 0
assert len(list(await cfg.option.list('optiondescription'))) == 2 assert len(list(await cfg.option.list('optiondescription'))) == 2
assert len(list(await cfg.option.list('optiondescription', group_type=groups.family))) == 1 assert len(list(await cfg.option.list('optiondescription', group_type=groups.family))) == 1
assert len(list(await cfg.option.list('optiondescription', group_type=groups.notfamily))) == 1 assert len(list(await cfg.option.list('optiondescription', group_type=groups.notfamily))) == 1
try: try:
list(await cfg.option.list('unknown')) list(await cfg.option.list('unknown'))
except AssertionError: except AssertionError:
pass pass
else: else:
raise Exception('must raise') raise Exception('must raise')
try: try:
list(await cfg.option.list('option', group_type='toto')) list(await cfg.option.list('option', group_type='toto'))
except AssertionError: except AssertionError:
pass pass
else: else:
raise Exception('must raise') raise Exception('must raise')
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -247,16 +255,18 @@ async def test_optiondescription_group_redefined():
i = IntOption('test', '') i = IntOption('test', '')
od1 = OptionDescription('od', '', [i]) od1 = OptionDescription('od', '', [i])
od1.impl_set_group_type(groups.family) od1.impl_set_group_type(groups.family)
with pytest.raises(ValueError): with pytest.raises(ValueError):
od1.impl_set_group_type(groups.notfamily) od1.impl_set_group_type(groups.notfamily)
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_optiondescription_group_leadership(): async def test_optiondescription_group_leadership():
i = IntOption('test', '') i = IntOption('test', '')
od1 = OptionDescription('od', '', [i]) od1 = OptionDescription('od', '', [i])
with pytest.raises(ConfigError): with pytest.raises(ConfigError):
od1.impl_set_group_type(groups.leadership) od1.impl_set_group_type(groups.leadership)
assert not await list_sessions()
@ -265,11 +275,12 @@ async def test_asign_optiondescription():
i = IntOption('test', '') i = IntOption('test', '')
od1 = OptionDescription('od', '', [i]) od1 = OptionDescription('od', '', [i])
od2 = OptionDescription('od', '', [od1]) od2 = OptionDescription('od', '', [od1])
cfg = await Config(od2) async with await Config(od2) as cfg:
with pytest.raises(APIError): with pytest.raises(APIError):
await cfg.option('od').value.set('test') await cfg.option('od').value.set('test')
with pytest.raises(APIError): with pytest.raises(APIError):
await cfg.option('od').value.reset() await cfg.option('od').value.reset()
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -277,25 +288,28 @@ async def test_intoption():
i1 = IntOption('test1', 'description', min_number=3) i1 = IntOption('test1', 'description', min_number=3)
i2 = IntOption('test2', 'description', max_number=3) i2 = IntOption('test2', 'description', max_number=3)
od = OptionDescription('od', '', [i1, i2]) od = OptionDescription('od', '', [i1, i2])
cfg = await Config(od) async with await Config(od) as cfg:
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('test1').value.set(2) await cfg.option('test1').value.set(2)
await cfg.option('test1').value.set(3) await cfg.option('test1').value.set(3)
await cfg.option('test1').value.set(4) await cfg.option('test1').value.set(4)
await cfg.option('test2').value.set(2) await cfg.option('test2').value.set(2)
await cfg.option('test2').value.set(3) await cfg.option('test2').value.set(3)
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('test2').value.set(4) await cfg.option('test2').value.set(4)
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_get_display_type(): async def test_get_display_type():
i1 = IntOption('test1', 'description', min_number=3) i1 = IntOption('test1', 'description', min_number=3)
assert i1.get_display_type() == _('integer') assert i1.get_display_type() == _('integer')
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_option_not_in_config(): async def test_option_not_in_config():
i1 = IntOption('test1', 'description', min_number=3) i1 = IntOption('test1', 'description', min_number=3)
with pytest.raises(AttributeError): with pytest.raises(AttributeError):
i1.impl_getpath() i1.impl_getpath()
assert not await list_sessions()

File diff suppressed because it is too large Load diff

View file

@ -1,23 +1,19 @@
"test all types of option default values for options, add new option in a descr" "test all types of option default values for options, add new option in a descr"
from .autopath import do_autopath from .autopath import do_autopath
do_autopath() do_autopath()
from .config import config_type, get_config
import pytest import pytest
from tiramisu.setting import owners from tiramisu.setting import owners
from tiramisu.error import PropertiesOptionError, ConfigError, LeadershipError from tiramisu.error import PropertiesOptionError, ConfigError, LeadershipError
from tiramisu import IntOption, FloatOption, StrOption, ChoiceOption, \ from tiramisu import IntOption, FloatOption, StrOption, ChoiceOption, \
BoolOption, OptionDescription, Leadership, Config, undefined BoolOption, OptionDescription, Leadership, Config, undefined, delete_session
from tiramisu.storage import list_sessions from tiramisu.storage import list_sessions
from .config import config_type, get_config, event_loop
owners.addowner("frozenmultifollower") owners.addowner("frozenmultifollower")
def teardown_function(function):
assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__)
def make_description(): def make_description():
gcoption = ChoiceOption('name', 'GC name', ['ref', 'framework'], 'ref') gcoption = ChoiceOption('name', 'GC name', ['ref', 'framework'], 'ref')
gcdummy = BoolOption('dummy', 'dummy', default=False) gcdummy = BoolOption('dummy', 'dummy', default=False)
@ -54,11 +50,12 @@ async def test_default_is_none(config_type):
dummy1 = BoolOption('dummy1', 'doc dummy') dummy1 = BoolOption('dummy1', 'doc dummy')
dummy2 = BoolOption('dummy2', 'doc dummy') dummy2 = BoolOption('dummy2', 'doc dummy')
group = OptionDescription('group', '', [dummy1, dummy2]) group = OptionDescription('group', '', [dummy1, dummy2])
cfg = await Config(group) async with await Config(group) as cfg:
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
# so when the default value is not set, there is actually a default value # so when the default value is not set, there is actually a default value
assert await cfg.option('dummy1').value.get() is None assert await cfg.option('dummy1').value.get() is None
assert await cfg.option('dummy2').value.get() is None assert await cfg.option('dummy2').value.get() is None
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -66,6 +63,7 @@ async def test_set_defaut_value_from_option_object():
"""Options have an available default setting and can give it back""" """Options have an available default setting and can give it back"""
b = BoolOption("boolean", "", default=False) b = BoolOption("boolean", "", default=False)
assert b.impl_getdefault() is False assert b.impl_getdefault() is False
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -74,42 +72,43 @@ async def test_force_default_on_freeze():
dummy1 = BoolOption('dummy1', 'doc dummy', default=False, properties=('force_default_on_freeze',)) dummy1 = BoolOption('dummy1', 'doc dummy', default=False, properties=('force_default_on_freeze',))
dummy2 = BoolOption('dummy2', 'doc dummy', default=True) dummy2 = BoolOption('dummy2', 'doc dummy', default=True)
group = OptionDescription('group', '', [dummy1, dummy2]) group = OptionDescription('group', '', [dummy1, dummy2])
cfg_ori = await Config(group) async with await Config(group) as cfg_ori:
await cfg_ori.property.read_write() await cfg_ori.property.read_write()
cfg = cfg_ori cfg = cfg_ori
# FIXME cfg = await get_config(cfg_ori, config_type) # FIXME cfg = await get_config(cfg_ori, config_type)
owner = await cfg.owner.get() owner = await cfg.owner.get()
await cfg.option('dummy1').value.set(True) await cfg.option('dummy1').value.set(True)
await cfg.option('dummy2').value.set(False) await cfg.option('dummy2').value.set(False)
assert await cfg.option('dummy1').owner.get() == owner assert await cfg.option('dummy1').owner.get() == owner
assert await cfg.option('dummy2').owner.get() == owner assert await cfg.option('dummy2').owner.get() == owner
# if config_type == 'tiramisu-api': # if config_type == 'tiramisu-api':
# await cfg.send() # await cfg.send()
await cfg_ori.option('dummy1').property.add('frozen') await cfg_ori.option('dummy1').property.add('frozen')
await cfg_ori.option('dummy2').property.add('frozen') await cfg_ori.option('dummy2').property.add('frozen')
# cfg = await get_config(cfg_ori, config_type) # cfg = await get_config(cfg_ori, config_type)
assert await cfg.option('dummy1').value.get() is False assert await cfg.option('dummy1').value.get() is False
assert await cfg.option('dummy2').value.get() is False assert await cfg.option('dummy2').value.get() is False
assert await cfg.option('dummy1').owner.isdefault() assert await cfg.option('dummy1').owner.isdefault()
assert await cfg.option('dummy2').owner.get() == owner assert await cfg.option('dummy2').owner.get() == owner
# if config_type == 'tiramisu-api': # if config_type == 'tiramisu-api':
# await cfg.send() # await cfg.send()
with pytest.raises(PropertiesOptionError): with pytest.raises(PropertiesOptionError):
await cfg_ori.option('dummy2').owner.set('frozen') await cfg_ori.option('dummy2').owner.set('frozen')
# cfg = await get_config(cfg_ori, config_type) # cfg = await get_config(cfg_ori, config_type)
with pytest.raises(PropertiesOptionError): with pytest.raises(PropertiesOptionError):
await cfg.option('dummy1').value.reset()
# if config_type == 'tiramisu-api':
# await cfg.send()
await cfg_ori.option('dummy1').property.pop('frozen')
# cfg = await get_config(cfg_ori, config_type)
await cfg.option('dummy1').value.reset() await cfg.option('dummy1').value.reset()
# if config_type == 'tiramisu-api': # if config_type == 'tiramisu-api':
# await cfg.send() # await cfg.send()
await cfg_ori.option('dummy1').property.pop('frozen') await cfg.option('dummy1').property.add('frozen')
# cfg = await get_config(cfg_ori, config_type) # cfg = await get_config(cfg_ori, config_type)
await cfg.option('dummy1').value.reset() with pytest.raises(PropertiesOptionError):
# if config_type == 'tiramisu-api': await cfg.option('dummy2').owner.set('frozen')
# await cfg.send() assert not await list_sessions()
await cfg.option('dummy1').property.add('frozen')
# cfg = await get_config(cfg_ori, config_type)
with pytest.raises(PropertiesOptionError):
await cfg.option('dummy2').owner.set('frozen')
@pytest.mark.asyncio @pytest.mark.asyncio
@ -117,36 +116,37 @@ async def test_force_default_on_freeze_multi():
dummy1 = BoolOption('dummy1', 'doc dummy', default=[False], properties=('force_default_on_freeze',), multi=True) dummy1 = BoolOption('dummy1', 'doc dummy', default=[False], properties=('force_default_on_freeze',), multi=True)
dummy2 = BoolOption('dummy2', 'doc dummy', default=[True], multi=True) dummy2 = BoolOption('dummy2', 'doc dummy', default=[True], multi=True)
group = OptionDescription('group', '', [dummy1, dummy2]) group = OptionDescription('group', '', [dummy1, dummy2])
cfg_ori = await Config(group) async with await Config(group) as cfg_ori:
await cfg_ori.property.read_write() await cfg_ori.property.read_write()
cfg = cfg_ori cfg = cfg_ori
# FIXME cfg = await get_config(cfg_ori, config_type) # FIXME cfg = await get_config(cfg_ori, config_type)
await cfg.option('dummy1').value.set([undefined, True]) await cfg.option('dummy1').value.set([undefined, True])
await cfg.option('dummy2').value.set([undefined, False]) await cfg.option('dummy2').value.set([undefined, False])
owner = await cfg.owner.get() owner = await cfg.owner.get()
assert await cfg.option('dummy1').owner.get() == owner assert await cfg.option('dummy1').owner.get() == owner
assert await cfg.option('dummy2').owner.get() == owner assert await cfg.option('dummy2').owner.get() == owner
# if config_type == 'tiramisu-api': # if config_type == 'tiramisu-api':
# await cfg.send() # await cfg.send()
await cfg_ori.option('dummy1').property.add('frozen') await cfg_ori.option('dummy1').property.add('frozen')
await cfg_ori.option('dummy2').property.add('frozen') await cfg_ori.option('dummy2').property.add('frozen')
# cfg = await get_config(cfg_ori, config_type) # cfg = await get_config(cfg_ori, config_type)
assert await cfg.option('dummy1').value.get() == [False] assert await cfg.option('dummy1').value.get() == [False]
assert await cfg.option('dummy2').value.get() == [True, False] assert await cfg.option('dummy2').value.get() == [True, False]
assert await cfg.option('dummy1').owner.isdefault() assert await cfg.option('dummy1').owner.isdefault()
assert await cfg.option('dummy2').owner.get() == owner assert await cfg.option('dummy2').owner.get() == owner
# if config_type == 'tiramisu-api': # if config_type == 'tiramisu-api':
# await cfg.send() # await cfg.send()
with pytest.raises(PropertiesOptionError): with pytest.raises(PropertiesOptionError):
await cfg_ori.option('dummy2').owner.set('owner') await cfg_ori.option('dummy2').owner.set('owner')
# cfg = await get_config(cfg_ori, config_type) # cfg = await get_config(cfg_ori, config_type)
with pytest.raises(PropertiesOptionError): with pytest.raises(PropertiesOptionError):
await cfg.option('dummy2').value.reset() await cfg.option('dummy2').value.reset()
# if config_type == 'tiramisu-api': # if config_type == 'tiramisu-api':
# await cfg.send() # await cfg.send()
await cfg_ori.option('dummy1').property.pop('frozen') await cfg_ori.option('dummy1').property.pop('frozen')
# cfg = await get_config(cfg_ori, config_type) # cfg = await get_config(cfg_ori, config_type)
await cfg.option('dummy1').value.reset() await cfg.option('dummy1').value.reset()
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -155,8 +155,10 @@ async def test_force_default_on_freeze_leader():
dummy2 = BoolOption('dummy2', 'Test string option', multi=True) dummy2 = BoolOption('dummy2', 'Test string option', multi=True)
descr = Leadership("dummy1", "", [dummy1, dummy2]) descr = Leadership("dummy1", "", [dummy1, dummy2])
descr = OptionDescription("root", "", [descr]) descr = OptionDescription("root", "", [descr])
with pytest.raises(ConfigError): with pytest.raises(ConfigError):
await Config(descr) await Config(descr, session_id='error')
await delete_session('error')
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -165,8 +167,10 @@ async def test_force_metaconfig_on_freeze_leader():
dummy2 = BoolOption('dummy2', 'Test string option', multi=True) dummy2 = BoolOption('dummy2', 'Test string option', multi=True)
descr = Leadership("dummy1", "", [dummy1, dummy2]) descr = Leadership("dummy1", "", [dummy1, dummy2])
descr = OptionDescription("root", "", [descr]) descr = OptionDescription("root", "", [descr])
with pytest.raises(ConfigError): with pytest.raises(ConfigError):
await Config(descr) await Config(descr, session_id='error')
await delete_session('error')
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -175,9 +179,10 @@ async def test_force_default_on_freeze_leader_frozen():
dummy2 = BoolOption('dummy2', 'Test string option', multi=True) dummy2 = BoolOption('dummy2', 'Test string option', multi=True)
descr = Leadership("dummy1", "", [dummy1, dummy2]) descr = Leadership("dummy1", "", [dummy1, dummy2])
descr = OptionDescription("root", "", [descr]) descr = OptionDescription("root", "", [descr])
cfg = await Config(descr) async with await Config(descr) as cfg:
with pytest.raises(LeadershipError): with pytest.raises(LeadershipError):
await cfg.option('dummy1.dummy1').property.pop('frozen') await cfg.option('dummy1.dummy1').property.pop('frozen')
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -186,9 +191,10 @@ async def test_force_metaconfig_on_freeze_leader_frozen():
dummy2 = BoolOption('dummy2', 'Test string option', multi=True) dummy2 = BoolOption('dummy2', 'Test string option', multi=True)
descr = Leadership("dummy1", "", [dummy1, dummy2]) descr = Leadership("dummy1", "", [dummy1, dummy2])
descr = OptionDescription("root", "", [descr]) descr = OptionDescription("root", "", [descr])
cfg = await Config(descr) async with await Config(descr) as cfg:
with pytest.raises(LeadershipError): with pytest.raises(LeadershipError):
await cfg.option('dummy1.dummy1').property.pop('frozen') await cfg.option('dummy1.dummy1').property.pop('frozen')
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -197,62 +203,63 @@ async def test_force_default_on_freeze_follower(config_type):
dummy2 = BoolOption('dummy2', 'Test string option', multi=True, properties=('force_default_on_freeze',)) dummy2 = BoolOption('dummy2', 'Test string option', multi=True, properties=('force_default_on_freeze',))
descr = Leadership("dummy1", "", [dummy1, dummy2]) descr = Leadership("dummy1", "", [dummy1, dummy2])
descr = OptionDescription("root", "", [descr]) descr = OptionDescription("root", "", [descr])
cfg_ori = await Config(descr) async with await Config(descr) as cfg_ori:
await cfg_ori.property.read_write() await cfg_ori.property.read_write()
cfg = await get_config(cfg_ori, config_type) cfg = await get_config(cfg_ori, config_type)
await cfg.option('dummy1.dummy1').value.set([True]) await cfg.option('dummy1.dummy1').value.set([True])
await cfg.option('dummy1.dummy2', 0).value.set(False) await cfg.option('dummy1.dummy2', 0).value.set(False)
assert await cfg.option('dummy1.dummy1').value.get() == [True] assert await cfg.option('dummy1.dummy1').value.get() == [True]
assert await cfg.option('dummy1.dummy2', 0).value.get() == False assert await cfg.option('dummy1.dummy2', 0).value.get() == False
assert await cfg.option('dummy1.dummy1').owner.get() == 'user' assert await cfg.option('dummy1.dummy1').owner.get() == 'user'
assert await cfg.option('dummy1.dummy2', 0).owner.get() == 'user' assert await cfg.option('dummy1.dummy2', 0).owner.get() == 'user'
# #
if config_type == 'tiramisu-api': if config_type == 'tiramisu-api':
await cfg.send() await cfg.send()
await cfg_ori.option('dummy1.dummy2').property.add('frozen') await cfg_ori.option('dummy1.dummy2').property.add('frozen')
cfg = await get_config(cfg_ori, config_type) cfg = await get_config(cfg_ori, config_type)
assert await cfg.option('dummy1.dummy1').value.get() == [True] assert await cfg.option('dummy1.dummy1').value.get() == [True]
assert await cfg.option('dummy1.dummy2', 0).value.get() == None assert await cfg.option('dummy1.dummy2', 0).value.get() == None
assert await cfg.option('dummy1.dummy1').owner.get() == 'user' assert await cfg.option('dummy1.dummy1').owner.get() == 'user'
assert await cfg.option('dummy1.dummy2', 0).owner.isdefault() assert await cfg.option('dummy1.dummy2', 0).owner.isdefault()
if config_type == 'tiramisu-api': if config_type == 'tiramisu-api':
await cfg.send() await cfg.send()
with pytest.raises(PropertiesOptionError): with pytest.raises(PropertiesOptionError):
await cfg_ori.option('dummy1.dummy2', 0).owner.set('frozenmultifollower') await cfg_ori.option('dummy1.dummy2', 0).owner.set('frozenmultifollower')
cfg = await get_config(cfg_ori, config_type) cfg = await get_config(cfg_ori, config_type)
# #
if config_type == 'tiramisu-api': if config_type == 'tiramisu-api':
await cfg.send() await cfg.send()
await cfg_ori.option('dummy1.dummy2').property.pop('frozen') await cfg_ori.option('dummy1.dummy2').property.pop('frozen')
cfg = await get_config(cfg_ori, config_type) cfg = await get_config(cfg_ori, config_type)
await cfg.option('dummy1.dummy1').value.set([True, True]) await cfg.option('dummy1.dummy1').value.set([True, True])
await cfg.option('dummy1.dummy2', 1).value.set(False) await cfg.option('dummy1.dummy2', 1).value.set(False)
assert await cfg.option('dummy1.dummy1').value.get() == [True, True] assert await cfg.option('dummy1.dummy1').value.get() == [True, True]
assert await cfg.option('dummy1.dummy2', 0).value.get() == False assert await cfg.option('dummy1.dummy2', 0).value.get() == False
assert await cfg.option('dummy1.dummy2', 1).value.get() == False assert await cfg.option('dummy1.dummy2', 1).value.get() == False
# #
if config_type == 'tiramisu-api': if config_type == 'tiramisu-api':
await cfg.send() await cfg.send()
await cfg_ori.option('dummy1.dummy2').property.add('frozen') await cfg_ori.option('dummy1.dummy2').property.add('frozen')
cfg = await get_config(cfg_ori, config_type) cfg = await get_config(cfg_ori, config_type)
assert await cfg.option('dummy1.dummy1').value.get() == [True, True] assert await cfg.option('dummy1.dummy1').value.get() == [True, True]
assert await cfg.option('dummy1.dummy2', 0).value.get() == None assert await cfg.option('dummy1.dummy2', 0).value.get() == None
assert await cfg.option('dummy1.dummy2', 1).value.get() == None assert await cfg.option('dummy1.dummy2', 1).value.get() == None
# #
await cfg.option('dummy1.dummy1').value.pop(1) await cfg.option('dummy1.dummy1').value.pop(1)
assert await cfg.option('dummy1.dummy1').value.get() == [True] assert await cfg.option('dummy1.dummy1').value.get() == [True]
assert await cfg.option('dummy1.dummy2', 0).value.get() == None assert await cfg.option('dummy1.dummy2', 0).value.get() == None
# #
if config_type == 'tiramisu-api': if config_type == 'tiramisu-api':
await cfg.send() await cfg.send()
await cfg_ori.option('dummy1.dummy2').property.pop('frozen') await cfg_ori.option('dummy1.dummy2').property.pop('frozen')
cfg = await get_config(cfg_ori, config_type) cfg = await get_config(cfg_ori, config_type)
assert await cfg.option('dummy1.dummy1').value.get() == [True] assert await cfg.option('dummy1.dummy1').value.get() == [True]
assert await cfg.option('dummy1.dummy2', 0).value.get() == False assert await cfg.option('dummy1.dummy2', 0).value.get() == False
# #
await cfg.option('dummy1.dummy1').value.set([True, True]) await cfg.option('dummy1.dummy1').value.set([True, True])
assert await cfg.option('dummy1.dummy2', 0).value.get() == False assert await cfg.option('dummy1.dummy2', 0).value.get() == False
assert await cfg.option('dummy1.dummy2', 1).value.get() == None assert await cfg.option('dummy1.dummy2', 1).value.get() == None
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -260,25 +267,28 @@ async def test_overrides_changes_option_value(config_type):
"with config.override(), the default is changed and the value is changed" "with config.override(), the default is changed and the value is changed"
descr = OptionDescription("test", "", [ descr = OptionDescription("test", "", [
BoolOption("b", "", default=False)]) BoolOption("b", "", default=False)])
cfg = await Config(descr) async with await Config(descr) as cfg:
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
await cfg.option('b').value.set(True) await cfg.option('b').value.set(True)
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_choice_with_no_default(config_type): async def test_choice_with_no_default(config_type):
descr = OptionDescription("test", "", [ descr = OptionDescription("test", "", [
ChoiceOption("backend", "", ("c", "cli"))]) ChoiceOption("backend", "", ("c", "cli"))])
cfg = await Config(descr) async with await Config(descr) as cfg:
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
assert await cfg.option('backend').value.get() is None assert await cfg.option('backend').value.get() is None
await cfg.option('backend').value.set('c') await cfg.option('backend').value.set('c')
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_choice_with_default(config_type): async def test_choice_with_default(config_type):
descr = OptionDescription("test", "", [ descr = OptionDescription("test", "", [
ChoiceOption("backend", "", ("c", "cli"), default="cli")]) ChoiceOption("backend", "", ("c", "cli"), default="cli")])
cfg = await Config(descr) async with await Config(descr) as cfg:
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
assert await cfg.option('backend').value.get() == 'cli' assert await cfg.option('backend').value.get() == 'cli'
assert not await list_sessions()

View file

@ -1,6 +1,5 @@
from .autopath import do_autopath from .autopath import do_autopath
do_autopath() do_autopath()
from .config import config_type, get_config
import pytest import pytest
@ -9,16 +8,13 @@ from tiramisu import ChoiceOption, BoolOption, IntOption, FloatOption, \
StrOption, OptionDescription, SymLinkOption, Leadership, Config StrOption, OptionDescription, SymLinkOption, Leadership, Config
from tiramisu.error import ConfigError, ConstError, PropertiesOptionError, APIError from tiramisu.error import ConfigError, ConstError, PropertiesOptionError, APIError
from tiramisu.storage import list_sessions from tiramisu.storage import list_sessions
from .config import config_type, get_config, event_loop
owners.addowner("readonly2") owners.addowner("readonly2")
owners.addowner("new2") owners.addowner("new2")
def teardown_function(function):
assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__)
def make_description(): def make_description():
gcoption = ChoiceOption('name', 'GC name', ['ref', 'framework'], 'ref') gcoption = ChoiceOption('name', 'GC name', ['ref', 'framework'], 'ref')
gcdummy = BoolOption('dummy', 'dummy', default=False) gcdummy = BoolOption('dummy', 'dummy', default=False)
@ -45,61 +41,64 @@ def make_description():
async def test_default_owner(config_type): async def test_default_owner(config_type):
gcdummy = BoolOption('dummy', 'dummy', default=False) gcdummy = BoolOption('dummy', 'dummy', default=False)
descr = OptionDescription('tiramisu', '', [gcdummy]) descr = OptionDescription('tiramisu', '', [gcdummy])
cfg = await Config(descr) async with await Config(descr) as cfg:
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
assert await cfg.option('dummy').value.get() is False assert await cfg.option('dummy').value.get() is False
assert await cfg.option('dummy').owner.get() == 'default' assert await cfg.option('dummy').owner.get() == 'default'
await cfg.option('dummy').value.set(True) await cfg.option('dummy').value.set(True)
owner = await cfg.owner.get() owner = await cfg.owner.get()
assert await cfg.option('dummy').owner.get() == owner assert await cfg.option('dummy').owner.get() == owner
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_hidden_owner(): async def test_hidden_owner():
gcdummy = BoolOption('dummy', 'dummy', default=False, properties=('hidden',)) gcdummy = BoolOption('dummy', 'dummy', default=False, properties=('hidden',))
descr = OptionDescription('tiramisu', '', [gcdummy]) descr = OptionDescription('tiramisu', '', [gcdummy])
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
#with pytest.raises(PropertiesOptionError): #with pytest.raises(PropertiesOptionError):
# await cfg.forcepermissive.option('dummy').owner.get() # await cfg.forcepermissive.option('dummy').owner.get()
#with pytest.raises(PropertiesOptionError): #with pytest.raises(PropertiesOptionError):
# await cfg.option('dummy').owner.isdefault() # await cfg.option('dummy').owner.isdefault()
#with pytest.raises(PropertiesOptionError): #with pytest.raises(PropertiesOptionError):
# await cfg.forcepermissive.option('dummy').owner.isdefault() # await cfg.forcepermissive.option('dummy').owner.isdefault()
await cfg.permissive.add('hidden') await cfg.permissive.add('hidden')
await cfg.forcepermissive.option('dummy').value.get() await cfg.forcepermissive.option('dummy').value.get()
await cfg.forcepermissive.option('dummy').owner.isdefault() await cfg.forcepermissive.option('dummy').owner.isdefault()
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_addowner(config_type): async def test_addowner(config_type):
gcdummy = BoolOption('dummy', 'dummy', default=False) gcdummy = BoolOption('dummy', 'dummy', default=False)
descr = OptionDescription('tiramisu', '', [gcdummy]) descr = OptionDescription('tiramisu', '', [gcdummy])
cfg_ori = await Config(descr) async with await Config(descr) as cfg_ori:
cfg = await get_config(cfg_ori, config_type) cfg = await get_config(cfg_ori, config_type)
assert await cfg.option('dummy').value.get() is False assert await cfg.option('dummy').value.get() is False
assert await cfg.option('dummy').owner.get() == 'default' assert await cfg.option('dummy').owner.get() == 'default'
assert await cfg.option('dummy').owner.isdefault() assert await cfg.option('dummy').owner.isdefault()
if config_type == 'tiramisu-api': if config_type == 'tiramisu-api':
await cfg.send() await cfg.send()
await cfg_ori.owner.set('gen_config') await cfg_ori.owner.set('gen_config')
cfg = await get_config(cfg_ori, config_type) cfg = await get_config(cfg_ori, config_type)
await cfg.option('dummy').value.set(True) await cfg.option('dummy').value.set(True)
assert await cfg.option('dummy').owner.get() == owners.gen_config assert await cfg.option('dummy').owner.get() == owners.gen_config
assert not await cfg.option('dummy').owner.isdefault() assert not await cfg.option('dummy').owner.isdefault()
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_addowner_multiple_time(): async def test_addowner_multiple_time():
owners.addowner("testowner2") owners.addowner("testowner2")
with pytest.raises(ConstError): with pytest.raises(ConstError):
owners.addowner("testowner2") owners.addowner("testowner2")
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_delete_owner(): async def test_delete_owner():
owners.addowner('deleted2') owners.addowner('deleted2')
with pytest.raises(ConstError): with pytest.raises(ConstError):
del(owners.deleted2) del(owners.deleted2)
@ -107,88 +106,93 @@ async def test_delete_owner():
async def test_owner_is_not_a_string(config_type): async def test_owner_is_not_a_string(config_type):
gcdummy = BoolOption('dummy', 'dummy', default=False) gcdummy = BoolOption('dummy', 'dummy', default=False)
descr = OptionDescription('tiramisu', '', [gcdummy]) descr = OptionDescription('tiramisu', '', [gcdummy])
cfg = await Config(descr) async with await Config(descr) as cfg:
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
assert await cfg.option('dummy').value.get() is False assert await cfg.option('dummy').value.get() is False
assert await cfg.option('dummy').owner.get() == owners.default assert await cfg.option('dummy').owner.get() == owners.default
assert await cfg.option('dummy').owner.get() == 'default' assert await cfg.option('dummy').owner.get() == 'default'
if config_type == 'tiramisu': if config_type == 'tiramisu':
assert isinstance(await cfg.option('dummy').owner.get(), owners.Owner) assert isinstance(await cfg.option('dummy').owner.get(), owners.Owner)
await cfg.option('dummy').value.set(True) await cfg.option('dummy').value.set(True)
assert await cfg.option('dummy').owner.get() == 'user' assert await cfg.option('dummy').owner.get() == 'user'
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_setowner_without_valid_owner(config_type): async def test_setowner_without_valid_owner(config_type):
gcdummy = BoolOption('dummy', 'dummy', default=False) gcdummy = BoolOption('dummy', 'dummy', default=False)
descr = OptionDescription('tiramisu', '', [gcdummy]) descr = OptionDescription('tiramisu', '', [gcdummy])
cfg = await Config(descr) async with await Config(descr) as cfg:
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
assert await cfg.option('dummy').value.get() is False assert await cfg.option('dummy').value.get() is False
assert await cfg.option('dummy').owner.get() == 'default' assert await cfg.option('dummy').owner.get() == 'default'
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_setowner_for_value(config_type): async def test_setowner_for_value(config_type):
gcdummy = BoolOption('dummy', 'dummy', default=False) gcdummy = BoolOption('dummy', 'dummy', default=False)
descr = OptionDescription('tiramisu', '', [gcdummy]) descr = OptionDescription('tiramisu', '', [gcdummy])
cfg_ori = await Config(descr) async with await Config(descr) as cfg_ori:
cfg = await get_config(cfg_ori, config_type) cfg = await get_config(cfg_ori, config_type)
assert await cfg.option('dummy').value.get() is False assert await cfg.option('dummy').value.get() is False
assert await cfg.option('dummy').owner.get() == 'default' assert await cfg.option('dummy').owner.get() == 'default'
if config_type == 'tiramisu-api': if config_type == 'tiramisu-api':
await cfg.send() await cfg.send()
with pytest.raises(ConfigError): with pytest.raises(ConfigError):
await cfg_ori.option('dummy').owner.set('new2')
cfg = await get_config(cfg_ori, config_type)
await cfg.option('dummy').value.set(False)
assert await cfg.option('dummy').owner.get() == owners.user
if config_type == 'tiramisu-api':
await cfg.send()
await cfg_ori.option('dummy').owner.set('new2') await cfg_ori.option('dummy').owner.set('new2')
cfg = await get_config(cfg_ori, config_type) cfg = await get_config(cfg_ori, config_type)
await cfg.option('dummy').value.set(False) assert await cfg.option('dummy').owner.get() == owners.new2
assert await cfg.option('dummy').owner.get() == owners.user assert not await list_sessions()
if config_type == 'tiramisu-api':
await cfg.send()
await cfg_ori.option('dummy').owner.set('new2')
cfg = await get_config(cfg_ori, config_type)
assert await cfg.option('dummy').owner.get() == owners.new2
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_setowner_forbidden(config_type): async def test_setowner_forbidden(config_type):
gcdummy = BoolOption('dummy', 'dummy', default=False) gcdummy = BoolOption('dummy', 'dummy', default=False)
descr = OptionDescription('tiramisu', '', [gcdummy]) descr = OptionDescription('tiramisu', '', [gcdummy])
cfg_ori = await Config(descr) async with await Config(descr) as cfg_ori:
cfg = await get_config(cfg_ori, config_type) cfg = await get_config(cfg_ori, config_type)
assert await cfg.option('dummy').value.get() is False assert await cfg.option('dummy').value.get() is False
assert await cfg.option('dummy').owner.get() == 'default' assert await cfg.option('dummy').owner.get() == 'default'
if config_type == 'tiramisu-api': if config_type == 'tiramisu-api':
await cfg.send() await cfg.send()
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg_ori.owner.set('default') await cfg_ori.owner.set('default')
cfg = await get_config(cfg_ori, config_type) cfg = await get_config(cfg_ori, config_type)
await cfg.option('dummy').value.set(False) await cfg.option('dummy').value.set(False)
if config_type == 'tiramisu-api': if config_type == 'tiramisu-api':
await cfg.send() await cfg.send()
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg_ori.option('dummy').owner.set('default') await cfg_ori.option('dummy').owner.set('default')
cfg = await get_config(cfg_ori, config_type) cfg = await get_config(cfg_ori, config_type)
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_setowner_read_only(config_type): async def test_setowner_read_only(config_type):
gcdummy = BoolOption('dummy', 'dummy', default=False) gcdummy = BoolOption('dummy', 'dummy', default=False)
descr = OptionDescription('tiramisu', '', [gcdummy]) descr = OptionDescription('tiramisu', '', [gcdummy])
cfg_ori = await Config(descr) async with await Config(descr) as cfg_ori:
await cfg_ori.property.read_write() await cfg_ori.property.read_write()
cfg = await get_config(cfg_ori, config_type) cfg = await get_config(cfg_ori, config_type)
assert await cfg.option('dummy').value.get() is False assert await cfg.option('dummy').value.get() is False
assert await cfg.option('dummy').owner.get() == 'default' assert await cfg.option('dummy').owner.get() == 'default'
await cfg.option('dummy').value.set(False) await cfg.option('dummy').value.set(False)
assert await cfg.option('dummy').owner.get() == owners.user assert await cfg.option('dummy').owner.get() == owners.user
if config_type == 'tiramisu-api': if config_type == 'tiramisu-api':
await cfg.send() await cfg.send()
await cfg_ori.property.read_only() await cfg_ori.property.read_only()
with pytest.raises(PropertiesOptionError): with pytest.raises(PropertiesOptionError):
await cfg_ori.option('dummy').owner.set('readonly2') await cfg_ori.option('dummy').owner.set('readonly2')
cfg = await get_config(cfg_ori, config_type) cfg = await get_config(cfg_ori, config_type)
assert await cfg.option('dummy').owner.get() == owners.user assert await cfg.option('dummy').owner.get() == owners.user
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -196,12 +200,13 @@ async def test_setowner_optiondescription(config_type):
gcdummy = BoolOption('dummy', 'dummy', default=False) gcdummy = BoolOption('dummy', 'dummy', default=False)
descr1 = OptionDescription('tiramisu', '', [gcdummy]) descr1 = OptionDescription('tiramisu', '', [gcdummy])
descr = OptionDescription('tiramisu', '', [descr1]) descr = OptionDescription('tiramisu', '', [descr1])
cfg = await Config(descr) async with await Config(descr) as cfg:
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
with pytest.raises(APIError): with pytest.raises(APIError):
await cfg.option('tiramisu').owner.get() await cfg.option('tiramisu').owner.get()
with pytest.raises(APIError): with pytest.raises(APIError):
await cfg.option('tiramisu').owner.set('user') await cfg.option('tiramisu').owner.set('user')
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -210,15 +215,16 @@ async def test_setowner_symlinkoption(config_type):
s = SymLinkOption('symdummy', gcdummy) s = SymLinkOption('symdummy', gcdummy)
descr1 = OptionDescription('tiramisu', '', [gcdummy, s]) descr1 = OptionDescription('tiramisu', '', [gcdummy, s])
descr = OptionDescription('tiramisu', '', [descr1]) descr = OptionDescription('tiramisu', '', [descr1])
cfg_ori = await Config(descr) async with await Config(descr) as cfg_ori:
cfg = await get_config(cfg_ori, config_type) cfg = await get_config(cfg_ori, config_type)
assert await cfg.option('tiramisu.symdummy').owner.isdefault() assert await cfg.option('tiramisu.symdummy').owner.isdefault()
await cfg.option('tiramisu.dummy').value.set(True) await cfg.option('tiramisu.dummy').value.set(True)
assert not await cfg.option('tiramisu.symdummy').owner.isdefault() assert not await cfg.option('tiramisu.symdummy').owner.isdefault()
if config_type == 'tiramisu-api': if config_type == 'tiramisu-api':
await cfg.send() await cfg.send()
with pytest.raises(ConfigError): with pytest.raises(ConfigError):
await cfg_ori.option('tiramisu.symdummy').owner.set('user') await cfg_ori.option('tiramisu.symdummy').owner.set('user')
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -227,20 +233,21 @@ async def test_owner_leadership(config_type):
c = StrOption('str', 'Test string option', multi=True) c = StrOption('str', 'Test string option', multi=True)
descr = Leadership("int", "", [b, c]) descr = Leadership("int", "", [b, c])
od = OptionDescription('od', '', [descr]) od = OptionDescription('od', '', [descr])
cfg_ori = await Config(od) async with await Config(od) as cfg_ori:
with pytest.raises(ConfigError): with pytest.raises(ConfigError):
await cfg_ori.option('int.str', 0).owner.set('user') await cfg_ori.option('int.str', 0).owner.set('user')
cfg = await get_config(cfg_ori, config_type) cfg = await get_config(cfg_ori, config_type)
await cfg.option('int.int').value.set([0, 1]) await cfg.option('int.int').value.set([0, 1])
await cfg.option('int.str', 0).value.set('yes') await cfg.option('int.str', 0).value.set('yes')
assert not await cfg.option('int.str', 0).owner.isdefault() assert not await cfg.option('int.str', 0).owner.isdefault()
assert await cfg.option('int.str', 1).owner.isdefault() assert await cfg.option('int.str', 1).owner.isdefault()
if config_type == 'tiramisu-api': if config_type == 'tiramisu-api':
await cfg.send() await cfg.send()
await cfg_ori.option('int.str', 0).owner.set('user') await cfg_ori.option('int.str', 0).owner.set('user')
cfg = await get_config(cfg_ori, config_type) cfg = await get_config(cfg_ori, config_type)
assert await cfg.option('int.str', 0).owner.get() == owners.user assert await cfg.option('int.str', 0).owner.get() == owners.user
assert await cfg.option('int.str', 1).owner.isdefault() assert await cfg.option('int.str', 1).owner.isdefault()
assert await cfg.option('int.str', 0).value.get() == 'yes' assert await cfg.option('int.str', 0).value.get() == 'yes'
assert await cfg.option('int.str', 1).value.get() == None assert await cfg.option('int.str', 1).value.get() == None
assert not await list_sessions()

File diff suppressed because it is too large Load diff

View file

@ -2,7 +2,6 @@
"frozen and hidden values" "frozen and hidden values"
from .autopath import do_autopath from .autopath import do_autopath
do_autopath() do_autopath()
from .config import config_type, get_config
import pytest import pytest
@ -11,10 +10,7 @@ from tiramisu import ChoiceOption, BoolOption, IntOption, FloatOption, \
Calculation, Params, ParamOption, ParamValue, calc_value Calculation, Params, ParamOption, ParamValue, calc_value
from tiramisu.error import PropertiesOptionError from tiramisu.error import PropertiesOptionError
from tiramisu.storage import list_sessions from tiramisu.storage import list_sessions
from .config import config_type, get_config, event_loop
def teardown_function(function):
assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__)
def make_description(): def make_description():
@ -56,140 +52,147 @@ def make_description():
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_is_hidden(config_type): async def test_is_hidden(config_type):
descr = make_description() descr = make_description()
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
assert not 'frozen' in await cfg.forcepermissive.option('gc.dummy').property.get() assert not 'frozen' in await cfg.forcepermissive.option('gc.dummy').property.get()
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
# setattr # setattr
with pytest.raises(PropertiesOptionError): with pytest.raises(PropertiesOptionError):
await cfg.option('gc.dummy').value.get() == False await cfg.option('gc.dummy').value.get() == False
# getattr # getattr
with pytest.raises(PropertiesOptionError): with pytest.raises(PropertiesOptionError):
await cfg.option('gc.dummy').value.get() await cfg.option('gc.dummy').value.get()
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_group_is_hidden(config_type): async def test_group_is_hidden(config_type):
descr = make_description() descr = make_description()
cfg_ori = await Config(descr) async with await Config(descr) as cfg_ori:
await cfg_ori.property.read_write() await cfg_ori.property.read_write()
await cfg_ori.option('gc').property.add('hidden') await cfg_ori.option('gc').property.add('hidden')
cfg = await get_config(cfg_ori, config_type) cfg = await get_config(cfg_ori, config_type)
with pytest.raises(PropertiesOptionError): with pytest.raises(PropertiesOptionError):
await cfg.option('gc.dummy').value.get() await cfg.option('gc.dummy').value.get()
if config_type == 'tiramisu-api': if config_type == 'tiramisu-api':
await cfg.send() await cfg.send()
assert 'hidden' in await cfg_ori.forcepermissive.option('gc').property.get() assert 'hidden' in await cfg_ori.forcepermissive.option('gc').property.get()
cfg = await get_config(cfg_ori, config_type) cfg = await get_config(cfg_ori, config_type)
with pytest.raises(PropertiesOptionError): with pytest.raises(PropertiesOptionError):
await cfg.option('gc.float').value.get() await cfg.option('gc.float').value.get()
# manually set the subconfigs to "show" # manually set the subconfigs to "show"
if config_type == 'tiramisu-api': if config_type == 'tiramisu-api':
await cfg.send() await cfg.send()
await cfg_ori.forcepermissive.option('gc').property.pop('hidden') await cfg_ori.forcepermissive.option('gc').property.pop('hidden')
cfg = await get_config(cfg_ori, config_type) cfg = await get_config(cfg_ori, config_type)
assert not 'hidden' in await cfg.option('gc').property.get() assert not 'hidden' in await cfg.option('gc').property.get()
assert await cfg.option('gc.float').value.get() == 2.3 assert await cfg.option('gc.float').value.get() == 2.3
#dummy est en hide #dummy est en hide
prop = [] prop = []
try: try:
await cfg.option('gc.dummy').value.set(False) await cfg.option('gc.dummy').value.set(False)
except PropertiesOptionError as err: except PropertiesOptionError as err:
prop = err.proptype prop = err.proptype
if config_type == 'tiramisu-api': if config_type == 'tiramisu-api':
assert 'disabled' in prop assert 'disabled' in prop
else: else:
assert 'hidden' in prop assert 'hidden' in prop
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_group_is_hidden_multi(config_type): async def test_group_is_hidden_multi(config_type):
descr = make_description() descr = make_description()
cfg_ori = await Config(descr) async with await Config(descr) as cfg_ori:
await cfg_ori.property.read_write() await cfg_ori.property.read_write()
await cfg_ori.option('objspace').property.add('hidden') await cfg_ori.option('objspace').property.add('hidden')
cfg = await get_config(cfg_ori, config_type) cfg = await get_config(cfg_ori, config_type)
with pytest.raises(PropertiesOptionError): with pytest.raises(PropertiesOptionError):
await cfg.option('objspace').value.get() await cfg.option('objspace').value.get()
if config_type == 'tiramisu-api': if config_type == 'tiramisu-api':
await cfg.send() await cfg.send()
assert 'hidden' in await cfg_ori.forcepermissive.option('objspace').property.get() assert 'hidden' in await cfg_ori.forcepermissive.option('objspace').property.get()
cfg = await get_config(cfg_ori, config_type) cfg = await get_config(cfg_ori, config_type)
prop = [] prop = []
try: try:
await cfg.option('objspace').value.set(['std']) await cfg.option('objspace').value.set(['std'])
except PropertiesOptionError as err: except PropertiesOptionError as err:
prop = err.proptype prop = err.proptype
if config_type == 'tiramisu-api': if config_type == 'tiramisu-api':
assert 'disabled' in prop assert 'disabled' in prop
else: else:
assert 'hidden' in prop assert 'hidden' in prop
if config_type == 'tiramisu-api': if config_type == 'tiramisu-api':
await cfg.send() await cfg.send()
await cfg_ori.forcepermissive.option('objspace').property.pop('hidden') await cfg_ori.forcepermissive.option('objspace').property.pop('hidden')
cfg = await get_config(cfg_ori, config_type) cfg = await get_config(cfg_ori, config_type)
assert not 'hidden' in await cfg.option('objspace').property.get() assert not 'hidden' in await cfg.option('objspace').property.get()
await cfg.option('objspace').value.set(['std', 'thunk']) await cfg.option('objspace').value.set(['std', 'thunk'])
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_global_show(config_type): async def test_global_show(config_type):
descr = make_description() descr = make_description()
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
await cfg.forcepermissive.option('gc.dummy').property.add('hidden') await cfg.forcepermissive.option('gc.dummy').property.add('hidden')
assert 'hidden' in await cfg.forcepermissive.option('gc.dummy').property.get() assert 'hidden' in await cfg.forcepermissive.option('gc.dummy').property.get()
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
with pytest.raises(PropertiesOptionError): with pytest.raises(PropertiesOptionError):
await cfg.option('gc.dummy').value.get() == False await cfg.option('gc.dummy').value.get() == False
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_with_many_subgroups(config_type): async def test_with_many_subgroups(config_type):
descr = make_description() descr = make_description()
cfg_ori = await Config(descr) async with await Config(descr) as cfg_ori:
#booltwo = config.unwrap_from_path('gc.subgroup.booltwo') #booltwo = config.unwrap_from_path('gc.subgroup.booltwo')
#setting = config.cfgimpl_get_settings() #setting = config.cfgimpl_get_settings()
cfg = await get_config(cfg_ori, config_type) cfg = await get_config(cfg_ori, config_type)
assert not 'hidden' in await cfg.option('gc.subgroup.booltwo').property.get() assert not 'hidden' in await cfg.option('gc.subgroup.booltwo').property.get()
assert await cfg.option('gc.subgroup.booltwo').value.get() is False assert await cfg.option('gc.subgroup.booltwo').value.get() is False
if config_type == 'tiramisu-api': if config_type == 'tiramisu-api':
await cfg.send() await cfg.send()
await cfg_ori.option('gc.subgroup.booltwo').property.add('hidden') await cfg_ori.option('gc.subgroup.booltwo').property.add('hidden')
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_password_option(config_type): async def test_password_option(config_type):
o = PasswordOption('o', '') o = PasswordOption('o', '')
d = OptionDescription('d', '', [o]) d = OptionDescription('d', '', [o])
cfg = await Config(d) async with await Config(d) as cfg:
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
await cfg.option('o').value.set('a_valid_password') await cfg.option('o').value.set('a_valid_password')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('o').value.set(1) await cfg.option('o').value.set(1)
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_date_option(config_type): async def test_date_option(config_type):
o = DateOption('o', '') o = DateOption('o', '')
d = OptionDescription('d', '', [o]) d = OptionDescription('d', '', [o])
cfg = await Config(d) async with await Config(d) as cfg:
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
await cfg.option('o').value.set('2017-02-04') await cfg.option('o').value.set('2017-02-04')
await cfg.option('o').value.set('2017-2-4') await cfg.option('o').value.set('2017-2-4')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('o').value.set(1) await cfg.option('o').value.set(1)
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('o').value.set('2017-13-20') await cfg.option('o').value.set('2017-13-20')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('o').value.set('2017-11-31') await cfg.option('o').value.set('2017-11-31')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('o').value.set('2017-12-32') await cfg.option('o').value.set('2017-12-32')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('o').value.set('2017-2-29') await cfg.option('o').value.set('2017-2-29')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('o').value.set('2-2-2017') await cfg.option('o').value.set('2-2-2017')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('o').value.set('2017/2/2') await cfg.option('o').value.set('2017/2/2')
assert not await list_sessions()

View file

@ -2,10 +2,9 @@
from .autopath import do_autopath from .autopath import do_autopath
do_autopath() do_autopath()
from py.test import raises import pytest
from tiramisu.option import UsernameOption from tiramisu import UsernameOption
from tiramisu.storage import list_sessions
def test_username(): def test_username():
@ -15,14 +14,20 @@ def test_username():
UsernameOption('a', '', 'string_') UsernameOption('a', '', 'string_')
UsernameOption('a', '', 'string$') UsernameOption('a', '', 'string$')
UsernameOption('a', '', '_string$') UsernameOption('a', '', '_string$')
raises(ValueError, "UsernameOption('a', '', 'strin$g')") with pytest.raises(ValueError):
UsernameOption('a', '', 'strin$g')
UsernameOption('a', '', 's-tring') UsernameOption('a', '', 's-tring')
raises(ValueError, "UsernameOption('a', '', '-string')") with pytest.raises(ValueError):
UsernameOption('a', '', '-string')
UsernameOption('a', '', 's9tring') UsernameOption('a', '', 's9tring')
raises(ValueError, "UsernameOption('a', '', '9string')") with pytest.raises(ValueError):
raises(ValueError, "UsernameOption('a', '', '')") UsernameOption('a', '', '9string')
with pytest.raises(ValueError):
UsernameOption('a', '', '')
UsernameOption('a', '', 's') UsernameOption('a', '', 's')
UsernameOption('a', '', 's2345678901234567890123456789012') UsernameOption('a', '', 's2345678901234567890123456789012')
raises(ValueError, "UsernameOption('a', '', 's23456789012345678901234567890123')") with pytest.raises(ValueError):
UsernameOption('a', '', 's23456789012345678901234567890123')
UsernameOption('a', '', 's234567890123456789012345678901$') UsernameOption('a', '', 's234567890123456789012345678901$')
raises(ValueError, "UsernameOption('a', '', 's2345678901234567890123456789012$')") with pytest.raises(ValueError):
UsernameOption('a', '', 's2345678901234567890123456789012$')

File diff suppressed because it is too large Load diff

View file

@ -1,16 +1,12 @@
#this test is much more to test that **it's there** and answers attribute access #this test is much more to test that **it's there** and answers attribute access
from .autopath import do_autopath from .autopath import do_autopath
do_autopath() do_autopath()
from .config import config_type, get_config
import pytest import pytest
from tiramisu import BoolOption, OptionDescription, ChoiceOption,\ from tiramisu import BoolOption, OptionDescription, ChoiceOption,\
IntOption, FloatOption, StrOption, Config IntOption, FloatOption, StrOption, Config
from tiramisu.storage import list_sessions from tiramisu.storage import list_sessions
from .config import config_type, get_config, event_loop
def teardown_function(function):
assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__)
def make_description(): def make_description():
@ -42,13 +38,14 @@ async def test_root_config_answers_ok(config_type):
gcdummy = BoolOption('dummy', 'dummy', default=False) gcdummy = BoolOption('dummy', 'dummy', default=False)
boolop = BoolOption('boolop', 'Test boolean option op', default=True) boolop = BoolOption('boolop', 'Test boolean option op', default=True)
descr = OptionDescription('tiramisu', '', [gcdummy, boolop]) descr = OptionDescription('tiramisu', '', [gcdummy, boolop])
cfg = await Config(descr) async with await Config(descr) as cfg:
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
#settings = await cfg.cfgimpl_get_settings() #settings = await cfg.cfgimpl_get_settings()
#settings.append('hidden') #settings.append('hidden')
assert await cfg.option('dummy').value.get() is False assert await cfg.option('dummy').value.get() is False
assert await cfg.option('boolop').value.get() is True assert await cfg.option('boolop').value.get() is True
assert not await list_sessions()
#@pytest.mark.asyncio #@pytest.mark.asyncio
@ -61,7 +58,8 @@ async def test_root_config_answers_ok(config_type):
async def test_option_has_an_api_name(config_type): async def test_option_has_an_api_name(config_type):
b = BoolOption('impl_has_dependency', 'dummy', default=True) b = BoolOption('impl_has_dependency', 'dummy', default=True)
descr = OptionDescription('tiramisu', '', [b]) descr = OptionDescription('tiramisu', '', [b])
cfg = await Config(descr) async with await Config(descr) as cfg:
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
assert await cfg.option('impl_has_dependency').value.get() is True assert await cfg.option('impl_has_dependency').value.get() is True
assert b.impl_has_dependency() is False assert b.impl_has_dependency() is False
assert not await list_sessions()

View file

@ -1,17 +1,13 @@
# coding: utf-8 # coding: utf-8
from .autopath import do_autopath from .autopath import do_autopath
do_autopath() do_autopath()
from .config import config_type, get_config
import pytest import pytest
from tiramisu import IntOption, StrOption, OptionDescription, Config from tiramisu import IntOption, StrOption, OptionDescription, Config
from tiramisu.error import PropertiesOptionError, ConfigError from tiramisu.error import PropertiesOptionError, ConfigError
from tiramisu.storage import list_sessions, delete_session from tiramisu.storage import list_sessions, delete_session
from .config import config_type, get_config, event_loop
def teardown_function(function):
assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__)
def make_description(): def make_description():
@ -23,410 +19,425 @@ def make_description():
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_permissive(config_type): async def test_permissive(config_type):
descr = make_description() descr = make_description()
cfg_ori = await Config(descr) async with await Config(descr) as cfg_ori:
await cfg_ori.property.read_write() await cfg_ori.property.read_write()
await cfg_ori.property.read_write() await cfg_ori.property.read_write()
cfg = await get_config(cfg_ori, config_type) cfg = await get_config(cfg_ori, config_type)
props = frozenset() props = frozenset()
try: try:
await cfg.option('u1').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled'}
if config_type == 'tiramisu-api':
await cfg.send()
await cfg_ori.unrestraint.permissive.add('disabled')
await cfg_ori.unrestraint.permissive.pop('hidden')
assert await cfg_ori.unrestraint.permissive.get() == frozenset(['disabled'])
cfg = await get_config(cfg_ori, config_type)
props = frozenset()
try:
await cfg.option('u1').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled'}
if config_type == 'tiramisu-api':
await cfg.send()
await cfg_ori.property.add('permissive')
cfg = await get_config(cfg_ori, config_type)
await cfg.option('u1').value.get() await cfg.option('u1').value.get()
except PropertiesOptionError as err: if config_type == 'tiramisu-api':
props = err.proptype await cfg.send()
assert set(props) == {'disabled'} await cfg_ori.property.pop('permissive')
if config_type == 'tiramisu-api': cfg = await get_config(cfg_ori, config_type)
await cfg.send() props = frozenset()
await cfg_ori.unrestraint.permissive.add('disabled') try:
await cfg_ori.unrestraint.permissive.pop('hidden') await cfg.option('u1').value.get()
assert await cfg_ori.unrestraint.permissive.get() == frozenset(['disabled']) except PropertiesOptionError as err:
cfg = await get_config(cfg_ori, config_type) props = err.proptype
props = frozenset() assert set(props) == {'disabled'}
try: assert not await list_sessions()
await cfg.option('u1').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled'}
if config_type == 'tiramisu-api':
await cfg.send()
await cfg_ori.property.add('permissive')
cfg = await get_config(cfg_ori, config_type)
await cfg.option('u1').value.get()
if config_type == 'tiramisu-api':
await cfg.send()
await cfg_ori.property.pop('permissive')
cfg = await get_config(cfg_ori, config_type)
props = frozenset()
try:
await cfg.option('u1').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled'}
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_permissive_add(config_type): async def test_permissive_add(config_type):
descr = make_description() descr = make_description()
cfg_ori = await Config(descr) async with await Config(descr) as cfg_ori:
await cfg_ori.property.read_write() await cfg_ori.property.read_write()
await cfg_ori.property.read_write() await cfg_ori.property.read_write()
cfg = await get_config(cfg_ori, config_type) cfg = await get_config(cfg_ori, config_type)
props = frozenset() props = frozenset()
try: try:
await cfg.option('u1').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled'}
if config_type == 'tiramisu-api':
await cfg.send()
await cfg_ori.unrestraint.permissive.add('disabled')
assert await cfg_ori.unrestraint.permissive.get() == frozenset(['hidden', 'disabled'])
cfg = await get_config(cfg_ori, config_type)
props = frozenset()
try:
await cfg.option('u1').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled'}
if config_type == 'tiramisu-api':
await cfg.send()
await cfg_ori.property.add('permissive')
cfg = await get_config(cfg_ori, config_type)
await cfg.option('u1').value.get() await cfg.option('u1').value.get()
except PropertiesOptionError as err: if config_type == 'tiramisu-api':
props = err.proptype await cfg.send()
assert set(props) == {'disabled'} await cfg_ori.property.pop('permissive')
if config_type == 'tiramisu-api': cfg = await get_config(cfg_ori, config_type)
await cfg.send() props = frozenset()
await cfg_ori.unrestraint.permissive.add('disabled') try:
assert await cfg_ori.unrestraint.permissive.get() == frozenset(['hidden', 'disabled']) await cfg.option('u1').value.get()
cfg = await get_config(cfg_ori, config_type) except PropertiesOptionError as err:
props = frozenset() props = err.proptype
try: assert set(props) == {'disabled'}
await cfg.option('u1').value.get() assert not await list_sessions()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled'}
if config_type == 'tiramisu-api':
await cfg.send()
await cfg_ori.property.add('permissive')
cfg = await get_config(cfg_ori, config_type)
await cfg.option('u1').value.get()
if config_type == 'tiramisu-api':
await cfg.send()
await cfg_ori.property.pop('permissive')
cfg = await get_config(cfg_ori, config_type)
props = frozenset()
try:
await cfg.option('u1').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled'}
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_permissive_pop(): async def test_permissive_pop():
descr = make_description() descr = make_description()
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
await cfg.property.read_write() await cfg.property.read_write()
props = frozenset() props = frozenset()
try: try:
await cfg.forcepermissive.option('u1').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled'}
await cfg.unrestraint.permissive.add('disabled')
assert await cfg.unrestraint.permissive.get() == frozenset(['hidden', 'disabled'])
await cfg.forcepermissive.option('u1').value.get() await cfg.forcepermissive.option('u1').value.get()
except PropertiesOptionError as err: await cfg.unrestraint.permissive.pop('disabled')
props = err.proptype props = frozenset()
assert set(props) == {'disabled'} try:
await cfg.unrestraint.permissive.add('disabled') await cfg.forcepermissive.option('u1').value.get()
assert await cfg.unrestraint.permissive.get() == frozenset(['hidden', 'disabled']) except PropertiesOptionError as err:
await cfg.forcepermissive.option('u1').value.get() props = err.proptype
await cfg.unrestraint.permissive.pop('disabled') assert set(props) == {'disabled'}
props = frozenset() assert not await list_sessions()
try:
await cfg.forcepermissive.option('u1').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled'}
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_permissive_reset(): async def test_permissive_reset():
descr = make_description() descr = make_description()
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
assert await cfg.unrestraint.permissive.get() == frozenset(['hidden']) assert await cfg.unrestraint.permissive.get() == frozenset(['hidden'])
# #
await cfg.unrestraint.permissive.add('disabled') await cfg.unrestraint.permissive.add('disabled')
await cfg.unrestraint.permissive.pop('hidden') await cfg.unrestraint.permissive.pop('hidden')
assert await cfg.unrestraint.permissive.get() == frozenset(['disabled']) assert await cfg.unrestraint.permissive.get() == frozenset(['disabled'])
# #
await cfg.unrestraint.permissive.reset() await cfg.unrestraint.permissive.reset()
assert await cfg.unrestraint.permissive.get() == frozenset() assert await cfg.unrestraint.permissive.get() == frozenset()
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_permissive_mandatory(): async def test_permissive_mandatory():
descr = make_description() descr = make_description()
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_only() await cfg.property.read_only()
props = frozenset() props = frozenset()
try: try:
await cfg.option('u1').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
await cfg.unrestraint.permissive.add('mandatory')
await cfg.unrestraint.permissive.add('disabled')
assert await cfg.unrestraint.permissive.get() == frozenset(['mandatory', 'disabled'])
await cfg.property.add('permissive')
await cfg.option('u1').value.get() await cfg.option('u1').value.get()
except PropertiesOptionError as err: await cfg.property.pop('permissive')
props = err.proptype try:
assert frozenset(props) == frozenset(['disabled']) await cfg.option('u1').value.get()
await cfg.unrestraint.permissive.add('mandatory') except PropertiesOptionError as err:
await cfg.unrestraint.permissive.add('disabled') props = err.proptype
assert await cfg.unrestraint.permissive.get() == frozenset(['mandatory', 'disabled']) assert frozenset(props) == frozenset(['disabled'])
await cfg.property.add('permissive') assert not await list_sessions()
await cfg.option('u1').value.get()
await cfg.property.pop('permissive')
try:
await cfg.option('u1').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_permissive_frozen(): async def test_permissive_frozen():
descr = make_description() descr = make_description()
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
await cfg.unrestraint.permissive.pop('hidden') await cfg.unrestraint.permissive.pop('hidden')
await cfg.unrestraint.permissive.add('frozen') await cfg.unrestraint.permissive.add('frozen')
await cfg.unrestraint.permissive.add('disabled') await cfg.unrestraint.permissive.add('disabled')
assert await cfg.unrestraint.permissive.get() == frozenset(['frozen', 'disabled']) assert await cfg.unrestraint.permissive.get() == frozenset(['frozen', 'disabled'])
assert await cfg.permissive.get() == frozenset(['frozen', 'disabled']) assert await cfg.permissive.get() == frozenset(['frozen', 'disabled'])
try: try:
await cfg.option('u1').value.set(1)
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
await cfg.property.add('permissive')
await cfg.option('u1').value.set(1) await cfg.option('u1').value.set(1)
except PropertiesOptionError as err: assert await cfg.option('u1').value.get() == 1
props = err.proptype await cfg.property.pop('permissive')
assert frozenset(props) == frozenset(['disabled']) try:
await cfg.property.add('permissive') await cfg.option('u1').value.set(1)
await cfg.option('u1').value.set(1) except PropertiesOptionError as err:
assert await cfg.option('u1').value.get() == 1 props = err.proptype
await cfg.property.pop('permissive') assert frozenset(props) == frozenset(['disabled'])
try: assert not await list_sessions()
await cfg.option('u1').value.set(1)
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_invalid_permissive(): async def test_invalid_permissive():
descr = make_description() descr = make_description()
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
# FIXME with pytest.raises(TypeError): # FIXME with pytest.raises(TypeError):
# await cfg.unrestraint.permissive.set(['frozen', 'disabled'])") # await cfg.unrestraint.permissive.set(['frozen', 'disabled'])")
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_forbidden_permissive(): async def test_forbidden_permissive():
descr = make_description() descr = make_description()
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
with pytest.raises(ConfigError): with pytest.raises(ConfigError):
await cfg.permissive.add('force_default_on_freeze') await cfg.permissive.add('force_default_on_freeze')
with pytest.raises(ConfigError): with pytest.raises(ConfigError):
await cfg.permissive.add('force_metaconfig_on_freeze') await cfg.permissive.add('force_metaconfig_on_freeze')
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_permissive_option(config_type): async def test_permissive_option(config_type):
descr = make_description() descr = make_description()
cfg_ori = await Config(descr) async with await Config(descr) as cfg_ori:
await cfg_ori.property.read_write() await cfg_ori.property.read_write()
cfg = await get_config(cfg_ori, config_type) cfg = await get_config(cfg_ori, config_type)
props = frozenset() props = frozenset()
try: try:
await cfg.option('u1').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled'}
props = frozenset()
try:
await cfg.option('u2').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled'}
if config_type == 'tiramisu-api':
await cfg.send()
await cfg_ori.unrestraint.option('u1').permissive.set(frozenset(['disabled']))
cfg = await get_config(cfg_ori, config_type)
props = frozenset()
try:
await cfg.option('u1').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset()
props = frozenset()
try:
await cfg.option('u2').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled'}
if config_type == 'tiramisu-api':
await cfg.send()
await cfg_ori.property.add('permissive')
cfg = await get_config(cfg_ori, config_type)
await cfg.option('u1').value.get() await cfg.option('u1').value.get()
except PropertiesOptionError as err: props = frozenset()
props = err.proptype try:
assert set(props) == {'disabled'} await cfg.option('u2').value.get()
props = frozenset() except PropertiesOptionError as err:
try: props = err.proptype
await cfg.option('u2').value.get() assert set(props) == {'disabled'}
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled'}
if config_type == 'tiramisu-api': if config_type == 'tiramisu-api':
await cfg.send() await cfg.send()
await cfg_ori.unrestraint.option('u1').permissive.set(frozenset(['disabled'])) await cfg_ori.property.pop('permissive')
cfg = await get_config(cfg_ori, config_type) cfg = await get_config(cfg_ori, config_type)
props = frozenset() props = frozenset()
try: try:
await cfg.option('u1').value.get() await cfg.option('u1').value.get()
except PropertiesOptionError as err: except PropertiesOptionError as err:
props = err.proptype props = err.proptype
assert frozenset(props) == frozenset() assert frozenset(props) == frozenset()
props = frozenset() props = frozenset()
try: try:
await cfg.option('u2').value.get() await cfg.option('u2').value.get()
except PropertiesOptionError as err: except PropertiesOptionError as err:
props = err.proptype props = err.proptype
assert set(props) == {'disabled'} assert set(props) == {'disabled'}
assert not await list_sessions()
if config_type == 'tiramisu-api':
await cfg.send()
await cfg_ori.property.add('permissive')
cfg = await get_config(cfg_ori, config_type)
await cfg.option('u1').value.get()
props = frozenset()
try:
await cfg.option('u2').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled'}
if config_type == 'tiramisu-api':
await cfg.send()
await cfg_ori.property.pop('permissive')
cfg = await get_config(cfg_ori, config_type)
props = frozenset()
try:
await cfg.option('u1').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset()
props = frozenset()
try:
await cfg.option('u2').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled'}
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_permissive_option_cache(): async def test_permissive_option_cache():
descr = make_description() descr = make_description()
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
props = frozenset() props = frozenset()
try: try:
await cfg.option('u1').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled'}
props = frozenset()
try:
await cfg.option('u2').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled'}
await cfg.unrestraint.option('u1').permissive.set(frozenset(['disabled']))
props = frozenset()
try:
await cfg.option('u1').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset()
props = frozenset()
try:
await cfg.option('u2').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled'}
await cfg.property.add('permissive')
await cfg.option('u1').value.get() await cfg.option('u1').value.get()
except PropertiesOptionError as err: props = frozenset()
props = err.proptype try:
assert set(props) == {'disabled'} await cfg.option('u2').value.get()
props = frozenset() except PropertiesOptionError as err:
try: props = err.proptype
await cfg.option('u2').value.get() assert set(props) == {'disabled'}
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled'}
await cfg.unrestraint.option('u1').permissive.set(frozenset(['disabled'])) await cfg.property.pop('permissive')
props = frozenset() props = frozenset()
try: try:
await cfg.option('u1').value.get() await cfg.option('u1').value.get()
except PropertiesOptionError as err: except PropertiesOptionError as err:
props = err.proptype props = err.proptype
assert frozenset(props) == frozenset() assert frozenset(props) == frozenset()
props = frozenset() props = frozenset()
try: try:
await cfg.option('u2').value.get() await cfg.option('u2').value.get()
except PropertiesOptionError as err: except PropertiesOptionError as err:
props = err.proptype props = err.proptype
assert set(props) == {'disabled'} assert set(props) == {'disabled'}
assert not await list_sessions()
await cfg.property.add('permissive')
await cfg.option('u1').value.get()
props = frozenset()
try:
await cfg.option('u2').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled'}
await cfg.property.pop('permissive')
props = frozenset()
try:
await cfg.option('u1').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset()
props = frozenset()
try:
await cfg.option('u2').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled'}
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_permissive_option_mandatory(): async def test_permissive_option_mandatory():
descr = make_description() descr = make_description()
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_only() await cfg.property.read_only()
props = frozenset() props = frozenset()
try: try:
await cfg.option('u1').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
await cfg.unrestraint.option('u1').permissive.set(frozenset(['mandatory', 'disabled']))
assert await cfg.unrestraint.option('u1').permissive.get() == frozenset(['mandatory', 'disabled'])
await cfg.property.add('permissive')
await cfg.option('u1').value.get() await cfg.option('u1').value.get()
except PropertiesOptionError as err: await cfg.property.pop('permissive')
props = err.proptype try:
assert frozenset(props) == frozenset(['disabled']) await cfg.option('u1').value.get()
await cfg.unrestraint.option('u1').permissive.set(frozenset(['mandatory', 'disabled'])) except PropertiesOptionError as err:
assert await cfg.unrestraint.option('u1').permissive.get() == frozenset(['mandatory', 'disabled']) props = err.proptype
await cfg.property.add('permissive') assert frozenset(props) == frozenset(['disabled'])
await cfg.option('u1').value.get() assert not await list_sessions()
await cfg.property.pop('permissive')
try:
await cfg.option('u1').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_permissive_option_frozen(): async def test_permissive_option_frozen():
descr = make_description() descr = make_description()
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
await cfg.unrestraint.option('u1').permissive.set(frozenset(['frozen', 'disabled'])) await cfg.unrestraint.option('u1').permissive.set(frozenset(['frozen', 'disabled']))
await cfg.option('u1').value.set(1) await cfg.option('u1').value.set(1)
assert await cfg.option('u1').value.get() == 1 assert await cfg.option('u1').value.get() == 1
await cfg.property.add('permissive') await cfg.property.add('permissive')
assert await cfg.option('u1').value.get() == 1 assert await cfg.option('u1').value.get() == 1
await cfg.property.pop('permissive') await cfg.property.pop('permissive')
assert await cfg.option('u1').value.get() == 1 assert await cfg.option('u1').value.get() == 1
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_invalid_option_permissive(): async def test_invalid_option_permissive():
descr = make_description() descr = make_description()
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
with pytest.raises(TypeError): with pytest.raises(TypeError):
await cfg.unrestraint.option('u1').permissive.set(['frozen', 'disabled']) await cfg.unrestraint.option('u1').permissive.set(['frozen', 'disabled'])
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_remove_option_permissive(config_type): async def test_remove_option_permissive(config_type):
var1 = StrOption('var1', '', u'value', properties=('hidden',)) var1 = StrOption('var1', '', u'value', properties=('hidden',))
od1 = OptionDescription('od1', '', [var1]) od1 = OptionDescription('od1', '', [var1])
rootod = OptionDescription('rootod', '', [od1]) descr = OptionDescription('rootod', '', [od1])
cfg_ori = await Config(rootod) async with await Config(descr) as cfg_ori:
await cfg_ori.property.read_write() await cfg_ori.property.read_write()
cfg = await get_config(cfg_ori, config_type) cfg = await get_config(cfg_ori, config_type)
with pytest.raises(PropertiesOptionError): with pytest.raises(PropertiesOptionError):
await cfg.option('od1.var1').value.get() await cfg.option('od1.var1').value.get()
if config_type == 'tiramisu-api': if config_type == 'tiramisu-api':
await cfg.send() await cfg.send()
await cfg_ori.forcepermissive.option('od1.var1').permissive.set(frozenset(['hidden'])) await cfg_ori.forcepermissive.option('od1.var1').permissive.set(frozenset(['hidden']))
assert await cfg_ori.forcepermissive.option('od1.var1').permissive.get() == frozenset(['hidden']) assert await cfg_ori.forcepermissive.option('od1.var1').permissive.get() == frozenset(['hidden'])
cfg = await get_config(cfg_ori, config_type) cfg = await get_config(cfg_ori, config_type)
assert await cfg.option('od1.var1').value.get() == 'value' assert await cfg.option('od1.var1').value.get() == 'value'
if config_type == 'tiramisu-api': if config_type == 'tiramisu-api':
await cfg.send() await cfg.send()
await cfg_ori.forcepermissive.option('od1.var1').permissive.set(frozenset()) await cfg_ori.forcepermissive.option('od1.var1').permissive.set(frozenset())
assert await cfg_ori.forcepermissive.option('od1.var1').permissive.get() == frozenset() assert await cfg_ori.forcepermissive.option('od1.var1').permissive.get() == frozenset()
cfg = await get_config(cfg_ori, config_type) cfg = await get_config(cfg_ori, config_type)
with pytest.raises(PropertiesOptionError): with pytest.raises(PropertiesOptionError):
await cfg.option('od1.var1').value.get() await cfg.option('od1.var1').value.get()
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_reset_option_permissive(config_type): async def test_reset_option_permissive(config_type):
var1 = StrOption('var1', '', u'value', properties=('hidden',)) var1 = StrOption('var1', '', u'value', properties=('hidden',))
od1 = OptionDescription('od1', '', [var1]) od1 = OptionDescription('od1', '', [var1])
rootod = OptionDescription('rootod', '', [od1]) descr = OptionDescription('rootod', '', [od1])
cfg_ori = await Config(rootod) async with await Config(descr) as cfg_ori:
await cfg_ori.property.read_write() await cfg_ori.property.read_write()
cfg = await get_config(cfg_ori, config_type) cfg = await get_config(cfg_ori, config_type)
with pytest.raises(PropertiesOptionError): with pytest.raises(PropertiesOptionError):
await cfg.option('od1.var1').value.get() await cfg.option('od1.var1').value.get()
if config_type == 'tiramisu-api': if config_type == 'tiramisu-api':
await cfg.send() await cfg.send()
await cfg_ori.forcepermissive.option('od1.var1').permissive.set(frozenset(['hidden'])) await cfg_ori.forcepermissive.option('od1.var1').permissive.set(frozenset(['hidden']))
assert await cfg_ori.forcepermissive.option('od1.var1').permissive.get() == frozenset(['hidden']) assert await cfg_ori.forcepermissive.option('od1.var1').permissive.get() == frozenset(['hidden'])
cfg = await get_config(cfg_ori, config_type) cfg = await get_config(cfg_ori, config_type)
assert await cfg.option('od1.var1').value.get() == 'value' assert await cfg.option('od1.var1').value.get() == 'value'
if config_type == 'tiramisu-api': if config_type == 'tiramisu-api':
await cfg.send() await cfg.send()
await cfg_ori.forcepermissive.option('od1.var1').permissive.reset() await cfg_ori.forcepermissive.option('od1.var1').permissive.reset()
assert await cfg_ori.forcepermissive.option('od1.var1').permissive.get() == frozenset() assert await cfg_ori.forcepermissive.option('od1.var1').permissive.get() == frozenset()
cfg = await get_config(cfg_ori, config_type) cfg = await get_config(cfg_ori, config_type)
with pytest.raises(PropertiesOptionError): with pytest.raises(PropertiesOptionError):
await cfg.option('od1.var1').value.get() await cfg.option('od1.var1').value.get()
assert not await list_sessions()

File diff suppressed because it is too large Load diff

View file

@ -3,7 +3,6 @@ from .autopath import do_autopath
do_autopath() do_autopath()
import pytest import pytest
from py.test import raises
import warnings import warnings
try: try:
@ -18,60 +17,72 @@ from tiramisu.option import ChoiceOption, BoolOption, IntOption, FloatOption,\
PortOption, NetworkOption, NetmaskOption, DomainnameOption, EmailOption, \ PortOption, NetworkOption, NetmaskOption, DomainnameOption, EmailOption, \
URLOption, FilenameOption URLOption, FilenameOption
from tiramisu.storage import list_sessions, delete_session from tiramisu.storage import list_sessions, delete_session
from .config import event_loop
def teardown_function(function):
with warnings.catch_warnings(record=True) as w:
assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__)
def test_slots_option(): def test_slots_option():
c = ChoiceOption('a', '', ('a',)) c = ChoiceOption('a', '', ('a',))
raises(AttributeError, "c.x = 1") with pytest.raises(AttributeError):
c.x = 1
del c del c
c = BoolOption('a', '') c = BoolOption('a', '')
raises(AttributeError, "c.x = 1") with pytest.raises(AttributeError):
c.x = 1
del c del c
c = IntOption('a', '') c = IntOption('a', '')
raises(AttributeError, "c.x = 1") with pytest.raises(AttributeError):
c.x = 1
del c del c
c = FloatOption('a', '') c = FloatOption('a', '')
raises(AttributeError, "c.x = 1") with pytest.raises(AttributeError):
c.x = 1
del c del c
c = StrOption('a', '') c = StrOption('a', '')
raises(AttributeError, "c.x = 1") with pytest.raises(AttributeError):
c.x = 1
c = SymLinkOption('b', c) c = SymLinkOption('b', c)
raises(AttributeError, "c.x = 1") with pytest.raises(AttributeError):
c.x = 1
del c del c
c = StrOption('a', '') c = StrOption('a', '')
raises(AttributeError, "c.x = 1") with pytest.raises(AttributeError):
c.x = 1
del c del c
c = IPOption('a', '') c = IPOption('a', '')
raises(AttributeError, "c.x = 1") with pytest.raises(AttributeError):
c.x = 1
del c del c
c = OptionDescription('a', '', []) c = OptionDescription('a', '', [])
raises(AttributeError, "c.x = 1") with pytest.raises(AttributeError):
c.x = 1
del c del c
c = PortOption('a', '') c = PortOption('a', '')
raises(AttributeError, "c.x = 1") with pytest.raises(AttributeError):
c.x = 1
del c del c
c = NetworkOption('a', '') c = NetworkOption('a', '')
raises(AttributeError, "c.x = 1") with pytest.raises(AttributeError):
c.x = 1
del c del c
c = NetmaskOption('a', '') c = NetmaskOption('a', '')
raises(AttributeError, "c.x = 1") with pytest.raises(AttributeError):
c.x = 1
del c del c
c = DomainnameOption('a', '') c = DomainnameOption('a', '')
raises(AttributeError, "c.x = 1") with pytest.raises(AttributeError):
c.x = 1
del c del c
c = EmailOption('a', '') c = EmailOption('a', '')
raises(AttributeError, "c.x = 1") with pytest.raises(AttributeError):
c.x = 1
del c del c
c = URLOption('a', '') c = URLOption('a', '')
raises(AttributeError, "c.x = 1") with pytest.raises(AttributeError):
c.x = 1
del c del c
c = FilenameOption('a', '') c = FilenameOption('a', '')
raises(AttributeError, "c.x = 1") with pytest.raises(AttributeError):
c.x = 1
del c del c
@ -107,22 +118,39 @@ async def test_slots_option_readonly():
o._name = 'o' o._name = 'o'
p._name = 'p' p._name = 'p'
q._name = 'q' q._name = 'q'
await Config(m) async with await Config(m) as cfg:
raises(AttributeError, "a._requires = 'a'") pass
raises(AttributeError, "b._requires = 'b'") with pytest.raises(AttributeError):
raises(AttributeError, "c._requires = 'c'") a._requires = 'a'
raises(AttributeError, "d._requires = 'd'") with pytest.raises(AttributeError):
raises(AttributeError, "e._requires = 'e'") b._requires = 'b'
raises(AttributeError, "g._requires = 'g'") with pytest.raises(AttributeError):
raises(AttributeError, "h._requires = 'h'") c._requires = 'c'
raises(AttributeError, "i._requires = 'i'") with pytest.raises(AttributeError):
raises(AttributeError, "j._requires = 'j'") d._requires = 'd'
raises(AttributeError, "k._requires = 'k'") with pytest.raises(AttributeError):
raises(AttributeError, "l._requires = 'l'") e._requires = 'e'
raises(AttributeError, "m._requires = 'm'") with pytest.raises(AttributeError):
raises(AttributeError, "o._requires = 'o'") g._requires = 'g'
raises(AttributeError, "p._requires = 'p'") with pytest.raises(AttributeError):
raises(AttributeError, "q._requires = 'q'") h._requires = 'h'
with pytest.raises(AttributeError):
i._requires = 'i'
with pytest.raises(AttributeError):
j._requires = 'j'
with pytest.raises(AttributeError):
k._requires = 'k'
with pytest.raises(AttributeError):
l._requires = 'l'
with pytest.raises(AttributeError):
m._requires = 'm'
with pytest.raises(AttributeError):
o._requires = 'o'
with pytest.raises(AttributeError):
p._requires = 'p'
with pytest.raises(AttributeError):
q._requires = 'q'
assert not await list_sessions()
#def test_slots_description(): #def test_slots_description():
@ -138,34 +166,43 @@ async def test_slots_option_readonly():
async def test_slots_config(): async def test_slots_config():
od1 = OptionDescription('a', '', []) od1 = OptionDescription('a', '', [])
od2 = OptionDescription('a', '', [od1]) od2 = OptionDescription('a', '', [od1])
c = await Config(od2) async with await Config(od2) as c:
raises(AttributeError, "c._config_bag.context.x = 1") with pytest.raises(AttributeError):
raises(AttributeError, "c._config_bag.context.cfgimpl_x = 1") c._config_bag.context.x = 1
option_bag = OptionBag() with pytest.raises(AttributeError):
option_bag.set_option(od2, c._config_bag.context.cfgimpl_x = 1
'a', option_bag = OptionBag()
ConfigBag(c._config_bag.context, None, None)) option_bag.set_option(od2,
sc = await c._config_bag.context.get_subconfig(option_bag) 'a',
assert isinstance(sc, SubConfig) ConfigBag(c._config_bag.context, None, None))
raises(AttributeError, "sc.x = 1") sc = await c._config_bag.context.get_subconfig(option_bag)
raises(AttributeError, "sc.cfgimpl_x = 1") assert isinstance(sc, SubConfig)
with pytest.raises(AttributeError):
sc.x = 1
with pytest.raises(AttributeError):
sc.cfgimpl_x = 1
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_slots_setting(): async def test_slots_setting():
od1 = OptionDescription('a', '', []) od1 = OptionDescription('a', '', [])
od2 = OptionDescription('a', '', [od1]) od2 = OptionDescription('a', '', [od1])
c = await Config(od2) async with await Config(od2) as c:
s = c._config_bag.context.cfgimpl_get_settings() s = c._config_bag.context.cfgimpl_get_settings()
s s
raises(AttributeError, "s.x = 1") with pytest.raises(AttributeError):
s.x = 1
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_slots_value(): async def test_slots_value():
od1 = OptionDescription('a', '', []) od1 = OptionDescription('a', '', [])
od2 = OptionDescription('a', '', [od1]) od2 = OptionDescription('a', '', [od1])
c = await Config(od2) async with await Config(od2) as c:
v = c._config_bag.context.cfgimpl_get_values() v = c._config_bag.context.cfgimpl_get_values()
v v
raises(AttributeError, "v.x = 1") with pytest.raises(AttributeError):
v.x = 1
assert not await list_sessions()

View file

@ -1,215 +1,12 @@
#from autopath import do_autopath from .autopath import do_autopath
#do_autopath() do_autopath()
#
from tiramisu import BoolOption, StrOption, SymLinkOption, OptionDescription, DynOptionDescription, \ from tiramisu import BoolOption, StrOption, SymLinkOption, OptionDescription, DynOptionDescription, \
Calculation, Params, ParamOption, ParamValue, calc_value, Config Calculation, Params, ParamOption, ParamValue, calc_value, Config
from pickle import dumps from pickle import dumps
from py.test import raises
import pytest import pytest
import sys, warnings import sys, warnings
from tiramisu.storage import list_sessions from tiramisu.storage import list_sessions
from .config import event_loop
def teardown_function(function):
with warnings.catch_warnings(record=True) as w:
assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__)
def _get_slots(opt):
slots = set()
for subclass in opt.__class__.__mro__:
if subclass is not object and '__slots__' in dir(subclass):
slots.update(subclass.__slots__)
return slots
def _no_state(opt):
for attr in _get_slots(opt):
if 'state' in attr:
try:
getattr(opt, attr)
except:
pass
else:
raise Exception('opt should have already attribute {0}'.format(attr))
def _diff_opt(opt1, opt2):
attr1 = set(_get_slots(opt1))
attr2 = set(_get_slots(opt2))
diff1 = attr1 - attr2
diff2 = attr2 - attr1
if diff1 != set():
raise Exception('more attribute in opt1 {0}'.format(list(diff1)))
if diff2 != set():
raise Exception('more attribute in opt2 {0}'.format(list(diff2)))
for attr in attr1:
if attr in ['_cache_paths', '_cache_consistencies']:
continue
err1 = False
err2 = False
val1 = None
val2 = None
try:
val1 = getattr(opt1, attr)
msg1 = "exists"
tval = val1
except:
err1 = True
msg1 = "not exists"
try:
val2 = getattr(opt2, attr)
msg2 = "exists"
tval = val2
except:
err2 = True
msg2 = "not exists"
if not err1 == err2:
raise ValueError("{0} {1} before but {2} after for {3}: {4}".format(attr, msg1, msg2, opt1.impl_getname(), tval))
if val1 is None:
assert val1 == val2
elif attr == '_children':
assert val1[0] == val2[0]
for index, _opt in enumerate(val1[1]):
assert _opt._name == val2[1][index]._name
elif attr == '_requires':
if val1 == val2 == []:
pass
else:
for idx1, req1 in enumerate(val1):
for idx2, req2 in enumerate(val1[idx1]):
for idx3, req3 in enumerate(val1[idx1][idx2][0]):
assert val1[idx1][idx2][0][idx3][0].impl_getname() == val2[idx1][idx2][0][idx3][0].impl_getname()
assert val1[idx1][idx2][0][idx3][1] == val2[idx1][idx2][0][idx3][1]
assert val1[idx1][idx2][1:] == val2[idx1][idx2][1:], '{} - {}\n{} - {}'.format(val1, val2, val1[0][0][1:], val2[0][0][1:])
elif attr == '_opt':
assert val1._name == val2._name
elif attr == '_consistencies':
# dict is only a cache
if isinstance(val1, list):
for index, consistency in enumerate(val1):
assert consistency[0] == val2[index][0]
for idx, opt in enumerate(consistency[1]):
assert opt._name == val2[index][1][idx]._name
elif attr == '_val_call':
for idx, v in enumerate(val1):
if v is None:
assert val2[idx] is None
else:
assert v[0] == val2[idx][0]
if len(v) == 2:
if v[1] is not None:
for key, values in v[1].items():
for i, value in enumerate(values):
if isinstance(value, tuple) and value[0] is not None:
assert v[1][key][i][0].impl_getname() == val2[idx][1][key][i][0].impl_getname()
assert v[1][key][i][1] == val2[idx][1][key][i][1]
else:
assert v[1][key][i] == val2[idx][1][key][i]
else:
assert v[1] == val2[idx][1]
elif attr == '_leadership':
assert val1._p_._sm_get_leader().impl_getname() == val2._p_._sm_get_leader().impl_getname()
sval1 = [opt.impl_getname() for opt in val1._p_._sm_get_followers()]
sval2 = [opt.impl_getname() for opt in val2._p_._sm_get_followers()]
assert sval1 == sval2
elif attr == '_subdyn':
try:
assert val1.impl_getname() == val2.impl_getname()
except AttributeError:
assert val1 == val2
elif attr == '_dependencies':
assert len(val1) == len(val2), "_dependencies has not same len: {} - {}".format(val1, val2)
lst1 = []
lst2 = []
for idx, val in enumerate(val1):
if isinstance(val, Leadership):
lst1.append(val._p_.leader.impl_getname())
else:
lst1.append(val.impl_getname())
for idx, val in enumerate(val2):
if isinstance(val, Leadership):
lst2.append(val._p_.leader.impl_getname())
else:
lst2.append(val.impl_getname())
assert set(lst1) == set(lst2), '{} - {}'.format(lst1, lst2)
elif attr == '_cache_force_store_values':
for idx, tup in enumerate(val1):
assert tup[0] == val2[idx][0]
assert tup[1].impl_getname() == val2[idx][1].impl_getname()
elif attr in ['_extra', '_information']:
dico1 = {}
dico2 = {}
assert len(val1[0]) == len(val2[0])
assert set(val1[0]) == set(val2[0])
for idx, val in enumerate(val1[0]):
idx2 = val1[0].index(val)
assert val1[1][idx] == val1[1][idx2]
else:
#print(attr, val1, val2)
assert val1 == val2, "error for {}".format(attr)
def _diff_opts(opt1, opt2):
_diff_opt(opt1, opt2)
if isinstance(opt1, OptionDescription) or isinstance(opt1, DynOptionDescription):
children1 = set([opt.impl_getname() for opt in opt1.impl_getchildren(dyn=False)])
children2 = set([opt.impl_getname() for opt in opt2.impl_getchildren(dyn=False)])
diff1 = children1 - children2
diff2 = children2 - children1
if diff1 != set():
raise Exception('more attribute in opt1 {0}'.format(list(diff1)))
if diff2 != set():
raise Exception('more attribute in opt2 {0}'.format(list(diff2)))
for child in children1:
_diff_opts(opt1._getattr(child, dyn=False), opt2._getattr(child, dyn=False))
def _diff_conf(cfg1, cfg2):
attr1 = set(_get_slots(cfg1))
attr2 = set(_get_slots(cfg2))
diff1 = attr1 - attr2
diff2 = attr2 - attr1
if diff1 != set():
raise Exception('more attribute in cfg1 {0}'.format(list(diff1)))
if diff2 != set():
raise Exception('more attribute in cfg2 {0}'.format(list(diff2)))
for attr in attr1:
if attr in ('_impl_context', '__weakref__'):
continue
err1 = False
err2 = False
val1 = None
val2 = None
try:
val1 = getattr(cfg1, attr)
except:
err1 = True
try:
val2 = getattr(cfg2, attr)
except:
err2 = True
assert err1 == err2
if val1 is None:
assert val1 == val2
elif attr == '_impl_values':
assert cfg1.cfgimpl_get_values().get_modified_values() == cfg2.cfgimpl_get_values().get_modified_values()
elif attr == '_impl_settings':
assert cfg1.cfgimpl_get_settings().get_modified_properties() == cfg2.cfgimpl_get_settings().get_modified_properties()
assert cfg1.cfgimpl_get_settings().get_modified_permissives() == cfg2.cfgimpl_get_settings().get_modified_permissives()
elif attr == '_impl_descr':
_diff_opt(cfg1.cfgimpl_get_description(), cfg2.cfgimpl_get_description())
elif attr == '_impl_children':
for index, _opt in enumerate(val1):
_diff_conf(_opt, val2[index])
elif attr == '_impl_name':
#FIXME
pass
else:
assert val1 == val2
def test_diff_opt(): def test_diff_opt():
@ -224,7 +21,8 @@ def test_diff_opt():
o = OptionDescription('o', '', [b, u, s]) o = OptionDescription('o', '', [b, u, s])
o1 = OptionDescription('o1', '', [o]) o1 = OptionDescription('o1', '', [o])
raises(NotImplementedError, "dumps(o1)") with pytest.raises(NotImplementedError):
dumps(o1)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -235,12 +33,15 @@ async def test_diff_information_config():
b.impl_set_information('info2', 'oh') b.impl_set_information('info2', 'oh')
o = OptionDescription('o', '', [b]) o = OptionDescription('o', '', [b])
o1 = OptionDescription('o1', '', [o]) o1 = OptionDescription('o1', '', [o])
d = await Config(o1) async with await Config(o1) as cfg:
c = d._config_bag.context c = cfg._config_bag.context
raises(NotImplementedError, "dumps(c)") with pytest.raises(NotImplementedError):
dumps(c)
assert not await list_sessions()
def test_only_optiondescription(): def test_only_optiondescription():
b = BoolOption('b', '') b = BoolOption('b', '')
b b
raises(NotImplementedError, "a = dumps(b)") with pytest.raises(NotImplementedError):
dumps(b)

View file

@ -9,150 +9,127 @@ from tiramisu.error import ConfigError
from tiramisu import Config, BoolOption, OptionDescription, Leadership, \ from tiramisu import Config, BoolOption, OptionDescription, Leadership, \
list_sessions, delete_session, default_storage, MetaConfig list_sessions, delete_session, default_storage, MetaConfig
from tiramisu.setting import groups, owners from tiramisu.setting import groups, owners
from .config import event_loop
def teardown_function(function):
assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__)
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_non_persistent(): async def test_non_persistent():
b = BoolOption('b', '') b = BoolOption('b', '')
o = OptionDescription('od', '', [b]) o = OptionDescription('od', '', [b])
await Config(o, session_id='test_non_persistent') async with await Config(o, session_id='test_non_persistent', delete_old_session=True) as cfg:
pass
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_list(): async def test_list():
b = BoolOption('b', '') b = BoolOption('b', '')
o = OptionDescription('od', '', [b]) o = OptionDescription('od', '', [b])
cfg = await Config(o, session_id='test_non_persistent') async with await Config(o, session_id='test_non_persistent') as cfg:
await cfg.option('b').value.set(True) await cfg.option('b').value.set(True)
assert 'test_non_persistent' in list_sessions() assert 'test_non_persistent' in await list_sessions()
del(cfg) assert 'test_non_persistent' not in await list_sessions()
assert 'test_non_persistent' not in list_sessions() assert not await list_sessions()
@pytest.mark.asyncio
async def test_delete_not_persistent():
b = BoolOption('b', '')
o = OptionDescription('od', '', [b])
if not default_storage.is_persistent():
cfg = await Config(o, session_id='not_test_persistent')
assert 'not_test_persistent' in list_sessions()
del cfg
assert 'not_test_persistent' not in list_sessions()
#
cfg = await Config(o, session_id='not_test_persistent')
raises(ValueError, "delete_session('not_test_persistent')")
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_create_persistent(): async def test_create_persistent():
b = BoolOption('b', '') b = BoolOption('b', '')
o = OptionDescription('od', '', [b]) o = OptionDescription('od', '', [b])
if default_storage.is_persistent(): await Config(o, session_id='test_persistent')
await Config(o, session_id='test_persistent', persistent=True) await delete_session('test_persistent')
delete_session('test_persistent') assert not await list_sessions()
@pytest.mark.asyncio
async def test_create_delete_not_persistent():
b = BoolOption('b', '')
o = OptionDescription('od', '', [b])
if not default_storage.is_persistent():
raises(ValueError, "delete_session('test_persistent')")
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_list_sessions_persistent(): async def test_list_sessions_persistent():
b = BoolOption('b', '') b = BoolOption('b', '')
o = OptionDescription('od', '', [b]) o = OptionDescription('od', '', [b])
if default_storage.is_persistent(): cfg = await Config(o, session_id='test_persistent')
cfg = await Config(o, session_id='test_persistent', persistent=True) await cfg.option('b').value.set(True)
await cfg.option('b').value.set(True) assert 'test_persistent' in await list_sessions()
assert 'test_persistent' in list_sessions() await delete_session('test_persistent')
delete_session('test_persistent') assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_delete_session_persistent(): async def test_delete_session_persistent():
b = BoolOption('b', '') b = BoolOption('b', '')
o = OptionDescription('od', '', [b]) o = OptionDescription('od', '', [b])
if default_storage.is_persistent(): await Config(o, session_id='test_persistent')
await Config(o, session_id='test_persistent', persistent=True) assert 'test_persistent' in await list_sessions()
assert 'test_persistent' in list_sessions() await delete_session('test_persistent')
delete_session('test_persistent') assert 'test_persistent' not in await list_sessions()
assert 'test_persistent' not in list_sessions() assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_create_persistent_retrieve(): async def test_create_persistent_retrieve():
b = BoolOption('b', '') b = BoolOption('b', '')
o = OptionDescription('od', '', [b]) o = OptionDescription('od', '', [b])
if default_storage.is_persistent(): cfg = await Config(o, session_id='test_persistent')
cfg = await Config(o, session_id='test_persistent', persistent=True) assert await cfg.option('b').value.get() is None
assert await cfg.option('b').value.get() is None await cfg.option('b').value.set(True)
await cfg.option('b').value.set(True) assert await cfg.option('b').value.get() is True
assert await cfg.option('b').value.get() is True del cfg
del cfg cfg = await Config(o, session_id='test_persistent')
cfg = await Config(o, session_id='test_persistent', persistent=True) assert await cfg.option('b').value.get() is True
assert await cfg.option('b').value.get() is True assert 'test_persistent' in await list_sessions()
assert 'test_persistent' in list_sessions() await delete_session(await cfg.session.id())
delete_session(await cfg.config.name()) del cfg
del cfg cfg = await Config(o, session_id='test_persistent')
cfg = await Config(o, session_id='test_persistent', persistent=True) assert await cfg.option('b').value.get() is None
assert await cfg.option('b').value.get() is None await delete_session(await cfg.session.id())
delete_session(await cfg.config.name()) del cfg
del cfg assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_two_persistent(): async def test_two_persistent():
b = BoolOption('b', '') b = BoolOption('b', '')
o = OptionDescription('od', '', [b]) o = OptionDescription('od', '', [b])
if default_storage.is_persistent(): cfg = await Config(o, session_id='test_persistent')
cfg = await Config(o, session_id='test_persistent', persistent=True) cfg2 = await Config(o, session_id='test_persistent')
cfg2 = await Config(o, session_id='test_persistent', persistent=True) await cfg2.property.pop('cache')
await cfg2.property.pop('cache') assert await cfg.option('b').value.get() is None
assert await cfg.option('b').value.get() is None assert await cfg2.option('b').value.get() is None
assert await cfg2.option('b').value.get() is None #
# await cfg.option('b').value.set(False)
await cfg.option('b').value.set(False) assert await cfg.option('b').value.get() is False
assert await cfg.option('b').value.get() is False assert await cfg2.option('b').value.get() is False
assert await cfg2.option('b').value.get() is False #
# await cfg.option('b').value.set(True)
await cfg.option('b').value.set(True) assert await cfg.option('b').value.get() is True
assert await cfg.option('b').value.get() is True assert await cfg2.option('b').value.get() is True
assert await cfg2.option('b').value.get() is True await delete_session('test_persistent')
delete_session('test_persistent') assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_create_persistent_retrieve_owner(): async def test_create_persistent_retrieve_owner():
b = BoolOption('b', '') b = BoolOption('b', '')
o = OptionDescription('od', '', [b]) o = OptionDescription('od', '', [b])
if default_storage.is_persistent(): cfg = await Config(o, session_id='test_persistent')
cfg = await Config(o, session_id='test_persistent', persistent=True) assert await cfg.option('b').owner.isdefault()
assert await cfg.option('b').owner.isdefault() await cfg.option('b').value.set(True)
await cfg.option('b').value.set(True) assert await cfg.option('b').value.get()
assert await cfg.option('b').value.get() assert await cfg.option('b').owner.get() == 'user'
assert await cfg.option('b').owner.get() == 'user' ##owners.addowner('persistentowner')
##owners.addowner('persistentowner') await cfg.option('b').owner.set('persistentowner')
await cfg.option('b').owner.set('persistentowner') assert await cfg.option('b').owner.get() == 'persistentowner'
assert await cfg.option('b').owner.get() == 'persistentowner' del cfg
del cfg #
# cfg = await Config(o, session_id='test_persistent')
cfg = await Config(o, session_id='test_persistent', persistent=True) await cfg.option('b').owner.set('persistentowner')
await cfg.option('b').owner.set('persistentowner') await delete_session(await cfg.session.id())
delete_session(await cfg.config.name()) del cfg
del cfg #
# cfg = await Config(o, session_id='test_persistent')
cfg = await Config(o, session_id='test_persistent', persistent=True) assert await cfg.option('b').value.get() is None
assert await cfg.option('b').value.get() is None assert await cfg.option('b').owner.isdefault()
assert await cfg.option('b').owner.isdefault() await delete_session(await cfg.session.id())
delete_session(await cfg.config.name()) del cfg
del cfg assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -161,213 +138,196 @@ async def test_create_persistent_retrieve_owner_leadership():
b = BoolOption('b', '', multi=True) b = BoolOption('b', '', multi=True)
o = Leadership('a', '', [a, b]) o = Leadership('a', '', [a, b])
o1 = OptionDescription('a', '', [o]) o1 = OptionDescription('a', '', [o])
if default_storage.is_persistent(): cfg = await Config(o1, session_id='test_persistent')
cfg = await Config(o1, session_id='test_persistent', persistent=True) assert await cfg.option('a.a').owner.isdefault()
assert await cfg.option('a.a').owner.isdefault() await cfg.option('a.a').value.set([True, False])
await cfg.option('a.a').value.set([True, False]) await cfg.option('a.b', 1).value.set(True)
await cfg.option('a.b', 1).value.set(True) assert await cfg.option('a.a').owner.get() == 'user'
assert await cfg.option('a.a').owner.get() == 'user' assert await cfg.option('a.b', 0).owner.isdefault()
assert await cfg.option('a.b', 0).owner.isdefault() assert await cfg.option('a.b', 1).owner.get() == 'user'
assert await cfg.option('a.b', 1).owner.get() == 'user' #owners.addowner('persistentowner2')
#owners.addowner('persistentowner2') await cfg.option('a.b', 1).owner.set('persistentowner2')
await cfg.option('a.b', 1).owner.set('persistentowner2') await cfg.option('a.b', 0).value.set(True)
await cfg.option('a.b', 0).value.set(True) assert await cfg.option('a.b', 0).owner.get() == 'user'
assert await cfg.option('a.b', 0).owner.get() == 'user' assert await cfg.option('a.b', 1).owner.get() == 'persistentowner2'
assert await cfg.option('a.b', 1).owner.get() == 'persistentowner2' assert await cfg.option('a.a').value.get() == [True, False]
assert await cfg.option('a.a').value.get() == [True, False] del cfg
del cfg #
# cfg = await Config(o1, session_id='test_persistent')
cfg = await Config(o1, session_id='test_persistent', persistent=True) assert await cfg.option('a.a').value.get() == [True, False]
assert await cfg.option('a.a').value.get() == [True, False] assert await cfg.option('a.b', 0).owner.get() == 'user'
assert await cfg.option('a.b', 0).owner.get() == 'user' assert await cfg.option('a.b', 1).owner.get() == 'persistentowner2'
assert await cfg.option('a.b', 1).owner.get() == 'persistentowner2' await delete_session(await cfg.session.id())
delete_session(await cfg.config.name()) del cfg
del cfg #
# cfg = await Config(o1, session_id='test_persistent')
cfg = await Config(o1, session_id='test_persistent', persistent=True) assert await cfg.option('a.a').value.get() == []
assert await cfg.option('a.a').value.get() == [] await delete_session(await cfg.session.id())
delete_session(await cfg.config.name()) del cfg
del cfg assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_two_persistent_owner(): async def test_two_persistent_owner():
b = BoolOption('b', '') b = BoolOption('b', '')
o = OptionDescription('od', '', [b]) o = OptionDescription('od', '', [b])
if default_storage.is_persistent(): cfg = await Config(o, session_id='test_persistent')
cfg = await Config(o, session_id='test_persistent', persistent=True) await cfg.property.pop('cache')
await cfg.property.pop('cache') cfg2 = await Config(o, session_id='test_persistent')
cfg2 = await Config(o, session_id='test_persistent', persistent=True) await cfg2.property.pop('cache')
await cfg2.property.pop('cache') assert await cfg.option('b').owner.isdefault()
assert await cfg.option('b').owner.isdefault() assert await cfg2.option('b').owner.isdefault()
assert await cfg2.option('b').owner.isdefault() await cfg.option('b').value.set(False)
await cfg.option('b').value.set(False) assert await cfg.option('b').owner.get() == 'user'
assert await cfg.option('b').owner.get() == 'user' assert await cfg2.option('b').owner.get() == 'user'
assert await cfg2.option('b').owner.get() == 'user' await cfg.option('b').owner.set('persistent')
await cfg.option('b').owner.set('persistent') assert await cfg.option('b').owner.get() == 'persistent'
assert await cfg.option('b').owner.get() == 'persistent' assert await cfg2.option('b').owner.get() == 'persistent'
assert await cfg2.option('b').owner.get() == 'persistent' await delete_session('test_persistent')
delete_session('test_persistent') assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_create_persistent_retrieve_information(): async def test_create_persistent_retrieve_information():
b = BoolOption('b', '') b = BoolOption('b', '')
o = OptionDescription('od', '', [b]) o = OptionDescription('od', '', [b])
if default_storage.is_persistent(): cfg = await Config(o, session_id='test_persistent')
cfg = await Config(o, session_id='test_persistent', persistent=True) await cfg.information.set('info', 'string')
await cfg.information.set('info', 'string') assert await cfg.information.get('info') == 'string'
assert await cfg.information.get('info') == 'string' del cfg
del cfg #
# cfg = await Config(o, session_id='test_persistent')
cfg = await Config(o, session_id='test_persistent', persistent=True) assert await cfg.information.get('info') == 'string'
assert await cfg.information.get('info') == 'string' await delete_session(await cfg.session.id())
delete_session(await cfg.config.name()) del cfg
del cfg #
# cfg = await Config(o, session_id='test_persistent')
cfg = await Config(o, session_id='test_persistent', persistent=True) assert await cfg.information.get('info', None) is None
assert await cfg.information.get('info', None) is None await delete_session(await cfg.session.id())
delete_session(await cfg.config.name()) del cfg
del cfg assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_two_persistent_information(): async def test_two_persistent_information():
b = BoolOption('b', '') b = BoolOption('b', '')
o = OptionDescription('od', '', [b]) o = OptionDescription('od', '', [b])
if default_storage.is_persistent(): cfg = await Config(o, session_id='test_persistent')
cfg = await Config(o, session_id='test_persistent', persistent=True) await cfg.property.pop('cache')
await cfg.property.pop('cache') await cfg.information.set('info', 'string')
await cfg.information.set('info', 'string') assert await cfg.information.get('info') == 'string'
assert await cfg.information.get('info') == 'string' cfg2 = await Config(o, session_id='test_persistent')
cfg2 = await Config(o, session_id='test_persistent', persistent=True) await cfg2.property.pop('cache')
await cfg2.property.pop('cache') assert await cfg2.information.get('info') == 'string'
assert await cfg2.information.get('info') == 'string' await delete_session('test_persistent')
delete_session('test_persistent') assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_two_different_persistents(): async def test_two_different_persistents():
b = BoolOption('b', '') b = BoolOption('b', '')
o = OptionDescription('od', '', [b]) o = OptionDescription('od', '', [b])
if default_storage.is_persistent(): cfg = await Config(o, session_id='test_persistent')
cfg = await Config(o, session_id='test_persistent', persistent=True) await cfg.property.pop('cache')
await cfg.property.pop('cache') cfg2 = await Config(o, session_id='test_persistent2')
cfg2 = await Config(o, session_id='test_persistent2', persistent=True) await cfg2.property.pop('cache')
await cfg2.property.pop('cache') await cfg.option('b').property.add('test')
await cfg.option('b').property.add('test') assert await cfg.option('b').property.get() == {'test'}
assert await cfg.option('b').property.get() == {'test'} assert await cfg2.option('b').property.get() == set()
assert await cfg2.option('b').property.get() == set() assert await cfg.option('b').value.get() is None
assert await cfg.option('b').value.get() is None assert await cfg2.option('b').value.get() is None
assert await cfg2.option('b').value.get() is None await cfg.option('b').value.set(True)
await cfg.option('b').value.set(True) assert await cfg.option('b').value.get() == True
assert await cfg.option('b').value.get() == True assert await cfg2.option('b').value.get() is None
assert await cfg2.option('b').value.get() is None
delete_session('test_persistent') await delete_session('test_persistent')
delete_session('test_persistent2') await delete_session('test_persistent2')
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_two_different_information(): async def test_two_different_information():
b = BoolOption('b', '') b = BoolOption('b', '')
o = OptionDescription('od', '', [b]) o = OptionDescription('od', '', [b])
if default_storage.is_persistent(): cfg = await Config(o, session_id='test_persistent')
cfg = await Config(o, session_id='test_persistent', persistent=True) await cfg.information.set('a', 'a')
await cfg.information.set('a', 'a') cfg2 = await Config(o, session_id='test_persistent2')
cfg2 = await Config(o, session_id='test_persistent2', persistent=True) await cfg2.information.set('a', 'b')
await cfg2.information.set('a', 'b') assert await cfg.information.get('a') == 'a'
assert await cfg.information.get('a') == 'a' assert await cfg2.information.get('a') == 'b'
assert await cfg2.information.get('a') == 'b'
delete_session('test_persistent') await delete_session('test_persistent')
delete_session('test_persistent2') await delete_session('test_persistent2')
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_exportation_importation(): async def test_exportation_importation():
b = BoolOption('b', '') b = BoolOption('b', '')
o = OptionDescription('od', '', [b]) o = OptionDescription('od', '', [b])
if default_storage.is_persistent(): cfg = await Config(o, session_id='test_persistent')
cfg = await Config(o, session_id='test_persistent', persistent=True) cfg2 = await Config(o, session_id='test_persistent2')
cfg2 = await Config(o, session_id='test_persistent2', persistent=True) cfg3 = await Config(o, session_id='test_persistent3')
cfg3 = await Config(o, session_id='test_persistent3', persistent=True) await cfg.owner.set('export')
await cfg.owner.set('export') assert await cfg.option('b').value.get() is None
assert await cfg.option('b').value.get() is None await cfg.option('b').value.set(True)
await cfg.option('b').value.set(True) assert await cfg.option('b').value.get() is True
assert await cfg.option('b').value.get() is True assert await cfg.owner.get() == 'export'
assert await cfg.owner.get() == 'export' del cfg
del cfg #
# cfg = await Config(o, session_id='test_persistent')
cfg = await Config(o, session_id='test_persistent', persistent=True) assert await cfg.owner.get() == 'export'
assert await cfg.owner.get() == 'export' assert await cfg.value.exportation() == [['b'], [None], [True], ['export']]
assert await cfg.value.exportation() == [['b'], [None], [True], ['export']] await cfg2.value.importation(await cfg.value.exportation())
await cfg2.value.importation(await cfg.value.exportation()) assert await cfg.value.exportation() == [['b'], [None], [True], ['export']]
assert await cfg.value.exportation() == [['b'], [None], [True], ['export']] assert await cfg.owner.get() == 'export'
assert await cfg.owner.get() == 'export' assert await cfg2.value.exportation() == [['b'], [None], [True], ['export']]
assert await cfg2.value.exportation() == [['b'], [None], [True], ['export']] assert await cfg2.owner.get() == 'user'
assert await cfg2.owner.get() == 'user' del cfg2
del cfg2 #
# cfg2 = await Config(o, session_id='test_persistent2')
cfg2 = await Config(o, session_id='test_persistent2', persistent=True) assert await cfg2.value.exportation() == [['b'], [None], [True], ['export']]
assert await cfg2.value.exportation() == [['b'], [None], [True], ['export']] assert await cfg2.owner.get() == 'user'
assert await cfg2.owner.get() == 'user' #
# await cfg3.value.importation(await cfg.value.exportation(with_default_owner=True))
await cfg3.value.importation(await cfg.value.exportation(with_default_owner=True)) assert await cfg3.value.exportation() == [['b'], [None], [True], ['export']]
assert await cfg3.value.exportation() == [['b'], [None], [True], ['export']] assert await cfg3.owner.get() == 'export'
assert await cfg3.owner.get() == 'export' del cfg3
del cfg3 #
# cfg3 = await Config(o, session_id='test_persistent3')
cfg3 = await Config(o, session_id='test_persistent3', persistent=True) assert await cfg3.value.exportation() == [['b'], [None], [True], ['export']]
assert await cfg3.value.exportation() == [['b'], [None], [True], ['export']] assert await cfg3.owner.get() == 'export'
assert await cfg3.owner.get() == 'export' #
# await delete_session('test_persistent')
delete_session('test_persistent') await delete_session('test_persistent2')
delete_session('test_persistent2') await delete_session('test_persistent3')
delete_session('test_persistent3') assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_create_persistent_context_property(): async def test_create_persistent_context_property():
b = BoolOption('b', '') b = BoolOption('b', '')
o = OptionDescription('od', '', [b]) o = OptionDescription('od', '', [b])
if default_storage.is_persistent(): cfg = await Config(o, session_id='test_persistent')
cfg = await Config(o, session_id='test_persistent', persistent=True) await cfg.property.add('persistent')
await cfg.property.add('persistent') del cfg
del cfg #
# cfg = await Config(o, session_id='test_persistent')
cfg = await Config(o, session_id='test_persistent', persistent=True) assert 'persistent' in await cfg.property.get()
assert 'persistent' in await cfg.property.get() del cfg
del cfg await delete_session('test_persistent')
delete_session('test_persistent') assert not await list_sessions()
@pytest.mark.asyncio
async def test_create_persistent_context_property_metaconfig():
b = BoolOption('b', '')
o = OptionDescription('od', '', [b])
if default_storage.is_persistent():
cfg = await Config(o, session_id='test_persistent', persistent=True)
await cfg.property.add('persistent')
del cfg
#
meta = await MetaConfig([], optiondescription=o)
cfg = await meta.config.new(session_id='test_persistent', persistent=True)
assert 'persistent' in await cfg.property.get()
del cfg
delete_session('test_persistent')
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_create_persistent_property(): async def test_create_persistent_property():
b = BoolOption('b', '') b = BoolOption('b', '')
o = OptionDescription('od', '', [b]) o = OptionDescription('od', '', [b])
if default_storage.is_persistent(): cfg = await Config(o, session_id='test_persistent')
cfg = await Config(o, session_id='test_persistent', persistent=True) await cfg.option('b').property.add('persistent')
await cfg.option('b').property.add('persistent') del cfg
del cfg #
# cfg = await Config(o, session_id='test_persistent')
cfg = await Config(o, session_id='test_persistent', persistent=True) assert 'persistent' in await cfg.option('b').property.get()
assert 'persistent' in await cfg.option('b').property.get() del cfg
del cfg await delete_session('test_persistent')
delete_session('test_persistent')

View file

@ -1,7 +1,6 @@
# coding: utf-8 # coding: utf-8
from .autopath import do_autopath from .autopath import do_autopath
do_autopath() do_autopath()
from py.test import raises
import pytest import pytest
import warnings import warnings
@ -12,11 +11,7 @@ from tiramisu import StrOption, IntOption, OptionDescription, submulti, Leadersh
MetaConfig, undefined, Params, ParamOption, Calculation MetaConfig, undefined, Params, ParamOption, Calculation
from tiramisu.error import LeadershipError from tiramisu.error import LeadershipError
from tiramisu.storage import list_sessions from tiramisu.storage import list_sessions
from .config import event_loop
def teardown_function(function):
with warnings.catch_warnings(record=True) as w:
assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__)
def return_val(val=None): def return_val(val=None):
@ -36,7 +31,8 @@ def return_list2(value=None):
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_unknown_multi(): async def test_unknown_multi():
raises(ValueError, "StrOption('multi', '', multi='unknown')") with pytest.raises(ValueError):
StrOption('multi', '', multi='unknown')
@pytest.mark.asyncio @pytest.mark.asyncio
@ -49,20 +45,22 @@ async def test_submulti():
multi2 = StrOption('multi2', '', default_multi=default_multi, multi=submulti) multi2 = StrOption('multi2', '', default_multi=default_multi, multi=submulti)
multi3 = StrOption('multi3', '', default=[['yes']], multi=submulti) multi3 = StrOption('multi3', '', default=[['yes']], multi=submulti)
od = OptionDescription('od', '', [multi, multi2, multi3]) od = OptionDescription('od', '', [multi, multi2, multi3])
cfg = await Config(od) async with await Config(od) as cfg:
assert await cfg.option('multi').option.ismulti() assert await cfg.option('multi').option.ismulti()
assert await cfg.option('multi').option.issubmulti() assert await cfg.option('multi').option.issubmulti()
assert await cfg.option('multi').owner.get() == owners.default assert await cfg.option('multi').owner.get() == owners.default
assert await cfg.option('multi').value.get() == [] assert await cfg.option('multi').value.get() == []
assert await cfg.option('multi').owner.get() == owners.default assert await cfg.option('multi').owner.get() == owners.default
assert await cfg.option('multi').owner.get() == owners.default assert await cfg.option('multi').owner.get() == owners.default
assert await cfg.option('multi3').value.get() == [['yes']] assert await cfg.option('multi3').value.get() == [['yes']]
assert await cfg.option('multi').owner.get() == owners.default assert await cfg.option('multi').owner.get() == owners.default
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_submulti_default_multi_not_list(): async def test_submulti_default_multi_not_list():
raises(ValueError, "StrOption('multi2', '', default_multi='yes', multi=submulti)") with pytest.raises(ValueError):
StrOption('multi2', '', default_multi='yes', multi=submulti)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -75,31 +73,32 @@ async def test_append_submulti():
multi2 = StrOption('multi2', '', default_multi=default_multi, multi=submulti) multi2 = StrOption('multi2', '', default_multi=default_multi, multi=submulti)
multi3 = StrOption('multi3', '', default=[['yes']], multi=submulti) multi3 = StrOption('multi3', '', default=[['yes']], multi=submulti)
od = OptionDescription('od', '', [multi, multi2, multi3]) od = OptionDescription('od', '', [multi, multi2, multi3])
cfg = await Config(od) async with await Config(od) as cfg:
owner = await cfg.owner.get() owner = await cfg.owner.get()
assert await cfg.option('multi').value.get() == [] assert await cfg.option('multi').value.get() == []
assert await cfg.option('multi').owner.get() == owners.default assert await cfg.option('multi').owner.get() == owners.default
await cfg.option('multi').value.set([undefined]) await cfg.option('multi').value.set([undefined])
assert await cfg.option('multi').owner.get() == owner assert await cfg.option('multi').owner.get() == owner
assert await cfg.option('multi').value.get() == [[]] assert await cfg.option('multi').value.get() == [[]]
await cfg.option('multi').value.set([undefined, ['no']]) await cfg.option('multi').value.set([undefined, ['no']])
assert await cfg.option('multi').value.get() == [[], ['no']] assert await cfg.option('multi').value.get() == [[], ['no']]
# #
assert await cfg.option('multi2').value.get() == [] assert await cfg.option('multi2').value.get() == []
assert await cfg.option('multi2').owner.get() == owners.default assert await cfg.option('multi2').owner.get() == owners.default
await cfg.option('multi2').value.set([undefined]) await cfg.option('multi2').value.set([undefined])
assert await cfg.option('multi2').owner.get() == owner assert await cfg.option('multi2').owner.get() == owner
assert await cfg.option('multi2').value.get() == [['yes']] assert await cfg.option('multi2').value.get() == [['yes']]
await cfg.option('multi2').value.set([undefined, ['no']]) await cfg.option('multi2').value.set([undefined, ['no']])
assert await cfg.option('multi2').value.get() == [['yes'], ['no']] assert await cfg.option('multi2').value.get() == [['yes'], ['no']]
# #
assert await cfg.option('multi3').value.get() == [['yes']] assert await cfg.option('multi3').value.get() == [['yes']]
assert await cfg.option('multi3').owner.get() == owners.default assert await cfg.option('multi3').owner.get() == owners.default
await cfg.option('multi3').value.set([undefined, undefined]) await cfg.option('multi3').value.set([undefined, undefined])
assert await cfg.option('multi3').owner.get() == owner assert await cfg.option('multi3').owner.get() == owner
assert await cfg.option('multi3').value.get() == [['yes'], []] assert await cfg.option('multi3').value.get() == [['yes'], []]
await cfg.option('multi3').value.set([undefined, undefined, ['no']]) await cfg.option('multi3').value.set([undefined, undefined, ['no']])
assert await cfg.option('multi3').value.get() == [['yes'], [], ['no']] assert await cfg.option('multi3').value.get() == [['yes'], [], ['no']]
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -112,26 +111,27 @@ async def test_append_unvalide_submulti():
multi2 = StrOption('multi2', '', default_multi=default_multi, multi=submulti) multi2 = StrOption('multi2', '', default_multi=default_multi, multi=submulti)
multi3 = StrOption('multi3', '', default=[['yes']], multi=submulti) multi3 = StrOption('multi3', '', default=[['yes']], multi=submulti)
od = OptionDescription('od', '', [multi, multi2, multi3]) od = OptionDescription('od', '', [multi, multi2, multi3])
cfg = await Config(od) async with await Config(od) as cfg:
assert await cfg.option('multi').value.get() == [] assert await cfg.option('multi').value.get() == []
assert await cfg.option('multi').owner.get() == owners.default assert await cfg.option('multi').owner.get() == owners.default
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('multi').value.set([[1]]) await cfg.option('multi').value.set([[1]])
assert await cfg.option('multi').value.get() == [] assert await cfg.option('multi').value.get() == []
assert await cfg.option('multi').owner.get() == owners.default assert await cfg.option('multi').owner.get() == owners.default
# #
assert await cfg.option('multi2').value.get() == [] assert await cfg.option('multi2').value.get() == []
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('multi2').value.set(['no']) await cfg.option('multi2').value.set(['no'])
assert await cfg.option('multi').owner.get() == owners.default assert await cfg.option('multi').owner.get() == owners.default
assert await cfg.option('multi2').value.get() == [] assert await cfg.option('multi2').value.get() == []
# #
assert await cfg.option('multi3').value.get() == [['yes']] assert await cfg.option('multi3').value.get() == [['yes']]
assert await cfg.option('multi3').owner.get() == owners.default assert await cfg.option('multi3').owner.get() == owners.default
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('multi3').value.set([[1]]) await cfg.option('multi3').value.set([[1]])
assert await cfg.option('multi3').value.get() == [['yes']] assert await cfg.option('multi3').value.get() == [['yes']]
assert await cfg.option('multi3').owner.get() == owners.default assert await cfg.option('multi3').owner.get() == owners.default
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -144,74 +144,78 @@ async def test_pop_submulti():
multi2 = StrOption('multi2', '', default_multi=default_multi, multi=submulti) multi2 = StrOption('multi2', '', default_multi=default_multi, multi=submulti)
multi3 = StrOption('multi3', '', default=[['yes']], multi=submulti) multi3 = StrOption('multi3', '', default=[['yes']], multi=submulti)
od = OptionDescription('od', '', [multi, multi2, multi3]) od = OptionDescription('od', '', [multi, multi2, multi3])
cfg = await Config(od) async with await Config(od) as cfg:
owner = await cfg.owner.get() owner = await cfg.owner.get()
assert await cfg.option('multi').value.get() == [] assert await cfg.option('multi').value.get() == []
assert await cfg.option('multi3').owner.get() == owners.default assert await cfg.option('multi3').owner.get() == owners.default
await cfg.option('multi').value.set([['no', 'yes'], ['peharps']]) await cfg.option('multi').value.set([['no', 'yes'], ['peharps']])
assert await cfg.option('multi').owner.get() == owner assert await cfg.option('multi').owner.get() == owner
assert await cfg.option('multi').value.get() == [['no', 'yes'], ['peharps']] assert await cfg.option('multi').value.get() == [['no', 'yes'], ['peharps']]
# #
assert await cfg.option('multi3').value.get() == [['yes']] assert await cfg.option('multi3').value.get() == [['yes']]
assert await cfg.option('multi3').owner.get() == owners.default assert await cfg.option('multi3').owner.get() == owners.default
await cfg.option('multi3').value.set([]) await cfg.option('multi3').value.set([])
assert await cfg.option('multi').owner.get() == owner assert await cfg.option('multi').owner.get() == owner
assert await cfg.option('multi3').value.get() == [] assert await cfg.option('multi3').value.get() == []
await cfg.option('multi3').value.reset() await cfg.option('multi3').value.reset()
assert await cfg.option('multi3').owner.get() == owners.default assert await cfg.option('multi3').owner.get() == owners.default
await cfg.option('multi3').value.set([[]]) await cfg.option('multi3').value.set([[]])
assert await cfg.option('multi3').owner.get() == owner assert await cfg.option('multi3').owner.get() == owner
assert await cfg.option('multi3').value.get() == [[]] assert await cfg.option('multi3').value.get() == [[]]
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_callback_submulti_str(): async def test_callback_submulti_str():
multi = StrOption('multi', '', [[Calculation(return_val)]], multi=submulti, default_multi=[Calculation(return_val)]) multi = StrOption('multi', '', [[Calculation(return_val)]], multi=submulti, default_multi=[Calculation(return_val)])
od = OptionDescription('od', '', [multi]) od = OptionDescription('od', '', [multi])
cfg = await Config(od) async with await Config(od) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
owner = await cfg.owner.get() owner = await cfg.owner.get()
assert await cfg.option('multi').owner.get() == owners.default assert await cfg.option('multi').owner.get() == owners.default
assert await cfg.option('multi').value.get() == [['val']] assert await cfg.option('multi').value.get() == [['val']]
await cfg.option('multi').value.set([['val'], undefined]) await cfg.option('multi').value.set([['val'], undefined])
assert await cfg.option('multi').owner.get() == owner assert await cfg.option('multi').owner.get() == owner
assert await cfg.option('multi').value.get() == [['val'], ['val']] assert await cfg.option('multi').value.get() == [['val'], ['val']]
await cfg.option('multi').value.reset() await cfg.option('multi').value.reset()
assert await cfg.option('multi').owner.get() == owners.default assert await cfg.option('multi').owner.get() == owners.default
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_callback_submulti_list(): async def test_callback_submulti_list():
multi = StrOption('multi', '', [Calculation(return_list)], multi=submulti, default_multi=Calculation(return_list), properties=('notunique',)) multi = StrOption('multi', '', [Calculation(return_list)], multi=submulti, default_multi=Calculation(return_list), properties=('notunique',))
od = OptionDescription('od', '', [multi]) od = OptionDescription('od', '', [multi])
cfg = await Config(od) async with await Config(od) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
owner = await cfg.owner.get() owner = await cfg.owner.get()
assert await cfg.option('multi').value.get() == [['val', 'val']] assert await cfg.option('multi').value.get() == [['val', 'val']]
assert await cfg.option('multi').owner.get() == owners.default assert await cfg.option('multi').owner.get() == owners.default
await cfg.option('multi').value.set([['val', 'val'], undefined]) await cfg.option('multi').value.set([['val', 'val'], undefined])
#assert await cfg.option('multi').owner.get() == owner #assert await cfg.option('multi').owner.get() == owner
#assert await cfg.option('multi').value.get() == [['val', 'val'], ['val', 'val']] #assert await cfg.option('multi').value.get() == [['val', 'val'], ['val', 'val']]
#await cfg.option('multi').value.set([['val', 'val'], undefined, undefined]) #await cfg.option('multi').value.set([['val', 'val'], undefined, undefined])
#assert await cfg.option('multi').value.get() == [['val', 'val'], ['val', 'val'], ['val', 'val']] #assert await cfg.option('multi').value.get() == [['val', 'val'], ['val', 'val'], ['val', 'val']]
#await cfg.option('multi').value.reset() #await cfg.option('multi').value.reset()
#assert await cfg.option('multi').owner.get() == owners.default #assert await cfg.option('multi').owner.get() == owners.default
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_callback_submulti_list_list(): async def test_callback_submulti_list_list():
multi = StrOption('multi', '', Calculation(return_list2), multi=submulti, properties=('notunique',)) multi = StrOption('multi', '', Calculation(return_list2), multi=submulti, properties=('notunique',))
od = OptionDescription('od', '', [multi]) od = OptionDescription('od', '', [multi])
cfg = await Config(od) async with await Config(od) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
owner = await cfg.owner.get() owner = await cfg.owner.get()
assert await cfg.option('multi').value.get() == [['val', 'val']] assert await cfg.option('multi').value.get() == [['val', 'val']]
assert await cfg.option('multi').owner.get() == owners.default assert await cfg.option('multi').owner.get() == owners.default
await cfg.option('multi').value.set([['val', 'val'], undefined]) await cfg.option('multi').value.set([['val', 'val'], undefined])
assert await cfg.option('multi').owner.get() == owner assert await cfg.option('multi').owner.get() == owner
assert await cfg.option('multi').value.get() == [['val', 'val'], []] assert await cfg.option('multi').value.get() == [['val', 'val'], []]
await cfg.option('multi').value.reset() await cfg.option('multi').value.reset()
assert await cfg.option('multi').owner.get() == owners.default assert await cfg.option('multi').owner.get() == owners.default
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -228,8 +232,10 @@ async def test_groups_with_leader_in_config_submulti():
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=submulti) netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=submulti)
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
od = OptionDescription('root', '', [interface1]) od = OptionDescription('root', '', [interface1])
await Config(od) async with await Config(od) as cfg:
pass
assert interface1.impl_get_group_type() == groups.leadership assert interface1.impl_get_group_type() == groups.leadership
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -238,26 +244,27 @@ async def test_values_with_leader_and_followers_submulti():
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=submulti) netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=submulti)
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
maconfig = OptionDescription('toto', '', [interface1]) maconfig = OptionDescription('toto', '', [interface1])
cfg = await Config(maconfig) async with await Config(maconfig) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
owner = await cfg.owner.get() owner = await cfg.owner.get()
assert interface1.impl_get_group_type() == groups.leadership assert interface1.impl_get_group_type() == groups.leadership
assert await cfg.option('ip_admin_eth0.ip_admin_eth0').owner.get() == owners.default assert await cfg.option('ip_admin_eth0.ip_admin_eth0').owner.get() == owners.default
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(["192.168.230.145"]) await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(["192.168.230.145"])
assert await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == ["192.168.230.145"] assert await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == ["192.168.230.145"]
assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == [] assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == []
assert await cfg.option('ip_admin_eth0.ip_admin_eth0').owner.get() == owner assert await cfg.option('ip_admin_eth0.ip_admin_eth0').owner.get() == owner
assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).owner.get() == owners.default assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).owner.get() == owners.default
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(["192.168.230.145", "192.168.230.147"]) await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(["192.168.230.145", "192.168.230.147"])
assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == [] assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == []
assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get() == [] assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get() == []
await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set(['255.255.255.0']) await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set(['255.255.255.0'])
assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == ['255.255.255.0'] assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == ['255.255.255.0']
assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get() == [] assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get() == []
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set('255.255.255.0') await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set('255.255.255.0')
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set([['255.255.255.0']]) await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set([['255.255.255.0']])
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -266,25 +273,26 @@ async def test_reset_values_with_leader_and_followers_submulti():
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=submulti) netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=submulti)
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
maconfig = OptionDescription('toto', '', [interface1]) maconfig = OptionDescription('toto', '', [interface1])
cfg = await Config(maconfig) async with await Config(maconfig) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
owner = await cfg.owner.get() owner = await cfg.owner.get()
assert interface1.impl_get_group_type() == groups.leadership assert interface1.impl_get_group_type() == groups.leadership
assert await cfg.option('ip_admin_eth0.ip_admin_eth0').owner.get() == owners.default assert await cfg.option('ip_admin_eth0.ip_admin_eth0').owner.get() == owners.default
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.230.145']) await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.230.145'])
assert await cfg.option('ip_admin_eth0.ip_admin_eth0').owner.get() == owner assert await cfg.option('ip_admin_eth0.ip_admin_eth0').owner.get() == owner
assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).owner.get() == owners.default assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).owner.get() == owners.default
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.reset() await cfg.option('ip_admin_eth0.ip_admin_eth0').value.reset()
assert await cfg.option('ip_admin_eth0.ip_admin_eth0').owner.get() == owners.default assert await cfg.option('ip_admin_eth0.ip_admin_eth0').owner.get() == owners.default
assert await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == [] assert await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
# #
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.230.145']) await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.230.145'])
await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set(['255.255.255.0']) await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set(['255.255.255.0'])
assert await cfg.option('ip_admin_eth0.ip_admin_eth0').owner.get() == owner assert await cfg.option('ip_admin_eth0.ip_admin_eth0').owner.get() == owner
assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).owner.get() == owner assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).owner.get() == owner
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.reset() await cfg.option('ip_admin_eth0.ip_admin_eth0').value.reset()
assert await cfg.option('ip_admin_eth0.ip_admin_eth0').owner.get() == owners.default assert await cfg.option('ip_admin_eth0.ip_admin_eth0').owner.get() == owners.default
assert await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == [] assert await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -293,19 +301,20 @@ async def test_values_with_leader_and_followers_follower_submulti():
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=submulti) netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=submulti)
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
maconfig = OptionDescription('toto', '', [interface1]) maconfig = OptionDescription('toto', '', [interface1])
cfg = await Config(maconfig) async with await Config(maconfig) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
with pytest.raises(LeadershipError): with pytest.raises(LeadershipError):
await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set(['255.255.255.0'])
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.230.145'])
await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set(['255.255.255.0']) await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set(['255.255.255.0'])
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.230.145']) await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set(['255.255.255.0', '255.255.255.0'])
await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set(['255.255.255.0']) await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.reset()
await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set(['255.255.255.0', '255.255.255.0']) await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set(['255.255.255.0'])
await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.reset() await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.230.145', '192.168.230.145'])
await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set(['255.255.255.0']) assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == ['255.255.255.0']
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.230.145', '192.168.230.145']) assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get() == []
assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == ['255.255.255.0'] await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set(['255.255.255.0'])
assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get() == [] assert not await list_sessions()
await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set(['255.255.255.0'])
@pytest.mark.asyncio @pytest.mark.asyncio
@ -314,19 +323,20 @@ async def test_values_with_leader_and_leadership_submulti():
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=submulti) netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=submulti)
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
maconfig = OptionDescription('toto', '', [interface1]) maconfig = OptionDescription('toto', '', [interface1])
cfg = await Config(maconfig) async with await Config(maconfig) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(["192.168.230.145"]) await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(["192.168.230.145"])
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(["192.168.230.145", "192.168.230.145"]) await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(["192.168.230.145", "192.168.230.145"])
await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set(['255.255.255.0']) await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set(['255.255.255.0'])
await cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.set(['255.255.255.0']) await cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.set(['255.255.255.0'])
assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == ['255.255.255.0'] assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == ['255.255.255.0']
assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get() == ['255.255.255.0'] assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get() == ['255.255.255.0']
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.pop(1) await cfg.option('ip_admin_eth0.ip_admin_eth0').value.pop(1)
assert await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == ["192.168.230.145"] assert await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == ["192.168.230.145"]
assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == ['255.255.255.0'] assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == ['255.255.255.0']
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.reset() await cfg.option('ip_admin_eth0.ip_admin_eth0').value.reset()
assert await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == [] assert await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -335,15 +345,16 @@ async def test_values_with_leader_owner_submulti():
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=submulti) netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=submulti)
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
maconfig = OptionDescription('toto', '', [interface1]) maconfig = OptionDescription('toto', '', [interface1])
cfg = await Config(maconfig) async with await Config(maconfig) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
owner = await cfg.owner.get() owner = await cfg.owner.get()
assert await cfg.option('ip_admin_eth0.ip_admin_eth0').owner.get() == owners.default assert await cfg.option('ip_admin_eth0.ip_admin_eth0').owner.get() == owners.default
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.230.145']) await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.230.145'])
assert await cfg.option('ip_admin_eth0.ip_admin_eth0').owner.get() == owner assert await cfg.option('ip_admin_eth0.ip_admin_eth0').owner.get() == owner
assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).owner.get() == owners.default assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).owner.get() == owners.default
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.reset() await cfg.option('ip_admin_eth0.ip_admin_eth0').value.reset()
assert await cfg.option('ip_admin_eth0.ip_admin_eth0').owner.get() == owners.default assert await cfg.option('ip_admin_eth0.ip_admin_eth0').owner.get() == owners.default
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -352,24 +363,25 @@ async def test_values_with_leader_disabled_submulti():
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=submulti) netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=submulti)
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
maconfig = OptionDescription('toto', '', [interface1]) maconfig = OptionDescription('toto', '', [interface1])
cfg = await Config(maconfig) async with await Config(maconfig) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.230.145']) await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.230.145'])
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.pop(0) await cfg.option('ip_admin_eth0.ip_admin_eth0').value.pop(0)
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.230.145']) await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.230.145'])
await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set(['192.168.230.145']) await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set(['192.168.230.145'])
await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.reset() await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.reset()
await cfg.option('ip_admin_eth0.netmask_admin_eth0').property.add('disabled') await cfg.option('ip_admin_eth0.netmask_admin_eth0').property.add('disabled')
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.230.145', '192.168.230.145']) await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.230.145', '192.168.230.145'])
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.pop(1) await cfg.option('ip_admin_eth0.ip_admin_eth0').value.pop(1)
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.pop(0) await cfg.option('ip_admin_eth0.ip_admin_eth0').value.pop(0)
#delete with value in disabled var #delete with value in disabled var
await cfg.unrestraint.option('ip_admin_eth0.netmask_admin_eth0').property.pop('disabled') await cfg.unrestraint.option('ip_admin_eth0.netmask_admin_eth0').property.pop('disabled')
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.230.145']) await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.230.145'])
await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set(['192.168.230.145']) await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set(['192.168.230.145'])
await cfg.unrestraint.option('ip_admin_eth0.netmask_admin_eth0').property.add('disabled') await cfg.unrestraint.option('ip_admin_eth0.netmask_admin_eth0').property.add('disabled')
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.pop(0) await cfg.option('ip_admin_eth0.ip_admin_eth0').value.pop(0)
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -378,23 +390,24 @@ async def test_leader_is_submulti():
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True) netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True)
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
maconfig = OptionDescription('toto', '', [interface1]) maconfig = OptionDescription('toto', '', [interface1])
cfg = await Config(maconfig) async with await Config(maconfig) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
owner = await cfg.owner.get() owner = await cfg.owner.get()
assert interface1.impl_get_group_type() == groups.leadership assert interface1.impl_get_group_type() == groups.leadership
assert await cfg.option('ip_admin_eth0.ip_admin_eth0').owner.isdefault() assert await cfg.option('ip_admin_eth0.ip_admin_eth0').owner.isdefault()
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set([["192.168.230.145"]]) await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set([["192.168.230.145"]])
assert await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == [["192.168.230.145"]] assert await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == [["192.168.230.145"]]
assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None
assert await cfg.option('ip_admin_eth0.ip_admin_eth0').owner.get() == owner assert await cfg.option('ip_admin_eth0.ip_admin_eth0').owner.get() == owner
assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).owner.isdefault() assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).owner.isdefault()
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set([["192.168.230.145"], ["192.168.230.147"]]) await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set([["192.168.230.145"], ["192.168.230.147"]])
assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None
assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get() == None assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get() == None
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set([["192.168.230.145", '192.168.1.1'], ["192.168.230.147"]]) await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set([["192.168.230.145", '192.168.1.1'], ["192.168.230.147"]])
assert await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == [["192.168.230.145", '192.168.1.1'], ["192.168.230.147"]] assert await cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == [["192.168.230.145", '192.168.1.1'], ["192.168.230.147"]]
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1', '192.168.1.1']) await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1', '192.168.1.1'])
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -402,53 +415,56 @@ async def test_callback_submulti():
multi = StrOption('multi', '', multi=submulti) multi = StrOption('multi', '', multi=submulti)
multi2 = StrOption('multi2', '', Calculation(return_val, Params(ParamOption(multi))), multi=submulti) multi2 = StrOption('multi2', '', Calculation(return_val, Params(ParamOption(multi))), multi=submulti)
od = OptionDescription('multi', '', [multi, multi2]) od = OptionDescription('multi', '', [multi, multi2])
cfg = await Config(od) async with await Config(od) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
owner = await cfg.owner.get() owner = await cfg.owner.get()
assert await cfg.option('multi').owner.get() == owners.default assert await cfg.option('multi').owner.get() == owners.default
assert await cfg.option('multi').value.get() == [] assert await cfg.option('multi').value.get() == []
assert await cfg.option('multi2').value.get() == [] assert await cfg.option('multi2').value.get() == []
await cfg.option('multi').value.set([['val']]) await cfg.option('multi').value.set([['val']])
assert await cfg.option('multi').owner.get() == owner assert await cfg.option('multi').owner.get() == owner
assert await cfg.option('multi2').owner.get() == owners.default assert await cfg.option('multi2').owner.get() == owners.default
assert await cfg.option('multi').value.get() == [['val']] assert await cfg.option('multi').value.get() == [['val']]
assert await cfg.option('multi2').value.get() == [['val']] assert await cfg.option('multi2').value.get() == [['val']]
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_submulti_unique(): async def test_submulti_unique():
i = IntOption('int', '', multi=submulti, properties=('unique',)) i = IntOption('int', '', multi=submulti, properties=('unique',))
o = OptionDescription('od', '', [i]) o = OptionDescription('od', '', [i])
cfg = await Config(o) async with await Config(o) as cfg:
assert await cfg.option('int').value.get() == [] assert await cfg.option('int').value.get() == []
await cfg.option('int').value.set([[0]]) await cfg.option('int').value.set([[0]])
assert await cfg.option('int').value.get() == [[0]] assert await cfg.option('int').value.get() == [[0]]
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('int').value.set([[0, 0]]) await cfg.option('int').value.set([[0, 0]])
await cfg.option('int').value.set([[0], [0]]) await cfg.option('int').value.set([[0], [0]])
with pytest.raises(ValueError): with pytest.raises(ValueError):
await cfg.option('int').value.set([[1, 0, 2, 3, 4, 5, 6, 0, 7], [0]]) await cfg.option('int').value.set([[1, 0, 2, 3, 4, 5, 6, 0, 7], [0]])
await cfg.option('int').value.set([[0, 4, 5, 6], [0]]) await cfg.option('int').value.set([[0, 4, 5, 6], [0]])
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_multi_submulti_meta(): async def test_multi_submulti_meta():
multi = StrOption('multi', '', multi=submulti) multi = StrOption('multi', '', multi=submulti)
od = OptionDescription('od', '', [multi]) od = OptionDescription('od', '', [multi])
cfg = await Config(od, session_id='cfg') async with await Config(od, session_id='cfg') as cfg:
await cfg.property.read_write() await cfg.property.read_write()
cfg2 = await Config(od, session_id='cfg2') async with await Config(od, session_id='cfg2') as cfg2:
await cfg2.property.read_write() await cfg2.property.read_write()
meta = await MetaConfig([cfg, cfg2]) async with await MetaConfig([cfg, cfg2]) as meta:
await meta.property.read_write() await meta.property.read_write()
await meta.option('multi').value.set([['val']]) await meta.option('multi').value.set([['val']])
assert await meta.option('multi').value.get() == [['val']] assert await meta.option('multi').value.get() == [['val']]
newcfg = await meta.config('cfg') newcfg = await meta.config('cfg')
await newcfg.option('multi').value.set([['val', None]]) await newcfg.option('multi').value.set([['val', None]])
assert await cfg.option('multi').value.get() == [['val', None]] assert await cfg.option('multi').value.get() == [['val', None]]
newcfg = await meta.config('cfg') newcfg = await meta.config('cfg')
assert await newcfg.option('multi').value.get() == [['val', None]] assert await newcfg.option('multi').value.get() == [['val', None]]
assert await meta.option('multi').value.get() == [['val']] assert await meta.option('multi').value.get() == [['val']]
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -456,18 +472,19 @@ async def test_multi_submulti_meta_no_cache():
multi = StrOption('multi', '', multi=submulti) multi = StrOption('multi', '', multi=submulti)
multi = StrOption('multi', '', multi=submulti) multi = StrOption('multi', '', multi=submulti)
od = OptionDescription('od', '', [multi]) od = OptionDescription('od', '', [multi])
cfg = await Config(od, session_id='cfg') async with await Config(od, session_id='cfg') as cfg:
await cfg.property.read_write() await cfg.property.read_write()
cfg2 = await Config(od, session_id='cfg2') async with await Config(od, session_id='cfg2') as cfg2:
await cfg.property.read_write() await cfg.property.read_write()
meta = await MetaConfig([cfg, cfg2]) async with await MetaConfig([cfg, cfg2]) as meta:
await meta.property.read_write() await meta.property.read_write()
await meta.property.pop('cache') await meta.property.pop('cache')
await meta.option('multi').value.set([['val']]) await meta.option('multi').value.set([['val']])
assert await meta.option('multi').value.get() == [['val']] assert await meta.option('multi').value.get() == [['val']]
newcfg = await meta.config('cfg') newcfg = await meta.config('cfg')
await newcfg.option('multi').value.set([['val', None]]) await newcfg.option('multi').value.set([['val', None]])
assert await cfg.option('multi').value.get() == [['val', None]] assert await cfg.option('multi').value.get() == [['val', None]]
newcfg = await meta.config('cfg') newcfg = await meta.config('cfg')
assert await newcfg.option('multi').value.get() == [['val', None]] assert await newcfg.option('multi').value.get() == [['val', None]]
assert await meta.option('multi').value.get() == [['val']] assert await meta.option('multi').value.get() == [['val']]
assert not await list_sessions()

View file

@ -9,10 +9,7 @@ from tiramisu import BoolOption, StrOption, SymLinkOption, \
from tiramisu.error import PropertiesOptionError, ConfigError from tiramisu.error import PropertiesOptionError, ConfigError
from tiramisu.setting import groups, owners from tiramisu.setting import groups, owners
from tiramisu.storage import list_sessions from tiramisu.storage import list_sessions
from .config import event_loop
def teardown_function(function):
assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__)
def return_value(): def return_value():
@ -26,19 +23,20 @@ async def test_symlink_option(config_type):
linkopt = SymLinkOption("c", boolopt) linkopt = SymLinkOption("c", boolopt)
descr = OptionDescription("opt", "", descr = OptionDescription("opt", "",
[linkopt, OptionDescription("s1", "", [boolopt])]) [linkopt, OptionDescription("s1", "", [boolopt])])
cfg = await Config(descr) async with await Config(descr) as cfg:
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
assert await cfg.option('s1.b').value.get() is False assert await cfg.option('s1.b').value.get() is False
await cfg.option("s1.b").value.set(True) await cfg.option("s1.b").value.set(True)
await cfg.option("s1.b").value.set(False) await cfg.option("s1.b").value.set(False)
assert await cfg.option('s1.b').value.get() is False assert await cfg.option('s1.b').value.get() is False
assert await cfg.option('c').value.get() is False assert await cfg.option('c').value.get() is False
await cfg.option('s1.b').value.set(True) await cfg.option('s1.b').value.set(True)
assert await cfg.option('s1.b').value.get() is True assert await cfg.option('s1.b').value.get() is True
assert await cfg.option('c').value.get() is True assert await cfg.option('c').value.get() is True
await cfg.option('s1.b').value.set(False) await cfg.option('s1.b').value.set(False)
assert await cfg.option('s1.b').value.get() is False assert await cfg.option('s1.b').value.get() is False
assert await cfg.option('c').value.get() is False assert await cfg.option('c').value.get() is False
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -47,10 +45,11 @@ async def test_symlink_assign_option(config_type):
linkopt = SymLinkOption("c", boolopt) linkopt = SymLinkOption("c", boolopt)
descr = OptionDescription("opt", "", descr = OptionDescription("opt", "",
[linkopt, OptionDescription("s1", "", [boolopt])]) [linkopt, OptionDescription("s1", "", [boolopt])])
cfg = await Config(descr) async with await Config(descr) as cfg:
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
with pytest.raises(ConfigError): with pytest.raises(ConfigError):
await cfg.option('c').value.set(True) await cfg.option('c').value.set(True)
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -59,10 +58,11 @@ async def test_symlink_del_option(config_type):
linkopt = SymLinkOption("c", boolopt) linkopt = SymLinkOption("c", boolopt)
descr = OptionDescription("opt", "", descr = OptionDescription("opt", "",
[linkopt, OptionDescription("s1", "", [boolopt])]) [linkopt, OptionDescription("s1", "", [boolopt])])
cfg = await Config(descr) async with await Config(descr) as cfg:
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
with pytest.raises(ConfigError): with pytest.raises(ConfigError):
await cfg.option('c').value.reset() await cfg.option('c').value.reset()
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -70,16 +70,17 @@ async def test_symlink_addproperties():
boolopt = BoolOption('b', '', default=True, properties=('test',)) boolopt = BoolOption('b', '', default=True, properties=('test',))
linkopt = SymLinkOption("c", boolopt) linkopt = SymLinkOption("c", boolopt)
descr = OptionDescription('opt', '', [boolopt, linkopt]) descr = OptionDescription('opt', '', [boolopt, linkopt])
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
with pytest.raises(TypeError): with pytest.raises(TypeError):
await cfg.option('c').property.add('new') await cfg.option('c').property.add('new')
try: try:
await cfg.option('c').property.reset() await cfg.option('c').property.reset()
except AssertionError: except AssertionError:
pass pass
else: else:
raise Exception('must raise') raise Exception('must raise')
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -87,10 +88,11 @@ async def test_symlink_getpermissive():
boolopt = BoolOption('b', '', default=True, properties=('test',)) boolopt = BoolOption('b', '', default=True, properties=('test',))
linkopt = SymLinkOption("c", boolopt) linkopt = SymLinkOption("c", boolopt)
descr = OptionDescription('opt', '', [boolopt, linkopt]) descr = OptionDescription('opt', '', [boolopt, linkopt])
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
await cfg.option('b').permissive.set(frozenset(['perm'])) await cfg.option('b').permissive.set(frozenset(['perm']))
await cfg.option('c').permissive.get() == frozenset(['perm']) await cfg.option('c').permissive.get() == frozenset(['perm'])
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -98,16 +100,17 @@ async def test_symlink_addpermissives():
boolopt = BoolOption('b', '', default=True, properties=('test',)) boolopt = BoolOption('b', '', default=True, properties=('test',))
linkopt = SymLinkOption("c", boolopt) linkopt = SymLinkOption("c", boolopt)
descr = OptionDescription('opt', '', [boolopt, linkopt]) descr = OptionDescription('opt', '', [boolopt, linkopt])
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
with pytest.raises(TypeError): with pytest.raises(TypeError):
await cfg.option('c').permissive.set(frozenset(['new'])) await cfg.option('c').permissive.set(frozenset(['new']))
try: try:
await cfg.option('c').permissive.reset() await cfg.option('c').permissive.reset()
except AssertionError: except AssertionError:
pass pass
else: else:
raise Exception('must raise') raise Exception('must raise')
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -115,10 +118,11 @@ async def test_symlink_getproperties():
boolopt = BoolOption('b', '', default=True, properties=('test',)) boolopt = BoolOption('b', '', default=True, properties=('test',))
linkopt = SymLinkOption("c", boolopt) linkopt = SymLinkOption("c", boolopt)
descr = OptionDescription('opt', '', [boolopt, linkopt]) descr = OptionDescription('opt', '', [boolopt, linkopt])
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
assert boolopt.impl_getproperties() == linkopt.impl_getproperties() == {'test'} assert boolopt.impl_getproperties() == linkopt.impl_getproperties() == {'test'}
assert boolopt.impl_has_callback() == linkopt.impl_has_callback() == False assert boolopt.impl_has_callback() == linkopt.impl_has_callback() == False
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -126,11 +130,12 @@ async def test_symlink_getcallback():
boolopt = BoolOption('b', '', Calculation(return_value)) boolopt = BoolOption('b', '', Calculation(return_value))
linkopt = SymLinkOption("c", boolopt) linkopt = SymLinkOption("c", boolopt)
descr = OptionDescription('opt', '', [boolopt, linkopt]) descr = OptionDescription('opt', '', [boolopt, linkopt])
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
#assert boolopt.impl_has_callback() == linkopt.impl_has_callback() == True #assert boolopt.impl_has_callback() == linkopt.impl_has_callback() == True
#assert boolopt.impl_get_callback() == linkopt.impl_get_callback() == (return_value, None) #assert boolopt.impl_get_callback() == linkopt.impl_get_callback() == (return_value, None)
assert boolopt.impl_has_callback() == linkopt.impl_has_callback() == False assert boolopt.impl_has_callback() == linkopt.impl_has_callback() == False
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -143,27 +148,28 @@ async def test_symlink_requires(config_type):
stropt = StrOption('s', '', properties=(disabled_property,)) stropt = StrOption('s', '', properties=(disabled_property,))
linkopt = SymLinkOption("c", stropt) linkopt = SymLinkOption("c", stropt)
descr = OptionDescription('opt', '', [boolopt, stropt, linkopt]) descr = OptionDescription('opt', '', [boolopt, stropt, linkopt])
cfg = await Config(descr) async with await Config(descr) as cfg:
await cfg.property.read_write() await cfg.property.read_write()
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
assert await cfg.option('b').value.get() is True assert await cfg.option('b').value.get() is True
assert await cfg.option('s').value.get() is None assert await cfg.option('s').value.get() is None
assert await cfg.option('c').value.get() is None assert await cfg.option('c').value.get() is None
await cfg.option('b').value.set(False) await cfg.option('b').value.set(False)
# #
props = [] props = []
try: try:
await cfg.option('s').value.get() await cfg.option('s').value.get()
except PropertiesOptionError as err: except PropertiesOptionError as err:
props = err.proptype props = err.proptype
assert props == {'disabled'} assert props == {'disabled'}
# #
props = [] props = []
try: try:
await cfg.option('c').value.get() await cfg.option('c').value.get()
except PropertiesOptionError as err: except PropertiesOptionError as err:
props = err.proptype props = err.proptype
assert props == {'disabled'} assert props == {'disabled'}
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -172,21 +178,22 @@ async def test_symlink_multi(config_type):
linkopt = SymLinkOption("c", boolopt) linkopt = SymLinkOption("c", boolopt)
descr = OptionDescription("opt", "", descr = OptionDescription("opt", "",
[linkopt, OptionDescription("s1", "", [boolopt])]) [linkopt, OptionDescription("s1", "", [boolopt])])
cfg = await Config(descr) async with await Config(descr) as cfg:
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
assert await cfg.option('s1.b').value.get() == [False] assert await cfg.option('s1.b').value.get() == [False]
assert await cfg.option('c').value.get() == [False] assert await cfg.option('c').value.get() == [False]
await cfg.option('s1.b').value.set([True]) await cfg.option('s1.b').value.set([True])
assert await cfg.option('s1.b').value.get() == [True] assert await cfg.option('s1.b').value.get() == [True]
assert await cfg.option('c').value.get() == [True] assert await cfg.option('c').value.get() == [True]
await cfg.option('s1.b').value.set([False]) await cfg.option('s1.b').value.set([False])
assert await cfg.option('s1.b').value.get() == [False] assert await cfg.option('s1.b').value.get() == [False]
assert await cfg.option('c').value.get() == [False] assert await cfg.option('c').value.get() == [False]
await cfg.option('s1.b').value.set([False, True]) await cfg.option('s1.b').value.set([False, True])
assert await cfg.option('s1.b').value.get() == [False, True] assert await cfg.option('s1.b').value.get() == [False, True]
assert await cfg.option('c').value.get() == [False, True] assert await cfg.option('c').value.get() == [False, True]
assert boolopt.impl_is_multi() is True assert boolopt.impl_is_multi() is True
assert linkopt.impl_is_multi() is True assert linkopt.impl_is_multi() is True
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -195,10 +202,11 @@ async def test_symlink_assign(config_type):
linkopt = SymLinkOption("c", boolopt) linkopt = SymLinkOption("c", boolopt)
descr = OptionDescription("opt", "", descr = OptionDescription("opt", "",
[linkopt, OptionDescription("s1", "", [boolopt])]) [linkopt, OptionDescription("s1", "", [boolopt])])
cfg = await Config(descr) async with await Config(descr) as cfg:
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
with pytest.raises(ConfigError): with pytest.raises(ConfigError):
await cfg.option('c').value.set(True) await cfg.option('c').value.set(True)
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -207,13 +215,14 @@ async def test_symlink_owner(config_type):
linkopt = SymLinkOption("c", boolopt) linkopt = SymLinkOption("c", boolopt)
descr = OptionDescription("opt", "", descr = OptionDescription("opt", "",
[linkopt, OptionDescription("s1", "", [boolopt])]) [linkopt, OptionDescription("s1", "", [boolopt])])
cfg = await Config(descr) async with await Config(descr) as cfg:
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
assert await cfg.option('s1.b').owner.isdefault() assert await cfg.option('s1.b').owner.isdefault()
assert await cfg.option('c').owner.isdefault() assert await cfg.option('c').owner.isdefault()
await cfg.option('s1.b').value.set(True) await cfg.option('s1.b').value.set(True)
assert not await cfg.option('s1.b').owner.isdefault() assert not await cfg.option('s1.b').owner.isdefault()
assert not await cfg.option('c').owner.isdefault() assert not await cfg.option('c').owner.isdefault()
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -233,7 +242,7 @@ async def test_symlink_leader():
a = StrOption('a', "", multi=True) a = StrOption('a', "", multi=True)
ip_admin_eth0 = SymLinkOption('ip_admin_eth0', a) ip_admin_eth0 = SymLinkOption('ip_admin_eth0', a)
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "", multi=True) netmask_admin_eth0 = StrOption('netmask_admin_eth0', "", multi=True)
with pytest.raises(ValueError): with pytest.raises(ValueError):
Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
@ -242,7 +251,7 @@ async def test_symlink_followers():
a = StrOption('a', "", multi=True) a = StrOption('a', "", multi=True)
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True) ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
netmask_admin_eth0 = SymLinkOption('netmask_admin_eth0', a) netmask_admin_eth0 = SymLinkOption('netmask_admin_eth0', a)
with pytest.raises(ValueError): with pytest.raises(ValueError):
Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
@ -253,11 +262,12 @@ async def test_symlink_with_leader(config_type):
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
leader = SymLinkOption('leader', ip_admin_eth0) leader = SymLinkOption('leader', ip_admin_eth0)
od = OptionDescription('root', '', [interface1, leader]) od = OptionDescription('root', '', [interface1, leader])
cfg = await Config(od) async with await Config(od) as cfg:
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
assert await cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': [], 'ip_admin_eth0.netmask_admin_eth0': [], 'leader': []} assert await cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': [], 'ip_admin_eth0.netmask_admin_eth0': [], 'leader': []}
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['val1', 'val2']) await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['val1', 'val2'])
assert await cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': ['val1', 'val2'], 'ip_admin_eth0.netmask_admin_eth0': [None, None], 'leader': ['val1', 'val2']} assert await cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': ['val1', 'val2'], 'ip_admin_eth0.netmask_admin_eth0': [None, None], 'leader': ['val1', 'val2']}
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -267,24 +277,25 @@ async def test_symlink_with_follower(config_type):
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
follower = SymLinkOption('follower', netmask_admin_eth0) follower = SymLinkOption('follower', netmask_admin_eth0)
od = OptionDescription('root', '', [interface1, follower]) od = OptionDescription('root', '', [interface1, follower])
cfg = await Config(od) async with await Config(od) as cfg:
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
assert await cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': [], 'ip_admin_eth0.netmask_admin_eth0': [], 'follower': []} assert await cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': [], 'ip_admin_eth0.netmask_admin_eth0': [], 'follower': []}
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['val1', 'val2']) await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['val1', 'val2'])
assert await cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': ['val1', 'val2'], 'ip_admin_eth0.netmask_admin_eth0': [None, None], 'follower': [None, None]} assert await cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': ['val1', 'val2'], 'ip_admin_eth0.netmask_admin_eth0': [None, None], 'follower': [None, None]}
# #
assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None
assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get() == None assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get() == None
assert await cfg.option('follower', 0).value.get() == None assert await cfg.option('follower', 0).value.get() == None
assert await cfg.option('follower', 1).value.get() == None assert await cfg.option('follower', 1).value.get() == None
# #
await cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.set('val3') await cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.set('val3')
assert await cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': ['val1', 'val2'], 'ip_admin_eth0.netmask_admin_eth0': [None, 'val3'], 'follower': [None, 'val3']} assert await cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': ['val1', 'val2'], 'ip_admin_eth0.netmask_admin_eth0': [None, 'val3'], 'follower': [None, 'val3']}
# #
assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None
assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get() == 'val3' assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get() == 'val3'
assert await cfg.option('follower', 0).value.get() == None assert await cfg.option('follower', 0).value.get() == None
assert await cfg.option('follower', 1).value.get() == 'val3' assert await cfg.option('follower', 1).value.get() == 'val3'
assert not await list_sessions()
#____________________________________________________________ #____________________________________________________________
@ -294,11 +305,12 @@ async def test_symlink_dependency():
linkopt = SymLinkOption("c", boolopt) linkopt = SymLinkOption("c", boolopt)
descr = OptionDescription("opt", "", descr = OptionDescription("opt", "",
[linkopt, OptionDescription("s1", "", [boolopt])]) [linkopt, OptionDescription("s1", "", [boolopt])])
cfg = await Config(descr) async with await Config(descr) as cfg:
assert await cfg.option('s1.b').option.has_dependency() is False assert await cfg.option('s1.b').option.has_dependency() is False
assert await cfg.option('c').option.has_dependency() is True assert await cfg.option('c').option.has_dependency() is True
assert await cfg.option('s1.b').option.has_dependency(False) is True assert await cfg.option('s1.b').option.has_dependency(False) is True
assert await cfg.option('c').option.has_dependency(False) is False assert await cfg.option('c').option.has_dependency(False) is False
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -307,11 +319,12 @@ async def test_symlink_makedict(config_type):
linkopt = SymLinkOption("c", boolopt) linkopt = SymLinkOption("c", boolopt)
descr = OptionDescription("opt", "", descr = OptionDescription("opt", "",
[linkopt, OptionDescription("s1", "", [boolopt])]) [linkopt, OptionDescription("s1", "", [boolopt])])
cfg = await Config(descr) async with await Config(descr) as cfg:
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
assert await cfg.value.dict() == {'c': False, 's1.b': False} assert await cfg.value.dict() == {'c': False, 's1.b': False}
await cfg.option('s1.b').value.set(True) await cfg.option('s1.b').value.set(True)
assert await cfg.value.dict() == {'c': True, 's1.b': True} assert await cfg.value.dict() == {'c': True, 's1.b': True}
assert not await list_sessions()
@pytest.mark.asyncio @pytest.mark.asyncio
@ -320,14 +333,15 @@ async def test_symlink_list(config_type):
linkopt = SymLinkOption("c", boolopt) linkopt = SymLinkOption("c", boolopt)
descr = OptionDescription("opt", "", descr = OptionDescription("opt", "",
[linkopt, OptionDescription("s1", "", [boolopt])]) [linkopt, OptionDescription("s1", "", [boolopt])])
cfg = await Config(descr) async with await Config(descr) as cfg:
cfg = await get_config(cfg, config_type) cfg = await get_config(cfg, config_type)
list_opt = [] list_opt = []
for opt in await cfg.option.list(): for opt in await cfg.option.list():
list_opt.append(await opt.option.path()) list_opt.append(await opt.option.path())
assert list_opt == ['c'] assert list_opt == ['c']
# #
list_opt = [] list_opt = []
for opt in await cfg.option.list(recursive=True): for opt in await cfg.option.list(recursive=True):
list_opt.append(await opt.option.path()) list_opt.append(await opt.option.path())
assert list_opt == ['c', 's1.b'] assert list_opt == ['c', 's1.b']
assert not await list_sessions()

View file

@ -1,4 +1,4 @@
# Copyright (C) 2012-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2012-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2019-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the
@ -20,10 +20,10 @@ from functools import wraps
def asyncinit(obj): def asyncinit(obj):
@wraps(obj.__new__) @wraps(obj.__new__)
async def new(cls, *args, **kwargs): async def new(cls, *args, **kwargs):
instance = object.__new__(cls) # (cls, *args, **kwargs) instance = object.__new__(cls) # (cls, *args, **kwargs)
await instance.__init__(*args, **kwargs) await instance.__init__(*args, **kwargs)
return instance return instance
obj.__new__ = new obj.__new__ = new
return obj return obj

View file

@ -1,4 +1,4 @@
# Copyright (C) 2012-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2012-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the
@ -150,8 +150,8 @@ class Calculation:
option_bag: OptionBag, option_bag: OptionBag,
leadership_must_have_index: bool=False) -> str: leadership_must_have_index: bool=False) -> str:
if not self.help_function: if not self.help_function:
return self.execute(option_bag, return await self.execute(option_bag,
leadership_must_have_index=leadership_must_have_index) leadership_must_have_index=leadership_must_have_index)
return await carry_out_calculation(option_bag.option, return await carry_out_calculation(option_bag.option,
callback=self.help_function, callback=self.help_function,
callback_params=self.params, callback_params=self.params,
@ -204,12 +204,8 @@ async def manager_callback(callbk: Union[ParamOption, ParamValue],
path = option.impl_getpath() path = option.impl_getpath()
option_bag = await get_option_bag(config_bag, option_bag = await get_option_bag(config_bag,
option, option,
apply_index) apply_index,
option_bag.config_bag.unrestraint() True)
option_bag.config_bag.remove_validation()
# if we are in properties calculation, cannot calculated properties
option_bag.properties = await config_bag.context.cfgimpl_get_settings().getproperties(option_bag,
apply_requires=False)
new_value = await get_value(callbk, option_bag, path) new_value = await get_value(callbk, option_bag, path)
if apply_index is None and is_follower: if apply_index is None and is_follower:
new_value[index] = value new_value[index] = value
@ -235,7 +231,8 @@ async def manager_callback(callbk: Union[ParamOption, ParamValue],
async def get_option_bag(config_bag, async def get_option_bag(config_bag,
opt, opt,
index_): index_,
self_calc):
# don't validate if option is option that we tried to validate # don't validate if option is option that we tried to validate
config_bag = config_bag.copy() config_bag = config_bag.copy()
config_bag.properties = config_bag.true_properties - {'warnings'} config_bag.properties = config_bag.true_properties - {'warnings'}
@ -245,7 +242,14 @@ async def manager_callback(callbk: Union[ParamOption, ParamValue],
option_bag.set_option(opt, option_bag.set_option(opt,
index_, index_,
config_bag) config_bag)
option_bag.properties = await config_bag.context.cfgimpl_get_settings().getproperties(option_bag) if not self_calc:
option_bag.properties = await config_bag.context.cfgimpl_get_settings().getproperties(option_bag)
else:
option_bag.config_bag.unrestraint()
option_bag.config_bag.remove_validation()
# if we are in properties calculation, cannot calculated properties
option_bag.properties = await config_bag.context.cfgimpl_get_settings().getproperties(option_bag,
apply_requires=False)
return option_bag return option_bag
if isinstance(callbk, ParamValue): if isinstance(callbk, ParamValue):
@ -294,7 +298,8 @@ async def manager_callback(callbk: Union[ParamOption, ParamValue],
path = callbk_option.impl_getpath() path = callbk_option.impl_getpath()
option_bag = await get_option_bag(config_bag, option_bag = await get_option_bag(config_bag,
callbk_option, callbk_option,
index_) index_,
False)
value = await get_value(callbk, option_bag, path) value = await get_value(callbk, option_bag, path)
if with_index: if with_index:
value = value[index] value = value[index]

View file

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2012-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2012-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the
@ -148,7 +148,7 @@ class SubConfig:
doption_bag.set_option(option, doption_bag.set_option(option,
option_bag.index, option_bag.index,
option_bag.config_bag) option_bag.config_bag)
doption_bag.properties = await self.cfgimpl_get_settings().getproperties(doption_bag) doption_bag.properties = None
await self.reset_one_option_cache(desc, await self.reset_one_option_cache(desc,
resetted_opts, resetted_opts,
doption_bag) doption_bag)
@ -212,9 +212,7 @@ class SubConfig:
async def setattr(self, async def setattr(self,
value, value,
option_bag, option_bag):
_commit=True):
if option_bag.option.impl_is_symlinkoption(): if option_bag.option.impl_is_symlinkoption():
raise ConfigError(_("can't set value to a SymLinkOption")) raise ConfigError(_("can't set value to a SymLinkOption"))
context = option_bag.config_bag.context context = option_bag.config_bag.context
@ -223,22 +221,18 @@ class SubConfig:
raise LeadershipError(_('cannot reduce length of the leader "{}"' raise LeadershipError(_('cannot reduce length of the leader "{}"'
'').format(option_bag.option.impl_get_display_name())) '').format(option_bag.option.impl_get_display_name()))
return await context.cfgimpl_get_values().setvalue(value, return await context.cfgimpl_get_values().setvalue(value,
option_bag, option_bag)
_commit)
async def delattr(self, async def delattr(self,
option_bag, option_bag):
_commit=True):
option = option_bag.option option = option_bag.option
if option.impl_is_symlinkoption(): if option.impl_is_symlinkoption():
raise ConfigError(_("can't delete a SymLinkOption")) raise ConfigError(_("can't delete a SymLinkOption"))
values = self.cfgimpl_get_values() values = self.cfgimpl_get_values()
if option_bag.index is not None: if option_bag.index is not None:
await values.reset_follower(option_bag, await values.reset_follower(option_bag)
_commit)
else: else:
await values.reset(option_bag, await values.reset(option_bag)
_commit)
def _get_subpath(self, name): def _get_subpath(self, name):
if self._impl_path is None: if self._impl_path is None:
@ -261,7 +255,8 @@ class SubConfig:
name, name,
option_bag, option_bag,
from_follower=False, from_follower=False,
needs_re_verify_follower_properties=False): needs_re_verify_follower_properties=False,
need_help=True):
""" """
:return: option's value if name is an option name, OptionDescription :return: option's value if name is an option name, OptionDescription
otherwise otherwise
@ -289,17 +284,20 @@ class SubConfig:
if not option.impl_is_follower() or \ if not option.impl_is_follower() or \
(needs_re_verify_follower_properties and option_bag.index is not None) or \ (needs_re_verify_follower_properties and option_bag.index is not None) or \
(not needs_re_verify_follower_properties and (not from_follower or option_bag.index is None)): (not needs_re_verify_follower_properties and (not from_follower or option_bag.index is None)):
await self.cfgimpl_get_settings().validate_properties(option_bag) await self.cfgimpl_get_settings().validate_properties(option_bag,
need_help=need_help)
if option.impl_is_follower() and not from_follower: if option.impl_is_follower() and not from_follower:
length = await self.cfgimpl_get_length_leadership(option_bag) length = await self.cfgimpl_get_length_leadership(option_bag)
follower_len = await self.cfgimpl_get_values()._p_.get_max_length(option_bag.path) follower_len = await self.cfgimpl_get_values()._p_.get_max_length(option_bag.config_bag.connection,
option_bag.path)
if follower_len > length: if follower_len > length:
raise LeadershipError(_('the follower option "{}" has greater length ({}) than the leader ' raise LeadershipError(_('the follower option "{}" has greater length ({}) than the leader '
'length ({})').format(option.impl_get_display_name(), 'length ({})').format(option.impl_get_display_name(),
follower_len, follower_len,
length, length,
option_bag.index)) option_bag.index))
if option.impl_is_follower() and option_bag.index is None: if option.impl_is_follower() and option_bag.index is None:
value = [] value = []
for idx in range(length): for idx in range(length):
@ -307,8 +305,8 @@ class SubConfig:
soption_bag.set_option(option, soption_bag.set_option(option,
idx, idx,
config_bag) config_bag)
soption_bag.properties = await self.cfgimpl_get_settings().getproperties(soption_bag)
try: try:
soption_bag.properties = await self.cfgimpl_get_settings().getproperties(soption_bag)
value.append(await self.getattr(name, value.append(await self.getattr(name,
soption_bag, soption_bag,
from_follower=True, from_follower=True,
@ -422,7 +420,8 @@ class SubConfig:
pathsvalues, pathsvalues,
leader_to_list): leader_to_list):
for opt in await self.cfgimpl_get_description().get_children(config_bag): for opt in await self.cfgimpl_get_description().get_children(config_bag):
if opt.impl_is_optiondescription() and leader_to_list and opt.impl_is_leadership(): if leader_to_list and opt.impl_is_optiondescription() and opt.impl_is_leadership():
# leader
children = await opt.get_children(config_bag) children = await opt.get_children(config_bag)
leader = children[0] leader = children[0]
loption_bag = OptionBag() loption_bag = OptionBag()
@ -453,27 +452,36 @@ class SubConfig:
foption_bag.set_option(follower_opt, foption_bag.set_option(follower_opt,
idx, idx,
config_bag) config_bag)
foption_bag.properties = await self.cfgimpl_get_settings().getproperties(foption_bag) try:
await subconfig._make_sub_dict(leadership_pathsvalues, foption_bag.properties = await self.cfgimpl_get_settings().getproperties(foption_bag)
leader_currpath, await subconfig._make_sub_dict(leadership_pathsvalues,
foption_bag, leader_currpath,
flatten, foption_bag,
fullpath, flatten,
leader_to_list) fullpath,
leader_to_list)
except PropertiesOptionError as err:
if err.proptype in (['mandatory'], ['empty']):
raise err
continue
pathsvalues[leader_name].append(leadership_pathsvalues) pathsvalues[leader_name].append(leadership_pathsvalues)
else: else:
soption_bag = OptionBag() soption_bag = OptionBag()
soption_bag.set_option(opt, soption_bag.set_option(opt,
None, None,
config_bag) config_bag)
soption_bag.properties = await self.cfgimpl_get_settings().getproperties(soption_bag) try:
await self._make_sub_dict(pathsvalues, soption_bag.properties = await self.cfgimpl_get_settings().getproperties(soption_bag)
_currpath, await self._make_sub_dict(pathsvalues,
soption_bag, _currpath,
flatten, soption_bag,
fullpath, flatten,
leader_to_list) fullpath,
return pathsvalues leader_to_list)
except PropertiesOptionError as err:
if err.proptype in (['mandatory'], ['empty']):
raise err
continue
async def _make_sub_dict(self, async def _make_sub_dict(self,
pathsvalues, pathsvalues,
@ -485,31 +493,22 @@ class SubConfig:
option = option_bag.option option = option_bag.option
name = option.impl_getname() name = option.impl_getname()
if option.impl_is_optiondescription(): if option.impl_is_optiondescription():
try: await self.cfgimpl_get_settings().validate_properties(option_bag,
await self.cfgimpl_get_settings().validate_properties(option_bag) need_help=False)
subconfig = await SubConfig(option_bag.option, subconfig = await SubConfig(option_bag.option,
self._impl_context, self._impl_context,
option_bag.config_bag, option_bag.config_bag,
option_bag.path) option_bag.path)
await subconfig._make_dict(option_bag.config_bag, await subconfig._make_dict(option_bag.config_bag,
_currpath + [name], _currpath + [name],
flatten, flatten,
fullpath, fullpath,
pathsvalues, pathsvalues,
leader_to_list) leader_to_list)
except PropertiesOptionError as err:
if err.proptype in (['mandatory'], ['empty']):
raise err
else: else:
try: ret = await self.getattr(name,
ret = await self.getattr(name, option_bag,
option_bag) need_help=False)
except PropertiesOptionError as err:
# import traceback
# traceback.print_exc()
if err.proptype in (['mandatory'], ['empty']):
raise err
return
if flatten: if flatten:
name_ = option.impl_getname() name_ = option.impl_getname()
elif fullpath: elif fullpath:
@ -551,6 +550,7 @@ class _CommonConfig(SubConfig):
# information # information
async def impl_set_information(self, async def impl_set_information(self,
connection,
key, key,
value): value):
"""updates the information's attribute """updates the information's attribute
@ -558,48 +558,56 @@ class _CommonConfig(SubConfig):
:param key: information's key (ex: "help", "doc" :param key: information's key (ex: "help", "doc"
:param value: information's value (ex: "the help string") :param value: information's value (ex: "the help string")
""" """
await self._impl_values.set_information(key, await self._impl_values.set_information(connection,
key,
value) value)
async def impl_get_information(self, async def impl_get_information(self,
connection,
key, key,
default=undefined): default=undefined):
"""retrieves one information's item """retrieves one information's item
:param key: the item string (ex: "help") :param key: the item string (ex: "help")
""" """
return await self._impl_values.get_information(key, return await self._impl_values.get_information(connection,
key,
default) default)
async def impl_del_information(self, async def impl_del_information(self,
connection,
key, key,
raises=True): raises=True):
await self._impl_values.del_information(key, await self._impl_values.del_information(connection,
key,
raises) raises)
async def impl_list_information(self): async def impl_list_information(self,
return await self._impl_values.list_information() connection):
return await self._impl_values.list_information(connection)
def __getstate__(self): def __getstate__(self):
raise NotImplementedError() raise NotImplementedError()
async def _gen_fake_values(self): async def _gen_fake_values(self,
connection):
fake_config = await KernelConfig(self._impl_descr, fake_config = await KernelConfig(self._impl_descr,
persistent=False, force_values=await get_default_values_storages(connection),
force_values=await get_default_values_storages(),
force_settings=self.cfgimpl_get_settings(), force_settings=self.cfgimpl_get_settings(),
display_name=self._display_name) display_name=self._display_name,
export = await self.cfgimpl_get_values()._p_.exportation() connection=connection)
await fake_config.cfgimpl_get_values()._p_.importation(export) export = await self.cfgimpl_get_values()._p_.exportation(connection)
await fake_config.cfgimpl_get_values()._p_.importation(connection,
export)
fake_config.parents = self.parents fake_config.parents = self.parents
return fake_config return fake_config
async def duplicate(self, async def duplicate(self,
connection,
session_id=None, session_id=None,
force_values=None, force_values=None,
force_settings=None, force_settings=None,
storage=None, storage=None,
persistent=False,
metaconfig_prefix=None, metaconfig_prefix=None,
child=None, child=None,
deep=None): deep=None):
@ -610,8 +618,8 @@ class _CommonConfig(SubConfig):
session_id=session_id, session_id=session_id,
force_values=force_values, force_values=force_values,
force_settings=force_settings, force_settings=force_settings,
persistent=persistent,
storage=storage, storage=storage,
connection=connection,
display_name=self._display_name) display_name=self._display_name)
else: else:
if session_id is None and metaconfig_prefix is not None: if session_id is None and metaconfig_prefix is not None:
@ -620,15 +628,18 @@ class _CommonConfig(SubConfig):
_duplicate=True, _duplicate=True,
optiondescription=self._impl_descr, optiondescription=self._impl_descr,
session_id=session_id, session_id=session_id,
persistent=persistent,
storage=storage, storage=storage,
connection=connection,
display_name=self._display_name) display_name=self._display_name)
duplicated_values = duplicated_config.cfgimpl_get_values() duplicated_values = duplicated_config.cfgimpl_get_values()
duplicated_settings = duplicated_config.cfgimpl_get_settings() duplicated_settings = duplicated_config.cfgimpl_get_settings()
await duplicated_values._p_.importation(await self.cfgimpl_get_values()._p_.exportation()) await duplicated_values._p_.importation(connection,
properties = await self.cfgimpl_get_settings()._p_.exportation() await self.cfgimpl_get_values()._p_.exportation(connection))
await duplicated_settings._p_.importation(properties) properties = await self.cfgimpl_get_settings()._p_.exportation(connection)
await duplicated_settings._pp_.importation(await self.cfgimpl_get_settings()._pp_.exportation()) await duplicated_settings._p_.importation(connection,
properties)
await duplicated_settings._pp_.importation(connection,
await self.cfgimpl_get_settings()._pp_.exportation(connection))
duplicated_settings.ro_append = self.cfgimpl_get_settings().ro_append duplicated_settings.ro_append = self.cfgimpl_get_settings().ro_append
duplicated_settings.rw_append = self.cfgimpl_get_settings().rw_append duplicated_settings.rw_append = self.cfgimpl_get_settings().rw_append
duplicated_settings.ro_remove = self.cfgimpl_get_settings().ro_remove duplicated_settings.ro_remove = self.cfgimpl_get_settings().ro_remove
@ -644,11 +655,11 @@ class _CommonConfig(SubConfig):
wparent = parent() wparent = parent()
if wparent not in deep: if wparent not in deep:
deep.append(wparent) deep.append(wparent)
duplicated_config = await wparent.duplicate(deep=deep, duplicated_config = await wparent.duplicate(connection,
deep=deep,
storage=storage, storage=storage,
metaconfig_prefix=metaconfig_prefix, metaconfig_prefix=metaconfig_prefix,
child=duplicated_config, child=duplicated_config)
persistent=persistent)
else: else:
duplicated_config.parents = self.parents duplicated_config.parents = self.parents
for parent in self.parents: for parent in self.parents:
@ -672,13 +683,15 @@ class KernelConfig(_CommonConfig):
__slots__ = ('__weakref__', __slots__ = ('__weakref__',
'_impl_name', '_impl_name',
'_display_name', '_display_name',
'_impl_symlink') '_impl_symlink',
'_storage')
impl_type = 'config' impl_type = 'config'
async def __init__(self, async def __init__(self,
descr, descr,
connection,
session_id=None, session_id=None,
persistent=False, delete_old_session=False,
force_values=None, force_values=None,
force_settings=None, force_settings=None,
display_name=None, display_name=None,
@ -690,11 +703,8 @@ class KernelConfig(_CommonConfig):
:type descr: an instance of ``option.OptionDescription`` :type descr: an instance of ``option.OptionDescription``
:param context: the current root config :param context: the current root config
:type context: `Config` :type context: `Config`
:param session_id: session ID is import with persistent Config to :param session_id: name of the session
retrieve good session
:type session_id: `str` :type session_id: `str`
:param persistent: if persistent, don't delete storage when leaving
:type persistent: `boolean`
""" """
self.parents = [] self.parents = []
self._impl_symlink = [] self._impl_symlink = []
@ -711,21 +721,25 @@ class KernelConfig(_CommonConfig):
self._impl_settings = force_settings self._impl_settings = force_settings
self._impl_permissives_cache = Cache() self._impl_permissives_cache = Cache()
self._impl_properties_cache = Cache() self._impl_properties_cache = Cache()
self._impl_values = await Values(force_values) self._impl_values = await Values(force_values,
connection)
self._impl_values_cache = Cache() self._impl_values_cache = Cache()
else: else:
properties, permissives, values, session_id = await get_storages(self, storage, properties, permissives, values, session_id = await get_storages(self,
session_id, session_id,
persistent, delete_old_session,
storage=storage) storage,
connection)
if not valid_name(session_id): if not valid_name(session_id):
raise ValueError(_("invalid session ID: {0} for config").format(session_id)) raise ValueError(_("invalid session ID: {0} for config").format(session_id))
self._impl_settings = Settings(properties, self._impl_settings = Settings(properties,
permissives) permissives)
self._impl_permissives_cache = Cache() self._impl_permissives_cache = Cache()
self._impl_properties_cache = Cache() self._impl_properties_cache = Cache()
self._impl_values = await Values(values) self._impl_values = await Values(values,
connection)
self._impl_values_cache = Cache() self._impl_values_cache = Cache()
self._storage = storage
self._impl_context = weakref.ref(self) self._impl_context = weakref.ref(self)
await super().__init__(descr, await super().__init__(descr,
self._impl_context, self._impl_context,
@ -738,6 +752,9 @@ class KernelConfig(_CommonConfig):
def impl_getname(self): def impl_getname(self):
return self._impl_name return self._impl_name
def getconnection(self):
return self.cfgimpl_get_settings()._p_.getconnection()
@asyncinit @asyncinit
class KernelGroupConfig(_CommonConfig): class KernelGroupConfig(_CommonConfig):
@ -803,17 +820,10 @@ class KernelGroupConfig(_CommonConfig):
index, index,
value, value,
config_bag, config_bag,
only_config=False, only_config=False):
_commit=True):
"""Setattr not in current KernelGroupConfig, but in each children """Setattr not in current KernelGroupConfig, but in each children
""" """
ret = [] ret = []
if self.impl_type == 'group':
# No value so cannot commit only one time
commit = True
else:
# Commit only one time
commit = False
for child in self._impl_children: for child in self._impl_children:
cconfig_bag = config_bag.copy() cconfig_bag = config_bag.copy()
cconfig_bag.context = child cconfig_bag.context = child
@ -822,12 +832,12 @@ class KernelGroupConfig(_CommonConfig):
index, index,
value, value,
cconfig_bag, cconfig_bag,
only_config=only_config, only_config=only_config))
_commit=commit))
else: else:
settings = child.cfgimpl_get_settings() settings = child.cfgimpl_get_settings()
properties = await settings.get_context_properties(child._impl_properties_cache) properties = await settings.get_context_properties(config_bag.connection,
permissives = await settings.get_context_permissives() child._impl_properties_cache)
permissives = await settings.get_context_permissives(config_bag.connection)
cconfig_bag.properties = properties cconfig_bag.properties = properties
cconfig_bag.permissives = permissives cconfig_bag.permissives = permissives
try: try:
@ -842,8 +852,7 @@ class KernelGroupConfig(_CommonConfig):
cconfig_bag) cconfig_bag)
option_bag.properties = await settings.getproperties(option_bag) option_bag.properties = await settings.getproperties(option_bag)
await child.setattr(value, await child.setattr(value,
option_bag, option_bag)
_commit=commit)
except PropertiesOptionError as err: except PropertiesOptionError as err:
ret.append(PropertiesOptionError(err._option_bag, ret.append(PropertiesOptionError(err._option_bag,
err.proptype, err.proptype,
@ -853,8 +862,6 @@ class KernelGroupConfig(_CommonConfig):
err._orig_opt)) err._orig_opt))
except (ValueError, LeadershipError, AttributeError) as err: except (ValueError, LeadershipError, AttributeError) as err:
ret.append(err) ret.append(err)
if _commit and self.impl_type != 'group':
await self.cfgimpl_get_values()._p_.commit()
return ret return ret
@ -896,8 +903,9 @@ class KernelGroupConfig(_CommonConfig):
cconfig_bag = config_bag.copy() cconfig_bag = config_bag.copy()
cconfig_bag.context = child cconfig_bag.context = child
settings = child.cfgimpl_get_settings() settings = child.cfgimpl_get_settings()
properties = await settings.get_context_properties(child._impl_properties_cache) properties = await settings.get_context_properties(config_bag.connection,
permissives = await settings.get_context_permissives() child._impl_properties_cache)
permissives = await settings.get_context_permissives(config_bag.connection)
cconfig_bag.properties = properties cconfig_bag.properties = properties
cconfig_bag.permissives = permissives cconfig_bag.permissives = permissives
async for path in child.find(None, async for path in child.find(None,
@ -918,15 +926,17 @@ class KernelGroupConfig(_CommonConfig):
return self._impl_name return self._impl_name
async def reset(self, async def reset(self,
path, connection,
_commit=True): path):
for child in self._impl_children: for child in self._impl_children:
settings = child.cfgimpl_get_settings() settings = child.cfgimpl_get_settings()
properties = await settings.get_context_properties(child._impl_properties_cache) properties = await settings.get_context_properties(connection,
permissives = await settings.get_context_permissives() child._impl_properties_cache)
permissives = await settings.get_context_permissives(connection)
config_bag = ConfigBag(child, config_bag = ConfigBag(child,
properties=properties, properties=properties,
permissives=permissives) permissives=permissives)
config_bag.connection = connection
config_bag.remove_validation() config_bag.remove_validation()
subconfig, name = await child.cfgimpl_get_home_by_path(path, subconfig, name = await child.cfgimpl_get_home_by_path(path,
config_bag) config_bag)
@ -939,8 +949,7 @@ class KernelGroupConfig(_CommonConfig):
config_bag) config_bag)
option_bag.properties = await child.cfgimpl_get_settings().getproperties(option_bag) option_bag.properties = await child.cfgimpl_get_settings().getproperties(option_bag)
option_bag.config_bag.context = child option_bag.config_bag.context = child
await child.cfgimpl_get_values().reset(option_bag, await child.cfgimpl_get_values().reset(option_bag)
_commit=_commit)
def getconfig(self, def getconfig(self,
name): name):
@ -949,18 +958,26 @@ class KernelGroupConfig(_CommonConfig):
return child return child
raise ConfigError(_('unknown config "{}"').format(name)) raise ConfigError(_('unknown config "{}"').format(name))
def getconnection(self):
if self.impl_type == 'group':
# Get the first storage, assume that all children have same storage
return self._impl_children[0].getconnection()
return self.cfgimpl_get_settings()._p_.getconnection()
@asyncinit @asyncinit
class KernelMixConfig(KernelGroupConfig): class KernelMixConfig(KernelGroupConfig):
__slots__ = ('_display_name', __slots__ = ('_display_name',
'_impl_symlink') '_impl_symlink',
'_storage')
impl_type = 'mix' impl_type = 'mix'
async def __init__(self, async def __init__(self,
optiondescription, optiondescription,
children, children,
connection,
session_id=None, session_id=None,
persistent=False, delete_old_session=False,
storage=None, storage=None,
display_name=None, display_name=None,
_duplicate=False): _duplicate=False):
@ -971,16 +988,19 @@ class KernelMixConfig(KernelGroupConfig):
if not isinstance(child, (KernelConfig, KernelMixConfig)): if not isinstance(child, (KernelConfig, KernelMixConfig)):
raise TypeError(_("child must be a Config, MixConfig or MetaConfig")) raise TypeError(_("child must be a Config, MixConfig or MetaConfig"))
child.parents.append(weakref.ref(self)) child.parents.append(weakref.ref(self))
properties, permissives, values, session_id = await get_storages(self, storage, properties, permissives, values, session_id = await get_storages(self,
session_id, session_id,
persistent, delete_old_session,
storage=storage) storage,
connection)
self._impl_settings = Settings(properties, self._impl_settings = Settings(properties,
permissives) permissives)
self._impl_permissives_cache = Cache() self._impl_permissives_cache = Cache()
self._impl_properties_cache = Cache() self._impl_properties_cache = Cache()
self._impl_values = await Values(values) self._impl_values = await Values(values,
connection)
self._impl_values_cache = Cache() self._impl_values_cache = Cache()
self._storage = storage
await super().__init__(children, await super().__init__(children,
session_id=session_id, session_id=session_id,
_descr=optiondescription) _descr=optiondescription)
@ -994,8 +1014,7 @@ class KernelMixConfig(KernelGroupConfig):
force_default=False, force_default=False,
force_dont_change_value=False, force_dont_change_value=False,
force_default_if_same=False, force_default_if_same=False,
only_config=False, only_config=False):
_commit=True):
"""only_config: could be set if you want modify value in all Config included in """only_config: could be set if you want modify value in all Config included in
this KernelMetaConfig this KernelMetaConfig
""" """
@ -1008,8 +1027,7 @@ class KernelMixConfig(KernelGroupConfig):
index, index,
value, value,
config_bag, config_bag,
only_config=only_config, only_config=only_config)
_commit=_commit)
ret = [] ret = []
subconfig, name = await self.cfgimpl_get_home_by_path(path, subconfig, name = await self.cfgimpl_get_home_by_path(path,
config_bag) config_bag)
@ -1029,8 +1047,9 @@ class KernelMixConfig(KernelGroupConfig):
cconfig_bag = config_bag.copy() cconfig_bag = config_bag.copy()
cconfig_bag.context = child cconfig_bag.context = child
settings = child.cfgimpl_get_settings() settings = child.cfgimpl_get_settings()
properties = await settings.get_context_properties(child._impl_properties_cache) properties = await settings.get_context_properties(config_bag.connection,
permissives = await settings.get_context_permissives() child._impl_properties_cache)
permissives = await settings.get_context_permissives(config_bag.connection)
cconfig_bag.properties = properties cconfig_bag.properties = properties
cconfig_bag.permissives = permissives cconfig_bag.permissives = permissives
try: try:
@ -1053,22 +1072,21 @@ class KernelMixConfig(KernelGroupConfig):
cconfig_bag) cconfig_bag)
moption_bag.properties = await settings.getproperties(moption_bag) moption_bag.properties = await settings.getproperties(moption_bag)
if force_default_if_same: if force_default_if_same:
if not await child.cfgimpl_get_values()._p_.hasvalue(path): if not await child.cfgimpl_get_values()._p_.hasvalue(config_bag.connection,
path):
child_value = undefined child_value = undefined
else: else:
child_value = await subconfig2.getattr(name, child_value = await subconfig2.getattr(name,
moption_bag) moption_bag)
if force_default or (force_default_if_same and value == child_value): if force_default or (force_default_if_same and value == child_value):
await child.cfgimpl_get_values().reset(moption_bag, await child.cfgimpl_get_values().reset(moption_bag)
_commit=False)
continue continue
if force_dont_change_value: if force_dont_change_value:
child_value = await child.getattr(name, child_value = await child.getattr(name,
moption_bag) moption_bag)
if value != child_value: if value != child_value:
await subconfig2.setattr(child_value, await subconfig2.setattr(child_value,
moption_bag, moption_bag)
_commit=False)
except PropertiesOptionError as err: except PropertiesOptionError as err:
ret.append(PropertiesOptionError(err._option_bag, ret.append(PropertiesOptionError(err._option_bag,
err.proptype, err.proptype,
@ -1089,8 +1107,7 @@ class KernelMixConfig(KernelGroupConfig):
else: else:
moption_bag = option_bag moption_bag = option_bag
await subconfig.setattr(value, await subconfig.setattr(value,
moption_bag, moption_bag)
_commit=False)
except (PropertiesOptionError, ValueError, LeadershipError) as err: except (PropertiesOptionError, ValueError, LeadershipError) as err:
ret.append(err) ret.append(err)
return ret return ret
@ -1098,8 +1115,7 @@ class KernelMixConfig(KernelGroupConfig):
async def reset(self, async def reset(self,
path, path,
only_children, only_children,
config_bag, config_bag):
commit=True):
rconfig_bag = config_bag.copy() rconfig_bag = config_bag.copy()
rconfig_bag.remove_validation() rconfig_bag.remove_validation()
if self.impl_type == 'meta': if self.impl_type == 'meta':
@ -1144,21 +1160,16 @@ class KernelMixConfig(KernelGroupConfig):
None, None,
rconfig_bag) rconfig_bag)
moption_bag.properties = await self.cfgimpl_get_settings().getproperties(moption_bag) moption_bag.properties = await self.cfgimpl_get_settings().getproperties(moption_bag)
await child.cfgimpl_get_values().reset(moption_bag, await child.cfgimpl_get_values().reset(moption_bag)
_commit=False)
except AttributeError: except AttributeError:
pass pass
if isinstance(child, KernelMixConfig): if isinstance(child, KernelMixConfig):
await child.reset(path, await child.reset(path,
False, False,
rconfig_bag, rconfig_bag)
commit=False)
if not only_children: if not only_children:
option_bag.config_bag = config_bag option_bag.config_bag = config_bag
await self.cfgimpl_get_values().reset(option_bag, await self.cfgimpl_get_values().reset(option_bag)
_commit=False)
if commit:
await self.cfgimpl_get_values()._p_.commit()
async def add_config(self, async def add_config(self,
apiconfig): apiconfig):
@ -1201,8 +1212,9 @@ class KernelMetaConfig(KernelMixConfig):
async def __init__(self, async def __init__(self,
children, children,
connection,
session_id=None, session_id=None,
persistent=False, delete_old_session=False,
optiondescription=None, optiondescription=None,
storage=None, storage=None,
display_name=None, display_name=None,
@ -1217,7 +1229,8 @@ class KernelMetaConfig(KernelMixConfig):
' must have string has child, ' ' must have string has child, '
'not {}').format(child_session_id) 'not {}').format(child_session_id)
new_children.append(await KernelConfig(optiondescription, new_children.append(await KernelConfig(optiondescription,
persistent=persistent, connection,
delete_old_session=delete_old_session,
session_id=child_session_id, session_id=child_session_id,
display_name=self._display_name)) display_name=self._display_name))
children = new_children children = new_children
@ -1233,46 +1246,51 @@ class KernelMetaConfig(KernelMixConfig):
'have the same optiondescription')) 'have the same optiondescription'))
await super().__init__(descr, await super().__init__(descr,
children, children,
persistent=persistent, connection,
delete_old_session=delete_old_session,
storage=storage, storage=storage,
session_id=session_id) session_id=session_id)
async def new_config(self, async def new_config(self,
connection,
session_id, session_id,
type_='config', type_='config',
persistent=False,
storage=None): storage=None):
if session_id in [child.impl_getname() for child in self._impl_children]: if session_id in [child.impl_getname() for child in self._impl_children]:
raise ConflictError(_('config name must be uniq in ' raise ConflictError(_('config name must be uniq in '
'groupconfig for {0}').format(session_id)) 'groupconfig for {0}').format(session_id))
assert type_ in ('config', 'metaconfig', 'mixconfig'), _('unknown type {}').format(type_) assert type_ in ('config', 'metaconfig', 'mixconfig'), _('unknown type {}').format(type_)
new = not persistent or session_id not in list_sessions() new = session_id not in await list_sessions()
if type_ == 'config': if type_ == 'config':
config = await KernelConfig(self._impl_descr, config = await KernelConfig(self._impl_descr,
session_id=session_id, session_id=session_id,
persistent=persistent,
storage=storage, storage=storage,
connection=connection,
display_name=self._display_name) display_name=self._display_name)
elif type_ == 'metaconfig': elif type_ == 'metaconfig':
config = await KernelMetaConfig([], config = await KernelMetaConfig([],
optiondescription=self._impl_descr, optiondescription=self._impl_descr,
session_id=session_id, session_id=session_id,
persistent=persistent,
storage=storage, storage=storage,
connection=connection,
display_name=self._display_name) display_name=self._display_name)
elif type_ == 'mixconfig': elif type_ == 'mixconfig':
config = await KernelMixConfig(children=[], config = await KernelMixConfig(children=[],
optiondescription=self._impl_descr, optiondescription=self._impl_descr,
session_id=session_id, session_id=session_id,
persistent=persistent,
storage=storage, storage=storage,
connection=connection,
display_name=self._display_name) display_name=self._display_name)
# Copy context properties/permissives # Copy context properties/permissives
if new: if new:
settings = config.cfgimpl_get_settings() settings = config.cfgimpl_get_settings()
properties = await self.cfgimpl_get_settings().get_context_properties(config._impl_properties_cache) properties = await self.cfgimpl_get_settings().get_context_properties(connection,
await settings.set_context_properties(properties, config) config._impl_properties_cache)
await settings.set_context_permissives(await self.cfgimpl_get_settings().get_context_permissives()) await settings.set_context_properties(connection,
properties,
config)
await settings.set_context_permissives(connection,
await self.cfgimpl_get_settings().get_context_permissives(connection))
settings.ro_append = self.cfgimpl_get_settings().ro_append settings.ro_append = self.cfgimpl_get_settings().ro_append
settings.rw_append = self.cfgimpl_get_settings().rw_append settings.rw_append = self.cfgimpl_get_settings().rw_append
settings.ro_remove = self.cfgimpl_get_settings().ro_remove settings.ro_remove = self.cfgimpl_get_settings().ro_remove

View file

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2012-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2012-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the
@ -57,7 +57,8 @@ class PropertiesOptionError(AttributeError):
settings, settings,
opt_type=None, opt_type=None,
name=None, name=None,
orig_opt=None): orig_opt=None,
help_properties=None):
if opt_type: if opt_type:
self._opt_type = opt_type self._opt_type = opt_type
self._name = name self._name = name
@ -71,6 +72,7 @@ class PropertiesOptionError(AttributeError):
self._orig_opt = None self._orig_opt = None
self._option_bag = option_bag self._option_bag = option_bag
self.proptype = proptype self.proptype = proptype
self.help_properties = help_properties
self._settings = settings self._settings = settings
self.msg = None self.msg = None
super().__init__(None) super().__init__(None)
@ -84,12 +86,10 @@ class PropertiesOptionError(AttributeError):
return self.msg return self.msg
if self._settings is None: if self._settings is None:
return 'error' return 'error'
#for property_ in self._settings.get_calculated_properties(self._option_bag): if self.help_properties:
# prop = property_.help(self._option_bag) properties = list(self.help_properties)
# if prop is not None: else:
# properties.append(prop) properties = list(self.proptype)
properties = list(self.proptype)
only_one = len(properties) == 1 only_one = len(properties) == 1
properties_msg = display_list(properties, add_quote=True) properties_msg = display_list(properties, add_quote=True)
if only_one: if only_one:

View file

@ -1,4 +1,4 @@
# Copyright (C) 2018-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2018-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the
@ -510,8 +510,8 @@ class CalcValuePropertyHelp(CalcValue):
msgs.append(self.build_arg(name, f'"{value}"')) msgs.append(self.build_arg(name, f'"{value}"'))
msg = display_list(msgs, self.condition_operator.lower()) msg = display_list(msgs, self.condition_operator.lower())
else: else:
return [f'"{action}"'] return [(action, f'"{action}"')]
return [f'"{action}" ({msg})'] return [(action, f'"{action}" ({msg})')]
return return
## calc_properties.setdefault(action, []).append(msg) ## calc_properties.setdefault(action, []).append(msg)

View file

@ -1,5 +1,5 @@
# -*- coding: UTF-8 -*- # -*- coding: UTF-8 -*-
# Copyright (C) 2012-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2012-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"logger for tiramisu" "logger for tiramisu"
# Copyright (C) 2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2019-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the

View file

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2014-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the

View file

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2017-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2017-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the

View file

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2017-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2017-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the

View file

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2017-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2017-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the

View file

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2017-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2017-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the

View file

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2017-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2017-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the

View file

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2017-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2017-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the

View file

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2017-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2017-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the

View file

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2017-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2017-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the

View file

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2017-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2017-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the

View file

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2017-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2017-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the

View file

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2017-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2017-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"Leadership support" "Leadership support"
# Copyright (C) 2014-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2014-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the
@ -113,8 +113,7 @@ class Leadership(OptionDescription):
async def reset(self, async def reset(self,
values: Values, values: Values,
option_bag: OptionBag, option_bag: OptionBag) -> None:
_commit: bool=True) -> None:
config_bag = option_bag.config_bag.copy() config_bag = option_bag.config_bag.copy()
config_bag.remove_validation() config_bag.remove_validation()
for follower in self.get_followers(): for follower in self.get_followers():
@ -123,15 +122,13 @@ class Leadership(OptionDescription):
None, None,
config_bag) config_bag)
soption_bag.properties = await config_bag.context.cfgimpl_get_settings().getproperties(soption_bag) soption_bag.properties = await config_bag.context.cfgimpl_get_settings().getproperties(soption_bag)
await values.reset(soption_bag, await values.reset(soption_bag)
_commit=_commit)
async def follower_force_store_value(self, async def follower_force_store_value(self,
values, values,
value, value,
option_bag, option_bag,
owner, owner,
_commit,
dyn=None) -> None: dyn=None) -> None:
settings = option_bag.config_bag.context.cfgimpl_get_settings() settings = option_bag.config_bag.context.cfgimpl_get_settings()
if value: if value:
@ -152,8 +149,7 @@ class Leadership(OptionDescription):
foption_bag.properties = await settings.getproperties(foption_bag) foption_bag.properties = await settings.getproperties(foption_bag)
await values._setvalue(foption_bag, await values._setvalue(foption_bag,
await values.getvalue(foption_bag), await values.getvalue(foption_bag),
owner, owner)
commit=False)
async def pop(self, async def pop(self,
values: Values, values: Values,
@ -167,7 +163,8 @@ class Leadership(OptionDescription):
config_bag.remove_validation() config_bag.remove_validation()
for follower in followers: for follower in followers:
follower_path = follower.impl_getpath() follower_path = follower.impl_getpath()
followerlen = await values._p_.get_max_length(follower_path) followerlen = await values._p_.get_max_length(config_bag.connection,
follower_path)
soption_bag = OptionBag() soption_bag = OptionBag()
soption_bag.set_option(follower, soption_bag.set_option(follower,
index, index,
@ -177,13 +174,16 @@ class Leadership(OptionDescription):
is_default = await values.is_default_owner(soption_bag, is_default = await values.is_default_owner(soption_bag,
validate_meta=False) validate_meta=False)
if not is_default and followerlen > index: if not is_default and followerlen > index:
await values._p_.resetvalue_index(follower_path, await values._p_.resetvalue_index(config_bag.connection,
index, follower_path,
True) index)
if followerlen > index + 1: if followerlen > index + 1:
for idx in range(index + 1, followerlen): for idx in range(index + 1, followerlen):
if await values._p_.hasvalue(follower_path, idx): if await values._p_.hasvalue(config_bag.connection,
await values._p_.reduce_index(follower_path, follower_path,
idx):
await values._p_.reduce_index(config_bag.connection,
follower_path,
idx) idx)
def reset_cache(self, def reset_cache(self,

View file

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2017-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2017-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the

View file

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2017-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2017-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"option types and option description" "option types and option description"
# Copyright (C) 2012-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2012-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the

View file

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2014-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the
@ -109,10 +109,10 @@ class CacheOptionDescription(BaseOption):
config_bag: ConfigBag) -> None: config_bag: ConfigBag) -> None:
if 'force_store_value' not in config_bag.properties: if 'force_store_value' not in config_bag.properties:
return return
commit = False
values = config_bag.context.cfgimpl_get_values() values = config_bag.context.cfgimpl_get_values()
for subpath, option in self._cache_force_store_values: for subpath, option in self._cache_force_store_values:
if not await values._p_.hasvalue(subpath): if not await values._p_.hasvalue(config_bag.connection,
subpath):
if option.impl_is_follower(): if option.impl_is_follower():
option_bag = OptionBag() option_bag = OptionBag()
leader = option.impl_get_leadership().get_leader() leader = option.impl_get_leadership().get_leader()
@ -127,7 +127,8 @@ class CacheOptionDescription(BaseOption):
index, index,
config_bag) config_bag)
option_bag.properties = frozenset() option_bag.properties = frozenset()
await values._p_.setvalue(subpath, await values._p_.setvalue(config_bag.connection,
subpath,
await values.getvalue(option_bag), await values.getvalue(option_bag),
owners.forced, owners.forced,
index, index,
@ -138,15 +139,12 @@ class CacheOptionDescription(BaseOption):
None, None,
config_bag) config_bag)
option_bag.properties = frozenset() option_bag.properties = frozenset()
await values._p_.setvalue(subpath, await values._p_.setvalue(config_bag.connection,
subpath,
await values.getvalue(option_bag), await values.getvalue(option_bag),
owners.forced, owners.forced,
None, None,
False) False)
commit = True
if commit:
await values._p_.commit()
class OptionDescriptionWalk(CacheOptionDescription): class OptionDescriptionWalk(CacheOptionDescription):

View file

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2017-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2017-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the

View file

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2017-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2017-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the

View file

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2017-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2017-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the

View file

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2017-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2017-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the

View file

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2018-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2018-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the

View file

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2017-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2017-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the
@ -103,7 +103,7 @@ class SynDynOptionDescription:
config_bag, config_bag,
self): self):
yield option yield option
def impl_getpath(self) -> str: def impl_getpath(self) -> str:
subpath = self._subpath subpath = self._subpath
if subpath != '': if subpath != '':
@ -150,11 +150,9 @@ class SynDynLeadership(SynDynOptionDescription):
values, values,
value, value,
option_bag, option_bag,
owner, owner) -> None:
_commit) -> None:
await self._opt.follower_force_store_value(values, await self._opt.follower_force_store_value(values,
value, value,
option_bag, option_bag,
owner, owner,
_commit,
dyn=self) dyn=self)

View file

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2017-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2017-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the

View file

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2017-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2017-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"sets the options of the configuration objects Config object itself" "sets the options of the configuration objects Config object itself"
# Copyright (C) 2012-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2012-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the
@ -192,7 +192,8 @@ class ConfigBag:
'true_properties', # properties for current context 'true_properties', # properties for current context
'is_unrestraint', 'is_unrestraint',
'permissives', # permissives for current context 'permissives', # permissives for current context
'expiration_time' # EXPIRATION_TIME 'expiration_time', # EXPIRATION_TIME
'connection',
) )
def __init__(self, def __init__(self,
@ -236,7 +237,10 @@ class ConfigBag:
def copy(self): def copy(self):
kwargs = {} kwargs = {}
for key in self.__slots__: for key in self.__slots__:
kwargs[key] = getattr(self, key) try:
kwargs[key] = getattr(self, key)
except KeyError:
pass
return ConfigBag(**kwargs) return ConfigBag(**kwargs)
@ -374,9 +378,6 @@ class Settings(object):
:param context: the root config :param context: the root config
:param storage: the storage type :param storage: the storage type
- dictionary -> in memory
- sqlite3 -> persistent
""" """
# generic owner # generic owner
self._p_ = properties self._p_ = properties
@ -391,6 +392,7 @@ class Settings(object):
# get properties and permissive methods # get properties and permissive methods
async def get_context_properties(self, async def get_context_properties(self,
connection,
cache): cache):
is_cached, props, validated = cache.getcache(None, is_cached, props, validated = cache.getcache(None,
None, None,
@ -399,7 +401,8 @@ class Settings(object):
{}, {},
'context_props') 'context_props')
if not is_cached: if not is_cached:
props = await self._p_.getproperties(None, props = await self._p_.getproperties(connection,
None,
None, None,
self.default_properties) self.default_properties)
cache.setcache(None, cache.setcache(None,
@ -413,7 +416,8 @@ class Settings(object):
async def getproperties(self, async def getproperties(self,
option_bag, option_bag,
apply_requires=True, apply_requires=True,
uncalculated=False): uncalculated=False,
help_property=False):
""" """
""" """
option = option_bag.option option = option_bag.option
@ -422,44 +426,58 @@ class Settings(object):
option = option.impl_getopt() option = option.impl_getopt()
path = option.impl_getpath() path = option.impl_getpath()
index = option_bag.index index = option_bag.index
if apply_requires and not uncalculated: if apply_requires and not uncalculated and not help_property:
cache = config_bag.context._impl_properties_cache cache = config_bag.context._impl_properties_cache
config_bag_props = config_bag.properties
is_cached, props, validated = cache.getcache(path, is_cached, props, validated = cache.getcache(path,
config_bag.expiration_time, config_bag.expiration_time,
index, index,
config_bag_props, config_bag.properties,
{}, {},
'self_props') 'self_props')
else: else:
is_cached = False is_cached = False
if not is_cached: if not is_cached:
props = set() props = set()
p_props = await self._p_.getproperties(path, # if index, get option's properties (without index) too
p_props = await self._p_.getproperties(config_bag.connection,
path,
None, None,
option.impl_getproperties()) option.impl_getproperties())
if index is not None: if index is not None:
p_props = chain(p_props, p_props = chain(p_props,
await self._p_.getproperties(path, await self._p_.getproperties(config_bag.connection,
path,
index, index,
option.impl_getproperties())) option.impl_getproperties()))
for prop in p_props: for prop in p_props:
if uncalculated or isinstance(prop, str): if uncalculated or isinstance(prop, str):
props.add(prop) if not help_property:
props.add(prop)
else:
props.add((prop, prop))
elif apply_requires: elif apply_requires:
new_prop = await prop.execute(option_bag, if not help_property:
leadership_must_have_index=True) new_prop = await prop.execute(option_bag,
leadership_must_have_index=True)
else:
new_prop = await prop.help(option_bag,
leadership_must_have_index=True)
if isinstance(new_prop, str):
new_prop = (new_prop, new_prop)
if new_prop is None: if new_prop is None:
continue continue
elif not isinstance(new_prop, str): elif (not help_property and not isinstance(new_prop, str)) or \
(help_property and not isinstance(new_prop, tuple)):
raise ValueError(_('invalid property type {} for {} with {} function').format(type(new_prop), raise ValueError(_('invalid property type {} for {} with {} function').format(type(new_prop),
option_bag.option.impl_getname(), option_bag.option.impl_getname(),
prop.function.__name__)) prop.function.__name__))
if not option.impl_is_optiondescription() and option.impl_is_leader() and new_prop not in ALLOWED_LEADER_PROPERTIES: if not option.impl_is_optiondescription() and \
option.impl_is_leader() and \
new_prop not in ALLOWED_LEADER_PROPERTIES:
raise LeadershipError(_('leader cannot have "{}" property').format(new_prop)) raise LeadershipError(_('leader cannot have "{}" property').format(new_prop))
props.add(new_prop) props.add(new_prop)
props -= await self.getpermissives(option_bag) props -= await self.getpermissives(option_bag)
if not uncalculated and apply_requires and not config_bag.is_unrestraint: if not uncalculated and apply_requires and not config_bag.is_unrestraint and not help_property:
cache.setcache(path, cache.setcache(path,
index, index,
props, props,
@ -468,36 +486,20 @@ class Settings(object):
True) True)
return props return props
async def get_calculated_properties(self,
option_bag):
option = option_bag.option
if option.impl_is_symlinkoption():
option = option.impl_getopt()
path = option.impl_getpath()
p_props = await self._p_.getproperties(path,
None,
option.impl_getproperties())
if option_bag.index is not None:
p_props = chain(p_props,
await self._p_.getproperties(path,
option_bag.index,
option.impl_getproperties()))
for prop in p_props:
if not isinstance(prop, str):
yield prop
async def has_properties_index(self, async def has_properties_index(self,
option_bag): option_bag):
option = option_bag.option option = option_bag.option
if option.impl_is_symlinkoption(): if option.impl_is_symlinkoption():
option = option.impl_getopt() option = option.impl_getopt()
path = option.impl_getpath() path = option.impl_getpath()
p_props = await self._p_.getproperties(path, p_props = await self._p_.getproperties(option_bag.config_bag.connection,
path,
None, None,
option.impl_getproperties()) option.impl_getproperties())
if option_bag.index is not None: if option_bag.index is not None:
p_props = chain(p_props, p_props = chain(p_props,
await self._p_.getproperties(path, await self._p_.getproperties(option_bag.config_bag.connection,
path,
option_bag.index, option_bag.index,
option.impl_getproperties())) option.impl_getproperties()))
for prop in p_props: for prop in p_props:
@ -505,11 +507,14 @@ class Settings(object):
return True return True
return False return False
async def get_context_permissives(self): async def get_context_permissives(self,
return await self.getpermissives(None) connection):
return await self.getpermissives(None,
connection=connection)
async def getpermissives(self, async def getpermissives(self,
option_bag): option_bag,
connection=None):
if option_bag is None: if option_bag is None:
path = None path = None
index = None index = None
@ -521,18 +526,25 @@ class Settings(object):
else: else:
path = option_bag.path path = option_bag.path
index = option_bag.index index = option_bag.index
permissives = await self._pp_.getpermissives(path, None) connection = option_bag.config_bag.connection
permissives = await self._pp_.getpermissives(connection,
path,
None)
if index is not None: if index is not None:
option_permissives = await self._pp_.getpermissives(path, index) option_permissives = await self._pp_.getpermissives(connection,
path,
index)
permissives = frozenset(option_permissives | permissives) permissives = frozenset(option_permissives | permissives)
return permissives return permissives
#____________________________________________________________ #____________________________________________________________
# set methods # set methods
async def set_context_properties(self, async def set_context_properties(self,
connection,
properties, properties,
context): context):
await self._p_.setproperties(None, await self._p_.setproperties(connection,
None,
None, None,
properties) properties)
await context.cfgimpl_reset_cache(None) await context.cfgimpl_reset_cache(None)
@ -561,7 +573,8 @@ class Settings(object):
raise LeadershipError(_('a leader ({0}) cannot have ' raise LeadershipError(_('a leader ({0}) cannot have '
'"force_default_on_freeze" or "force_metaconfig_on_freeze" property without "frozen"' '"force_default_on_freeze" or "force_metaconfig_on_freeze" property without "frozen"'
'').format(opt.impl_get_display_name())) '').format(opt.impl_get_display_name()))
await self._p_.setproperties(path, await self._p_.setproperties(option_bag.config_bag.connection,
path,
option_bag.index, option_bag.index,
properties) properties)
# values too because of follower values could have a PropertiesOptionError has value # values too because of follower values could have a PropertiesOptionError has value
@ -569,13 +582,16 @@ class Settings(object):
option_bag.properties = properties option_bag.properties = properties
async def set_context_permissives(self, async def set_context_permissives(self,
connection,
permissives): permissives):
await self.setpermissives(None, await self.setpermissives(None,
permissives) permissives,
connection=connection)
async def setpermissives(self, async def setpermissives(self,
option_bag, option_bag,
permissives): permissives,
connection=None):
""" """
enables us to put the permissives in the storage enables us to put the permissives in the storage
@ -594,6 +610,7 @@ class Settings(object):
"").format(opt.impl_get_display_name())) "").format(opt.impl_get_display_name()))
path = option_bag.path path = option_bag.path
index = option_bag.index index = option_bag.index
connection = option_bag.config_bag.connection
else: else:
path = None path = None
index = None index = None
@ -601,7 +618,10 @@ class Settings(object):
if forbidden_permissives: if forbidden_permissives:
raise ConfigError(_('cannot add those permissives: {0}').format( raise ConfigError(_('cannot add those permissives: {0}').format(
' '.join(forbidden_permissives))) ' '.join(forbidden_permissives)))
await self._pp_.setpermissives(path, index, permissives) await self._pp_.setpermissives(connection,
path,
index,
permissives)
if option_bag is not None: if option_bag is not None:
await option_bag.config_bag.context.cfgimpl_reset_cache(option_bag) await option_bag.config_bag.context.cfgimpl_reset_cache(option_bag)
@ -610,7 +630,7 @@ class Settings(object):
async def reset(self, async def reset(self,
option_bag, option_bag,
context): config_bag):
if option_bag is None: if option_bag is None:
opt = None opt = None
path = None path = None
@ -622,12 +642,14 @@ class Settings(object):
"").format(opt.impl_get_display_name()) "").format(opt.impl_get_display_name())
path = option_bag.path path = option_bag.path
index = option_bag.index index = option_bag.index
await self._p_.delproperties(path, index) await self._p_.delproperties(config_bag.connection,
await context.cfgimpl_reset_cache(option_bag) path,
index)
await config_bag.context.cfgimpl_reset_cache(option_bag)
async def reset_permissives(self, async def reset_permissives(self,
option_bag, option_bag,
context): config_bag):
if option_bag is None: if option_bag is None:
opt = None opt = None
path = None path = None
@ -639,8 +661,10 @@ class Settings(object):
"").format(opt.impl_get_display_name()) "").format(opt.impl_get_display_name())
index = option_bag.index index = option_bag.index
path = option_bag.path path = option_bag.path
await self._pp_.delpermissive(path, index) await self._pp_.delpermissive(config_bag.connection,
await context.cfgimpl_reset_cache(option_bag) path,
index)
await config_bag.context.cfgimpl_reset_cache(option_bag)
#____________________________________________________________ #____________________________________________________________
# validate properties # validate properties
@ -664,29 +688,36 @@ class Settings(object):
option_properties): option_properties):
raises_properties = context_properties - SPECIAL_PROPERTIES raises_properties = context_properties - SPECIAL_PROPERTIES
# remove global permissive properties # remove global permissive properties
if raises_properties and ('permissive' in raises_properties): if raises_properties and 'permissive' in raises_properties:
raises_properties -= context_permissives raises_properties -= context_permissives
properties = option_properties & raises_properties properties = option_properties & raises_properties
# at this point an option should not remain in properties # at this point it should not remain any property for the option
return properties return properties
async def validate_properties(self, async def validate_properties(self,
option_bag): option_bag,
""" need_help=True):
validation upon the properties related to `opt` config_properties = option_bag.config_bag.properties
if not config_properties or config_properties == frozenset(['cache']):
:param opt: an option or an option description object # if no global property
:param force_permissive: behaves as if the permissive property
was present
"""
config_bag = option_bag.config_bag
if not config_bag.properties or config_bag.properties == frozenset(['cache']): # pragma: no cover
return return
properties = await self.calc_raises_properties(option_bag) properties = await self.calc_raises_properties(option_bag)
if properties != frozenset(): if properties != frozenset():
if need_help:
help_properties = dict(await self.getproperties(option_bag,
help_property=True))
calc_properties = []
for property_ in self._calc_raises_properties(option_bag.config_bag.properties,
option_bag.config_bag.permissives,
set(help_properties.keys())):
calc_properties.append(help_properties[property_])
calc_properties = frozenset(calc_properties)
else:
calc_properties = properties
raise PropertiesOptionError(option_bag, raise PropertiesOptionError(option_bag,
properties, properties,
self) self,
help_properties=calc_properties)
def validate_mandatory(self, def validate_mandatory(self,
value, value,
@ -731,8 +762,9 @@ class Settings(object):
async def _read(self, async def _read(self,
remove, remove,
append, append,
context): config_bag):
props = await self._p_.getproperties(None, props = await self._p_.getproperties(config_bag.connection,
None,
None, None,
self.default_properties) self.default_properties)
modified = False modified = False
@ -743,19 +775,20 @@ class Settings(object):
props = props | append props = props | append
modified = True modified = True
if modified: if modified:
await self.set_context_properties(frozenset(props), await self.set_context_properties(config_bag.connection,
context) frozenset(props),
config_bag.context)
async def read_only(self, async def read_only(self,
context): config_bag):
"convenience method to freeze, hide and disable" "convenience method to freeze, hide and disable"
await self._read(self.ro_remove, await self._read(self.ro_remove,
self.ro_append, self.ro_append,
context) config_bag)
async def read_write(self, async def read_write(self,
context): config_bag):
"convenience method to freeze, hide and disable" "convenience method to freeze, hide and disable"
await self._read(self.rw_remove, await self._read(self.rw_remove,
self.rw_append, self.rw_append,
context) config_bag)

View file

@ -1,4 +1,4 @@
# Copyright (C) 2013-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2013-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the
@ -18,7 +18,6 @@
settings changes will be lost. settings changes will be lost.
The storage is the system Tiramisu uses to communicate with various DB. The storage is the system Tiramisu uses to communicate with various DB.
You can specified a persistent storage.
Storage is basic components used to set Config informations in DB. Storage is basic components used to set Config informations in DB.
""" """
@ -44,16 +43,26 @@ class Storage:
after. after.
""" """
def __init__(self, def __init__(self,
**kwargs: Dict[str, str]) -> None: engine=None) -> None:
self.storage_type = None self.storage_type = engine
self.mod = None self.mod = None
if kwargs: self.kwargs = {}
self.setting(**kwargs)
def get(self): def engine(self,
engine) -> None:
if self.mod is not None:
raise ValueError(_('cannot change setting when storage is already in use'))
self.storage_type = engine
def setting(self,
**kwargs: Dict[str, str]) -> None:
if self.mod is not None:
raise ValueError(_('cannot change setting when storage is already in use'))
self.kwargs = kwargs
async def get(self):
if self.storage_type is None: if self.storage_type is None:
self.storage_type = environ.get('TIRAMISU_STORAGE', DEFAULT_STORAGE) self.storage_type = environ.get('TIRAMISU_STORAGE', DEFAULT_STORAGE)
self.setting()
if self.mod is None: if self.mod is None:
modulepath = '{0}.storage.{1}'.format(MODULE_PATH, modulepath = '{0}.storage.{1}'.format(MODULE_PATH,
self.storage_type) self.storage_type)
@ -65,25 +74,11 @@ class Storage:
for token in modulepath.split(".")[1:]: for token in modulepath.split(".")[1:]:
mod = getattr(mod, token) mod = getattr(mod, token)
self.mod = mod self.mod = mod
return self.mod for key, value in self.kwargs.items():
def setting(self,
**kwargs: Dict[str, str]) -> None:
if 'engine' in kwargs:
name = kwargs['engine']
if self.storage_type is not None and self.storage_type != name: # pragma: no cover
raise ConfigError(_('storage_type is already set, '
'cannot rebind it'))
self.storage_type = name
del kwargs['engine']
if kwargs: # pragma: no cover
mod = self.get()
for key, value in kwargs.items():
setattr(mod.SETTING, key, value) setattr(mod.SETTING, key, value)
del self.kwargs
def is_persistent(self): await self.mod.init()
mod = self.get() return self.mod
return mod.PERSISTENT
default_storage = Storage() default_storage = Storage()
@ -94,60 +89,62 @@ def gen_storage_id(session_id,
config): config):
if session_id is not None: if session_id is not None:
return session_id return session_id
return 'c' + str(id(config)) + str(int(time())) + str(randint(0, 500)) return 'c' + str(id(config)) + str(int(time())) + str(randint(0, 50000))
async def get_storages(context, async def get_storages(context,
session_id, session_id,
persistent, delete_old_session,
storage): storage,
connection):
session_id = gen_storage_id(session_id, session_id = gen_storage_id(session_id,
context) context)
if storage is None: if storage is None:
storage = default_storage storage = default_storage
imp = storage.get() imp = await storage.get()
imp_storage = await imp.Storage(session_id, imp_storage = await imp.Storage(connection,
persistent) session_id,
delete_old_session)
properties = imp.Properties(imp_storage) properties = imp.Properties(imp_storage)
permissives = imp.Permissives(imp_storage) permissives = imp.Permissives(imp_storage)
values = imp.Values(imp_storage) values = imp.Values(imp_storage)
return properties, permissives, values, session_id return storage, properties, permissives, values, session_id
async def get_default_values_storages(): async def get_default_values_storages(connection):
imp = memory_storage.get() imp = await memory_storage.get()
storage = await imp.Storage('__validator_storage', storage = await imp.Storage(connection,
persistent=False, '__validator_storage',
test=True) delete_old_session=True)
return imp.Values(storage) return imp.Values(storage)
async def get_default_settings_storages(): async def get_default_settings_storages(connection):
imp = memory_storage.get() imp = await memory_storage.get()
storage = await imp.Storage('__validator_storage', persistent=False, test=True) storage = await imp.Storage(connection,
'__validator_storage',
delete_old_session=True)
properties = imp.Properties(storage) properties = imp.Properties(storage)
permissives = imp.Permissives(storage) permissives = imp.Permissives(storage)
return properties, permissives return properties, permissives
def list_sessions(storage=default_storage): async def list_sessions(storage=default_storage):
"""List all available session (persistent or not persistent) """List all available session
""" """
return storage.get().list_sessions() stor = await storage.get()
return await stor.list_sessions()
def delete_session(session_id, storage=default_storage): async def delete_session(session_id,
storage=default_storage):
"""Delete a selected session, be careful, you can deleted a session """Delete a selected session, be careful, you can deleted a session
use by an other instance use by an other instance
:params session_id: id of session to delete :params session_id: id of session to delete
""" """
storage_module = storage.get() storage_module = await storage.get()
session = storage_module.storage.getsession() await storage_module.value.delete_session(session_id)
storage_module.value.delete_session(session_id) await storage_module.storage.delete_session(session_id)
storage_module.storage.delete_session(session_id)
if session: # pragma: no cover
session.commit()
del(session)
__all__ = ('list_sessions', 'delete_session') __all__ = ('list_sessions', 'delete_session')

View file

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2018-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2018-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"cache used by storage" "cache used by storage"
# Copyright (C) 2013-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2013-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the
@ -30,11 +30,11 @@ class Cache(DictCache):
if follower, add index if follower, add index
""" """
if 'cache' in props or 'cache' in self_props: if 'cache' in props or 'cache' in self_props:
log.debug('setcache %s with index %s and value %s in %s (%s)', # log.debug('setcache %s with index %s and value %s in %s (%s)',
path, index, val, _display_classname(self), id(self)) # path, index, val, _display_classname(self), id(self))
super().setcache(path, index, val, time(), validated) super().setcache(path, index, val, time(), validated)
log.debug('not setcache %s with index %s and value %s and props %s and %s in %s (%s)', # log.debug('not setcache %s with index %s and value %s and props %s and %s in %s (%s)',
path, index, val, props, self_props, _display_classname(self), id(self)) # path, index, val, props, self_props, _display_classname(self), id(self))
def getcache(self, def getcache(self,
path, path,
@ -63,31 +63,31 @@ class Cache(DictCache):
'expire' in self_props): 'expire' in self_props):
ntime = int(time()) ntime = int(time())
if timestamp + expiration_time >= ntime: if timestamp + expiration_time >= ntime:
log.debug('getcache in cache (1) %s %s %s %s %s', path, value, _display_classname(self), # log.debug('getcache in cache (1) %s %s %s %s %s', path, value, _display_classname(self),
id(self), index) # id(self), index)
return True, value, validated return True, value, validated
else: # else:
log.debug('getcache expired value for path %s < %s', # log.debug('getcache expired value for path %s < %s',
timestamp + expiration_time, ntime) # timestamp + expiration_time, ntime)
# if expired, remove from cache # if expired, remove from cache
# self.delcache(path) # self.delcache(path)
else: else:
log.debug('getcache in cache (2) %s %s %s %s %s', path, value, _display_classname(self), # log.debug('getcache in cache (2) %s %s %s %s %s', path, value, _display_classname(self),
id(self), index) # id(self), index)
return True, value, validated return True, value, validated
log.debug('getcache %s with index %s not in %s cache', # log.debug('getcache %s with index %s not in %s cache',
path, index, _display_classname(self)) # path, index, _display_classname(self))
return no_cache return no_cache
def delcache(self, path): def delcache(self, path):
"""remove cache for a specified path """remove cache for a specified path
""" """
log.debug('delcache %s %s %s', path, _display_classname(self), id(self)) # log.debug('delcache %s %s %s', path, _display_classname(self), id(self))
super().delcache(path) super().delcache(path)
def reset_all_cache(self): def reset_all_cache(self):
"empty the cache" "empty the cache"
log.debug('reset_all_cache %s %s', _display_classname(self), id(self)) # log.debug('reset_all_cache %s %s', _display_classname(self), id(self))
super().reset_all_cache() super().reset_all_cache()
def get_cached(self): def get_cached(self):
@ -96,5 +96,5 @@ class Cache(DictCache):
example: {'path1': {'index1': ('value1', 'time1')}, 'path2': {'index2': ('value2', 'time2', )}} example: {'path1': {'index1': ('value1', 'time1')}, 'path2': {'index2': ('value2', 'time2', )}}
""" """
cache = super().get_cached() cache = super().get_cached()
log.debug('get_chached %s for %s (%s)', cache, _display_classname(self), id(self)) # log.debug('get_chached %s for %s (%s)', cache, _display_classname(self), id(self))
return cache return cache

View file

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2013-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2013-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the
@ -17,14 +17,12 @@
"""Default plugin for storage. All informations are store in a simple """Default plugin for storage. All informations are store in a simple
dictionary in memory. dictionary in memory.
You cannot have persistente informations with this kind of storage.
The advantage of this solution is that you can easily create a Config and The advantage of this solution is that you can easily create a Config and
use it. But if something goes wrong, you will lost your modifications. use it. But if something goes wrong, you will lost your modifications.
""" """
from .value import Values from .value import Values
from .setting import Properties, Permissives from .setting import Properties, Permissives
from .storage import PERSISTENT, SETTING, Storage, list_sessions from .storage import PERSISTENT, SETTING, Storage, list_sessions, init, Connection
__all__ = ('PERSISTENT', __all__ = ('PERSISTENT',
@ -33,4 +31,6 @@ __all__ = ('PERSISTENT',
'Properties', 'Properties',
'Permissives', 'Permissives',
'Storage', 'Storage',
'init',
'Connection',
'list_sessions') 'list_sessions')

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"default plugin for setting: set it in a simple dictionary" "default plugin for setting: set it in a simple dictionary"
# Copyright (C) 2013-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2013-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the
@ -20,75 +20,108 @@ from ...log import log
class Properties: class Properties:
__slots__ = ('_properties', __slots__ = ('_storage',)
'_storage')
def __init__(self, storage): def __init__(self, storage):
# properties attribute: the name of a property enables this property # properties attribute: the name of a property enables this property
# key is None for global properties # key is None for global properties
self._properties = {}
self._storage = storage self._storage = storage
# properties # properties
async def setproperties(self, path, index, properties): async def setproperties(self,
connection,
path,
index,
properties):
log.debug('setproperties %s %s %s', path, index, properties) log.debug('setproperties %s %s %s', path, index, properties)
self._properties.setdefault(path, {})[index] = properties self._storage.get_properties().setdefault(path, {})[index] = properties
async def getproperties(self, path, index, default_properties): async def getproperties(self,
if path not in self._properties: connection,
path,
index,
default_properties):
properties = self._storage.get_properties()
if path not in properties:
ret = frozenset(default_properties) ret = frozenset(default_properties)
else: else:
ret = self._properties[path].get(index, frozenset(default_properties)) ret = properties[path].get(index, frozenset(default_properties))
log.debug('getproperties %s %s %s', path, index, ret) log.debug('getproperties %s %s %s', path, index, ret)
return ret return ret
async def delproperties(self, path, index): async def delproperties(self,
connection,
path,
index):
log.debug('delproperties %s', path) log.debug('delproperties %s', path)
if path in self._properties and index in self._properties[path]: properties = self._storage.get_properties()
del(self._properties[path][index]) if path in properties and index in properties[path]:
del(properties[path][index])
async def exportation(self): async def exportation(self,
connection):
"""return all modified settings in a dictionary """return all modified settings in a dictionary
example: {'path1': set(['prop1', 'prop2'])} example: {'path1': set(['prop1', 'prop2'])}
""" """
return deepcopy(self._properties) return deepcopy(self._storage.get_properties())
async def importation(self, properties): async def importation(self,
self._properties = properties connection,
properties):
self._storage.set_properties(properties)
def getconnection(self):
return self._storage.getconnection()
class Permissives: class Permissives:
__slots__ = ('_permissives', __slots__ = ('_storage',)
'_storage')
def __init__(self, storage): def __init__(self, storage):
# permissive properties # permissive properties
self._permissives = {}
self._storage = storage self._storage = storage
async def setpermissives(self, path, index, permissives): async def setpermissives(self,
connection,
path,
index,
permissives):
log.debug('setpermissives %s %s', path, permissives) log.debug('setpermissives %s %s', path, permissives)
self._permissives.setdefault(path, {})[index] = permissives self._storage.get_permissives().setdefault(path, {})[index] = permissives
async def getpermissives(self, path, index): async def getpermissives(self,
if not path in self._permissives: connection,
path,
index):
permissives = self._storage.get_permissives()
if not path in permissives:
ret = frozenset() ret = frozenset()
else: else:
ret = self._permissives[path].get(index, frozenset()) ret = permissives[path].get(index, frozenset())
log.debug('getpermissives %s %s', path, ret) log.debug('getpermissives %s %s', path, ret)
return ret return ret
async def delpermissive(self, path, index): async def delpermissive(self,
connection,
path,
index):
log.debug('delpermissive %s', path) log.debug('delpermissive %s', path)
if path in self._permissives and index in self._permissives[path]: permissives = self._storage.get_permissives()
del(self._permissives[path][index]) if path in permissives and index in permissives[path]:
del(permissives[path][index])
async def exportation(self): async def exportation(self,
connection):
"""return all modified permissives in a dictionary """return all modified permissives in a dictionary
example: {'path1': set(['perm1', 'perm2'])} example: {'path1': set(['perm1', 'perm2'])}
""" """
return deepcopy(self._permissives) return deepcopy(self._storage.get_permissives())
async def importation(self, permissives): async def importation(self,
self._permissives = permissives connection,
permissives):
self._storage.set_permissives(permissives)
def getconnection(self):
return self._storage.getconnection()

View file

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2013-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2013-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the
@ -26,36 +26,95 @@ class Setting:
SETTING = Setting() SETTING = Setting()
_list_sessions = [] _list_sessions = {}
PERSISTENT = False PERSISTENT = True
def list_sessions(): async def init():
return _list_sessions pass
class Connection:
async def __aenter__(self):
return self
async def __aexit__(self,
type,
value,
traceback):
pass
async def list_sessions():
lst = list(_list_sessions.keys())
if '__validator_storage' in lst:
lst.remove('__validator_storage')
return lst
async def delete_session(session_id):
try:
del _list_sessions[session_id]
except KeyError:
pass
@asyncinit @asyncinit
class Storage: class Storage:
__slots__ = ('session_id', 'persistent') __slots__ = ('session_id',)
storage = 'dictionary' storage = 'dictionary'
# if object could be serializable
serializable = True
async def __init__(self, session_id, persistent, test=False): def add_session(self):
if not test and session_id in _list_sessions: # values (('path1',), (index1,), (value1,), ('owner1'))
raise ConflictError(_('session "{}" already exists').format(session_id)) _list_sessions[self.session_id] = {'values': ([], [], [], []),
if persistent: 'informations': {},
raise ValueError(_('a dictionary cannot be persistent')) 'properties': {},
'permissives': {}}
async def __init__(self,
connection: Connection,
session_id: str,
delete_old_session: bool) -> None:
if not isinstance(session_id, str):
raise ValueError(_('session_id has to be a string'))
self.session_id = session_id self.session_id = session_id
self.persistent = persistent if self.session_id not in _list_sessions:
_list_sessions.append(self.session_id) self.add_session()
def __del__(self): async def delete_session(self):
try: await delete_session(self.session_id)
_list_sessions.remove(self.session_id)
except AttributeError:
pass
async def list_sessions(self):
return await list_sessions()
def getsession(): def get_session(self):
pass if self.session_id not in _list_sessions:
self.add_session()
return _list_sessions.get(self.session_id, {})
def get_values(self):
return self.get_session()['values']
def set_values(self, values):
self.get_session()['values'] = values
def get_informations(self):
return self.get_session()['informations']
def set_informations(self, informations):
self.get_session()['informations'] = informations
def get_properties(self):
return self.get_session()['properties']
def set_properties(self, properties):
self.get_session()['properties'] = properties
def get_permissives(self):
return self.get_session()['permissives']
def set_permissives(self, permissives):
self.get_session()['permissives'] = permissives
def getconnection(self):
return Connection()

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"default plugin for value: set it in a simple dictionary" "default plugin for value: set it in a simple dictionary"
# Copyright (C) 2013-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2013-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the
@ -18,6 +18,7 @@
from ...setting import undefined from ...setting import undefined
from ...i18n import _ from ...i18n import _
from ...log import log from ...log import log
from .storage import delete_session
from copy import deepcopy from copy import deepcopy
@ -30,16 +31,12 @@ class Values:
def __init__(self, storage): def __init__(self, storage):
"""init plugin means create values storage """init plugin means create values storage
""" """
#(('path1',), (index1,), (value1,), ('owner1')) #self._values = ([], [], [], [])
self._values = ([], [], [], []) #self._informations = {}
self._informations = {}
self._storage = storage self._storage = storage
async def commit(self):
pass
def _setvalue_info(self, nb, idx, value, index, follower_idx=None): def _setvalue_info(self, nb, idx, value, index, follower_idx=None):
lst = self._values[nb] lst = self._storage.get_values()[nb]
if index is None or nb == 0: if index is None or nb == 0:
# not follower or path # not follower or path
lst[idx] = value lst[idx] = value
@ -58,26 +55,27 @@ class Values:
def _add_new_value(self, index, nb, value): def _add_new_value(self, index, nb, value):
if index is None or nb == 0: if index is None or nb == 0:
# not follower or path # not follower or path
self._values[nb].append(value) self._storage.get_values()[nb].append(value)
else: else:
# follower # follower
self._values[nb].append([value]) self._storage.get_values()[nb].append([value])
def _add_new_value(self, index, nb, value): def _add_new_value(self, index, nb, value):
if index is None or nb == 0: if index is None or nb == 0:
# not follower or path # not follower or path
self._values[nb].append(value) self._storage.get_values()[nb].append(value)
else: else:
# follower # follower
self._values[nb].append([value]) self._storage.get_values()[nb].append([value])
# value # value
async def setvalue(self, async def setvalue(self,
connection,
path, path,
value, value,
owner, owner,
index, index,
commit): new=False):
"""set value for a path """set value for a path
a specified value must be associated to an owner a specified value must be associated to an owner
""" """
@ -85,8 +83,9 @@ class Values:
#if isinstance(value, list): #if isinstance(value, list):
# value = value # value = value
if path in self._values[0]: values = self._storage.get_values()
idx = self._values[0].index(path) if not new and path in values[0]:
idx = values[0].index(path)
self._setvalue_info(0, idx, path, index) self._setvalue_info(0, idx, path, index)
follower_idx = self._setvalue_info(1, idx, index, index) follower_idx = self._setvalue_info(1, idx, index, index)
self._setvalue_info(2, idx, value, index, follower_idx) self._setvalue_info(2, idx, value, index, follower_idx)
@ -97,47 +96,56 @@ class Values:
self._add_new_value(index, 2, value) self._add_new_value(index, 2, value)
self._add_new_value(index, 3, owner) self._add_new_value(index, 3, owner)
async def hasvalue(self, path, index=None): async def hasvalue(self,
connection,
path,
index=None):
"""if path has a value """if path has a value
return: boolean return: boolean
""" """
has_path = path in self._values[0] values = self._storage.get_values()
has_path = path in values[0]
log.debug('hasvalue %s %s %s %s', path, index, has_path, id(self)) log.debug('hasvalue %s %s %s %s', path, index, has_path, id(self))
if index is None: if index is None:
return has_path return has_path
elif has_path: elif has_path:
path_idx = self._values[0].index(path) path_idx = values[0].index(path)
indexes = self._values[1][path_idx] indexes = values[1][path_idx]
return index in indexes return index in indexes
return False return False
async def reduce_index(self, path, index): async def reduce_index(self,
connection,
path,
index):
""" """
_values == ((path1, path2), ((idx1_1, idx1_2), None), ((value1_1, value1_2), value2), ((owner1_1, owner1_2), owner2)) _values == ((path1, path2), ((idx1_1, idx1_2), None), ((value1_1, value1_2), value2), ((owner1_1, owner1_2), owner2))
""" """
log.debug('reduce_index %s %s %s', path, index, id(self)) log.debug('reduce_index %s %s %s', path, index, id(self))
path_idx = self._values[0].index(path) values = self._storage.get_values()
path_idx = values[0].index(path)
# get the "index" position # get the "index" position
subidx = self._values[1][path_idx].index(index) subidx = values[1][path_idx].index(index)
# reduce to one the index # reduce to one the index
self._values[1][path_idx][subidx] -= 1 values[1][path_idx][subidx] -= 1
async def resetvalue_index(self, async def resetvalue_index(self,
connection,
path, path,
index, index):
commit):
log.debug('resetvalue_index %s %s %s', path, index, id(self)) log.debug('resetvalue_index %s %s %s', path, index, id(self))
values = self._storage.get_values()
def _resetvalue(nb): def _resetvalue(nb):
del self._values[nb][path_idx] del self._storage.get_values()[nb][path_idx]
def _resetvalue_index(nb): def _resetvalue_index(nb):
del self._values[nb][path_idx][subidx] del self._storage.get_values()[nb][path_idx][subidx]
path_idx = self._values[0].index(path) path_idx = values[0].index(path)
indexes = self._values[1][path_idx] indexes = values[1][path_idx]
if index in indexes: if index in indexes:
subidx = indexes.index(index) subidx = indexes.index(index)
if len(self._values[1][path_idx]) == 1: if len(values[1][path_idx]) == 1:
_resetvalue(0) _resetvalue(0)
_resetvalue(1) _resetvalue(1)
_resetvalue(2) _resetvalue(2)
@ -148,15 +156,16 @@ class Values:
_resetvalue_index(3) _resetvalue_index(3)
async def resetvalue(self, async def resetvalue(self,
path, connection,
commit): path):
"""remove value means delete value in storage """remove value means delete value in storage
""" """
log.debug('resetvalue %s %s', path, id(self)) log.debug('resetvalue %s %s', path, id(self))
values = self._storage.get_values()
def _resetvalue(nb): def _resetvalue(nb):
self._values[nb].pop(idx) values[nb].pop(idx)
if path in self._values[0]: if path in values[0]:
idx = self._values[0].index(path) idx = values[0].index(path)
_resetvalue(0) _resetvalue(0)
_resetvalue(1) _resetvalue(1)
_resetvalue(2) _resetvalue(2)
@ -164,19 +173,22 @@ class Values:
# owner # owner
async def setowner(self, async def setowner(self,
connection,
path, path,
owner, owner,
index=None): index):
"""change owner for a path """change owner for a path
""" """
idx = self._values[0].index(path) values = self._storage.get_values()
idx = values[0].index(path)
if index is None: if index is None:
follower_idx = None follower_idx = None
else: else:
follower_idx = self._values[1][idx].index(index) follower_idx = values[1][idx].index(index)
self._setvalue_info(3, idx, owner, index, follower_idx) self._setvalue_info(3, idx, owner, index, follower_idx)
async def getowner(self, async def getowner(self,
connection,
path, path,
default, default,
index=None, index=None,
@ -202,24 +214,25 @@ class Values:
""" """
_values == ((path1, path2), ((idx1_1, idx1_2), None), ((value1_1, value1_2), value2), ((owner1_1, owner1_2), owner2)) _values == ((path1, path2), ((idx1_1, idx1_2), None), ((value1_1, value1_2), value2), ((owner1_1, owner1_2), owner2))
""" """
values = self._storage.get_values()
value = undefined value = undefined
if path in self._values[0]: if path in values[0]:
path_idx = self._values[0].index(path) path_idx = values[0].index(path)
indexes = self._values[1][path_idx] indexes = values[1][path_idx]
if indexes is None: if indexes is None:
if index is not None: # pragma: no cover if index is not None: # pragma: no cover
raise ValueError('index is forbidden for {}'.format(path)) raise ValueError('index is forbidden for {}'.format(path))
owner = self._values[3][path_idx] owner = values[3][path_idx]
if with_value: if with_value:
value = self._values[2][path_idx] value = values[2][path_idx]
else: else:
if index is None: # pragma: no cover if index is None: # pragma: no cover
raise ValueError('index is mandatory for {}'.format(path)) raise ValueError('index is mandatory for {}'.format(path))
if index in indexes: if index in indexes:
subidx = indexes.index(index) subidx = indexes.index(index)
owner = self._values[3][path_idx][subidx] owner = values[3][path_idx][subidx]
if with_value: if with_value:
value = self._values[2][path_idx][subidx] value = values[2][path_idx][subidx]
else: else:
owner = undefined owner = undefined
else: else:
@ -228,57 +241,79 @@ class Values:
value = list(value) value = list(value)
return owner, value return owner, value
async def set_information(self, path, key, value): async def set_information(self,
connection,
path,
key,
value):
"""updates the information's attribute """updates the information's attribute
(which is a dictionary) (which is a dictionary)
:param key: information's key (ex: "help", "doc" :param key: information's key (ex: "help", "doc"
:param value: information's value (ex: "the help string") :param value: information's value (ex: "the help string")
""" """
self._informations.setdefault(path, {}) informations = self._storage.get_informations()
self._informations[path][key] = value informations.setdefault(path, {})
informations[path][key] = value
async def get_information(self, path, key, default): async def get_information(self,
connection,
path,
key,
default):
"""retrieves one information's item """retrieves one information's item
:param key: the item string (ex: "help") :param key: the item string (ex: "help")
""" """
value = self._informations.get(path, {}).get(key, default) value = self._storage.get_informations().get(path, {}).get(key, default)
if value is undefined: if value is undefined:
raise ValueError(_("information's item" raise ValueError(_("information's item"
" not found: {0}").format(key)) " not found: {0}").format(key))
return value return value
async def del_information(self, path, key, raises): async def del_information(self,
if path in self._informations and key in self._informations[path]: connection,
del self._informations[path][key] path,
key,
raises):
informations = self._storage.get_informations()
if path in informations and key in informations[path]:
del informations[path][key]
else: else:
if raises: if raises:
raise ValueError(_("information's item not found {0}").format(key)) raise ValueError(_("information's item not found {0}").format(key))
async def list_information(self, path): async def list_information(self,
if path in self._informations: connection,
return self._informations[path].keys() path):
informations = self._storage.get_informations()
if path in informations:
return informations[path].keys()
else: else:
return [] return []
async def del_informations(self): async def del_informations(self,
self._informations = {} connection):
self._storage.set_informations({})
async def exportation(self): async def exportation(self,
return deepcopy(self._values) connection):
return deepcopy(self._storage.get_values())
async def importation(self, export): async def importation(self,
self._values = deepcopy(export) connection,
export):
self._storage.set_values(deepcopy(export))
async def get_max_length(self, async def get_max_length(self,
connection,
path): path):
if path in self._values[0]: values = self._storage.get_values()
idx = self._values[0].index(path) if path in values[0]:
idx = values[0].index(path)
else: else:
return 0 return 0
return max(self._values[1][idx]) + 1 return max(values[1][idx]) + 1
def getconnection(self):
def delete_session(session_id): return self._storage.getconnection()
raise ValueError(_('cannot delete none persistent session'))

View file

@ -0,0 +1,32 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2020 Team tiramisu (see AUTHORS for all contributors)
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the
# Free Software Foundation, either version 3 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# ____________________________________________________________
"""Postgres plugin for storage.
"""
from .value import Values
from .setting import Properties, Permissives
from .storage import PERSISTENT, SETTING, Storage, list_sessions, init, Connection
__all__ = ('PERSISTENT',
'SETTING',
'Values',
'Properties',
'Permissives',
'Storage',
'init',
'Connection',
'list_sessions')

View file

@ -0,0 +1,179 @@
# -*- coding: utf-8 -*-
"default plugin for setting: set it in a simple dictionary"
# Copyright (C) 2020 Team tiramisu (see AUTHORS for all contributors)
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the
# Free Software Foundation, either version 3 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# ____________________________________________________________
try:
from cPickle import loads, dumps
except ImportError:
from pickle import loads, dumps
from ...log import log
class Properties:
__slots__ = ('_storage',)
def __init__(self, storage):
self._storage = storage
# properties
async def setproperties(self,
connection,
path,
index,
properties):
index = self._storage.convert_index(index)
path = self._storage.convert_path(path)
await self.delproperties(connection, path, index)
sql = "INSERT INTO property(path, idx, properties, session_id) VALUES ($1, $2, $3, $4)"
params = [path, index, dumps(properties), self._storage.database_id]
await connection.execute(sql, *params)
async def getproperties(self,
connection,
path,
index,
default_properties):
index = self._storage.convert_index(index)
path = self._storage.convert_path(path)
sql = 'SELECT properties FROM property WHERE path = $1 AND session_id = $2 AND idx = $3'
params = [path, self._storage.database_id, index]
value = await connection.fetchval(sql, *params)
if value is None:
return set(default_properties)
else:
return set(loads(value))
async def delproperties(self,
connection,
path,
index):
index = self._storage.convert_index(index)
path = self._storage.convert_path(path)
sql = 'DELETE FROM property WHERE session_id = $1 AND path = $2 AND idx = $3'
params = [self._storage.database_id, path, index]
await connection.execute(sql, *params)
async def exportation(self,
connection):
"""return all modified settings in a dictionary
example: {'path1': set(['prop1', 'prop2'])}
"""
ret = {}
for path, idx, properties, _ in await connection.fetch("SELECT * FROM property "
"WHERE session_id = $1",
self._storage.database_id):
idx = self._storage.load_index(idx)
path = self._storage.load_path(path)
ret.setdefault(path, {})[idx] = loads(properties)
return ret
async def importation(self,
connection,
properties):
await connection.execute("DELETE FROM property WHERE session_id = $1", self._storage.database_id)
for path, indexed_properties in properties.items():
path = self._storage.convert_path(path)
for index, property_ in indexed_properties.items():
index = self._storage.convert_index(index)
await connection.execute("INSERT INTO property(path, idx, properties, session_id) "
"VALUES ($1,$2,$3,$4)", path,
index,
dumps(property_),
self._storage.database_id)
def getconnection(self):
return self._storage.getconnection()
class Permissives:
__slots__ = ('_storage',)
def __init__(self,
storage):
self._storage = storage
# permissive
async def setpermissives(self,
connection,
path,
index,
permissive):
# log.debug('setpermissive %s %s %s %s', path, index, permissive, id(self))
index = self._storage.convert_index(index)
path = self._storage.convert_path(path)
await self.delpermissive(connection,
path,
index)
await connection.execute("INSERT INTO permissive(path, idx, permissives, session_id) "
"VALUES ($1,$2,$3,$4)", path,
index,
dumps(permissive),
self._storage.database_id)
async def getpermissives(self,
connection,
path,
index):
index = self._storage.convert_index(index)
path = self._storage.convert_path(path)
sql = 'SELECT permissives FROM permissive WHERE session_id = $1 AND path = $2 AND idx = $3'
params = [self._storage.database_id, path, index]
permissives = await connection.fetchval(sql,
*params)
if permissives is None:
return frozenset()
else:
return loads(permissives)
# log.debug('getpermissive %s %s %s', path, ret, id(self))
async def delpermissive(self,
connection,
path,
index):
index = self._storage.convert_index(index)
path = self._storage.convert_path(path)
sql = 'DELETE FROM permissive WHERE session_id = $1 AND path = $2 AND idx = $3'
params = [self._storage.database_id, path, index]
await connection.execute(sql, *params)
async def exportation(self,
connection):
"""return all modified permissives in a dictionary
example: {'path1': set(['perm1', 'perm2'])}
"""
ret = {}
sql = "SELECT path, idx, permissives FROM permissive WHERE session_id = $1"
for path, index, permissives in await connection.fetch(sql,
self._storage.database_id):
ret.setdefault(self._storage.load_path(path), {})[self._storage.load_index(index)] = loads(permissives)
return ret
async def importation(self,
connection,
permissives):
await connection.execute("DELETE FROM permissive WHERE session_id = $1", self._storage.database_id)
for path, indexed_permissives in permissives.items():
for index, permissive in indexed_permissives.items():
index = self._storage.convert_index(index)
path = self._storage.convert_path(path)
await connection.execute("INSERT INTO permissive(path, idx, permissives, session_id) "
"VALUES ($1,$2,$3,$4)", path,
index,
dumps(permissive),
self._storage.database_id)
def getconnection(self):
return self._storage.getconnection()

View file

@ -0,0 +1,183 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2020 Team tiramisu (see AUTHORS for all contributors)
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the
# Free Software Foundation, either version 3 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# ____________________________________________________________
from asyncpg import create_pool
from asyncpg.exceptions import UniqueViolationError
import warnings
from os.path import join
from typing import Optional, Dict
from ...i18n import _
from ...error import ConflictError
from ...asyncinit import asyncinit
class Setting:
""":param dsn: something like postgres://tiramisu:tiramisu@localhost:5432/tiramisu
"""
__slots__ = ('dsn',)
def __init__(self):
self.dsn = 'postgres://tiramisu:tiramisu@localhost:5432/tiramisu'
# FIXME
self.dsn = 'postgres:///tiramisu?host=/var/run/postgresql/&user=tiramisu'
def __setattr__(self, key, value):
if POOL is not None: # pragma: no cover
raise Exception(_('cannot change setting when connexion is already '
'opened'))
super().__setattr__(key, value)
POOL = None
PERSISTENT = True
SETTING = Setting()
class Connection:
async def __aenter__(self):
self.connection = await POOL.acquire()
self.transaction = self.connection.transaction()
await self.transaction.__aenter__()
return self
async def __aexit__(self,
type,
value,
traceback):
await self.transaction.__aexit__(type,
value,
traceback)
await self.connection.close()
async def fetch(self,
*args):
return await self.connection.fetch(*args)
async def fetchrow(self,
*args):
return await self.connection.fetchrow(*args)
async def fetchval(self,
*args):
return await self.connection.fetchval(*args)
async def execute(self,
*args):
await self.connection.execute(*args)
async def list_sessions():
async with Connection() as connection:
return await _list_sessions(connection)
async def _list_sessions(connection):
return [row[0] for row in await connection.fetch("SELECT session FROM session")]
async def delete_session(session_id):
async with Connection() as connection:
database_id = await connection.fetchval("SELECT session_id FROM session WHERE session = $1", session_id)
if database_id is not None:
await _delete_session(database_id,
connection)
async def _delete_session(database_id,
connection):
await connection.execute('DELETE FROM property WHERE session_id = $1', database_id)
await connection.execute('DELETE FROM permissive WHERE session_id = $1', database_id)
await connection.execute('DELETE FROM value WHERE session_id = $1', database_id)
await connection.execute('DELETE FROM information WHERE session_id = $1', database_id)
await connection.execute('DELETE FROM session WHERE session_id = $1', database_id)
async def init():
# self.pool = await connect(dsn=SETTING.dsn)
global POOL
if POOL is None:
POOL = await create_pool(dsn=SETTING.dsn)
#print(' async with POOL.acquire() as connection:')
#print(' async with connection.transaction():')
sql = """
CREATE TABLE IF NOT EXISTS session(session_id SERIAL, session TEXT UNIQUE, PRIMARY KEY(session_id));
CREATE TABLE IF NOT EXISTS property(path TEXT, idx INTEGER, properties BYTEA, session_id INTEGER, PRIMARY KEY(path, idx, session_id), FOREIGN KEY(session_id) REFERENCES session(session_id));
CREATE TABLE IF NOT EXISTS permissive(path TEXT, idx INTEGER, permissives BYTEA, session_id INTEGER, PRIMARY KEY(path, idx, session_id), FOREIGN KEY(session_id) REFERENCES session(session_id));
CREATE TABLE IF NOT EXISTS value(path TEXT, value BYTEA, owner TEXT, idx INTEGER, session_id INTEGER, PRIMARY KEY (path, idx, session_id), FOREIGN KEY(session_id) REFERENCES session(session_id));
CREATE TABLE IF NOT EXISTS information(key TEXT, value BYTEA, session_id INTEGER, path TEXT, PRIMARY KEY (key, session_id), FOREIGN KEY(session_id) REFERENCES session(session_id));"""
#print(' await connection.execute("""'+sql+'""")')
await POOL.execute(sql)
@asyncinit
class Storage:
__slots__ = ('pool',
'database_id',
'session_id',
'created')
storage = 'postgres'
async def __init__(self,
connection: Connection,
session_id: str,
delete_old_session: bool) -> None:
if not isinstance(session_id, str):
raise ValueError(_('session_id has to be a string'))
self.database_id = None
self.session_id = session_id
select = await connection.fetchval("SELECT session_id FROM session WHERE session = $1",
self.session_id)
if select is not None:
if delete_old_session:
await self.delete_session()
else:
self.database_id = select
if self.database_id is None:
self.database_id = await connection.fetchval('INSERT INTO session(session) VALUES ($1) RETURNING session_id',
self.session_id)
def convert_index(self, index):
if index is None:
index = -1
return index
def convert_path(self, path):
if path is None:
path = '_none'
return path
def load_index(self, index):
if index == -1:
index = None
return index
def load_path(self, path):
if path == '_none':
path = None
return path
async def delete_session(self):
if self.database_id is not None:
await _delete_session(self.database_id,
POOL)
self.database_id = None
async def list_sessions(self,
connection):
return await _list_sessions(connection)
def getconnection(self):
return Connection()

View file

@ -0,0 +1,298 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2020 Team tiramisu (see AUTHORS for all contributors)
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the
# Free Software Foundation, either version 3 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# ____________________________________________________________
try:
from cPickle import loads, dumps
except ImportError:
from pickle import loads, dumps
from ...setting import undefined, owners
from ...i18n import _
from ...log import log
from .storage import delete_session
class Values:
__slots__ = ('__weakref__',
'_storage')
def __init__(self,
storage):
"""init plugin means create values storage
"""
self._storage = storage
# value
async def setvalue(self,
connection,
path,
value,
owner,
index,
new=False):
"""set value for an option
a specified value must be associated to an owner
"""
# log.debug('setvalue %s %s %s %s %s', path, value, owner, index, commit)
index = self._storage.convert_index(index)
path = self._storage.convert_path(path)
sql = 'INSERT INTO value(value, owner, session_id, path, idx) VALUES ($1,$2,$3,$4,$5)'
idx = self._storage.convert_index(index)
path = self._storage.convert_path(path)
params = [dumps(value), str(owner), self._storage.database_id, path, idx]
if new is False:
if index != -1:
await self.resetvalue_index(connection,
path,
index)
else:
await self.resetvalue(connection,
path)
await connection.execute(sql,
*params)
async def hasvalue(self,
connection,
path,
index=None):
"""if opt has a value
return: boolean
"""
# log.debug('hasvalue %s %s', path, index)
if index is not None:
index = self._storage.convert_index(index)
path = self._storage.convert_path(path)
request = "SELECT value FROM value WHERE path = $1 AND session_id = $2 AND idx = $3"
params = (path, self._storage.database_id, index)
else:
path = self._storage.convert_path(path)
request = "SELECT value FROM value WHERE path = $1 AND session_id = $2"
params = (path, self._storage.database_id)
ret = await connection.fetchrow(request, *params)
return ret is not None
async def reduce_index(self,
connection,
path,
index):
"""
_values == ((path1, path2), ((idx1_1, idx1_2), None),
((value1_1, value1_2), value2), ((owner1_1, owner1_2), owner2))
"""
# log.debug('reduce_index %s %s %s', path, index, id(self))
await connection.execute("UPDATE value SET idx = $1 WHERE path = $2 and idx = $3 "
"AND session_id = $4",
index - 1, path, index, self._storage.database_id)
async def resetvalue_index(self,
connection,
path,
index):
"""remove value means delete value in storage
"""
# log.debug('resetvalue_index %s %s', path, index)
await connection.execute("DELETE FROM value WHERE path = $1 AND session_id = $2 AND idx = $3",
path, self._storage.database_id, index)
await self.hasvalue(connection,
path,
index)
async def resetvalue(self,
connection,
path):
"""remove value means delete value in storage
"""
# log.debug('resetvalue %s', path)
await connection.execute("DELETE FROM value WHERE path = $1 AND session_id = $2",
path, self._storage.database_id)
# owner
async def setowner(self,
connection,
path,
owner,
index):
"""change owner for an option
"""
# log.debug('setowner %s %s %s', path, owner, index)
index = self._storage.convert_index(index)
path = self._storage.convert_path(path)
await connection.execute("UPDATE value SET owner = $1 WHERE path = $2 and idx = $3 AND session_id = $4",
str(owner), path, index, self._storage.database_id)
async def getowner(self,
connection,
path,
default,
index,
with_value=False):
"""get owner for an option
return: owner object
"""
# log.debug('getowner %s %s %s %s', path, default, index, with_value)
path = self._storage.convert_path(path)
index = self._storage.convert_index(index)
request = "SELECT owner, value FROM value WHERE session_id = $1 AND path = $2 AND idx = $3"
params = [self._storage.database_id, path, index]
owner = await connection.fetchrow(request, *params)
if owner is None:
if not with_value:
return default
return default, None
# autocreate owners
try:
nowner = getattr(owners, owner[0])
except AttributeError: # pragma: no cover
owners.addowner(owner[0])
nowner = getattr(owners, owner[0])
if not with_value:
return nowner
value = loads(owner[1])
return nowner, value
async def set_information(self,
connection,
path,
key,
value):
"""updates the information's attribute
(which is a dictionary)
:param key: information's key (ex: "help", "doc"
:param value: information's value (ex: "the help string")
"""
# log.debug('set_information %s %s', key, value)
path = self._storage.convert_path(path)
await connection.execute("DELETE FROM information WHERE key = $1 AND session_id = $2 AND path = $3",
key, self._storage.database_id, path)
await connection.execute("INSERT INTO information(key, value, session_id, path) VALUES "
"($1, $2, $3, $4)", key, dumps(value), self._storage.database_id, path)
async def get_information(self,
connection,
path,
key,
default):
"""retrieves one information's item
:param key: the item string (ex: "help")
"""
# log.debug('get_information %s %s', key, default)
path = self._storage.convert_path(path)
value = await connection.fetchval("SELECT value FROM information WHERE key = $1 AND "
"session_id = $2 AND path = $3",
key, self._storage.database_id, path)
if value is None:
if default is undefined:
raise ValueError(_("information's item"
" not found: {0}").format(key))
return default
else:
return loads(value)
async def del_information(self,
connection,
path,
key,
raises):
# log.debug('del_information %s %s', key, raises)
path = self._storage.convert_path(path)
information = await connection.fetchval("SELECT value FROM information WHERE key = $1 "
"AND session_id = $2 AND path = $3",
key, self._storage.database_id, path)
if raises and information is None:
raise ValueError(_("information's item not found {0}").format(key))
await connection.execute("DELETE FROM information WHERE key = $1 AND session_id = $2 AND path = $3",
key, self._storage.database_id, path)
async def list_information(self,
connection,
path):
path = self._storage.convert_path(path)
return [row[0] for row in await connection.fetch("SELECT key FROM information WHERE session_id = $1 AND path = $2",
self._storage.database_id, path)]
async def del_informations(self,
connection):
await connection.execute("DELETE FROM information WHERE session_id = $1",
self._storage.database_id)
async def exportation(self,
connection):
# log.debug('exportation')
ret = [[], [], [], []]
rows = await connection.fetch("SELECT path, value, owner, idx FROM value WHERE "
"session_id = $1", self._storage.database_id)
for row in rows:
path = self._storage.load_path(row[0])
value = loads(row[1])
owner = row[2]
index = self._storage.load_index(row[3])
if index is None:
ret[0].append(path)
ret[1].append(index)
ret[2].append(value)
ret[3].append(owner)
else:
if path in ret[0]:
path_idx = ret[0].index(path)
ret[1][path_idx].append(index)
ret[2][path_idx].append(value)
ret[3][path_idx].append(owner)
else:
ret[0].append(path)
ret[1].append([index])
ret[2].append([value])
ret[3].append([owner])
return ret
async def importation(self,
connection,
export):
# log.debug('importation')
request = "DELETE FROM value WHERE session_id = $1"
await connection.execute(request, self._storage.database_id)
for idx, path in enumerate(export[0]):
path = self._storage.convert_path(path)
index = self._storage.convert_index(export[1][idx])
value = export[2][idx]
owner = export[3][idx]
if index == -1:
await connection.execute("INSERT INTO value(path, value, owner, idx, session_id) VALUES "
"($1, $2, $3, $4, $5)", path, dumps(value),
str(owner), index,
self._storage.database_id)
else:
for val in zip(index, value, owner):
await connection.execute("INSERT INTO value(path, value, owner, idx, session_id)"
"VALUES ($1, $2, $3, $4, $5)", path,
dumps(val[1]),
str(val[2]), val[0],
self._storage.database_id)
async def get_max_length(self,
connection,
path):
# log.debug('get_max_length %s', path)
val_max = await connection.fetchval("SELECT max(idx) FROM value WHERE path = $1 AND session_id = $2",
path, self._storage.database_id)
if val_max is None:
return 0
return val_max + 1
def getconnection(self):
return self._storage.getconnection()

View file

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2013-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2013-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the
@ -14,15 +14,11 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# ____________________________________________________________ # ____________________________________________________________
"""Sqlite3 plugin for storage. This storage is not made to be used in productive """Sqlite3 plugin for storage.
environment. It was developing as proof of concept.
You should not configure differents Configs with same session_id.
""" """
from .value import Values from .value import Values
from .setting import Properties, Permissives from .setting import Properties, Permissives
from .storage import PERSISTENT, SETTING, Storage, list_sessions from .storage import PERSISTENT, SETTING, Storage, list_sessions, init, Connection
__all__ = ('PERSISTENT', __all__ = ('PERSISTENT',
@ -31,4 +27,6 @@ __all__ = ('PERSISTENT',
'Properties', 'Properties',
'Permissives', 'Permissives',
'Storage', 'Storage',
'init',
'Connection',
'list_sessions') 'list_sessions')

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"default plugin for setting: set it in a simple dictionary" "default plugin for setting: set it in a simple dictionary"
# Copyright (C) 2013-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2013-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the
@ -26,15 +26,25 @@ class Properties(Sqlite3DB):
super(Properties, self).__init__(storage) super(Properties, self).__init__(storage)
# properties # properties
async def setproperties(self, path, index, properties): async def setproperties(self,
await self.delproperties(path, index, commit=False) connection,
await self._storage.execute("INSERT INTO property(path, tiram_index, properties, session_id) VALUES " path,
"(?, ?, ?, ?)", (path, index,
index, properties):
self._sqlite_encode(properties), await self.delproperties(connection,
self._session_id)) path,
index)
await connection.execute("INSERT INTO property(path, tiram_index, properties, session_id) VALUES "
"(?, ?, ?, ?)", (path,
index,
self._sqlite_encode(properties),
self._session_id))
async def getproperties(self, path, index, default_properties): async def getproperties(self,
connection,
path,
index,
default_properties):
sql = 'SELECT properties FROM property WHERE session_id = ? ' sql = 'SELECT properties FROM property WHERE session_id = ? '
params = [self._session_id] params = [self._session_id]
if path is None: if path is None:
@ -47,13 +57,16 @@ class Properties(Sqlite3DB):
else: else:
sql += "AND tiram_index = ? LIMIT 1" sql += "AND tiram_index = ? LIMIT 1"
params.append(index) params.append(index)
value = await self._storage.select(sql, params) value = await connection.select(sql, params)
if value is None: if value is None:
return set(default_properties) return set(default_properties)
else: else:
return set(self._sqlite_decode(value[0])) return set(self._sqlite_decode(value[0]))
async def delproperties(self, path, index, commit=True): async def delproperties(self,
connection,
path,
index):
sql = 'DELETE FROM property WHERE session_id = ? ' sql = 'DELETE FROM property WHERE session_id = ? '
params = [self._session_id] params = [self._session_id]
if path is None: if path is None:
@ -66,47 +79,61 @@ class Properties(Sqlite3DB):
else: else:
params.append(index) params.append(index)
sql += 'AND tiram_index = ?' sql += 'AND tiram_index = ?'
await self._storage.execute(sql, params, commit) await connection.execute(sql, params)
async def exportation(self): async def exportation(self,
connection):
"""return all modified settings in a dictionary """return all modified settings in a dictionary
example: {'path1': set(['prop1', 'prop2'])} example: {'path1': set(['prop1', 'prop2'])}
""" """
ret = {} ret = {}
for path, tiram_index, properties, _ in await self._storage.select("SELECT * FROM property " for path, tiram_index, properties, _ in await connection.select("SELECT * FROM property "
"WHERE session_id = ?", "WHERE session_id = ?",
(self._session_id,), (self._session_id,),
only_one=False): only_one=False):
ret.setdefault(path, {})[tiram_index] = self._sqlite_decode(properties) ret.setdefault(path, {})[tiram_index] = self._sqlite_decode(properties)
return ret return ret
async def importation(self, properties): async def importation(self,
await self._storage.execute("DELETE FROM property WHERE session_id = ?", (self._session_id,), commit=False) connection,
properties):
await connection.execute("DELETE FROM property WHERE session_id = ?", (self._session_id,))
for path, indexed_properties in properties.items(): for path, indexed_properties in properties.items():
for index, property_ in indexed_properties.items(): for index, property_ in indexed_properties.items():
await self._storage.execute("INSERT INTO property(path, tiram_index, properties, session_id) " await connection.execute("INSERT INTO property(path, tiram_index, properties, session_id) "
"VALUES (?, ?, ?, ?)", (path, "VALUES (?, ?, ?, ?)", (path,
index, index,
self._sqlite_encode(property_), self._sqlite_encode(property_),
self._session_id, self._session_id,
), False) ))
self._storage._conn.commit()
def getconnection(self):
return self._storage.getconnection()
class Permissives(Sqlite3DB): class Permissives(Sqlite3DB):
__slots__ = tuple() __slots__ = tuple()
# permissive # permissive
async def setpermissives(self, path, index, permissive): async def setpermissives(self,
connection,
path,
index,
permissive):
log.debug('setpermissive %s %s %s %s', path, index, permissive, id(self)) log.debug('setpermissive %s %s %s %s', path, index, permissive, id(self))
await self.delpermissive(path, index, commit=False) await self.delpermissive(connection,
await self._storage.execute("INSERT INTO permissive(path, tiram_index, permissives, session_id) " path,
"VALUES (?, ?, ?, ?)", (path, index)
index, await connection.execute("INSERT INTO permissive(path, tiram_index, permissives, session_id) "
self._sqlite_encode(permissive), "VALUES (?, ?, ?, ?)", (path,
self._session_id)) index,
self._sqlite_encode(permissive),
self._session_id))
async def getpermissives(self, path, index): async def getpermissives(self,
connection,
path,
index):
sql = 'SELECT permissives FROM permissive WHERE session_id = ? ' sql = 'SELECT permissives FROM permissive WHERE session_id = ? '
params = [self._session_id] params = [self._session_id]
if path is None: if path is None:
@ -119,7 +146,7 @@ class Permissives(Sqlite3DB):
else: else:
sql += "AND tiram_index = ? LIMIT 1" sql += "AND tiram_index = ? LIMIT 1"
params.append(index) params.append(index)
permissives = await self._storage.select(sql, params) permissives = await connection.select(sql, params)
if permissives is None: if permissives is None:
ret = frozenset() ret = frozenset()
else: else:
@ -127,7 +154,10 @@ class Permissives(Sqlite3DB):
log.debug('getpermissive %s %s %s', path, ret, id(self)) log.debug('getpermissive %s %s %s', path, ret, id(self))
return ret return ret
async def delpermissive(self, path, index, commit=True): async def delpermissive(self,
connection,
path,
index):
sql = 'DELETE FROM permissive WHERE session_id = ? ' sql = 'DELETE FROM permissive WHERE session_id = ? '
params = [self._session_id] params = [self._session_id]
if path is None: if path is None:
@ -140,29 +170,30 @@ class Permissives(Sqlite3DB):
else: else:
params.append(index) params.append(index)
sql += 'AND tiram_index = ?' sql += 'AND tiram_index = ?'
await self._storage.execute(sql, params, commit) await connection.execute(sql, params)
async def exportation(self): async def exportation(self,
connection):
"""return all modified permissives in a dictionary """return all modified permissives in a dictionary
example: {'path1': set(['perm1', 'perm2'])} example: {'path1': set(['perm1', 'perm2'])}
""" """
ret = {} ret = {}
sql = "SELECT path, tiram_index, permissives FROM permissive WHERE session_id = ?" sql = "SELECT path, tiram_index, permissives FROM permissive WHERE session_id = ?"
for path, index, permissives in await self._storage.select(sql, for path, index, permissives in await connection.select(sql,
(self._session_id,), (self._session_id,),
only_one=False): only_one=False):
ret.setdefault(path, {})[index] = self._sqlite_decode(permissives) ret.setdefault(path, {})[index] = self._sqlite_decode(permissives)
return ret return ret
async def importation(self, permissives): async def importation(self,
await self._storage.execute("DELETE FROM permissive WHERE session_id = ?", (self._session_id,), connection,
commit=False) permissives):
await connection.execute("DELETE FROM permissive WHERE session_id = ?", (self._session_id,))
for path, indexed_permissives in permissives.items(): for path, indexed_permissives in permissives.items():
for index, permissive in indexed_permissives.items(): for index, permissive in indexed_permissives.items():
await self._storage.execute("INSERT INTO permissive(path, tiram_index, permissives, session_id) " await connection.execute("INSERT INTO permissive(path, tiram_index, permissives, session_id) "
"VALUES (?, ?, ?, ?)", (path, "VALUES (?, ?, ?, ?)", (path,
index, index,
self._sqlite_encode(permissive), self._sqlite_encode(permissive),
self._session_id, self._session_id,
), False) ))
self._storage._conn.commit()

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"sqlite3" "sqlite3"
# Copyright (C) 2013-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2013-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
" with sqlite3 engine" " with sqlite3 engine"
# Copyright (C) 2013-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2013-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the
@ -29,6 +29,67 @@ global CONN
CONN = None CONN = None
async def init():
global CONN
if CONN is None:
CONN = sqlite3.connect(_gen_filename())
CONN.text_factory = str
session_table = 'CREATE TABLE IF NOT EXISTS session(session_id INTEGER, session TEXT UNIQUE, PRIMARY KEY(session_id))'
settings_table = 'CREATE TABLE IF NOT EXISTS property(path TEXT, tiram_index INTEGER, properties TEXT, session_id INTEGER, PRIMARY KEY(path, tiram_index, session_id), ' \
'FOREIGN KEY(session_id) REFERENCES session(session_id))'
permissives_table = 'CREATE TABLE IF NOT EXISTS permissive(path TEXT, tiram_index INTEGER, permissives TEXT, session_id INTEGER, ' \
'PRIMARY KEY(path, tiram_index, session_id), ' \
'FOREIGN KEY(session_id) REFERENCES session(session_id))'
values_table = 'CREATE TABLE IF NOT EXISTS value(path TEXT, value TEXT, owner TEXT, idx INTEGER, session_id INTEGER, ' \
'PRIMARY KEY (path, idx, session_id), ' \
'FOREIGN KEY(session_id) REFERENCES session(session_id))'
informations_table = 'CREATE TABLE IF NOT EXISTS information(key TEXT, value TEXT, session_id INTEGER, path TEXT, ' \
'PRIMARY KEY (key, session_id), ' \
'FOREIGN KEY(session_id) REFERENCES session(session_id))'
cursor = CONN.cursor()
cursor.execute(session_table)
cursor.execute(values_table)
cursor.execute(informations_table)
cursor.execute(settings_table)
cursor.execute(permissives_table)
CONN.commit()
class Connection:
async def __aenter__(self):
self.connection = CONN.cursor()
return self
async def __aexit__(self,
type,
value,
traceback):
if type is None:
CONN.commit()
else:
CONN.rollback()
self.connection.close()
async def execute(self,
sql: str,
params: Optional[Dict]=None) -> None:
if params is None:
params = tuple()
self.connection.execute(sql, params)
async def select(self,
sql: str,
params: Optional[Dict]=None,
only_one: bool=True) -> 'Row':
if params is None:
params = tuple()
self.connection.execute(sql, params)
if only_one:
return self.connection.fetchone()
else:
return self.connection.fetchall()
class Setting: class Setting:
""":param extension: database file extension (by default: db) """:param extension: database file extension (by default: db)
:param dir_database: root database directory (by default: /tmp) :param dir_database: root database directory (by default: /tmp)
@ -57,134 +118,83 @@ def _gen_filename():
return join(SETTING.dir_database, '{0}.{1}'.format(SETTING.name, SETTING.extension)) return join(SETTING.dir_database, '{0}.{1}'.format(SETTING.name, SETTING.extension))
def list_sessions(): async def list_sessions():
if not CONN: if not CONN:
warnings.warn_explicit(Warning(_('Cannot list sessions, please connect to database first')), warnings.warn_explicit(Warning(_('Cannot list sessions, please connect to database first')),
category=Warning, category=Warning,
filename=__file__, filename=__file__,
lineno=63) lineno=63)
return [] return []
else:
cursor = CONN.cursor()
names = [row[0] for row in cursor.execute("SELECT session FROM session").fetchall()]
return names
def delete_session(session_id,
_session_id=None):
cursor = CONN.cursor() cursor = CONN.cursor()
if _session_id is None: return await _list_sessions(cursor)
_session_id = cursor.execute("SELECT session_id FROM session WHERE session = ?",
(session_id,)).fetchone()
if _session_id is not None: async def _list_sessions(cursor):
_session_id = _session_id[0] names = [row[0] for row in cursor.execute("SELECT session FROM session").fetchall()]
if _session_id is not None: return names
cursor.execute("DELETE FROM property WHERE session_id = ?", (_session_id,))
cursor.execute("DELETE FROM permissive WHERE session_id = ?", (_session_id,))
cursor.execute("DELETE FROM value WHERE session_id = ?", (_session_id,)) async def delete_session(session_id):
cursor.execute("DELETE FROM information WHERE session_id = ?", (_session_id,)) cursor = CONN.cursor()
cursor.execute("DELETE FROM session WHERE session_id = ?", (_session_id,)) ret = cursor.execute("SELECT session_id FROM session WHERE session = ?",
CONN.commit() (session_id,)).fetchone()
if ret is not None:
database_id = ret[0]
await _delete_session(database_id,
cursor)
cursor.close() cursor.close()
async def _delete_session(database_id,
cursor):
cursor.execute("DELETE FROM property WHERE session_id = ?", (database_id,))
cursor.execute("DELETE FROM permissive WHERE session_id = ?", (database_id,))
cursor.execute("DELETE FROM value WHERE session_id = ?", (database_id,))
cursor.execute("DELETE FROM information WHERE session_id = ?", (database_id,))
cursor.execute("DELETE FROM session WHERE session_id = ?", (database_id,))
CONN.commit()
@asyncinit @asyncinit
class Storage: class Storage:
__slots__ = ('_conn', __slots__ = ('_conn',
'_cursor', '_cursor',
'persistent',
'session_id', 'session_id',
'session_name', 'session_name',
'created') 'created')
storage = 'sqlite3' storage = 'sqlite3'
async def __init__(self, async def __init__(self,
connection: Connection,
session_id: str, session_id: str,
persistent: bool): delete_old_session: bool) -> None:
if not isinstance(session_id, str):
raise ValueError(_('session_id has to be a string'))
self.created = False self.created = False
self.persistent = persistent
global CONN
init = False
if CONN is None:
init = True
CONN = sqlite3.connect(_gen_filename())
CONN.text_factory = str
self._conn = CONN
self._cursor = self._conn.cursor()
self.session_name = session_id
if init:
session_table = 'CREATE TABLE IF NOT EXISTS session(session_id INTEGER, '
session_table += 'session TEXT UNIQUE, persistent BOOL, PRIMARY KEY(session_id))'
settings_table = 'CREATE TABLE IF NOT EXISTS property(path TEXT, '
settings_table += 'tiram_index INTEGER, properties TEXT, session_id INTEGER, PRIMARY KEY(path, tiram_index, session_id), '
settings_table += 'FOREIGN KEY(session_id) REFERENCES session(session_id))'
permissives_table = 'CREATE TABLE IF NOT EXISTS permissive(path TEXT,'
permissives_table += 'tiram_index INTEGER, permissives TEXT, session_id INTEGER, PRIMARY KEY(path, tiram_index, session_id), '
permissives_table += 'FOREIGN KEY(session_id) REFERENCES session(session_id))'
values_table = 'CREATE TABLE IF NOT EXISTS value(path TEXT, '
values_table += 'value TEXT, owner TEXT, idx INTEGER, session_id INTEGER, '\
'PRIMARY KEY (path, idx, session_id), '
values_table += 'FOREIGN KEY(session_id) REFERENCES session(session_id))'
informations_table = 'CREATE TABLE IF NOT EXISTS information(key TEXT,'
informations_table += 'value TEXT, session_id INTEGER, path TEXT, '
informations_table += 'PRIMARY KEY (key, session_id), '
informations_table += 'FOREIGN KEY(session_id) REFERENCES session(session_id))'
self._cursor.execute(session_table)
self._cursor.execute(values_table)
self._cursor.execute(informations_table)
self._cursor.execute(settings_table)
self._cursor.execute(permissives_table)
commit_needed = True
else:
commit_needed = False
self.session_id = None self.session_id = None
if self.persistent: self.session_name = session_id
select = await self.select("SELECT session_id FROM session WHERE session = ?", (session_id,)) select = await connection.select("SELECT session_id FROM session WHERE session = ?", (session_id,))
if select is not None: if select is not None:
if delete_old_session:
self.delete_session()
else:
self.session_id = select[0] self.session_id = select[0]
if self.session_id is None: if self.session_id is None:
try: await connection.execute('INSERT INTO session(session) VALUES (?)',
self._cursor.execute('INSERT INTO session(session, persistent) VALUES (?, ?)', (session_id,))
(session_id, persistent)) self.session_id = connection.connection.lastrowid
except sqlite3.IntegrityError: # pragma: no cover
raise ConflictError(_('session "{}" already exists').format(session_id))
commit_needed = True
self.session_id = self._cursor.lastrowid
if commit_needed:
self._conn.commit()
self.created = True self.created = True
async def commit(self) -> None: async def delete_session(self):
self._conn.commit() if self.session_id is not None:
await _delete_session(self.session_id,
CONN)
self.session_id = None
async def execute(self, async def list_sessions(self):
sql: str, return await _list_sessions(self._cursor)
params: Optional[Dict]=None,
commit: bool=True) -> None:
#print(sql, params, commit)
if params is None:
params = tuple()
self._cursor.execute(sql, params)
if commit:
await self.commit()
async def select(self, def getconnection(self):
sql: str, return Connection()
params: Optional[Dict]=None,
only_one: bool=True) -> 'Row':
await self.execute(sql, params=params, commit=False)
if only_one:
return self._cursor.fetchone()
else:
return self._cursor.fetchall()
def __del__(self) -> None:
self._cursor.close()
if self.created and not self.persistent:
if delete_session is not None:
session_id = getattr(self, 'session_id', None)
delete_session(self.session_name,
session_id)
def getsession(): def getsession():

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"default plugin for value: set it in a simple dictionary" "default plugin for value: set it in a simple dictionary"
# Copyright (C) 2013-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2013-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the
@ -32,50 +32,52 @@ class Values(Sqlite3DB):
super(Values, self).__init__(storage) super(Values, self).__init__(storage)
# sqlite # sqlite
async def _sqlite_select(self, path, index): async def _sqlite_select(self,
connection,
path,
index):
request = "SELECT value FROM value WHERE path = ? AND session_id = ? " request = "SELECT value FROM value WHERE path = ? AND session_id = ? "
params = (path, self._session_id) params = (path, self._session_id)
if index is not None: if index is not None:
request += "and idx = ? " request += "and idx = ? "
params = (path, self._session_id, index) params = (path, self._session_id, index)
request += "LIMIT 1" request += "LIMIT 1"
return await self._storage.select(request, params) return await connection.select(request, params)
async def commit(self):
await self._storage.commit()
# value # value
async def setvalue(self, async def setvalue(self,
connection,
path, path,
value, value,
owner, owner,
index, index,
commit): new=False):
"""set value for an option """set value for an option
a specified value must be associated to an owner a specified value must be associated to an owner
""" """
log.debug('setvalue %s %s %s %s %s', path, value, owner, index, commit) log.debug('setvalue %s %s %s %s', path, value, owner, index)
path = self._sqlite_encode_path(path) path = self._sqlite_encode_path(path)
if index is not None: if index is not None:
await self.resetvalue_index(path, if not new:
index, await self.resetvalue_index(connection,
commit=False) path,
await self._storage.execute("INSERT INTO value(path, value, owner, idx, session_id) VALUES " index)
"(?, ?, ?, ?, ?)", (path, self._sqlite_encode(value), await connection.execute("INSERT INTO value(path, value, owner, idx, session_id) VALUES "
str(owner), "(?, ?, ?, ?, ?)", (path, self._sqlite_encode(value),
index,
self._session_id),
commit=commit)
else:
await self.resetvalue(path,
commit=False)
await self._storage.execute("INSERT INTO value(path, value, owner, session_id) VALUES "
"(?, ?, ?, ?)", (path, self._sqlite_encode(value),
str(owner), str(owner),
self._session_id), index,
commit=commit) self._session_id))
else:
if not new:
await self.resetvalue(connection,
path)
await connection.execute("INSERT INTO value(path, value, owner, session_id) VALUES "
"(?, ?, ?, ?)", (path, self._sqlite_encode(value),
str(owner),
self._session_id))
async def hasvalue(self, async def hasvalue(self,
connection,
path, path,
index=None): index=None):
"""if opt has a value """if opt has a value
@ -83,44 +85,48 @@ class Values(Sqlite3DB):
""" """
log.debug('hasvalue %s %s', path, index) log.debug('hasvalue %s %s', path, index)
path = self._sqlite_encode_path(path) path = self._sqlite_encode_path(path)
return await self._sqlite_select(path, index) is not None return await self._sqlite_select(connection,
path,
index) is not None
async def reduce_index(self, path, index): async def reduce_index(self,
connection,
path,
index):
""" """
_values == ((path1, path2), ((idx1_1, idx1_2), None), _values == ((path1, path2), ((idx1_1, idx1_2), None),
((value1_1, value1_2), value2), ((owner1_1, owner1_2), owner2)) ((value1_1, value1_2), value2), ((owner1_1, owner1_2), owner2))
""" """
log.debug('reduce_index %s %s %s', path, index, id(self)) log.debug('reduce_index %s %s %s', path, index, id(self))
await self._storage.execute("UPDATE value SET idx = ? WHERE path = ? and idx = ? " await connection.execute("UPDATE value SET idx = ? WHERE path = ? and idx = ? "
"AND session_id = ?", "AND session_id = ?",
(index - 1, path, index, self._session_id)) (index - 1, path, index, self._session_id))
async def resetvalue_index(self, async def resetvalue_index(self,
connection,
path, path,
index, index):
commit=True):
"""remove value means delete value in storage """remove value means delete value in storage
""" """
log.debug('resetvalue_index %s %s %s', path, index, commit) log.debug('resetvalue_index %s %s', path, index)
path = self._sqlite_encode_path(path) path = self._sqlite_encode_path(path)
await self._storage.execute("DELETE FROM value WHERE path = ? AND session_id = ? AND idx = ?", await connection.execute("DELETE FROM value WHERE path = ? AND session_id = ? AND idx = ?",
(path, self._session_id, index), (path, self._session_id, index))
commit=commit)
async def resetvalue(self, async def resetvalue(self,
path, connection,
commit): path):
"""remove value means delete value in storage """remove value means delete value in storage
""" """
log.debug('resetvalue %s %s', path, commit) log.debug('resetvalue %s', path)
path = self._sqlite_encode_path(path) path = self._sqlite_encode_path(path)
await self._storage.execute("DELETE FROM value WHERE path = ? AND session_id = ?", await connection.execute("DELETE FROM value WHERE path = ? AND session_id = ?",
(path, self._session_id), (path, self._session_id))
commit=commit)
# owner # owner
async def setowner(self, async def setowner(self,
connection,
path, path,
owner, owner,
index=None): index=None):
@ -129,17 +135,18 @@ class Values(Sqlite3DB):
log.debug('setowner %s %s %s', path, owner, index) log.debug('setowner %s %s %s', path, owner, index)
path = self._sqlite_encode_path(path) path = self._sqlite_encode_path(path)
if index is None: if index is None:
await self._storage.execute("UPDATE value SET owner = ? WHERE path = ? AND session_id = ?", await connection.execute("UPDATE value SET owner = ? WHERE path = ? AND session_id = ?",
(str(owner), path, self._session_id)) (str(owner), path, self._session_id))
else: else:
await self._storage.execute("UPDATE value SET owner = ? WHERE path = ? and idx = ? AND session_id = ?", await connection.execute("UPDATE value SET owner = ? WHERE path = ? and idx = ? AND session_id = ?",
(str(owner), path, index, self._session_id)) (str(owner), path, index, self._session_id))
async def getowner(self, async def getowner(self,
path, connection,
default, path,
index=None, default,
with_value=False): index=None,
with_value=False):
"""get owner for an option """get owner for an option
return: owner object return: owner object
""" """
@ -152,7 +159,7 @@ class Values(Sqlite3DB):
else: else:
params = (path, self._session_id) params = (path, self._session_id)
request += ' LIMIT 1' request += ' LIMIT 1'
owner = await self._storage.select(request, params) owner = await connection.select(request, params)
if owner is None: if owner is None:
if not with_value: if not with_value:
return default return default
@ -171,7 +178,11 @@ class Values(Sqlite3DB):
value = self._sqlite_decode(owner[1]) value = self._sqlite_decode(owner[1])
return nowner, value return nowner, value
async def set_information(self, path, key, value): async def set_information(self,
connection,
path,
key,
value):
"""updates the information's attribute """updates the information's attribute
(which is a dictionary) (which is a dictionary)
@ -180,22 +191,25 @@ class Values(Sqlite3DB):
""" """
log.debug('set_information %s %s', key, value) log.debug('set_information %s %s', key, value)
path = self._sqlite_encode_path(path) path = self._sqlite_encode_path(path)
await self._storage.execute("DELETE FROM information WHERE key = ? AND session_id = ? AND path = ?", await connection.execute("DELETE FROM information WHERE key = ? AND session_id = ? AND path = ?",
(key, self._session_id, path), (key, self._session_id, path))
False) await connection.execute("INSERT INTO information(key, value, session_id, path) VALUES "
await self._storage.execute("INSERT INTO information(key, value, session_id, path) VALUES " "(?, ?, ?, ?)", (key, self._sqlite_encode(value), self._session_id, path))
"(?, ?, ?, ?)", (key, self._sqlite_encode(value), self._session_id, path))
async def get_information(self, path, key, default): async def get_information(self,
connection,
path,
key,
default):
"""retrieves one information's item """retrieves one information's item
:param key: the item string (ex: "help") :param key: the item string (ex: "help")
""" """
log.debug('get_information %s %s', key, default) log.debug('get_information %s %s', key, default)
path = self._sqlite_encode_path(path) path = self._sqlite_encode_path(path)
value = await self._storage.select("SELECT value FROM information WHERE key = ? AND " value = await connection.select("SELECT value FROM information WHERE key = ? AND "
"session_id = ? AND path = ?", "session_id = ? AND path = ?",
(key, self._session_id, path)) (key, self._session_id, path))
if value is None: if value is None:
if default is undefined: if default is undefined:
raise ValueError(_("information's item" raise ValueError(_("information's item"
@ -204,35 +218,43 @@ class Values(Sqlite3DB):
else: else:
return self._sqlite_decode(value[0]) return self._sqlite_decode(value[0])
async def del_information(self, path, key, raises): async def del_information(self,
connection,
path,
key,
raises):
log.debug('del_information %s %s', key, raises) log.debug('del_information %s %s', key, raises)
path = self._sqlite_encode_path(path) path = self._sqlite_encode_path(path)
information = await self._storage.select("SELECT value FROM information WHERE key = ? " information = await connection.select("SELECT value FROM information WHERE key = ? "
"AND session_id = ? AND path = ?", "AND session_id = ? AND path = ?",
(key, self._session_id, path)) (key, self._session_id, path))
if raises and information is None: if raises and information is None:
raise ValueError(_("information's item not found {0}").format(key)) raise ValueError(_("information's item not found {0}").format(key))
await self._storage.execute("DELETE FROM information WHERE key = ? AND session_id = ? AND path = ?", await connection.execute("DELETE FROM information WHERE key = ? AND session_id = ? AND path = ?",
(key, self._session_id, path)) (key, self._session_id, path))
async def list_information(self, path): async def list_information(self,
connection,
path):
path = self._sqlite_encode_path(path) path = self._sqlite_encode_path(path)
rows = await self._storage.select("SELECT key FROM information WHERE session_id = ? AND path = ?", rows = await connection.select("SELECT key FROM information WHERE session_id = ? AND path = ?",
(self._session_id, path), (self._session_id, path),
only_one=False) only_one=False)
ret = [] ret = []
for row in rows: for row in rows:
ret.append(self._sqlite_decode_path(row[0])) ret.append(self._sqlite_decode_path(row[0]))
return ret return ret
async def del_informations(self): async def del_informations(self,
await self._storage.execute("DELETE FROM information WHERE session_id = ?", connection):
(self._session_id,)) await connection.execute("DELETE FROM information WHERE session_id = ?",
(self._session_id,))
async def exportation(self): async def exportation(self,
connection):
log.debug('exportation') log.debug('exportation')
rows = await self._storage.select("SELECT path, value, owner, idx FROM value WHERE " rows = await connection.select("SELECT path, value, owner, idx FROM value WHERE "
"session_id = ?;", (self._session_id,), only_one=False) "session_id = ?;", (self._session_id,), only_one=False)
ret = [[], [], [], []] ret = [[], [], [], []]
for row in rows: for row in rows:
path = self._sqlite_decode_path(row[0]) path = self._sqlite_decode_path(row[0])
@ -258,36 +280,36 @@ class Values(Sqlite3DB):
return ret return ret
async def importation(self, export): async def importation(self,
connection,
export):
log.debug('importation') log.debug('importation')
request = "DELETE FROM value WHERE session_id = ?" request = "DELETE FROM value WHERE session_id = ?"
await self._storage.execute(request, (self._session_id,), await connection.execute(request, (self._session_id,))
commit=False)
for idx, path in enumerate(export[0]): for idx, path in enumerate(export[0]):
path = self._sqlite_encode_path(path) path = self._sqlite_encode_path(path)
index = export[1][idx] index = export[1][idx]
value = export[2][idx] value = export[2][idx]
owner = export[3][idx] owner = export[3][idx]
if index is None: if index is None:
await self._storage.execute("INSERT INTO value(path, value, owner, idx, session_id) VALUES " await connection.execute("INSERT INTO value(path, value, owner, idx, session_id) VALUES "
"(?, ?, ?, ?, ?)", (path, self._sqlite_encode(value), "(?, ?, ?, ?, ?)", (path, self._sqlite_encode(value),
str(owner), index, str(owner), index,
self._session_id), commit=False) self._session_id))
else: else:
for val in zip(index, value, owner): for val in zip(index, value, owner):
await self._storage.execute("INSERT INTO value(path, value, owner, idx, session_id)" await connection.execute("INSERT INTO value(path, value, owner, idx, session_id)"
"VALUES (?, ?, ?, ?, ?)", (path, "VALUES (?, ?, ?, ?, ?)", (path,
self._sqlite_encode(val[1]), self._sqlite_encode(val[1]),
str(val[2]), val[0], str(val[2]), val[0],
self._session_id), self._session_id))
commit=False)
self._storage._conn.commit()
async def get_max_length(self, async def get_max_length(self,
connection,
path): path):
log.debug('get_max_length %s', path) log.debug('get_max_length %s', path)
val_max = await self._storage.select("SELECT max(idx) FROM value WHERE path = ? AND session_id = ?", val_max = await connection.select("SELECT max(idx) FROM value WHERE path = ? AND session_id = ?",
(path, self._session_id), False) (path, self._session_id), False)
if val_max[0][0] is None: if val_max[0][0] is None:
return 0 return 0
return val_max[0][0] + 1 return val_max[0][0] + 1

View file

@ -606,7 +606,7 @@ class TiramisuDict:
old_properties = childapi._option_bag.config_bag.properties old_properties = childapi._option_bag.config_bag.properties
config = childapi._option_bag.config_bag.context config = childapi._option_bag.config_bag.context
settings = config.cfgimpl_get_settings() settings = config.cfgimpl_get_settings()
childapi._option_bag.config_bag.properties = await settings.get_context_properties(config._impl_properties_cache) childapi._option_bag.config_bag.properties = await self.config.property.get(default=True) # settings.get_context_properties(config._impl_properties_cache)
childapi._option_bag.config_bag.properties -= {'permissive'} childapi._option_bag.config_bag.properties -= {'permissive'}
properties = await childapi.property.get(only_raises=True, properties = await childapi.property.get(only_raises=True,
uncalculated=True) uncalculated=True)

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"takes care of the option's values and multi values" "takes care of the option's values and multi values"
# Copyright (C) 2013-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2013-2020 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the
@ -34,7 +34,8 @@ class Values:
'__weakref__') '__weakref__')
async def __init__(self, async def __init__(self,
storage): storage,
connection):
""" """
Initializes the values's dict. Initializes the values's dict.
@ -44,13 +45,17 @@ class Values:
# store the storage # store the storage
self._p_ = storage self._p_ = storage
# set default owner # set default owner
owner = await self._p_.getowner(None, None) owner = await self._p_.getowner(connection,
None,
None,
None)
if owner is None: if owner is None:
await self._p_.setvalue(None, await self._p_.setvalue(connection,
None,
None, None,
owners.user, owners.user,
None, None,
True) new=True)
#______________________________________________________________________ #______________________________________________________________________
# get value # get value
@ -105,7 +110,10 @@ class Values:
if 'force_metaconfig_on_freeze' in option_bag.properties: if 'force_metaconfig_on_freeze' in option_bag.properties:
settings = option_bag.config_bag.context.cfgimpl_get_settings() settings = option_bag.config_bag.context.cfgimpl_get_settings()
if 'force_metaconfig_on_freeze' in option_bag.option.impl_getproperties() and \ if 'force_metaconfig_on_freeze' in option_bag.option.impl_getproperties() and \
not await settings._p_.getproperties(option_bag.path, None, frozenset()): not await settings._p_.getproperties(option_bag.config_bag.connection,
option_bag.path,
None,
frozenset()):
# if force_metaconfig_on_freeze is only in option (not in config) # if force_metaconfig_on_freeze is only in option (not in config)
return option_bag.config_bag.context.impl_type == 'config' return option_bag.config_bag.context.impl_type == 'config'
else: else:
@ -143,7 +151,8 @@ class Values:
_index = None _index = None
else: else:
_index = index _index = index
owner, value = await self._p_.getowner(option_bag.path, owner, value = await self._p_.getowner(option_bag.config_bag.connection,
option_bag.path,
owners.default, owners.default,
index=_index, index=_index,
with_value=True) with_value=True)
@ -286,10 +295,9 @@ class Values:
# set value # set value
async def setvalue(self, async def setvalue(self,
value, value,
option_bag, option_bag):
_commit):
context = option_bag.config_bag.context context = option_bag.config_bag.context
owner = await self.get_context_owner() owner = await self.get_context_owner(option_bag.config_bag.connection)
if 'validator' in option_bag.config_bag.properties: if 'validator' in option_bag.config_bag.properties:
await self.setvalue_validation(value, await self.setvalue_validation(value,
option_bag) option_bag)
@ -299,8 +307,7 @@ class Values:
value = value.copy() value = value.copy()
await self._setvalue(option_bag, await self._setvalue(option_bag,
value, value,
owner, owner)
commit=False)
setting_properties = option_bag.config_bag.properties setting_properties = option_bag.config_bag.properties
validator = 'validator' in setting_properties and 'demoting_error_warning' not in setting_properties validator = 'validator' in setting_properties and 'demoting_error_warning' not in setting_properties
if validator: if validator:
@ -315,10 +322,7 @@ class Values:
await option_bag.option.impl_get_leadership().follower_force_store_value(self, await option_bag.option.impl_get_leadership().follower_force_store_value(self,
value, value,
option_bag, option_bag,
owners.forced, owners.forced)
_commit=_commit)
if _commit:
await self._p_.commit()
async def setvalue_validation(self, async def setvalue_validation(self,
value, value,
@ -343,14 +347,13 @@ class Values:
async def _setvalue(self, async def _setvalue(self,
option_bag, option_bag,
value, value,
owner, owner):
commit=True):
await option_bag.config_bag.context.cfgimpl_reset_cache(option_bag) await option_bag.config_bag.context.cfgimpl_reset_cache(option_bag)
await self._p_.setvalue(option_bag.path, await self._p_.setvalue(option_bag.config_bag.connection,
option_bag.path,
value, value,
owner, owner,
option_bag.index, option_bag.index)
commit)
async def _get_modified_parent(self, async def _get_modified_parent(self,
option_bag: OptionBag) -> Optional[OptionBag]: option_bag: OptionBag) -> Optional[OptionBag]:
@ -420,13 +423,15 @@ class Values:
'force_default_on_freeze' in option_bag.properties: 'force_default_on_freeze' in option_bag.properties:
return owners.default return owners.default
if only_default: if only_default:
if await self._p_.hasvalue(option_bag.path, if await self._p_.hasvalue(option_bag.config_bag.connection,
option_bag.path,
option_bag.index): option_bag.index):
owner = 'not_default' owner = 'not_default'
else: else:
owner = owners.default owner = owners.default
else: else:
owner = await self._p_.getowner(option_bag.path, owner = await self._p_.getowner(option_bag.config_bag.connection,
option_bag.path,
owners.default, owners.default,
index=option_bag.index) index=option_bag.index)
if validate_meta is not False and (owner is owners.default or \ if validate_meta is not False and (owner is owners.default or \
@ -455,26 +460,27 @@ class Values:
if owner in forbidden_owners: if owner in forbidden_owners:
raise ValueError(_('set owner "{0}" is forbidden').format(str(owner))) raise ValueError(_('set owner "{0}" is forbidden').format(str(owner)))
if not await self._p_.hasvalue(option_bag.path): if not await self._p_.hasvalue(option_bag.config_bag.connection,
option_bag.path):
raise ConfigError(_('no value for {0} cannot change owner to {1}' raise ConfigError(_('no value for {0} cannot change owner to {1}'
'').format(option_bag.path, owner)) '').format(option_bag.path, owner))
option_bag.config_bag.context.cfgimpl_get_settings().validate_frozen(option_bag) option_bag.config_bag.context.cfgimpl_get_settings().validate_frozen(option_bag)
await self._p_.setowner(option_bag.path, await self._p_.setowner(option_bag.config_bag.connection,
owner, option_bag.path,
index=option_bag.index) owner,
index=option_bag.index)
#______________________________________________________________________ #______________________________________________________________________
# reset # reset
async def reset(self, async def reset(self,
option_bag, option_bag):
_commit=True):
context = option_bag.config_bag.context context = option_bag.config_bag.context
hasvalue = await self._p_.hasvalue(option_bag.path) hasvalue = await self._p_.hasvalue(option_bag.config_bag.connection,
option_bag.path)
setting_properties = option_bag.config_bag.properties setting_properties = option_bag.config_bag.properties
if hasvalue and 'validator' in option_bag.config_bag.properties: if hasvalue and 'validator' in option_bag.config_bag.properties:
fake_context = await context._gen_fake_values() fake_context = await context._gen_fake_values(option_bag.config_bag.connection)
config_bag = option_bag.config_bag.copy() config_bag = option_bag.config_bag.copy()
config_bag.remove_validation() config_bag.remove_validation()
config_bag.context = fake_context config_bag.context = fake_context
@ -489,21 +495,19 @@ class Values:
opt = option_bag.option opt = option_bag.option
if opt.impl_is_leader(): if opt.impl_is_leader():
await opt.impl_get_leadership().reset(self, await opt.impl_get_leadership().reset(self,
option_bag, option_bag)
_commit=_commit)
if hasvalue: if hasvalue:
if 'force_store_value' in option_bag.config_bag.properties and 'force_store_value' in option_bag.properties: if 'force_store_value' in option_bag.config_bag.properties and 'force_store_value' in option_bag.properties:
value = await self.getdefaultvalue(option_bag) value = await self.getdefaultvalue(option_bag)
await self._setvalue(option_bag, await self._setvalue(option_bag,
value, value,
owners.forced, owners.forced)
commit=_commit)
else: else:
# for leader only # for leader only
value = None value = None
await self._p_.resetvalue(option_bag.path, await self._p_.resetvalue(option_bag.config_bag.connection,
_commit) option_bag.path)
await context.cfgimpl_reset_cache(option_bag) await context.cfgimpl_reset_cache(option_bag)
if 'force_store_value' in setting_properties and option_bag.option.impl_is_leader(): if 'force_store_value' in setting_properties and option_bag.option.impl_is_leader():
if value is None: if value is None:
@ -511,17 +515,17 @@ class Values:
await option_bag.option.impl_get_leadership().follower_force_store_value(self, await option_bag.option.impl_get_leadership().follower_force_store_value(self,
value, value,
option_bag, option_bag,
owners.forced, owners.forced)
_commit=_commit)
async def reset_follower(self, async def reset_follower(self,
option_bag, option_bag):
_commit=True): if await self._p_.hasvalue(option_bag.config_bag.connection,
if await self._p_.hasvalue(option_bag.path, index=option_bag.index): option_bag.path,
index=option_bag.index):
context = option_bag.config_bag.context context = option_bag.config_bag.context
setting_properties = option_bag.config_bag.properties setting_properties = option_bag.config_bag.properties
if 'validator' in setting_properties: if 'validator' in setting_properties:
fake_context = await context._gen_fake_values() fake_context = await context._gen_fake_values(option_bag.config_bag.connection)
fake_value = fake_context.cfgimpl_get_values() fake_value = fake_context.cfgimpl_get_values()
config_bag = option_bag.config_bag.copy() config_bag = option_bag.config_bag.copy()
config_bag.remove_validation() config_bag.remove_validation()
@ -537,12 +541,11 @@ class Values:
await self._setvalue(option_bag, await self._setvalue(option_bag,
value, value,
owners.forced, owners.forced)
commit=_commit)
else: else:
await self._p_.resetvalue_index(option_bag.path, await self._p_.resetvalue_index(option_bag.config_bag.connection,
option_bag.index, option_bag.path,
_commit) option_bag.index)
await context.cfgimpl_reset_cache(option_bag) await context.cfgimpl_reset_cache(option_bag)
async def reset_leadership(self, async def reset_leadership(self,
@ -561,13 +564,13 @@ class Values:
index, index,
option_bag) option_bag)
await self.setvalue(current_value, await self.setvalue(current_value,
option_bag, option_bag)
_commit=True)
#______________________________________________________________________ #______________________________________________________________________
# information # information
async def set_information(self, async def set_information(self,
connection,
key, key,
value, value,
path=None): path=None):
@ -576,11 +579,13 @@ class Values:
:param key: information's key (ex: "help", "doc" :param key: information's key (ex: "help", "doc"
:param value: information's value (ex: "the help string") :param value: information's value (ex: "the help string")
""" """
await self._p_.set_information(path, await self._p_.set_information(connection,
path,
key, key,
value) value)
async def get_information(self, async def get_information(self,
connection,
key, key,
default=undefined, default=undefined,
path=None): path=None):
@ -588,21 +593,26 @@ class Values:
:param key: the item string (ex: "help") :param key: the item string (ex: "help")
""" """
return await self._p_.get_information(path, return await self._p_.get_information(connection,
path,
key, key,
default) default)
async def del_information(self, async def del_information(self,
connection,
key, key,
raises=True, raises=True,
path=None): path=None):
await self._p_.del_information(path, await self._p_.del_information(connection,
path,
key, key,
raises) raises)
async def list_information(self, async def list_information(self,
connection,
path=None): path=None):
return await self._p_.list_information(path) return await self._p_.list_information(connection,
path)
#______________________________________________________________________ #______________________________________________________________________
# mandatory warnings # mandatory warnings
@ -675,18 +685,20 @@ class Values:
od_setting_properties = config_bag.properties - {'mandatory', 'empty'} od_setting_properties = config_bag.properties - {'mandatory', 'empty'}
setting_properties = set(config_bag.properties) - {'warnings'} setting_properties = set(config_bag.properties) - {'warnings'}
setting_properties.update(['mandatory', 'empty']) setting_properties.update(['mandatory', 'empty'])
config_bag = ConfigBag(context=config_bag.context, nconfig_bag = ConfigBag(context=config_bag.context,
properties=frozenset(setting_properties), properties=frozenset(setting_properties),
permissives=config_bag.permissives) permissives=config_bag.permissives)
config_bag.set_permissive() nconfig_bag.connection = config_bag.connection
od_config_bag = ConfigBag(context=config_bag.context, nconfig_bag.set_permissive()
od_config_bag = ConfigBag(context=nconfig_bag.context,
properties=frozenset(od_setting_properties), properties=frozenset(od_setting_properties),
permissives=config_bag.permissives) permissives=nconfig_bag.permissives)
od_config_bag.connection = config_bag.connection
od_config_bag.set_permissive() od_config_bag.set_permissive()
descr = context.cfgimpl_get_description() descr = context.cfgimpl_get_description()
async for option in self._mandatory_warnings(context, async for option in self._mandatory_warnings(context,
config_bag, nconfig_bag,
descr, descr,
[], [],
context, context,
@ -696,15 +708,20 @@ class Values:
#____________________________________________________________ #____________________________________________________________
# default owner methods # default owner methods
async def set_context_owner(self, async def set_context_owner(self,
connection,
owner): owner):
":param owner: sets the default value for owner at the Config level" ":param owner: sets the default value for owner at the Config level"
if owner in forbidden_owners: if owner in forbidden_owners:
raise ValueError(_('set owner "{0}" is forbidden').format(str(owner))) raise ValueError(_('set owner "{0}" is forbidden').format(str(owner)))
await self._p_.setowner(None, await self._p_.setowner(connection,
None,
owner, owner,
index=None) index=None)
async def get_context_owner(self): async def get_context_owner(self,
return await self._p_.getowner(None, connection):
return await self._p_.getowner(connection,
None,
None,
None) None)