2024-12-02 20:22:27 +01:00
from pytest import fixture # , raises
from pathlib import Path
2025-07-04 06:43:31 +02:00
from yaml import safe_load
2024-12-02 20:22:27 +01:00
from rougail import Rougail
from rougail . output_ansible import RougailOutputAnsible as RougailOutput
2025-07-04 06:43:31 +02:00
from rougail . user_data_yaml import RougailUserDataYaml
2024-12-02 20:22:27 +01:00
from rougail_tests . utils import get_structures_list , get_rougail_config , get_values_for_config
EXT = ' json '
2026-01-21 08:55:24 +01:00
excludes = [
# '04_5disabled_calculation_variable11',
2024-12-02 20:22:27 +01:00
# '60_5family_dynamic_variable_outside_sub_suffix',
2026-01-21 08:55:24 +01:00
]
2024-12-02 20:22:27 +01:00
test_ok = get_structures_list ( excludes )
2025-12-29 19:29:11 +01:00
# test_ok = [Path('../rougail-tests/structures/40_0leadership')]
2024-12-02 20:22:27 +01:00
def idfn ( fixture_value ) :
return fixture_value . name
@fixture ( scope = " module " , params = test_ok , ids = idfn )
def test_dir ( request ) :
return request . param
2025-09-22 14:29:45 +02:00
def _test_structural_files ( test_dir , namespace , ext , * , read_write = True , mandatory = False , do_calc = True ) :
2026-01-14 14:25:35 +01:00
for output in [ ' inventory ' , ' doc ' ] :
rougailconfig = get_rougail_config ( test_dir , namespace )
if not rougailconfig :
continue
##################################
rougailconfig [ ' step.output ' ] = ' ansible '
rougailconfig [ " json.mandatory " ] = mandatory
if output == ' inventory ' :
extra_namespaces = rougailconfig [ " extra_namespaces " ]
extra_namespaces [ " hosts " ] = [ str ( Path ( __file__ ) . parent / " hosts " ) ]
rougailconfig [ ' extra_namespaces ' ] = extra_namespaces
##################################
dir_name = ' test '
if namespace :
dir_name + = ' _namespace '
elif ( test_dir / ' force_namespace ' ) . is_file ( ) :
return
##################################
if read_write :
dir_name + = ' _read_write '
2025-04-21 21:23:58 +02:00
if mandatory :
2026-01-14 14:25:35 +01:00
dir_name + = ' _mandatory '
if not do_calc :
dir_name + = ' _errors '
##################################
rougail = Rougail ( rougailconfig )
config = rougail . run ( )
config . information . set ( " description_type " , " path_and_description " )
##################################
if do_calc and ( mandatory or not read_write ) :
if mandatory :
get_values_for_config ( config , exclude_namespace = " hosts " )
else :
get_values_for_config ( config , level = " mandatories " , exclude_namespace = " hosts " )
##################################
if read_write :
config . property . read_write ( )
2025-04-21 21:23:58 +02:00
else :
2026-01-14 14:25:35 +01:00
config . property . read_only ( )
if output == ' inventory ' :
dirname = ' results '
else :
subconfig = config . list ( )
if len ( subconfig ) != 1 or not subconfig [ 0 ] . isoptiondescription ( ) :
continue
dirname = ' results-doc '
ext = ' sh '
rougailconfig [ ' ansible.output ' ] = output
generated_output = RougailOutput ( config , rougailconfig = rougailconfig ) . run ( ) [ 1 ]
output_file = Path ( __file__ ) . parent / dirname / dir_name / ( test_dir . name + " . " + ext )
if not output_file . is_file ( ) :
if not output_file . parent . is_dir ( ) :
output_file . parent . mkdir ( parents = True )
with output_file . open ( ' w ' ) as outfh :
outfh . write ( generated_output )
with output_file . open ( ) as outfh :
attented_output = outfh . read ( )
assert generated_output == attented_output , f ' filename { output_file } '
2024-12-02 20:22:27 +01:00
# do not test without namespace, ansible needs namespaces
2025-09-22 14:29:45 +02:00
def test_structural_files_ansible_namespace ( test_dir ) :
_test_structural_files ( test_dir , True , EXT )
2024-12-02 20:22:27 +01:00
2025-09-22 14:29:45 +02:00
def test_structural_files_ansible_namespace_errors ( test_dir ) :
_test_structural_files ( test_dir , True , EXT , do_calc = False , mandatory = True )
2024-12-02 20:22:27 +01:00
2025-09-22 14:29:45 +02:00
def test_structural_files_ansible_namespace_read_only ( test_dir ) :
_test_structural_files ( test_dir , True , EXT , read_write = False )
2024-12-02 20:22:27 +01:00
2025-09-22 14:29:45 +02:00
def test_structural_files_ansible_namespace_mandatory ( test_dir ) :
_test_structural_files ( test_dir , True , EXT , mandatory = True )
2024-12-02 20:22:27 +01:00
2025-09-22 14:29:45 +02:00
def test_structural_files_ansible_namespace_mandatory_read_only ( test_dir ) :
_test_structural_files ( test_dir , True , EXT , read_write = False , mandatory = True )
2025-07-04 06:43:31 +02:00
def test_warnings ( ) :
rougailconfig = get_rougail_config ( Path ( ' tests/warnings/structures ' ) , True )
##################################
rougailconfig [ ' step.output ' ] = ' ansible '
rougailconfig [ ' step.user_data ' ] = [ ' yaml ' ]
rougailconfig [ ' yaml.filename ' ] = [ ' tests/warnings/yaml/config.yml ' ]
2025-09-22 14:29:45 +02:00
extra_namespaces = rougailconfig [ " extra_namespaces " ]
extra_namespaces [ " hosts " ] = [ str ( Path ( __file__ ) . parent / " hosts " ) ]
rougailconfig [ ' extra_namespaces ' ] = extra_namespaces
2025-07-04 06:43:31 +02:00
##################################
rougail = Rougail ( rougailconfig )
config = rougail . run ( )
generated_user_data = RougailUserDataYaml ( config , rougailconfig = rougailconfig ) . run ( )
2025-12-29 19:29:11 +01:00
err_warn = rougail . user_data ( generated_user_data )
2025-07-04 06:43:31 +02:00
output = RougailOutput (
config = config ,
rougailconfig = rougailconfig ,
user_data_errors = err_warn [ " errors " ] ,
user_data_warnings = err_warn [ " warnings " ] ,
)
ret = output . run ( )
assert ret [ 0 ] is True
assert safe_load ( ret [ 1 ] ) == {
" _meta " : {
" hostvars " : {
" localhost " : {
" _warnings " : [
2026-01-21 08:55:24 +01:00
" rougail: variable or family \" an_unknown_var \" does not exist so cannot load \" rougail.an_unknown_var \" , it will be ignored when loading from the YAML file \" tests/warnings/yaml/config.yml \" "
2025-07-04 06:43:31 +02:00
]
} ,
" GROUP1_01 " : {
" ansible_host " : " group1.net " ,
" rougail " : {
" a_var " : " a_value "
}
} ,
" GROUP2_01 " : {
" ansible_host " : " group2.net " ,
2025-09-10 17:42:09 +02:00
' rougail ' : {
' a_var ' : ' a_value ' ,
} ,
} ,
' GROUP2_02 ' : {
' ansible_host ' : ' group3.net ' ,
' rougail ' : {
' a_var ' : ' a_value ' ,
} ,
} ,
' group4.net ' : {
' ansible_host ' : ' group4.net ' ,
' rougail ' : {
' a_var ' : ' a_value ' ,
} ,
} ,
' group5.net ' : {
' ansible_host ' : ' group5.net ' ,
2025-07-04 06:43:31 +02:00
" rougail " : {
" a_var " : " a_value "
}
}
}
} ,
" ungrouped " : {
" hosts " : [
" localhost "
]
} ,
" group1 " : {
" hosts " : [
" GROUP1_01 "
]
} ,
" group2 " : {
" hosts " : [
2025-09-10 17:42:09 +02:00
" GROUP2_01 " ,
' GROUP2_02 '
2025-07-04 06:43:31 +02:00
]
} ,
2025-09-10 17:42:09 +02:00
' group3 ' : {
' hosts ' : [
' group4.net ' ,
' group5.net ' ,
]
} ,
2025-07-04 06:43:31 +02:00
" groups " : {
" children " : [
" group1 " ,
" group2 "
]
}
}
def test_no_warnings ( ) :
rougailconfig = get_rougail_config ( Path ( ' tests/warnings/structures ' ) , True )
##################################
rougailconfig [ ' step.output ' ] = ' ansible '
2026-01-14 14:25:35 +01:00
rougailconfig [ ' ansible.inventory.export_warnings ' ] = False
2025-07-04 06:43:31 +02:00
rougailconfig [ ' step.user_data ' ] = [ ' yaml ' ]
rougailconfig [ ' yaml.filename ' ] = [ ' tests/warnings/yaml/config.yml ' ]
2025-09-22 14:29:45 +02:00
extra_namespaces = rougailconfig [ " extra_namespaces " ]
extra_namespaces [ " hosts " ] = [ str ( Path ( __file__ ) . parent / " hosts " ) ]
rougailconfig [ ' extra_namespaces ' ] = extra_namespaces
2025-07-04 06:43:31 +02:00
##################################
rougail = Rougail ( rougailconfig )
config = rougail . run ( )
generated_user_data = RougailUserDataYaml ( config , rougailconfig = rougailconfig ) . run ( )
2025-12-29 19:29:11 +01:00
err_warn = rougail . user_data ( generated_user_data )
2025-07-04 06:43:31 +02:00
output = RougailOutput (
config = config ,
rougailconfig = rougailconfig ,
user_data_errors = err_warn [ " errors " ] ,
user_data_warnings = err_warn [ " warnings " ] ,
)
ret = output . run ( )
assert ret [ 0 ] is True
assert safe_load ( ret [ 1 ] ) == {
2026-01-09 08:46:16 +01:00
" _meta " : {
" hostvars " : {
" GROUP1_01 " : {
" ansible_host " : " group1.net " ,
" rougail " : {
" a_var " : " a_value "
}
} ,
" GROUP2_01 " : {
" ansible_host " : " group2.net " ,
' rougail ' : {
' a_var ' : ' a_value ' ,
} ,
} ,
' GROUP2_02 ' : {
' ansible_host ' : ' group3.net ' ,
' rougail ' : {
' a_var ' : ' a_value ' ,
} ,
} ,
' group4.net ' : {
' ansible_host ' : ' group4.net ' ,
' rougail ' : {
' a_var ' : ' a_value ' ,
} ,
} ,
' group5.net ' : {
' ansible_host ' : ' group5.net ' ,
" rougail " : {
" a_var " : " a_value "
}
}
}
} ,
' group1 ' : {
' hosts ' : [
' GROUP1_01 ' ,
] ,
} ,
' group2 ' : {
' hosts ' : [
' GROUP2_01 ' ,
' GROUP2_02 ' ,
] ,
} ,
' group3 ' : {
' hosts ' : [
' group4.net ' ,
' group5.net ' ,
] ,
} ,
' groups ' : {
' children ' : [
' group1 ' ,
' group2 ' ,
] ,
}
}
def test_host_with_vars ( ) :
rougailconfig = get_rougail_config ( Path ( ' tests/warnings/structures ' ) , True )
##################################
rougailconfig [ ' step.output ' ] = ' ansible '
2026-01-14 14:25:35 +01:00
rougailconfig [ ' ansible.inventory.export_warnings ' ] = False
2026-01-09 08:46:16 +01:00
rougailconfig [ ' step.user_data ' ] = [ ' yaml ' ]
rougailconfig [ ' yaml.filename ' ] = [ ' tests/warnings/yaml/config.yml ' ]
extra_namespaces = rougailconfig [ " extra_namespaces " ]
extra_namespaces [ " hosts " ] = [ str ( Path ( __file__ ) . parent / " hosts-with-vars " ) ]
rougailconfig [ ' extra_namespaces ' ] = extra_namespaces
##################################
rougail = Rougail ( rougailconfig )
config = rougail . run ( )
generated_user_data = RougailUserDataYaml ( config , rougailconfig = rougailconfig ) . run ( )
err_warn = rougail . user_data ( generated_user_data )
output = RougailOutput (
config = config ,
rougailconfig = rougailconfig ,
user_data_errors = err_warn [ " errors " ] ,
user_data_warnings = err_warn [ " warnings " ] ,
)
ret = output . run ( )
assert ret [ 0 ] is True
assert safe_load ( ret [ 1 ] ) == {
2025-07-04 06:43:31 +02:00
" _meta " : {
" hostvars " : {
" GROUP1_01 " : {
" ansible_host " : " group1.net " ,
" rougail " : {
" a_var " : " a_value "
}
} ,
" GROUP2_01 " : {
2026-01-10 17:04:47 +01:00
' a_family ' : {
' with_a_variable ' : 1 ,
} ,
' added_var1 ' : True ,
' added_var2 ' : True ,
2025-07-04 06:43:31 +02:00
" ansible_host " : " group2.net " ,
2025-09-10 17:42:09 +02:00
' rougail ' : {
' a_var ' : ' a_value ' ,
} ,
} ,
' GROUP2_02 ' : {
2026-01-10 17:04:47 +01:00
' a_family ' : {
' with_a_variable ' : 1 ,
} ,
' added_var1 ' : True ,
2025-09-10 17:42:09 +02:00
' ansible_host ' : ' group3.net ' ,
' rougail ' : {
' a_var ' : ' a_value ' ,
} ,
} ,
' group4.net ' : {
' ansible_host ' : ' group4.net ' ,
' rougail ' : {
' a_var ' : ' a_value ' ,
} ,
} ,
' group5.net ' : {
' ansible_host ' : ' group5.net ' ,
2025-07-04 06:43:31 +02:00
" rougail " : {
" a_var " : " a_value "
}
}
}
} ,
2025-09-10 17:42:09 +02:00
' group1 ' : {
' hosts ' : [
' GROUP1_01 ' ,
] ,
2025-07-04 06:43:31 +02:00
} ,
2025-09-10 17:42:09 +02:00
' group2 ' : {
' hosts ' : [
' GROUP2_01 ' ,
' GROUP2_02 ' ,
] ,
2025-07-04 06:43:31 +02:00
} ,
2025-09-10 17:42:09 +02:00
' group3 ' : {
' hosts ' : [
' group4.net ' ,
' group5.net ' ,
] ,
2025-07-04 06:43:31 +02:00
} ,
2025-09-10 17:42:09 +02:00
' groups ' : {
' children ' : [
' group1 ' ,
' group2 ' ,
] ,
2025-07-04 06:43:31 +02:00
}
}