Rm resmgr.grant releated contents
[vfc/nfvo/lcm.git] / lcm / ns_vnfs / tests / tests.py
index b4c60cf..a88e05d 100644 (file)
@@ -19,8 +19,9 @@ import mock
 from django.test import TestCase, Client
 from rest_framework import status
 
+from lcm.ns_vnfs.biz.grant_vnfs import GrantVnfs
 from lcm.pub.database.models import VLInstModel, NfInstModel, JobModel, NSInstModel, VmInstModel, \
-    OOFDataModel, VNFCInstModel, PortInstModel, CPInstModel
+    OOFDataModel, VNFCInstModel, PortInstModel, CPInstModel, SubscriptionModel
 from lcm.pub.exceptions import NSLCMException
 from lcm.pub.utils import restcall
 from lcm.jobs.enum import JOB_MODEL_STATUS, JOB_TYPE, JOB_ACTION, JOB_PROGRESS
@@ -32,15 +33,13 @@ from lcm.ns_vnfs.biz.heal_vnfs import NFHealService
 from lcm.ns_vnfs.biz.scale_vnfs import NFManualScaleService
 from lcm.ns_vnfs.biz.subscribe import SubscriptionDeletion
 from lcm.ns_vnfs.biz.terminate_nfs import TerminateVnfs
-from lcm.ns_vnfs.enum import VNF_STATUS, LIFE_CYCLE_OPERATION, RESOURCE_CHANGE_TYPE, VNFC_CHANGE_TYPE, INST_TYPE, \
-    NETWORK_RESOURCE_TYPE
+from lcm.ns_vnfs.enum import VNF_STATUS, LIFE_CYCLE_OPERATION, RESOURCE_CHANGE_TYPE, VNFC_CHANGE_TYPE, \
+    INST_TYPE, NETWORK_RESOURCE_TYPE
 from lcm.ns_vnfs.biz.place_vnfs import PlaceVnfs
-from lcm.pub.msapi import resmgr
 from lcm.ns_vnfs.tests.test_data import vnfm_info, vim_info, vnf_place_request
 from lcm.ns_vnfs.tests.test_data import nf_package_info, nsd_model_dict, subscription_response_data
 from lcm.ns_vnfs.biz.create_vnfs import CreateVnfs
-from lcm.ns_vnfs.biz import create_vnfs
-from lcm.ns_vnfs.biz.grant_vnfs import GrantVnfs
+from lcm.ns_vnfs.biz import create_vnfs, grant_vnf
 from lcm.ns_vnfs.biz.update_vnfs import NFOperateService
 from lcm.ns_vnfs.biz.verify_vnfs import VerifyVnfs
 from lcm.ns.enum import OWNER_TYPE
@@ -93,10 +92,13 @@ class TestTerminateVnfViews(TestCase):
                                    vimid='{"cloud_owner": "VCPE", "cloud_regionid": "RegionOne"}',
                                    instid=self.nf_inst_id
                                    )
+        SubscriptionModel(vnf_instance_filter=self.nf_inst_id, callback_uri="", links="").save()
 
     def tearDown(self):
         NSInstModel.objects.all().delete()
         NfInstModel.objects.all().delete()
+        VmInstModel.objects.all().delete()
+        SubscriptionModel.objects.all().delete()
 
     @mock.patch.object(TerminateVnfs, "run")
     def test_terminate_vnf_url(self, mock_run):
@@ -109,8 +111,7 @@ class TestTerminateVnfViews(TestCase):
 
     @mock.patch.object(time, "sleep")
     @mock.patch.object(restcall, "call_req")
-    @mock.patch.object(SubscriptionDeletion, "send_subscription_deletion_request")
-    def test_terminate_vnf(self, mock_send_subscription_deletion_request, mock_call_req, mock_sleep):
+    def test_terminate_vnf(self, mock_call_req, mock_sleep):
         job_id = JobUtil.create_job(JOB_TYPE.VNF, JOB_ACTION.TERMINATE, self.nf_inst_id)
         job_info = {
             "jobId": job_id,
@@ -124,7 +125,9 @@ class TestTerminateVnfViews(TestCase):
             "/api/ztevnfmdriver/v1/1/jobs/" + job_id + "?responseId=0":
                 [0, json.JSONEncoder().encode(job_info), "200"],
             "/api/resmgr/v1/vnf/1":
-                [0, json.JSONEncoder().encode({"jobId": job_id}), "200"]
+                [0, json.JSONEncoder().encode({"jobId": job_id}), "200"],
+            "api/gvnfmdriver/v1/1/subscriptions/":
+                [0, json.JSONEncoder().encode({}), "200"]
         }
 
         def side_effect(*args):
