TestVimConnectivity improvement and UTs
Move get_controller method from N2VC to
juju paas activitities.
Change-Id: Id3b8e79055690536746bd2a04578bf6de8dde3e1
Signed-off-by: Patricia Reinoso <patricia.reinoso@canonical.com>
diff --git a/osm_lcm/temporal/juju_paas_activities.py b/osm_lcm/temporal/juju_paas_activities.py
index f2b9a16..d86f1c2 100644
--- a/osm_lcm/temporal/juju_paas_activities.py
+++ b/osm_lcm/temporal/juju_paas_activities.py
@@ -16,10 +16,10 @@
import asyncio
import base64
import logging
+from dataclasses import dataclass
from juju.application import Application
from juju.controller import Controller
from n2vc.config import EnvironConfig
-from n2vc.temporal_libjuju import ConnectionInfo, Libjuju
from osm_common.dataclasses.temporal_dataclasses import (
CharmInfo,
CheckCharmStatusInput,
@@ -29,14 +29,30 @@
)
from osm_common.temporal_constants import (
ACTIVITY_TEST_VIM_CONNECTIVITY,
+ ACTIVITY_CHECK_CHARM_STATUS,
ACTIVITY_CREATE_MODEL,
ACTIVITY_DEPLOY_CHARM,
- ACTIVITY_CHECK_CHARM_STATUS,
)
from osm_lcm.data_utils.database.database import Database
from temporalio import activity
+@dataclass
+class ConnectionInfo:
+ """Information to connect to juju controller"""
+
+ endpoint: str
+ user: str
+ password: str
+ cacert: str
+
+ def __repr__(self):
+ return f"{self.__class__.__name__}(endpoint: {self.endpoint}, user: {self.user}, password: ******, cacert: ******)"
+
+ def __str__(self):
+ return f"{self.__class__.__name__}(endpoint: {self.endpoint}, user: {self.user}, password: ******, cacert: ******)"
+
+
class JujuPaasConnector:
"""Handles Juju Controller operations.
@@ -77,16 +93,8 @@
username = vim_content["vim_user"]
vim_config = vim_content["config"]
cacert = vim_config["ca_cert_content"]
- cloud_name = vim_config["cloud"]
- cloud_credentials = vim_config["cloud_credentials"]
password = self._decrypt_password(vim_content)
- return ConnectionInfo(
- endpoint, username, password, cacert, cloud_name, cloud_credentials
- )
-
- def _get_libjuju(self, vim_uuid):
- connection_info = self._get_connection_info(vim_uuid)
- return Libjuju(connection_info)
+ return ConnectionInfo(endpoint, username, password, cacert)
async def _get_controller(self, vim_uuid) -> Controller:
connection_info = self._get_connection_info(vim_uuid)
@@ -126,14 +134,9 @@
and wait on each connection attempt.
"""
vim_id = test_connectivity_input.vim_uuid
- controller = None
- try:
- libjuju = self._get_libjuju(vim_id)
- controller = await libjuju.get_controller()
- message = f"Connection to juju controller succeeded for {vim_id}"
- self.logger.info(message)
- finally:
- await libjuju.disconnect_controller(controller)
+ self._get_controller(vim_id)
+ message = f"Connection to juju controller succeeded for {vim_id}"
+ self.logger.info(message)
@activity.defn(name=ACTIVITY_CREATE_MODEL)
async def create_model(self, create_model_input: ModelInfo) -> None:
diff --git a/osm_lcm/temporal/vnf_workflows.py b/osm_lcm/temporal/vnf_workflows.py
index ed81a8e..d2d6d71 100644
--- a/osm_lcm/temporal/vnf_workflows.py
+++ b/osm_lcm/temporal/vnf_workflows.py
@@ -186,7 +186,7 @@
vim_id = vnfr.get("vim-account-id")
sw_image_descs = vnfd.get("sw-image-desc")
vdu_info = CharmInfoUtils.get_charm_info(vdu, sw_image_descs)
- vdu_instantiate_input = VduInstantiateInput(vim_id, model_name, vdu_info)
+ vdu_instantiate_input = VduInstantiateInput(vim_id, model_name, vdu_info, None)
vdu_instantiate_workflow_id = (
vdu_instantiate_input.model_name
+ "-"
diff --git a/osm_lcm/tests/test_juju_paas_activities.py b/osm_lcm/tests/test_juju_paas_activities.py
index ddafd54..1aee12b 100644
--- a/osm_lcm/tests/test_juju_paas_activities.py
+++ b/osm_lcm/tests/test_juju_paas_activities.py
@@ -23,24 +23,21 @@
from juju.model import Model
from juju.errors import JujuError
from juju.unit import Unit
-from n2vc.temporal_libjuju import ConnectionInfo
from osm_common.dataclasses.temporal_dataclasses import (
CharmInfo,
CheckCharmStatusInput,
ModelInfo,
+ TestVimConnectivityInput,
+ VduComputeConstraints,
VduInstantiateInput,
)
+from osm_common.dbbase import DbException
from osm_lcm.temporal.juju_paas_activities import JujuPaasConnector
from parameterized import parameterized
from temporalio.testing import ActivityEnvironment
from unittest.mock import ANY, AsyncMock, Mock
-vim_id = "some-vim-uuid"
namespace = "some-namespace"
-model_info = ModelInfo(vim_id, namespace)
-connection_info = ConnectionInfo(
- "1.2.3.4:17070", "user", "password", "cacert", "cloud_name", "cloud_credentials"
-)
vim_content = {
"_id": "82258772-0145-47cf-9a56-98a83aab38cc",
"name": "juju-with-key",
@@ -60,17 +57,74 @@
}
+@asynctest.mock.patch("juju.controller.Controller.connect")
class TestJujuPaasConnector(asynctest.TestCase):
def setUp(self):
self.db = Mock()
- self.env = ActivityEnvironment()
self.juju_paas_connector = JujuPaasConnector(self.db)
+ self.juju_paas_connector._decrypt_password = Mock()
+ self.juju_paas_connector._decrypt_password.side_effect = ["password"]
+
+ async def test_get_controller_nominal_case(self, mock_connect):
+ self.db.get_one.side_effect = [vim_content]
+ controller = await self.juju_paas_connector._get_controller(vim_content["_id"])
+ self.assertIsInstance(controller, Controller)
+ mock_connect.assert_called_once_with(
+ endpoint=vim_content["vim_url"],
+ username=vim_content["vim_user"],
+ password="password",
+ cacert=vim_content["config"]["ca_cert_content"],
+ )
+
+ async def test_get_controller_raises_juju_error(self, mock_connect):
+ self.db.get_one.side_effect = [vim_content]
+ mock_connect.side_effect = JujuError()
+ with self.assertRaises(JujuError):
+ await self.juju_paas_connector._get_controller(vim_content["_id"])
+ mock_connect.assert_called_once_with(
+ endpoint=vim_content["vim_url"],
+ username=vim_content["vim_user"],
+ password="password",
+ cacert=vim_content["config"]["ca_cert_content"],
+ )
+
+ async def test_get_controller_raises_db_error(self, mock_connect):
+ self.db.get_one.side_effect = DbException("DB Exception")
+ with self.assertRaises(DbException):
+ await self.juju_paas_connector._get_controller(vim_content["_id"])
+ mock_connect.assert_not_called()
+
+
+class TestJujuPaasActivitiesBase(asynctest.TestCase):
+ def setUp(self) -> None:
+ self.db = Mock()
+ self.env = ActivityEnvironment()
self.controller = AsyncMock(spec=Controller)
+ self.mock_model()
async def get_controller(_: str):
return self.controller
- self.juju_paas_connector._get_controller = get_controller
+ self.juju_paas = JujuPaasConnector(self.db)
+ self.juju_paas._get_controller = get_controller
+
+ def mock_model(self) -> None:
+ self.model = Mock(spec=Model)
+ self.model.applications = {}
+ self.controller.get_model.return_value = self.model
+
+ def add_application(self, application_name) -> None:
+ self.application_name = application_name
+ self.application = Mock(spec=Application)
+ self.application.name = self.application_name
+ self.model.applications = {self.application_name: self.application}
+
+
+class TestCreateModel(TestJujuPaasActivitiesBase):
+ model_info = ModelInfo(vim_content["_id"], namespace)
+
+ def setUp(self):
+ super().setUp()
self._api_endpoints = []
self.controller.api_endpoints = self.api_endpoints
@@ -80,44 +134,22 @@
async def test_create_model_nominal_case(self):
self.db.get_one.side_effect = [vim_content]
- self.juju_paas_connector._decrypt_password = Mock()
- self.juju_paas_connector._decrypt_password.side_effect = ["password"]
- await self.env.run(self.juju_paas_connector.create_model, model_info)
+ self.juju_paas._decrypt_password = Mock()
+ self.juju_paas._decrypt_password.side_effect = ["password"]
+ await self.env.run(self.juju_paas.create_model, self.model_info)
self.controller.add_model.assert_called_once_with(
- model_info.model_name,
+ self.model_info.model_name,
config=ANY,
cloud_name=vim_content["config"]["cloud"],
credential_name=vim_content["config"]["cloud_credentials"],
)
async def test_create_model_already_exists(self):
- self.controller.list_models.return_value = [model_info.model_name]
- await self.env.run(self.juju_paas_connector.create_model, model_info)
+ self.controller.list_models.return_value = [self.model_info.model_name]
+ await self.env.run(self.juju_paas.create_model, self.model_info)
self.controller.add_model.assert_not_called()
-class TestJujuPaasActivitiesBase(asynctest.TestCase):
- def setUp(self) -> None:
- self.db = Mock()
- self.env = ActivityEnvironment()
- self.controller = AsyncMock()
- self.model = Mock(spec=Model)
- self.model.applications = {}
- self.controller.get_model.return_value = self.model
-
- async def get_controller(_: str):
- return self.controller
-
- self.juju_paas = JujuPaasConnector(self.db)
- self.juju_paas._get_controller = get_controller
-
- def add_application(self, application_name) -> None:
- self.application_name = application_name
- self.application = Mock(spec=Application)
- self.application.name = self.application_name
- self.model.applications = {self.application_name: self.application}
-
-
class TestCheckCharmStatus(TestJujuPaasActivitiesBase):
def setUp(self) -> None:
super().setUp()
@@ -225,7 +257,10 @@
channel = "latest"
entity_url = "ch:my-charm"
charm_info = CharmInfo(app_name, channel, entity_url)
- vdu_instantiate_input = VduInstantiateInput(vim_id, namespace, charm_info)
+ constraints = VduComputeConstraints(1, 2, "")
+ vdu_instantiate_input = VduInstantiateInput(
+ vim_content["_id"], namespace, charm_info, constraints
+ )
async def test_deploy_charm_nominal_case(self):
await self.env.run(self.juju_paas.deploy_charm, self.vdu_instantiate_input)
@@ -250,3 +285,20 @@
with self.assertRaises(JujuError):
await self.env.run(self.juju_paas.deploy_charm, self.vdu_instantiate_input)
self.model.deploy.assert_not_called()
+
+
+class TestTestVimConnectivity(TestJujuPaasActivitiesBase):
+ test_vim_connectivity_input = TestVimConnectivityInput(vim_content["_id"])
+
+ async def test_connectivity_nominal_case(self):
+ await self.env.run(
+ self.juju_paas.test_vim_connectivity, self.test_vim_connectivity_input
+ )
+
+ async def test_connectivity_raises_exception(self):
+ self.juju_paas._get_controller = Mock()
+ self.juju_paas._get_controller.side_effect = JujuError()
+ with self.assertRaises(JujuError):
+ await self.env.run(
+ self.juju_paas.test_vim_connectivity, self.test_vim_connectivity_input
+ )
diff --git a/osm_lcm/tests/test_vdu_workflow.py b/osm_lcm/tests/test_vdu_workflow.py
index 23de701..c5b2adc 100644
--- a/osm_lcm/tests/test_vdu_workflow.py
+++ b/osm_lcm/tests/test_vdu_workflow.py
@@ -16,7 +16,11 @@
import asynctest
-from osm_common.dataclasses.temporal_dataclasses import CharmInfo, VduInstantiateInput
+from osm_common.dataclasses.temporal_dataclasses import (
+ CharmInfo,
+ VduInstantiateInput,
+ VduComputeConstraints,
+)
from osm_common.temporal_constants import (
ACTIVITY_DEPLOY_CHARM,
ACTIVITY_CHECK_CHARM_STATUS,
@@ -58,8 +62,12 @@
app_name = "my_app_name"
channel = "latest"
entity_url = "ch:my-charm"
+ cloud = "microk8s"
+ constraints = VduComputeConstraints(mem=1, cores=1, cloud=cloud)
charm_info = CharmInfo(app_name, channel, entity_url)
- vdu_instantiate_input = VduInstantiateInput(vim_id, namespace, charm_info)
+ vdu_instantiate_input = VduInstantiateInput(
+ vim_id, namespace, charm_info, constraints
+ )
worflow_id = namespace + "-" + app_name
async def setUp(self):
diff --git a/osm_lcm/tests/test_vnf_workflows.py b/osm_lcm/tests/test_vnf_workflows.py
index 633d113..912f5d0 100644
--- a/osm_lcm/tests/test_vnf_workflows.py
+++ b/osm_lcm/tests/test_vnf_workflows.py
@@ -30,6 +30,7 @@
GetTaskQueueOutput,
GetVnfDetailsInput,
GetVnfDetailsOutput,
+ VduComputeConstraints,
VduInstantiateInput,
VnfInstantiateInput,
VnfInstantiationState,
@@ -52,6 +53,7 @@
vnfr_uuid="86b53d92-4f5a-402e-8ac2-585ec6b64698",
model_name="a-model-name",
)
+cloud = "microk8s"
juju_task_queue = "juju_task_queue"
vnfr_uuid = "9f472177-95c0-4335-b357-5cdc17a79965"
sample_vnfr = {
@@ -481,6 +483,7 @@
charm_info=CharmInfo(
app_name="my-app", channel="latest", entity_url="my-url"
),
+ constraints=VduComputeConstraints(cores=1, mem=1, cloud=cloud),
),
"vdu_instantiate_workflow_id",
)