rougail-user-data-commandline/tests/test_load.py
2025-10-07 20:54:52 +02:00

204 lines
7.7 KiB
Python

import os
from pytest import fixture # , raises
from pathlib import Path
from rougail import Rougail
#########################
from rougail.user_data_commandline import RougailUserDataCommandline as RougailUserData
from json import load, dump, loads, dumps
#########################
from rougail_tests.utils import get_structures_list, get_rougail_config, get_values_for_config, config_to_dict
EXT = "cmdline_opts"
excludes = [
'60_5family_dynamic_unknown_suffix', # needs to load all option before load data
]
test_ok = get_structures_list(excludes)
# test_ok = [Path('../rougail-tests/structures/60_5family_dynamic_unknown_suffix')]
def idfn(fixture_value):
return fixture_value.name
@fixture(scope="module", params=test_ok, ids=idfn)
def test_dir(request):
return request.param
def _test_structural_files(test_dir, namespace, ext, *, level, need_exclude=False):
rougailconfig = get_rougail_config(test_dir, namespace)
if not rougailconfig:
return
# rougailconfig['tiramisu_cache'] = "cache.py"
##################################
rougailconfig['step.user_data'] = ['commandline']
##################################
dir_name = 'test'
if namespace:
dir_name += '_namespace'
elif (test_dir / 'force_namespace').is_file():
return
rougail = Rougail(rougailconfig)
config = rougail.run()
##################################
root_path = Path('tests') / 'results' / dir_name / test_dir.name
makedict = root_path / 'makedict' / f'{level}.json'
filename = root_path / 'file'
if need_exclude:
filename = filename / f'{level}_exclude.{EXT}'
else:
filename = filename / f'{level}.{EXT}'
try:
populate(filename, makedict, rougailconfig, level, need_exclude, namespace)
except SubMulti:
return
with filename.open() as file_content:
arguments = load(file_content)
print('arguments', arguments, type(arguments))
##################################
# loads variables in the tiramisu config
generated_user_data = RougailUserData(config, rougailconfig=rougailconfig, arguments=arguments, prog="test_load").run()
print(generated_user_data)
errors = rougail.user_datas(generated_user_data)
#expected output
expected_filename = Path('tests') / 'results' / dir_name / test_dir.name / 'makedict' / f'{level}.json'
with expected_filename.open() as json_file:
expected = load(json_file)
# here is the effective test
errors_file = Path('tests') / 'results' / dir_name / test_dir.name / 'errors' / f'{level}.json'
if need_exclude:
errors = loads(dumps(errors).replace('all_exclude.yml', 'all.yml'))
if not errors_file.is_file():
errors_file.parent.mkdir(parents=True, exist_ok=True)
with open(errors_file, 'a') as json_file:
dump(errors, json_file, indent=4)
with open(errors_file) as json_file:
expected_errors = load(json_file)
# expected_errors = {
# 'errors': [],
# 'warnings': [],
# }
assert expected_errors == errors, errors_file
#
config.property.read_only()
config_dict = dict(config_to_dict(config.value.get()))
assert expected == config_dict, expected_filename
def populate(filename, makedict_file, rougailconfig, level, need_exclude, namespace):
if filename.is_file() and makedict_file.is_file():
return
config = Rougail(rougailconfig).run()
values = get_values_for_config(config, not need_exclude, level, follower_with_index=True)
print(filename)
if not filename.is_file():
filename.parent.mkdir(parents=True, exist_ok=True)
##############################################
v = values_to_commandline(values)
print('========================')
print('========================')
print('========================')
print(v)
print('========================')
##############################################
with filename.open('w') as fh:
##############################################
dump(v, fh, indent=4)
##############################################
if not makedict_file.is_file():
makedict_file.parent.mkdir(parents=True, exist_ok=True)
config.property.read_only()
config_dict = dict(config_to_dict(config.value.get()))
with makedict_file.open('w') as fh:
dump(config_dict, fh, indent=4)
fh.write('\n')
class SubMulti(Exception):
pass
##############################################
def values_to_commandline(values):
print(values)
def parse(root_path, values_, level=-1):
level += 1
for key, value in values_.items():
if level == 0:
sub_root_path = key
else:
sub_root_path = root_path + '.' + key
if isinstance(value, dict):
yield from parse(sub_root_path, value, level)
elif isinstance(value, list):
print("+++++++++++++++++++++", sub_root_path, value)
if value and isinstance(value[0], dict):
keys = []
for ls in value:
for k in ls:
if k not in keys:
keys.append(k)
for k in keys:
leader_values = []
for val in value:
sub_val = val.get(k, "")
if not isinstance(sub_val, tuple):
# it's a leader
leader_values.append(sub_val)
if isinstance(sub_val, list) or (isinstance(sub_val, tuple) and isinstance(sub_val[1], list)):
raise SubMulti("submulti is not allowed for environment user_datas")
if leader_values:
yield "--" + (sub_root_path + '.' + k)
for val in value:
yield convert_str(val.get(k, ""))
for idx, val in enumerate(value):
val = val.get(k, "")
if isinstance(val, tuple):
# it's a follower
yield "--" + (sub_root_path + '.' + k)
yield str(val[0])
yield convert_str(val[1])
else:
yield "--" + sub_root_path
for val in value:
yield convert_str(val)
elif value is None or value == 'None':
yield "--" + sub_root_path
# yield ""
elif isinstance(value, bool):
if value:
yield "--" + sub_root_path
else:
yield "--" + sub_root_path.rsplit(".", 1)[0] + '.no-' + sub_root_path.rsplit(".", 1)[-1]
else:
yield "--" + sub_root_path
yield convert_str(value)
return list(parse(None, values))
def convert_str(val):
if isinstance(val, bool):
return {True: 'true', False: 'false'}.get(val)
if val is None:
return ""
return str(val)
##############################################
def test_structural_files_all(test_dir):
"tests the output"
_test_structural_files(test_dir, True, EXT, level='all')
#
#
#def test_structural_files_all_exclude(test_dir):
# "tests the output"
# _test_structural_files(test_dir, True, EXT, level='all', need_exclude=True)
def test_structural_files_mandatories(test_dir):
"tests the output"
_test_structural_files(test_dir, True, EXT, level='mandatories')