@@ -138,6 +141,62 @@ class TestTerminateVnfViews(TestCase):
             self.assertEqual(1, 1)
         self.assertEqual(JobModel.objects.get(jobid=job_id).progress, 100)
 
+    @mock.patch.object(time, "sleep")
+    @mock.patch.object(restcall, "call_req")
+    @mock.patch.object(SubscriptionDeletion, "send_subscription_deletion_request")
+    def test_terminate_vnf_when_no_vnf_uuid(self, mock_send_subscription_deletion_request, mock_call_req, mock_sleep):
+        nf_inst_id = "test_terminate_vnf_when_no_vnf_uuid"
+        NSInstModel(id=nf_inst_id, name="ns_name_2").save()
+        NfInstModel.objects.create(nfinstid=nf_inst_id,
+                                   vnfm_inst_id="2",
+                                   status="active",
+                                   vnfd_model=self.vnfd_model
+                                   )
+        VmInstModel.objects.create(vmid="2",
+                                   vimid='{"cloud_owner": "VCPE", "cloud_regionid": "RegionOne"}',
+                                   instid=nf_inst_id
+                                   )
+        job_id = JobUtil.create_job(JOB_TYPE.VNF, JOB_ACTION.TERMINATE, nf_inst_id)
+        job_info = {
+            "jobId": job_id,
+            "responsedescriptor": {"status": JOB_MODEL_STATUS.FINISHED}
+        }
+        mock_vals = {
+            "/external-system/esr-vnfm-list/esr-vnfm/2?depth=all":
+                [0, json.JSONEncoder().encode(vnfm_info), "200"],
+            "/api/ztevnfmdriver/v1/2/vnfs/None/terminate":
+                [0, json.JSONEncoder().encode({"jobId": job_id}), "200"],
+            "/api/ztevnfmdriver/v1/2/jobs/" + job_id + "?responseId=0":
+                [0, json.JSONEncoder().encode(job_info), "200"],
+            "/api/resmgr/v1/vnf/%s" % nf_inst_id:
+                [0, json.JSONEncoder().encode({"jobId": job_id}), "200"]
+        }
+
+        def side_effect(*args):
+            return mock_vals[args[4]]
+
+        mock_call_req.side_effect = side_effect
+        TerminateVnfs(self.data, nf_inst_id, job_id).run()
+        nfinst = NfInstModel.objects.filter(nfinstid=nf_inst_id)
+        if nfinst:
+            self.assertEqual(1, 0)
+        else:
+            self.assertEqual(1, 1)
+        self.assertEqual(JobModel.objects.get(jobid=job_id).progress, 100)
+
+    @mock.patch.object(time, "sleep")
+    @mock.patch.object(restcall, "call_req")
+    @mock.patch.object(SubscriptionDeletion, "send_subscription_deletion_request")
+    def test_terminate_vnf_when_nf_not_exists(self, mock_send_subscription_deletion_request, mock_call_req, mock_sleep):
+        job_id = JobUtil.create_job(JOB_TYPE.VNF, JOB_ACTION.TERMINATE, self.nf_inst_id)
+        TerminateVnfs(self.data, "nf_not_exists", job_id).run()
+        nfinst = NfInstModel.objects.filter(nfinstid="nf_not_exists")
+        if nfinst:
+            self.assertEqual(1, 0)
+        else:
+            self.assertEqual(1, 1)
+        self.assertEqual(JobModel.objects.get(jobid=job_id).progress, 255)
+
     def test_terminate_vnf_when_vnf_is_dealing(self):
         NfInstModel.objects.filter(nfinstid=self.nf_inst_id).update(status=VNF_STATUS.TERMINATING)
         job_id = JobUtil.create_job(JOB_TYPE.VNF, JOB_ACTION.TERMINATE, self.nf_inst_id)
@@ -553,6 +612,8 @@ class TestPlaceVnfViews(TestCase):
         self.vnf_inst_id = "1234"
         self.vnf_id = "vG"
         self.client = Client()
