"""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 = [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 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")