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.hpa_utils import match_hpa
32 from conductor.data.plugins.triage_translator.triage_translator import TraigeTranslator
35 class TestAAI(unittest.TestCase):
38 cfg.CONF.set_override('password', '4HyU6sI+Tw0YMXgSHr5sJ5C0UTkeBaxXoxQqWuSVFugls7sQnaAXp4zMfJ8FKFrH', 'aai')
40 CONF.register_opts(aai.AAI_OPTS, group='aai')
47 def test_get_version_from_string(self):
49 self.assertEqual("2.5", self.aai_ep._get_version_from_string("AAI2.5"))
50 self.assertEqual("3.0", self.aai_ep._get_version_from_string("AAI3.0"))
52 def test_aai_versioned_path(self):
54 self.assertEqual('/{}/cloud-infrastructure/cloud-regions/?depth=0'.format(self.conf.aai.server_url_version),
55 self.aai_ep._aai_versioned_path("/cloud-infrastructure/cloud-regions/?depth=0"))
56 self.assertEqual('/{}/query?format=id'.format(self.conf.aai.server_url_version),
57 self.aai_ep._aai_versioned_path("/query?format=id"))
59 def test_resolve_clli_location(self):
61 req_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_request_clli_location.json'
62 req_json = json.loads(open(req_json_file).read())
64 response = mock.MagicMock()
65 response.status_code = 200
67 response.json.return_value = req_json
69 self.mock_get_request = mock.patch.object(AAI, '_request', return_value=response)
70 self.mock_get_request.start()
71 self.assertEqual({'country': u'USA', 'latitude': u'40.39596', 'longitude': u'-74.135342'} ,
72 self.aai_ep.resolve_clli_location("clli_code"))
74 def test_get_inventory_group_pair(self):
76 req_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_request_inventory_group_pair.json'
77 req_json = json.loads(open(req_json_file).read())
79 response = mock.MagicMock()
80 response.status_code = 200
82 response.json.return_value = req_json
84 self.mock_get_request = mock.patch.object(AAI, '_request', return_value=response)
85 self.mock_get_request.start()
86 self.assertEqual([[u'instance-1', u'instance-2']] ,
87 self.aai_ep.get_inventory_group_pairs("service_description"))
89 def test_resolve_host_location(self):
91 req_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_request_host_name.json'
92 req_json = json.loads(open(req_json_file).read())
94 req_response = mock.MagicMock()
95 req_response.status_code = 200
96 req_response.ok = True
97 req_response.json.return_value = req_json
99 complex_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_get_complex.json'
100 complex_json = json.loads(open(complex_json_file).read())
102 self.mock_get_request = mock.patch.object(AAI, '_request', return_value=req_response)
103 self.mock_get_request.start()
105 self.mock_get_complex = mock.patch.object(AAI, '_get_complex', return_value=complex_json)
106 self.mock_get_complex.start()
108 self.assertEqual({'country': u'USA', 'latitude': u'28.543251', 'longitude': u'-81.377112'} ,
109 self.aai_ep.resolve_host_location("host_name"))
111 def test_resolve_demands_inventory_type_cloud(self):
113 self.aai_ep.conf.HPA_enabled = True
114 TraigeTranslator.getPlanIdNAme = mock.MagicMock(return_value=None)
115 TraigeTranslator.addDemandsTriageTranslator = mock.MagicMock(return_value=None)
121 triage_translator_data = None
123 demands_list_file = './conductor/tests/unit/data/plugins/inventory_provider/demand_list.json'
124 demands_list = json.loads(open(demands_list_file).read())
126 generic_vnf_list_file = './conductor/tests/unit/data/plugins/inventory_provider/generic_vnf_list.json'
127 generic_vnf_list = json.loads(open(generic_vnf_list_file).read())
129 regions_response_file = './conductor/tests/unit/data/plugins/inventory_provider/regions.json'
130 regions_response = json.loads(open(regions_response_file).read())
132 demand_service_response_file = './conductor/tests/unit/data/plugins/inventory_provider/resolve_demand_service_response.json'
133 demand_service_response = json.loads(open(demand_service_response_file).read())
135 complex_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_get_complex.json'
136 complex_json = json.loads(open(complex_json_file).read())
138 req_response = mock.MagicMock()
139 req_response.status_code = 200
140 req_response.ok = True
141 req_response.json.return_value = demand_service_response
143 self.mock_first_level_service_call = mock.patch.object(AAI, 'first_level_service_call', return_value=generic_vnf_list)
144 self.mock_first_level_service_call.start()
146 self.mock_get_regions = mock.patch.object(AAI, '_get_regions', return_value=regions_response)
147 self.mock_get_regions.start()
149 regions_list = list()
150 regions_list.append(regions_response.get('region-name'))
151 self.mock_resolve_cloud_regions_by_cloud_region_id = mock.patch.object(AAI,
152 'resolve_cloud_regions_by_cloud_region_id',
153 return_value=regions_list)
154 self.mock_resolve_cloud_regions_by_cloud_region_id.start()
157 self.mock_resolve_v_server_for_candidate = mock.patch.object(AAI, 'resolve_v_server_for_candidate',
158 return_value=demand_service_response)
159 self.mock_resolve_v_server_for_candidate.start()
161 complex_link = {"link": "/aai/v10/complex-id", "d_value": 'test-id'}
162 self.mock_resolve_complex_info_link_for_v_server = mock.patch.object(AAI,
163 'resolve_complex_info_link_for_v_server',
164 return_value=complex_link)
165 self.mock_resolve_complex_info_link_for_v_server.start()
167 self.mock_get_complex = mock.patch.object(AAI, '_get_complex', return_value=complex_json)
168 self.mock_get_complex.start()
170 flavor_info = regions_response["region-name"]["flavors"]
172 self.assertCountEqual({u'demand_name': [
173 {'candidate_id': u'service-instance-id', 'city': None,
174 'cloud_owner': u'cloud-owner',
175 'uniqueness': 'true',
176 'vim-id': u'cloud-owner_cloud-region-id',
177 'vlan_key': None, 'cloud_region_version': '', 'complex_name': None, 'cost': 1.0,
178 'country': u'USA', 'existing_placement': 'false',
179 'host_id': u'vnf-name', 'inventory_provider': 'aai',
180 'inventory_type': 'service', 'latitude': u'28.543251',
181 'location_id': u'cloud-region-id', 'location_type': 'att_aic',
182 'longitude': u'-81.377112', 'physical_location_id': u'test-id',
184 'region': u'SE', 'service_resource_id': '',
185 'sriov_automation': 'false', 'state': None},
186 {'candidate_id': u'region-name', 'city': u'Middletown',
187 'cloud_owner': u'cloud-owner',
188 'uniqueness': 'true',
189 'vim-id': u'cloud-owner_region-name',
190 'cloud_region_version': u'1.0', 'complex_name': u'complex-name',
191 'cost': 2.0, 'country': u'USA', 'existing_placement': 'false',
192 'inventory_provider': 'aai', 'inventory_type': 'cloud',
193 'latitude': u'50.34', 'location_id': u'region-name',
194 'location_type': 'att_aic', 'longitude': u'30.12',
195 'physical_location_id': u'complex-id',
196 'region': u'USA', 'service_resource_id': u'service-resource-id-123',
197 'sriov_automation': 'false', 'state': u'NJ',
198 'flavors': flavor_info}]},
199 self.aai_ep.resolve_demands(demands_list, plan_info=plan_info,
200 triage_translator_data=triage_translator_data))
202 def test_resolve_demands_inventory_type_service(self):
203 self.aai_ep.conf.HPA_enabled = True
204 TraigeTranslator.getPlanIdNAme = mock.MagicMock(return_value=None)
205 TraigeTranslator.addDemandsTriageTranslator = mock.MagicMock(return_value=None)
211 triage_translator_data = None
213 demands_list_file = './conductor/tests/unit/data/plugins/inventory_provider/service_demand_list.json'
214 demands_list = json.loads(open(demands_list_file).read())
216 generic_vnf_list_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_service_generic_vnf_list.json'
217 generic_vnf_list = json.loads(open(generic_vnf_list_file).read())
219 v_server_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_vserver.json'
220 v_server = json.loads(open(v_server_file).read())
222 demand_service_response_file = './conductor/tests/unit/data/plugins/inventory_provider/resolve_demand_service_response.json'
223 demand_service_response = json.loads(open(demand_service_response_file).read())
225 complex_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_complex.json'
226 complex_response = json.loads(open(complex_file).read())
228 region_response_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_region.json'
229 region_response = json.loads(open(region_response_file).read())
231 results_file = './conductor/tests/unit/data/plugins/inventory_provider/service_candidates.json'
232 results_json = json.loads(open(results_file).read())
234 req_response = mock.MagicMock()
235 req_response.status_code = 200
236 req_response.ok = True
237 req_response.json.return_value = demand_service_response
239 def mock_first_level_service_call_response(path, name, service_type):
240 if "equipment-role" in path:
243 return generic_vnf_list
245 self.mock_first_level_service_call = mock.patch.object(AAI, 'first_level_service_call',
246 side_effect=mock_first_level_service_call_response)
247 self.mock_first_level_service_call.start()
250 regions.append(region_response)
251 self.mock_resolve_cloud_regions_by_cloud_region_id = mock.patch.object(AAI,
252 'resolve_cloud_regions_by_cloud_region_id',
253 return_value=regions)
254 self.mock_resolve_cloud_regions_by_cloud_region_id.start()
256 self.mock_resolve_v_server_for_candidate = mock.patch.object(AAI, 'resolve_v_server_for_candidate',
257 return_value=v_server)
258 self.mock_resolve_v_server_for_candidate.start()
260 complex_link = {"link": "/aai/v14/cloud-infrastructure/complexes/complex/clli1", "d_value": 'clli1'}
261 self.mock_resolve_complex_info_link_for_v_server = mock.patch.object(AAI,
262 'resolve_complex_info_link_for_v_server',
263 return_value=complex_link)
264 self.mock_resolve_complex_info_link_for_v_server.start()
266 self.mock_get_complex = mock.patch.object(AAI, '_get_complex', return_value=complex_response)
267 self.mock_get_complex.start()
270 self.assertEqual(results_json, self.aai_ep.resolve_demands(demands_list, plan_info=plan_info,
271 triage_translator_data=triage_translator_data))
273 def test_resolve_demands_inventory_type_vfmodule(self):
274 self.aai_ep.conf.HPA_enabled = True
275 TraigeTranslator.getPlanIdNAme = mock.MagicMock(return_value=None)
276 TraigeTranslator.addDemandsTriageTranslator = mock.MagicMock(return_value=None)
282 triage_translator_data = None
284 demands_list_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_demand_list.json'
285 demands_list = json.loads(open(demands_list_file).read())
287 generic_vnf_list_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_service_generic_vnf_list.json'
288 generic_vnf_list = json.loads(open(generic_vnf_list_file).read())
290 vfmodules_list_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_list.json'
291 vfmodules_list = json.loads(open(vfmodules_list_file).read())
293 v_server_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_vserver.json'
294 v_server = json.loads(open(v_server_file).read())
296 demand_service_response_file = './conductor/tests/unit/data/plugins/inventory_provider/resolve_demand_service_response.json'
297 demand_service_response = json.loads(open(demand_service_response_file).read())
299 complex_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_complex.json'
300 complex_response = json.loads(open(complex_file).read())
302 region_response_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_region.json'
303 region_response = json.loads(open(region_response_file).read())
305 results_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_candidates.json'
306 results_json = json.loads(open(results_file).read())
308 req_response = mock.MagicMock()
309 req_response.status_code = 200
310 req_response.ok = True
311 req_response.json.return_value = demand_service_response
313 def mock_first_level_service_call_response(path, name, service_type):
314 if "equipment-role" in path:
317 return generic_vnf_list
319 self.mock_first_level_service_call = mock.patch.object(AAI, 'first_level_service_call',
320 side_effect=mock_first_level_service_call_response)
321 self.mock_first_level_service_call.start()
323 self.mock_resolve_vf_modules_for_generic_vnf = mock.patch.object(AAI, 'resolve_vf_modules_for_generic_vnf',
324 return_value=vfmodules_list)
325 self.mock_resolve_vf_modules_for_generic_vnf.start()
328 regions.append(region_response)
329 self.mock_resolve_cloud_regions_by_cloud_region_id = mock.patch.object(AAI,
330 'resolve_cloud_regions_by_cloud_region_id',
331 return_value=regions)
332 self.mock_resolve_cloud_regions_by_cloud_region_id.start()
334 self.mock_resolve_v_server_for_candidate = mock.patch.object(AAI, 'resolve_v_server_for_candidate',
335 return_value=v_server)
336 self.mock_resolve_v_server_for_candidate.start()
338 complex_link = {"link": "/aai/v14/cloud-infrastructure/complexes/complex/clli1", "d_value": 'clli1'}
339 self.mock_resolve_complex_info_link_for_v_server = mock.patch.object(AAI, 'resolve_complex_info_link_for_v_server',
340 return_value=complex_link)
341 self.mock_resolve_complex_info_link_for_v_server.start()
343 self.mock_get_complex = mock.patch.object(AAI, '_get_complex', return_value=complex_response)
344 self.mock_get_complex.start()
347 self.assertEqual(results_json, self.aai_ep.resolve_demands(demands_list, plan_info=plan_info,
348 triage_translator_data=triage_translator_data))
350 def test_get_complex(self):
352 complex_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_request_get_complex.json'
353 complex_json = json.loads(open(complex_json_file).read())
355 response = mock.MagicMock()
356 response.status_code = 200
358 response.json.return_value = complex_json
360 self.mock_get_request = mock.patch.object(AAI, '_request', return_value=response)
361 self.mock_get_request.start()
363 self.assertEqual({u'city': u'Middletown', u'latitude': u'28.543251', u'longitude': u'-81.377112', u'country': u'USA', u'region': u'SE'},
364 self.aai_ep._get_complex("/v10/complex/complex_id", "complex_id"))
366 def test_check_network_roles(self):
368 network_role_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_request_network_role.json'
369 network_role_json = json.loads(open(network_role_json_file).read())
371 response = mock.MagicMock()
372 response.status_code = 200
374 response.json.return_value = network_role_json
376 self.mock_get_request = mock.patch.object(AAI, '_request', return_value=response)
377 self.mock_get_request.start()
378 self.assertEqual(set(['test-cloud-value']) ,
379 self.aai_ep.check_network_roles("network_role_id"))
381 def test_check_candidate_role(self):
383 candidate_role_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_request_candidate_role.json'
384 candidate_role_json = json.loads(open(candidate_role_json_file).read())
386 response = mock.MagicMock()
387 response.status_code = 200
389 response.json.return_value = candidate_role_json
391 self.mock_get_request = mock.patch.object(AAI, '_request', return_value=response)
392 self.mock_get_request.start()
394 self.assertEqual("test-role",
395 self.aai_ep.check_candidate_role("candidate_host_id"))
397 def test_match_inventory_attributes(self):
398 template_attributes = dict()
399 template_attributes['attr-1'] = ['attr-1-value1', 'attr-1-value2']
401 inventory_attributes = dict()
402 inventory_attributes['attr-1'] = 'attr-1-value1'
404 self.assertEqual(True,
405 self.aai_ep.match_inventory_attributes(template_attributes, inventory_attributes, "candidate-id"))
407 template_attributes['attr-1'] = {
408 'not': ['attr-1-value2']
410 self.assertEqual(True,
411 self.aai_ep.match_inventory_attributes(template_attributes, inventory_attributes,
414 template_attributes['attr-1'] = {
415 'not': ['attr-1-value1']
417 self.assertEqual(False,
418 self.aai_ep.match_inventory_attributes(template_attributes, inventory_attributes,
421 def test_refresh_cache(self):
422 regions_response_file = './conductor/tests/unit/data/plugins/inventory_provider/cache_regions.json'
423 regions_response = json.loads(open(regions_response_file).read())
425 complex_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_cached_complex.json'
426 complex_json = json.loads(open(complex_json_file).read())
428 flavors_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_request_get_flavors.json'
429 flavors_json = json.loads(open(flavors_json_file).read())
431 response = mock.MagicMock()
432 response.status_code = 200
434 response.json.return_value = regions_response
436 self.mock_get_regions = mock.patch.object(AAI, '_request', return_value=response)
437 self.mock_get_regions.start()
439 self.mock_get_complex = mock.patch.object(AAI, '_get_complex', return_value=complex_json)
440 self.mock_get_complex.start()
442 self.mock_get_flavors = mock.patch.object(AAI, '_get_flavors',
443 return_value=flavors_json)
444 self.mock_get_flavors.start()
446 self.assertEqual(None,
447 self.aai_ep._refresh_cache())
449 def test_get_aai_rel_link(self):
451 relatonship_response_file = './conductor/tests/unit/data/plugins/inventory_provider/relationship_list.json'
452 relatonship_response = json.loads(open(relatonship_response_file).read())
453 related_to = "service-instance"
455 self.assertEqual("relationship-link",
456 self.aai_ep._get_aai_rel_link(relatonship_response, related_to))
458 def test_get_flavor(self):
459 flavors_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_request_get_flavors.json'
460 flavors_json = json.loads(open(flavors_json_file).read())
462 response = mock.MagicMock()
463 response.json.return_value = None
465 self.mock_get_request = mock.patch.object(AAI, '_request',
466 return_value=response)
467 self.mock_get_request.start()
469 flavors_info = self.aai_ep._get_flavors("mock-cloud-owner",
470 "mock-cloud-region-id")
471 self.assertEqual(None, flavors_info)
473 response.status_code = 200
475 response.json.return_value = flavors_json
477 flavors_info = self.aai_ep._get_flavors("mock-cloud-owner",
478 "mock-cloud-region-id")
479 self.assertEqual(2, len(flavors_info['flavor']))
481 def test_resolve_complex_info_link_for_v_server(self):
482 TraigeTranslator.collectDroppedCandiate = mock.MagicMock(return_value=None)
483 triage_translator_data = None
486 cloud_owner = 'CloudOwner'
487 cloud_region_id = 'RegionOne'
488 v_server_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_vserver.json'
489 v_server = json.loads(open(v_server_file).read())
490 region_response_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_region.json'
491 region_response = json.loads(open(region_response_file).read())
493 candidate_id = 'some_id'
494 location_id = 'some_location_id'
495 inventory_type = 'service'
497 response = mock.MagicMock()
498 response.status_code = 200
500 response.json.return_value = region_response
502 self.mock_get_request = mock.patch.object(AAI, '_request', return_value=response)
503 self.mock_get_request.start()
505 link_rl_data = self.aai_ep.resolve_complex_info_link_for_v_server(candidate_id, v_server, None,
506 cloud_region_id, service_type,
507 demand_name, triage_translator_data)
508 self.assertEqual(None, link_rl_data)
510 complex_link = {"link": "/aai/v14/cloud-infrastructure/complexes/complex/clli1", "d_value": 'clli1'}
511 link_rl_data = self.aai_ep.resolve_complex_info_link_for_v_server(candidate_id, v_server, cloud_owner,
512 cloud_region_id, service_type,
513 demand_name, triage_translator_data)
514 self.assertEqual(complex_link, link_rl_data)
516 def test_build_complex_info_for_candidate(self):
517 TraigeTranslator.collectDroppedCandiate = mock.MagicMock(return_value=None)
518 triage_translator_data = None
521 complex_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_complex.json'
522 complex_response = json.loads(open(complex_file).read())
525 candidate['candidate_id'] = 'some_id'
526 candidate['location_id'] = 'some_location_id'
527 candidate['inventory_type'] = 'service'
528 initial_candidate = copy.deepcopy(candidate)
529 complex_list_empty = dict()
530 complex_list = list()
531 complex_list.append({"link": "/aai/v14/cloud-infrastructure/complexes/complex/clli1", "d_value": 'clli1'})
532 complex_list.append({"link": "/aai/v14/cloud-infrastructure/complexes/complex/clli2", "d_value": 'clli2'})
534 self.mock_get_complex = mock.patch.object(AAI, '_get_complex', return_value=complex_response)
535 self.mock_get_complex.start()
537 self.aai_ep.build_complex_info_for_candidate(candidate['candidate_id'], candidate['location_id'], None, complex_list_empty, candidate['inventory_type'], demand_name,
538 triage_translator_data)
539 self.assertEqual(initial_candidate, candidate)
540 self.assertEqual(1, TraigeTranslator.collectDroppedCandiate.call_count)
542 self.aai_ep.build_complex_info_for_candidate(candidate['candidate_id'], candidate['location_id'], None, complex_list, candidate['inventory_type'], demand_name,
543 triage_translator_data)
544 self.assertEqual(initial_candidate, candidate)
545 self.assertEqual(2, TraigeTranslator.collectDroppedCandiate.call_count)
548 self.aai_ep.build_complex_info_for_candidate(candidate['candidate_id'], candidate['location_id'], None, complex_list, candidate['inventory_type'], demand_name,
549 triage_translator_data)
551 self.assertEqual(self.aai_ep.build_complex_info_for_candidate(candidate['candidate_id'], candidate['location_id'], None, complex_list, candidate['inventory_type'], demand_name,
552 triage_translator_data), {'city': u'example-city-val-27150', 'country': u'example-country-val-94173',
553 'region': u'example-region-val-13893', 'longitude': u'32.89948', 'state': u'example-state-val-59487',
554 'physical_location_id': 'clli1', 'latitude': u'example-latitude-val-89101',
555 'complex_name': u'clli1'})
556 self.assertEqual(2, TraigeTranslator.collectDroppedCandiate.call_count)
558 def test_resolve_vnf_parameters(self):
559 TraigeTranslator.collectDroppedCandiate = mock.MagicMock(return_value=None)
560 triage_translator_data = None
564 candidate_id = 'some_id'
565 location_id = 'some_location_id'
566 candidate['inventory_type'] = 'service'
568 generic_vnf_list_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_service_generic_vnf_list.json'
569 good_vnf = json.loads(open(generic_vnf_list_file).read())[0]
570 bad_generic_vnf_list_file = './conductor/tests/unit/data/plugins/inventory_provider/bad_generic_vnf_list.json'
571 bad_vnf = json.loads(open(bad_generic_vnf_list_file).read())[0]
572 region_response_file = './conductor/tests/unit/data/plugins/inventory_provider/vfmodule_region.json'
573 region_response = json.loads(open(region_response_file).read())
576 regions.append(region_response)
577 self.mock_get_regions = mock.patch.object(AAI, 'resolve_cloud_regions_by_cloud_region_id',
578 return_value=regions)
579 self.mock_get_regions.start()
581 good_cloud_info = self.aai_ep.resolve_cloud_for_vnf(candidate_id, location_id, good_vnf, service_type,
582 demand_name, triage_translator_data)
583 bad_cloud_info = self.aai_ep.resolve_cloud_for_vnf(candidate_id, location_id, bad_vnf, service_type,
584 demand_name, triage_translator_data)
585 self.assertEqual("CloudOwner", good_cloud_info['cloud_owner'])
586 self.assertEqual("RegionOne", good_cloud_info['location_id'])
587 self.assertEqual("1", good_cloud_info['cloud_region_version'])
589 self.assertIsNone(bad_cloud_info)
591 v_server_links = list()
592 v_server_links.append("/aai/v14/cloud-infrastructure/cloud-regions/cloud-region/CloudOwner/RegionOne/tenants/\
593 tenant/3c6c471ada7747fe8ff7f28e100b61e8/vservers/vserver/00bddefc-126e-4e4f-a18d-99b94d8d9a30")
594 v_server_links.append("/aai/v14/cloud-infrastructure/cloud-regions/cloud-region/CloudOwner2/RegionOne2/tenants/\
595 tenant/3c6c471ada7747fe8ff7f28e100b61e8/vservers/vserver/00bddefc-126e-4e4f-a18d-99b94d8d9a31")
596 self.assertEqual(v_server_links, self.aai_ep.resolve_v_server_links_for_vnf(bad_vnf))
598 customer_id = 'Demonstration'
599 self.assertEqual(customer_id,
600 self.aai_ep.resolve_global_customer_id_for_vnf(candidate_id, location_id, good_vnf, customer_id, service_type,
602 triage_translator_data).get('d_value'))
603 self.assertEqual("3e8d118c-10ca-4b4b-b3db-089b5e9e6a1c",
604 self.aai_ep.resolve_service_instance_id_for_vnf(candidate_id, location_id, good_vnf, customer_id, service_type,
606 triage_translator_data).get('d_value'))
607 self.assertIsNone(self.aai_ep.resolve_service_instance_id_for_vnf(candidate_id, location_id, bad_vnf, customer_id, service_type,
608 demand_name, triage_translator_data))
610 def test_add_passthrough_parameters(self):
611 triage_translator_data = None
614 candidate['candidate_id'] = 'some_id'
615 candidate['location_id'] = 'some_location_id'
616 candidate['inventory_type'] = 'service'
619 parameters['param_one'] = "value"
620 parameters['param_two'] = "value"
622 candidate_info = copy.deepcopy(candidate)
623 candidate_info['passthrough_attributes'] = dict()
624 candidate_info['passthrough_attributes']['param_one'] = "value"
625 candidate_info['passthrough_attributes']['param_two'] = "value"
627 self.aai_ep.add_passthrough_attributes(candidate, parameters, 'demand')
628 self.assertDictEqual(candidate, candidate_info)
630 def test_match_candidate_by_list(self):
631 TraigeTranslator.collectDroppedCandiate = mock.MagicMock(return_value=None)
632 triage_translator_data = None
635 candidate['candidate_id'] = 'some_id'
636 candidate['location_id'] = 'some_location_id'
637 candidate['inventory_type'] = 'service'
639 candidate_list_empty = list()
640 candidate_list = list()
641 candidate_info = copy.deepcopy(candidate)
642 candidate_info['candidate_id'] = list()
643 candidate_info['candidate_id'].append(candidate['candidate_id'])
644 candidate_list.append(candidate_info)
646 self.assertFalse(self.aai_ep.match_candidate_by_list(candidate, candidate_list_empty, True, 'demand',
647 triage_translator_data)),
648 self.assertEqual(0, TraigeTranslator.collectDroppedCandiate.call_count)
649 self.assertTrue(self.aai_ep.match_candidate_by_list(candidate, candidate_list, True, 'demand',
650 triage_translator_data))
651 self.assertEqual(1, TraigeTranslator.collectDroppedCandiate.call_count)
652 self.assertTrue(self.aai_ep.match_candidate_by_list(candidate, candidate_list, False, 'demand',
653 triage_translator_data))
654 self.assertEqual(1, TraigeTranslator.collectDroppedCandiate.call_count)
655 self.assertFalse(self.aai_ep.match_candidate_by_list(candidate, candidate_list_empty, False, 'demand',
656 triage_translator_data))
657 self.assertEqual(2, TraigeTranslator.collectDroppedCandiate.call_count)
659 def test_match_hpa(self):
661 './conductor/tests/unit/data/plugins/inventory_provider/hpa_flavors.json'
662 flavor_json = json.loads(open(flavor_json_file).read())
663 feature_json_file = \
664 './conductor/tests/unit/data/plugins/inventory_provider/hpa_req_features.json'
665 feature_json = json.loads(open(feature_json_file).read())
666 candidate_json_file = './conductor/tests/unit/data/candidate_list.json'
667 candidate_json = json.loads(open(candidate_json_file).read())
668 candidate_json['candidate_list'][1]['flavors'] = flavor_json
672 "flavor_map": {"flavor-id": "f5aa2b2e-3206-41b6-80d5-cf041b098c43",
673 "flavor-name": "flavor-cpu-pinning-ovsdpdk-instruction-set",
675 self.assertEqual(flavor_map,
676 match_hpa(candidate_json['candidate_list'][1],
679 flavor_map = {"flavor_map": {"flavor-id": "f5aa2b2e-3206-41b6-80d5-cf041b098c43",
680 "flavor-name": "flavor-cpu-ovsdpdk-instruction-set",
683 self.assertEqual(flavor_map,
684 match_hpa(candidate_json['candidate_list'][1],
686 flavor_map = {"flavor_map": {"flavor-id": "f5aa2b2e-3206-41b6-80d5-cf6t2b098c43",
687 "flavor-name": "flavor-ovsdpdk-cpu-pinning-sriov-NIC-Network-set",
690 "type": "sriovNICNetwork_directives",
693 "attribute_name": "A",
694 "attribute_value": "a"
698 self.assertEqual(flavor_map,
699 match_hpa(candidate_json['candidate_list'][1],
701 self.assertEqual(None, match_hpa(candidate_json['candidate_list'][1],
703 flavor_map = {"flavor_map": {"flavor-id": "f5aa2b2e-3206-41b6-19d5-cf6t2b098c43",
704 "flavor-name": "flavor-ovsdpdk-cpu-pinning-double-sriov-NIC-Network-set",
708 "type": "sriovNICNetwork_directives",
711 "attribute_name": "A",
712 "attribute_value": "a"
717 "type": "sriovNICNetwork_directives",
720 "attribute_name": "B",
721 "attribute_value": "b"
726 self.assertEqual(flavor_map, match_hpa(candidate_json['candidate_list'][1],
728 self.assertEqual(None, match_hpa(candidate_json['candidate_list'][1],
731 def test_filter_nssi_candidates(self):
732 nssi_response_file = './conductor/tests/unit/data/plugins/inventory_provider/nssi_response.json'
733 nssi_response = json.loads(open(nssi_response_file).read())
734 slice_profile_file = './conductor/tests/unit/data/plugins/inventory_provider/nssi_slice_profile.json'
735 slice_profile = json.loads(open(slice_profile_file).read())
736 nssi_candidates_file = './conductor/tests/unit/data/plugins/inventory_provider/nssi_candidate.json'
737 nssi_candidates = json.loads(open(nssi_candidates_file).read())
739 self.mock_get_profiles = mock.patch.object(AAI, 'get_profile_instances', return_value=[slice_profile])
740 self.mock_get_profiles.start()
742 service_role = 'nssi'
743 second_level_filter = dict()
744 second_level_filter['service-role'] = service_role
745 default_attributes = dict()
746 default_attributes['creation_cost'] =1
747 self.assertEqual(nssi_candidates, self.aai_ep.filter_nxi_candidates(nssi_response, second_level_filter,
748 default_attributes, "true", service_role))
750 nssi_response['service-instance'][0]['service-role'] = 'service'
752 self.assertEqual([], self.aai_ep.filter_nxi_candidates(nssi_response, second_level_filter, default_attributes,
753 "true", service_role))
755 self.assertEqual([], self.aai_ep.filter_nxi_candidates(None, second_level_filter, default_attributes,
756 "true", service_role))
758 self.assertEqual([], self.aai_ep.filter_nxi_candidates(None, None, default_attributes, "true", service_role))
760 self.assertEqual(nssi_candidates, self.aai_ep.filter_nxi_candidates(nssi_response, None, default_attributes,
761 "true", service_role))
762 del nssi_candidates[0]['creation_cost']
763 self.assertEqual(nssi_candidates, self.aai_ep.filter_nxi_candidates(nssi_response, None, None, "true",
766 def test_resolve_demands_inventory_type_nssi(self):
767 self.aai_ep.conf.HPA_enabled = True
768 TraigeTranslator.getPlanIdNAme = mock.MagicMock(return_value=None)
769 TraigeTranslator.addDemandsTriageTranslator = mock.MagicMock(return_value=None)
775 triage_translator_data = None
777 demands_list_file = './conductor/tests/unit/data/plugins/inventory_provider/nssi_demand_list.json'
778 demands_list = json.loads(open(demands_list_file).read())
780 nssi_response_file = './conductor/tests/unit/data/plugins/inventory_provider/nssi_response.json'
781 nssi_response = json.loads(open(nssi_response_file).read())
782 slice_profile_file = './conductor/tests/unit/data/plugins/inventory_provider/nssi_slice_profile.json'
783 slice_profile = json.loads(open(slice_profile_file).read())
784 nssi_candidates_file = './conductor/tests/unit/data/plugins/inventory_provider/nssi_candidate.json'
785 nssi_candidates = json.loads(open(nssi_candidates_file).read())
787 result['embb_cn'] = nssi_candidates
789 self.mock_get_nxi_candidates = mock.patch.object(AAI, 'get_nxi_candidates',
790 return_value=nssi_response)
791 self.mock_get_nxi_candidates.start()
793 self.mock_get_profiles = mock.patch.object(AAI, 'get_profile_instances', return_value=[slice_profile])
794 self.mock_get_profiles.start()
796 self.assertEqual(result, self.aai_ep.resolve_demands(demands_list, plan_info=plan_info,
797 triage_translator_data=triage_translator_data))
799 def test_filter_nsi_candidates(self):
800 nsi_response_file = './conductor/tests/unit/data/plugins/inventory_provider/nsi_response.json'
801 nsi_response = json.loads(open(nsi_response_file).read())
802 nsi_candidates_file = './conductor/tests/unit/data/plugins/inventory_provider/nsi_candidate.json'
803 nsi_candidates = json.loads(open(nsi_candidates_file).read())
804 service_profile_file = './conductor/tests/unit/data/plugins/inventory_provider/nsi_service_profile.json'
805 service_profile = json.loads(open(service_profile_file).read())
807 self.mock_get_profiles = mock.patch.object(AAI, 'get_profile_instances', return_value=[service_profile])
808 self.mock_get_profiles.start()
811 second_level_filter = dict()
812 second_level_filter['service-role'] = service_role
813 default_attributes = dict()
814 default_attributes['creation_cost'] = 1
816 self.assertEqual(nsi_candidates, self.aai_ep.filter_nxi_candidates(nsi_response, second_level_filter,
817 default_attributes, "true", service_role))
818 nsi_response['service-instance'][0]['service-role'] = 'service'
820 self.assertEqual([], self.aai_ep.filter_nxi_candidates(nsi_response, second_level_filter, default_attributes,
821 "true", service_role))
823 def test_resolve_demands_inventory_type_nsi(self):
824 self.aai_ep.conf.HPA_enabled = True
825 TraigeTranslator.getPlanIdNAme = mock.MagicMock(return_value=None)
826 TraigeTranslator.addDemandsTriageTranslator = mock.MagicMock(return_value=None)
832 triage_translator_data = None
834 demands_list_file = './conductor/tests/unit/data/plugins/inventory_provider/nsi_demand_list.json'
835 demands_list = json.loads(open(demands_list_file).read())
837 nsi_response_file = './conductor/tests/unit/data/plugins/inventory_provider/nsi_response.json'
838 nsi_response = json.loads(open(nsi_response_file).read())
839 nsi_candidates_file = './conductor/tests/unit/data/plugins/inventory_provider/nsi_candidate.json'
840 nsi_candidates = json.loads(open(nsi_candidates_file).read())
842 result['embb_nst'] = nsi_candidates
844 service_profile_file = './conductor/tests/unit/data/plugins/inventory_provider/nsi_service_profile.json'
845 service_profile = json.loads(open(service_profile_file).read())
847 self.mock_get_profiles = mock.patch.object(AAI, 'get_profile_instances', return_value=[service_profile])
848 self.mock_get_profiles.start()
850 self.mock_get_nxi_candidates = mock.patch.object(AAI, 'get_nxi_candidates',
851 return_value=nsi_response)
852 self.mock_get_nxi_candidates.start()
854 self.assertEqual(result, self.aai_ep.resolve_demands(demands_list, plan_info=plan_info,
855 triage_translator_data=triage_translator_data))
858 def test_get_nst_candidates(self):
859 nst_response_file = './conductor/tests/unit/data/plugins/inventory_provider/nst_response.json'
860 nst_response = json.loads(open(nst_response_file).read())
864 second_level_filter=None
866 default_attributes = dict()
867 default_attributes['creation_cost'] = 1
868 self.assertEqual("5d345ca8-1f8e-4f1e-aac7-6c8b33cc33e7", self.aai_ep.get_nst_candidates(nst_response, second_level_filter,
869 default_attributes, "true", "nst").__getitem__(0).__getattribute__('candidate_id'))
872 def test_resolve_demands_inventory_type_nst(self):
873 self.aai_ep.conf.HPA_enabled = True
874 TraigeTranslator.getPlanIdNAme = mock.MagicMock(return_value=None)
875 TraigeTranslator.addDemandsTriageTranslator = mock.MagicMock(return_value=None)
881 triage_translator_data = None
883 demands_list_file = './conductor/tests/unit/data/plugins/inventory_provider/nst_demand_list.json'
884 demands_list = json.loads(open(demands_list_file).read())
886 nst_response_file = './conductor/tests/unit/data/plugins/inventory_provider/nst_response.json'
887 nst_response = json.loads(open(nst_response_file).read())
888 final_nst_candidates_file = './conductor/tests/unit/data/plugins/inventory_provider/final_nst_candidate.json'
889 final_nst_candidates = json.loads(open(final_nst_candidates_file).read())
891 result['embb_nst'] = final_nst_candidates
893 self.mock_get_nst_candidates = mock.patch.object(AAI, 'get_nst_response',
894 return_value=nst_response)
895 self.mock_get_final_nst_candidates = mock.patch.object(SDC, 'update_candidates',
896 return_value=final_nst_candidates)
897 self.mock_get_nst_candidates.start()
898 self.mock_get_final_nst_candidates.start()
900 self.assertEqual(result, self.aai_ep.resolve_demands(demands_list, plan_info=plan_info,
901 triage_translator_data=triage_translator_data))
903 def test_get_aai_data(self):
904 nst_response_file = './conductor/tests/unit/data/plugins/inventory_provider/nst_response.json'
905 nst_response = json.loads(open(nst_response_file).read())
906 response = mock.MagicMock()
907 response.status_code = 200
909 response.json.return_value = nst_response
910 self.mock_get_request = mock.patch.object(AAI, '_request', return_value=response)
911 self.mock_get_request.start()
912 filtering_attr={"model-role":"NST"}
913 self.assertEquals(nst_response, self.aai_ep.get_nst_response(filtering_attr))
915 def test_get_profile_instances(self):
916 nsi_response_file = './conductor/tests/unit/data/plugins/inventory_provider/nsi_response.json'
917 nsi_response = json.loads(open(nsi_response_file).read())
918 service_profile_file = './conductor/tests/unit/data/plugins/inventory_provider/nsi_service_profile.json'
919 service_profile = json.loads(open(service_profile_file).read())
921 response = mock.MagicMock()
922 response.status_code = 200
924 response.json.return_value = service_profile
925 self.mock_get_profiles = mock.patch.object(AAI, '_request', return_value=response)
926 self.mock_get_profiles.start()
928 self.assertEquals([service_profile], self.aai_ep.get_profile_instances(nsi_response["service-instance"][0]))