mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-08-29 15:06:26 +02:00
Solved collection dependency bug
This commit is contained in:
79
tests/integration/test_dependency_application_id.py
Normal file
79
tests/integration/test_dependency_application_id.py
Normal file
@@ -0,0 +1,79 @@
|
||||
import os
|
||||
import unittest
|
||||
import yaml
|
||||
import glob
|
||||
|
||||
class TestDependencyApplicationId(unittest.TestCase):
|
||||
def test_application_id_matches_folder_for_dependent_roles(self):
|
||||
"""
|
||||
For any role A that depends on role B (listed under A/meta/main.yml → dependencies),
|
||||
if both A and B have vars/main.yml with application_id defined,
|
||||
then application_id must equal the role's folder name for both.
|
||||
"""
|
||||
base_dir = os.path.dirname(__file__)
|
||||
roles_dir = os.path.abspath(os.path.join(base_dir, '..', '..', 'roles'))
|
||||
|
||||
violations = []
|
||||
|
||||
# Helper to load application_id if present
|
||||
def load_app_id(role_path):
|
||||
vars_file = os.path.join(role_path, 'vars', 'main.yml')
|
||||
if not os.path.isfile(vars_file):
|
||||
return None
|
||||
data = yaml.safe_load(open(vars_file, encoding='utf-8')) or {}
|
||||
return data.get('application_id')
|
||||
|
||||
# Iterate all roles
|
||||
for role_path in glob.glob(os.path.join(roles_dir, '*')):
|
||||
if not os.path.isdir(role_path):
|
||||
continue
|
||||
|
||||
role_name = os.path.basename(role_path)
|
||||
meta_file = os.path.join(role_path, 'meta', 'main.yml')
|
||||
if not os.path.isfile(meta_file):
|
||||
continue
|
||||
|
||||
meta = yaml.safe_load(open(meta_file, encoding='utf-8')) or {}
|
||||
deps = meta.get('dependencies', [])
|
||||
if not isinstance(deps, list):
|
||||
continue
|
||||
|
||||
# collect just the role names this role depends on
|
||||
dep_names = []
|
||||
for item in deps:
|
||||
if isinstance(item, dict) and 'role' in item:
|
||||
dep_names.append(item['role'])
|
||||
elif isinstance(item, str):
|
||||
dep_names.append(item)
|
||||
|
||||
# load application_id for this role once
|
||||
app_id_role = load_app_id(role_path)
|
||||
for dep_name in dep_names:
|
||||
dep_path = os.path.join(roles_dir, dep_name)
|
||||
if not os.path.isdir(dep_path):
|
||||
continue
|
||||
|
||||
app_id_dep = load_app_id(dep_path)
|
||||
# only check if both app_ids are defined
|
||||
if app_id_role is None or app_id_dep is None:
|
||||
continue
|
||||
|
||||
# check role A
|
||||
if app_id_role != role_name:
|
||||
violations.append(
|
||||
f"{role_name}: application_id='{app_id_role}' ≠ folder name '{role_name}'"
|
||||
)
|
||||
# check role B
|
||||
if app_id_dep != dep_name:
|
||||
violations.append(
|
||||
f"{dep_name}: application_id='{app_id_dep}' ≠ folder name '{dep_name}'"
|
||||
)
|
||||
|
||||
if violations:
|
||||
self.fail(
|
||||
"application_id mismatches between role folder names and vars/main.yml:\n"
|
||||
+ "\n".join(violations)
|
||||
)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
@@ -18,25 +18,25 @@ class TestApplicationsIfGroupAndDeps(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.filter = FilterModule().applications_if_group_and_deps
|
||||
self.sample_apps = {
|
||||
'html': {},
|
||||
'legal': {},
|
||||
'file': {},
|
||||
'asset': {},
|
||||
'portfolio': {},
|
||||
'corporate-identity': {},
|
||||
'web-svc-html': {},
|
||||
'web-svc-legal': {},
|
||||
'web-svc-file': {},
|
||||
'web-svc-asset': {},
|
||||
'web-app-portfolio': {},
|
||||
'util-srv-corporate-identity': {},
|
||||
}
|
||||
|
||||
def test_direct_group(self):
|
||||
result = self.filter(self.sample_apps, ['html'])
|
||||
self.assertIn('html', result)
|
||||
self.assertNotIn('legal', result)
|
||||
result = self.filter(self.sample_apps, ['web-svc-html'])
|
||||
self.assertIn('web-svc-html', result)
|
||||
self.assertNotIn('web-svc-legal', result)
|
||||
|
||||
def test_recursive_deps(self):
|
||||
# html -> depends on none, but corporate-identity pulls in web-svc-legal -> web-svc-html -> legal
|
||||
# html -> depends on none, but util-srv-corporate-identity pulls in web-svc-legal -> web-svc-html -> legal
|
||||
result = self.filter(self.sample_apps, ['util-srv-corporate-identity'])
|
||||
self.assertIn('corporate-identity', result)
|
||||
self.assertIn('legal', result) # via web-svc-legal
|
||||
self.assertIn('html', result) # via web-svc-legal -> html
|
||||
self.assertIn('util-srv-corporate-identity', result)
|
||||
self.assertIn('web-svc-legal', result) # via web-svc-legal
|
||||
self.assertIn('web-svc-html', result) # via web-svc-legal -> html
|
||||
|
||||
def test_real_vars_files(self):
|
||||
# load real vars to get application_id
|
||||
|
Reference in New Issue
Block a user