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