rougail-user-data-environment/tests/test_load.py

256 lines
9.3 KiB
Python
Raw Normal View History

2024-10-01 17:51:34 +02:00
import os
2025-10-29 11:16:37 +01:00
from pytest import fixture, raises
2024-09-30 16:40:24 +02:00
from pathlib import Path
2025-10-29 11:16:37 +01:00
from rougail import Rougail, RougailConfig
2024-12-09 10:13:44 +01:00
#########################
2024-09-24 16:42:03 +02:00
from dotenv import load_dotenv
2024-12-09 10:13:44 +01:00
from rougail.user_data_environment import RougailUserDataEnvironment as RougailUserData
from json import load, dump
#########################
2024-09-18 11:43:22 +02:00
2024-12-09 10:13:44 +01:00
from rougail_tests.utils import get_structures_list, get_rougail_config, get_values_for_config, config_to_dict
2024-09-18 11:43:22 +02:00
2024-12-09 10:13:44 +01:00
EXT = "env"
2024-09-30 16:40:24 +02:00
2024-12-09 10:13:44 +01:00
#########################
2024-10-01 15:33:30 +02:00
#let's save the original environment
2024-10-01 17:51:34 +02:00
save = os.environ.copy()
2024-12-09 10:13:44 +01:00
#########################
2024-10-01 15:33:30 +02:00
2024-09-18 11:43:22 +02:00
2025-10-29 11:16:37 +01:00
excludes = ["60_0family_dynamic_source_hidden"]
2024-11-23 11:08:24 +01:00
2024-12-09 10:13:44 +01:00
test_ok = get_structures_list(excludes)
2025-11-05 21:36:41 +01:00
# test_ok = [Path('../rougail-tests/structures/60_0family_dynamic_1_0_empty')]
2024-10-01 11:57:38 +02:00
2024-12-09 10:13:44 +01:00
def idfn(fixture_value):
return fixture_value.name
2024-10-01 11:57:38 +02:00
2024-12-09 10:13:44 +01:00
@fixture(scope="module", params=test_ok, ids=idfn)
2024-09-18 11:43:22 +02:00
def test_dir(request):
return request.param
2025-09-22 14:18:35 +02:00
def _test_structural_files(test_dir, namespace, ext, *, level, need_exclude=False):
2024-12-09 10:13:44 +01:00
rougailconfig = get_rougail_config(test_dir, namespace)
if not rougailconfig:
return
2025-05-11 19:10:02 +02:00
# rougailconfig['tiramisu_cache'] = "cache.py"
2024-12-09 10:13:44 +01:00
##################################
2024-09-24 16:42:03 +02:00
rougailconfig['step.user_data'] = ['environment']
2025-10-29 11:16:37 +01:00
rougailconfig['environment.custom_separator'] = 'o'
2024-12-09 10:13:44 +01:00
##################################
dir_name = 'test'
if namespace:
dir_name += '_namespace'
elif (test_dir / 'force_namespace').is_file():
return
2024-11-23 11:08:24 +01:00
rougail = Rougail(rougailconfig)
config = rougail.run()
2024-12-09 10:13:44 +01:00
##################################
2024-12-16 17:23:34 +01:00
root_path = Path('tests') / 'results' / dir_name / test_dir.name
2025-10-10 08:01:45 +02:00
makedict = root_path / 'makedict' / f'{level}.json'
filename = root_path / 'file'
2024-11-23 11:08:24 +01:00
if need_exclude:
2024-12-09 10:13:44 +01:00
filename = filename / f'{level}_exclude.{EXT}'
2024-11-23 11:08:24 +01:00
else:
2024-12-09 10:13:44 +01:00
filename = filename / f'{level}.{EXT}'
2025-04-26 09:21:46 +02:00
try:
populate(filename, makedict, rougailconfig, level, need_exclude, namespace)
except SubMulti:
return
2024-11-23 11:08:24 +01:00
load_dotenv(str(filename))
2024-12-09 10:13:44 +01:00
##################################
2024-11-23 11:08:24 +01:00
# loads variables in the tiramisu config
2024-12-09 10:13:44 +01:00
generated_user_data = RougailUserData(config, rougailconfig=rougailconfig).run()
errors = rougail.user_datas(generated_user_data)
2024-10-01 17:51:34 +02:00
#expected output
2025-10-10 08:01:45 +02:00
expected_filename = Path('tests') / 'results' / dir_name / test_dir.name / 'makedict' / f'{level}.json'
with expected_filename.open() as json_file:
2024-10-01 12:03:52 +02:00
expected = load(json_file)
2024-10-01 12:13:30 +02:00
# here is the effective test
2024-12-16 17:23:34 +01:00
errors_file = Path('tests') / 'results' / dir_name / test_dir.name / 'errors' / f'{level}.json'
2024-11-23 11:08:24 +01:00
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)
2024-12-09 10:13:44 +01:00
# expected_errors = {
# 'errors': [],
# 'warnings': [],
# }
2025-05-11 19:10:02 +02:00
assert expected_errors == errors, errors_file
2024-11-23 11:08:24 +01:00
#
config.property.read_only()
2024-12-09 10:13:44 +01:00
config_dict = dict(config_to_dict(config.value.get()))
2025-10-10 08:01:45 +02:00
assert expected == config_dict, expected_filename
2024-12-16 17:23:34 +01:00
######################################
2025-10-29 11:16:37 +01:00
#teardown: set the original environment again
2024-10-01 17:51:34 +02:00
os.environ = save.copy()
2024-12-16 17:23:34 +01:00
######################################
2024-09-30 14:13:42 +02:00
2024-12-16 17:23:34 +01:00
def populate(filename, makedict_file, rougailconfig, level, need_exclude, namespace):
2024-12-09 10:13:44 +01:00
if filename.is_file() and makedict_file.is_file():
return
config = Rougail(rougailconfig).run()
values = get_values_for_config(config, not need_exclude, level)
2024-11-23 11:08:24 +01:00
if not filename.is_file():
filename.parent.mkdir(parents=True, exist_ok=True)
2025-04-26 09:21:46 +02:00
##############################################
2025-10-29 11:16:37 +01:00
val = values_to_env(values, namespace)
for idx, v in enumerate(val):
if idx / 2 != int(idx / 2):
a, b = v.split('=')
val[idx] = a.replace('.', 'o') + "=" + b
2025-04-26 09:21:46 +02:00
##############################################
2024-11-23 11:08:24 +01:00
with filename.open('w') as fh:
2024-12-16 17:23:34 +01:00
##############################################
2025-10-29 11:16:37 +01:00
fh.write('\n'.join(val) + '\n')
2024-12-16 17:23:34 +01:00
##############################################
2024-11-23 11:08:24 +01:00
if not makedict_file.is_file():
2024-10-01 11:57:38 +02:00
makedict_file.parent.mkdir(parents=True, exist_ok=True)
2024-11-23 11:08:24 +01:00
config.property.read_only()
2024-12-09 10:13:44 +01:00
config_dict = dict(config_to_dict(config.value.get()))
2024-11-23 11:08:24 +01:00
with makedict_file.open('w') as fh:
dump(config_dict, fh, indent=4)
fh.write('\n')
2025-04-26 09:21:46 +02:00
class SubMulti(Exception):
pass
2024-12-16 17:23:34 +01:00
##############################################
def values_to_env(values, namespace):
2024-11-23 11:08:24 +01:00
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):
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:
2024-12-09 10:13:44 +01:00
for val in value:
sub_val = val.get(k, "")
if isinstance(sub_val, list):
2025-04-26 09:21:46 +02:00
raise SubMulti("submulti is not allowed for environment user_datas")
2024-12-16 17:23:34 +01:00
ns = (sub_root_path + '.' + k).upper()
if not namespace:
ns = "ROUGAIL_" + ns
yield ns + '="' + ','.join([convert_str(val.get(k, "")) for val in value])+ '"'
2024-11-23 11:08:24 +01:00
else:
2024-12-16 17:23:34 +01:00
ns = sub_root_path.upper()
if not namespace:
ns = "ROUGAIL_" + ns
yield ns + '="' + ','.join([convert_str(val) for val in value]) + '"'
2024-12-09 10:13:44 +01:00
elif value is None or value == 'None':
2024-12-16 17:23:34 +01:00
ns = sub_root_path.upper()
if not namespace:
ns = "ROUGAIL_" + ns
yield ns + '=""'
2024-09-30 14:13:42 +02:00
else:
2024-12-16 17:23:34 +01:00
ns = sub_root_path.upper()
if not namespace:
ns = "ROUGAIL_" + ns
yield ns + '="' + str(value) + '"'
2024-11-23 11:08:24 +01:00
return list(parse(None, values))
def convert_str(val):
if isinstance(val, bool):
return {True: 'true', False: 'false'}.get(val)
2024-12-09 10:13:44 +01:00
if val is None:
return ""
2024-11-23 11:08:24 +01:00
return str(val)
2024-12-16 17:23:34 +01:00
##############################################
2024-11-23 11:08:24 +01:00
2025-09-22 14:18:35 +02:00
def test_structural_files_all(test_dir):
2024-12-09 10:13:44 +01:00
"tests the output"
2025-09-22 14:18:35 +02:00
_test_structural_files(test_dir, False, EXT, level='all')
2024-09-30 14:13:42 +02:00
2025-09-22 14:18:35 +02:00
def test_structural_files_all_exclude(test_dir):
2024-12-09 10:13:44 +01:00
"tests the output"
2025-09-22 14:18:35 +02:00
_test_structural_files(test_dir, False, EXT, level='all', need_exclude=True)
2024-09-30 14:13:42 +02:00
2025-09-22 14:18:35 +02:00
def test_structural_files_mandatories(test_dir):
2024-12-16 17:23:34 +01:00
"tests the output"
2025-09-22 14:18:35 +02:00
_test_structural_files(test_dir, False, EXT, level='mandatories')
2024-12-16 17:23:34 +01:00
2025-09-22 14:18:35 +02:00
def test_structural_files_namespace_all(test_dir):
2024-12-16 17:23:34 +01:00
"tests the output"
2025-09-22 14:18:35 +02:00
_test_structural_files(test_dir, True, EXT, level='all')
2024-12-16 17:23:34 +01:00
2025-09-22 14:18:35 +02:00
def test_structural_files_namespace_all_exclude(test_dir):
2024-12-16 17:23:34 +01:00
"tests the output"
2025-09-22 14:18:35 +02:00
_test_structural_files(test_dir, True, EXT, level='all', need_exclude=True)
2024-12-16 17:23:34 +01:00
2025-09-22 14:18:35 +02:00
def test_structural_files_namespace_mandatories(test_dir):
2024-12-09 10:13:44 +01:00
"tests the output"
2025-09-22 14:18:35 +02:00
_test_structural_files(test_dir, True, EXT, level='mandatories')
2025-05-11 19:10:02 +02:00
#######################################################################
error_env = list((Path(__file__).parent / 'errors' / 'environment').glob("*.env"))
error_env.sort()
@fixture(scope="module", params=error_env, ids=idfn)
def test_file_error(request):
return request.param
2025-09-22 14:18:35 +02:00
def test_structural_files_error(test_file_error):
2025-05-11 19:10:02 +02:00
rougailconfig = get_rougail_config(test_file_error.parent.parent / 'structure')
##################################
rougailconfig['step.user_data'] = ['environment']
rougail = Rougail(rougailconfig)
config = rougail.run()
load_dotenv(str(test_file_error))
##################################
# loads variables in the tiramisu config
generated_user_data = RougailUserData(config, rougailconfig=rougailconfig).run()
errors = rougail.user_datas(generated_user_data)
errors_file = test_file_error.parent.parent / "results" / test_file_error.name
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)
######################################
2025-10-29 11:16:37 +01:00
#teardown: set the original environment again
2025-05-11 19:10:02 +02:00
os.environ = save.copy()
######################################
assert expected_errors == errors, errors_file
2025-10-29 11:16:37 +01:00
def test_environment_name():
rougailconfig = RougailConfig.copy()
rougailconfig["main_namespace"] = None
rougailconfig['step.user_data'] = ['environment']
assert rougailconfig["environment.default_environment_name"] == "ROUGAIL"
with raises(ValueError):
rougailconfig["environment.default_environment_name"] = "lower"
with raises(ValueError):
rougailconfig["environment.default_environment_name"] = "LOWEr"
rougailconfig["environment.default_environment_name"] = "UPPER"