2 # -------------------------------------------------------------------------
3 # Copyright (c) 2015-2017 AT&T Intellectual Property
4 # Copyright (C) 2020 Wipro Limited.
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
10 # http://www.apache.org/licenses/LICENSE-2.0
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.
18 # -------------------------------------------------------------------------
24 from unittest.mock import patch
26 from oslo_config import cfg
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
36 class TestAAI(unittest.TestCase):
39 cfg.CONF.set_override('password', '4HyU6sI+Tw0YMXgSHr5sJ5C0UTkeBaxXoxQqWuSVFugls7sQnaAXp4zMfJ8FKFrH', 'aai')
41 CONF.register_opts(aai.AAI_OPTS, group='aai')
48 def test_get_version_from_string(self):
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"))
53 def test_aai_versioned_path(self):
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"))
60 def test_resolve_clli_location(self):
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())
65 response = mock.MagicMock()
66 response.status_code = 200
68 response.json.return_value = req_json
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"))
75 def test_get_inventory_group_pair(self):
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())
80 response = mock.MagicMock()
81 response.status_code = 200
83 response.json.return_value = req_json
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"))
90 def test_resolve_host_location(self):
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())
95 req_response = mock.MagicMock()
96 req_response.status_code = 200
97 req_response.ok = True
98 req_response.json.return_value = req_json
100 complex_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_get_complex.json'
101 complex_json = json.loads(open(complex_json_file).read())
103 self.mock_get_request = mock.patch.object(AAI, '_request', return_value=req_response)
104 self.mock_get_request.start()
106 self.mock_get_complex = mock.patch.object(AAI, '_get_complex', return_value=complex_json)
107 self.mock_get_complex.start()
109 self.assertEqual({'country': u'USA', 'latitude': u'28.543251', 'longitude': u'-81.377112'} ,
110 self.aai_ep.resolve_host_location("host_name"))
112 def test_resolve_demands_inventory_type_cloud(self):
114 self.aai_ep.conf.HPA_enabled = True
115 TraigeTranslator.getPlanIdNAme = mock.MagicMock(return_value=None)
116 TraigeTranslator.addDemandsTriageTranslator = mock.MagicMock(return_value=None)
122 triage_translator_data = None
124 demands_list_file = './conductor/tests/unit/data/plugins/inventory_provider/demand_list.json'
125 demands_list = json.loads(open(demands_list_file).read())
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())
130 regions_response_file = './conductor/tests/unit/data/plugins/inventory_provider/regions.json'
131 regions_response = json.loads(open(regions_response_file).read())
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())
136 complex_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_get_complex.json'
137 complex_json = json.loads(open(complex_json_file).read())
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
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()
147 self.mock_get_regions = mock.patch.object(AAI, '_get_regions', return_value=regions_response)
148 self.mock_get_regions.start()
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()
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()
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()
168 self.mock_get_complex = mock.patch.object(AAI, '_get_complex', return_value=complex_json)
169 self.mock_get_complex.start()
171 flavor_info = regions_response["region-name"]["flavors"]
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',
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))
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)
212 triage_translator_data = None
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())
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())
220 v_server_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_vserver.json'
221 v_server = json.loads(open(v_server_file).read())
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())
226 complex_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_complex.json'
227 complex_response = json.loads(open(complex_file).read())
229 region_response_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_region.json'
230 region_response = json.loads(open(region_response_file).read())
232 results_file = './conductor/tests/unit/data/plugins/inventory_provider/service_candidates.json'
233 results_json = json.loads(open(results_file).read())
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
240 def mock_first_level_service_call_response(path, name, service_type):
241 if "equipment-role" in path:
244 return generic_vnf_list
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()
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()
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()
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()
267 self.mock_get_complex = mock.patch.object(AAI, '_get_complex', return_value=complex_response)
268 self.mock_get_complex.start()
271 self.assertEqual(results_json, self.aai_ep.resolve_demands(demands_list, plan_info=plan_info,
272 triage_translator_data=triage_translator_data))
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)
283 triage_translator_data = None
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())
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())
291 vfmodules_list_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_list.json'
292 vfmodules_list = json.loads(open(vfmodules_list_file).read())
294 v_server_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_vserver.json'
295 v_server = json.loads(open(v_server_file).read())
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())
300 complex_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_complex.json'
301 complex_response = json.loads(open(complex_file).read())
303 region_response_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_region.json'
304 region_response = json.loads(open(region_response_file).read())
306 results_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_candidates.json'
307 results_json = json.loads(open(results_file).read())
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
314 def mock_first_level_service_call_response(path, name, service_type):
315 if "equipment-role" in path:
318 return generic_vnf_list
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()
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()
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()
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()
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()
344 self.mock_get_complex = mock.patch.object(AAI, '_get_complex', return_value=complex_response)
345 self.mock_get_complex.start()
348 self.assertEqual(results_json, self.aai_ep.resolve_demands(demands_list, plan_info=plan_info,
349 triage_translator_data=triage_translator_data))
351 def test_get_complex(self):
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())
356 response = mock.MagicMock()
357 response.status_code = 200
359 response.json.return_value = complex_json
361 self.mock_get_request = mock.patch.object(AAI, '_request', return_value=response)
362 self.mock_get_request.start()
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"))
367 def test_check_network_roles(self):
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())
372 response = mock.MagicMock()
373 response.status_code = 200
375 response.json.return_value = network_role_json
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"))
382 def test_check_candidate_role(self):
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())
387 response = mock.MagicMock()
388 response.status_code = 200
390 response.json.return_value = candidate_role_json
392 self.mock_get_request = mock.patch.object(AAI, '_request', return_value=response)
393 self.mock_get_request.start()
395 self.assertEqual("test-role",
396 self.aai_ep.check_candidate_role("candidate_host_id"))
398 def test_match_inventory_attributes(self):
399 template_attributes = dict()
400 template_attributes['attr-1'] = ['attr-1-value1', 'attr-1-value2']
402 inventory_attributes = dict()
403 inventory_attributes['attr-1'] = 'attr-1-value1'
405 self.assertEqual(True,
406 self.aai_ep.match_inventory_attributes(template_attributes, inventory_attributes, "candidate-id"))
408 template_attributes['attr-1'] = {
409 'not': ['attr-1-value2']
411 self.assertEqual(True,
412 self.aai_ep.match_inventory_attributes(template_attributes, inventory_attributes,
415 template_attributes['attr-1'] = {
416 'not': ['attr-1-value1']
418 self.assertEqual(False,
419 self.aai_ep.match_inventory_attributes(template_attributes, inventory_attributes,
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())
426 complex_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_cached_complex.json'
427 complex_json = json.loads(open(complex_json_file).read())
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())
432 response = mock.MagicMock()
433 response.status_code = 200
435 response.json.return_value = regions_response
437 self.mock_get_regions = mock.patch.object(AAI, '_request', return_value=response)
438 self.mock_get_regions.start()
440 self.mock_get_complex = mock.patch.object(AAI, '_get_complex', return_value=complex_json)
441 self.mock_get_complex.start()
443 self.mock_get_flavors = mock.patch.object(AAI, '_get_flavors',
444 return_value=flavors_json)
445 self.mock_get_flavors.start()
447 self.assertEqual(None,
448 self.aai_ep._refresh_cache())
450 def test_get_aai_rel_link(self):
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"
456 self.assertEqual("relationship-link",
457 self.aai_ep._get_aai_rel_link(relatonship_response, related_to))
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())
463 response = mock.MagicMock()
464 response.json.return_value = None
466 self.mock_get_request = mock.patch.object(AAI, '_request',
467 return_value=response)
468 self.mock_get_request.start()
470 flavors_info = self.aai_ep._get_flavors("mock-cloud-owner",
471 "mock-cloud-region-id")
472 self.assertEqual(None, flavors_info)
474 response.status_code = 200
476 response.json.return_value = flavors_json
478 flavors_info = self.aai_ep._get_flavors("mock-cloud-owner",
479 "mock-cloud-region-id")
480 self.assertEqual(2, len(flavors_info['flavor']))
482 def test_resolve_complex_info_link_for_v_server(self):
483 TraigeTranslator.collectDroppedCandiate = mock.MagicMock(return_value=None)
484 triage_translator_data = None
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())
494 candidate_id = 'some_id'
495 location_id = 'some_location_id'
496 inventory_type = 'service'
498 response = mock.MagicMock()
499 response.status_code = 200
501 response.json.return_value = region_response
503 self.mock_get_request = mock.patch.object(AAI, '_request', return_value=response)
504 self.mock_get_request.start()
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)
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)
517 def test_build_complex_info_for_candidate(self):
518 TraigeTranslator.collectDroppedCandiate = mock.MagicMock(return_value=None)
519 triage_translator_data = None
522 complex_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_complex.json'
523 complex_response = json.loads(open(complex_file).read())
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'})
535 self.mock_get_complex = mock.patch.object(AAI, '_get_complex', return_value=complex_response)
536 self.mock_get_complex.start()
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)
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)
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)
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)
559 def test_resolve_vnf_parameters(self):
560 TraigeTranslator.collectDroppedCandiate = mock.MagicMock(return_value=None)
561 triage_translator_data = None
565 candidate_id = 'some_id'
566 location_id = 'some_location_id'
567 candidate['inventory_type'] = 'service'
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())
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()
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'])
590 self.assertIsNone(bad_cloud_info)
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))
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,
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,
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))
611 def test_add_passthrough_parameters(self):
612 triage_translator_data = None
615 candidate['candidate_id'] = 'some_id'
616 candidate['location_id'] = 'some_location_id'
617 candidate['inventory_type'] = 'service'
620 parameters['param_one'] = "value"
621 parameters['param_two'] = "value"
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"
628 self.aai_ep.add_passthrough_attributes(candidate, parameters, 'demand')
629 self.assertDictEqual(candidate, candidate_info)
631 def test_match_candidate_by_list(self):
632 TraigeTranslator.collectDroppedCandiate = mock.MagicMock(return_value=None)
633 triage_translator_data = None
636 candidate['candidate_id'] = 'some_id'
637 candidate['location_id'] = 'some_location_id'
638 candidate['inventory_type'] = 'service'
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)
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)
660 def test_match_hpa(self):
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
673 "flavor_map": {"flavor-id": "f5aa2b2e-3206-41b6-80d5-cf041b098c43",
674 "flavor-name": "flavor-cpu-pinning-ovsdpdk-instruction-set",
676 self.assertEqual(flavor_map,
677 match_hpa(candidate_json['candidate_list'][1],
680 flavor_map = {"flavor_map": {"flavor-id": "f5aa2b2e-3206-41b6-80d5-cf041b098c43",
681 "flavor-name": "flavor-cpu-ovsdpdk-instruction-set",
684 self.assertEqual(flavor_map,
685 match_hpa(candidate_json['candidate_list'][1],
687 flavor_map = {"flavor_map": {"flavor-id": "f5aa2b2e-3206-41b6-80d5-cf6t2b098c43",
688 "flavor-name": "flavor-ovsdpdk-cpu-pinning-sriov-NIC-Network-set",
691 "type": "sriovNICNetwork_directives",
694 "attribute_name": "A",
695 "attribute_value": "a"
699 self.assertEqual(flavor_map,
700 match_hpa(candidate_json['candidate_list'][1],
702 self.assertEqual(None, match_hpa(candidate_json['candidate_list'][1],
704 flavor_map = {"flavor_map": {"flavor-id": "f5aa2b2e-3206-41b6-19d5-cf6t2b098c43",
705 "flavor-name": "flavor-ovsdpdk-cpu-pinning-double-sriov-NIC-Network-set",
709 "type": "sriovNICNetwork_directives",
712 "attribute_name": "A",
713 "attribute_value": "a"
718 "type": "sriovNICNetwork_directives",
721 "attribute_name": "B",
722 "attribute_value": "b"
727 self.assertEqual(flavor_map, match_hpa(candidate_json['candidate_list'][1],
729 self.assertEqual(None, match_hpa(candidate_json['candidate_list'][1],
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())
742 self.mock_get_profiles = mock.patch.object(AAI, 'get_profile_instances', return_value=[slice_profile])
743 self.mock_get_profiles.start()
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
751 self.mock_get_difference = mock.patch.object(DCAE, 'capacity_filter', return_value=nssi_candidates_updated)
752 self.mock_get_difference.start()
754 self.assertEqual(nssi_candidates_updated, self.aai_ep.filter_nxi_candidates(nssi_response, second_level_filter,
755 default_attributes, "true", service_role))
757 nssi_response['service-instance'][0]['service-role'] = 'service'
759 self.assertEqual([], self.aai_ep.filter_nxi_candidates(nssi_response, second_level_filter, default_attributes,
760 "true", service_role))
762 self.assertEqual([], self.aai_ep.filter_nxi_candidates(None, second_level_filter, default_attributes,
763 "true", service_role))
765 self.assertEqual([], self.aai_ep.filter_nxi_candidates(None, None, default_attributes, "true", service_role))
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",
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)
782 triage_translator_data = None
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())
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())
796 result['embb_cn'] = nssi_candidates_updated
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()
802 self.mock_get_difference = mock.patch.object(DCAE, 'capacity_filter', return_value=nssi_candidates_updated)
803 self.mock_get_difference.start()
805 self.mock_get_profiles = mock.patch.object(AAI, 'get_profile_instances', return_value=[slice_profile])
806 self.mock_get_profiles.start()
808 self.assertEqual(result, self.aai_ep.resolve_demands(demands_list, plan_info=plan_info,
809 triage_translator_data=triage_translator_data))
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())
821 self.mock_get_profiles = mock.patch.object(AAI, 'get_profile_instances', return_value=[service_profile])
822 self.mock_get_profiles.start()
825 second_level_filter = dict()
826 second_level_filter['service-role'] = service_role
827 default_attributes = dict()
828 default_attributes['creation_cost'] = 1
830 self.mock_get_profiles = mock.patch.object(DCAE, 'capacity_filter', return_value=nsi_candidates_updated)
831 self.mock_get_profiles.start()
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'
837 self.assertEqual([], self.aai_ep.filter_nxi_candidates(nsi_response, second_level_filter, default_attributes,
838 "true", service_role))
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)
849 triage_translator_data = None
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())
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())
861 result['embb_nst'] = nsi_candidates_updated
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())
866 self.mock_get_profiles = mock.patch.object(AAI, 'get_profile_instances', return_value=[service_profile])
867 self.mock_get_profiles.start()
869 self.mock_get_difference = mock.patch.object(DCAE, 'capacity_filter', return_value=nsi_candidates_updated)
870 self.mock_get_difference.start()
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()
876 self.assertEqual(result, self.aai_ep.resolve_demands(demands_list, plan_info=plan_info,
877 triage_translator_data=triage_translator_data))
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())
886 second_level_filter=None
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'))
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)
903 triage_translator_data = None
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())
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())
913 result['embb_nst'] = final_nst_candidates
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()
922 self.assertEqual(result, self.aai_ep.resolve_demands(demands_list, plan_info=plan_info,
923 triage_translator_data=triage_translator_data))
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
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))
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())
943 response = mock.MagicMock()
944 response.status_code = 200
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()
950 self.assertEquals([service_profile], self.aai_ep.get_profile_instances(nsi_response["service-instance"][0]))