1. Remove the mandatory dependency on MSB
[modeling/etsicatalog.git] / catalog / packages / tests / test_vnf_pkg_subscription.py
1 # Copyright (C) 2019 Verizon. All Rights Reserved
2 #
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
6 #
7 #         http://www.apache.org/licenses/LICENSE-2.0
8 #
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.
14
15 import json
16 import os
17 import uuid
18
19 import mock
20 from django.test import TestCase
21 from requests.auth import HTTPBasicAuth
22 from rest_framework import status
23 from rest_framework.test import APIClient
24
25 import catalog.pub.utils.timeutil
26 from catalog.packages import const
27 from catalog.packages.biz.notificationsutil import PkgNotifications
28 from catalog.packages.biz.vnf_pkg_subscription import QuerySubscription, TerminateSubscription
29 from catalog.packages.tests.const import vnfd_data
30 from catalog.pub.config.config import CATALOG_ROOT_PATH
31 from catalog.pub.database.models import VnfPkgSubscriptionModel, VnfPackageModel
32 from catalog.pub.exceptions import SubscriptionDoesNotExistsException
33 from catalog.pub.utils import toscaparser
34 from .const import vnf_subscription_data
35
36
37 class TestNfPackageSubscription(TestCase):
38     def setUp(self):
39         self.client = APIClient()
40         VnfPkgSubscriptionModel.objects.filter().delete()
41         self.vnf_subscription_data = vnf_subscription_data
42
43     def tearDown(self):
44         pass
45
46     @mock.patch("requests.get")
47     @mock.patch.object(uuid, 'uuid4')
48     def test_create_vnf_subscription(self, mock_uuid4, mock_requests):
49         temp_uuid = "99442b18-a5c7-11e8-998c-bf1755941f13"
50         mock_requests.return_value.status_code = 204
51         mock_requests.get.status_code = 204
52         mock_uuid4.return_value = temp_uuid
53         response = self.client.post(
54             "/api/vnfpkgm/v1/subscriptions",
55             data=self.vnf_subscription_data,
56             format='json'
57         )
58         self.assertEqual(201, response.status_code)
59         self.assertEqual(
60             self.vnf_subscription_data["callbackUri"],
61             response.data["callbackUri"]
62         )
63         self.assertEqual(temp_uuid, response.data["id"])
64
65     @mock.patch("requests.get")
66     @mock.patch.object(uuid, 'uuid4')
67     def test_duplicate_subscriptions(self, mock_uuid4, mock_requests):
68         temp_uuid = "99442b18-a5c7-11e8-998c-bf1755941f13"
69         temp1_uuid = "00342b18-a5c7-11e8-998c-bf1755941f12"
70         mock_requests.return_value.status_code = 204
71         mock_requests.get.status_code = 204
72         mock_uuid4.side_effect = [temp_uuid, temp1_uuid]
73         response = self.client.post(
74             "/api/vnfpkgm/v1/subscriptions",
75             data=self.vnf_subscription_data,
76             format='json'
77         )
78         self.assertEqual(201, response.status_code)
79         self.assertEqual(
80             self.vnf_subscription_data["callbackUri"],
81             response.data["callbackUri"]
82         )
83         self.assertEqual(temp_uuid, response.data["id"])
84         temp2_uuid = "00442b18-a5c7-11e8-998c-bf1755941f12"
85         mock_requests.return_value.status_code = 204
86         mock_requests.get.status_code = 204
87         mock_uuid4.return_value = temp2_uuid
88         response = self.client.post(
89             "/api/vnfpkgm/v1/subscriptions",
90             data=self.vnf_subscription_data,
91             format='json'
92         )
93         self.assertEqual(303, response.status_code)
94         redirect_addr = "/%s" % (os.path.join(const.VNFPKG_SUBSCRIPTION_ROOT_URI, temp_uuid))
95         self.assertEqual(redirect_addr, response["Location"])
96
97     @mock.patch("requests.get")
98     def test_callbackuri_same_subscriptions(self, mock_requests):
99         mock_requests.return_value.status_code = 204
100         mock_requests.get.status_code = 204
101         response = self.client.post(
102             "/api/vnfpkgm/v1/subscriptions",
103             data=self.vnf_subscription_data,
104             format='json'
105         )
106         self.assertEqual(201, response.status_code)
107         self.assertEqual(
108             self.vnf_subscription_data["callbackUri"],
109             response.data["callbackUri"]
110         )
111         newsubs = self.vnf_subscription_data
112         newsubs["filter"]["vnfdId"] = ["ssss"]
113         response = self.client.post(
114             "/api/vnfpkgm/v1/subscriptions",
115             data=self.vnf_subscription_data,
116             format='json'
117         )
118         self.assertEqual(201, response.status_code)
119         self.assertEqual(
120             newsubs["callbackUri"],
121             response.data["callbackUri"]
122         )
123
124     @mock.patch("requests.get")
125     @mock.patch.object(uuid, 'uuid4')
126     def test_get_subscriptions(self, mock_uuid4, mock_requests):
127         temp_uuid = "99442b18-a5c7-11e8-998c-bf1755941f13"
128         mock_requests.return_value.status_code = 204
129         mock_requests.get.status_code = 204
130         mock_uuid4.return_value = temp_uuid
131         self.client.post(
132             "/api/vnfpkgm/v1/subscriptions",
133             data=self.vnf_subscription_data,
134             format='json'
135         )
136         response = self.client.get(
137             "/api/vnfpkgm/v1/subscriptions?usageState=IN_USE",
138             format='json'
139         )
140         self.assertEqual(200, response.status_code)
141         self.assertEqual(1, len(response.data))
142
143     @mock.patch("requests.get")
144     @mock.patch.object(uuid, 'uuid4')
145     def test_get_subscriptions_with_invalid_params(self, mock_uuid4, mock_requests):
146         temp_uuid = "99442b18-a5c7-11e8-998c-bf1755941f13"
147         mock_requests.return_value.status_code = 204
148         mock_requests.get.status_code = 204
149         mock_uuid4.return_value = temp_uuid
150         self.client.post(
151             "/api/vnfpkgm/v1/subscriptions",
152             data=self.vnf_subscription_data,
153             format='json'
154         )
155         response = self.client.get(
156             "/api/vnfpkgm/v1/subscriptions?dummy=dummy",
157             format='json'
158         )
159         self.assertEqual(400, response.status_code)
160
161     @mock.patch("requests.get")
162     @mock.patch.object(uuid, 'uuid4')
163     def test_get_subscription_with_id(self, mock_uuid4, mock_requests):
164         temp_uuid = "99442b18-a5c7-11e8-998c-bf1755941f13"
165         mock_requests.return_value.status_code = 204
166         mock_requests.get.status_code = 204
167         mock_uuid4.return_value = temp_uuid
168         self.client.post(
169             "/api/vnfpkgm/v1/subscriptions",
170             data=self.vnf_subscription_data,
171             format='json'
172         )
173         response = self.client.get(
174             "/api/vnfpkgm/v1/subscriptions/%s" % temp_uuid,
175             format='json'
176         )
177         self.assertEqual(200, response.status_code)
178         self.assertEqual(temp_uuid, response.data["id"])
179
180     @mock.patch("requests.get")
181     def test_get_subscription_with_id_not_exists(self, mock_requests):
182         mock_requests.return_value.status_code = 204
183         mock_requests.get.status_code = 204
184         self.client.post(
185             "/api/vnfpkgm/v1/subscriptions",
186             data=self.vnf_subscription_data,
187             format='json'
188         )
189         response = self.client.get(
190             "/api/vnfpkgm/v1/subscriptions/111",
191             format='json'
192         )
193         self.assertEqual(404, response.status_code)
194
195     @mock.patch("requests.get")
196     @mock.patch.object(uuid, 'uuid4')
197     def test_delete_subscription_with_id(self, mock_uuid4, mock_requests):
198         temp_uuid = "99442b18-a5c7-11e8-998c-bf1755941f13"
199         dummy_uuid = str(uuid.uuid4())
200         mock_requests.return_value.status_code = 204
201         mock_requests.get.status_code = 204
202         mock_uuid4.return_value = temp_uuid
203         self.client.post(
204             "/api/vnfpkgm/v1/subscriptions",
205             data=self.vnf_subscription_data,
206             format='json'
207         )
208         self.client.get(
209             "/api/vnfpkgm/v1/subscriptions/%s" % dummy_uuid,
210             format='json'
211         )
212         response = self.client.delete("/api/vnfpkgm/v1/subscriptions/%s" % temp_uuid)
213         self.assertEqual(204, response.status_code)
214
215     def test_delete_subscription_with_id_not_exists(self):
216         dummy_uuid = str(uuid.uuid4())
217         response = self.client.delete("/api/vnfpkgm/v1/subscriptions/%s" % dummy_uuid)
218         self.assertEqual(404, response.status_code)
219
220     @mock.patch("requests.get")
221     @mock.patch.object(toscaparser, 'parse_vnfd')
222     @mock.patch("requests.post")
223     @mock.patch("uuid.uuid4")
224     @mock.patch.object(catalog.pub.utils.timeutil, "now_time")
225     def test_vnfpkg_subscript_notify(self, mock_nowtime, mock_uuid, mock_requests_post, mock_parse_vnfd,
226                                      mock_requests_get):
227         mock_nowtime.return_value = "2019-02-16 14:41:16"
228         uuid_subscriptid = "99442b18-a5c7-11e8-998c-bf1755941f13"
229         uuid_vnfPackageId = "3fa85f64-5717-4562-b3fc-2c963f66afa6"
230         uuid_vnfdid = "00342b18-a5c7-11e8-998c-bf1755941f12"
231         mock_uuid.side_effect = [uuid_subscriptid, "1111"]
232         mock_requests_get.return_value.status_code = 204
233         mock_parse_vnfd.return_value = json.JSONEncoder().encode(vnfd_data)
234
235         response = self.client.post(
236             "/api/vnfpkgm/v1/subscriptions",
237             data=vnf_subscription_data,
238             format='json')
239         self.assertEqual(201, response.status_code)
240
241         data = {'file': open(os.path.join(CATALOG_ROOT_PATH, "empty.txt"), "rt")}
242         VnfPackageModel.objects.create(
243             vnfPackageId=uuid_vnfPackageId,
244             onboardingState="CREATED"
245         )
246
247         response = self.client.put("/api/vnfpkgm/v1/vnf_packages/%s/package_content" % uuid_vnfPackageId, data=data)
248         vnf_pkg = VnfPackageModel.objects.filter(vnfPackageId=uuid_vnfPackageId)
249         self.assertEqual(uuid_vnfdid, vnf_pkg[0].vnfdId)
250         self.assertEqual(const.PKG_STATUS.ONBOARDED, vnf_pkg[0].onboardingState)
251         self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED)
252
253         expect_notification = {
254             'id': "1111",
255             'notificationType': const.PKG_NOTIFICATION_TYPE.ONBOARDING,
256             'timeStamp': "2019-02-16 14:41:16",
257             'vnfPkgId': uuid_vnfPackageId,
258             'vnfdId': uuid_vnfdid,
259             '_links': {
260                 'vnfPackage': {
261                     'href': '/%s/vnf_packages/%s' % (const.PKG_URL_PREFIX, uuid_vnfPackageId)
262                 },
263                 'subscription': {
264                     'href': '/%s%s' % (const.VNFPKG_SUBSCRIPTION_ROOT_URI, uuid_subscriptid)}
265             },
266             "subscriptionId": uuid_subscriptid
267         }
268         mock_requests_post.assert_called_with(vnf_subscription_data["callbackUri"],
269                                               data=json.dumps(expect_notification),
270                                               headers={'Connection': 'close',
271                                                        'content-type': 'application/json',
272                                                        'accept': 'application/json'},
273                                               auth=HTTPBasicAuth("admin", "pwd1234"),
274                                               verify=False)
275
276     def test_service_query_single_subscription_not_found(self):
277         try:
278             subscription_id = "test_not_found"
279             QuerySubscription().query_single_subscription(subscription_id)
280         except SubscriptionDoesNotExistsException as e:
281             self.assertEqual("Subscription with ID: %s does not exist" % subscription_id, e.args[0])
282
283     def test_service_delete_single_subscription_not_found(self):
284         try:
285             subscription_id = "test_not_found"
286             TerminateSubscription().terminate(subscription_id)
287         except SubscriptionDoesNotExistsException as e:
288             self.assertEqual("Subscription with ID: %s does not exist" % subscription_id, e.args[0])
289
290
291 class NotificationTest(TestCase):
292     def setUp(self):
293         VnfPackageModel.objects.all().delete()
294         VnfPkgSubscriptionModel.objects.all().delete()
295
296     def tearDown(self):
297         VnfPackageModel.objects.all().delete()
298         VnfPkgSubscriptionModel.objects.all().delete()
299
300     @mock.patch("requests.post")
301     @mock.patch("uuid.uuid4")
302     @mock.patch.object(catalog.pub.utils.timeutil, "now_time")
303     def test_vnfpkg_manual_notify(self, mock_nowtime, mock_uuid, mock_requests_post):
304         VnfPackageModel(vnfPackageId="vnfpkgid1",
305                         vnfdId="vnfdid1"
306                         ).save()
307
308         VnfPkgSubscriptionModel(subscription_id="1",
309                                 callback_uri="http://127.0.0.1/self",
310                                 notification_types=const.NOTIFICATION_TYPES,
311                                 vnfd_id="vnfdid1",
312                                 vnf_pkg_id="vnfpkgid1"
313                                 ).save()
314         mock_nowtime.return_value = "2019-12-16 14:41:16"
315         mock_uuid.return_value = "1111"
316         notify = PkgNotifications(const.PKG_NOTIFICATION_TYPE.CHANGE, "vnfpkgid1",
317                                   const.PKG_CHANGE_TYPE.OP_STATE_CHANGE, operational_state=None)
318
319         notify.send_notification()
320         expect_callbackuri = "http://127.0.0.1/self"
321         expect_notification = {
322             'id': "1111",
323             'notificationType': const.PKG_NOTIFICATION_TYPE.CHANGE,
324             'timeStamp': "2019-12-16 14:41:16",
325             'vnfPkgId': "vnfpkgid1",
326             'vnfdId': "vnfdid1",
327             '_links': {
328                 'vnfPackage': {
329                     'href': '/%s/vnf_packages/%s' % (const.PKG_URL_PREFIX, "vnfpkgid1")
330                 },
331                 'subscription': {
332                     'href': '/%s%s' % (const.VNFPKG_SUBSCRIPTION_ROOT_URI, "1")}
333             },
334             'changeType': const.PKG_CHANGE_TYPE.OP_STATE_CHANGE,
335             'operationalState': None,
336             "subscriptionId": "1"
337         }
338         mock_requests_post.assert_called_with(expect_callbackuri, data=json.dumps(expect_notification),
339                                               headers={'Connection': 'close',
340                                                        'content-type': 'application/json',
341                                                        'accept': 'application/json'},
342                                               verify=False)