creole/tests/test_genconfig.py

351 lines
15 KiB
Python

#-*-coding:utf-8*-*
from os.path import join, isdir
from json import load
from py.test import raises
from creole.loader import config_save_values
from creole.config import eoleroot
from tiramisu.error import PropertiesOptionError
from eolegenconfig import lib
ID_ = 'test'
DICO_DIR = '/usr/share/creole/tests/dicos'
if not isdir(DICO_DIR):
DICO_DIR = 'tests/dicos'
CONFIG_DIR = '/usr/share/creole/tests/configs'
if not isdir(CONFIG_DIR):
CONFIG_DIR = 'tests/configs'
def _calc_config_file(test):
"""
nom du fichier eol lié au test
"""
if isdir(CONFIG_DIR):
config_dir = CONFIG_DIR
else:
config_dir = 'tests/configs'
return join(config_dir, '{0}.eol'.format(test))
def _load(test, erase=True):
"""
Chargement des dictionnaires liés au test
Initialisation du fichier eol lié au test
"""
config_file = _calc_config_file(test)
if erase:
file(config_file, 'w')
if isdir(DICO_DIR):
dico_dir = DICO_DIR
else:
dico_dir = 'tests/dicos'
return lib.get_config(ID_, force_dirs=join(dico_dir, test),
force_configfile=config_file)
def _reload(test):
"""
recharge une configuration enregistrée
"""
_load(test, erase=False)
def _save(test):
"""
Enregistement des données
"""
config_file = _calc_config_file(test)
config = lib.get_config(ID_)
config_save_values(config, 'creole', eol_file=config_file, reload_config=False)
def test_basic_rules():
"""
Vérifie l'application de certines règles de base #7432
"""
config = _load('basic')
# variable obligatoire sans valeur par défaut => mode basique
assert lib.get_variable(ID_, 'test', 'obligatoire')['mode'] == 'basic'
# variable non obligatoire avec valeur par défaut => obligatoire
assert lib.get_variable(ID_, 'test', 'facultatif')['mandatory']
def test_obligatoire():
"""
Vérifie la validation des variables mandatory (#16660)
"""
config = _load('obligatoire')
# sauvegarde avec aucune variable renseignée
raises(PropertiesOptionError, "_save('obligatoire')")
lib.set_value(ID_, 'test', 'vmaster', ['val'])
# sauvegarde avec uniquement la master renseignée
raises(PropertiesOptionError, "_save('obligatoire')")
lib.set_value(ID_, 'test', 'vmaster.vslave1', ['val'])
# sauvegarde avec toutes les mandatory renseignées
_save('obligatoire')
lib.set_value(ID_, 'test', 'vmaster.vslave3', [None])
# sauvegarde avec la slave pré-remplie "vidée"
raises(PropertiesOptionError, "_save('obligatoire')")
def test_calc_multi_condition():
"""
calc_multi_condition avec une variable désactivée #8439
calc_multi_condition avec 2 valeurs différentes en entrée #9797
"""
config = _load('multicondition')
assert config.creole.test.target1 == 'resultat2'
assert config.creole.test.target2 == 'resultat1'
assert config.creole.test.target3 == 'oui'
lib.set_value(ID_, 'test', 'condition', 'non')
assert config.creole.test.target1 == 'resultat1'
assert config.creole.test.target2 == 'mismatch'
assert config.creole.test.target3 == 'non'
def test_auto_save():
"""
auto_save sur une variable multi (#8020)
"""
config = _load('autosave')
assert config.creole.test.autosave == [u'a', u'b']
_save('autosave')
content = load(file(_calc_config_file('autosave')))
assert content['autosave'] == {'owner': 'forced', 'val': [u'a', u'b']}
def test_auto_freeze():
"""
Comportement des variables auto_freeze='True'
"""
config = _load('autofreeze')
lib.set_mode(ID_, 'expert')
# variable auto_freeze => mode basic
assert lib.get_variable(ID_, 'test', 'autofreeze')['mode'] == 'basic'
# mais exception si mode='expert' (#7349)
assert lib.get_variable(ID_, 'test', 'autofreeze_x')['mode'] == 'expert'
lib.set_value(ID_, 'test', 'autofreeze', 'freeze')
# filling automatically an auto_freeze variable
assert config.creole.test.autofreeze_filled is None
lib.set_value(ID_, 'test', 'fixedvariable', 'filled')
assert config.creole.test.autofreeze_filled == 'filled'
assert lib.get_variable(ID_, 'test', 'autofreeze')['editable'] == True
assert lib.get_variable(ID_, 'test', 'autofreeze_filled')['editable'] == True
assert lib.get_variable(ID_, 'test', 'autofreeze_x')['editable'] == True
_save('autofreeze')
content = load(file(_calc_config_file('autofreeze')))
# les variables auto_freeze sont enregistrées
assert content[u'autofreeze'] == {u'owner': u'gen_config', u'val': u'freeze'}
assert content[u'autofreeze_x'] == {u'owner': u'forced', u'val': None}
assert content[u'autofreeze_filled'] == {u'owner': u'forced', u'val': u'filled'}
config = _reload('autofreeze')
# passage en mode debug pour accéder à la variable hidden "module_instancie"
lib.set_debug(ID_, True)
if lib.get_variable(ID_, 'general', 'module_instancie')['value'] == 'oui':
# la variable n'est plus éditable après instance
assert lib.get_variable(ID_, 'test', 'autofreeze')['editable'] == False
assert lib.get_variable(ID_, 'test', 'autofreeze_filled')['editable'] == False
assert lib.get_variable(ID_, 'test', 'autofreeze_x')['editable'] == False
else:
# la variable est toujours éditable avant instance
assert lib.get_variable(ID_, 'test', 'autofreeze')['editable'] == True
assert lib.get_variable(ID_, 'test', 'autofreeze_filled')['editable'] == True
assert lib.get_variable(ID_, 'test', 'autofreeze_x')['editable'] == True
def test_wrong_calc():
"""
pas de traceback en cas de valeur calculée invalide
"""
config = _load('wrong_calc')
assert config.creole.test.test_value == 'FR'
assert config.creole.test.test_country_name == 'FR'
assert config.creole.test.test_country_name2 == 'FR'
lib.set_value(ID_, 'test', 'test_value', 'EU')
assert config.creole.test.test_country_name == 'EU'
assert config.creole.test.test_country_name2 == 'EU'
lib.set_value(ID_, 'test', 'test_value', 'I2')
var = lib.get_variable(ID_, 'test', 'test_country_name')
assert var['value'] is None
assert var['description'].encode('utf8') in var.get('warning', '')
assert config.creole.test.test_country_name2 == 'FR'
def test_redefine():
"""
Vérifie que redefine et remove_check font leur travail #9468
Vérifie le redefine entre fill et auto #10475
Vérifie que redefine et remove_condition font leur travail #13729
"""
config = _load('redefine')
# tests redefine et remove_check
assert config.creole.test.abc1 == 'a'
assert config.creole.test.abc2 == 'b'
assert config.creole.test.abc3 == 'b'
raises(ValueError, "lib.set_value(ID_, 'test', 'abc1', 'd')")
raises(ValueError, "lib.set_value(ID_, 'test', 'abc2', 'd')")
lib.set_value(ID_, 'test', 'abc3', 'd')
assert config.creole.test.abc3 == 'd'
# tests redefine sur fill et auto
assert config.creole.test.fill2auto == 'valeur1valeur2'
assert config.creole.test.auto2fill == 'valeur'
raises(PropertiesOptionError, "lib.set_value(ID_, 'test', 'fill2auto', 'valeur3')")
lib.set_value(ID_, 'test', 'auto2fill', 'valeur3')
assert config.creole.test.auto2fill == 'valeur3'
# tests redefine et remove_condition
raises(PropertiesOptionError, "lib.set_value(ID_, 'test', 'disabled_if', 'val')")
lib.set_value(ID_, 'test', 'disabled_if_redefine', 'val')
lib.set_value(ID_, 'test', 'enabled_if', 'val')
raises(PropertiesOptionError, "lib.set_value(ID_, 'test', 'enabled_if_redefine', 'val')")
raises(PropertiesOptionError, "lib.set_value(ID_, 'test', 'frozen_if', 'val')")
lib.set_value(ID_, 'test', 'frozen_if_redefine', 'val')
def test_check():
"""
Vérifie le fonctionnement de optional & hidden
sur les check avec des variables #9472
"""
config = _load('check')
# variable inconnue dans le check
lib.set_value(ID_, 'test', 'check_unknown', 'ok')
assert config.creole.test.check_unknown == 'ok'
# variable désactivable dans le check
lib.set_value(ID_, 'test', 'check_disabled', 'ok')
assert config.creole.test.check_disabled == 'ok'
raises(ValueError, "lib.set_value(ID_, 'test', 'check_disabled', 'sample')")
lib.set_value(ID_, 'test', 'disable', 'oui')
lib.set_value(ID_, 'test', 'check_disabled', 'sample')
assert config.creole.test.check_disabled == 'sample'
lib.set_value(ID_, 'test', 'disable', 'non')
raises(ValueError, "lib.set_value(ID_, 'test', 'check_disabled', 'sample')")
lib.set_value(ID_, 'test', 'check_disabled', 'ok')
assert config.creole.test.check_disabled == 'ok'
def test_disabled():
"""
Vérifie le fonctionnement de disabled_if_in et disabled_if_not_in
sur une même variable #18657
"""
config = _load('disabled')
assert config.creole.test.source1 == 'oui'
assert config.creole.test.source2 == 'oui'
assert config.creole.test.cible == 'oui'
lib.set_value(ID_, 'test', 'source1', 'non')
raises(PropertiesOptionError, 'config.creole.test.cible')
lib.set_value(ID_, 'test', 'source2', 'non')
raises(PropertiesOptionError, 'config.creole.test.cible')
lib.set_value(ID_, 'test', 'source1', 'oui')
raises(PropertiesOptionError, 'config.creole.test.cible')
lib.set_value(ID_, 'test', 'source2', 'oui')
assert config.creole.test.cible == 'oui'
def test_disabled_slave():
"""
Vérifie le fonctionnement de disabled_if_in entre
variables esclaves d'un même groupe de variables #17536
"""
config = _load('disabled')
lib.set_value(ID_, 'test', 'ma_master', [u'v1', u'v2'])
for idx in (0,1):
assert config.creole.test.ma_master.ma_slave1[idx] == u'oui'
assert config.creole.test.ma_master.ma_slave2[idx] is None
raises(PropertiesOptionError, 'config.creole.test.ma_master.ma_slave3[idx]')
lib.set_value(ID_, 'test', 'ma_master.ma_slave1', [u'non', u'oui'])
assert config.creole.test.ma_master.ma_slave2[1] is None
assert config.creole.test.ma_master.ma_slave3[0] is None
raises(PropertiesOptionError, 'config.creole.test.ma_master.ma_slave2[0]')
raises(PropertiesOptionError, 'config.creole.test.ma_master.ma_slave3[1]')
def test_calc_multi_val():
"""
Vérifie le fonctionnement de calc_multi_val
Ajouté pour valider #10251 mais pourra être complété
"""
config = _load('multival')
# variable non multi => None
assert config.creole.test.mail_src == None
# variable multi => []
assert config.creole.test.mail_dest == []
# désactivation de "mail_dest"
lib.set_value(ID_, 'test', 'condition', 'non')
# adresse invalide en source
lib.set_value(ID_, 'test', 'mail_src', 'badmail')
raises(PropertiesOptionError, "config.creole.test.mail_dest")
# ré-activation de "mail_dest"
lib.set_value(ID_, 'test', 'condition', 'oui')
raises(ValueError, "config.creole.test.mail_dest")
def test_mandatory_if_in():
"""
Vérifie le fonctionnement de mandatory_if_in (#15563)
"""
config = _load('mandatory')
# la condition n'est pas remplie
assert not lib.get_variable(ID_, 'test', 'mandatory_if')['mandatory']
assert not lib.get_variable(ID_, 'test', 'mandatory_ifnot')['mandatory']
_save('mandatory')
# la condition est remplie
lib.set_value(ID_, 'test', 'active_mandatory', 'oui')
assert lib.get_variable(ID_, 'test', 'mandatory_if')['mandatory']
assert lib.get_variable(ID_, 'test', 'mandatory_ifnot')['mandatory']
raises(PropertiesOptionError, "_save('mandatory')")
def test_bad_ips():
"""
Vérifie l'impossibilité de saisir des adresse invalides
(#11480 et #12858)
"""
config = _load('badips')
# moins de 3 éléments
raises(ValueError, "lib.set_value(ID_, 'test', 'adresse_ip', '1.1')")
raises(ValueError, "lib.set_value(ID_, 'test', 'adresse_network', '1.1')")
raises(ValueError, "lib.set_value(ID_, 'test', 'adresse_netmask', '255.255.255')")
# doubles zéros
raises(ValueError, "lib.set_value(ID_, 'test', 'adresse_ip', '1.1.1.00')")
raises(ValueError, "lib.set_value(ID_, 'test', 'adresse_network', '1.1.1.00')")
raises(ValueError, "lib.set_value(ID_, 'test', 'adresse_netmask', '255.255.255.00')")
def test_warning():
"""
Vérifie l'affichage et la disparition des warnings (#15796)
"""
if not isdir(eoleroot):
return
# utilisation des dictionnaires du module
lib.del_config(ID_)
lib.get_config(ID_)
lib.set_value(ID_, 'interface_0', 'adresse_ip_gw', '192.168.0.1')
# pas de warning au départ
assert lib.get_variable(ID_, 'interface_0', 'adresse_netmask_eth0')['warning'] == ''
lib.set_value(ID_, 'interface_0', 'adresse_ip_eth0', '192.168.20.240')
# warning parce que la gateway n'est pas dans le bon réseau
assert len(lib.get_variable(ID_, 'interface_0', 'adresse_netmask_eth0')['warning']) != ''
lib.set_value(ID_, 'interface_0', 'adresse_netmask_eth0', '255.255.255.128')
# warning parce que la gateway n'est (toujours) pas dans le bon réseau
assert len(lib.get_variable(ID_, 'interface_0', 'adresse_netmask_eth0')['warning']) != ''
lib.set_value(ID_, 'interface_0', 'adresse_netmask_eth0', '255.255.255.128')
lib.set_value(ID_, 'interface_0', 'adresse_ip_gw', '192.168.20.254')
# plus d'erreur mais le warning est conservé en cache (spécifique gen_config)
assert lib.get_variable(ID_, 'interface_0', 'adresse_netmask_eth0')['warning'] != ''
assert lib.get_variable(ID_, 'interface_0', 'adresse_netmask_eth0')['warning'] == ''
def test_types():
"""
Vérifie que la validation de certains types est bien fonctionnelle (#16831)
"""
config = _load('types')
# nom de domaine "souple"
lib.set_value(ID_, 'test', 'domaine', 'domaine.lan')
lib.set_value(ID_, 'test', 'domaine', 'sanspoint')
lib.set_value(ID_, 'test', 'domaine', '1.1.1.1')
raises(ValueError, "lib.set_value(ID_, 'test', 'domaine', '.lan')")
# nom de domaine "strict"
lib.set_value(ID_, 'test', 'domaine_strict', 'domaine.lan')
raises(ValueError, "lib.set_value(ID_, 'test', 'domaine_strict', 'sanspoint')")
raises(ValueError, "lib.set_value(ID_, 'test', 'domaine_strict', '1.1.1.1')")
raises(ValueError, "lib.set_value(ID_, 'test', 'domaine_strict', '.lan')")
# nom d'hôte "souple"
lib.set_value(ID_, 'test', 'nom_hote', 'toto')
lib.set_value(ID_, 'test', 'nom_hote', '1.1.1.1')
raises(ValueError, "lib.set_value(ID_, 'test', 'nom_hote', 'domaine.lan')")
# nom d'hôte "strict"
lib.set_value(ID_, 'test', 'nom_hote_strict', 'toto')
raises(ValueError, "lib.set_value(ID_, 'test', 'nom_hote_strict', '1.1.1.1')")
raises(ValueError, "lib.set_value(ID_, 'test', 'nom_hote_strict', 'domaine.lan')")