1 # Copyright 2017 ZTE Corporation.
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
16 from rest_framework import status
17 from django.test import TestCase
18 from django.test import Client
20 from catalog.pub.utils import restcall, toscaparser
21 from catalog.pub.utils import fileutil
22 from catalog.pub.database.models import VnfPackageModel
23 from catalog.pub.database.models import JobStatusModel, JobModel
24 from catalog.packages.nf_package import NfDistributeThread, NfPkgDeleteThread
25 from catalog.packages import nf_package
26 from catalog.pub.msapi import sdc
28 class TestNfPackage(TestCase):
30 self.client = Client()
31 VnfPackageModel.objects.filter().delete()
32 JobModel.objects.filter().delete()
33 JobStatusModel.objects.filter().delete()
42 "unit_size": 1000000000
44 "type_of_storage": "volume",
45 "rdma_enabled": False,
48 "volume_storage_id": "vNAT_Storage_6wdgwzedlb6sq18uzrr41sof7",
56 "vNAT_Storage_6wdgwzedlb6sq18uzrr41sof7"
63 "configurable_properties": {
65 "additional_vnfc_configurable_properties": {
72 "description": "the virtual machine of vNat",
83 "artifact_name": "vNatVNFImage",
84 "type": "tosca.artifacts.nfv.SwImage",
86 "operating_system": "linux",
87 "sw_image": "/swimages/vRouterVNF_ControlPlane.qcow2",
88 "name": "vNatVNFImage",
89 "container_format": "bare",
91 "disk_format": "qcow2",
92 "supported_virtualisation_environments": [
100 "file": "/swimages/vRouterVNF_ControlPlane.qcow2"
104 "flavor_extra_specs": {
105 "hw:cpu_sockets": "2",
106 "sw:ovs_dpdk": "true",
107 "hw:cpu_threads": "2",
108 "hw:numa_mem.1": "3072",
109 "hw:numa_mem.0": "1024",
110 "hw:numa_nodes": "2",
111 "hw:numa_cpus.0": "0,1",
112 "hw:numa_cpus.1": "2,3,4,5",
114 "hw:cpu_threads_policy": "isolate"
116 "cpu_frequency": "2.4 GHz",
120 "local_storages": [],
121 "image_file": "vNatVNFImage",
128 "operating_system": "linux",
129 "sw_image": "/swimages/vRouterVNF_ControlPlane.qcow2",
130 "name": "vNatVNFImage",
131 "container_format": "bare",
133 "disk_format": "qcow2",
134 "supported_virtualisation_environments": [
142 "image_file_id": "vNatVNFImage",
147 "local_storages": [],
151 "key_name": "sriov_plane",
152 "cp_id": "SRIOV_Port"
160 "vl_id": "sriov_link",
161 "route_external": False,
167 "connectivity_type": {
168 "layer_protocol": "ipv4",
169 "flow_pattern": "flat"
171 "description": "sriov_link",
180 "vl_id": "sriov_link",
181 "vdu_id": "vdu_vNat",
183 "cp_id": "SRIOV_Port",
187 "address_type": "ip_address",
189 "ip_address_type": "ipv4",
190 "floating_ip_activated": False,
191 "number_of_ip_address": 1,
192 "ip_address_assignment": True
196 "description": "sriov port",
197 "layer_protocol": "ipv4",
198 "virtual_network_interface_requirements": [
203 "support_mandatory": False,
205 "description": "sriov"
211 "support_mandatory": False,
213 "description": "normal"
217 "bitrate_requirement": 10
222 "vnfSoftwareVersion": "1.0.0",
223 "vnfProductName": "zte",
224 "localizationLanguage": [
228 "vnfProvider": "zte",
230 "defaultLocalizationLanguage": "english",
231 "vnfdId": "zte-hss-1.0",
233 "vnfProductInfoDescription": "hss",
234 "vnfdVersion": "1.0.0",
235 "vnfProductInfoName": "hss"
242 def assert_job_result(self, job_id, job_progress, job_detail):
243 jobs = JobStatusModel.objects.filter(
245 progress=job_progress,
247 self.assertEqual(1, len(jobs))
249 @mock.patch.object(NfDistributeThread, 'run')
250 def test_nf_pkg_distribute_normal(self, mock_run):
251 resp = self.client.post("/api/catalog/v1/vnfpackages", {
255 self.assertEqual(resp.status_code, status.HTTP_202_ACCEPTED)
257 def test_nf_pkg_distribute_when_csar_already_exist(self):
258 VnfPackageModel(vnfPackageId="1", vnfdId="vcpe_vfw_zte_1_0").save()
259 NfDistributeThread(csar_id="1",
263 self.assert_job_result("2", 255, "NF CSAR(1) already exists.")
265 @mock.patch.object(restcall, 'call_req')
266 @mock.patch.object(sdc, 'download_artifacts')
267 @mock.patch.object(toscaparser, 'parse_vnfd')
268 def test_nf_pkg_distribute_when_vnfd_already_exist(self,
269 mock_parse_vnfd, mock_download_artifacts, mock_call_req):
270 mock_parse_vnfd.return_value = json.JSONEncoder().encode(self.vnfd_data)
271 mock_download_artifacts.return_value = "/home/hss.csar"
272 mock_call_req.return_value = [0, json.JSONEncoder().encode([{
274 "toscaModelURL": "https://127.0.0.1:1234/sdc/v1/hss.csar"
276 VnfPackageModel(vnfPackageId="2", vnfdId="zte-hss-1.0").save()
277 NfDistributeThread(csar_id="1",
281 self.assert_job_result("2", 255, "NFD(zte-hss-1.0) already exists.")
283 @mock.patch.object(restcall, 'call_req')
284 @mock.patch.object(sdc, 'download_artifacts')
285 @mock.patch.object(toscaparser, 'parse_vnfd')
286 def test_nf_pkg_distribute_successfully(self,
287 mock_parse_vnfd, mock_download_artifacts, mock_call_req):
288 mock_parse_vnfd.return_value = json.JSONEncoder().encode(self.vnfd_data)
289 mock_download_artifacts.return_value = "/home/hss.csar"
290 mock_call_req.return_value = [0, json.JSONEncoder().encode([{
292 "toscaModelURL": "https://127.0.0.1:1234/sdc/v1/hss.csar"
294 NfDistributeThread(csar_id="1",
298 self.assert_job_result("4", 100, "CSAR(1) distribute successfully.")
300 ###############################################################################################################
302 @mock.patch.object(NfPkgDeleteThread, 'run')
303 def test_nf_pkg_delete_normal(self, mock_run):
304 resp = self.client.delete("/api/catalog/v1/vnfpackages/1")
305 self.assertEqual(resp.status_code, status.HTTP_202_ACCEPTED)
307 def test_nf_pkg_normal_delete(self):
308 VnfPackageModel(vnfPackageId="2", vnfdId="vcpe_vfw_zte_1_0").save()
309 NfPkgDeleteThread(csar_id="2", job_id="2").run()
310 self.assert_job_result("2", 100, "Delete CSAR(2) successfully.")
312 def test_nf_pkg_get_all(self):
313 VnfPackageModel(vnfPackageId="3", vnfdId="4").save()
315 resp = self.client.get("/api/catalog/v1/vnfpackages")
316 self.assertEqual(resp.status_code, status.HTTP_200_OK)
317 self.assertEqual({"csars": [{"csarId":"3", "vnfdId": "4"}]}, resp.data)
319 def test_nf_pkg_get_one(self):
320 VnfPackageModel(vnfPackageId="4", vnfdId="5", vnfVendor="6",
321 vnfdVersion="7", vnfSoftwareVersion="8", vnfPackageUri="4.csar").save()
323 resp = self.client.get("/api/catalog/v1/vnfpackages/4")
324 self.assertEqual(resp.status_code, status.HTTP_200_OK)
325 self.assertEqual({"csarId": "4",
331 "csarName": "4.csar",
332 "downloadUrl": "http://127.0.0.1:8806/static/catalog/4/4.csar"
334 "imageInfo": []}, resp.data)
336 ###############################################################################################################
338 @mock.patch.object(toscaparser, 'parse_vnfd')
339 def test_vnfd_parse_normal(self, mock_parse_vnfd):
340 VnfPackageModel(vnfPackageId="8", vnfdId="10").save()
341 mock_parse_vnfd.return_value = json.JSONEncoder().encode({"c": "d"})
342 resp = self.client.post("/api/catalog/v1/parservnfd",
343 {"csarId": "8", "inputs": []}, format='json')
344 self.assertEqual(resp.status_code, status.HTTP_202_ACCEPTED)
345 self.assertEqual({"model": '{"c": "d"}'}, resp.data)
347 def test_vnfd_parse_when_csar_not_exist(self):
348 resp = self.client.post("/api/catalog/v1/parservnfd",
349 {"csarId": "1", "inputs": []}, format='json')
350 self.assertEqual(resp.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR)
351 self.assertEqual(resp.data, {"error": "VNF CSAR(1) does not exist."})