Fix contrast issues with text-muted and bg-dark classes
- Fixed Bootstrap bg-dark class to use better contrasting color - Added comprehensive text-muted contrast fixes for various contexts - Improved dark theme colors for better accessibility - Fixed CSS inheritance issues for code elements in dark contexts - All color choices meet WCAG AA contrast requirements
This commit is contained in:
298
tests/test_unit_file.py
Normal file
298
tests/test_unit_file.py
Normal file
@@ -0,0 +1,298 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Tests for the systemd unit file parser and validator.
|
||||
"""
|
||||
|
||||
from backend.app.core.unit_file import SystemdUnitFile, UnitType, create_unit_file
|
||||
|
||||
|
||||
class TestSystemdUnitFile:
|
||||
"""Test cases for the SystemdUnitFile class."""
|
||||
|
||||
def test_parse_simple_service(self):
|
||||
"""Test parsing a simple service unit file."""
|
||||
content = """[Unit]
|
||||
Description=Test Service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/bin/test
|
||||
User=testuser
|
||||
Restart=on-failure
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
"""
|
||||
unit = SystemdUnitFile(content=content)
|
||||
assert unit.get_unit_type() == UnitType.SERVICE
|
||||
|
||||
info = unit.get_info()
|
||||
assert info.description == "Test Service"
|
||||
assert info.unit_type == UnitType.SERVICE
|
||||
|
||||
def test_validate_valid_service(self):
|
||||
"""Test validation of a valid service unit file."""
|
||||
content = """[Unit]
|
||||
Description=Valid Service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/bin/valid-service
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
"""
|
||||
unit = SystemdUnitFile(content=content)
|
||||
errors = unit.validate()
|
||||
|
||||
# Should have no errors
|
||||
error_list = [e for e in errors if e.severity == "error"]
|
||||
assert len(error_list) == 0
|
||||
|
||||
def test_validate_invalid_service_type(self):
|
||||
"""Test validation catches invalid service type."""
|
||||
content = """[Unit]
|
||||
Description=Invalid Service
|
||||
|
||||
[Service]
|
||||
Type=invalid-type
|
||||
ExecStart=/usr/bin/test
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
"""
|
||||
unit = SystemdUnitFile(content=content)
|
||||
errors = unit.validate()
|
||||
|
||||
# Should have an error about invalid service type
|
||||
error_list = [e for e in errors if e.severity == "error"]
|
||||
assert len(error_list) > 0
|
||||
assert any("Invalid service type" in e.message for e in error_list)
|
||||
|
||||
def test_validate_missing_exec_start(self):
|
||||
"""Test validation catches missing ExecStart for simple service."""
|
||||
content = """[Unit]
|
||||
Description=Missing ExecStart
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=testuser
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
"""
|
||||
unit = SystemdUnitFile(content=content)
|
||||
errors = unit.validate()
|
||||
|
||||
# Should have an error about missing ExecStart
|
||||
error_list = [e for e in errors if e.severity == "error"]
|
||||
assert len(error_list) > 0
|
||||
assert any("ExecStart" in e.message for e in error_list)
|
||||
|
||||
def test_parse_timer_unit(self):
|
||||
"""Test parsing a timer unit file."""
|
||||
content = """[Unit]
|
||||
Description=Test Timer
|
||||
|
||||
[Timer]
|
||||
OnCalendar=daily
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
"""
|
||||
unit = SystemdUnitFile(content=content)
|
||||
assert unit.get_unit_type() == UnitType.TIMER
|
||||
|
||||
def test_validate_timer_missing_schedule(self):
|
||||
"""Test validation catches timer without schedule."""
|
||||
content = """[Unit]
|
||||
Description=Timer without schedule
|
||||
|
||||
[Timer]
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
"""
|
||||
unit = SystemdUnitFile(content=content)
|
||||
errors = unit.validate()
|
||||
|
||||
# Should have an error about missing timer specification
|
||||
error_list = [e for e in errors if e.severity == "error"]
|
||||
assert len(error_list) > 0
|
||||
assert any("timing specification" in e.message.lower() for e in error_list)
|
||||
|
||||
def test_parse_socket_unit(self):
|
||||
"""Test parsing a socket unit file."""
|
||||
content = """[Unit]
|
||||
Description=Test Socket
|
||||
|
||||
[Socket]
|
||||
ListenStream=127.0.0.1:8080
|
||||
SocketUser=www-data
|
||||
|
||||
[Install]
|
||||
WantedBy=sockets.target
|
||||
"""
|
||||
unit = SystemdUnitFile(content=content)
|
||||
assert unit.get_unit_type() == UnitType.SOCKET
|
||||
|
||||
def test_validate_socket_missing_listen(self):
|
||||
"""Test validation catches socket without listen specification."""
|
||||
content = """[Unit]
|
||||
Description=Socket without listen
|
||||
|
||||
[Socket]
|
||||
SocketUser=www-data
|
||||
|
||||
[Install]
|
||||
WantedBy=sockets.target
|
||||
"""
|
||||
unit = SystemdUnitFile(content=content)
|
||||
errors = unit.validate()
|
||||
|
||||
# Should have an error about missing listen specification
|
||||
error_list = [e for e in errors if e.severity == "error"]
|
||||
assert len(error_list) > 0
|
||||
assert any("Listen specification" in e.message for e in error_list)
|
||||
|
||||
def test_set_and_get_values(self):
|
||||
"""Test setting and getting values in unit file."""
|
||||
unit = SystemdUnitFile()
|
||||
|
||||
unit.set_value("Unit", "Description", "Test Description")
|
||||
unit.set_value("Service", "Type", "simple")
|
||||
unit.set_value("Service", "ExecStart", "/usr/bin/test")
|
||||
|
||||
assert unit.get_value("Unit", "Description") == "Test Description"
|
||||
assert unit.get_value("Service", "Type") == "simple"
|
||||
assert unit.get_value("Service", "ExecStart") == "/usr/bin/test"
|
||||
|
||||
def test_remove_key(self):
|
||||
"""Test removing keys from unit file."""
|
||||
unit = SystemdUnitFile()
|
||||
unit.set_value("Service", "User", "testuser")
|
||||
|
||||
assert unit.get_value("Service", "User") == "testuser"
|
||||
|
||||
removed = unit.remove_key("Service", "User")
|
||||
assert removed is True
|
||||
assert unit.get_value("Service", "User") is None
|
||||
|
||||
def test_to_string(self):
|
||||
"""Test converting unit file back to string format."""
|
||||
unit = SystemdUnitFile()
|
||||
unit.set_value("Unit", "Description", "Test Service")
|
||||
unit.set_value("Service", "Type", "simple")
|
||||
unit.set_value("Service", "ExecStart", "/usr/bin/test")
|
||||
unit.set_value("Install", "WantedBy", "multi-user.target")
|
||||
|
||||
content = unit.to_string()
|
||||
|
||||
assert "[Unit]" in content
|
||||
assert "Description=Test Service" in content
|
||||
assert "[Service]" in content
|
||||
assert "Type=simple" in content
|
||||
assert "ExecStart=/usr/bin/test" in content
|
||||
assert "[Install]" in content
|
||||
assert "WantedBy=multi-user.target" in content
|
||||
|
||||
def test_validate_time_span(self):
|
||||
"""Test time span validation."""
|
||||
unit = SystemdUnitFile()
|
||||
|
||||
# Valid time spans
|
||||
valid_content = """[Service]
|
||||
TimeoutStartSec=30s
|
||||
RestartSec=5min
|
||||
"""
|
||||
unit = SystemdUnitFile(content=valid_content)
|
||||
errors = unit.validate()
|
||||
time_errors = [e for e in errors if "time span" in e.message.lower()]
|
||||
assert len(time_errors) == 0
|
||||
|
||||
# Invalid time span
|
||||
invalid_content = """[Service]
|
||||
TimeoutStartSec=invalid-time
|
||||
"""
|
||||
unit = SystemdUnitFile(content=invalid_content)
|
||||
errors = unit.validate()
|
||||
time_errors = [e for e in errors if "time span" in e.message.lower()]
|
||||
assert len(time_errors) > 0
|
||||
|
||||
|
||||
class TestCreateUnitFile:
|
||||
"""Test cases for the create_unit_file function."""
|
||||
|
||||
def test_create_simple_service(self):
|
||||
"""Test creating a simple service unit file."""
|
||||
unit = create_unit_file(
|
||||
UnitType.SERVICE,
|
||||
description="Test Service",
|
||||
exec_start="/usr/bin/test",
|
||||
user="testuser",
|
||||
restart="on-failure",
|
||||
)
|
||||
|
||||
assert unit.get_unit_type() == UnitType.SERVICE
|
||||
assert unit.get_value("Unit", "Description") == "Test Service"
|
||||
assert unit.get_value("Service", "ExecStart") == "/usr/bin/test"
|
||||
assert unit.get_value("Service", "User") == "testuser"
|
||||
assert unit.get_value("Service", "Restart") == "on-failure"
|
||||
|
||||
def test_create_timer_unit(self):
|
||||
"""Test creating a timer unit file."""
|
||||
unit = create_unit_file(
|
||||
UnitType.TIMER,
|
||||
description="Test Timer",
|
||||
on_calendar="daily",
|
||||
persistent=True,
|
||||
)
|
||||
|
||||
assert unit.get_unit_type() == UnitType.TIMER
|
||||
assert unit.get_value("Unit", "Description") == "Test Timer"
|
||||
assert unit.get_value("Timer", "OnCalendar") == "daily"
|
||||
assert unit.get_value("Timer", "Persistent") == "true"
|
||||
|
||||
def test_create_socket_unit(self):
|
||||
"""Test creating a socket unit file."""
|
||||
unit = create_unit_file(
|
||||
UnitType.SOCKET, description="Test Socket", listen_stream="127.0.0.1:8080"
|
||||
)
|
||||
|
||||
assert unit.get_unit_type() == UnitType.SOCKET
|
||||
assert unit.get_value("Unit", "Description") == "Test Socket"
|
||||
assert unit.get_value("Socket", "ListenStream") == "127.0.0.1:8080"
|
||||
|
||||
def test_create_mount_unit(self):
|
||||
"""Test creating a mount unit file."""
|
||||
unit = create_unit_file(
|
||||
UnitType.MOUNT,
|
||||
description="Test Mount",
|
||||
what="/dev/sdb1",
|
||||
where="/mnt/data",
|
||||
type="ext4",
|
||||
)
|
||||
|
||||
assert unit.get_unit_type() == UnitType.MOUNT
|
||||
assert unit.get_value("Unit", "Description") == "Test Mount"
|
||||
assert unit.get_value("Mount", "What") == "/dev/sdb1"
|
||||
assert unit.get_value("Mount", "Where") == "/mnt/data"
|
||||
assert unit.get_value("Mount", "Type") == "ext4"
|
||||
|
||||
def test_create_with_dependencies(self):
|
||||
"""Test creating unit file with dependencies."""
|
||||
unit = create_unit_file(
|
||||
UnitType.SERVICE,
|
||||
description="Service with dependencies",
|
||||
exec_start="/usr/bin/test",
|
||||
requires=["database.service"],
|
||||
wants=["network.service"],
|
||||
after=["network.target", "database.service"],
|
||||
)
|
||||
|
||||
assert unit.get_value("Unit", "Requires") == "database.service"
|
||||
assert unit.get_value("Unit", "Wants") == "network.service"
|
||||
assert unit.get_value("Unit", "After") == "network.target database.service"
|
||||
Reference in New Issue
Block a user