import unittest import os import glob import yaml class TestRoleDependencies(unittest.TestCase): def test_dependencies_exist(self): # Determine the path to the roles directory relative to this test file tests_dir = os.path.dirname(__file__) project_root = os.path.abspath(os.path.join(tests_dir, os.pardir, os.pardir)) roles_dir = os.path.join(project_root, 'roles') # Find all meta/main.yml files under roles/*/meta/main.yml pattern = os.path.join(roles_dir, '*', 'meta', 'main.yml') meta_files = glob.glob(pattern) self.assertTrue(meta_files, f"No meta/main.yml files found with pattern {pattern}") for meta_file in meta_files: role_dir = os.path.dirname(os.path.dirname(meta_file)) role_name = os.path.basename(role_dir) with self.subTest(role=role_name): # Load the YAML metadata with open(meta_file, 'r') as f: meta = yaml.safe_load(f) or {} # Extract dependencies list dependencies = meta.get('dependencies', []) self.assertIsInstance(dependencies, list, f"'dependencies' for role '{role_name}' is not a list") for dep in dependencies: # Dependencies can be strings or dicts with a 'role' key if isinstance(dep, str): dep_name = dep elif isinstance(dep, dict) and 'role' in dep: dep_name = dep['role'] else: self.fail(f"Invalid dependency format {dep!r} in role '{role_name}'") dep_path = os.path.join(roles_dir, dep_name) # Assert that the dependency role directory exists self.assertTrue( os.path.isdir(dep_path), f"Role '{role_name}' declares dependency '{dep_name}' but '{dep_path}' does not exist" ) if __name__ == '__main__': unittest.main()