mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-08-29 15:06:26 +02:00
Optimized role structure in preparation for new backup script
This commit is contained in:
0
tests/integration/backups/__init__.py
Normal file
0
tests/integration/backups/__init__.py
Normal file
51
tests/integration/backups/test_enabled.py
Normal file
51
tests/integration/backups/test_enabled.py
Normal file
@@ -0,0 +1,51 @@
|
||||
import unittest
|
||||
import os
|
||||
import yaml
|
||||
|
||||
class TestBackupsEnabledIntegrity(unittest.TestCase):
|
||||
def setUp(self):
|
||||
# Path to the roles directory
|
||||
self.roles_dir = os.path.abspath(
|
||||
os.path.join(os.path.dirname(__file__), '../../../roles')
|
||||
)
|
||||
|
||||
def test_backups_enabled_image_consistency(self):
|
||||
"""
|
||||
Ensure that if `backups.enabled` is set for any docker.services[*]:
|
||||
- it's a boolean value
|
||||
- the containing service dict has an `image` entry at the same level
|
||||
"""
|
||||
for role in os.listdir(self.roles_dir):
|
||||
docker_config_path = os.path.join(
|
||||
self.roles_dir, role, 'config', 'main.yml'
|
||||
)
|
||||
if not os.path.isfile(docker_config_path):
|
||||
continue
|
||||
|
||||
with open(docker_config_path, 'r') as f:
|
||||
try:
|
||||
config = yaml.safe_load(f) or {}
|
||||
except yaml.YAMLError as e:
|
||||
self.fail(f"YAML parsing failed for {docker_config_path}: {e}")
|
||||
continue
|
||||
|
||||
services = (config.get('docker', {}) or {}).get('services', {}) or {}
|
||||
|
||||
for service_key, service in services.items():
|
||||
if not isinstance(service, dict):
|
||||
continue
|
||||
|
||||
backups_cfg = service.get('backups', {}) or {}
|
||||
if 'enabled' in backups_cfg:
|
||||
with self.subTest(role=role, service=service_key):
|
||||
self.assertIsInstance(
|
||||
backups_cfg['enabled'], bool,
|
||||
f"`backups.enabled` in role '{role}', service '{service_key}' must be a boolean."
|
||||
)
|
||||
self.assertIn(
|
||||
'image', service,
|
||||
f"`image` is required in role '{role}', service '{service_key}' when `backups.enabled` is defined."
|
||||
)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
55
tests/integration/backups/test_no_stop_required.py
Normal file
55
tests/integration/backups/test_no_stop_required.py
Normal file
@@ -0,0 +1,55 @@
|
||||
import unittest
|
||||
import os
|
||||
import yaml
|
||||
|
||||
class TestNoStopRequiredIntegrity(unittest.TestCase):
|
||||
def setUp(self):
|
||||
# Path to the roles directory
|
||||
self.roles_dir = os.path.abspath(
|
||||
os.path.join(os.path.dirname(__file__), '../../../roles')
|
||||
)
|
||||
|
||||
def test_backup_no_stop_required_consistency(self):
|
||||
"""
|
||||
Ensure that if `backup.no_stop_required: true` is set for any docker.services[*]:
|
||||
- it's a boolean value
|
||||
- the containing service dict has an `image` entry at the same level
|
||||
"""
|
||||
for role in os.listdir(self.roles_dir):
|
||||
docker_config_path = os.path.join(
|
||||
self.roles_dir, role, 'config', 'main.yml'
|
||||
)
|
||||
if not os.path.isfile(docker_config_path):
|
||||
continue
|
||||
|
||||
with open(docker_config_path, 'r') as f:
|
||||
try:
|
||||
# Ensure config is at least an empty dict if YAML is empty or null
|
||||
config = yaml.safe_load(f) or {}
|
||||
except yaml.YAMLError as e:
|
||||
self.fail(f"YAML parsing failed for {docker_config_path}: {e}")
|
||||
continue
|
||||
|
||||
# Safely get services dict
|
||||
services = (config.get('docker', {}) or {}).get('services', {}) or {}
|
||||
|
||||
for service_key, service in services.items():
|
||||
if not isinstance(service, dict):
|
||||
continue
|
||||
backup_cfg = service.get('backup', {}) or {}
|
||||
# Check if no_stop_required is explicitly True
|
||||
if backup_cfg.get('no_stop_required') is True:
|
||||
with self.subTest(role=role, service=service_key):
|
||||
# Must be a boolean
|
||||
self.assertIsInstance(
|
||||
backup_cfg['no_stop_required'], bool,
|
||||
f"`backup.no_stop_required` in role '{role}', service '{service_key}' must be a boolean."
|
||||
)
|
||||
# Must have `image` defined at the service level
|
||||
self.assertIn(
|
||||
'image', service,
|
||||
f"`image` is required in role '{role}', service '{service_key}' when `backup.no_stop_required` is set to True."
|
||||
)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
@@ -1,52 +0,0 @@
|
||||
import unittest
|
||||
import os
|
||||
import yaml
|
||||
|
||||
class TestNoStopRequiredIntegrity(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.roles_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../roles'))
|
||||
|
||||
def test_no_stop_required_consistency(self):
|
||||
"""
|
||||
This test ensures that if 'no_stop_required' is defined in any
|
||||
docker.services[*] entry, it must:
|
||||
- be a boolean value (True/False)
|
||||
- have a 'name' entry defined on the same level
|
||||
|
||||
This is critical for the role 'sys-bkp-docker-2-loc', which uses the
|
||||
'no_stop_required' flag to determine which container names should be excluded
|
||||
from stopping during backup operations.
|
||||
|
||||
The logic for processing this flag is implemented in:
|
||||
https://github.com/kevinveenbirkenbach/backup-docker-to-local
|
||||
"""
|
||||
for role in os.listdir(self.roles_dir):
|
||||
docker_config_path = os.path.join(self.roles_dir, role, 'config', 'main.yml')
|
||||
if not os.path.isfile(docker_config_path):
|
||||
continue
|
||||
|
||||
with open(docker_config_path, 'r') as f:
|
||||
try:
|
||||
config = yaml.safe_load(f)
|
||||
except yaml.YAMLError as e:
|
||||
self.fail(f"YAML parsing failed for {docker_config_path}: {e}")
|
||||
continue
|
||||
|
||||
docker_services = (
|
||||
config.get('docker', {}).get('services', {}) if config else {}
|
||||
)
|
||||
|
||||
for service_key, service in docker_services.items():
|
||||
if isinstance(service, dict) and 'no_stop_required' in service:
|
||||
with self.subTest(role=role, service=service_key):
|
||||
self.assertIsInstance(
|
||||
service['no_stop_required'], bool,
|
||||
f"'no_stop_required' in role '{role}', service '{service_key}' must be a boolean."
|
||||
)
|
||||
self.assertIn(
|
||||
'name', service,
|
||||
f"'name' is required in role '{role}', service '{service_key}' when 'no_stop_required' is set."
|
||||
)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
Reference in New Issue
Block a user