from copy import deepcopy
import yaml
import copy
+from n2vc.exceptions import N2VCException
from os import getenv
from osm_lcm import ns
from osm_common.msgkafka import MsgKafka
from osm_lcm.ng_ro import NgRoClient
from osm_lcm.data_utils.database.database import Database
from osm_lcm.data_utils.filesystem.filesystem import Filesystem
+from osm_lcm.data_utils.vca import Relation, EERelation
from osm_lcm.data_utils.vnfd import find_software_version
from osm_lcm.lcm_utils import check_juju_bundle_existence, get_charm_artifact_path
from osm_lcm.lcm_utils import LcmException
return a
-class TestMyNS(asynctest.TestCase):
+class TestBaseNS(asynctest.TestCase):
async def _n2vc_DeployCharms(
self,
model_name,
return str(uuid4())
async def setUp(self):
-
- # Mock DB
+ self.mock_db()
+ self.mock_kafka()
+ self.mock_filesystem()
+ self.mock_task_registry()
+ self.mock_vca_k8s()
+ self.create_nslcm_class()
+ self.mock_logging()
+ self.mock_vca_n2vc()
+ self.mock_ro()
+
+ def mock_db(self):
if not getenv("OSMLCMTEST_DB_NOMOCK"):
# Cleanup singleton Database instance
Database.instance = None
self.db = Database({"database": {"driver": "memory"}}).instance.db
self.db.create_list("vnfds", yaml.safe_load(descriptors.db_vnfds_text))
self.db.create_list(
- "vnfds_revisions",
- yaml.safe_load(descriptors.db_vnfds_revisions_text),
+ "vnfds_revisions", yaml.safe_load(descriptors.db_vnfds_revisions_text)
)
self.db.create_list("nsds", yaml.safe_load(descriptors.db_nsds_text))
self.db.create_list("nsrs", yaml.safe_load(descriptors.db_nsrs_text))
self.db.create_list(
- "vim_accounts",
- yaml.safe_load(descriptors.db_vim_accounts_text),
+ "vim_accounts", yaml.safe_load(descriptors.db_vim_accounts_text)
)
self.db.create_list(
- "k8sclusters",
- yaml.safe_load(descriptors.db_k8sclusters_text),
+ "k8sclusters", yaml.safe_load(descriptors.db_k8sclusters_text)
)
self.db.create_list(
"nslcmops", yaml.safe_load(descriptors.db_nslcmops_text)
self.db.create_list("vnfrs", yaml.safe_load(descriptors.db_vnfrs_text))
self.db_vim_accounts = yaml.safe_load(descriptors.db_vim_accounts_text)
- # Mock kafka
+ def mock_kafka(self):
self.msg = asynctest.Mock(MsgKafka())
- # Mock filesystem
+ def mock_filesystem(self):
if not getenv("OSMLCMTEST_FS_NOMOCK"):
self.fs = asynctest.Mock(
Filesystem({"storage": {"driver": "local", "path": "/"}}).instance.fs
# self.fs.file_open.return_value.__enter__.return_value = asynctest.MagicMock() # called on a python "with"
# self.fs.file_open.return_value.__enter__.return_value.read.return_value = "" # empty file
- # Mock TaskRegistry
+ def mock_task_registry(self):
self.lcm_tasks = asynctest.Mock(TaskRegistry())
self.lcm_tasks.lock_HA.return_value = True
self.lcm_tasks.waitfor_related_HA.return_value = None
self.lcm_tasks.lookfor_related.return_value = ("", [])
- # Mock VCA - K8s
+ def mock_vca_k8s(self):
if not getenv("OSMLCMTEST_VCA_K8s_NOMOCK"):
ns.K8sJujuConnector = asynctest.MagicMock(ns.K8sJujuConnector)
ns.K8sHelmConnector = asynctest.MagicMock(ns.K8sHelmConnector)
ns.N2VCJujuConnector = asynctest.MagicMock(ns.N2VCJujuConnector)
ns.LCMHelmConn = asynctest.MagicMock(ns.LCMHelmConn)
- # Create NsLCM class
+ def create_nslcm_class(self):
self.my_ns = ns.NsLcm(self.msg, self.lcm_tasks, lcm_config, self.loop)
self.my_ns.fs = self.fs
self.my_ns.db = self.db
self.my_ns._wait_dependent_n2vc = asynctest.CoroutineMock()
- # Mock logging
+ def mock_logging(self):
if not getenv("OSMLCMTEST_LOGGING_NOMOCK"):
self.my_ns.logger = asynctest.Mock(self.my_ns.logger)
- # Mock VCA - N2VC
+ def mock_vca_n2vc(self):
if not getenv("OSMLCMTEST_VCA_NOMOCK"):
pub_key = getenv("OSMLCMTEST_NS_PUBKEY", "ssh-rsa test-pub-key t@osm.com")
# self.my_ns.n2vc = asynctest.Mock(N2VC())
self.my_ns.n2vc.delete_namespace = asynctest.CoroutineMock(
return_value=None
)
+ self.my_ns.n2vc.register_execution_environment = asynctest.CoroutineMock(
+ return_value="model-name.application-name.k8s"
+ )
- # Mock RO
+ def mock_ro(self):
if not getenv("OSMLCMTEST_RO_NOMOCK"):
self.my_ns.RO = asynctest.Mock(
NgRoClient(self.loop, **lcm_config.RO.to_dict())
# await self.test_instantiate()
# # this will check that the initial-congig-primitive 'not_to_be_called' is not called
+
+class TestMyNS(TestBaseNS):
@asynctest.fail_on(active_handles=True)
async def test_start_stop_rebuild_pass(self):
nsr_id = descriptors.test_ids["TEST-OP-VNF"]["ns"]
q_filter={"_id": vnfd_id + ":1"},
update_dict={"_admin.revision": 1, "kdu": []},
)
- self.db.set_one(
- "vnfrs",
- q_filter={"_id": vnfr_id},
- update_dict={"revision": 1},
- )
+ self.db.set_one("vnfrs", q_filter={"_id": vnfr_id}, update_dict={"revision": 1})
mock_charm_hash.return_value = False
mock_charm_artifact.side_effect = [
self.db.set_one(
"nsrs",
q_filter={"_id": nsr_id},
- update_dict={
- "_admin.deployed.VCA.0.kdu_name": "native-kdu",
- },
+ update_dict={"_admin.deployed.VCA.0.kdu_name": "native-kdu"},
)
self.db.set_one("vnfrs", q_filter={"_id": vnfr_id}, update_dict={"revision": 1})
self.db.set_one(
"vnfds",
q_filter={"_id": vnfd_id},
- update_dict={
- "_admin.revision": 3,
- "software-version": "1.0",
- "kdu": [],
- },
+ update_dict={"_admin.revision": 3, "software-version": "1.0", "kdu": []},
)
self.db.set_one(
"vnfds_revisions",
q_filter={"_id": vnfd_id + ":1"},
- update_dict={
- "_admin.revision": 1,
- "software-version": "1.0",
- "kdu": [],
- },
+ update_dict={"_admin.revision": 1, "software-version": "1.0", "kdu": []},
)
self.db.set_one("vnfrs", q_filter={"_id": vnfr_id}, update_dict={"revision": 1})
def test_ns_update_check_juju_charm_artifacts_base_folder_wth_pkgdir(self):
"""Check charm artifacts"""
- base_folder = {
- "folder": vnfd_id,
- "pkg-dir": "hackfest_3charmed_vnfd",
- }
+ base_folder = {"folder": vnfd_id, "pkg-dir": "hackfest_3charmed_vnfd"}
charm_name = "simple"
charm_type = "lxc_proxy_charm"
revision = 3
def test_ns_update_check_juju_charm_artifacts_base_folder_wthout_pkgdir(self):
"""Check charm artifacts, SOL004 packages"""
- base_folder = {
- "folder": vnfd_id,
- }
+ base_folder = {"folder": vnfd_id}
charm_name = "basic"
charm_type, revision = "", ""
expected_result = f"{vnfd_id}/Scripts/helm-charts/basic"
self.assertEqual(result, expected_result, "Wrong charm artifact path")
+class TestInstantiateN2VC(TestBaseNS):
+ async def setUp(self):
+ await super().setUp()
+ self.db_nsr = yaml.safe_load(descriptors.db_nsrs_text)[0]
+ self.db_vnfr = yaml.safe_load(descriptors.db_vnfrs_text)[0]
+ self.vca_index = 1
+ self.my_ns._write_configuration_status = Mock()
+
+ async def call_instantiate_N2VC(self):
+ logging_text = "N2VC Instantiation"
+ config_descriptor = {"config-access": {"ssh-access": {"default-user": "admin"}}}
+ base_folder = {"pkg-dir": "", "folder": "~"}
+ stage = ["Stage", "Message"]
+
+ await self.my_ns.instantiate_N2VC(
+ logging_text=logging_text,
+ vca_index=self.vca_index,
+ nsi_id="nsi_id",
+ db_nsr=self.db_nsr,
+ db_vnfr=self.db_vnfr,
+ vdu_id=None,
+ kdu_name=None,
+ vdu_index=None,
+ kdu_index=None,
+ config_descriptor=config_descriptor,
+ deploy_params={},
+ base_folder=base_folder,
+ nslcmop_id="nslcmop_id",
+ stage=stage,
+ vca_type="native_charm",
+ vca_name="vca_name",
+ ee_config_descriptor={},
+ )
+
+ def check_config_status(self, expected_status):
+ self.my_ns._write_configuration_status.assert_called_with(
+ nsr_id=self.db_nsr["_id"], vca_index=self.vca_index, status=expected_status
+ )
+
+ async def call_ns_add_relation(self):
+ ee_relation = EERelation(
+ {
+ "nsr-id": self.db_nsr["_id"],
+ "vdu-profile-id": None,
+ "kdu-resource-profile-id": None,
+ "vnf-profile-id": "hackfest_vnf1",
+ "execution-environment-ref": "f48163a6-c807-47bc-9682-f72caef5af85.alf-c-ab",
+ "endpoint": "127.0.0.1",
+ }
+ )
+
+ relation = Relation("relation-name", ee_relation, ee_relation)
+ cached_vnfrs = {"hackfest_vnf1": self.db_vnfr}
+
+ return await self.my_ns._add_relation(
+ relation=relation,
+ vca_type="native_charm",
+ db_nsr=self.db_nsr,
+ cached_vnfds={},
+ cached_vnfrs=cached_vnfrs,
+ )
+
+ async def test_add_relation_ok(self):
+ await self.call_instantiate_N2VC()
+ self.check_config_status(expected_status="READY")
+
+ async def test_add_relation_returns_false_raises_exception(self):
+ self.my_ns._add_vca_relations = asynctest.CoroutineMock(return_value=False)
+
+ with self.assertRaises(LcmException) as exception:
+ await self.call_instantiate_N2VC()
+
+ exception_msg = "Relations could not be added to VCA."
+ self.assertTrue(exception_msg in str(exception.exception))
+ self.check_config_status(expected_status="BROKEN")
+
+ async def test_add_relation_raises_lcm_exception(self):
+ exception_msg = "Relations FAILED"
+ self.my_ns._add_vca_relations = asynctest.CoroutineMock(
+ side_effect=LcmException(exception_msg)
+ )
+
+ with self.assertRaises(LcmException) as exception:
+ await self.call_instantiate_N2VC()
+
+ self.assertTrue(exception_msg in str(exception.exception))
+ self.check_config_status(expected_status="BROKEN")
+
+ async def test_n2vc_add_relation_fails_raises_exception(self):
+ exception_msg = "N2VC failed to add relations"
+ self.my_ns.n2vc.add_relation = asynctest.CoroutineMock(
+ side_effect=N2VCException(exception_msg)
+ )
+ with self.assertRaises(LcmException) as exception:
+ await self.call_ns_add_relation()
+ self.assertTrue(exception_msg in str(exception.exception))
+
+ async def test_n2vc_add_relation_ok_returns_true(self):
+ self.my_ns.n2vc.add_relation = asynctest.CoroutineMock(return_value=None)
+ self.assertTrue(await self.call_ns_add_relation())
+
+
if __name__ == "__main__":
asynctest.main()