mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-08-29 15:06:26 +02:00
Another bulk of refaktoring cleanup
This commit is contained in:
47
tests/integration/test_application_id.py
Normal file
47
tests/integration/test_application_id.py
Normal file
@@ -0,0 +1,47 @@
|
||||
import unittest
|
||||
import yaml
|
||||
import os
|
||||
import glob
|
||||
|
||||
from filter_plugins.invokable_paths import get_invokable_paths, get_non_invokable_paths
|
||||
|
||||
class TestSysRolesApplicationId(unittest.TestCase):
|
||||
"""
|
||||
Integration tests for sys-* roles based on categories.yml prefixes:
|
||||
For each actual sys-* directory under roles/:
|
||||
- If dash-joined prefix is in invokable_paths -> vars/main.yml must exist and contain application_id.
|
||||
- Otherwise (non-invokable or undeclared) -> if vars/main.yml exists, it must NOT contain application_id.
|
||||
"""
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
|
||||
cat_file = os.path.join(cls.base_dir, 'roles', 'categories.yml')
|
||||
cls.invokable_prefixes = set(get_invokable_paths(cat_file))
|
||||
# collect actual sys dirs
|
||||
pattern = os.path.join(cls.base_dir, 'roles', 'sys-*')
|
||||
cls.actual_dirs = [d for d in glob.glob(pattern) if os.path.isdir(d)]
|
||||
|
||||
def test_sys_roles_application_id(self):
|
||||
for role_dir in self.actual_dirs:
|
||||
name = os.path.basename(role_dir)
|
||||
prefix = f"sys-{name[len('sys-'):] if name.startswith('sys-') else name}"
|
||||
vars_file = os.path.join(role_dir, 'vars', 'main.yml')
|
||||
if prefix in self.invokable_prefixes:
|
||||
# must exist with id
|
||||
self.assertTrue(os.path.isfile(vars_file), f"Missing vars/main.yml for invokable role {prefix}")
|
||||
with open(vars_file) as f:
|
||||
content = yaml.safe_load(f) or {}
|
||||
self.assertIn('application_id', content,
|
||||
f"Expected 'application_id' in {vars_file} for invokable role {prefix}")
|
||||
else:
|
||||
# if exists, must not contain id
|
||||
if not os.path.isfile(vars_file):
|
||||
continue
|
||||
with open(vars_file) as f:
|
||||
content = yaml.safe_load(f) or {}
|
||||
self.assertNotIn('application_id', content,
|
||||
f"Unexpected 'application_id' in {vars_file} for non-invokable role {prefix}")
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
unittest.main()
|
@@ -1,25 +0,0 @@
|
||||
# tests/integration/test_no_application_id.py
|
||||
import unittest
|
||||
import yaml
|
||||
import glob
|
||||
import os
|
||||
|
||||
BASE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))
|
||||
test_files = glob.glob(os.path.join(BASE_DIR, "roles/sys-*/vars/main.yml"))
|
||||
|
||||
class TestNoApplicationId(unittest.TestCase):
|
||||
"""
|
||||
Ensure that no sys-* role main.yml defines an application_id variable.
|
||||
"""
|
||||
def test_no_application_id_defined(self):
|
||||
for file_path in test_files:
|
||||
with open(file_path, 'r') as f:
|
||||
content = yaml.safe_load(f) or {}
|
||||
|
||||
self.assertNotIn(
|
||||
'application_id', content,
|
||||
f"Unexpected 'application_id' defined in {file_path}"
|
||||
)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
73
tests/unit/filter_plugins/test_non_invokable_paths.py
Normal file
73
tests/unit/filter_plugins/test_non_invokable_paths.py
Normal file
@@ -0,0 +1,73 @@
|
||||
import unittest
|
||||
import tempfile
|
||||
import yaml
|
||||
import os
|
||||
|
||||
from filter_plugins.invokable_paths import get_non_invokable_paths
|
||||
|
||||
class TestNonInvokablePaths(unittest.TestCase):
|
||||
def write_yaml(self, data):
|
||||
tmp = tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.yml')
|
||||
yaml.dump(data, tmp)
|
||||
tmp.close()
|
||||
return tmp.name
|
||||
|
||||
def test_empty_roles(self):
|
||||
path = self.write_yaml({})
|
||||
# No roles, so no non-invokable paths
|
||||
self.assertEqual(get_non_invokable_paths(path), [])
|
||||
os.unlink(path)
|
||||
|
||||
def test_single_non_invokable_false_and_missing(self):
|
||||
data_false = {'role1': {'invokable': False}}
|
||||
path_false = self.write_yaml(data_false)
|
||||
self.assertEqual(get_non_invokable_paths(path_false), ['role1'])
|
||||
os.unlink(path_false)
|
||||
|
||||
data_missing = {'role1': {}}
|
||||
path_missing = self.write_yaml(data_missing)
|
||||
self.assertEqual(get_non_invokable_paths(path_missing), ['role1'])
|
||||
os.unlink(path_missing)
|
||||
|
||||
def test_single_invokable_true_excluded(self):
|
||||
data = {'role1': {'invokable': True}}
|
||||
path = self.write_yaml(data)
|
||||
# invokable True should not appear in non-invokable list
|
||||
self.assertEqual(get_non_invokable_paths(path), [])
|
||||
os.unlink(path)
|
||||
|
||||
def test_nested_and_deeply_nested(self):
|
||||
data = {
|
||||
'parent': {
|
||||
'invokable': True,
|
||||
'child': {'invokable': False},
|
||||
'other': {'invokable': True},
|
||||
'sub': {
|
||||
'deep': {}
|
||||
}
|
||||
}
|
||||
}
|
||||
path = self.write_yaml(data)
|
||||
# 'parent-child' (explicit False), 'parent-sub' (missing invokable), and 'parent-sub-deep' (missing) are non-invokable
|
||||
expected = ['parent-child', 'parent-sub', 'parent-sub-deep']
|
||||
self.assertEqual(sorted(get_non_invokable_paths(path)), sorted(expected))
|
||||
os.unlink(path)
|
||||
|
||||
def test_unwrap_roles_key(self):
|
||||
data = {'roles': {
|
||||
'role1': {'invokable': False},
|
||||
'role2': {'invokable': True}
|
||||
}}
|
||||
path = self.write_yaml(data)
|
||||
# Only role1 is non-invokable
|
||||
self.assertEqual(get_non_invokable_paths(path), ['role1'])
|
||||
os.unlink(path)
|
||||
|
||||
def test_suffix_appended(self):
|
||||
data = {'role1': {'invokable': False}}
|
||||
path = self.write_yaml(data)
|
||||
self.assertEqual(get_non_invokable_paths(path, suffix='_suf'), ['role1_suf'])
|
||||
os.unlink(path)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
Reference in New Issue
Block a user