TestVimConnectivity,
CheckCharmStatus,
CheckCharmIsRemoved,
+ CheckModelIsRemoved,
CreateModel,
DeployCharm,
RemoveCharm,
+ RemoveModel,
ResolveCharmErrors,
)
from osm_common.temporal.dataclasses_common import (
await asyncio.sleep(activity_input.poll_interval)
+@activity.defn(name=RemoveModel.__name__)
+class RemoveModelImpl(RemoveModel):
+ async def __call__(self, activity_input: RemoveModel.Input) -> None:
+ model_name = activity_input.model_name
+ controller: Controller = await self.juju_controller._get_controller(
+ activity_input.vim_uuid
+ )
+ if model_name not in (await controller.list_models()):
+ return
+ await controller.destroy_models(
+ model_name,
+ destroy_storage=True,
+ force=activity_input.force_remove,
+ )
+
+
+@activity.defn(name=CheckModelIsRemoved.__name__)
+class CheckModelIsRemovedImpl(CheckModelIsRemoved):
+ async def __call__(self, activity_input: CheckModelIsRemoved.Input) -> None:
+ model_name = activity_input.model_name
+ controller: Controller = await self.juju_controller._get_controller(
+ activity_input.vim_uuid
+ )
+ while model_name in (await controller.list_models()):
+ activity.heartbeat()
+ await asyncio.sleep(activity_input.poll_interval)
+
+
@activity.defn(name=ResolveCharmErrors.__name__)
class ResolveCharmErrorsImpl(ResolveCharmErrors):
async def __call__(self, activity_input: ResolveCharmErrors.Input) -> None:
CreateModelImpl,
CheckCharmStatusImpl,
CheckCharmIsRemovedImpl,
+ CheckModelIsRemovedImpl,
RemoveCharmImpl,
+ RemoveModelImpl,
ResolveCharmErrorsImpl,
)
from osm_common.temporal.workflows.vdu import VduInstantiateWorkflow
self.controller.get_model.assert_not_called()
+class TestRemoveModel(TestJujuPaasActivitiesBase):
+ def setUp(self) -> None:
+ super().setUp()
+ self.remove_model = RemoveModelImpl(self.juju_paas)
+
+ @parameterized.expand([False, True])
+ async def test_remove_model__nominal_case(self, is_forced):
+ remove_model_input = RemoveModelImpl.Input(
+ vim_uuid=vim_content["_id"],
+ model_name=namespace,
+ force_remove=is_forced,
+ )
+ self.controller.list_models.return_value = [namespace]
+ await self.env.run(
+ self.remove_model,
+ remove_model_input,
+ )
+ self.controller.destroy_models.assert_called_once_with(
+ namespace,
+ destroy_storage=True,
+ force=is_forced,
+ )
+
+ async def test_remove_model__model_does_not_exist(self):
+ remove_model_input = RemoveModelImpl.Input(
+ vim_uuid=vim_content["_id"],
+ model_name="not-existing-model",
+ force_remove=False,
+ )
+ self.controller.list_models.return_value = [namespace]
+ await self.env.run(
+ self.remove_model,
+ remove_model_input,
+ )
+ self.controller.destroy_models.assert_not_called()
+
+ async def test_remove_model__juju_error_occurred__model_is_not_removed(self):
+ remove_model_input = RemoveModelImpl.Input(
+ vim_uuid=vim_content["_id"],
+ model_name=namespace,
+ force_remove=False,
+ )
+ self.controller.list_models.side_effect = JujuError()
+ with self.assertRaises(JujuError):
+ await self.env.run(
+ self.remove_model,
+ remove_model_input,
+ )
+ self.controller.destroy_models.assert_not_called()
+
+
+class TestCheckModelIsRemoved(TestJujuPaasActivitiesBase):
+ def setUp(self) -> None:
+ super().setUp()
+ self.env.on_heartbeat = self.on_heartbeat
+ self.heartbeat_count = 0
+ self.heartbeat_maximum = 5
+ self.check_model_is_removed = CheckModelIsRemovedImpl(self.juju_paas)
+
+ def on_heartbeat(self, *args, **kwargs):
+ self.heartbeat_count += 1
+ if self.heartbeat_count > self.heartbeat_maximum:
+ self.env.cancel()
+
+ async def test_check_is_model_removed__nominal_case(self):
+ arg = CheckModelIsRemovedImpl.Input(
+ model_name=namespace,
+ vim_uuid="vim-uuid",
+ poll_interval=0,
+ )
+ self.controller.list_models.return_value = []
+
+ await self.env.run(self.check_model_is_removed.__call__, arg)
+
+ async def test_check_is_model_removed__cancel(self):
+ arg = CheckModelIsRemovedImpl.Input(
+ model_name=namespace,
+ vim_uuid="vim-uuid",
+ poll_interval=0,
+ )
+
+ self.controller.list_models.return_value = [namespace]
+
+ with self.assertRaises(asyncio.exceptions.CancelledError):
+ await self.env.run(self.check_model_is_removed.__call__, arg)
+
+
class TestResolveCharmErrors(TestJujuPaasActivitiesBase):
app_name = "my_app_name"