a5134c7d949a66ed31f430f53323baa6970b88d0
[vfc/nfvo/lcm.git] / lcm / ns / tests / test_ns_manual_scale.py
1 # Copyright 2017 ZTE Corporation.
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 uuid
16 import os
17 import mock
18 from django.test import Client
19 from django.test import TestCase
20 from rest_framework import status
21 from lcm.ns.const import NS_INST_STATUS
22 from lcm.ns.ns_manual_scale import NSManualScaleService
23 from lcm.pub.database.models import NSInstModel, JobModel, NfInstModel
24 from lcm.pub.exceptions import NSLCMException
25 from lcm.pub.utils import restcall
26 from lcm.pub.utils.jobutil import JobUtil, JOB_TYPE, JOB_MODEL_STATUS
27 from lcm.pub.msapi import catalog
28 from lcm.pub.utils.scaleaspect import get_json_data
29
30
31 SCALING_JSON = {
32     "scale_options": [
33         {
34             "nsd_id": "ns_ims",
35             "ns_scale_aspect": "TIC_CORE_IMS",
36             "ns_scale_info": [
37                 {
38                     "step": "1",
39                     "scale_list": [
40                         {
41                             "vnfd_id": "zte_ims_cscf",
42                             "vnf_scale_aspect": "mpu",
43                             "numberOfSteps": "1"
44                         },
45                         {
46                             "vnfd_id": "zte_ims_hss",
47                             "vnf_scale_aspect": "fpu",
48                             "numberOfSteps": "3"
49                         }
50                     ]
51                 },
52                 {
53                     "step": "2",
54                     "scale_list": [
55                         {
56                             "vnfd_id": "zte_ims_cscf",
57                             "vnf_scale_aspect": "mpu",
58                             "numberOfSteps": "2"
59                         },
60                         {
61                             "vnfd_id": "zte_ims_hss",
62                             "vnf_scale_aspect": "fpu",
63                             "numberOfSteps": "6"
64                         }
65                     ]
66                 }
67             ]
68         },
69         {
70             "nsd_id": "ns_epc",
71             "ns_scale_aspect": "TIC_EDGE_EPC",
72             "ns_scale_info": [
73                 {
74                     "step": "1",
75                     "scale_list": [
76                         {
77                             "vnfd_id": "zte_epc_spgw",
78                             "vnf_scale_aspect": "gpu",
79                             "numberOfSteps": "1"
80                         },
81                         {
82                             "vnfd_id": "zte_epc_tas",
83                             "vnf_scale_aspect": "fpu",
84                             "numberOfSteps": "2"
85                         }
86                     ]
87                 },
88                 {
89                     "step": "2",
90                     "scale_list": [
91                         {
92                             "vnfd_id": "zte_epc_spgw",
93                             "vnf_scale_aspect": "mpu",
94                             "numberOfSteps": "2"
95                         },
96                         {
97                             "vnfd_id": "zte_epc_tas",
98                             "vnf_scale_aspect": "fpu",
99                             "numberOfSteps": "4"
100                         }
101                     ]
102                 }
103             ]
104         }
105     ]
106 }
107
108
109 class TestNsManualScale(TestCase):
110     def setUp(self):
111         self.ns_inst_id = str(uuid.uuid4())
112         self.job_id = JobUtil.create_job(
113             "NS", JOB_TYPE.MANUAL_SCALE_VNF, self.ns_inst_id)
114         self.package_id = "7"
115         self.client = Client()
116         NSInstModel(
117             id=self.ns_inst_id,
118             name="abc",
119             nspackage_id=self.package_id,
120             nsd_id="111").save()
121
122         self.init_scaling_map_json()
123
124     def tearDown(self):
125         NSInstModel.objects.filter().delete()
126         JobModel.objects.filter().delete()
127
128     def init_scaling_map_json(self):
129         curdir_path = os.path.dirname(
130             os.path.dirname(
131                 os.path.dirname(
132                     os.path.abspath(__file__))))
133         filename = curdir_path + "/ns/data/scalemapping.json"
134         self.scaling_map_json = get_json_data(filename)
135
136     def insert_new_ns(self):
137         ns_inst_id = str(uuid.uuid4())
138         job_id = JobUtil.create_job(
139             "NS", JOB_TYPE.MANUAL_SCALE_VNF, self.ns_inst_id)
140         package_id = "23"
141         NSInstModel(
142             id=ns_inst_id,
143             name="abc",
144             nspackage_id=package_id,
145             nsd_id=package_id).save()
146         return ns_inst_id, job_id
147
148     def insert_new_nf(self):
149         # Create a third vnf instance
150         self.nf_name = "name_1"
151         self.vnf_id = "1"
152         self.vnfm_inst_id = "1"
153         nf_inst_id = "233"
154         package_id = "nf_zte_hss"
155         nf_uuid = "ab34-3g5j-de13-ab85-ij93"
156
157         NfInstModel.objects.create(
158             nfinstid=nf_inst_id,
159             nf_name=self.nf_name,
160             vnf_id=self.vnf_id,
161             vnfm_inst_id=self.vnfm_inst_id,
162             ns_inst_id=self.ns_inst_id,
163             max_cpu='14',
164             max_ram='12296',
165             max_hd='101',
166             max_shd="20",
167             max_net=10,
168             status='active',
169             mnfinstid=nf_uuid,
170             package_id=package_id,
171             vnfd_model='{"metadata": {"vnfdId": "1","vnfdName": "PGW001",'
172                        '"vnfProvider": "zte","vnfdVersion": "V00001","vnfVersion": "V5.10.20",'
173                        '"productType": "CN","vnfType": "PGW",'
174                        '"description": "PGW VNFD description",'
175                        '"isShared":true,"vnfExtendType":"driver"}}')
176
177     @mock.patch.object(NSManualScaleService, 'run')
178     def test_ns_manual_scale(self, mock_run):
179         data = {
180             "scaleType": "SCALE_NS",
181             "scaleNsData": [{
182                 "scaleNsByStepsData": [{
183                     "aspectId": "1",
184                     "numberOfSteps": 1,
185                     "scalingDirection": "0"
186                 }]
187             }]
188         }
189         response = self.client.post(
190             "/api/nslcm/v1/ns/%s/scale" %
191             self.ns_inst_id, data=data)
192         self.failUnlessEqual(status.HTTP_202_ACCEPTED, response.status_code)
193
194     def test_ns_manual_scale_error_scaletype(self):
195         data = {
196             "scaleType": "SCALE_ERR",
197             "scaleNsData": [{
198                 "scaleNsByStepsData": [{
199                     "aspectId": "sss_zte",
200                     "numberOfSteps": 1,
201                     "scalingDirection": "0"
202                 }]
203             }]
204         }
205         NSManualScaleService(self.ns_inst_id, data, self.job_id).run()
206         jobs = JobModel.objects.filter(jobid=self.job_id)
207         self.assertEqual(255, jobs[0].progress)
208
209     def test_ns_manual_scale_error_nsd_id(self):
210         data = {
211             "scaleType": "SCALE_NS",
212             "scaleNsData": [{
213                 "scaleNsByStepsData": [{
214                     "aspectId": "sss_zte",
215                     "numberOfSteps": 1,
216                     "scalingDirection": "0"
217                 }]
218             }]
219         }
220         NSManualScaleService(self.ns_inst_id, data, self.job_id).run()
221         jobs = JobModel.objects.filter(jobid=self.job_id)
222         self.assertEqual(255, jobs[0].progress)
223
224     def test_ns_manual_scale_error_aspect(self):
225         data = {
226             "scaleType": "SCALE_NS",
227             "scaleNsData": [{
228                 "scaleNsByStepsData": [{
229                     "aspectId": "sss_zte",
230                     "numberOfSteps": 1,
231                     "scalingDirection": "0"
232                 }]
233             }]
234         }
235         ns_inst_id, job_id = self.insert_new_ns()
236         job_id = JobUtil.create_job(
237             "NS", JOB_TYPE.MANUAL_SCALE_VNF, ns_inst_id)
238         NSManualScaleService(ns_inst_id, data, job_id).run()
239         jobs = JobModel.objects.filter(jobid=job_id)
240         self.assertEqual(255, jobs[0].progress)
241
242     @mock.patch.object(catalog, 'get_scalingmap_json_package')
243     @mock.patch.object(NSManualScaleService, 'do_vnfs_scale')
244     def test_ns_manual_scale_success(self, mock_do_vnfs_scale, mock_get_scalingmap_json_package):
245         data = {
246             "scaleType": "SCALE_NS",
247             "scaleNsData": [{
248                 "scaleNsByStepsData": [{
249                     "aspectId": "TIC_EDGE_IMS",
250                     "numberOfSteps": "1",
251                     "scalingDirection": "0"
252                 }]
253             }]
254         }
255         mock_get_scalingmap_json_package.return_value = self.scaling_map_json
256         mock_do_vnfs_scale.return_value = JOB_MODEL_STATUS.FINISHED
257         ns_inst_id, job_id = self.insert_new_ns()
258         job_id = JobUtil.create_job(
259             "NS", JOB_TYPE.MANUAL_SCALE_VNF, ns_inst_id)
260         self.insert_new_nf()
261         NSManualScaleService(ns_inst_id, data, job_id).run()
262         jobs = JobModel.objects.filter(jobid=job_id)
263         self.assertEqual(255, jobs[0].progress)
264
265     @mock.patch.object(restcall, 'call_req')
266     def test_ns_manual_scale_thread(self, mock_call):
267         data = {
268             "scaleType": "SCALE_NS",
269             "scaleNsData": [{
270                 "scaleNsByStepsData": [{
271                     "aspectId": "1",
272                     "numberOfSteps": 1,
273                     "scalingDirection": "0"
274                 }]
275             }]
276         }
277         NSManualScaleService(self.ns_inst_id, data, self.job_id).run()
278         self.assertTrue(
279             NSInstModel.objects.get(
280                 id=self.ns_inst_id).status,
281             NS_INST_STATUS.ACTIVE)
282
283     def test_swagger_ok(self):
284         resp = self.client.get("/api/nslcm/v1/swagger.json", format='json')
285         self.assertEqual(resp.status_code, status.HTTP_200_OK)
286
287     @mock.patch.object(NSManualScaleService, 'start')
288     def test_ns_manual_scale_empty_data(self, mock_start):
289         mock_start.side_effect = NSLCMException("NS scale failed.")
290         response = self.client.post(
291             "/api/nslcm/v1/ns/%s/scale" %
292             self.ns_inst_id, data={})
293         self.assertEqual(
294             response.status_code,
295             status.HTTP_500_INTERNAL_SERVER_ERROR)
296         self.assertIn("error", response.data)
297
298     @mock.patch.object(NSManualScaleService, 'start')
299     def test_ns_manual_scale_when_ns_not_exist(self, mock_start):
300         mock_start.side_effect = NSLCMException("NS scale failed.")
301         data = {
302             "scaleType": "SCALE_NS",
303             "scaleNsData": [{
304                 "scaleNsByStepsData": [{
305                     "aspectId": "1",
306                     "numberOfSteps": 1,
307                     "scalingDirection": "0"
308                 }]
309             }]
310         }
311         response = self.client.post("/api/nslcm/v1/ns/11/scale", data=data)
312         self.assertEqual(
313             response.status_code,
314             status.HTTP_500_INTERNAL_SERVER_ERROR)
315         self.assertIn("error", response.data)