Merge "Support new policy model in HAS"
[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 #
5 #   Licensed under the Apache License, Version 2.0 (the "License");
6 #   you may not use this file except in compliance with the License.
7 #   You may obtain a copy of the License at
8 #
9 #       http://www.apache.org/licenses/LICENSE-2.0
10 #
11 #   Unless required by applicable law or agreed to in writing, software
12 #   distributed under the License is distributed on an "AS IS" BASIS,
13 #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 #   See the License for the specific language governing permissions and
15 #   limitations under the License.
16 #
17 # -------------------------------------------------------------------------
18 #
19 import json
20 import unittest
21
22 import conductor.data.plugins.inventory_provider.aai as aai
23 import mock
24 from conductor.data.plugins.inventory_provider.aai import AAI
25 from oslo_config import cfg
26
27
28 class TestAAI(unittest.TestCase):
29
30     def setUp(self):
31         CONF = cfg.CONF
32         CONF.register_opts(aai.AAI_OPTS, group='aai')
33         self.conf = CONF
34         self.aai_ep = AAI()
35
36     def tearDown(self):
37         mock.patch.stopall()
38
39     def test_get_version_from_string(self):
40         self.assertEqual("2.5", self.aai_ep._get_version_from_string("AAI2.5"))
41         self.assertEqual("3.0", self.aai_ep._get_version_from_string("AAI3.0"))
42
43     def test_aai_versioned_path(self):
44         self.assertEqual('/{}/cloud-infrastructure/cloud-regions/?depth=0'.format(self.conf.aai.server_url_version),
45                          self.aai_ep._aai_versioned_path("/cloud-infrastructure/cloud-regions/?depth=0"))
46         self.assertEqual('/{}/query?format=id'.format(self.conf.aai.server_url_version),
47                          self.aai_ep._aai_versioned_path("/query?format=id"))
48
49     def test_resolve_clli_location(self):
50         req_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_request_clli_location.json'
51         req_json = json.loads(open(req_json_file).read())
52
53         response = mock.MagicMock()
54         response.status_code = 200
55         response.ok = True
56         response.json.return_value = req_json
57
58         self.mock_get_request = mock.patch.object(AAI, '_request', return_value=response)
59         self.mock_get_request.start()
60         self.assertEqual({'country': u'USA', 'latitude': u'40.39596', 'longitude': u'-74.135342'},
61                          self.aai_ep.resolve_clli_location("clli_code"))
62
63     def test_get_inventory_group_pair(self):
64         req_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_request_inventory_group_pair.json'
65         req_json = json.loads(open(req_json_file).read())
66
67         response = mock.MagicMock()
68         response.status_code = 200
69         response.ok = True
70         response.json.return_value = req_json
71
72         self.mock_get_request = mock.patch.object(AAI, '_request', return_value=response)
73         self.mock_get_request.start()
74         self.assertEqual([[u'instance-1', u'instance-2']],
75                          self.aai_ep.get_inventory_group_pairs("service_description"))
76
77     def test_resolve_host_location(self):
78         req_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_request_host_name.json'
79         req_json = json.loads(open(req_json_file).read())
80
81         req_response = mock.MagicMock()
82         req_response.status_code = 200
83         req_response.ok = True
84         req_response.json.return_value = req_json
85
86         complex_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_get_complex.json'
87         complex_json = json.loads(open(complex_json_file).read())
88
89         self.mock_get_request = mock.patch.object(AAI, '_request', return_value=req_response)
90         self.mock_get_request.start()
91
92         self.mock_get_complex = mock.patch.object(AAI, '_get_complex', return_value=complex_json)
93         self.mock_get_complex.start()
94
95         self.assertEqual({'country': u'USA', 'latitude': u'28.543251', 'longitude': u'-81.377112'},
96                          self.aai_ep.resolve_host_location("host_name"))
97
98     def test_resolve_demands(self):
99         self.assertEqual({}, self.aai_ep.resolve_demands(dict()))
100
101         demands_list_file = './conductor/tests/unit/data/plugins/inventory_provider/demand_list.json'
102         demands_list = json.loads(open(demands_list_file).read())
103
104         generic_vnf_list_file = './conductor/tests/unit/data/plugins/inventory_provider/generic_vnf_list.json'
105         generic_vnf_list = json.loads(open(generic_vnf_list_file).read())
106
107         regions_response_file = './conductor/tests/unit/data/plugins/inventory_provider/regions.json'
108         regions_response = json.loads(open(regions_response_file).read())
109
110         demand_service_response_file = './conductor/tests/unit/data/plugins/inventory_provider/resolve_demand_service_response.json'
111         demand_service_response = json.loads(open(demand_service_response_file).read())
112
113         complex_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_get_complex.json'
114         complex_json = json.loads(open(complex_json_file).read())
115
116         req_response = mock.MagicMock()
117         req_response.status_code = 200
118         req_response.ok = True
119         req_response.json.return_value = demand_service_response
120
121         self.mock_first_level_service_call = mock.patch.object(AAI, 'first_level_service_call',
122                                                                return_value=generic_vnf_list)
123         self.mock_first_level_service_call.start()
124
125         self.mock_get_regions = mock.patch.object(AAI, '_get_regions', return_value=regions_response)
126         self.mock_get_regions.start()
127
128         self.mock_get_regions = mock.patch.object(AAI, '_request', return_value=req_response)
129         self.mock_get_regions.start()
130
131         self.mock_get_complex = mock.patch.object(AAI, '_get_complex', return_value=complex_json)
132         self.mock_get_complex.start()
133
134         flavor_info = regions_response["region-name"]["flavors"]
135         self.maxDiff = None
136         self.assertEqual({u'demand_name': [
137             {'candidate_id': u'service-instance-id', 'city': None,
138              'cloud_owner': u'cloud-owner',
139              'vim-id': 'cloud-owner_cloud-region-id',
140              'cloud_region_version': '', 'complex_name': None, 'cost': 1.0,
141              'country': u'USA', 'existing_placement': 'false',
142              'host_id': u'vnf-name', 'inventory_provider': 'aai',
143              'inventory_type': 'service', 'latitude': u'28.543251',
144              'location_id': u'cloud-region-id', 'location_type': 'att_aic',
145              'longitude': u'-81.377112', 'physical_location_id': 'test-id',
146              'region': u'SE', 'service_resource_id': '',
147              'sriov_automation': 'false', 'state': None},
148             {'candidate_id': u'region-name', 'city': u'Middletown',
149              'cloud_owner': u'cloud-owner',
150              'vim-id': 'cloud-owner_region-name',
151              'cloud_region_version': u'1.0', 'complex_name': u'complex-name',
152              'cost': 2.0, 'country': u'USA', 'existing_placement': 'false',
153              'inventory_provider': 'aai', 'inventory_type': 'cloud',
154              'latitude': u'50.34', 'location_id': u'region-name',
155              'location_type': 'att_aic', 'longitude': u'30.12',
156              'physical_location_id': u'complex-id', 'region': u'USA',
157              'service_resource_id': u'service-resource-id-123',
158              'sriov_automation': 'false', 'state': u'NJ',
159              'flavors': flavor_info}]},
160             self.aai_ep.resolve_demands(demands_list))
161
162     def test_get_complex(self):
163         complex_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_request_get_complex.json'
164         complex_json = json.loads(open(complex_json_file).read())
165
166         response = mock.MagicMock()
167         response.status_code = 200
168         response.ok = True
169         response.json.return_value = complex_json
170
171         self.mock_get_request = mock.patch.object(AAI, '_request', return_value=response)
172         self.mock_get_request.start()
173
174         self.assertEqual(
175             {u'city': u'Middletown', u'latitude': u'28.543251', u'longitude': u'-81.377112', u'country': u'USA',
176              u'region': u'SE'},
177             self.aai_ep._get_complex("/v10/complex/complex_id", "complex_id"))
178
179     def test_check_network_roles(self):
180         network_role_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_request_network_role.json'
181         network_role_json = json.loads(open(network_role_json_file).read())
182
183         response = mock.MagicMock()
184         response.status_code = 200
185         response.ok = True
186         response.json.return_value = network_role_json
187
188         self.mock_get_request = mock.patch.object(AAI, '_request', return_value=response)
189         self.mock_get_request.start()
190         self.assertEqual(set(['test-cloud-value']),
191                          self.aai_ep.check_network_roles("network_role_id"))
192
193     def test_check_candidate_role(self):
194         candidate_role_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_request_candidate_role.json'
195         candidate_role_json = json.loads(open(candidate_role_json_file).read())
196
197         response = mock.MagicMock()
198         response.status_code = 200
199         response.ok = True
200         response.json.return_value = candidate_role_json
201
202         self.mock_get_request = mock.patch.object(AAI, '_request', return_value=response)
203         self.mock_get_request.start()
204
205         self.assertEqual("test-role",
206                          self.aai_ep.check_candidate_role("candidate_host_id"))
207
208     def test_match_inventory_attributes(self):
209         template_attributes = dict()
210         template_attributes['attr-1'] = ['attr-1-value1', 'attr-1-value2']
211
212         inventory_attributes = dict()
213         inventory_attributes['attr-1'] = 'attr-1-value1'
214
215         self.assertEqual(True,
216                          self.aai_ep.match_inventory_attributes(template_attributes, inventory_attributes,
217                                                                 "candidate-id"))
218
219         template_attributes['attr-1'] = {
220             'not': ['attr-1-value2']
221         }
222         self.assertEqual(True,
223                          self.aai_ep.match_inventory_attributes(template_attributes, inventory_attributes,
224                                                                 "candidate-id"))
225
226         template_attributes['attr-1'] = {
227             'not': ['attr-1-value1']
228         }
229         self.assertEqual(False,
230                          self.aai_ep.match_inventory_attributes(template_attributes, inventory_attributes,
231                                                                 "candidate-id"))
232
233     def test_refresh_cache(self):
234         regions_response_file = './conductor/tests/unit/data/plugins/inventory_provider/cache_regions.json'
235         regions_response = json.loads(open(regions_response_file).read())
236
237         complex_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_cached_complex.json'
238         complex_json = json.loads(open(complex_json_file).read())
239
240         flavors_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_request_get_flavors.json'
241         flavors_json = json.loads(open(flavors_json_file).read())
242
243         response = mock.MagicMock()
244         response.status_code = 200
245         response.ok = True
246         response.json.return_value = regions_response
247
248         self.mock_get_regions = mock.patch.object(AAI, '_request', return_value=response)
249         self.mock_get_regions.start()
250
251         self.mock_get_complex = mock.patch.object(AAI, '_get_complex', return_value=complex_json)
252         self.mock_get_complex.start()
253
254         self.mock_get_flavors = mock.patch.object(AAI, '_get_flavors',
255                                                   return_value=flavors_json)
256         self.mock_get_flavors.start()
257
258         self.assertEqual(None,
259                          self.aai_ep._refresh_cache())
260
261     def test_get_aai_rel_link(self):
262         relatonship_response_file = './conductor/tests/unit/data/plugins/inventory_provider/relationship_list.json'
263         relatonship_response = json.loads(open(relatonship_response_file).read())
264         related_to = "service-instance"
265
266         self.assertEqual("relationship-link",
267                          self.aai_ep._get_aai_rel_link(relatonship_response, related_to))
268
269     def test_get_flavor(self):
270         flavors_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_request_get_flavors.json'
271         flavors_json = json.loads(open(flavors_json_file).read())
272
273         response = mock.MagicMock()
274         response.json.return_value = None
275
276         self.mock_get_request = mock.patch.object(AAI, '_request',
277                                                   return_value=response)
278         self.mock_get_request.start()
279
280         flavors_info = self.aai_ep._get_flavors("mock-cloud-owner",
281                                                 "mock-cloud-region-id")
282         self.assertEqual(None, flavors_info)
283
284         response.status_code = 200
285         response.ok = True
286         response.json.return_value = flavors_json
287
288         flavors_info = self.aai_ep._get_flavors("mock-cloud-owner",
289                                                 "mock-cloud-region-id")
290         self.assertEqual(2, len(flavors_info['flavor']))
291
292     def test_match_hpa(self):
293         flavor_json_file = \
294             './conductor/tests/unit/data/plugins/inventory_provider/hpa_flavors.json'
295         flavor_json = json.loads(open(flavor_json_file).read())
296         feature_json_file = \
297             './conductor/tests/unit/data/plugins/inventory_provider/hpa_req_features.json'
298         feature_json = json.loads(open(feature_json_file).read())
299         candidate_json_file = './conductor/tests/unit/data/candidate_list.json'
300         candidate_json = json.loads(open(candidate_json_file).read())
301         candidate_json['candidate_list'][1]['flavors'] = flavor_json
302
303         flavor_map = {
304             "directives": [],
305             "flavor_map": {"flavor-id": "f5aa2b2e-3206-41b6-80d5-cf041b098c43",
306                            "flavor-name": "flavor-cpu-pinning-ovsdpdk-instruction-set",
307                            "score": 0}}
308         self.assertEqual(flavor_map,
309                          self.aai_ep.match_hpa(candidate_json['candidate_list'][1],
310                                                feature_json[0]))
311
312         flavor_map = {"flavor_map": {"flavor-id": "f5aa2b2e-3206-41b6-80d5-cf041b098c43",
313                                      "flavor-name": "flavor-cpu-ovsdpdk-instruction-set",
314                                      "score": 10},
315                       "directives": []}
316         self.assertEqual(flavor_map,
317                          self.aai_ep.match_hpa(candidate_json['candidate_list'][1],
318                                                feature_json[1]))
319         flavor_map = {"flavor_map": {"flavor-id": "f5aa2b2e-3206-41b6-80d5-cf6t2b098c43",
320                                      "flavor-name": "flavor-ovsdpdk-cpu-pinning-sriov-NIC-Network-set",
321                                      "score": 13},
322                       "directives": [{
323                           "type": "sriovNICNetwork_directives",
324                           "attributes": [
325                               {
326                                   "attribute_name": "A",
327                                   "attribute_value": "a"
328                               }
329                           ]
330                       }]}
331         self.assertEqual(flavor_map,
332                          self.aai_ep.match_hpa(candidate_json['candidate_list'][1],
333                                                feature_json[2]))