mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-08-29 23:08:06 +02:00
Fail safed more parts of the code
This commit is contained in:
@@ -1,51 +1,74 @@
|
||||
import os
|
||||
import unittest
|
||||
import yaml
|
||||
import glob
|
||||
import yaml
|
||||
import warnings
|
||||
import unittest
|
||||
|
||||
class TestApplicationIdMatchesRoleName(unittest.TestCase):
|
||||
def test_application_id_matches_role_directory(self):
|
||||
"""
|
||||
Warn if application_id in vars/main.yml does not match
|
||||
the role directory basename, to avoid confusion.
|
||||
If vars/main.yml is missing, do nothing.
|
||||
"""
|
||||
# locate the 'roles' directory (two levels up)
|
||||
# import your filters
|
||||
from filter_plugins.invokable_paths import get_invokable_paths, get_non_invokable_paths
|
||||
|
||||
class TestApplicationIdAndInvocability(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
# locate roles dir (two levels up)
|
||||
base_dir = os.path.dirname(__file__)
|
||||
roles_dir = os.path.abspath(os.path.join(base_dir, '..', '..', 'roles'))
|
||||
cls.roles_dir = os.path.abspath(os.path.join(base_dir, '..', '..', 'roles'))
|
||||
|
||||
# iterate over each role folder
|
||||
for role_path in glob.glob(os.path.join(roles_dir, '*')):
|
||||
# get lists of invokable and non-invokable role *names*
|
||||
# filters return dash-joined paths; for top-level roles names are just the basename
|
||||
cls.invokable = {
|
||||
p.split('-', 1)[0]
|
||||
for p in get_invokable_paths()
|
||||
}
|
||||
cls.non_invokable = {
|
||||
p.split('-', 1)[0]
|
||||
for p in get_non_invokable_paths()
|
||||
}
|
||||
|
||||
def test_application_id_presence_and_match(self):
|
||||
"""
|
||||
- Invokable roles must have application_id defined (else fail).
|
||||
- Non-invokable roles must NOT have application_id (else fail).
|
||||
- If application_id exists but != folder name, warn and recommend aligning.
|
||||
"""
|
||||
for role_path in glob.glob(os.path.join(self.roles_dir, '*')):
|
||||
if not os.path.isdir(role_path):
|
||||
continue
|
||||
|
||||
role_name = os.path.basename(role_path)
|
||||
vars_main = os.path.join(role_path, 'vars', 'main.yml')
|
||||
|
||||
# skip roles without vars/main.yml
|
||||
if not os.path.exists(vars_main):
|
||||
continue
|
||||
|
||||
with open(vars_main, 'r', encoding='utf-8') as f:
|
||||
data = yaml.safe_load(f) or {}
|
||||
# load vars/main.yml if it exists
|
||||
data = {}
|
||||
if os.path.exists(vars_main):
|
||||
with open(vars_main, 'r', encoding='utf-8') as f:
|
||||
data = yaml.safe_load(f) or {}
|
||||
|
||||
app_id = data.get('application_id')
|
||||
if app_id is None:
|
||||
|
||||
if role_name in self.invokable:
|
||||
# must have application_id
|
||||
if app_id is None:
|
||||
self.fail(f"{role_name}: invokable role is missing 'application_id' in vars/main.yml")
|
||||
elif role_name in self.non_invokable:
|
||||
# must NOT have application_id
|
||||
if app_id is not None:
|
||||
self.fail(f"{role_name}: non-invokable role should not define 'application_id' in vars/main.yml")
|
||||
else:
|
||||
# roles not mentioned in categories.yml? we'll skip them
|
||||
continue
|
||||
|
||||
# if present but mismatched, warn
|
||||
if app_id is not None and app_id != role_name:
|
||||
warnings.warn(
|
||||
f"{role_name}: 'application_id' is missing in vars/main.yml. "
|
||||
f"Consider setting it to '{role_name}' to avoid confusion."
|
||||
)
|
||||
elif app_id != role_name:
|
||||
warnings.warn(
|
||||
f"{role_name}: 'application_id' is '{app_id}', "
|
||||
f"but the folder name is '{role_name}'. "
|
||||
"This can lead to confusion—using the directory name "
|
||||
"as the application_id is recommended."
|
||||
f"{role_name}: 'application_id' is '{app_id}',"
|
||||
f" but the folder name is '{role_name}'."
|
||||
" Consider setting application_id to exactly the role folder name to avoid confusion."
|
||||
)
|
||||
|
||||
# always pass
|
||||
# if we get here, all presence/absence checks passed
|
||||
self.assertTrue(True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
Reference in New Issue
Block a user