7261cee3bf8e3d4d0833a61d3988711a78e10291
[optf/has.git] / conductor / conductor / tests / unit / data / plugins / inventory_provider / test_aai.py
1 #
2 # -------------------------------------------------------------------------
3 #   Copyright (c) 2015-2017 AT&T Intellectual Property
4 #   Copyright (C) 2020 Wipro Limited.
5 #
6 #   Licensed under the Apache License, Version 2.0 (the "License");
7 #   you may not use this file except in compliance with the License.
8 #   You may obtain a copy of the License at
9 #
10 #       http://www.apache.org/licenses/LICENSE-2.0
11 #
12 #   Unless required by applicable law or agreed to in writing, software
13 #   distributed under the License is distributed on an "AS IS" BASIS,
14 #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 #   See the License for the specific language governing permissions and
16 #   limitations under the License.
17 #
18 # -------------------------------------------------------------------------
19 #
20 import copy
21 import json
22 import mock
23 import unittest
24 from unittest.mock import patch
25
26 from oslo_config import cfg
27
28 import conductor.data.plugins.inventory_provider.aai as aai
29 from conductor.data.plugins.inventory_provider.aai import AAI
30 from conductor.data.plugins.inventory_provider.sdc import SDC
31 from conductor.data.plugins.inventory_provider.hpa_utils import match_hpa
32 from conductor.data.plugins.triage_translator.triage_translator import TraigeTranslator
33
34
35 class TestAAI(unittest.TestCase):
36
37     def setUp(self):
38         cfg.CONF.set_override('password', '4HyU6sI+Tw0YMXgSHr5sJ5C0UTkeBaxXoxQqWuSVFugls7sQnaAXp4zMfJ8FKFrH', 'aai')
39         CONF = cfg.CONF
40         CONF.register_opts(aai.AAI_OPTS, group='aai')
41         self.conf = CONF
42         self.aai_ep = AAI()
43
44     def tearDown(self):
45         mock.patch.stopall()
46
47     def test_get_version_from_string(self):
48
49         self.assertEqual("2.5", self.aai_ep._get_version_from_string("AAI2.5"))
50         self.assertEqual("3.0", self.aai_ep._get_version_from_string("AAI3.0"))
51
52     def test_aai_versioned_path(self):
53
54         self.assertEqual('/{}/cloud-infrastructure/cloud-regions/?depth=0'.format(self.conf.aai.server_url_version),
55                          self.aai_ep._aai_versioned_path("/cloud-infrastructure/cloud-regions/?depth=0"))
56         self.assertEqual('/{}/query?format=id'.format(self.conf.aai.server_url_version),
57                          self.aai_ep._aai_versioned_path("/query?format=id"))
58
59     def test_resolve_clli_location(self):
60
61         req_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_request_clli_location.json'
62         req_json = json.loads(open(req_json_file).read())
63
64         response = mock.MagicMock()
65         response.status_code = 200
66         response.ok = True
67         response.json.return_value = req_json
68
69         self.mock_get_request = mock.patch.object(AAI, '_request', return_value=response)
70         self.mock_get_request.start()
71         self.assertEqual({'country': u'USA', 'latitude': u'40.39596', 'longitude': u'-74.135342'} ,
72                         self.aai_ep.resolve_clli_location("clli_code"))
73
74     def test_get_inventory_group_pair(self):
75
76         req_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_request_inventory_group_pair.json'
77         req_json = json.loads(open(req_json_file).read())
78
79         response = mock.MagicMock()
80         response.status_code = 200
81         response.ok = True
82         response.json.return_value = req_json
83
84         self.mock_get_request = mock.patch.object(AAI, '_request', return_value=response)
85         self.mock_get_request.start()
86         self.assertEqual([[u'instance-1', u'instance-2']] ,
87                         self.aai_ep.get_inventory_group_pairs("service_description"))
88
89     def test_resolve_host_location(self):
90
91         req_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_request_host_name.json'
92         req_json = json.loads(open(req_json_file).read())
93
94         req_response = mock.MagicMock()
95         req_response.status_code = 200
96         req_response.ok = True
97         req_response.json.return_value = req_json
98
99         complex_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_get_complex.json'
100         complex_json = json.loads(open(complex_json_file).read())
101
102         self.mock_get_request = mock.patch.object(AAI, '_request', return_value=req_response)
103         self.mock_get_request.start()
104
105         self.mock_get_complex = mock.patch.object(AAI, '_get_complex', return_value=complex_json)
106         self.mock_get_complex.start()
107
108         self.assertEqual({'country': u'USA', 'latitude': u'28.543251', 'longitude': u'-81.377112'} ,
109                          self.aai_ep.resolve_host_location("host_name"))
110
111     def test_resolve_demands_inventory_type_cloud(self):
112
113         self.aai_ep.conf.HPA_enabled = True
114         TraigeTranslator.getPlanIdNAme = mock.MagicMock(return_value=None)
115         TraigeTranslator.addDemandsTriageTranslator = mock.MagicMock(return_value=None)
116
117         plan_info = {
118             'plan_name': 'name',
119             'plan_id': 'id'
120         }
121         triage_translator_data = None
122
123         demands_list_file = './conductor/tests/unit/data/plugins/inventory_provider/demand_list.json'
124         demands_list = json.loads(open(demands_list_file).read())
125
126         generic_vnf_list_file = './conductor/tests/unit/data/plugins/inventory_provider/generic_vnf_list.json'
127         generic_vnf_list = json.loads(open(generic_vnf_list_file).read())
128
129         regions_response_file = './conductor/tests/unit/data/plugins/inventory_provider/regions.json'
130         regions_response = json.loads(open(regions_response_file).read())
131
132         demand_service_response_file = './conductor/tests/unit/data/plugins/inventory_provider/resolve_demand_service_response.json'
133         demand_service_response = json.loads(open(demand_service_response_file).read())
134
135         complex_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_get_complex.json'
136         complex_json = json.loads(open(complex_json_file).read())
137
138         req_response = mock.MagicMock()
139         req_response.status_code = 200
140         req_response.ok = True
141         req_response.json.return_value = demand_service_response
142
143         self.mock_first_level_service_call = mock.patch.object(AAI, 'first_level_service_call', return_value=generic_vnf_list)
144         self.mock_first_level_service_call.start()
145
146         self.mock_get_regions = mock.patch.object(AAI, '_get_regions', return_value=regions_response)
147         self.mock_get_regions.start()
148
149         regions_list = list()
150         regions_list.append(regions_response.get('region-name'))
151         self.mock_resolve_cloud_regions_by_cloud_region_id = mock.patch.object(AAI,
152                                                                                'resolve_cloud_regions_by_cloud_region_id',
153                                                                                return_value=regions_list)
154         self.mock_resolve_cloud_regions_by_cloud_region_id.start()
155
156
157         self.mock_resolve_v_server_for_candidate = mock.patch.object(AAI, 'resolve_v_server_for_candidate',
158                                                                       return_value=demand_service_response)
159         self.mock_resolve_v_server_for_candidate.start()
160
161         complex_link = {"link": "/aai/v10/complex-id", "d_value": 'test-id'}
162         self.mock_resolve_complex_info_link_for_v_server = mock.patch.object(AAI,
163                                                                              'resolve_complex_info_link_for_v_server',
164                                                                              return_value=complex_link)
165         self.mock_resolve_complex_info_link_for_v_server.start()
166
167         self.mock_get_complex = mock.patch.object(AAI, '_get_complex', return_value=complex_json)
168         self.mock_get_complex.start()
169
170         flavor_info = regions_response["region-name"]["flavors"]
171         self.maxDiff = None
172         self.assertCountEqual({u'demand_name': [
173             {'candidate_id': u'service-instance-id', 'city': None,
174              'cloud_owner': u'cloud-owner',
175              'uniqueness': 'true',
176              'vim-id': u'cloud-owner_cloud-region-id',
177              'vlan_key': None, 'cloud_region_version': '', 'complex_name': None, 'cost': 1.0,
178              'country': u'USA', 'existing_placement': 'false',
179              'host_id': u'vnf-name', 'inventory_provider': 'aai',
180              'inventory_type': 'service', 'latitude': u'28.543251',
181              'location_id': u'cloud-region-id', 'location_type': 'att_aic',
182              'longitude': u'-81.377112', 'physical_location_id': u'test-id',
183              'port_key': None,
184              'region': u'SE', 'service_resource_id': '',
185              'sriov_automation': 'false', 'state': None},
186             {'candidate_id': u'region-name', 'city': u'Middletown',
187              'cloud_owner': u'cloud-owner',
188              'uniqueness': 'true',
189              'vim-id': u'cloud-owner_region-name',
190              'cloud_region_version': u'1.0', 'complex_name': u'complex-name',
191              'cost': 2.0, 'country': u'USA', 'existing_placement': 'false',
192              'inventory_provider': 'aai', 'inventory_type': 'cloud',
193              'latitude': u'50.34', 'location_id': u'region-name',
194              'location_type': 'att_aic', 'longitude': u'30.12',
195              'physical_location_id': u'complex-id',
196              'region': u'USA', 'service_resource_id': u'service-resource-id-123',
197              'sriov_automation': 'false', 'state': u'NJ',
198              'flavors': flavor_info}]},
199             self.aai_ep.resolve_demands(demands_list, plan_info=plan_info,
200                                         triage_translator_data=triage_translator_data))
201
202     def test_resolve_demands_inventory_type_service(self):
203         self.aai_ep.conf.HPA_enabled = True
204         TraigeTranslator.getPlanIdNAme = mock.MagicMock(return_value=None)
205         TraigeTranslator.addDemandsTriageTranslator = mock.MagicMock(return_value=None)
206
207         plan_info = {
208             'plan_name': 'name',
209             'plan_id': 'id'
210         }
211         triage_translator_data = None
212
213         demands_list_file = './conductor/tests/unit/data/plugins/inventory_provider/service_demand_list.json'
214         demands_list = json.loads(open(demands_list_file).read())
215
216         generic_vnf_list_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_service_generic_vnf_list.json'
217         generic_vnf_list = json.loads(open(generic_vnf_list_file).read())
218
219         v_server_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_vserver.json'
220         v_server = json.loads(open(v_server_file).read())
221
222         demand_service_response_file = './conductor/tests/unit/data/plugins/inventory_provider/resolve_demand_service_response.json'
223         demand_service_response = json.loads(open(demand_service_response_file).read())
224
225         complex_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_complex.json'
226         complex_response = json.loads(open(complex_file).read())
227
228         region_response_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_region.json'
229         region_response = json.loads(open(region_response_file).read())
230
231         results_file = './conductor/tests/unit/data/plugins/inventory_provider/service_candidates.json'
232         results_json = json.loads(open(results_file).read())
233
234         req_response = mock.MagicMock()
235         req_response.status_code = 200
236         req_response.ok = True
237         req_response.json.return_value = demand_service_response
238
239         def mock_first_level_service_call_response(path, name, service_type):
240             if "equipment-role" in path:
241                 return list()
242             else:
243                 return generic_vnf_list
244
245         self.mock_first_level_service_call = mock.patch.object(AAI, 'first_level_service_call',
246                                                                side_effect=mock_first_level_service_call_response)
247         self.mock_first_level_service_call.start()
248
249         regions = list()
250         regions.append(region_response)
251         self.mock_resolve_cloud_regions_by_cloud_region_id = mock.patch.object(AAI,
252                                                                                'resolve_cloud_regions_by_cloud_region_id',
253                                                                                return_value=regions)
254         self.mock_resolve_cloud_regions_by_cloud_region_id.start()
255
256         self.mock_resolve_v_server_for_candidate = mock.patch.object(AAI, 'resolve_v_server_for_candidate',
257                                                                       return_value=v_server)
258         self.mock_resolve_v_server_for_candidate.start()
259
260         complex_link = {"link": "/aai/v14/cloud-infrastructure/complexes/complex/clli1", "d_value": 'clli1'}
261         self.mock_resolve_complex_info_link_for_v_server = mock.patch.object(AAI,
262                                                                              'resolve_complex_info_link_for_v_server',
263                                                                              return_value=complex_link)
264         self.mock_resolve_complex_info_link_for_v_server.start()
265
266         self.mock_get_complex = mock.patch.object(AAI, '_get_complex', return_value=complex_response)
267         self.mock_get_complex.start()
268
269         self.maxDiff = None
270         self.assertEqual(results_json, self.aai_ep.resolve_demands(demands_list, plan_info=plan_info,
271                                          triage_translator_data=triage_translator_data))
272
273     def test_resolve_demands_inventory_type_vfmodule(self):
274         self.aai_ep.conf.HPA_enabled = True
275         TraigeTranslator.getPlanIdNAme = mock.MagicMock(return_value=None)
276         TraigeTranslator.addDemandsTriageTranslator = mock.MagicMock(return_value=None)
277
278         plan_info = {
279             'plan_name': 'name',
280             'plan_id': 'id'
281         }
282         triage_translator_data = None
283
284         demands_list_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_demand_list.json'
285         demands_list = json.loads(open(demands_list_file).read())
286
287         generic_vnf_list_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_service_generic_vnf_list.json'
288         generic_vnf_list = json.loads(open(generic_vnf_list_file).read())
289
290         vfmodules_list_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_list.json'
291         vfmodules_list = json.loads(open(vfmodules_list_file).read())
292
293         v_server_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_vserver.json'
294         v_server = json.loads(open(v_server_file).read())
295
296         demand_service_response_file = './conductor/tests/unit/data/plugins/inventory_provider/resolve_demand_service_response.json'
297         demand_service_response = json.loads(open(demand_service_response_file).read())
298
299         complex_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_complex.json'
300         complex_response = json.loads(open(complex_file).read())
301
302         region_response_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_region.json'
303         region_response = json.loads(open(region_response_file).read())
304
305         results_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_candidates.json'
306         results_json = json.loads(open(results_file).read())
307
308         req_response = mock.MagicMock()
309         req_response.status_code = 200
310         req_response.ok = True
311         req_response.json.return_value = demand_service_response
312
313         def mock_first_level_service_call_response(path, name, service_type):
314             if "equipment-role" in path:
315                 return list()
316             else:
317                 return generic_vnf_list
318
319         self.mock_first_level_service_call = mock.patch.object(AAI, 'first_level_service_call',
320                                                                side_effect=mock_first_level_service_call_response)
321         self.mock_first_level_service_call.start()
322
323         self.mock_resolve_vf_modules_for_generic_vnf = mock.patch.object(AAI, 'resolve_vf_modules_for_generic_vnf',
324                                                                          return_value=vfmodules_list)
325         self.mock_resolve_vf_modules_for_generic_vnf.start()
326
327         regions = list()
328         regions.append(region_response)
329         self.mock_resolve_cloud_regions_by_cloud_region_id = mock.patch.object(AAI,
330                                                                                'resolve_cloud_regions_by_cloud_region_id',
331                                                                                return_value=regions)
332         self.mock_resolve_cloud_regions_by_cloud_region_id.start()
333
334         self.mock_resolve_v_server_for_candidate = mock.patch.object(AAI, 'resolve_v_server_for_candidate',
335                                                                        return_value=v_server)
336         self.mock_resolve_v_server_for_candidate.start()
337
338         complex_link = {"link": "/aai/v14/cloud-infrastructure/complexes/complex/clli1", "d_value": 'clli1'}
339         self.mock_resolve_complex_info_link_for_v_server = mock.patch.object(AAI, 'resolve_complex_info_link_for_v_server',
340                                                                              return_value=complex_link)
341         self.mock_resolve_complex_info_link_for_v_server.start()
342
343         self.mock_get_complex = mock.patch.object(AAI, '_get_complex', return_value=complex_response)
344         self.mock_get_complex.start()
345
346         self.maxDiff = None
347         self.assertEqual(results_json, self.aai_ep.resolve_demands(demands_list, plan_info=plan_info,
348                                          triage_translator_data=triage_translator_data))
349
350     def test_get_complex(self):
351
352         complex_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_request_get_complex.json'
353         complex_json = json.loads(open(complex_json_file).read())
354
355         response = mock.MagicMock()
356         response.status_code = 200
357         response.ok = True
358         response.json.return_value = complex_json
359
360         self.mock_get_request = mock.patch.object(AAI, '_request', return_value=response)
361         self.mock_get_request.start()
362
363         self.assertEqual({u'city': u'Middletown', u'latitude': u'28.543251', u'longitude': u'-81.377112', u'country': u'USA', u'region': u'SE'},
364                          self.aai_ep._get_complex("/v10/complex/complex_id", "complex_id"))
365
366     def test_check_network_roles(self):
367
368         network_role_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_request_network_role.json'
369         network_role_json = json.loads(open(network_role_json_file).read())
370
371         response = mock.MagicMock()
372         response.status_code = 200
373         response.ok = True
374         response.json.return_value = network_role_json
375
376         self.mock_get_request = mock.patch.object(AAI, '_request', return_value=response)
377         self.mock_get_request.start()
378         self.assertEqual(set(['test-cloud-value']) ,
379                         self.aai_ep.check_network_roles("network_role_id"))
380
381     def test_check_candidate_role(self):
382
383         candidate_role_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_request_candidate_role.json'
384         candidate_role_json = json.loads(open(candidate_role_json_file).read())
385
386         response = mock.MagicMock()
387         response.status_code = 200
388         response.ok = True
389         response.json.return_value = candidate_role_json
390
391         self.mock_get_request = mock.patch.object(AAI, '_request', return_value=response)
392         self.mock_get_request.start()
393
394         self.assertEqual("test-role",
395                          self.aai_ep.check_candidate_role("candidate_host_id"))
396
397     def test_match_inventory_attributes(self):
398         template_attributes = dict()
399         template_attributes['attr-1'] = ['attr-1-value1', 'attr-1-value2']
400
401         inventory_attributes = dict()
402         inventory_attributes['attr-1'] = 'attr-1-value1'
403
404         self.assertEqual(True,
405                          self.aai_ep.match_inventory_attributes(template_attributes, inventory_attributes, "candidate-id"))
406
407         template_attributes['attr-1'] = {
408             'not': ['attr-1-value2']
409         }
410         self.assertEqual(True,
411                          self.aai_ep.match_inventory_attributes(template_attributes, inventory_attributes,
412                                                                 "candidate-id"))
413
414         template_attributes['attr-1'] = {
415             'not': ['attr-1-value1']
416         }
417         self.assertEqual(False,
418                          self.aai_ep.match_inventory_attributes(template_attributes, inventory_attributes,
419                                                                 "candidate-id"))
420
421     def test_refresh_cache(self):
422         regions_response_file = './conductor/tests/unit/data/plugins/inventory_provider/cache_regions.json'
423         regions_response = json.loads(open(regions_response_file).read())
424
425         complex_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_cached_complex.json'
426         complex_json = json.loads(open(complex_json_file).read())
427
428         flavors_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_request_get_flavors.json'
429         flavors_json = json.loads(open(flavors_json_file).read())
430
431         response = mock.MagicMock()
432         response.status_code = 200
433         response.ok = True
434         response.json.return_value = regions_response
435
436         self.mock_get_regions = mock.patch.object(AAI, '_request', return_value=response)
437         self.mock_get_regions.start()
438
439         self.mock_get_complex = mock.patch.object(AAI, '_get_complex', return_value=complex_json)
440         self.mock_get_complex.start()
441
442         self.mock_get_flavors = mock.patch.object(AAI, '_get_flavors',
443                                                   return_value=flavors_json)
444         self.mock_get_flavors.start()
445
446         self.assertEqual(None,
447                          self.aai_ep._refresh_cache())
448
449     def test_get_aai_rel_link(self):
450
451         relatonship_response_file = './conductor/tests/unit/data/plugins/inventory_provider/relationship_list.json'
452         relatonship_response = json.loads(open(relatonship_response_file).read())
453         related_to = "service-instance"
454
455         self.assertEqual("relationship-link",
456                          self.aai_ep._get_aai_rel_link(relatonship_response, related_to))
457
458     def test_get_flavor(self):
459         flavors_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_request_get_flavors.json'
460         flavors_json = json.loads(open(flavors_json_file).read())
461
462         response = mock.MagicMock()
463         response.json.return_value = None
464
465         self.mock_get_request = mock.patch.object(AAI, '_request',
466                                                   return_value=response)
467         self.mock_get_request.start()
468
469         flavors_info = self.aai_ep._get_flavors("mock-cloud-owner",
470                                                 "mock-cloud-region-id")
471         self.assertEqual(None, flavors_info)
472
473         response.status_code = 200
474         response.ok = True
475         response.json.return_value = flavors_json
476
477         flavors_info = self.aai_ep._get_flavors("mock-cloud-owner",
478                                                 "mock-cloud-region-id")
479         self.assertEqual(2, len(flavors_info['flavor']))
480
481     def test_resolve_complex_info_link_for_v_server(self):
482         TraigeTranslator.collectDroppedCandiate = mock.MagicMock(return_value=None)
483         triage_translator_data = None
484         demand_name = 'vPGN'
485         service_type = 'vFW'
486         cloud_owner = 'CloudOwner'
487         cloud_region_id = 'RegionOne'
488         v_server_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_vserver.json'
489         v_server = json.loads(open(v_server_file).read())
490         region_response_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_region.json'
491         region_response = json.loads(open(region_response_file).read())
492
493         candidate_id = 'some_id'
494         location_id = 'some_location_id'
495         inventory_type = 'service'
496
497         response = mock.MagicMock()
498         response.status_code = 200
499         response.ok = True
500         response.json.return_value = region_response
501
502         self.mock_get_request = mock.patch.object(AAI, '_request', return_value=response)
503         self.mock_get_request.start()
504
505         link_rl_data = self.aai_ep.resolve_complex_info_link_for_v_server(candidate_id, v_server, None,
506                                                                           cloud_region_id, service_type,
507                                                                           demand_name, triage_translator_data)
508         self.assertEqual(None, link_rl_data)
509
510         complex_link = {"link": "/aai/v14/cloud-infrastructure/complexes/complex/clli1", "d_value": 'clli1'}
511         link_rl_data = self.aai_ep.resolve_complex_info_link_for_v_server(candidate_id, v_server, cloud_owner,
512                                                                           cloud_region_id, service_type,
513                                                                           demand_name, triage_translator_data)
514         self.assertEqual(complex_link, link_rl_data)
515
516     def test_build_complex_info_for_candidate(self):
517         TraigeTranslator.collectDroppedCandiate = mock.MagicMock(return_value=None)
518         triage_translator_data = None
519         demand_name = 'vPGN'
520         service_type = 'vFW'
521         complex_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_complex.json'
522         complex_response = json.loads(open(complex_file).read())
523
524         candidate = dict()
525         candidate['candidate_id'] = 'some_id'
526         candidate['location_id'] = 'some_location_id'
527         candidate['inventory_type'] = 'service'
528         initial_candidate = copy.deepcopy(candidate)
529         complex_list_empty = dict()
530         complex_list = list()
531         complex_list.append({"link": "/aai/v14/cloud-infrastructure/complexes/complex/clli1", "d_value": 'clli1'})
532         complex_list.append({"link": "/aai/v14/cloud-infrastructure/complexes/complex/clli2", "d_value": 'clli2'})
533
534         self.mock_get_complex = mock.patch.object(AAI, '_get_complex', return_value=complex_response)
535         self.mock_get_complex.start()
536
537         self.aai_ep.build_complex_info_for_candidate(candidate['candidate_id'], candidate['location_id'], None, complex_list_empty, candidate['inventory_type'], demand_name,
538                                                      triage_translator_data)
539         self.assertEqual(initial_candidate, candidate)
540         self.assertEqual(1, TraigeTranslator.collectDroppedCandiate.call_count)
541
542         self.aai_ep.build_complex_info_for_candidate(candidate['candidate_id'], candidate['location_id'], None, complex_list, candidate['inventory_type'], demand_name,
543                                                      triage_translator_data)
544         self.assertEqual(initial_candidate, candidate)
545         self.assertEqual(2, TraigeTranslator.collectDroppedCandiate.call_count)
546
547         complex_list.pop()
548         self.aai_ep.build_complex_info_for_candidate(candidate['candidate_id'], candidate['location_id'], None, complex_list, candidate['inventory_type'], demand_name,
549                                                      triage_translator_data)
550
551         self.assertEqual(self.aai_ep.build_complex_info_for_candidate(candidate['candidate_id'], candidate['location_id'], None, complex_list, candidate['inventory_type'], demand_name,
552                                                      triage_translator_data), {'city': u'example-city-val-27150', 'country': u'example-country-val-94173',
553                                      'region': u'example-region-val-13893', 'longitude': u'32.89948', 'state': u'example-state-val-59487',
554                                      'physical_location_id': 'clli1', 'latitude': u'example-latitude-val-89101',
555                                      'complex_name': u'clli1'})
556         self.assertEqual(2, TraigeTranslator.collectDroppedCandiate.call_count)
557
558     def test_resolve_vnf_parameters(self):
559         TraigeTranslator.collectDroppedCandiate = mock.MagicMock(return_value=None)
560         triage_translator_data = None
561         demand_name = 'vPGN'
562         service_type = 'vFW'
563         candidate = dict()
564         candidate_id = 'some_id'
565         location_id = 'some_location_id'
566         candidate['inventory_type'] = 'service'
567
568         generic_vnf_list_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_service_generic_vnf_list.json'
569         good_vnf = json.loads(open(generic_vnf_list_file).read())[0]
570         bad_generic_vnf_list_file = './conductor/tests/unit/data/plugins/inventory_provider/bad_generic_vnf_list.json'
571         bad_vnf = json.loads(open(bad_generic_vnf_list_file).read())[0]
572         region_response_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_region.json'
573         region_response = json.loads(open(region_response_file).read())
574
575         regions = list()
576         regions.append(region_response)
577         self.mock_get_regions = mock.patch.object(AAI, 'resolve_cloud_regions_by_cloud_region_id',
578                                                   return_value=regions)
579         self.mock_get_regions.start()
580
581         good_cloud_info = self.aai_ep.resolve_cloud_for_vnf(candidate_id, location_id, good_vnf, service_type,
582                                                                  demand_name, triage_translator_data)
583         bad_cloud_info = self.aai_ep.resolve_cloud_for_vnf(candidate_id, location_id, bad_vnf, service_type,
584                                                                  demand_name, triage_translator_data)
585         self.assertEqual("CloudOwner", good_cloud_info['cloud_owner'])
586         self.assertEqual("RegionOne", good_cloud_info['location_id'])
587         self.assertEqual("1", good_cloud_info['cloud_region_version'])
588
589         self.assertIsNone(bad_cloud_info)
590
591         v_server_links = list()
592         v_server_links.append("/aai/v14/cloud-infrastructure/cloud-regions/cloud-region/CloudOwner/RegionOne/tenants/\
593 tenant/3c6c471ada7747fe8ff7f28e100b61e8/vservers/vserver/00bddefc-126e-4e4f-a18d-99b94d8d9a30")
594         v_server_links.append("/aai/v14/cloud-infrastructure/cloud-regions/cloud-region/CloudOwner2/RegionOne2/tenants/\
595 tenant/3c6c471ada7747fe8ff7f28e100b61e8/vservers/vserver/00bddefc-126e-4e4f-a18d-99b94d8d9a31")
596         self.assertEqual(v_server_links, self.aai_ep.resolve_v_server_links_for_vnf(bad_vnf))
597
598         customer_id = 'Demonstration'
599         self.assertEqual(customer_id,
600                          self.aai_ep.resolve_global_customer_id_for_vnf(candidate_id, location_id, good_vnf, customer_id, service_type,
601                                                                         demand_name,
602                                                                         triage_translator_data).get('d_value'))
603         self.assertEqual("3e8d118c-10ca-4b4b-b3db-089b5e9e6a1c",
604                          self.aai_ep.resolve_service_instance_id_for_vnf(candidate_id, location_id, good_vnf, customer_id, service_type,
605                                                                          demand_name,
606                                                                          triage_translator_data).get('d_value'))
607         self.assertIsNone(self.aai_ep.resolve_service_instance_id_for_vnf(candidate_id, location_id, bad_vnf, customer_id, service_type,
608                                                                           demand_name, triage_translator_data))
609
610     def test_add_passthrough_parameters(self):
611         triage_translator_data = None
612
613         candidate = dict()
614         candidate['candidate_id'] = 'some_id'
615         candidate['location_id'] = 'some_location_id'
616         candidate['inventory_type'] = 'service'
617
618         parameters = dict()
619         parameters['param_one'] = "value"
620         parameters['param_two'] = "value"
621
622         candidate_info = copy.deepcopy(candidate)
623         candidate_info['passthrough_attributes'] = dict()
624         candidate_info['passthrough_attributes']['param_one'] = "value"
625         candidate_info['passthrough_attributes']['param_two'] = "value"
626
627         self.aai_ep.add_passthrough_attributes(candidate, parameters, 'demand')
628         self.assertDictEqual(candidate, candidate_info)
629
630     def test_match_candidate_by_list(self):
631         TraigeTranslator.collectDroppedCandiate = mock.MagicMock(return_value=None)
632         triage_translator_data = None
633
634         candidate = dict()
635         candidate['candidate_id'] = 'some_id'
636         candidate['location_id'] = 'some_location_id'
637         candidate['inventory_type'] = 'service'
638
639         candidate_list_empty = list()
640         candidate_list = list()
641         candidate_info = copy.deepcopy(candidate)
642         candidate_info['candidate_id'] = list()
643         candidate_info['candidate_id'].append(candidate['candidate_id'])
644         candidate_list.append(candidate_info)
645
646         self.assertFalse(self.aai_ep.match_candidate_by_list(candidate, candidate_list_empty, True, 'demand',
647                                                              triage_translator_data)),
648         self.assertEqual(0, TraigeTranslator.collectDroppedCandiate.call_count)
649         self.assertTrue(self.aai_ep.match_candidate_by_list(candidate, candidate_list, True, 'demand',
650                                                             triage_translator_data))
651         self.assertEqual(1, TraigeTranslator.collectDroppedCandiate.call_count)
652         self.assertTrue(self.aai_ep.match_candidate_by_list(candidate, candidate_list, False, 'demand',
653                                                             triage_translator_data))
654         self.assertEqual(1, TraigeTranslator.collectDroppedCandiate.call_count)
655         self.assertFalse(self.aai_ep.match_candidate_by_list(candidate, candidate_list_empty, False, 'demand',
656                                                              triage_translator_data))
657         self.assertEqual(2, TraigeTranslator.collectDroppedCandiate.call_count)
658
659     def test_match_hpa(self):
660         flavor_json_file = \
661             './conductor/tests/unit/data/plugins/inventory_provider/hpa_flavors.json'
662         flavor_json = json.loads(open(flavor_json_file).read())
663         feature_json_file = \
664             './conductor/tests/unit/data/plugins/inventory_provider/hpa_req_features.json'
665         feature_json = json.loads(open(feature_json_file).read())
666         candidate_json_file = './conductor/tests/unit/data/candidate_list.json'
667         candidate_json = json.loads(open(candidate_json_file).read())
668         candidate_json['candidate_list'][1]['flavors'] = flavor_json
669
670         flavor_map = {
671             "directives": [],
672             "flavor_map": {"flavor-id": "f5aa2b2e-3206-41b6-80d5-cf041b098c43",
673                            "flavor-name": "flavor-cpu-pinning-ovsdpdk-instruction-set",
674                            "score": 0}}
675         self.assertEqual(flavor_map,
676                          match_hpa(candidate_json['candidate_list'][1],
677                                                feature_json[0]))
678
679         flavor_map = {"flavor_map": {"flavor-id": "f5aa2b2e-3206-41b6-80d5-cf041b098c43",
680                                      "flavor-name": "flavor-cpu-ovsdpdk-instruction-set",
681                                      "score": 10},
682                       "directives": []}
683         self.assertEqual(flavor_map,
684                          match_hpa(candidate_json['candidate_list'][1],
685                                                feature_json[1]))
686         flavor_map = {"flavor_map": {"flavor-id": "f5aa2b2e-3206-41b6-80d5-cf6t2b098c43",
687                                      "flavor-name": "flavor-ovsdpdk-cpu-pinning-sriov-NIC-Network-set",
688                                      "score": 13},
689                       "directives": [{
690                           "type": "sriovNICNetwork_directives",
691                           "attributes": [
692                               {
693                                   "attribute_name": "A",
694                                   "attribute_value": "a"
695                               }
696                           ]
697                       }]}
698         self.assertEqual(flavor_map,
699                          match_hpa(candidate_json['candidate_list'][1],
700                                                feature_json[2]))
701         self.assertEqual(None, match_hpa(candidate_json['candidate_list'][1],
702                                                      feature_json[3]))
703         flavor_map = {"flavor_map": {"flavor-id": "f5aa2b2e-3206-41b6-19d5-cf6t2b098c43",
704                                      "flavor-name": "flavor-ovsdpdk-cpu-pinning-double-sriov-NIC-Network-set",
705                                      "score": 6},
706                       "directives": [
707                           {
708                               "type": "sriovNICNetwork_directives",
709                               "attributes": [
710                                   {
711                                       "attribute_name": "A",
712                                       "attribute_value": "a"
713                                   }
714                               ]
715                           },
716                           {
717                               "type": "sriovNICNetwork_directives",
718                               "attributes": [
719                                   {
720                                       "attribute_name": "B",
721                                       "attribute_value": "b"
722                                   }
723                               ]
724                           }]
725                       }
726         self.assertEqual(flavor_map, match_hpa(candidate_json['candidate_list'][1],
727                                                            feature_json[4]))
728         self.assertEqual(None, match_hpa(candidate_json['candidate_list'][1],
729                                                      feature_json[5]))
730
731     def test_filter_nssi_candidates(self):
732         nssi_response_file = './conductor/tests/unit/data/plugins/inventory_provider/nssi_response.json'
733         nssi_response = json.loads(open(nssi_response_file).read())
734         slice_profile_file = './conductor/tests/unit/data/plugins/inventory_provider/nssi_slice_profile.json'
735         slice_profile = json.loads(open(slice_profile_file).read())
736         nssi_candidates_file = './conductor/tests/unit/data/plugins/inventory_provider/nssi_candidate.json'
737         nssi_candidates = json.loads(open(nssi_candidates_file).read())
738
739         self.mock_get_profiles = mock.patch.object(AAI, 'get_profile_instances', return_value=[slice_profile])
740         self.mock_get_profiles.start()
741
742         service_role = 'nssi'
743         second_level_filter = dict()
744         second_level_filter['service-role'] = service_role
745         default_attributes = dict()
746         default_attributes['creation_cost'] =1
747         self.assertEqual(nssi_candidates, self.aai_ep.filter_nxi_candidates(nssi_response, second_level_filter,
748                                                                             default_attributes, "true", service_role))
749
750         nssi_response['service-instance'][0]['service-role'] = 'service'
751
752         self.assertEqual([], self.aai_ep.filter_nxi_candidates(nssi_response, second_level_filter, default_attributes,
753                                                                "true", service_role))
754
755         self.assertEqual([], self.aai_ep.filter_nxi_candidates(None, second_level_filter, default_attributes,
756                                                                "true", service_role))
757
758         self.assertEqual([], self.aai_ep.filter_nxi_candidates(None, None, default_attributes, "true", service_role))
759
760         self.assertEqual(nssi_candidates, self.aai_ep.filter_nxi_candidates(nssi_response, None, default_attributes,
761                                                                             "true", service_role))
762         del nssi_candidates[0]['creation_cost']
763         self.assertEqual(nssi_candidates, self.aai_ep.filter_nxi_candidates(nssi_response, None, None, "true",
764                                                                             service_role))
765
766     def test_resolve_demands_inventory_type_nssi(self):
767         self.aai_ep.conf.HPA_enabled = True
768         TraigeTranslator.getPlanIdNAme = mock.MagicMock(return_value=None)
769         TraigeTranslator.addDemandsTriageTranslator = mock.MagicMock(return_value=None)
770
771         plan_info = {
772             'plan_name': 'name',
773             'plan_id': 'id'
774         }
775         triage_translator_data = None
776
777         demands_list_file = './conductor/tests/unit/data/plugins/inventory_provider/nssi_demand_list.json'
778         demands_list = json.loads(open(demands_list_file).read())
779
780         nssi_response_file = './conductor/tests/unit/data/plugins/inventory_provider/nssi_response.json'
781         nssi_response = json.loads(open(nssi_response_file).read())
782         slice_profile_file = './conductor/tests/unit/data/plugins/inventory_provider/nssi_slice_profile.json'
783         slice_profile = json.loads(open(slice_profile_file).read())
784         nssi_candidates_file = './conductor/tests/unit/data/plugins/inventory_provider/nssi_candidate.json'
785         nssi_candidates = json.loads(open(nssi_candidates_file).read())
786         result = dict()
787         result['embb_cn'] = nssi_candidates
788
789         self.mock_get_nxi_candidates = mock.patch.object(AAI, 'get_nxi_candidates',
790                                                          return_value=nssi_response)
791         self.mock_get_nxi_candidates.start()
792
793         self.mock_get_profiles = mock.patch.object(AAI, 'get_profile_instances', return_value=[slice_profile])
794         self.mock_get_profiles.start()
795
796         self.assertEqual(result, self.aai_ep.resolve_demands(demands_list, plan_info=plan_info,
797                                                              triage_translator_data=triage_translator_data))
798
799     def test_filter_nsi_candidates(self):
800         nsi_response_file = './conductor/tests/unit/data/plugins/inventory_provider/nsi_response.json'
801         nsi_response = json.loads(open(nsi_response_file).read())
802         nsi_candidates_file = './conductor/tests/unit/data/plugins/inventory_provider/nsi_candidate.json'
803         nsi_candidates = json.loads(open(nsi_candidates_file).read())
804         service_profile_file = './conductor/tests/unit/data/plugins/inventory_provider/nsi_service_profile.json'
805         service_profile = json.loads(open(service_profile_file).read())
806
807         self.mock_get_profiles = mock.patch.object(AAI, 'get_profile_instances', return_value=[service_profile])
808         self.mock_get_profiles.start()
809
810         service_role = 'nsi'
811         second_level_filter = dict()
812         second_level_filter['service-role'] = service_role
813         default_attributes = dict()
814         default_attributes['creation_cost'] = 1
815
816         self.assertEqual(nsi_candidates, self.aai_ep.filter_nxi_candidates(nsi_response, second_level_filter,
817                                                                            default_attributes, "true", service_role))
818         nsi_response['service-instance'][0]['service-role'] = 'service'
819
820         self.assertEqual([], self.aai_ep.filter_nxi_candidates(nsi_response, second_level_filter, default_attributes,
821                                                                "true", service_role))
822
823     def test_resolve_demands_inventory_type_nsi(self):
824         self.aai_ep.conf.HPA_enabled = True
825         TraigeTranslator.getPlanIdNAme = mock.MagicMock(return_value=None)
826         TraigeTranslator.addDemandsTriageTranslator = mock.MagicMock(return_value=None)
827
828         plan_info = {
829             'plan_name': 'name',
830             'plan_id': 'id'
831         }
832         triage_translator_data = None
833
834         demands_list_file = './conductor/tests/unit/data/plugins/inventory_provider/nsi_demand_list.json'
835         demands_list = json.loads(open(demands_list_file).read())
836
837         nsi_response_file = './conductor/tests/unit/data/plugins/inventory_provider/nsi_response.json'
838         nsi_response = json.loads(open(nsi_response_file).read())
839         nsi_candidates_file = './conductor/tests/unit/data/plugins/inventory_provider/nsi_candidate.json'
840         nsi_candidates = json.loads(open(nsi_candidates_file).read())
841         result = dict()
842         result['embb_nst'] = nsi_candidates
843
844         service_profile_file = './conductor/tests/unit/data/plugins/inventory_provider/nsi_service_profile.json'
845         service_profile = json.loads(open(service_profile_file).read())
846
847         self.mock_get_profiles = mock.patch.object(AAI, 'get_profile_instances', return_value=[service_profile])
848         self.mock_get_profiles.start()
849
850         self.mock_get_nxi_candidates = mock.patch.object(AAI, 'get_nxi_candidates',
851                                                          return_value=nsi_response)
852         self.mock_get_nxi_candidates.start()
853         self.maxDiff = None
854         self.assertEqual(result, self.aai_ep.resolve_demands(demands_list, plan_info=plan_info,
855                                                              triage_translator_data=triage_translator_data))
856
857
858     def test_get_nst_candidates(self):
859         nst_response_file = './conductor/tests/unit/data/plugins/inventory_provider/nst_response.json'
860         nst_response = json.loads(open(nst_response_file).read())
861
862
863
864         second_level_filter=None
865
866         default_attributes = dict()
867         default_attributes['creation_cost'] = 1
868         self.assertEqual("5d345ca8-1f8e-4f1e-aac7-6c8b33cc33e7", self.aai_ep.get_nst_candidates(nst_response, second_level_filter,
869                                                                            default_attributes, "true", "nst").__getitem__(0).__getattribute__('candidate_id'))
870
871
872     def test_resolve_demands_inventory_type_nst(self):
873         self.aai_ep.conf.HPA_enabled = True
874         TraigeTranslator.getPlanIdNAme = mock.MagicMock(return_value=None)
875         TraigeTranslator.addDemandsTriageTranslator = mock.MagicMock(return_value=None)
876
877         plan_info = {
878             'plan_name': 'name',
879             'plan_id': 'id'
880         }
881         triage_translator_data = None
882
883         demands_list_file = './conductor/tests/unit/data/plugins/inventory_provider/nst_demand_list.json'
884         demands_list = json.loads(open(demands_list_file).read())
885
886         nst_response_file = './conductor/tests/unit/data/plugins/inventory_provider/nst_response.json'
887         nst_response = json.loads(open(nst_response_file).read())
888         final_nst_candidates_file = './conductor/tests/unit/data/plugins/inventory_provider/final_nst_candidate.json'
889         final_nst_candidates = json.loads(open(final_nst_candidates_file).read())
890         result = dict()
891         result['embb_nst'] = final_nst_candidates
892
893         self.mock_get_nst_candidates = mock.patch.object(AAI, 'get_nst_response',
894                                                          return_value=nst_response)
895         self.mock_get_final_nst_candidates = mock.patch.object(SDC, 'update_candidates',
896                                                          return_value=final_nst_candidates)
897         self.mock_get_nst_candidates.start()
898         self.mock_get_final_nst_candidates.start()
899         self.maxDiff = None
900         self.assertEqual(result, self.aai_ep.resolve_demands(demands_list, plan_info=plan_info,
901                                                              triage_translator_data=triage_translator_data))
902
903     def test_get_aai_data(self):
904         nst_response_file = './conductor/tests/unit/data/plugins/inventory_provider/nst_response.json'
905         nst_response = json.loads(open(nst_response_file).read())
906         response = mock.MagicMock()
907         response.status_code = 200
908         response.ok = True
909         response.json.return_value = nst_response
910         self.mock_get_request = mock.patch.object(AAI, '_request', return_value=response)
911         self.mock_get_request.start()
912         filtering_attr={"model-role":"NST"}
913         self.assertEquals(nst_response, self.aai_ep.get_nst_response(filtering_attr))
914
915     def test_get_profile_instances(self):
916         nsi_response_file = './conductor/tests/unit/data/plugins/inventory_provider/nsi_response.json'
917         nsi_response = json.loads(open(nsi_response_file).read())
918         service_profile_file = './conductor/tests/unit/data/plugins/inventory_provider/nsi_service_profile.json'
919         service_profile = json.loads(open(service_profile_file).read())
920
921         response = mock.MagicMock()
922         response.status_code = 200
923         response.ok = True
924         response.json.return_value = service_profile
925         self.mock_get_profiles = mock.patch.object(AAI, '_request', return_value=response)
926         self.mock_get_profiles.start()
927
928         self.assertEquals([service_profile], self.aai_ep.get_profile_instances(nsi_response["service-instance"][0]))