"""Tests for borg server multi-instance repos and storage quota features""" import pytest import re testinfra_hosts = ['borg-server'] SERVER_CONFIG = { 'user': 'borg', 'home': '/opt/borg', } @pytest.fixture def config(host): return SERVER_CONFIG class TestBorgSSHSetupMultiInstance: """Tests for multi-instance repo configuration""" def test_authorized_keys_multi_instance_single_line(self, host, config): 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') 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, ' f"found {len(lines_with_both_repos)}" ) def test_authorized_keys_multi_instance_repo_count(self, host, config): auth_keys = host.file(f"{config['home']}/.ssh/authorized_keys") content = auth_keys.content_string restricted_repos = re.findall( r'--restrict-to-repository ([^\s"]+)', content, ) 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}" 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""" auth_keys = host.file(f"{config['home']}/.ssh/authorized_keys") content = auth_keys.content_string multi_lines = [ 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)}" ) multi_line = multi_lines[0] assert f"{config['home']}/configs" in multi_line, ( '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' ) assert f"{config['home']}/borg-client" not in multi_line, ( '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' ) class TestBorgSSHSetupStorageQuota: """Tests for storage quota configuration""" def test_authorized_keys_has_storage_quota(self, host, config): """Verify storage quota is set in authorized_keys for configured repos""" 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' def test_authorized_keys_multi_keys_different_quotas(self, host, config): """Verify per-repo keys can have different storage quotas""" auth_keys = host.file(f"{config['home']}/.ssh/authorized_keys") 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 ] 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] 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' ) class TestBorgRepositoryMultiInstance: """Tests for multi-instance repo accessibility""" def test_multi_instance_repos_exist(self, host, config): configs_repo = host.file(f"{config['home']}/configs") 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 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') 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')