diff options
Diffstat (limited to 'molecule/default/tests/test_server_setup_multi_instance.py')
| -rw-r--r-- | molecule/default/tests/test_server_setup_multi_instance.py | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/molecule/default/tests/test_server_setup_multi_instance.py b/molecule/default/tests/test_server_setup_multi_instance.py new file mode 100644 index 0000000..a235e2b --- /dev/null +++ b/molecule/default/tests/test_server_setup_multi_instance.py @@ -0,0 +1,134 @@ +"""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') |