| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255 |
- # -*- coding: utf-8 -*-
- """
- Unit-Tests für trixy_core.service.
- """
- import pytest
- from unittest.mock import MagicMock, AsyncMock
- from trixy_core.service.enums import ServicePriority, ServiceGroup, ServiceState
- from trixy_core.service.iservice import IService
- from trixy_core.service.service_container import ServiceContainer
- class TestServiceEnums:
- """Tests für Service-Enumerationen."""
- def test_service_priority_ordering(self):
- """Testet die Prioritätsreihenfolge."""
- assert ServicePriority.CRITICAL < ServicePriority.CORE
- assert ServicePriority.CORE < ServicePriority.NETWORK
- assert ServicePriority.NETWORK < ServicePriority.MANAGER
- assert ServicePriority.MANAGER < ServicePriority.PLUGIN
- assert ServicePriority.PLUGIN < ServicePriority.OPTIONAL
- def test_service_priority_values(self):
- """Testet die Prioritätswerte."""
- assert ServicePriority.CRITICAL == 0
- assert ServicePriority.CORE == 10
- assert ServicePriority.NETWORK == 20
- assert ServicePriority.MANAGER == 30
- assert ServicePriority.PLUGIN == 40
- assert ServicePriority.OPTIONAL == 50
- def test_service_group_exists(self):
- """Testet, dass Service-Gruppen existieren."""
- assert hasattr(ServiceGroup, "CRITICAL")
- assert hasattr(ServiceGroup, "NETWORK")
- assert hasattr(ServiceGroup, "MANAGER")
- assert hasattr(ServiceGroup, "AUDIO")
- assert hasattr(ServiceGroup, "ML")
- assert hasattr(ServiceGroup, "UTILITY")
- assert hasattr(ServiceGroup, "PLUGIN")
- def test_service_state_values(self):
- """Testet die Service-Zustände."""
- assert hasattr(ServiceState, "STOPPED")
- assert hasattr(ServiceState, "STARTING")
- assert hasattr(ServiceState, "RUNNING")
- assert hasattr(ServiceState, "STOPPING")
- assert hasattr(ServiceState, "FAILED")
- class ConcreteService(IService):
- """Konkrete Service-Implementierung für Tests."""
- PRIORITY = ServicePriority.CORE
- GROUP = ServiceGroup.UTILITY
- DEPENDENCIES = []
- NAME = "TestService"
- def __init__(self, application):
- super().__init__(application)
- self.started = False
- self.stopped = False
- async def start(self):
- self.started = True
- async def stop(self):
- self.stopped = True
- class DependentService(IService):
- """Service mit Abhängigkeit für Tests."""
- PRIORITY = ServicePriority.MANAGER
- GROUP = ServiceGroup.UTILITY
- DEPENDENCIES = ["TestService"]
- NAME = "DependentService"
- async def start(self):
- pass
- async def stop(self):
- pass
- class TestIService:
- """Tests für IService-Basisklasse."""
- @pytest.fixture
- def mock_application(self):
- """Erstellt eine Mock-Anwendung."""
- return MagicMock()
- @pytest.fixture
- def service(self, mock_application):
- """Erstellt eine Test-Service-Instanz."""
- return ConcreteService(mock_application)
- def test_service_initialization(self, service, mock_application):
- """Testet die Service-Initialisierung."""
- assert service.application == mock_application
- assert service.state == ServiceState.STOPPED
- def test_service_name(self, service):
- """Testet den Service-Namen."""
- assert service.name == "TestService"
- def test_service_is_running(self, service):
- """Testet die is_running-Eigenschaft."""
- assert service.is_running is False
- service._set_state(ServiceState.RUNNING)
- assert service.is_running is True
- def test_service_priority(self, service):
- """Testet die Service-Priorität."""
- assert service.PRIORITY == ServicePriority.CORE
- def test_service_group(self, service):
- """Testet die Service-Gruppe."""
- assert service.GROUP == ServiceGroup.UTILITY
- def test_service_dependencies(self, service):
- """Testet die Service-Abhängigkeiten."""
- assert service.DEPENDENCIES == []
- @pytest.mark.asyncio
- async def test_service_lifecycle_hooks(self, service):
- """Testet die Lifecycle-Hooks."""
- # Hooks sollten ohne Fehler durchlaufen
- await service.on_pre_start()
- await service.on_post_start()
- await service.on_pre_stop()
- await service.on_post_stop()
- await service.on_dependency_ready("SomeService")
- @pytest.mark.asyncio
- async def test_health_check_default(self, service):
- """Testet die Standard-Gesundheitsprüfung."""
- # Nicht laufend -> False
- assert await service.health_check() is False
- # Laufend -> True
- service._set_state(ServiceState.RUNNING)
- assert await service.health_check() is True
- class TestServiceContainer:
- """Tests für ServiceContainer."""
- @pytest.fixture
- def mock_application(self):
- """Erstellt eine Mock-Anwendung."""
- return MagicMock()
- @pytest.fixture
- def container(self, mock_application):
- """Erstellt einen ServiceContainer."""
- return ServiceContainer(mock_application)
- def test_container_initialization(self, container):
- """Testet die Container-Initialisierung."""
- assert container.services == {}
- def test_register_service(self, container):
- """Testet die Service-Registrierung."""
- service = container.register(ConcreteService)
- assert "TestService" in container.services
- assert isinstance(service, ConcreteService)
- def test_register_duplicate_raises_error(self, container):
- """Testet, dass doppelte Registrierung fehlschlägt."""
- container.register(ConcreteService)
- with pytest.raises(ValueError, match="bereits registriert"):
- container.register(ConcreteService)
- def test_get_service(self, container):
- """Testet get_service."""
- container.register(ConcreteService)
- service = container.get_service("TestService")
- assert service is not None
- assert isinstance(service, ConcreteService)
- def test_get_nonexistent_service(self, container):
- """Testet get_service für nicht existierenden Service."""
- assert container.get_service("NonExistent") is None
- def test_getitem_by_name(self, container):
- """Testet __getitem__ mit Name."""
- container.register(ConcreteService)
- service = container["TestService"]
- assert isinstance(service, ConcreteService)
- def test_getitem_by_class(self, container):
- """Testet __getitem__ mit Klasse."""
- container.register(ConcreteService)
- service = container[ConcreteService]
- assert isinstance(service, ConcreteService)
- def test_getitem_raises_keyerror(self, container):
- """Testet, dass __getitem__ KeyError wirft."""
- with pytest.raises(KeyError):
- _ = container["NonExistent"]
- def test_contains(self, container):
- """Testet __contains__."""
- container.register(ConcreteService)
- assert "TestService" in container
- assert "NonExistent" not in container
- assert ConcreteService in container
- @pytest.mark.asyncio
- async def test_start_all(self, container):
- """Testet start_all."""
- service = container.register(ConcreteService)
- await container.start_all()
- assert service.started is True
- assert service.state == ServiceState.RUNNING
- @pytest.mark.asyncio
- async def test_stop_all(self, container):
- """Testet stop_all."""
- service = container.register(ConcreteService)
- await container.start_all()
- await container.stop_all()
- assert service.stopped is True
- assert service.state == ServiceState.STOPPED
- @pytest.mark.asyncio
- async def test_dependency_order(self, container):
- """Testet die Abhängigkeitsreihenfolge."""
- container.register(ConcreteService)
- container.register(DependentService)
- order = container._resolve_start_order()
- test_idx = order.index("TestService")
- dependent_idx = order.index("DependentService")
- assert test_idx < dependent_idx
- @pytest.mark.asyncio
- async def test_restart_service(self, container):
- """Testet den Service-Neustart."""
- service = container.register(ConcreteService)
- await container.start_all()
- service.started = False
- service.stopped = False
- await container.restart_service("TestService")
- assert service.stopped is True
- assert service.started is True
|