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.
18 import catalog.pub.utils.timeutil
19 from requests.auth import HTTPBasicAuth
21 from django.test import TestCase
22 from rest_framework import status
23 from rest_framework.test import APIClient
25 from catalog.packages.biz.sdc_vnf_package import NfDistributeThread, NfPkgDeleteThread
26 from catalog.pub.database.models import JobStatusModel, JobModel
27 from catalog.pub.database.models import VnfPackageModel
28 from catalog.pub.msapi import sdc
29 from catalog.pub.utils import restcall, toscaparser
30 from .const import vnfd_data
31 from catalog.pub.config.config import CATALOG_ROOT_PATH
32 from catalog.packages import const
33 from catalog.pub.config import config as pub_config
36 class TestNfPackage(TestCase):
38 self.client = APIClient()
39 VnfPackageModel.objects.filter().delete()
40 JobModel.objects.filter().delete()
41 JobStatusModel.objects.filter().delete()
42 self.vnfd_data = vnfd_data
47 def assert_job_result(self, job_id, job_progress, job_detail):
48 jobs = JobStatusModel.objects.filter(
50 progress=job_progress,
52 self.assertEqual(1, len(jobs))
54 @mock.patch.object(NfDistributeThread, 'run')
55 def test_nf_pkg_distribute_normal(self, mock_run):
56 resp = self.client.post(
57 "/api/catalog/v1/vnfpackages",
64 self.assertEqual(resp.status_code, status.HTTP_202_ACCEPTED)
66 def test_nf_pkg_distribute_when_csar_already_exist(self):
69 vnfdId="vcpe_vfw_zte_1_0"
77 self.assert_job_result("2", 255, "NF CSAR(1) already exists.")
79 @mock.patch.object(restcall, 'call_req')
80 @mock.patch.object(sdc, 'download_artifacts')
81 @mock.patch.object(toscaparser, 'parse_vnfd')
82 def test_nf_pkg_distribute_when_vnfd_already_exist(self,
84 mock_download_artifacts,
86 mock_parse_vnfd.return_value = json.JSONEncoder().encode(self.vnfd_data)
87 mock_download_artifacts.return_value = "/home/hss.csar"
88 mock_call_req.return_value = [0, json.JSONEncoder().encode([{
90 "toscaModelURL": "https://127.0.0.1:1234/sdc/v1/hss.csar"
92 VnfPackageModel(vnfPackageId="2", vnfdId="00342b18-a5c7-11e8-998c-bf1755941f12").save()
99 self.assert_job_result("2", 255, "VNF package(00342b18-a5c7-11e8-998c-bf1755941f12) already exists.")
101 @mock.patch.object(restcall, 'call_req')
102 @mock.patch.object(sdc, 'download_artifacts')
103 @mock.patch.object(toscaparser, 'parse_vnfd')
104 def test_nf_pkg_distribute_successfully(self,
106 mock_download_artifacts,
108 mock_parse_vnfd.return_value = json.JSONEncoder().encode(self.vnfd_data)
109 mock_download_artifacts.return_value = "/home/hss.csar"
110 mock_call_req.return_value = [0, json.JSONEncoder().encode([{
112 "toscaModelURL": "https://127.0.0.1:1234/sdc/v1/hss.csar"
120 self.assert_job_result("4", 100, "CSAR(1) distribute successfully.")
122 ###############################################################################################################
124 @mock.patch.object(NfPkgDeleteThread, 'run')
125 def test_nf_pkg_delete_normal(self, mock_run):
126 resp = self.client.delete("/api/catalog/v1/vnfpackages/1")
127 self.assertEqual(resp.status_code, status.HTTP_202_ACCEPTED)
129 def test_nf_pkg_normal_delete(self):
132 vnfdId="vcpe_vfw_zte_1_0"
138 self.assert_job_result("2", 100, "Delete CSAR(2) successfully.")
140 def test_nf_pkg_get_all(self):
146 vnfSoftwareVersion='',
155 vnfSoftwareVersion='',
159 resp = self.client.get("/api/catalog/v1/vnfpackages")
160 self.assertEqual(resp.status_code, status.HTTP_200_OK)
170 "downloadUrl": "http://127.0.0.1:8806/static/catalog/3/",
184 "downloadUrl": "http://127.0.0.1:8806/static/catalog/4/",
191 self.assertEqual(expect_data, resp.data)
193 def test_nf_pkg_get_one(self):
199 vnfSoftwareVersion='',
204 resp = self.client.get("/api/catalog/v1/vnfpackages/4")
205 self.assertEqual(resp.status_code, status.HTTP_200_OK)
214 "downloadUrl": "http://127.0.0.1:8806/static/catalog/4/",
220 self.assertEqual(expect_data, resp.data)
222 def test_nf_pkg_get_one_failed(self):
228 vnfSoftwareVersion='',
233 resp = self.client.get("/api/catalog/v1/vnfpackages/2")
234 self.assertEqual(resp.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR)
235 self.assertEqual({'error': 'Vnf package[2] not Found.'}, resp.data)
237 ###############################################################################################################
239 @mock.patch.object(toscaparser, 'parse_vnfd')
240 def test_vnfd_parse_normal(self, mock_parse_vnfd):
245 mock_parse_vnfd.return_value = json.JSONEncoder().encode({"c": "d"})
250 resp = self.client.post(
251 "/api/parser/v1/parservnfd",
255 self.assertEqual(resp.status_code, status.HTTP_202_ACCEPTED)
256 self.assertEqual({"model": '{"c": "d"}'}, resp.data)
258 def test_vnfd_parse_when_csar_not_exist(self):
259 req_data = {"csarId": "1", "inputs": []}
260 resp = self.client.post(
261 "/api/parser/v1/parservnfd",
265 self.assertEqual(resp.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR)
266 self.assertEqual(resp.data, {"error": "VNF CSAR(1) does not exist."})
268 @mock.patch("requests.post")
269 @mock.patch.object(sdc, 'download_artifacts')
270 @mock.patch.object(sdc, 'get_artifact')
271 @mock.patch("requests.get")
272 @mock.patch("uuid.uuid4")
273 @mock.patch.object(catalog.pub.utils.timeutil, "now_time")
274 def test_service_pkg_distribute_and_notify(self, mock_nowtime, mock_uuid, mock_requests_get, mock_get_artifact,
275 mock_download_artifacts, mock_requests_post):
276 mock_nowtime.return_value = "2019-02-16 14:41:16"
277 uuid_subscriptid = "99442b18-a5c7-11e8-998c-bf1755941f13"
279 mock_uuid.side_effect = [uuid_subscriptid, "1111", "2222"]
280 mock_requests_get.return_value.status_code = 204
281 vnf_subscription_data = {
283 "notificationTypes": [
284 "VnfPackageOnboardingNotification",
285 "VnfPackageChangeNotification"
288 "b1bb0ce7-2222-4fa7-95ed-4840d70a1177"
290 "operationalState": ["ENABLED", "DISABLED"]
292 "callbackUri": "https://so-vnfm-simulator.onap:9093/vnfpkgm/v1/notification",
299 "password": "password1$"
303 response = self.client.post(
304 "/api/vnfpkgm/v1/subscriptions",
305 data=vnf_subscription_data,
307 self.assertEqual(201, response.status_code)
308 mock_download_artifacts.return_value = os.path.join(CATALOG_ROOT_PATH, "Sol004VnfCSAR.csar")
309 mock_get_artifact.return_value = {
310 "uuid": "c94490a0-f7ef-48be-b3f8-8d8662a37236",
311 "invariantUUID": "63eaec39-ffbe-411c-a838-448f2c73f7eb",
312 "name": "Sol004VnfCSAR",
314 "toscaModelURL": "/sdc/v1/catalog/resources/c94490a0-f7ef-48be-b3f8-8d8662a37236/toscaModel",
316 "subCategory": "VolteVF",
317 "resourceType": "VF",
318 "lifecycleState": "CERTIFIED",
319 "lastUpdaterUserId": "jh0003"
321 NfDistributeThread(csar_id=uuid_csarid, vim_ids=["1"], lab_vim_id="", job_id="4").on_distribute()
322 print(VnfPackageModel.objects.all().values())
323 expect_onboarding_notification = {
325 'notificationType': const.PKG_NOTIFICATION_TYPE.ONBOARDING,
326 'timeStamp': "2019-02-16 14:41:16",
328 'vnfdId': "b1bb0ce7-2222-4fa7-95ed-4840d70a1177",
331 'href': 'http://%s:%s/%s/vnf_packages/%s' % (pub_config.MSB_SERVICE_IP,
332 pub_config.MSB_SERVICE_PORT,
333 const.PKG_URL_PREFIX,
336 'href': 'http://%s:%s/%s%s' % (pub_config.MSB_SERVICE_IP,
337 pub_config.MSB_SERVICE_PORT,
338 const.VNFPKG_SUBSCRIPTION_ROOT_URI,
342 "subscriptionId": uuid_subscriptid
344 mock_requests_post.return_value.status_code = 204
345 mock_requests_post.assert_called_with(vnf_subscription_data["callbackUri"], data=expect_onboarding_notification,
346 headers={'Connection': 'close',
347 'content-type': 'application/json',
348 'accept': 'application/json'},
349 auth=HTTPBasicAuth("vnfm", "password1$"),
351 mock_requests_post.return_value.status_code = 204
352 expect_deleted_notification = {
354 'notificationType': const.PKG_NOTIFICATION_TYPE.CHANGE,
355 'timeStamp': "2019-02-16 14:41:16",
357 'vnfdId': "b1bb0ce7-2222-4fa7-95ed-4840d70a1177",
358 'changeType': const.PKG_CHANGE_TYPE.PKG_DELETE,
359 'operationalState': None,
360 "subscriptionId": uuid_subscriptid,
363 'href': 'http://%s:%s/%s%s' % (pub_config.MSB_SERVICE_IP,
364 pub_config.MSB_SERVICE_PORT,
365 const.VNFPKG_SUBSCRIPTION_ROOT_URI,
368 'href': 'http://%s:%s/%s/vnf_packages/%s' % (pub_config.MSB_SERVICE_IP,
369 pub_config.MSB_SERVICE_PORT,
370 const.PKG_URL_PREFIX,
375 NfPkgDeleteThread(csar_id=uuid_csarid, job_id="5").delete_csar()
376 mock_requests_post.assert_called_with(vnf_subscription_data["callbackUri"], data=expect_deleted_notification,
377 headers={'Connection': 'close',
378 'content-type': 'application/json',
379 'accept': 'application/json'},
380 auth=HTTPBasicAuth("vnfm", "password1$"),