Commit 5d17547a authored by George Papathanail's avatar George Papathanail
Browse files

fix: delet ap_instances_ row on successful termination

parent f224df61
Loading
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
from uuid import UUID

from sqlalchemy import select
from sqlalchemy import delete, select
from sqlalchemy.ext.asyncio import AsyncSession

from open_exposure_gateway.adapters.database.mappers import AppInstanceMapper
@@ -30,3 +30,7 @@ class SqlAppInstanceRepository(AppInstanceRepository):
        if saved is None:
            raise RuntimeError("Saved app instance could not be reloaded")
        return saved

    async def delete(self, app_instance_id: UUID) -> None:
        stmt = delete(AppInstanceRow).where(AppInstanceRow.app_instance_id == app_instance_id)
        await self._session.execute(stmt)
+7 −0
Original line number Diff line number Diff line
@@ -440,6 +440,7 @@ class EdgeApplicationManagementService:
        )
        await self._operation_repo.save(updated)

        is_terminate = operation.operation_type == OperationType.TERMINATE
        updated_instances: list[AppInstance] = []

        if event.instances:
@@ -452,6 +453,12 @@ class EdgeApplicationManagementService:
                        app_instance_id=instance.service_instance_id,
                    )
                    continue
                if is_terminate and instance.status == "completed":
                    # No terminal "terminated" state exists on app_instances.state
                    # (only instantiating/ready/failed/terminating) -- once SRM
                    # confirms teardown, the row's job is done.
                    await self._app_instance_repo.delete(app_instance_id)
                    continue
                saved = await self._app_instance_repo.save(
                    app_instance.model_copy(
                        update={"state": _APP_INSTANCE_COMPLETION_STATE_MAP[instance.status]}
+4 −0
Original line number Diff line number Diff line
@@ -18,3 +18,7 @@ class AppInstanceRepository(ABC):
    @abstractmethod
    async def save(self, app_instance: AppInstance) -> AppInstance:
        pass

    @abstractmethod
    async def delete(self, app_instance_id: UUID) -> None:
        pass
+3 −0
Original line number Diff line number Diff line
@@ -355,6 +355,9 @@ class FakeAppInstanceRepository(AppInstanceRepository):
        self.rows[stored.app_instance_id] = stored
        return stored.model_copy(deep=True)

    async def delete(self, app_instance_id: UUID) -> None:
        self.rows.pop(app_instance_id, None)


class FakeCallbackRegistrationRepository(CallbackRegistrationRepository):
    def __init__(self) -> None:
+17 −0
Original line number Diff line number Diff line
@@ -326,6 +326,23 @@ class TestDeleteAppInstanceFlow:
        assert updated_instance is not None
        assert updated_instance.state == AppInstanceState.TERMINATING

    def test_app_instance_row_removed_after_srm_confirms_termination(
        self,
        api_client: TestClient,
        live_srm: FakeSRMClient,
        app_instance_repo: FakeAppInstanceRepository,
    ) -> None:
        """End-to-end through the real DI wiring: live_srm completes the
        terminate synchronously, and the app_instances row should be gone --
        not flipped to ready, which is what the deploy-completion path does."""
        create_response = api_client.post(f"{EAM_BASE}/appinstances", json=CREATE_INSTANCE_BODY)
        instance_id = create_response.json()["appInstanceId"]

        response = api_client.delete(f"{EAM_BASE}/appinstances/{instance_id}")

        assert response.status_code == 202
        assert app_instance_repo.rows.get(UUID(instance_id)) is None


class TestSubmitAppFlow:
    def test_returns_201_and_registers_catalog_entry_in_srm(
Loading