Feature 10916: Remove VNF Instance from NS - NS Update 54/11954/9
authorelumalai <deepika.e@tataelxsi.co.in>
Wed, 27 Apr 2022 18:45:59 +0000 (00:15 +0530)
committerelumalai <deepika.e@tataelxsi.co.in>
Wed, 25 May 2022 12:21:21 +0000 (14:21 +0200)
Added support for input validation of Remove VNF update type
Added unit test cases

Change-Id: Ia294114ef093a0cf8a8ba141fc4710cef1bd3b98
Signed-off-by: elumalai <deepika.e@tataelxsi.co.in>
osm_nbi/instance_topics.py
osm_nbi/tests/test_instance_topics.py

index 787f6e1..2df6a7d 100644 (file)
@@ -1278,6 +1278,9 @@ class NsLcmOpTopic(BaseTopic):
         - it checks the vnfInstanceId, whether it's available under ns instance
         - it checks the vnfdId whether it matches with the vnfd-id in the vnf-record of specified VNF.
         Otherwise exception will be raised.
+        If updateType is REMOVE_VNF:
+        - it checks if the vnfInstanceId is available in the ns instance
+        - Otherwise exception will be raised.
 
         Args:
             indata: includes updateType such as CHANGE_VNFPKG,
@@ -1338,6 +1341,14 @@ class NsLcmOpTopic(BaseTopic):
                         ),
                         http_code=HTTPStatus.UNPROCESSABLE_ENTITY,
                     )
+            elif indata["updateType"] == "REMOVE_VNF":
+                vnf_instance_id = indata["removeVnfInstanceId"]
+                ns_instance_id = indata["nsInstanceId"]
+                if vnf_instance_id not in nsr["constituent-vnfr-ref"]:
+                    raise EngineException(
+                        "Invalid VNF Instance Id. '{}' is not "
+                        "present in the NS '{}'".format(vnf_instance_id, ns_instance_id)
+                    )
 
         except (
             DbException,
index b05ee0c..7623e8e 100644 (file)
@@ -57,7 +57,6 @@ class TestNsLcmOpTopic(unittest.TestCase):
         self.db.create_list("vnfrs", yaml.load(db_vnfrs_text, Loader=yaml.Loader))
         self.db.create_list("nsrs", yaml.load(db_nsrs_text, Loader=yaml.Loader))
         self.db.create = Mock(return_value="created_id")
-        self.db.set_one = Mock(return_value={"updated": 1})
         self.nsd = self.db.get_list("nsds")[0]
         self.nsd_id = self.nsd["_id"]
         self.nsr = self.db.get_list("nsrs")[0]
@@ -68,6 +67,7 @@ class TestNsLcmOpTopic(unittest.TestCase):
         self.vim_id = self.vim["_id"]
 
     def test_create_instantiate(self):
+        self.db.set_one = Mock(return_value={"updated": 1})
         session = {
             "force": False,
             "admin": False,
@@ -228,6 +228,59 @@ class TestNsLcmOpTopic(unittest.TestCase):
                 "Engine exception bad http_code with {}".format(indata_copy),
             )
 
+    def test_update_remove_vnf(self):
+        vnfr_id = self.db.get_list("vnfrs")[0]["_id"]
+        session = {}
+        self.db.set_one(
+            "nsrs",
+            {"_id": self.nsr_id},
+            {"_admin.nsState": "INSTANTIATED"},
+        )
+        indata = {
+            "lcmOperationType": "update",
+            "updateType": "REMOVE_VNF",
+            "nsInstanceId": self.nsr_id,
+            "removeVnfInstanceId": vnfr_id
+        }
+
+        session = {
+            "force": False,
+            "admin": False,
+            "public": False,
+            "project_id": [self.nsr_project],
+            "method": "write",
+        }
+        rollback = []
+        headers = {}
+
+        nslcmop_id, _ = self.nslcmop_topic.new(
+            rollback, session, indata, kwargs=None, headers=headers
+        )
+
+        self.assertEqual(
+            self.db.create.call_count,
+            1,
+            "database create not called, or called more than once",
+        )
+        _call = self.db.create.call_args_list[0]
+        self.assertEqual(
+            _call[0][0], "nslcmops", "nslcmops entry must be created at database"
+        )
+        created_nslcmop = _call[0][1]
+        self.assertEqual(
+            self.nsr_id,
+            created_nslcmop["nsInstanceId"],
+            "mismatch between nsId '_id' in created nslcmop and database nsr",
+        )
+        self.assertTrue(
+            created_nslcmop["lcmOperationType"] == "update",
+            "Database record must contain 'lcmOperationType=update'",
+        )
+        self.assertTrue(
+            created_nslcmop["operationParams"]["updateType"] == "REMOVE_VNF",
+            "Database record must contain 'updateType=REMOVE_VNF'",
+        )
+
 
 class TestNsLcmOpTopicWithMock(unittest.TestCase):
     def setUp(self):
@@ -356,6 +409,20 @@ class TestNsLcmOpTopicWithMock(unittest.TestCase):
                 "VNF instance: 88d90b0c-faff-4b9f-bccd-017f33985984",
             )
 
+        with self.subTest(i=5, t="Ns update REMOVE_VNF request validated with no exception"):
+            test_vnfr = yaml.load(db_vnfrs_text, Loader=yaml.Loader)
+            test_vnfr[0]["revision"] = 2
+            test_nsr = yaml.load(db_nsrs_text, Loader=yaml.Loader)
+            self.db.create_list("vnfrs", test_vnfr)
+            self.db.create_list("nsrs", test_nsr)
+            nsrs = self.db.get_list("nsrs")[1]
+            indata = {
+                "updateType": "REMOVE_VNF",
+                "removeVnfInstanceId": "88d90b0c-faff-4b9f-bccd-017f33985984",
+                "nsInstanceId": "f48163a6-c807-47bc-9682-f72caef5af85",
+            }
+            with self.assertNotRaises(EngineException):
+                self.nslcmop_topic._check_ns_operation(session, nsrs, "update", indata)
 
 class TestNsrTopic(unittest.TestCase):
     def setUp(self):