+        self.url = "/api/nslcm/v1/ns/placevnf"
+        self.data = vnf_place_request
         OOFDataModel.objects.all().delete()
         OOFDataModel.objects.create(
             request_id="1234",
@@ -577,6 +638,7 @@ class TestPlaceVnfViews(TestCase):
             "flavorId": "12345",
             "directive": []
         }]
+        # response = self.client.post(self.url, data=self.data)
         PlaceVnfs(vnf_place_request).extract()
         db_info = OOFDataModel.objects.filter(request_id=vnf_place_request.get("requestId"), transaction_id=vnf_place_request.get("transactionId"))
         self.assertEqual(db_info[0].request_status, "completed")
@@ -803,7 +865,6 @@ class TestGrantVnfsViews(TestCase):
     #     }
     #     response = self.client.post(self.url, data=data)
     #     self.assertEqual(response.status_code, status.HTTP_201_CREATED)
-
     @mock.patch.object(restcall, "call_req")
     def test_nf_grant_view_when_add_resource(self, mock_call_req):
         mock_vals = {
@@ -867,7 +928,7 @@ class TestGrantVnfViews(TestCase):
         OOFDataModel.objects.all().delete()
         NfInstModel.objects.all().delete()
 
-    @mock.patch.object(resmgr, "grant_vnf")
+    @mock.patch.object(grant_vnf, "vim_connections_get")
     def test_vnf_grant_view(self, mock_grant):
         resmgr_grant_resp = {
             "vim": {
@@ -886,7 +947,7 @@ class TestGrantVnfViews(TestCase):
         self.assertEqual(response.data["vimAssets"]["computeResourceFlavours"][0]["vimFlavourId"], "flavor_id_001")
 
     @mock.patch.object(restcall, "call_req")
-    @mock.patch.object(resmgr, "grant_vnf")
+    @mock.patch.object(grant_vnf, "vim_connections_get")
     def test_exec_grant_when_add_resources_success(self, mock_grant, mock_call_req):
         mock_vals = {
             "/api/catalog/v1/vnfpackages/package_id_001":
@@ -923,7 +984,7 @@ class TestGrantVnfViews(TestCase):
 
     @mock.patch.object(time, "sleep")
     @mock.patch.object(restcall, "call_req")
-    @mock.patch.object(resmgr, "grant_vnf")
+    @mock.patch.object(grant_vnf, "vim_connections_get")
     def test_exec_grant_when_add_resources_but_no_off(self, mock_grant, mock_call_req, mock_sleep):
         NfInstModel(mnfinstid="add_resources_but_no_off", nfinstid="vnf_inst_id_002",
                     package_id="package_id_002").save()
@@ -960,7 +1021,7 @@ class TestGrantVnfViews(TestCase):
         }]
         self.assertEqual(resp["vimConnections"], vimConnections)
 
-    @mock.patch.object(resmgr, "grant_vnf")
+    @mock.patch.object(grant_vnf, "vim_connections_get")
     def test_exec_grant_when_resource_template_in_add_resources(self, mock_grant):
         resmgr_grant_resp = {
             "vim": {
@@ -978,7 +1039,7 @@ class TestGrantVnfViews(TestCase):
         self.assertEqual(resp["vimAssets"]["computeResourceFlavours"][0]["vimFlavourId"], "flavor_id_001")
 
     @mock.patch.object(restcall, "call_req")
-    @mock.patch.object(resmgr, "grant_vnf")
+    @mock.patch.object(grant_vnf, "vim_connections_get")
     def test_exec_grant_when_remove_resources_success(self, mock_grant, mock_call_req):
         mock_vals = {
             "/api/catalog/v1/vnfpackages/package_id_001":
@@ -1020,7 +1081,7 @@ class TestGrantVnfViews(TestCase):
 
     @mock.patch.object(time, "sleep")
     @mock.patch.object(restcall, "call_req")
-    @mock.patch.object(resmgr, "grant_vnf")
+    @mock.patch.object(grant_vnf, "vim_connections_get")
     def test_exec_grant_when_remove_resources_but_no_off(self, mock_grant, mock_call_req, mock_sleep):
         NfInstModel(mnfinstid="remove_resources_but_no_off", nfinstid="vnf_inst_id_002", package_id="package_id_002",
                     vnfm_inst_id="vnfm_id_002").save()
@@ -1060,7 +1121,7 @@ class TestGrantVnfViews(TestCase):
         }]
         self.assertEqual(resp["vimConnections"], vimConnections)
 
-    @mock.patch.object(resmgr, "grant_vnf")
+    @mock.patch.object(grant_vnf, "vim_connections_get")
     def test_exec_grant_when_resource_template_in_remove_resources(self, mock_grant):
         resmgr_grant_resp = {
             "vim": {
@@ -1150,7 +1211,7 @@ class TestCreateVnfViews(TestCase):
                                                                            "statusdescription": "creating",
                                                                            "errorcode": "0"}]}}), "200"],
             "api/gvnfmdriver/v1/1/subscriptions":
