From 006d74f9a2c66bee22e83e12a35c1ece645da6a8 Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 11 Jun 2024 21:24:01 +0200 Subject: [PATCH] fix: ensure on_delete behavior for process parents Signed-off-by: Alex --- src/aap_eda/core/models/activation.py | 12 ++++++-- src/aap_eda/core/models/event_stream.py | 11 +++++-- src/aap_eda/core/models/mixins.py | 16 ++++++++++ tests/integration/core/test_process_parent.py | 29 ++++++++++++++++++- 4 files changed, 63 insertions(+), 5 deletions(-) diff --git a/src/aap_eda/core/models/activation.py b/src/aap_eda/core/models/activation.py index 83007b0b9..2a7ef094a 100644 --- a/src/aap_eda/core/models/activation.py +++ b/src/aap_eda/core/models/activation.py @@ -16,6 +16,7 @@ from aap_eda.core.enums import ( ActivationStatus, + ProcessParentType, RestartPolicy, RulebookProcessLogLevel, ) @@ -23,14 +24,18 @@ from aap_eda.services.activation.engine.common import ContainerableMixin from .base import BaseOrgModel, UniqueNamedModel -from .mixins import StatusHandlerModelMixin +from .mixins import OnDeleteProcessParentMixin, StatusHandlerModelMixin from .user import AwxToken, User __all__ = ("Activation",) class Activation( - StatusHandlerModelMixin, ContainerableMixin, BaseOrgModel, UniqueNamedModel + StatusHandlerModelMixin, + ContainerableMixin, + OnDeleteProcessParentMixin, + BaseOrgModel, + UniqueNamedModel, ): class Meta: db_table = "core_activation" @@ -127,3 +132,6 @@ class Meta: blank=True, help_text="Name of the kubernetes service", ) + + def get_parent_type(self) -> str: + return ProcessParentType.ACTIVATION diff --git a/src/aap_eda/core/models/event_stream.py b/src/aap_eda/core/models/event_stream.py index 79d3b84d1..053d5accb 100644 --- a/src/aap_eda/core/models/event_stream.py +++ b/src/aap_eda/core/models/event_stream.py @@ -16,6 +16,7 @@ from aap_eda.core.enums import ( ActivationStatus, + ProcessParentType, RestartPolicy, RulebookProcessLogLevel, ) @@ -23,11 +24,14 @@ from aap_eda.services.activation.engine.common import ContainerableMixin from .base import UniqueNamedModel -from .mixins import StatusHandlerModelMixin +from .mixins import OnDeleteProcessParentMixin, StatusHandlerModelMixin class EventStream( - StatusHandlerModelMixin, ContainerableMixin, UniqueNamedModel + StatusHandlerModelMixin, + ContainerableMixin, + OnDeleteProcessParentMixin, + UniqueNamedModel, ): """Model representing an event stream.""" @@ -107,3 +111,6 @@ def __str__(self) -> str: def _get_skip_audit_events(self) -> bool: """Event stream skips audit events.""" return True + + def get_parent_type(self) -> str: + return ProcessParentType.EVENT_STREAM diff --git a/src/aap_eda/core/models/mixins.py b/src/aap_eda/core/models/mixins.py index a5388aab0..addc7083d 100644 --- a/src/aap_eda/core/models/mixins.py +++ b/src/aap_eda/core/models/mixins.py @@ -14,6 +14,7 @@ import typing as tp +from django.apps import apps from django.db import models from aap_eda.core.enums import ACTIVATION_STATUS_MESSAGE_MAP, ActivationStatus @@ -98,3 +99,18 @@ def _is_valid_status(self): ActivationStatus(self.status) except ValueError as error: raise UnknownStatusError(error) from None + + +class OnDeleteProcessParentMixin: + """Mixin to delete related objects when the parent is deleted.""" + + def _delete_request_queue(self): + model = apps.get_model("core", "ActivationRequestQueue") + model.objects.filter( + process_parent_id=self.id, + process_parent_type=self.get_parent_type(), + ).delete() + + def delete(self, *args, **kwargs): + self._delete_request_queue() + super().delete(*args, **kwargs) diff --git a/tests/integration/core/test_process_parent.py b/tests/integration/core/test_process_parent.py index 19eeca49f..cdeafb3e9 100644 --- a/tests/integration/core/test_process_parent.py +++ b/tests/integration/core/test_process_parent.py @@ -17,7 +17,7 @@ from pytest_lazyfixture import lazy_fixture from aap_eda.core import models -from aap_eda.core.enums import ActivationStatus +from aap_eda.core.enums import ActivationRequest, ActivationStatus @pytest.mark.parametrize( @@ -58,3 +58,30 @@ def test_latest_instance_field(instance): first_instance.status = ActivationStatus.COMPLETED first_instance.save(update_fields=["status"]) assert instance.latest_instance == second_instance + + +@pytest.mark.parametrize( + "instance", + [ + pytest.param( + lazy_fixture("new_activation"), + id="activation", + ), + pytest.param( + lazy_fixture("new_event_stream"), + id="event_stream", + ), + ], +) +@pytest.mark.django_db +def test_on_delete_process_parent_mixin(instance): + """Test on_delete_process_parent_mixin.""" + queue_item = models.ActivationRequestQueue.objects.create( + process_parent_type=instance.get_parent_type(), + process_parent_id=instance.id, + request=ActivationRequest.AUTO_START, + ) + instance.delete() + assert not models.ActivationRequestQueue.objects.filter( + id=queue_item.id + ).exists()