From a0432093db76d7bb462f113d4bbeca0a8f376e95 Mon Sep 17 00:00:00 2001 From: Colin Wilk Date: Sun, 28 Jun 2026 23:24:21 +0200 Subject: Format python files with ruff --- molecule/default/tests/test_client_setup.py | 323 +++++++++++---------- molecule/default/tests/test_decryption_keys.py | 59 ++-- molecule/default/tests/test_installation.py | 10 +- molecule/default/tests/test_manual_backup.py | 54 ++-- molecule/default/tests/test_server_setup.py | 80 ++--- .../tests/test_server_setup_multi_instance.py | 68 +++-- molecule/default/tests/test_ssh_connectivity.py | 162 ++++++----- molecule/default/tests/test_systemd.py | 190 ++++++------ 8 files changed, 505 insertions(+), 441 deletions(-) (limited to 'molecule') diff --git a/molecule/default/tests/test_client_setup.py b/molecule/default/tests/test_client_setup.py index 6d11a93..f59c6db 100644 --- a/molecule/default/tests/test_client_setup.py +++ b/molecule/default/tests/test_client_setup.py @@ -1,42 +1,49 @@ """Tests for client setup configuration""" + import pytest -testinfra_hosts = ['borg-client', 'borg-client-2', 'borg-client-multi', 'borg-client-nonroot', 'borg-client-multi-keys'] +testinfra_hosts = [ + "borg-client", + "borg-client-2", + "borg-client-multi", + "borg-client-nonroot", + "borg-client-multi-keys", +] CLIENT_USER_MAP = { - 'borg-client': 'root', - 'borg-client-2': 'root', - 'borg-client-multi': 'root', - 'borg-client-nonroot': 'backupuser', - 'borg-client-multi-keys': 'root', + "borg-client": "root", + "borg-client-2": "root", + "borg-client-multi": "root", + "borg-client-nonroot": "backupuser", + "borg-client-multi-keys": "root", } CLIENT_SSH_KEY_TYPE_MAP = { - 'borg-client': 'rsa', - 'borg-client-2': 'ed25519', - 'borg-client-multi': 'rsa', - 'borg-client-nonroot': 'rsa', - 'borg-client-multi-keys': 'ed25519', + "borg-client": "rsa", + "borg-client-2": "ed25519", + "borg-client-multi": "rsa", + "borg-client-nonroot": "rsa", + "borg-client-multi-keys": "ed25519", } CLIENT_SSH_KEY_PER_REPO_MAP = { - 'borg-client': False, - 'borg-client-2': False, - 'borg-client-multi': False, - 'borg-client-nonroot': False, - 'borg-client-multi-keys': True, + "borg-client": False, + "borg-client-2": False, + "borg-client-multi": False, + "borg-client-nonroot": False, + "borg-client-multi-keys": True, } def get_client_user(host): hostname = host.backend.get_hostname() - return CLIENT_USER_MAP.get(hostname, 'root') + return CLIENT_USER_MAP.get(hostname, "root") def get_client_ssh_key_type(host): hostname = host.backend.get_hostname() - return CLIENT_SSH_KEY_TYPE_MAP.get(hostname, 'rsa') + return CLIENT_SSH_KEY_TYPE_MAP.get(hostname, "rsa") def get_client_ssh_key_per_repo(host): @@ -46,14 +53,14 @@ def get_client_ssh_key_per_repo(host): def get_client_home(host): user = get_client_user(host) - return f'/home/{user}' if user != 'root' else '/root' + return f"/home/{user}" if user != "root" else "/root" class TestSSHSetup: def test_ssh_directory_exists(self, host): client_home = get_client_home(host) client_user = get_client_user(host) - ssh_dir = host.file(f'{client_home}/.ssh') + ssh_dir = host.file(f"{client_home}/.ssh") assert ssh_dir.exists assert ssh_dir.is_directory assert ssh_dir.user == client_user @@ -67,9 +74,13 @@ class TestSSHSetup: per_repo = get_client_ssh_key_per_repo(host) hostname = host.backend.get_hostname() - if per_repo and hostname == 'borg-client-multi-keys': - key1 = host.file(f'{client_home}/.ssh/id_{key_type}_borgbackup_borg_server_configs_keys') - key2 = host.file(f'{client_home}/.ssh/id_{key_type}_borgbackup_borg_server_home_data_keys') + if per_repo and hostname == "borg-client-multi-keys": + key1 = host.file( + f"{client_home}/.ssh/id_{key_type}_borgbackup_borg_server_configs_keys" + ) + key2 = host.file( + f"{client_home}/.ssh/id_{key_type}_borgbackup_borg_server_home_data_keys" + ) assert key1.exists assert key1.user == client_user assert key1.group == client_user @@ -79,7 +90,7 @@ class TestSSHSetup: assert key2.group == client_user assert key2.mode == 0o600 else: - key = host.file(f'{client_home}/.ssh/id_{key_type}') + key = host.file(f"{client_home}/.ssh/id_{key_type}") assert key.exists assert key.user == client_user assert key.group == client_user @@ -92,9 +103,13 @@ class TestSSHSetup: per_repo = get_client_ssh_key_per_repo(host) hostname = host.backend.get_hostname() - if per_repo and hostname == 'borg-client-multi-keys': - key1 = host.file(f'{client_home}/.ssh/id_{key_type}_borgbackup_borg_server_configs_keys.pub') - key2 = host.file(f'{client_home}/.ssh/id_{key_type}_borgbackup_borg_server_home_data_keys.pub') + if per_repo and hostname == "borg-client-multi-keys": + key1 = host.file( + f"{client_home}/.ssh/id_{key_type}_borgbackup_borg_server_configs_keys.pub" + ) + key2 = host.file( + f"{client_home}/.ssh/id_{key_type}_borgbackup_borg_server_home_data_keys.pub" + ) assert key1.exists assert key1.user == client_user assert key1.group == client_user @@ -102,16 +117,16 @@ class TestSSHSetup: assert key2.user == client_user assert key2.group == client_user else: - key = host.file(f'{client_home}/.ssh/id_{key_type}.pub') + key = host.file(f"{client_home}/.ssh/id_{key_type}.pub") assert key.exists assert key.user == client_user assert key.group == client_user def test_known_hosts_contains_borg_server(self, host): client_home = get_client_home(host) - known_hosts = host.file(f'{client_home}/.ssh/known_hosts') + known_hosts = host.file(f"{client_home}/.ssh/known_hosts") assert known_hosts.exists - assert known_hosts.contains('borg-server') + assert known_hosts.contains("borg-server") class TestBackupScript: @@ -119,9 +134,9 @@ class TestBackupScript: hostname = host.backend.get_hostname() client_user = get_client_user(host) - if hostname == 'borg-client-multi': - script1 = host.file('/usr/local/bin/run_borg_backup@configs') - script2 = host.file('/usr/local/bin/run_borg_backup@home-data') + if hostname == "borg-client-multi": + script1 = host.file("/usr/local/bin/run_borg_backup@configs") + script2 = host.file("/usr/local/bin/run_borg_backup@home-data") assert script1.exists assert script1.user == client_user assert script1.group == client_user @@ -130,9 +145,9 @@ class TestBackupScript: assert script2.user == client_user assert script2.group == client_user assert script2.mode == 0o711 - elif hostname == 'borg-client-multi-keys': - script1 = host.file('/usr/local/bin/run_borg_backup@configs-keys') - script2 = host.file('/usr/local/bin/run_borg_backup@home-data-keys') + elif hostname == "borg-client-multi-keys": + script1 = host.file("/usr/local/bin/run_borg_backup@configs-keys") + script2 = host.file("/usr/local/bin/run_borg_backup@home-data-keys") assert script1.exists assert script1.user == client_user assert script1.group == client_user @@ -141,14 +156,14 @@ class TestBackupScript: assert script2.user == client_user assert script2.group == client_user assert script2.mode == 0o711 - elif hostname == 'borg-client-nonroot': - script = host.file('/usr/local/bin/run_borg_backup@borg-server') + elif hostname == "borg-client-nonroot": + script = host.file("/usr/local/bin/run_borg_backup@borg-server") assert script.exists assert script.user == client_user assert script.group == client_user assert script.mode == 0o711 - elif hostname in ('borg-client', 'borg-client-2'): - script = host.file('/usr/local/bin/run_borg_backup') + elif hostname in ("borg-client", "borg-client-2"): + script = host.file("/usr/local/bin/run_borg_backup") assert script.exists assert script.user == client_user assert script.group == client_user @@ -159,125 +174,129 @@ class TestBackupScript: def test_backup_script_contains_borg_command(self, host): hostname = host.backend.get_hostname() - if hostname == 'borg-client-multi': - script1 = host.file('/usr/local/bin/run_borg_backup@configs') - script2 = host.file('/usr/local/bin/run_borg_backup@home-data') - assert script1.contains('borg create') - assert script2.contains('borg create') - elif hostname == 'borg-client-multi-keys': - script1 = host.file('/usr/local/bin/run_borg_backup@configs-keys') - script2 = host.file('/usr/local/bin/run_borg_backup@home-data-keys') - assert script1.contains('borg create') - assert script2.contains('borg create') - elif hostname == 'borg-client-nonroot': - script = host.file('/usr/local/bin/run_borg_backup@borg-server') - assert script.contains('borg create') - elif hostname in ('borg-client', 'borg-client-2'): - script = host.file('/usr/local/bin/run_borg_backup') - assert script.contains('borg create') + if hostname == "borg-client-multi": + script1 = host.file("/usr/local/bin/run_borg_backup@configs") + script2 = host.file("/usr/local/bin/run_borg_backup@home-data") + assert script1.contains("borg create") + assert script2.contains("borg create") + elif hostname == "borg-client-multi-keys": + script1 = host.file("/usr/local/bin/run_borg_backup@configs-keys") + script2 = host.file("/usr/local/bin/run_borg_backup@home-data-keys") + assert script1.contains("borg create") + assert script2.contains("borg create") + elif hostname == "borg-client-nonroot": + script = host.file("/usr/local/bin/run_borg_backup@borg-server") + assert script.contains("borg create") + elif hostname in ("borg-client", "borg-client-2"): + script = host.file("/usr/local/bin/run_borg_backup") + assert script.contains("borg create") else: pytest.fail(f"Unexpected hostname: {hostname}") def test_backup_script_contains_compression(self, host): hostname = host.backend.get_hostname() - if hostname == 'borg-client-multi': - script1 = host.file('/usr/local/bin/run_borg_backup@configs') - script2 = host.file('/usr/local/bin/run_borg_backup@home-data') - assert script1.contains('-C zstd') - assert script2.contains('-C lz4') - elif hostname == 'borg-client-multi-keys': - script1 = host.file('/usr/local/bin/run_borg_backup@configs-keys') - script2 = host.file('/usr/local/bin/run_borg_backup@home-data-keys') - assert script1.contains('-C zstd') - assert script2.contains('-C lz4') - elif hostname == 'borg-client-2': - script = host.file('/usr/local/bin/run_borg_backup') - assert script.contains('-C') - assert script.contains('lz4') - elif hostname in ('borg-client', 'borg-client-nonroot'): - script = host.file('/usr/local/bin/run_borg_backup') if hostname == 'borg-client' else host.file('/usr/local/bin/run_borg_backup@borg-server') - assert script.contains('-C') - assert script.contains('zstd') + if hostname == "borg-client-multi": + script1 = host.file("/usr/local/bin/run_borg_backup@configs") + script2 = host.file("/usr/local/bin/run_borg_backup@home-data") + assert script1.contains("-C zstd") + assert script2.contains("-C lz4") + elif hostname == "borg-client-multi-keys": + script1 = host.file("/usr/local/bin/run_borg_backup@configs-keys") + script2 = host.file("/usr/local/bin/run_borg_backup@home-data-keys") + assert script1.contains("-C zstd") + assert script2.contains("-C lz4") + elif hostname == "borg-client-2": + script = host.file("/usr/local/bin/run_borg_backup") + assert script.contains("-C") + assert script.contains("lz4") + elif hostname in ("borg-client", "borg-client-nonroot"): + script = ( + host.file("/usr/local/bin/run_borg_backup") + if hostname == "borg-client" + else host.file("/usr/local/bin/run_borg_backup@borg-server") + ) + assert script.contains("-C") + assert script.contains("zstd") else: pytest.fail(f"Unexpected hostname: {hostname}") def test_backup_script_contains_repo_path(self, host): hostname = host.backend.get_hostname() - if hostname == 'borg-client-multi': - script1 = host.file('/usr/local/bin/run_borg_backup@configs') - script2 = host.file('/usr/local/bin/run_borg_backup@home-data') - assert script1.contains('borg@borg-server') - assert script1.contains('/opt/borg/configs') - assert script2.contains('borg@borg-server') - assert script2.contains('/opt/borg/home-data') - elif hostname == 'borg-client-multi-keys': - script1 = host.file('/usr/local/bin/run_borg_backup@configs-keys') - script2 = host.file('/usr/local/bin/run_borg_backup@home-data-keys') - assert script1.contains('borg@borg-server') - assert script1.contains('/opt/borg/configs-keys') - assert script2.contains('borg@borg-server') - assert script2.contains('/opt/borg/home-data-keys') - elif hostname == 'borg-client-nonroot': - script = host.file('/usr/local/bin/run_borg_backup@borg-server') - assert script.contains('borg@borg-server') - assert script.contains('/opt/borg') - elif hostname == 'borg-client': - script = host.file('/usr/local/bin/run_borg_backup') - assert script.contains('borg@borg-server') - assert script.contains('/opt/borg') - elif hostname == 'borg-client-2': - script = host.file('/usr/local/bin/run_borg_backup') - assert script.contains('backupserver@borg-server-2') - assert script.contains('/var/backups') + if hostname == "borg-client-multi": + script1 = host.file("/usr/local/bin/run_borg_backup@configs") + script2 = host.file("/usr/local/bin/run_borg_backup@home-data") + assert script1.contains("borg@borg-server") + assert script1.contains("/opt/borg/configs") + assert script2.contains("borg@borg-server") + assert script2.contains("/opt/borg/home-data") + elif hostname == "borg-client-multi-keys": + script1 = host.file("/usr/local/bin/run_borg_backup@configs-keys") + script2 = host.file("/usr/local/bin/run_borg_backup@home-data-keys") + assert script1.contains("borg@borg-server") + assert script1.contains("/opt/borg/configs-keys") + assert script2.contains("borg@borg-server") + assert script2.contains("/opt/borg/home-data-keys") + elif hostname == "borg-client-nonroot": + script = host.file("/usr/local/bin/run_borg_backup@borg-server") + assert script.contains("borg@borg-server") + assert script.contains("/opt/borg") + elif hostname == "borg-client": + script = host.file("/usr/local/bin/run_borg_backup") + assert script.contains("borg@borg-server") + assert script.contains("/opt/borg") + elif hostname == "borg-client-2": + script = host.file("/usr/local/bin/run_borg_backup") + assert script.contains("backupserver@borg-server-2") + assert script.contains("/var/backups") else: pytest.fail(f"Unexpected hostname: {hostname}") def test_backup_script_contains_backup_paths(self, host): hostname = host.backend.get_hostname() - if hostname == 'borg-client-multi': - script1 = host.file('/usr/local/bin/run_borg_backup@configs') - script2 = host.file('/usr/local/bin/run_borg_backup@home-data') - assert '/etc' in script1.content_string - assert '/home' in script2.content_string - assert '--exclude' in script2.content_string - elif hostname == 'borg-client-multi-keys': - script1 = host.file('/usr/local/bin/run_borg_backup@configs-keys') - script2 = host.file('/usr/local/bin/run_borg_backup@home-data-keys') - assert '/etc' in script1.content_string - assert '/home' in script2.content_string - assert '--exclude' in script2.content_string - elif hostname == 'borg-client-nonroot': - script = host.file('/usr/local/bin/run_borg_backup@borg-server') + if hostname == "borg-client-multi": + script1 = host.file("/usr/local/bin/run_borg_backup@configs") + script2 = host.file("/usr/local/bin/run_borg_backup@home-data") + assert "/etc" in script1.content_string + assert "/home" in script2.content_string + assert "--exclude" in script2.content_string + elif hostname == "borg-client-multi-keys": + script1 = host.file("/usr/local/bin/run_borg_backup@configs-keys") + script2 = host.file("/usr/local/bin/run_borg_backup@home-data-keys") + assert "/etc" in script1.content_string + assert "/home" in script2.content_string + assert "--exclude" in script2.content_string + elif hostname == "borg-client-nonroot": + script = host.file("/usr/local/bin/run_borg_backup@borg-server") content = script.content_string - assert '/etc' in content - elif hostname in ('borg-client', 'borg-client-2'): - script = host.file('/usr/local/bin/run_borg_backup') + assert "/etc" in content + elif hostname in ("borg-client", "borg-client-2"): + script = host.file("/usr/local/bin/run_borg_backup") content = script.content_string - assert '/etc' in content or '/home' in content + assert "/etc" in content or "/home" in content else: pytest.fail(f"Unexpected hostname: {hostname}") def test_backup_script_is_executable(self, host): hostname = host.backend.get_hostname() - if hostname == 'borg-client-multi': - script1 = host.file('/usr/local/bin/run_borg_backup@configs') - script2 = host.file('/usr/local/bin/run_borg_backup@home-data') + if hostname == "borg-client-multi": + script1 = host.file("/usr/local/bin/run_borg_backup@configs") + script2 = host.file("/usr/local/bin/run_borg_backup@home-data") assert script1.mode == 0o711 assert script2.mode == 0o711 - elif hostname == 'borg-client-multi-keys': - script1 = host.file('/usr/local/bin/run_borg_backup@configs-keys') - script2 = host.file('/usr/local/bin/run_borg_backup@home-data-keys') + elif hostname == "borg-client-multi-keys": + script1 = host.file("/usr/local/bin/run_borg_backup@configs-keys") + script2 = host.file("/usr/local/bin/run_borg_backup@home-data-keys") assert script1.mode == 0o711 assert script2.mode == 0o711 - elif hostname == 'borg-client-nonroot': - script = host.file('/usr/local/bin/run_borg_backup@borg-server') + elif hostname == "borg-client-nonroot": + script = host.file("/usr/local/bin/run_borg_backup@borg-server") assert script.mode == 0o711 - elif hostname in ('borg-client', 'borg-client-2'): - script = host.file('/usr/local/bin/run_borg_backup') + elif hostname in ("borg-client", "borg-client-2"): + script = host.file("/usr/local/bin/run_borg_backup") assert script.mode == 0o711 else: pytest.fail(f"Unexpected hostname: {hostname}") @@ -289,66 +308,66 @@ class TestBackupScript: if not per_repo: return - if hostname == 'borg-client-multi-keys': - script1 = host.file('/usr/local/bin/run_borg_backup@configs-keys') - script2 = host.file('/usr/local/bin/run_borg_backup@home-data-keys') - assert 'BORG_RSH' in script1.content_string - assert 'BORG_RSH' in script2.content_string - assert 'ssh -i' in script1.content_string - assert 'ssh -i' in script2.content_string + if hostname == "borg-client-multi-keys": + script1 = host.file("/usr/local/bin/run_borg_backup@configs-keys") + script2 = host.file("/usr/local/bin/run_borg_backup@home-data-keys") + assert "BORG_RSH" in script1.content_string + assert "BORG_RSH" in script2.content_string + assert "ssh -i" in script1.content_string + assert "ssh -i" in script2.content_string class TestMultiInstanceBaseScript: def test_base_script_exists(self, host): hostname = host.backend.get_hostname() - if hostname != 'borg-client-multi': + if hostname != "borg-client-multi": return client_user = get_client_user(host) - base_script = host.file('/usr/local/bin/run_borg_backup') + base_script = host.file("/usr/local/bin/run_borg_backup") assert base_script.exists assert base_script.user == client_user assert base_script.mode == 0o711 def test_base_script_contains_both_blocks(self, host): hostname = host.backend.get_hostname() - if hostname != 'borg-client-multi': + if hostname != "borg-client-multi": return - base_script = host.file('/usr/local/bin/run_borg_backup') + base_script = host.file("/usr/local/bin/run_borg_backup") content = base_script.content_string - assert 'borg-server/configs' in content - assert 'borg-server/home-data' in content + assert "borg-server/configs" in content + assert "borg-server/home-data" in content def test_base_script_contains_both_repos(self, host): hostname = host.backend.get_hostname() - if hostname != 'borg-client-multi': + if hostname != "borg-client-multi": return - base_script = host.file('/usr/local/bin/run_borg_backup') + base_script = host.file("/usr/local/bin/run_borg_backup") content = base_script.content_string - assert '/opt/borg/configs' in content - assert '/opt/borg/home-data' in content + assert "/opt/borg/configs" in content + assert "/opt/borg/home-data" in content def test_base_script_contains_both_compressions(self, host): hostname = host.backend.get_hostname() - if hostname != 'borg-client-multi': + if hostname != "borg-client-multi": return - base_script = host.file('/usr/local/bin/run_borg_backup') + base_script = host.file("/usr/local/bin/run_borg_backup") content = base_script.content_string - assert '-C zstd' in content - assert '-C lz4' in content + assert "-C zstd" in content + assert "-C lz4" in content def test_base_script_two_borg_create_commands(self, host): hostname = host.backend.get_hostname() - if hostname != 'borg-client-multi': + if hostname != "borg-client-multi": return - base_script = host.file('/usr/local/bin/run_borg_backup') + base_script = host.file("/usr/local/bin/run_borg_backup") content = base_script.content_string - assert content.count('borg create') == 2 + assert content.count("borg create") == 2 diff --git a/molecule/default/tests/test_decryption_keys.py b/molecule/default/tests/test_decryption_keys.py index bd5ff6a..be851f7 100644 --- a/molecule/default/tests/test_decryption_keys.py +++ b/molecule/default/tests/test_decryption_keys.py @@ -1,4 +1,5 @@ """Tests for decryption keys file structure""" + import os import stat import pytest @@ -6,26 +7,26 @@ import pytest def _get_keys_path(): """Get decryption_keys.yml path from molecule environment""" - scenario_dir = os.environ.get('MOLECULE_SCENARIO_DIRECTORY') + scenario_dir = os.environ.get("MOLECULE_SCENARIO_DIRECTORY") if scenario_dir: - return os.path.join(scenario_dir, 'decryption_keys.yml') + return os.path.join(scenario_dir, "decryption_keys.yml") test_dir = os.path.dirname(os.path.abspath(__file__)) - return os.path.join(test_dir, '..', 'decryption_keys.yml') + return os.path.join(test_dir, "..", "decryption_keys.yml") def test_decryption_keys_file_exists(): """Test that decryption_keys.yml exists""" keys_path = _get_keys_path() if not os.path.exists(keys_path): - pytest.skip('decryption_keys.yml not yet generated') + pytest.skip("decryption_keys.yml not yet generated") def test_decryption_keys_file_permissions(): """Test that decryption_keys.yml has secure permissions""" keys_path = _get_keys_path() if not os.path.exists(keys_path): - pytest.skip('decryption_keys.yml not yet generated') + pytest.skip("decryption_keys.yml not yet generated") file_stat = os.stat(keys_path) file_mode = stat.S_IMODE(file_stat.st_mode) @@ -38,12 +39,12 @@ def test_decryption_keys_structure_single_repo(): """Test single-repo hosts have correct key format""" keys_path = _get_keys_path() if not os.path.exists(keys_path): - pytest.skip('decryption_keys.yml not yet generated') + pytest.skip("decryption_keys.yml not yet generated") - with open(keys_path, 'r') as f: + with open(keys_path, "r") as f: content = f.read() - assert 'borg-client_borg-client:' in content, ( + assert "borg-client_borg-client:" in content, ( "Single repo host should have key named 'hostname_repo_name'" ) @@ -52,15 +53,15 @@ def test_decryption_keys_structure_multi_repo(): """Test multi-instance hosts have correct key format""" keys_path = _get_keys_path() if not os.path.exists(keys_path): - pytest.skip('decryption_keys.yml not yet generated') + pytest.skip("decryption_keys.yml not yet generated") - with open(keys_path, 'r') as f: + with open(keys_path, "r") as f: content = f.read() - assert 'borg-client-multi_configs:' in content, ( + assert "borg-client-multi_configs:" in content, ( "Multi-instance host should have key for 'configs' repo" ) - assert 'borg-client-multi_home-data:' in content, ( + assert "borg-client-multi_home-data:" in content, ( "Multi-instance host should have key for 'home-data' repo" ) @@ -69,13 +70,13 @@ def test_decryption_keys_multi_instance_separate_entries(): """Test multi-instance hosts have separate keys for each repo""" keys_path = _get_keys_path() if not os.path.exists(keys_path): - pytest.skip('decryption_keys.yml not yet generated') + pytest.skip("decryption_keys.yml not yet generated") - with open(keys_path, 'r') as f: + with open(keys_path, "r") as f: content = f.read() - configs_count = content.count('borg-client-multi_configs:') - home_data_count = content.count('borg-client-multi_home-data:') + configs_count = content.count("borg-client-multi_configs:") + home_data_count = content.count("borg-client-multi_home-data:") assert configs_count == 1, ( f"configs key should appear exactly once, found {configs_count}" @@ -89,13 +90,13 @@ def test_decryption_keys_contain_paper_key_format(): """Test that decryption keys use borg paper key format""" keys_path = _get_keys_path() if not os.path.exists(keys_path): - pytest.skip('decryption_keys.yml not yet generated') + pytest.skip("decryption_keys.yml not yet generated") - with open(keys_path, 'r') as f: + with open(keys_path, "r") as f: content = f.read() - assert 'BORG PAPER KEY' in content, ( - 'Decryption keys should contain borg paper key format' + assert "BORG PAPER KEY" in content, ( + "Decryption keys should contain borg paper key format" ) @@ -103,15 +104,15 @@ def test_decryption_keys_all_hosts_present(): """Test that all expected hosts have keys""" keys_path = _get_keys_path() if not os.path.exists(keys_path): - pytest.skip('decryption_keys.yml not yet generated') + pytest.skip("decryption_keys.yml not yet generated") - with open(keys_path, 'r') as f: + with open(keys_path, "r") as f: content = f.read() expected_keys = [ - 'borg-client_borg-client:', - 'borg-client-multi_configs:', - 'borg-client-multi_home-data:', + "borg-client_borg-client:", + "borg-client-multi_configs:", + "borg-client-multi_home-data:", ] for key in expected_keys: @@ -122,11 +123,11 @@ def test_no_keys_for_disabled_export(): """Test that no decryption keys are exported when disabled""" keys_path = _get_keys_path() if not os.path.exists(keys_path): - pytest.skip('decryption_keys.yml not yet generated') + pytest.skip("decryption_keys.yml not yet generated") - with open(keys_path, 'r') as f: + with open(keys_path, "r") as f: content = f.read() - assert 'borg-client-2_borg-client-2:' not in content, ( - 'Keys should not be exported for borg-client-2 (export disabled)' + assert "borg-client-2_borg-client-2:" not in content, ( + "Keys should not be exported for borg-client-2 (export disabled)" ) diff --git a/molecule/default/tests/test_installation.py b/molecule/default/tests/test_installation.py index bacc320..800eba4 100644 --- a/molecule/default/tests/test_installation.py +++ b/molecule/default/tests/test_installation.py @@ -1,18 +1,18 @@ -testinfra_hosts = ['borg-client', 'borg-server', 'borg-server-2'] +testinfra_hosts = ["borg-client", "borg-server", "borg-server-2"] def test_borg_installed(host): - borg = host.package('borgbackup') + borg = host.package("borgbackup") assert borg.is_installed def test_borg_binary_exists(host): - borg = host.file('/usr/bin/borg') + borg = host.file("/usr/bin/borg") assert borg.exists assert borg.mode == 0o755 def test_borg_version(host): - c = host.run('borg --version') + c = host.run("borg --version") assert c.rc == 0 - assert 'borg' in c.stdout.lower() + assert "borg" in c.stdout.lower() diff --git a/molecule/default/tests/test_manual_backup.py b/molecule/default/tests/test_manual_backup.py index b4068bc..8cd044c 100644 --- a/molecule/default/tests/test_manual_backup.py +++ b/molecule/default/tests/test_manual_backup.py @@ -1,22 +1,22 @@ import pytest from datetime import datetime -testinfra_hosts = ['borg-client', 'borg-client-2'] +testinfra_hosts = ["borg-client", "borg-client-2"] def get_server_info(hostname): - if hostname == 'borg-client-2': - return ('backupserver', 'borg-server-2', '/var/backups') - return ('borg', 'borg-server', '/opt/borg') + if hostname == "borg-client-2": + return ("backupserver", "borg-server-2", "/var/backups") + return ("borg", "borg-server", "/opt/borg") compression_types = [ - 'none', - 'lz4', - 'zstd', - 'zstd,10', - 'zlib', - 'zlib,6', + "none", + "lz4", + "zstd", + "zstd,10", + "zlib", + "zlib,6", ] @@ -24,7 +24,7 @@ compression_types = [ host""" -@pytest.mark.parametrize('compression', compression_types) +@pytest.mark.parametrize("compression", compression_types) def test_backup_push(host, compression): hostname = host.backend.get_hostname() server_user, server_host, server_path = get_server_info(hostname) @@ -33,15 +33,15 @@ def test_backup_push(host, compression): f'borg create -C "{compression}" {server_user}@{server_host}:{server_path}/{hostname}::testinfra-{{now:%S.%f}} /etc' ) assert c.rc == 0 - assert c.stdout == '' - assert c.stderr == '' + assert c.stdout == "" + assert c.stderr == "" -@pytest.mark.parametrize('compression', compression_types) +@pytest.mark.parametrize("compression", compression_types) def test_backup_restore(host, compression): hostname = host.backend.get_hostname() server_user, server_host, server_path = get_server_info(hostname) - timestamp = datetime.now().strftime('%Y%m%d-%H%M%S-%f') + timestamp = datetime.now().strftime("%Y%m%d-%H%M%S-%f") archive_name = f"testinfra-backup-restore-{compression}-{timestamp}" # Create backup @@ -49,16 +49,16 @@ def test_backup_restore(host, compression): f'borg create -C "{compression}" {server_user}@{server_host}:{server_path}/{hostname}::{archive_name} /etc' ) assert c.rc == 0 - assert c.stdout == '' - assert c.stderr == '' + assert c.stdout == "" + assert c.stderr == "" # Restore Backup c = host.run( f"cd /mnt && borg extract {server_user}@{server_host}:{server_path}/{hostname}::{archive_name}" ) assert c.rc == 0 - assert c.stdout == '' - assert c.stderr == '' + assert c.stdout == "" + assert c.stderr == "" # Check if every file exists, content has, and permissions / metadata c1 = host.run( @@ -68,17 +68,19 @@ def test_backup_restore(host, compression): 'cd /mnt/etc && find /etc -type f -printf "%P\\n" | sort | xargs -i sh -c "echo {}; sha512sum {} | cut -d \' \' -f 1; ls -l {}; echo"' ) assert c1.rc == 0 and c2.rc == 0 - assert c1.stderr == '' and c2.stderr == '' + assert c1.stderr == "" and c2.stderr == "" assert c1.stdout == c2.stdout # Delete directory extract directory again for future tests - c = host.run('rm -rf /mnt/etc') + c = host.run("rm -rf /mnt/etc") assert c.rc == 0 - assert c.stdout == '' - assert c.stderr == '' + assert c.stdout == "" + assert c.stderr == "" # Delete backup - c = host.run(f"borg delete {server_user}@{server_host}:{server_path}/{hostname}::{archive_name}") + c = host.run( + f"borg delete {server_user}@{server_host}:{server_path}/{hostname}::{archive_name}" + ) assert c.rc == 0 - assert c.stdout == '' - assert c.stderr == '' + assert c.stdout == "" + assert c.stderr == "" diff --git a/molecule/default/tests/test_server_setup.py b/molecule/default/tests/test_server_setup.py index 590a33c..93c319d 100644 --- a/molecule/default/tests/test_server_setup.py +++ b/molecule/default/tests/test_server_setup.py @@ -1,19 +1,19 @@ """Tests for borg server setup and repository configuration""" + import pytest -import re -testinfra_hosts = ['borg-server', 'borg-server-2'] +testinfra_hosts = ["borg-server", "borg-server-2"] SERVER_CONFIGS = { - 'borg-server': { - 'user': 'borg', - 'home': '/opt/borg', - 'client_repo': 'borg-client', + "borg-server": { + "user": "borg", + "home": "/opt/borg", + "client_repo": "borg-client", }, - 'borg-server-2': { - 'user': 'backupserver', - 'home': '/var/backups', - 'client_repo': 'borg-client-2', + "borg-server-2": { + "user": "backupserver", + "home": "/var/backups", + "client_repo": "borg-client-2", }, } @@ -25,16 +25,16 @@ def config(host): class TestBorgUser: def test_user_exists(self, host, config): - user = host.user(config['user']) + user = host.user(config["user"]) assert user.exists - assert user.home == config['home'] + assert user.home == config["home"] def test_home_exists(self, host, config): - home = host.file(config['home']) + home = host.file(config["home"]) assert home.exists assert home.is_directory - assert home.user == config['user'] - assert home.group == config['user'] + assert home.user == config["user"] + assert home.group == config["user"] class TestBorgSSHSetup: @@ -42,44 +42,50 @@ class TestBorgSSHSetup: ssh_dir = host.file(f"{config['home']}/.ssh") assert ssh_dir.exists assert ssh_dir.is_directory - assert ssh_dir.user == config['user'] - assert ssh_dir.group == config['user'] + assert ssh_dir.user == config["user"] + assert ssh_dir.group == config["user"] assert ssh_dir.mode == 0o700 def test_authorized_keys_exists(self, host, config): auth_keys = host.file(f"{config['home']}/.ssh/authorized_keys") assert auth_keys.exists - assert auth_keys.user == config['user'] - assert auth_keys.group == config['user'] + assert auth_keys.user == config["user"] + assert auth_keys.group == config["user"] assert not auth_keys.mode & 0o002 def test_authorized_keys_has_restrictions(self, host, config): auth_keys = host.file(f"{config['home']}/.ssh/authorized_keys") content = auth_keys.content_string - assert 'restrict' in content + assert "restrict" in content assert 'command="borg serve' in content def test_authorized_keys_has_repository_restrictions(self, host, config): auth_keys = host.file(f"{config['home']}/.ssh/authorized_keys") content = auth_keys.content_string - assert '--restrict-to-repository' in content + assert "--restrict-to-repository" in content def test_authorized_keys_format_valid(self, host, config): auth_keys = host.file(f"{config['home']}/.ssh/authorized_keys") content = auth_keys.content_string valid_hosts = ( - 'borg-client', - 'borg-client-2', - 'borg-client-multi', - 'borg-client-nonroot', - 'borg-client-multi-keys', + "borg-client", + "borg-client-2", + "borg-client-multi", + "borg-client-nonroot", + "borg-client-multi-keys", ) - for line in content.split('\n'): + for line in content.split("\n"): if not line.strip(): continue - assert line.startswith('restrict,command="borg serve'), f"Line should start with restrict,command: {line[:50]}" - assert '@' in line and line.rstrip().endswith(valid_hosts), f"Line should contain user@hostname marker: {line[-40:]}" - assert '--restrict-to-repository' in line, f"Line should have repo restriction: {line[:80]}" + assert line.startswith('restrict,command="borg serve'), ( + f"Line should start with restrict,command: {line[:50]}" + ) + assert "@" in line and line.rstrip().endswith(valid_hosts), ( + f"Line should contain user@hostname marker: {line[-40:]}" + ) + assert "--restrict-to-repository" in line, ( + f"Line should have repo restriction: {line[:80]}" + ) class TestBorgRepository: @@ -87,12 +93,14 @@ class TestBorgRepository: repo = host.file(f"{config['home']}/{config['client_repo']}") assert repo.exists assert repo.is_directory - assert repo.user == config['user'] - assert repo.group == config['user'] + assert repo.user == config["user"] + assert repo.group == config["user"] def test_repo_initialized(self, host, config): - c = host.run(f"borg list {config['user']}@localhost:{config['home']}/{config['client_repo']}") - assert c.rc == 0 or 'does not exist' not in c.stderr + c = host.run( + f"borg list {config['user']}@localhost:{config['home']}/{config['client_repo']}" + ) + assert c.rc == 0 or "does not exist" not in c.stderr def test_repo_has_encryption(self, host, config): repo_config = host.file(f"{config['home']}/{config['client_repo']}/config") @@ -110,5 +118,5 @@ class TestBorgRepository: def test_repo_permissions(self, host, config): repo = host.file(f"{config['home']}/{config['client_repo']}") - assert repo.user == config['user'] - assert repo.group == config['user'] + assert repo.user == config["user"] + assert repo.group == config["user"] diff --git a/molecule/default/tests/test_server_setup_multi_instance.py b/molecule/default/tests/test_server_setup_multi_instance.py index a235e2b..90c941c 100644 --- a/molecule/default/tests/test_server_setup_multi_instance.py +++ b/molecule/default/tests/test_server_setup_multi_instance.py @@ -1,12 +1,13 @@ """Tests for borg server multi-instance repos and storage quota features""" + import pytest import re -testinfra_hosts = ['borg-server'] +testinfra_hosts = ["borg-server"] SERVER_CONFIG = { - 'user': 'borg', - 'home': '/opt/borg', + "user": "borg", + "home": "/opt/borg", } @@ -22,13 +23,14 @@ class TestBorgSSHSetupMultiInstance: auth_keys = host.file(f"{config['home']}/.ssh/authorized_keys") content = auth_keys.content_string lines_with_both_repos = [ - line for line in content.split('\n') + line + for line in content.split("\n") if line and f"{config['home']}/configs" in line and f"{config['home']}/home-data" in line ] assert len(lines_with_both_repos) == 1, ( - 'Expected exactly one authorized_keys line containing both configs and home-data repos, ' + "Expected exactly one authorized_keys line containing both configs and home-data repos, " f"found {len(lines_with_both_repos)}" ) @@ -43,8 +45,12 @@ class TestBorgSSHSetupMultiInstance: configs_count = restricted_repos.count(f"{config['home']}/configs") home_data_count = restricted_repos.count(f"{config['home']}/home-data") - assert configs_count == 1, f"configs repo should appear once in authorized_keys, found {configs_count}" - assert home_data_count == 1, f"home-data repo should appear once in authorized_keys, found {home_data_count}" + assert configs_count == 1, ( + f"configs repo should appear once in authorized_keys, found {configs_count}" + ) + assert home_data_count == 1, ( + f"home-data repo should appear once in authorized_keys, found {home_data_count}" + ) def test_authorized_keys_multi_instance_no_cross_host_repos(self, host, config): """Verify multi-instance host doesn't have repos from other hosts in authorized_keys""" @@ -52,8 +58,9 @@ class TestBorgSSHSetupMultiInstance: content = auth_keys.content_string multi_lines = [ - line for line in content.split('\n') - if line.rstrip().endswith('root@borg-client-multi') + line + for line in content.split("\n") + if line.rstrip().endswith("root@borg-client-multi") ] assert len(multi_lines) == 1, ( f"Should have exactly one entry for borg-client-multi, found {len(multi_lines)}" @@ -62,17 +69,17 @@ class TestBorgSSHSetupMultiInstance: multi_line = multi_lines[0] assert f"{config['home']}/configs" in multi_line, ( - 'borg-client-multi line should contain configs repo' + "borg-client-multi line should contain configs repo" ) assert f"{config['home']}/home-data" in multi_line, ( - 'borg-client-multi line should contain home-data repo' + "borg-client-multi line should contain home-data repo" ) assert f"{config['home']}/borg-client" not in multi_line, ( - 'borg-client-multi should NOT have access to borg-client repo' + "borg-client-multi should NOT have access to borg-client repo" ) assert f"{config['home']}/borg-client-2" not in multi_line, ( - 'borg-client-multi should NOT have access to borg-client-2 repo' + "borg-client-multi should NOT have access to borg-client-2 repo" ) @@ -84,9 +91,9 @@ class TestBorgSSHSetupStorageQuota: auth_keys = host.file(f"{config['home']}/.ssh/authorized_keys") content = auth_keys.content_string - quotas = re.findall(r'--storage-quota (\S+)', content) - assert '10G' in quotas, '10G quota should be set for configs-keys repo' - assert '50G' in quotas, '50G quota should be set for home-data-keys repo' + quotas = re.findall(r"--storage-quota (\S+)", content) + assert "10G" in quotas, "10G quota should be set for configs-keys repo" + assert "50G" in quotas, "50G quota should be set for home-data-keys repo" def test_authorized_keys_multi_keys_different_quotas(self, host, config): """Verify per-repo keys can have different storage quotas""" @@ -94,22 +101,25 @@ class TestBorgSSHSetupStorageQuota: content = auth_keys.content_string multi_keys_lines = [ - line for line in content.split('\n') - if line and 'root@borg-client-multi-keys' in line + line + for line in content.split("\n") + if line and "root@borg-client-multi-keys" in line ] assert len(multi_keys_lines) == 2, ( f"Should have two entries for borg-client-multi-keys, found {len(multi_keys_lines)}" ) - configs_line = [l for l in multi_keys_lines if 'configs-keys' in l][0] - home_data_line = [l for l in multi_keys_lines if 'home-data-keys' in l][0] + configs_line = [line for line in multi_keys_lines if "configs-keys" in line][0] + home_data_line = [ + line for line in multi_keys_lines if "home-data-keys" in line + ][0] - assert '--storage-quota 10G' in configs_line, ( - 'configs-keys should have 10G quota' + assert "--storage-quota 10G" in configs_line, ( + "configs-keys should have 10G quota" ) - assert '--storage-quota 50G' in home_data_line, ( - 'home-data-keys should have 50G quota' + assert "--storage-quota 50G" in home_data_line, ( + "home-data-keys should have 50G quota" ) @@ -121,14 +131,14 @@ class TestBorgRepositoryMultiInstance: home_data_repo = host.file(f"{config['home']}/home-data") configs_exists = configs_repo.exists home_data_exists = home_data_repo.exists - assert configs_exists or 'skip' or home_data_exists or True + assert configs_exists or "skip" or home_data_exists or True def test_configs_repo_accessible(self, host, config): c = host.run(f"borg list {config['user']}@localhost:{config['home']}/configs") - if c.rc != 0 and 'does not exist' in c.stderr: - pytest.skip('configs repo not created in this test run') + if c.rc != 0 and "does not exist" in c.stderr: + pytest.skip("configs repo not created in this test run") def test_home_data_repo_accessible(self, host, config): c = host.run(f"borg list {config['user']}@localhost:{config['home']}/home-data") - if c.rc != 0 and 'does not exist' in c.stderr: - pytest.skip('home-data repo not created in this test run') + if c.rc != 0 and "does not exist" in c.stderr: + pytest.skip("home-data repo not created in this test run") diff --git a/molecule/default/tests/test_ssh_connectivity.py b/molecule/default/tests/test_ssh_connectivity.py index f57b7b6..4a983ee 100644 --- a/molecule/default/tests/test_ssh_connectivity.py +++ b/molecule/default/tests/test_ssh_connectivity.py @@ -1,15 +1,21 @@ """Tests for SSH connectivity between client and server""" + import pytest -testinfra_hosts = ['borg-client', 'borg-client-2', 'borg-client-multi', 'borg-client-multi-keys'] +testinfra_hosts = [ + "borg-client", + "borg-client-2", + "borg-client-multi", + "borg-client-multi-keys", +] def get_borg_rsh(host, repo_name): hostname = host.backend.get_hostname() - if hostname != 'borg-client-multi-keys': - return '' + if hostname != "borg-client-multi-keys": + return "" - sanitized_repo_name = repo_name.replace('-', '_') + sanitized_repo_name = repo_name.replace("-", "_") return ( 'BORG_RSH="ssh -i ' f'/root/.ssh/id_ed25519_borgbackup_borg_server_{sanitized_repo_name}"' @@ -17,23 +23,25 @@ def get_borg_rsh(host, repo_name): def get_server_user(hostname): - if hostname == 'borg-client-2': - return 'backupserver' - return 'borg' + if hostname == "borg-client-2": + return "backupserver" + return "borg" def get_server_host(hostname): - if hostname == 'borg-client-2': - return 'borg-server-2' - return 'borg-server' + if hostname == "borg-client-2": + return "borg-server-2" + return "borg-server" def test_ssh_connection_to_server(host): hostname = host.backend.get_hostname() server_user = get_server_user(hostname) server_host = get_server_host(hostname) - c = host.run(f'ssh -o BatchMode=yes -o ConnectTimeout=5 {server_user}@{server_host} echo test') - assert c.rc == 0 or 'Connection refused' not in c.stderr + c = host.run( + f"ssh -o BatchMode=yes -o ConnectTimeout=5 {server_user}@{server_host} echo test" + ) + assert c.rc == 0 or "Connection refused" not in c.stderr def test_no_password_prompt_on_connect(host): @@ -41,16 +49,16 @@ def test_no_password_prompt_on_connect(host): server_user = get_server_user(hostname) server_host = get_server_host(hostname) - if hostname == 'borg-client-multi-keys': + if hostname == "borg-client-multi-keys": c = host.run( - 'ssh -i /root/.ssh/id_ed25519_borgbackup_borg_server_configs_keys ' - '-o BatchMode=yes -o PreferredAuthentications=publickey ' - f'{server_user}@{server_host} exit' + "ssh -i /root/.ssh/id_ed25519_borgbackup_borg_server_configs_keys " + "-o BatchMode=yes -o PreferredAuthentications=publickey " + f"{server_user}@{server_host} exit" ) else: c = host.run( - 'ssh -o BatchMode=yes -o PreferredAuthentications=publickey ' - f'{server_user}@{server_host} exit' + "ssh -o BatchMode=yes -o PreferredAuthentications=publickey " + f"{server_user}@{server_host} exit" ) assert c.rc == 0 @@ -58,10 +66,10 @@ def test_no_password_prompt_on_connect(host): def test_known_hosts_has_correct_entry(host): hostname = host.backend.get_hostname() server_host = get_server_host(hostname) - known_hosts = host.file('/root/.ssh/known_hosts') + known_hosts = host.file("/root/.ssh/known_hosts") content = known_hosts.content_string assert server_host in content - assert 'ssh-' in content + assert "ssh-" in content def test_borg_can_connect_to_server(host): @@ -69,21 +77,23 @@ def test_borg_can_connect_to_server(host): server_user = get_server_user(hostname) server_host = get_server_host(hostname) - if hostname == 'borg-client-multi': - c = host.run(f'borg list {server_user}@{server_host}:/opt/borg/configs') - assert c.rc == 0, 'Should be able to connect to configs repo' - elif hostname == 'borg-client-multi-keys': + if hostname == "borg-client-multi": + c = host.run(f"borg list {server_user}@{server_host}:/opt/borg/configs") + assert c.rc == 0, "Should be able to connect to configs repo" + elif hostname == "borg-client-multi-keys": c = host.run( - f'{get_borg_rsh(host, "configs-keys")} ' - f'borg list {server_user}@{server_host}:/opt/borg/configs-keys' + f"{get_borg_rsh(host, 'configs-keys')} " + f"borg list {server_user}@{server_host}:/opt/borg/configs-keys" ) - assert c.rc == 0, 'Should be able to connect to configs-keys repo' - elif hostname == 'borg-client': - c = host.run(f'borg list {server_user}@{server_host}:/opt/borg/borg-client') + assert c.rc == 0, "Should be able to connect to configs-keys repo" + elif hostname == "borg-client": + c = host.run(f"borg list {server_user}@{server_host}:/opt/borg/borg-client") assert c.rc == 0 - elif hostname == 'borg-client-2': - c = host.run(f'borg list {server_user}@{server_host}:/var/backups/borg-client-2') - assert c.rc == 0, 'Should be able to connect to borg-client-2 repo' + elif hostname == "borg-client-2": + c = host.run( + f"borg list {server_user}@{server_host}:/var/backups/borg-client-2" + ) + assert c.rc == 0, "Should be able to connect to borg-client-2 repo" else: pytest.fail(f"Unexpected hostname: {hostname}") @@ -93,96 +103,90 @@ def test_borg_info_works(host): server_user = get_server_user(hostname) server_host = get_server_host(hostname) - if hostname == 'borg-client-multi': - c = host.run(f'borg info {server_user}@{server_host}:/opt/borg/configs') - assert c.rc == 0, 'Should be able to get info for configs repo' - c2 = host.run(f'borg info {server_user}@{server_host}:/opt/borg/home-data') - assert c2.rc == 0, 'Should be able to get info for home-data repo' - elif hostname == 'borg-client-multi-keys': + if hostname == "borg-client-multi": + c = host.run(f"borg info {server_user}@{server_host}:/opt/borg/configs") + assert c.rc == 0, "Should be able to get info for configs repo" + c2 = host.run(f"borg info {server_user}@{server_host}:/opt/borg/home-data") + assert c2.rc == 0, "Should be able to get info for home-data repo" + elif hostname == "borg-client-multi-keys": c = host.run( - f'{get_borg_rsh(host, "configs-keys")} ' - f'borg info {server_user}@{server_host}:/opt/borg/configs-keys' + f"{get_borg_rsh(host, 'configs-keys')} " + f"borg info {server_user}@{server_host}:/opt/borg/configs-keys" ) - assert c.rc == 0, 'Should be able to get info for configs-keys repo' + assert c.rc == 0, "Should be able to get info for configs-keys repo" c2 = host.run( - f'{get_borg_rsh(host, "home-data-keys")} ' - f'borg info {server_user}@{server_host}:/opt/borg/home-data-keys' + f"{get_borg_rsh(host, 'home-data-keys')} " + f"borg info {server_user}@{server_host}:/opt/borg/home-data-keys" ) - assert c2.rc == 0, 'Should be able to get info for home-data-keys repo' - elif hostname == 'borg-client': - c = host.run(f'borg info {server_user}@{server_host}:/opt/borg/borg-client') + assert c2.rc == 0, "Should be able to get info for home-data-keys repo" + elif hostname == "borg-client": + c = host.run(f"borg info {server_user}@{server_host}:/opt/borg/borg-client") assert c.rc == 0 - elif hostname == 'borg-client-2': - c = host.run(f'borg info {server_user}@{server_host}:/var/backups/borg-client-2') - assert c.rc == 0, 'Should be able to get info for borg-client-2 repo' + elif hostname == "borg-client-2": + c = host.run( + f"borg info {server_user}@{server_host}:/var/backups/borg-client-2" + ) + assert c.rc == 0, "Should be able to get info for borg-client-2 repo" else: pytest.fail(f"Unexpected hostname: {hostname}") def test_multi_instance_can_access_both_repos(host): hostname = host.backend.get_hostname() - if hostname != 'borg-client-multi': + if hostname != "borg-client-multi": return server_user = get_server_user(hostname) server_host = get_server_host(hostname) - c1 = host.run(f'borg list {server_user}@{server_host}:/opt/borg/configs') - assert c1.rc == 0, 'borg-client-multi should access configs repo' + c1 = host.run(f"borg list {server_user}@{server_host}:/opt/borg/configs") + assert c1.rc == 0, "borg-client-multi should access configs repo" - c2 = host.run(f'borg list {server_user}@{server_host}:/opt/borg/home-data') - assert c2.rc == 0, 'borg-client-multi should access home-data repo' + c2 = host.run(f"borg list {server_user}@{server_host}:/opt/borg/home-data") + assert c2.rc == 0, "borg-client-multi should access home-data repo" def test_multi_instance_cannot_access_other_hosts_repos(host): hostname = host.backend.get_hostname() - if hostname != 'borg-client-multi': + if hostname != "borg-client-multi": return server_user = get_server_user(hostname) server_host = get_server_host(hostname) - c1 = host.run(f'borg list {server_user}@{server_host}:/opt/borg/borg-client') - assert c1.rc != 0, ( - 'borg-client-multi should NOT access borg-client repo' - ) + c1 = host.run(f"borg list {server_user}@{server_host}:/opt/borg/borg-client") + assert c1.rc != 0, "borg-client-multi should NOT access borg-client repo" - c2 = host.run(f'borg list {server_user}@{server_host}:/opt/borg/borg-client-2') - assert c2.rc != 0, ( - 'borg-client-multi should NOT access borg-client-2 repo' - ) + c2 = host.run(f"borg list {server_user}@{server_host}:/opt/borg/borg-client-2") + assert c2.rc != 0, "borg-client-multi should NOT access borg-client-2 repo" def test_single_host_cannot_access_multi_repos(host): hostname = host.backend.get_hostname() - if hostname not in ['borg-client', 'borg-client-2']: + if hostname not in ["borg-client", "borg-client-2"]: return server_user = get_server_user(hostname) server_host = get_server_host(hostname) - if hostname == 'borg-client': - c1 = host.run(f'borg list {server_user}@{server_host}:/opt/borg/configs') + if hostname == "borg-client": + c1 = host.run(f"borg list {server_user}@{server_host}:/opt/borg/configs") assert c1.rc != 0, ( - f'{hostname} should NOT access configs repo (belongs to borg-client-multi)' + f"{hostname} should NOT access configs repo (belongs to borg-client-multi)" ) - c2 = host.run('borg list borg@borg-server:/opt/borg/home-data') + c2 = host.run("borg list borg@borg-server:/opt/borg/home-data") assert c2.rc != 0, ( - f'{hostname} should NOT access home-data repo (belongs to borg-client-multi)' + f"{hostname} should NOT access home-data repo (belongs to borg-client-multi)" ) def test_single_hosts_cannot_access_each_others_repos(host): """Verify single-instance hosts cannot access each other's repos""" hostname = host.backend.get_hostname() - if hostname == 'borg-client': - c = host.run('borg list borg@borg-server:/opt/borg/borg-client-2') - assert c.rc != 0, ( - 'borg-client should NOT access borg-client-2 repo' - ) - elif hostname == 'borg-client-2': - c = host.run('borg list borg@borg-server:/opt/borg/borg-client') - assert c.rc != 0, ( - 'borg-client-2 should NOT access borg-client repo' - ) + if hostname == "borg-client": + c = host.run("borg list borg@borg-server:/opt/borg/borg-client-2") + assert c.rc != 0, "borg-client should NOT access borg-client-2 repo" + elif hostname == "borg-client-2": + c = host.run("borg list borg@borg-server:/opt/borg/borg-client") + assert c.rc != 0, "borg-client-2 should NOT access borg-client repo" diff --git a/molecule/default/tests/test_systemd.py b/molecule/default/tests/test_systemd.py index 94b82c4..e68e232 100644 --- a/molecule/default/tests/test_systemd.py +++ b/molecule/default/tests/test_systemd.py @@ -2,44 +2,50 @@ import pytest -testinfra_hosts = ['borg-client', 'borg-client-2', 'borg-client-multi', 'borg-client-nonroot', 'borg-client-multi-keys'] +testinfra_hosts = [ + "borg-client", + "borg-client-2", + "borg-client-multi", + "borg-client-nonroot", + "borg-client-multi-keys", +] CLIENT_CONFIGS = { - 'borg-client': { - 'user': 'root', - 'server': 'borg-server', - 'schedule': '*-*-* 02:00:00', - 'success_exit_status': False, + "borg-client": { + "user": "root", + "server": "borg-server", + "schedule": "*-*-* 02:00:00", + "success_exit_status": False, }, - 'borg-client-2': { - 'user': 'root', - 'server': 'borg-server-2', - 'schedule': '*-*-* 03:00:00', - 'success_exit_status': True, + "borg-client-2": { + "user": "root", + "server": "borg-server-2", + "schedule": "*-*-* 03:00:00", + "success_exit_status": True, }, - 'borg-client-nonroot': { - 'user': 'backupuser', - 'server': 'borg-server', - 'schedule': '*-*-* 02:00:00', - 'success_exit_status': False, + "borg-client-nonroot": { + "user": "backupuser", + "server": "borg-server", + "schedule": "*-*-* 02:00:00", + "success_exit_status": False, }, } MULTI_INSTANCE_CONFIGS = { - 'borg-client-multi': { - 'user': 'root', - 'repos': ['configs', 'home-data'], - 'schedules': { - 'configs': '*-*-* 02:00:00', - 'home-data': '*-*-* 04:00:00', + "borg-client-multi": { + "user": "root", + "repos": ["configs", "home-data"], + "schedules": { + "configs": "*-*-* 02:00:00", + "home-data": "*-*-* 04:00:00", }, }, - 'borg-client-multi-keys': { - 'user': 'root', - 'repos': ['configs-keys', 'home-data-keys'], - 'schedules': { - 'configs-keys': '*-*-* 02:00:00', - 'home-data-keys': '*-*-* 04:00:00', + "borg-client-multi-keys": { + "user": "root", + "repos": ["configs-keys", "home-data-keys"], + "schedules": { + "configs-keys": "*-*-* 02:00:00", + "home-data-keys": "*-*-* 04:00:00", }, }, } @@ -49,127 +55,141 @@ MULTI_INSTANCE_CONFIGS = { def config(host): hostname = host.backend.hostname if hostname in CLIENT_CONFIGS: - return {'type': 'single', **CLIENT_CONFIGS[hostname]} - return {'type': 'multi', **MULTI_INSTANCE_CONFIGS[hostname]} + return {"type": "single", **CLIENT_CONFIGS[hostname]} + return {"type": "multi", **MULTI_INSTANCE_CONFIGS[hostname]} class TestSystemdServiceFile: def test_service_file_exists(self, host, config): - if config['type'] == 'single': - service = host.file(f"/etc/systemd/system/borg_backup@{config['server']}.service") + if config["type"] == "single": + service = host.file( + f"/etc/systemd/system/borg_backup@{config['server']}.service" + ) assert service.exists - assert service.user == 'root' - assert service.group == 'root' + assert service.user == "root" + assert service.group == "root" assert service.mode == 0o644 else: - for repo in config['repos']: + for repo in config["repos"]: service = host.file(f"/etc/systemd/system/borg_backup@{repo}.service") assert service.exists - assert service.user == 'root' - assert service.group == 'root' + assert service.user == "root" + assert service.group == "root" def test_service_content(self, host, config): - if config['type'] == 'single': - service = host.file(f"/etc/systemd/system/borg_backup@{config['server']}.service") - assert service.contains('[Unit]') - assert service.contains('[Service]') - assert service.contains('[Install]') - assert service.contains('Type=oneshot') - assert service.contains('ExecStart=/usr/local/bin/run_borg_backup') + if config["type"] == "single": + service = host.file( + f"/etc/systemd/system/borg_backup@{config['server']}.service" + ) + assert service.contains("[Unit]") + assert service.contains("[Service]") + assert service.contains("[Install]") + assert service.contains("Type=oneshot") + assert service.contains("ExecStart=/usr/local/bin/run_borg_backup") else: - for repo in config['repos']: + for repo in config["repos"]: service = host.file(f"/etc/systemd/system/borg_backup@{repo}.service") - assert service.contains('[Unit]') - assert service.contains('[Service]') - assert service.contains('[Install]') - assert service.contains('Type=oneshot') + assert service.contains("[Unit]") + assert service.contains("[Service]") + assert service.contains("[Install]") + assert service.contains("Type=oneshot") def test_service_user(self, host, config): - if config['type'] == 'single': - service = host.file(f"/etc/systemd/system/borg_backup@{config['server']}.service") + if config["type"] == "single": + service = host.file( + f"/etc/systemd/system/borg_backup@{config['server']}.service" + ) assert service.contains(f"User={config['user']}") assert service.contains(f"Group={config['user']}") else: - for repo in config['repos']: + for repo in config["repos"]: service = host.file(f"/etc/systemd/system/borg_backup@{repo}.service") assert service.contains(f"User={config['user']}") assert service.contains(f"Group={config['user']}") def test_success_exit_status(self, host, config): - if config['type'] != 'single': + if config["type"] != "single": return - service = host.file(f"/etc/systemd/system/borg_backup@{config['server']}.service") + service = host.file( + f"/etc/systemd/system/borg_backup@{config['server']}.service" + ) assert service.exists - if config['success_exit_status']: - assert service.contains('SuccessExitStatus=1 TEMPFAIL') + if config["success_exit_status"]: + assert service.contains("SuccessExitStatus=1 TEMPFAIL") else: - assert not service.contains('SuccessExitStatus=') + assert not service.contains("SuccessExitStatus=") class TestSystemdTimerFile: def test_timer_file_exists(self, host, config): - if config['type'] == 'single': - timer = host.file(f"/etc/systemd/system/borg_backup@{config['server']}.timer") + if config["type"] == "single": + timer = host.file( + f"/etc/systemd/system/borg_backup@{config['server']}.timer" + ) assert timer.exists - assert timer.user == 'root' - assert timer.group == 'root' + assert timer.user == "root" + assert timer.group == "root" assert timer.mode == 0o644 else: - for repo in config['repos']: + for repo in config["repos"]: timer = host.file(f"/etc/systemd/system/borg_backup@{repo}.timer") assert timer.exists def test_timer_content(self, host, config): - if config['type'] == 'single': - timer = host.file(f"/etc/systemd/system/borg_backup@{config['server']}.timer") - assert timer.contains('[Unit]') - assert timer.contains('[Timer]') - assert timer.contains('[Install]') - assert timer.contains('OnCalendar=') - assert timer.contains('AccuracySec=') + if config["type"] == "single": + timer = host.file( + f"/etc/systemd/system/borg_backup@{config['server']}.timer" + ) + assert timer.contains("[Unit]") + assert timer.contains("[Timer]") + assert timer.contains("[Install]") + assert timer.contains("OnCalendar=") + assert timer.contains("AccuracySec=") else: - for repo in config['repos']: + for repo in config["repos"]: timer = host.file(f"/etc/systemd/system/borg_backup@{repo}.timer") - assert timer.contains('[Unit]') - assert timer.contains('[Timer]') - assert timer.contains('[Install]') - assert timer.contains('OnCalendar=') - assert timer.contains('AccuracySec=') + assert timer.contains("[Unit]") + assert timer.contains("[Timer]") + assert timer.contains("[Install]") + assert timer.contains("OnCalendar=") + assert timer.contains("AccuracySec=") def test_timer_schedule(self, host, config): - if config['type'] == 'single': - timer = host.file(f"/etc/systemd/system/borg_backup@{config['server']}.timer") + if config["type"] == "single": + timer = host.file( + f"/etc/systemd/system/borg_backup@{config['server']}.timer" + ) assert f"OnCalendar={config['schedule']}" in timer.content_string else: - for repo in config['repos']: + for repo in config["repos"]: timer = host.file(f"/etc/systemd/system/borg_backup@{repo}.timer") assert f"OnCalendar={config['schedules'][repo]}" in timer.content_string class TestSystemdState: def test_timer_enabled(self, host, config): - if config['type'] == 'single': + if config["type"] == "single": timer_name = f"borg_backup@{config['server']}.timer" c = host.run(f"systemctl is-enabled {timer_name}") assert c.rc == 0 - assert c.stdout.strip() == 'enabled' + assert c.stdout.strip() == "enabled" else: - for repo in config['repos']: + for repo in config["repos"]: c = host.run(f"systemctl is-enabled borg_backup@{repo}.timer") assert c.rc == 0 - assert c.stdout.strip() == 'enabled' + assert c.stdout.strip() == "enabled" def test_timer_active(self, host, config): - if config['type'] == 'single': + if config["type"] == "single": timer_name = f"borg_backup@{config['server']}.timer" c = host.run(f"systemctl is-active {timer_name}") assert c.rc == 0 else: - for repo in config['repos']: + for repo in config["repos"]: c = host.run(f"systemctl is-active borg_backup@{repo}.timer") assert c.rc == 0 def test_daemon_reload_ok(self, host, config): - c = host.run('systemctl daemon-reload') + c = host.run("systemctl daemon-reload") assert c.rc == 0 -- cgit v1.2.3