-                [0, json.JSONEncoder().encode({}), "200"],
+                [0, json.JSONEncoder().encode(subscription_response_data), "200"],
             "/api/resmgr/v1/vnfinfo":
                 [0, json.JSONEncoder().encode(subscription_response_data), "200"],
 
@@ -1292,6 +1353,55 @@ class TestCreateVnfViews(TestCase):
         ret = OOFDataModel.objects.filter(request_id="1234", transaction_id="1234")
         self.assertIsNotNone(ret)
 
+    @mock.patch.object(time, "sleep")
+    @mock.patch.object(restcall, "call_req")
+    def test_create_vnf_thread_sucess_when_failed_to_subscribe_from_vnfm(self, mock_call_req, mock_sleep):
+        mock_sleep.return_value = None
+        nf_inst_id, job_id = create_vnfs.prepare_create_params()
+        mock_vals = {
+            "/api/catalog/v1/vnfpackages/zte_vbras":
+                [0, json.JSONEncoder().encode(nf_package_info), "200"],
+            "/external-system/esr-vnfm-list/esr-vnfm/1?depth=all":
+                [0, json.JSONEncoder().encode(vnfm_info), "200"],
+            "/api/ztevnfmdriver/v1/1/vnfs":
+                [0, json.JSONEncoder().encode({"jobId": self.job_id, "vnfInstanceId": 3}), "200"],
+            "/api/oof/v1/placement":
+                [0, json.JSONEncoder().encode({}), "202"],
+            "/api/resmgr/v1/vnf":
+                [0, json.JSONEncoder().encode({}), "200"],
+            "/api/ztevnfmdriver/v1/1/jobs/" + self.job_id + "?responseId=0":
+                [0, json.JSONEncoder().encode({"jobid": self.job_id,
+                                               "responsedescriptor": {"progress": "100",
+                                                                      "status": JOB_MODEL_STATUS.FINISHED,
+                                                                      "responseid": "3",
+                                                                      "statusdescription": "creating",
+                                                                      "errorcode": "0",
+                                                                      "responsehistorylist": [
+                                                                          {"progress": "0",
+                                                                           "status": JOB_MODEL_STATUS.PROCESSING,
+                                                                           "responseid": "2",
+                                                                           "statusdescription": "creating",
+                                                                           "errorcode": "0"}]}}), "200"],
+            "api/gvnfmdriver/v1/1/subscriptions":
+                [1, json.JSONEncoder().encode(subscription_response_data), "200"],
+            "/api/resmgr/v1/vnfinfo":
+                [0, json.JSONEncoder().encode(subscription_response_data), "200"],
+        }
+
+        def side_effect(*args):
+            return mock_vals[args[4]]
+
+        mock_call_req.side_effect = side_effect
+        data = {
+            "ns_instance_id": ignore_case_get(self.data, "nsInstanceId"),
+            "additional_param_for_ns": ignore_case_get(self.data, "additionalParamForNs"),
+            "additional_param_for_vnf": ignore_case_get(self.data, "additionalParamForVnf"),
+            "vnf_index": ignore_case_get(self.data, "vnfIndex")
+        }
+        CreateVnfs(data, nf_inst_id, job_id).run()
+        self.assertEqual(NfInstModel.objects.get(nfinstid=nf_inst_id).status, VNF_STATUS.ACTIVE)
+        self.assertEqual(JobModel.objects.get(jobid=job_id).progress, JOB_PROGRESS.FINISHED)
+
 
 class TestUpdateVnfsViews(TestCase):
     def setUp(self):
