mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-01-21 07:55:00 +00:00
- To be used when configuration has to change based on the package version. Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
235 lines
8.5 KiB
Python
235 lines
8.5 KiB
Python
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
"""
|
|
Test the component that manages drop-in configuration.
|
|
"""
|
|
|
|
from unittest.mock import Mock, patch
|
|
|
|
import pytest
|
|
|
|
from plinth.app import App
|
|
from plinth.config import DropinConfigs
|
|
from plinth.diagnostic_check import DiagnosticCheck, Result
|
|
|
|
pytestmark = pytest.mark.usefixtures('mock_privileged')
|
|
privileged_modules_to_mock = ['plinth.privileged.config']
|
|
|
|
|
|
@pytest.fixture(name='dropin_configs')
|
|
def fixture_dropin_configs():
|
|
"""Fixture to create a basic drop-in configs component."""
|
|
|
|
class AppTest(App):
|
|
app_id = 'test-app'
|
|
|
|
app = AppTest()
|
|
component = DropinConfigs('test-component',
|
|
['/etc/test/path1', '/etc/path2'])
|
|
app.add(component)
|
|
|
|
return component
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def fixture_assert_dropin_config(dropin_configs):
|
|
"""Mock asserting dropin config path."""
|
|
with patch('plinth.privileged.config._get_managed_dropin_config') as mock:
|
|
mock.return_value = dropin_configs
|
|
yield
|
|
|
|
|
|
def test_dropin_configs_init(dropin_configs):
|
|
"""Test initialization of drop-in configs component."""
|
|
assert dropin_configs.component_id == 'test-component'
|
|
assert dropin_configs.etc_paths[0] == '/etc/test/path1'
|
|
assert dropin_configs.etc_paths[1] == '/etc/path2'
|
|
assert not dropin_configs.copy_only
|
|
|
|
component = DropinConfigs('test-component', [], copy_only=False)
|
|
assert not component.copy_only
|
|
|
|
component = DropinConfigs('test-component', [], copy_only=True)
|
|
assert component.copy_only
|
|
|
|
|
|
def _assert_symlinks(component, tmp_path, should_exist, copy_only=False):
|
|
"""Assert that symlinks exists and they point correctly."""
|
|
for path in component.etc_paths:
|
|
full_path = tmp_path / path.lstrip('/')
|
|
if should_exist:
|
|
target = tmp_path / 'usr/share/freedombox' / path.lstrip('/')
|
|
if copy_only:
|
|
assert full_path.is_file()
|
|
assert full_path.read_text() == target.read_text()
|
|
else:
|
|
assert full_path.is_symlink()
|
|
assert full_path.resolve() == target
|
|
else:
|
|
assert not full_path.exists()
|
|
|
|
|
|
def test_dropin_configs_setup(dropin_configs, tmp_path):
|
|
"""Test setup for dropin configs component."""
|
|
with patch('plinth.config.DropinConfigs.ROOT', new=tmp_path):
|
|
is_enabled = Mock()
|
|
App.get('test-app').is_enabled = is_enabled
|
|
|
|
is_enabled.return_value = False
|
|
dropin_configs.setup(old_version=0)
|
|
_assert_symlinks(dropin_configs, tmp_path, should_exist=False)
|
|
|
|
is_enabled.return_value = True
|
|
dropin_configs.setup(old_version=0)
|
|
_assert_symlinks(dropin_configs, tmp_path, should_exist=True)
|
|
|
|
|
|
def test_dropin_configs_enable_disable_symlinks(dropin_configs, tmp_path):
|
|
"""Test enable/disable for dropin configs component for symlinks."""
|
|
with patch('plinth.config.DropinConfigs.ROOT', new=tmp_path):
|
|
# Enable when nothing exists
|
|
dropin_configs.enable()
|
|
_assert_symlinks(dropin_configs, tmp_path, should_exist=True)
|
|
|
|
# Disable
|
|
dropin_configs.disable()
|
|
_assert_symlinks(dropin_configs, tmp_path, should_exist=False)
|
|
|
|
# Enable when a file already exists
|
|
dropin_configs.disable()
|
|
etc_path = dropin_configs.get_etc_path('/etc/test/path1')
|
|
etc_path.touch()
|
|
dropin_configs.enable()
|
|
_assert_symlinks(dropin_configs, tmp_path, should_exist=True)
|
|
|
|
# When symlink already exists to wrong location
|
|
dropin_configs.disable()
|
|
etc_path.symlink_to('/blah')
|
|
dropin_configs.enable()
|
|
_assert_symlinks(dropin_configs, tmp_path, should_exist=True)
|
|
|
|
# When symlink already exists to correct location
|
|
dropin_configs.disable()
|
|
target_path = dropin_configs.get_target_path('/etc/test/path1')
|
|
etc_path.symlink_to(target_path)
|
|
dropin_configs.enable()
|
|
_assert_symlinks(dropin_configs, tmp_path, should_exist=True)
|
|
|
|
|
|
def test_dropin_configs_enable_disable_copy_only(dropin_configs, tmp_path):
|
|
"""Test enable/disable for dropin configs component for copying."""
|
|
with patch('plinth.config.DropinConfigs.ROOT', new=tmp_path):
|
|
dropin_configs.copy_only = True
|
|
for path in ['/etc/test/path1', '/etc/path2']:
|
|
target = dropin_configs.get_target_path(path)
|
|
target.parent.mkdir(parents=True, exist_ok=True)
|
|
target.write_text('test-config-content')
|
|
|
|
# Enable when nothing exists
|
|
dropin_configs.enable()
|
|
_assert_symlinks(dropin_configs, tmp_path, should_exist=True,
|
|
copy_only=True)
|
|
|
|
# Disable
|
|
dropin_configs.disable()
|
|
_assert_symlinks(dropin_configs, tmp_path, should_exist=False,
|
|
copy_only=True)
|
|
|
|
# Enable when a file already exists with wrong content
|
|
dropin_configs.disable()
|
|
etc_path = dropin_configs.get_etc_path('/etc/test/path1')
|
|
etc_path.write_text('x-invalid-content')
|
|
dropin_configs.enable()
|
|
_assert_symlinks(dropin_configs, tmp_path, should_exist=True,
|
|
copy_only=True)
|
|
|
|
# When the file is a symlink
|
|
dropin_configs.disable()
|
|
etc_path.symlink_to('/blah')
|
|
dropin_configs.enable()
|
|
_assert_symlinks(dropin_configs, tmp_path, should_exist=True,
|
|
copy_only=True)
|
|
|
|
# When copy already exists with correct content
|
|
dropin_configs.disable()
|
|
etc_path.write_text('test-config-content')
|
|
dropin_configs.enable()
|
|
_assert_symlinks(dropin_configs, tmp_path, should_exist=True,
|
|
copy_only=True)
|
|
|
|
|
|
def test_dropin_config_diagnose_symlinks(dropin_configs, tmp_path):
|
|
"""Test diagnosing dropin configs for symlinks."""
|
|
with patch('plinth.config.DropinConfigs.ROOT', new=tmp_path):
|
|
# Nothing exists
|
|
results = dropin_configs.diagnose()
|
|
assert results == [
|
|
DiagnosticCheck(
|
|
f'dropin-config-{tmp_path}/etc/test/path1',
|
|
'Static configuration {etc_path} is setup properly',
|
|
Result.FAILED, {'etc_path': f'{tmp_path}/etc/test/path1'},
|
|
'test-component'),
|
|
DiagnosticCheck(
|
|
f'dropin-config-{tmp_path}/etc/path2',
|
|
'Static configuration {etc_path} is setup properly',
|
|
Result.FAILED, {'etc_path': f'{tmp_path}/etc/path2'},
|
|
'test-component'),
|
|
]
|
|
|
|
# Proper symlinks exist
|
|
dropin_configs.enable()
|
|
results = dropin_configs.diagnose()
|
|
assert results[0].result == 'passed'
|
|
assert results[1].result == 'passed'
|
|
|
|
# A file exists instead of symlink
|
|
dropin_configs.disable()
|
|
etc_path = dropin_configs.get_etc_path('/etc/test/path1')
|
|
etc_path.touch()
|
|
results = dropin_configs.diagnose()
|
|
assert results[0].result == 'failed'
|
|
|
|
# Symlink points to wrong location
|
|
dropin_configs.disable()
|
|
etc_path.symlink_to('/blah')
|
|
results = dropin_configs.diagnose()
|
|
assert results[0].result == 'failed'
|
|
|
|
# Symlink is recreated
|
|
dropin_configs.enable()
|
|
results = dropin_configs.diagnose()
|
|
assert results[0].result == 'passed'
|
|
|
|
|
|
def test_dropin_config_diagnose_copy_only(dropin_configs, tmp_path):
|
|
"""Test diagnosing dropin configs."""
|
|
with patch('plinth.config.DropinConfigs.ROOT', new=tmp_path):
|
|
dropin_configs.copy_only = True
|
|
for path in ['/etc/test/path1', '/etc/path2']:
|
|
target = dropin_configs.get_target_path(path)
|
|
target.parent.mkdir(parents=True, exist_ok=True)
|
|
target.write_text('test-config-content')
|
|
|
|
# Nothing exists
|
|
results = dropin_configs.diagnose()
|
|
assert results[0].result == 'failed'
|
|
assert results[1].result == 'failed'
|
|
|
|
# Proper copies exist
|
|
dropin_configs.enable()
|
|
results = dropin_configs.diagnose()
|
|
assert results[0].result == 'passed'
|
|
assert results[1].result == 'passed'
|
|
|
|
# A symlink exists instead of a copied file
|
|
dropin_configs.disable()
|
|
etc_path = dropin_configs.get_etc_path('/etc/test/path1')
|
|
etc_path.symlink_to('/blah')
|
|
results = dropin_configs.diagnose()
|
|
assert results[0].result == 'failed'
|
|
|
|
# Copied file contains wrong contents
|
|
dropin_configs.disable()
|
|
etc_path.write_text('x-invalid-contents')
|
|
results = dropin_configs.diagnose()
|
|
assert results[0].result == 'failed'
|