mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-05-20 10:34:30 +00:00
test: Add tests for action utilities
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>
This commit is contained in:
parent
aef0dcd381
commit
e11ce5f58f
139
plinth/tests/test_action_utils.py
Normal file
139
plinth/tests/test_action_utils.py
Normal file
@ -0,0 +1,139 @@
|
||||
# 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')
|
||||
Loading…
x
Reference in New Issue
Block a user