@@ -2158,7 +2268,14 @@ class TestVnfNotifyView(TestCase):
                                                           "id": "cpd_id",
                                                           "resourceHandle": {
                                                               "vimConnectionId": "vim_connection_id",
-                                                              "resourceId": "resource_id"
+                                                              "resourceId": "resource_id",
+                                                              "resourceProviderId": "resourceProviderId",
+                                                              "tenant": "tenant",
+                                                              "ipAddress": "ipAddress",
+                                                              "macAddress": "macAddress",
+                                                              "instId": "instId",
+                                                              "networkId": "networkId",
+                                                              "subnetId": "subnetId"
                                                           }
                                                           }],
                                         }]
@@ -2182,6 +2299,7 @@ class TestVnfNotifyView(TestCase):
         CPInstModel.objects.all().delete()
 
     def test_handle_vnf_lcm_ooc_notification_when_change_type_is_added(self):
+        # response = self.client.post(self.url, data=self.data)
         HandleVnfLcmOocNotification(self.vnfm_inst_id, self.m_nf_inst_id, self.data).do_biz()
         vnfc_inst = VNFCInstModel.objects.get(vnfcinstanceid="vnfc_instance_id", vduid="vdu_id",
                                               nfinstid=self.nf_inst_id, vmid="resource_id")
@@ -2194,13 +2312,13 @@ class TestVnfNotifyView(TestCase):
                                           vlinstancename="resource_id", ownertype=0, ownerid=self.nf_inst_id,
                                           relatednetworkid="resource_id", vltype=0)
         self.assertIsInstance(vl_inst, VLInstModel)
-        port_inst = PortInstModel.objects.get(networkid='unknown', subnetworkid='unknown', vimid="vim_connection_id",
-                                              resourceid="resource_id", name="resource_id", instid="unknown",
+        port_inst = PortInstModel.objects.get(networkid='networkId', subnetworkid='subnetId', vimid="vim_connection_id",
+                                              resourceid="resource_id", name="resourceProviderId", instid="instId",
                                               cpinstanceid="cp_instance_id", bandwidth='unknown',
-                                              operationalstate='active', ipaddress="unkown", macaddress='unknown',
+                                              operationalstate='active', ipaddress="ipAddress", macaddress='macAddress',
                                               floatipaddress='unknown', serviceipaddress='unknown',
                                               typevirtualnic='unknown', sfcencapsulation='gre', direction='unknown',
-                                              tenant="unkown")
+                                              tenant="tenant")
         self.assertIsInstance(port_inst, PortInstModel)
         cp_inst = CPInstModel.objects.get(cpinstanceid="cp_instance_id", cpdid="cpd_id", ownertype=0,
                                           ownerid=self.nf_inst_id, relatedtype=2, status='active')
@@ -2293,7 +2411,14 @@ class TestVnfNotifyView(TestCase):
                                                           "id": "cpd_id",
                                                           "resourceHandle": {
                                                               "vimConnectionId": "vim_connection_id",
-                                                              "resourceId": "resource_id"
+                                                              "resourceId": "resource_id",
+                                                              "resourceProviderId": "resourceProviderId",
+                                                              "tenant": "tenant",
+                                                              "ipAddress": "ipAddress",
+                                                              "macAddress": "macAddress",
+                                                              "instId": "instId",
+                                                              "networkId": "networkId",
+                                                              "subnetId": "subnetId"
                                                           }
                                                           }],
                                         }]
@@ -2306,13 +2431,13 @@ class TestVnfNotifyView(TestCase):
                                           vlinstancename="resource_id", ownertype=0, ownerid=self.nf_inst_id,
                                           relatednetworkid="resource_id", vltype=0)
         self.assertIsInstance(vl_inst, VLInstModel)
-        port_inst = PortInstModel.objects.get(networkid='unknown', subnetworkid='unknown', vimid="vim_connection_id",
-                                              resourceid="resource_id", name="resource_id", instid="unknown",
+        port_inst = PortInstModel.objects.get(networkid='networkId', subnetworkid='subnetId', vimid="vim_connection_id",
+                                              resourceid="resource_id", name="resourceProviderId", instid="instId",
                                               cpinstanceid="cp_instance_id", bandwidth='unknown',
-                                              operationalstate='active', ipaddress="unkown", macaddress='unknown',
+                                              operationalstate='active', ipaddress="ipAddress", macaddress='macAddress',
                                               floatipaddress='unknown', serviceipaddress='unknown',
                                               typevirtualnic='unknown', sfcencapsulation='gre', direction='unknown',
-                                              tenant="unkown")
+                                              tenant="tenant")
         self.assertIsInstance(port_inst, PortInstModel)
         cp_inst = CPInstModel.objects.get(cpinstanceid="cp_instance_id", cpdid="cpd_id", ownertype=0,
                                           ownerid=self.nf_inst_id, relatedtype=2, status='active')
