mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-01-28 08:03:36 +00:00
Signed-off-by: Fioddor Superconcentrado <fioddor@gmail.com> [sunil: Minor refactoring, relax a test to make it work on CI] [sunil: Run tests only when systemd, ip commands are available] Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org> Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
140 lines
4.4 KiB
Python
140 lines
4.4 KiB
Python
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
"""
|
|
Test module for key/value store.
|
|
"""
|
|
|
|
import json
|
|
import pathlib
|
|
import subprocess
|
|
from unittest.mock import patch
|
|
|
|
import pytest
|
|
|
|
from plinth.action_utils import (get_addresses, get_hostname,
|
|
is_systemd_running, service_action,
|
|
service_disable, service_enable,
|
|
service_is_enabled, service_is_running,
|
|
service_reload, service_restart,
|
|
service_start, service_stop,
|
|
service_try_restart, service_unmask)
|
|
|
|
UNKNOWN = 'unknowndeamon'
|
|
|
|
systemctl_path = pathlib.Path('/usr/bin/systemctl')
|
|
systemd_installed = pytest.mark.skipif(not systemctl_path.exists(),
|
|
reason='systemd not available')
|
|
|
|
ip_path = pathlib.Path('/usr/bin/ip')
|
|
ip_installed = pytest.mark.skipif(not ip_path.exists(),
|
|
reason='ip command not available')
|
|
|
|
|
|
@patch('os.path.exists')
|
|
def test_is_systemd_running(mock):
|
|
"""Trivial white box test for a trivial implementation."""
|
|
mock.return_value = True
|
|
assert is_systemd_running()
|
|
mock.return_value = False
|
|
assert not is_systemd_running()
|
|
|
|
|
|
@systemd_installed
|
|
def test_service_checks():
|
|
"""Test basic checks on status of an arbitrary service."""
|
|
assert not service_is_running(UNKNOWN)
|
|
assert not service_is_enabled(UNKNOWN)
|
|
|
|
# expected is best if: generic. Alternatives: systemd-sysctl, logrotate
|
|
expected = 'networking'
|
|
if not service_is_running(expected):
|
|
pytest.skip(f'Needs service {expected} running.')
|
|
|
|
assert service_is_enabled(expected)
|
|
|
|
|
|
@pytest.mark.usefixtures('needs_root')
|
|
@systemd_installed
|
|
def test_service_enable_and_disable():
|
|
"""Test enabling and disabling of an arbitrary service."""
|
|
# service is best if: non-essential part of FreedomBox that restarts fast
|
|
service = 'unattended-upgrades'
|
|
if not service_is_enabled(service):
|
|
reason = f'Needs service {service} enabled.'
|
|
pytest.skip(reason)
|
|
|
|
service_disable(service)
|
|
assert not service_is_running(service)
|
|
service_enable(service)
|
|
assert service_is_running(service)
|
|
|
|
# Ignore unknown services, don't fail:
|
|
service_disable(UNKNOWN)
|
|
service_enable(UNKNOWN)
|
|
|
|
|
|
@patch('plinth.action_utils.service_action')
|
|
@systemd_installed
|
|
def test_service_actions(mock):
|
|
"""Trivial white box test for trivial implementations."""
|
|
service_start(UNKNOWN)
|
|
mock.assert_called_with(UNKNOWN, 'start')
|
|
service_stop(UNKNOWN)
|
|
mock.assert_called_with(UNKNOWN, 'stop')
|
|
service_restart(UNKNOWN)
|
|
mock.assert_called_with(UNKNOWN, 'restart')
|
|
service_try_restart(UNKNOWN)
|
|
mock.assert_called_with(UNKNOWN, 'try-restart')
|
|
service_reload(UNKNOWN)
|
|
mock.assert_called_with(UNKNOWN, 'reload')
|
|
|
|
|
|
@pytest.mark.usefixtures('needs_root')
|
|
@systemd_installed
|
|
def test_service_unmask():
|
|
"""Test unmasking of an arbitrary masked service."""
|
|
|
|
def is_masked(service):
|
|
process = subprocess.run([
|
|
'systemctl', 'list-unit-files', '--output=json',
|
|
service + '.service'
|
|
], stdout=subprocess.PIPE, check=False)
|
|
output = json.loads(process.stdout)
|
|
return output[0]['state'] == 'masked' if output else False
|
|
|
|
# SERVICE is best if: part of FreedomBox, so we can mess with least risk.
|
|
service = 'samba-ad-dc'
|
|
if not is_masked(service):
|
|
pytest.skip(f'Needs service {service} masked.')
|
|
|
|
service_unmask(service)
|
|
assert not is_masked(service)
|
|
|
|
service_action(service, 'mask')
|
|
assert is_masked(service)
|
|
|
|
|
|
def test_get_hostname():
|
|
"""get_hostname returns a string.
|
|
|
|
In fact, the maximum length for a hostname is 253 characters, but
|
|
anything longer than 80 is very suspicious, so we fail the test.
|
|
|
|
To avoid error messages pass as hostnames we seek and fail if we find
|
|
some unexpected characters.
|
|
"""
|
|
hostname = get_hostname()
|
|
assert hostname
|
|
assert isinstance(hostname, str)
|
|
assert len(hostname) < 80
|
|
for char in ' ,:;!?=$%&@*+()[]{}<>"\'':
|
|
assert char not in hostname
|
|
|
|
|
|
@ip_installed
|
|
def test_get_addresses():
|
|
"""Test that any FreedomBox has some addresses."""
|
|
ips = get_addresses()
|
|
assert len(ips) > 3 # min: ip, 2x'localhost', hostname
|
|
for address in ips:
|
|
assert address['kind'] in ('4', '6')
|