finally:
await self.disconnect_controller(controller)
- async def destroy_application(self, model: Model, application_name: str):
+ async def destroy_application(
+ self, model_name: str, application_name: str, total_timeout: float
+ ):
"""
Destroy application
- :param: model: Model object
+ :param: model_name: Model name
:param: application_name: Application name
+ :param: total_timeout: Timeout
"""
- self.log.debug(
- "Destroying application {} in model {}".format(
- application_name, model.info.name
+
+ controller = await self.get_controller()
+ model = None
+
+ try:
+ model = await self.get_model(controller, model_name)
+ self.log.debug(
+ "Destroying application {} in model {}".format(
+ application_name, model_name
+ )
)
- )
- application = model.applications.get(application_name)
- if application:
- await application.destroy()
- else:
- self.log.warning("Application not found: {}".format(application_name))
+ application = self._get_application(model, application_name)
+ if application:
+ await application.destroy()
+ else:
+ self.log.warning("Application not found: {}".format(application_name))
+
+ self.log.debug(
+ "Waiting for application {} to be destroyed in model {}...".format(
+ application_name, model_name
+ )
+ )
+ if total_timeout is None:
+ total_timeout = 3600
+ end = time.time() + total_timeout
+ while time.time() < end:
+ if not self._get_application(model, application_name):
+ self.log.debug(
+ "The application {} was destroyed in model {} ".format(
+ application_name, model_name
+ )
+ )
+ return
+ await asyncio.sleep(5)
+ raise Exception(
+ "Timeout waiting for application {} to be destroyed in model {}".format(
+ application_name, model_name
+ )
+ )
+ finally:
+ if model is not None:
+ await self.disconnect_model(model)
+ await self.disconnect_controller(controller)
async def _destroy_pending_machines(self, model: Model, only_manual: bool = False):
"""
# destroy the model
# TODO: should this be removed?
await self.libjuju.destroy_model(
- model_name=model_name, total_timeout=total_timeout
+ model_name=model_name,
+ total_timeout=total_timeout,
)
else:
- # get juju model and observer
- controller = await self.libjuju.get_controller()
- model = await self.libjuju.get_model(controller, model_name)
# destroy the application
await self.libjuju.destroy_application(
- model=model, application_name=application_name)
+ model_name=model_name,
+ application_name=application_name,
+ total_timeout=total_timeout,
+ )
except Exception as e:
raise N2VCException(
message=(
# TODO destroy_model testcase
+@asynctest.mock.patch("n2vc.libjuju.Libjuju.get_controller")
+@asynctest.mock.patch("n2vc.libjuju.Libjuju.get_model")
+@asynctest.mock.patch("n2vc.libjuju.Libjuju.disconnect_controller")
+@asynctest.mock.patch("n2vc.libjuju.Libjuju._get_application")
+@asynctest.mock.patch("n2vc.libjuju.Libjuju.disconnect_model")
+class DestroyApplicationTest(LibjujuTestCase):
+ def setUp(self):
+ super(DestroyApplicationTest, self).setUp()
+
+ def test_success(
+ self,
+ mock_get_controller,
+ mock_get_model,
+ mock_disconnect_controller,
+ mock_get_application,
+ mock_disconnect_model,
+ ):
+ mock_get_application.return_value = FakeApplication()
+ mock_get_model.return_value = None
+ self.loop.run_until_complete(
+ self.libjuju.destroy_application(
+ "existing_model",
+ "existing_app",
+ 3600,
+ )
+ )
+ mock_get_application.assert_called()
+ mock_disconnect_controller.assert_called_once()
+ mock_disconnect_model.assert_called_once()
+
+ def test_no_application(
+ self,
+ mock_get_controller,
+ mock_get_model,
+ mock_disconnect_controller,
+ mock_get_application,
+ mock_disconnect_model,
+ ):
+ mock_get_model.return_value = None
+ mock_get_application.return_value = None
+
+ self.loop.run_until_complete(
+ self.libjuju.destroy_application(
+ "existing_model",
+ "existing_app",
+ 3600,
+ )
+ )
+ mock_get_application.assert_called()
+
+ def test_exception(
+ self,
+ mock_get_controller,
+ mock_get_model,
+ mock_disconnect_controller,
+ mock_get_application,
+ mock_disconnect_model,
+ ):
+ mock_get_application.return_value = FakeApplication
+ mock_get_model.return_value = None
+
+ with self.assertRaises(Exception):
+ self.loop.run_until_complete(
+ self.libjuju.destroy_application(
+ "existing_model",
+ "existing_app",
+ 0,
+ )
+ )
+ mock_get_application.assert_called_once()
+
+
# @asynctest.mock.patch("juju.model.Model.get_machines")
# @asynctest.mock.patch("logging.Logger.debug")
# class DestroyMachineTest(LibjujuTestCase):