@@ -2357,3 +2482,81 @@ class TestVnfNotifyView(TestCase):
             self.assertEqual(1, 0)
         except Exception:
             self.assertEqual(1, 1)
+
+    @mock.patch.object(restcall, "call_req")
+    def test_handle_vnf_identifier_notification_when_save_ip_aai(self, mock_call_req):
+        l_interface_info_aai = {
+            "interface-name": "resourceProviderId",
+            "is-port-mirrored": False,
+            "resource-version": "1589506153510",
+            "in-maint": False,
+            "is-ip-unnumbered": False
+        }
+        l3_interface_ipv4_address_list = {
+            "l3-interface-ipv4-address": "ipAddress",
+            "resource-version": "1589527363970"
+        }
+        mock_vals = {
+            "/network/generic-vnfs/generic-vnf/%s/l-interfaces/l-interface/%s"
+            % ("test_vnf_notify", "resourceProviderId"):
+                [0, json.JSONEncoder().encode(l_interface_info_aai), "200"],
+            "/network/generic-vnfs/generic-vnf/%s/l-interfaces/l-interface/%s/l3-interface-ipv4-address-list/%s"
+            % ("test_vnf_notify", "resourceProviderId", "ipAddress"):
+                [0, json.JSONEncoder().encode(l3_interface_ipv4_address_list), "200"],
+            "/network/l3-networks/l3-network/%s" % "vl_instance_id":
+                [0, json.JSONEncoder().encode({}), "200"],
+
+        }
+
+        def side_effect(*args):
+            return mock_vals[args[4]]
+
+        mock_call_req.side_effect = side_effect
+
+        data = {
+            "id": "1111",
+            "notificationType": "VnfLcmOperationOccurrenceNotification",
+            "subscriptionId": "1111",
+            "timeStamp": "1111",
+            "notificationStatus": "START",
+            "operationState": "STARTING",
+            "vnfInstanceId": self.nf_inst_id,
+            "operation": "INSTANTIATE",
+            "isAutomaticInvocation": "1111",
+            "vnfLcmOpOccId": "1111",
+            "affectedVnfcs": [{"id": "vnfc_instance_id",
+                               "vduId": "vdu_id",
+                               "changeType": VNFC_CHANGE_TYPE.MODIFIED,
+                               "computeResource": {
+                                   "vimConnectionId": "vim_connection_id",
+                                   "resourceId": "resource_id"
+                               }}],
+            "affectedVirtualLinks": [{"id": "vl_instance_id",
+                                      "virtualLinkDescId": "virtual_link_desc_id",
+                                      "changeType": VNFC_CHANGE_TYPE.MODIFIED,
+                                      "networkResource": {
+                                          "vimLevelResourceType": "network",
+                                          "resourceId": "resource_id"
+                                      }}],
+            "changedExtConnectivity": [{"id": "virtual_link_instance_id",
+                                        "extLinkPorts": [{"cpInstanceId": "cp_instance_id",
+                                                          "id": "cpd_id",
+                                                          "resourceHandle": {
+                                                              "vimConnectionId": "vim_connection_id",
+                                                              "resourceId": "resource_id",
+                                                              "resourceProviderId": "resourceProviderId",
+                                                              "tenant": "tenant",
+                                                              "ipAddress": "ipAddress",
+                                                              "macAddress": "macAddress",
+                                                              "instId": "instId",
+                                                              "networkId": "networkId",
+                                                              "subnetId": "subnetId"
+                                                          }
+                                                          }],
+                                        "changeType": VNFC_CHANGE_TYPE.MODIFIED
+                                        }]
+        }
+        HandleVnfLcmOocNotification(self.vnfm_inst_id, self.m_nf_inst_id, data).do_biz()
+        url = '/api/nslcm/v2/ns/%s/vnfs/%s/Notify' % (self.vnfm_inst_id, self.m_nf_inst_id)
+        response = self.client.post(url, data)
+        self.assertEqual(status.HTTP_204_NO_CONTENT, response.status_code, response.content)