"""Tests for decryption keys file structure""" import os import stat import pytest def _get_keys_path(): """Get decryption_keys.yml path from molecule environment""" scenario_dir = os.environ.get("MOLECULE_SCENARIO_DIRECTORY") if scenario_dir: 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") 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") 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") file_stat = os.stat(keys_path) file_mode = stat.S_IMODE(file_stat.st_mode) assert file_mode == 0o600, ( f"decryption_keys.yml should have 0600 permissions, got {oct(file_mode)}" ) 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") with open(keys_path, "r") as f: content = f.read() assert "borg-client_borg-client:" in content, ( "Single repo host should have key named 'hostname_repo_name'" ) 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") with open(keys_path, "r") as f: content = f.read() assert "borg-client-multi_configs:" in content, ( "Multi-instance host should have key for 'configs' repo" ) assert "borg-client-multi_home-data:" in content, ( "Multi-instance host should have key for 'home-data' repo" ) 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") 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:") assert configs_count == 1, ( f"configs key should appear exactly once, found {configs_count}" ) assert home_data_count == 1, ( f"home-data key should appear exactly once, found {home_data_count}" ) 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") with open(keys_path, "r") as f: content = f.read() assert "BORG PAPER KEY" in content, ( "Decryption keys should contain borg paper key format" ) 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") 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:", ] for key in expected_keys: assert key in content, f"Expected key {key} not found in decryption_keys.yml" 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") 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)" )