mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-08-29 23:08:06 +02:00
Huge role refactoring/cleanup. Other commits will propably follow. Because some bugs will exist. Still important for longrun and also for auto docs/help/slideshow generation
This commit is contained in:
67
tests/integration/test_role_dependencies_circular.py
Normal file
67
tests/integration/test_role_dependencies_circular.py
Normal file
@@ -0,0 +1,67 @@
|
||||
import unittest
|
||||
import os
|
||||
import yaml
|
||||
|
||||
def load_yaml_file(file_path):
|
||||
"""Load a YAML file and return its content."""
|
||||
with open(file_path, 'r') as file:
|
||||
return yaml.safe_load(file) or {}
|
||||
|
||||
def get_meta_info(role_path):
|
||||
"""Extract dependencies from the meta/main.yml of a role."""
|
||||
meta_file = os.path.join(role_path, 'meta', 'main.yml')
|
||||
if not os.path.isfile(meta_file):
|
||||
return []
|
||||
meta_data = load_yaml_file(meta_file)
|
||||
dependencies = meta_data.get('dependencies', [])
|
||||
return dependencies
|
||||
|
||||
def resolve_dependencies(roles_dir):
|
||||
"""Resolve all role dependencies and detect circular dependencies."""
|
||||
visited = set() # Tracks roles that have been processed
|
||||
|
||||
def visit(role_path, stack):
|
||||
role_name = os.path.basename(role_path)
|
||||
|
||||
# Check for circular dependencies (if role is already in the current stack)
|
||||
if role_name in stack:
|
||||
raise ValueError(f"Circular dependency detected: {' -> '.join(stack)} -> {role_name}")
|
||||
|
||||
# Check if role is already processed
|
||||
if role_name in visited:
|
||||
return []
|
||||
|
||||
# Mark role as visited and add to stack
|
||||
visited.add(role_name)
|
||||
stack.append(role_name)
|
||||
|
||||
# Get dependencies and resolve them
|
||||
dependencies = get_meta_info(role_path)
|
||||
for dep in dependencies:
|
||||
dep_path = os.path.join(roles_dir, dep)
|
||||
visit(dep_path, stack) # Recurse into dependencies
|
||||
|
||||
stack.pop() # Remove the current role from the stack
|
||||
|
||||
for role_name in os.listdir(roles_dir):
|
||||
role_path = os.path.join(roles_dir, role_name)
|
||||
if os.path.isdir(role_path):
|
||||
try:
|
||||
visit(role_path, []) # Start recursion from this role
|
||||
except ValueError as e:
|
||||
raise ValueError(f"Error processing role '{role_name}' at path '{role_path}': {str(e)}")
|
||||
|
||||
class TestRoleDependencies(unittest.TestCase):
|
||||
def test_no_circular_dependencies(self):
|
||||
roles_dir = "roles" # Path to the roles directory
|
||||
|
||||
try:
|
||||
resolve_dependencies(roles_dir)
|
||||
except ValueError as e:
|
||||
self.fail(f"Circular dependency detected: {e}")
|
||||
|
||||
# If no exception, the test passed
|
||||
self.assertTrue(True)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
Reference in New Issue
Block a user