Code Coverage

Cobertura Coverage Report > osm_pla.test >

test_nsPlacementDataFactory.py

Trend

Classes100%
 
Lines99%
   
Conditionals100%
 

File Coverage summary

NameClassesLinesConditionals
test_nsPlacementDataFactory.py
100%
1/1
99%
257/260
100%
0/0

Coverage Breakdown by Class

NameLinesConditionals
test_nsPlacementDataFactory.py
99%
257/260
N/A

Source

osm_pla/test/test_nsPlacementDataFactory.py
1 # Copyright 2020 ArctosLabs Scandinavia AB
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #    http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12 # implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 1 import os
16 1 import unittest
17 1 from collections import Counter
18 1 from pathlib import Path
19 1 from unittest import TestCase, mock
20 1 from unittest.mock import call
21
22 1 import yaml
23
24 1 from osm_pla.placement.mznplacement import NsPlacementDataFactory
25
26
27 1 class TestNsPlacementDataFactory(TestCase):
28 1     vim_accounts = [{"vim_password": "FxtnynxBCnouzAT4Hkerhg==", "config": {},
29                      "_admin": {"modified": 1564579854.0480285, "created": 1564579854.0480285,
30                                 "operationalState": "ENABLED",
31                                 "projects_read": ["69915588-e5e2-46d3-96b0-a29bedef6f73"],
32                                 "deployed": {"RO-account": "6beb4e2e-b397-11e9-a7a3-02420aff0008",
33                                              "RO": "6bcfc3fc-b397-11e9-a7a3-02420aff0008"},
34                                 "projects_write": ["69915588-e5e2-46d3-96b0-a29bedef6f73"], "detailed-status": "Done"},
35                      "name": "OpenStack1", "vim_type": "openstack", "_id": "92b056a7-38f5-438d-b8ee-3f93b3531f87",
36                      "schema_version": "1.1", "vim_user": "admin", "vim_url": "http://10.234.12.47:5000/v3",
37                      "vim_tenant_name": "admin"},
38                     {"config": {}, "vim_tenant_name": "osm_demo", "schema_version": "1.1", "name": "OpenStack2",
39                      "vim_password": "gK5v4Gh2Pl41o6Skwp6RCw==", "vim_type": "openstack",
40                      "_admin": {"modified": 1567148372.2490237, "created": 1567148372.2490237,
41                                 "operationalState": "ENABLED",
42                                 "projects_read": ["69915588-e5e2-46d3-96b0-a29bedef6f73"],
43                                 "deployed": {"RO-account": "b7fb0034-caf3-11e9-9388-02420aff000a",
44                                              "RO": "b7f129ce-caf3-11e9-9388-02420aff000a"},
45                                 "projects_write": ["69915588-e5e2-46d3-96b0-a29bedef6f73"], "detailed-status": "Done"},
46                      "vim_user": "admin", "vim_url": "http://10.234.12.44:5000/v3",
47                      "_id": "6618d412-d7fc-4eb0-a6f8-d2c258e0e900"},
48                     {"config": {}, "schema_version": "1.1", "name": "OpenStack3",
49                      "vim_password": "1R2FoMQnaL6rNSosoRP2hw==", "vim_type": "openstack", "vim_tenant_name": "osm_demo",
50                      "_admin": {"modified": 1567599746.689582, "created": 1567599746.689582,
51                                 "operationalState": "ENABLED",
52                                 "projects_read": ["69915588-e5e2-46d3-96b0-a29bedef6f73"],
53                                 "deployed": {"RO-account": "a8161f54-cf0e-11e9-9388-02420aff000a",
54                                              "RO": "a80b6280-cf0e-11e9-9388-02420aff000a"},
55                                 "projects_write": ["69915588-e5e2-46d3-96b0-a29bedef6f73"], "detailed-status": "Done"},
56                      "vim_user": "admin", "vim_url": "http://10.234.12.46:5000/v3",
57                      "_id": "331ffdec-44a8-4707-94a1-af7a292d9735"},
58                     {"config": {}, "schema_version": "1.1", "name": "OpenStack4",
59                      "vim_password": "6LScyPeMq3QFh3GRb/xwZw==", "vim_type": "openstack", "vim_tenant_name": "osm_demo",
60                      "_admin": {"modified": 1567599911.5108898, "created": 1567599911.5108898,
61                                 "operationalState": "ENABLED",
62                                 "projects_read": ["69915588-e5e2-46d3-96b0-a29bedef6f73"],
63                                 "deployed": {"RO-account": "0a651200-cf0f-11e9-9388-02420aff000a",
64                                              "RO": "0a4defc6-cf0f-11e9-9388-02420aff000a"},
65                                 "projects_write": ["69915588-e5e2-46d3-96b0-a29bedef6f73"], "detailed-status": "Done"},
66                      "vim_user": "admin", "vim_url": "http://10.234.12.43:5000/v3",
67                      "_id": "eda92f47-29b9-4007-9709-c1833dbfbe31"}]
68
69 1     vim_accounts_fewer_vims = [{"vim_password": "FxtnynxBCnouzAT4Hkerhg==", "config": {},
70                                 "_admin": {"modified": 1564579854.0480285, "created": 1564579854.0480285,
71                                            "operationalState": "ENABLED",
72                                            "projects_read": ["69915588-e5e2-46d3-96b0-a29bedef6f73"],
73                                            "deployed": {"RO-account": "6beb4e2e-b397-11e9-a7a3-02420aff0008",
74                                                         "RO": "6bcfc3fc-b397-11e9-a7a3-02420aff0008"},
75                                            "projects_write": ["69915588-e5e2-46d3-96b0-a29bedef6f73"],
76                                            "detailed-status": "Done"},
77                                 "name": "OpenStack1", "vim_type": "openstack",
78                                 "_id": "92b056a7-38f5-438d-b8ee-3f93b3531f87",
79                                 "schema_version": "1.1", "vim_user": "admin", "vim_url": "http://10.234.12.47:5000/v3",
80                                 "vim_tenant_name": "admin"},
81                                {"config": {}, "vim_tenant_name": "osm_demo", "schema_version": "1.1",
82                                 "name": "OpenStack2",
83                                 "vim_password": "gK5v4Gh2Pl41o6Skwp6RCw==", "vim_type": "openstack",
84                                 "_admin": {"modified": 1567148372.2490237, "created": 1567148372.2490237,
85                                            "operationalState": "ENABLED",
86                                            "projects_read": ["69915588-e5e2-46d3-96b0-a29bedef6f73"],
87                                            "deployed": {"RO-account": "b7fb0034-caf3-11e9-9388-02420aff000a",
88                                                         "RO": "b7f129ce-caf3-11e9-9388-02420aff000a"},
89                                            "projects_write": ["69915588-e5e2-46d3-96b0-a29bedef6f73"],
90                                            "detailed-status": "Done"},
91                                 "vim_user": "admin", "vim_url": "http://10.234.12.44:5000/v3",
92                                 "_id": "6618d412-d7fc-4eb0-a6f8-d2c258e0e900"},
93                                {"config": {}, "schema_version": "1.1", "name": "OpenStack4",
94                                 "vim_password": "6LScyPeMq3QFh3GRb/xwZw==", "vim_type": "openstack",
95                                 "vim_tenant_name": "osm_demo",
96                                 "_admin": {"modified": 1567599911.5108898, "created": 1567599911.5108898,
97                                            "operationalState": "ENABLED",
98                                            "projects_read": ["69915588-e5e2-46d3-96b0-a29bedef6f73"],
99                                            "deployed": {"RO-account": "0a651200-cf0f-11e9-9388-02420aff000a",
100                                                         "RO": "0a4defc6-cf0f-11e9-9388-02420aff000a"},
101                                            "projects_write": ["69915588-e5e2-46d3-96b0-a29bedef6f73"],
102                                            "detailed-status": "Done"},
103                                 "vim_user": "admin", "vim_url": "http://10.234.12.43:5000/v3",
104                                 "_id": "eda92f47-29b9-4007-9709-c1833dbfbe31"}]
105
106 1     vim_accounts_more_vims = [{"vim_password": "FxtnynxBCnouzAT4Hkerhg==", "config": {},
107                                "_admin": {"modified": 1564579854.0480285, "created": 1564579854.0480285,
108                                           "operationalState": "ENABLED",
109                                           "projects_read": ["69915588-e5e2-46d3-96b0-a29bedef6f73"],
110                                           "deployed": {"RO-account": "6beb4e2e-b397-11e9-a7a3-02420aff0008",
111                                                        "RO": "6bcfc3fc-b397-11e9-a7a3-02420aff0008"},
112                                           "projects_write": ["69915588-e5e2-46d3-96b0-a29bedef6f73"],
113                                           "detailed-status": "Done"},
114                                "name": "OpenStack1", "vim_type": "openstack",
115                                "_id": "92b056a7-38f5-438d-b8ee-3f93b3531f87",
116                                "schema_version": "1.1", "vim_user": "admin", "vim_url": "http://10.234.12.47:5000/v3",
117                                "vim_tenant_name": "admin"},
118                               {"config": {}, "vim_tenant_name": "osm_demo", "schema_version": "1.1",
119                                "name": "OpenStack2",
120                                "vim_password": "gK5v4Gh2Pl41o6Skwp6RCw==", "vim_type": "openstack",
121                                "_admin": {"modified": 1567148372.2490237, "created": 1567148372.2490237,
122                                           "operationalState": "ENABLED",
123                                           "projects_read": ["69915588-e5e2-46d3-96b0-a29bedef6f73"],
124                                           "deployed": {"RO-account": "b7fb0034-caf3-11e9-9388-02420aff000a",
125                                                        "RO": "b7f129ce-caf3-11e9-9388-02420aff000a"},
126                                           "projects_write": ["69915588-e5e2-46d3-96b0-a29bedef6f73"],
127                                           "detailed-status": "Done"},
128                                "vim_user": "admin", "vim_url": "http://10.234.12.44:5000/v3",
129                                "_id": "6618d412-d7fc-4eb0-a6f8-d2c258e0e900"},
130                               {"config": {}, "schema_version": "1.1", "name": "OpenStack4",
131                                "vim_password": "6LScyPeMq3QFh3GRb/xwZw==", "vim_type": "openstack",
132                                "vim_tenant_name": "osm_demo",
133                                "_admin": {"modified": 1567599911.5108898, "created": 1567599911.5108898,
134                                           "operationalState": "ENABLED",
135                                           "projects_read": ["69915588-e5e2-46d3-96b0-a29bedef6f73"],
136                                           "deployed": {"RO-account": "0a651200-cf0f-11e9-9388-02420aff000a",
137                                                        "RO": "0a4defc6-cf0f-11e9-9388-02420aff000a"},
138                                           "projects_write": ["69915588-e5e2-46d3-96b0-a29bedef6f73"],
139                                           "detailed-status": "Done"},
140                                "vim_user": "admin", "vim_url": "http://10.234.12.43:5000/v3",
141                                "_id": "eda92f47-29b9-4007-9709-c1833dbfbe31"},
142                               {"config": {}, "schema_version": "1.1", "name": "OpenStack3",
143                                "vim_password": "6LScyPeMq3QFh3GRb/xwZw==", "vim_type": "openstack",
144                                "vim_tenant_name": "osm_demo",
145                                "_admin": {"modified": 1567599911.5108898, "created": 1567599911.5108898,
146                                           "operationalState": "ENABLED",
147                                           "projects_read": ["69915588-e5e2-46d3-96b0-a29bedef6f73"],
148                                           "deployed": {"RO-account": "0a651200-cf0f-11e9-9388-02420aff000a",
149                                                        "RO": "0a4defc6-cf0f-11e9-9388-02420aff000a"},
150                                           "projects_write": ["69915588-e5e2-46d3-96b0-a29bedef6f73"],
151                                           "detailed-status": "Done"},
152                                "vim_user": "admin", "vim_url": "http://10.234.12.46:5000/v3",
153                                "_id": "eda92f47-29b9-4007-9709-c1833dbfbe31"},
154                               {"config": {}, "schema_version": "1.1", "name": "OpenStack5",
155                                "vim_password": "6LScyPeMq3QFh3GRb/xwZw==", "vim_type": "openstack",
156                                "vim_tenant_name": "osm_demo",
157                                "_admin": {"modified": 1567599911.5108898, "created": 1567599911.5108898,
158                                           "operationalState": "ENABLED",
159                                           "projects_read": ["69915588-e5e2-46d3-96b0-a29bedef6f73"],
160                                           "deployed": {"RO-account": "0a651200-cf0f-11e9-9388-02420aff000a",
161                                                        "RO": "0a4defc6-cf0f-11e9-9388-02420aff000a"},
162                                           "projects_write": ["69915588-e5e2-46d3-96b0-a29bedef6f73"],
163                                           "detailed-status": "Done"},
164                                "vim_user": "admin", "vim_url": "http://1.1.1.1:5000/v3",
165                                "_id": "ffffffff-29b9-4007-9709-c1833dbfbe31"}]
166
167 1     def _produce_ut_vim_accounts_info(self, vim_accounts):
168         """
169         FIXME temporary, we will need more control over vim_urls and _id for test purpose - make a generator
170         :return: vim_url and _id as dict, i.e. extract these from vim_accounts data
171         """
172 1         return {_['name']: _['_id'] for _ in vim_accounts}
173
174 1     def _adjust_path(self, file):
175         """In case we are not running from test directory,
176         then assume we are in top level directory (e.g. running from tox) and adjust file path accordingly"""
177 1         path_component = '/osm_pla/test/'
178 1         real_path = os.path.realpath(file)
179 1         if path_component not in real_path:
180 1             return os.path.dirname(real_path) + path_component + os.path.basename(real_path)
181         else:
182 0             return real_path
183
184 1     def _populate_pil_info(self, file):
185         """
186         Note str(Path()) is a 3.5 thing
187         """
188 1         with open(str(Path(self._adjust_path(file)))) as pp_fd:
189 1             test_data = yaml.safe_load_all(pp_fd)
190 1             return next(test_data)
191
192 1     def _get_ut_nsd_from_file(self, nsd_file_name):
193         """
194         creates the structure representing the nsd.
195
196         IMPORTANT NOTE: If using .yaml files from the NS packages for the unit tests (which we do),
197         then the files must be modified with respect to the way booleans are processed at on-boarding in OSM.
198         The following construct in the NS package yaml file:
199         mgmt-network: 'false'
200         will become a boolean in the MongoDB, and therefore the yaml used in these unit test must use yaml
201         tag as follows:
202         mgmt-network: !!bool False
203         The modification also applies to 'true' => !!bool True
204         This will ensure that the object returned from this function is as expected by PLA.
205         """
206 1         with open(str(Path(self._adjust_path(nsd_file_name)))) as nsd_fd:
207 1             test_data = yaml.safe_load_all(nsd_fd)
208 1             return next(test_data)
209
210 1     def _produce_ut_vnf_price_list(self):
211 1         price_list_file = "vnf_price_list.yaml"
212 1         with open(str(Path(self._adjust_path(price_list_file)))) as pl_fd:
213 1             price_list_data = yaml.safe_load_all(pl_fd)
214 1             return {i['vnfd']: {i1['vim_name']: i1['price'] for i1 in i['prices']} for i in next(price_list_data)}
215
216 1     def _produce_ut_vnf_test_price_list(self, price_list):
217 1         price_list_file = price_list
218 1         with open(str(Path(self._adjust_path(price_list_file)))) as pl_fd:
219 1             price_list_data = yaml.safe_load_all(pl_fd)
220 1             return {i['vnfd']: {i1['vim_name']: i1['price'] for i1 in i['prices']} for i in next(price_list_data)}
221
222 1     def test__produce_trp_link_characteristics_link_latency_with_more_vims(self):
223         """
224          -test with more(other) vims compared to pil
225          """
226 1         content_expected = [0, 0, 0, 0, 0, 120, 120, 130, 130, 140, 140, 230, 230, 240, 240,
227                             340, 340, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767]
228 1         nspdf = NsPlacementDataFactory(
229             self._produce_ut_vim_accounts_info(TestNsPlacementDataFactory.vim_accounts_more_vims),
230             self._produce_ut_vnf_price_list(),
231             nsd=None,
232             pil_info=self._populate_pil_info('pil_unittest1_keys.yaml'),
233             pinning=None)
234 1         pil_latencies = nspdf._produce_trp_link_characteristics_data('pil_latency')
235 1         content_produced = [i for row in pil_latencies for i in row]
236 1         self.assertEqual(Counter(content_expected), Counter(content_produced), 'trp_link_latency incorrect')
237
238 1     def test__produce_trp_link_characteristics_link_latency_with_fewer_vims(self):
239         """
240         -test with fewer vims compared to pil
241         :return:
242         """
243 1         content_expected = [0, 0, 0, 120, 120, 140, 140, 240, 240]
244 1         nspdf = NsPlacementDataFactory(
245             self._produce_ut_vim_accounts_info(TestNsPlacementDataFactory.vim_accounts_fewer_vims),
246             self._produce_ut_vnf_price_list(),
247             nsd=None,
248             pil_info=self._populate_pil_info('pil_unittest1_keys.yaml'),
249             pinning=None)
250 1         pil_latencies = nspdf._produce_trp_link_characteristics_data('pil_latency')
251 1         content_produced = [i for row in pil_latencies for i in row]
252 1         self.assertEqual(Counter(content_expected), Counter(content_produced), 'trp_link_latency incorrect')
253
254 1     def test__produce_trp_link_characteristic_not_supported(self):
255         """
256         - test with non-supported characteristic
257         """
258 1         nspdf = NsPlacementDataFactory(self._produce_ut_vim_accounts_info(TestNsPlacementDataFactory.vim_accounts),
259                                        self._produce_ut_vnf_price_list(),
260                                        nsd=None,
261                                        pil_info=self._populate_pil_info('pil_unittest1.yaml'), pinning=None)
262
263 1         with self.assertRaises(Exception) as e:
264 1             nspdf._produce_trp_link_characteristics_data('test_no_support')
265 1         self.assertRegex(str(e.exception), r'characteristic.*not supported', "invalid exception content")
266
267 1     def test__produce_trp_link_characteristics_link_latency(self):
268         """
269         -test with full set of vims as in pil
270         -test with fewer vims compared to pil
271         -test with more(other) vims compared to pil
272         -test with invalid/corrupt pil configuration file (e.g. missing endpoint), empty file, not yaml conformant
273         - test with non-supported characteristic
274
275         :return:
276         """
277 1         content_expected = [0, 0, 0, 0, 120, 120, 130, 130, 140, 140, 230, 230, 240, 240, 340, 340]
278
279 1         nspdf = NsPlacementDataFactory(self._produce_ut_vim_accounts_info(TestNsPlacementDataFactory.vim_accounts),
280                                        self._produce_ut_vnf_price_list(),
281                                        nsd=None,
282                                        pil_info=self._populate_pil_info('pil_unittest1_keys.yaml'), pinning=None)
283 1         pil_latencies = nspdf._produce_trp_link_characteristics_data('pil_latency')
284 1         content_produced = [i for row in pil_latencies for i in row]
285 1         self.assertEqual(Counter(content_expected), Counter(content_produced), 'trp_link_latency incorrect')
286
287 1     def test__produce_trp_link_characteristics_link_jitter(self):
288         """
289         -test with full set of vims as in pil
290         """
291 1         content_expected = [0, 0, 0, 0, 1200, 1200, 1300, 1300, 1400, 1400, 2300, 2300, 2400, 2400, 3400, 3400]
292
293 1         nspdf = NsPlacementDataFactory(self._produce_ut_vim_accounts_info(TestNsPlacementDataFactory.vim_accounts),
294                                        self._produce_ut_vnf_price_list(),
295                                        nsd=None,
296                                        pil_info=self._populate_pil_info('pil_unittest1_keys.yaml'), pinning=None)
297 1         pil_jitter = nspdf._produce_trp_link_characteristics_data('pil_jitter')
298 1         content_produced = [i for row in pil_jitter for i in row]
299 1         self.assertEqual(Counter(content_expected), Counter(content_produced), 'trp_link_jitter incorrect')
300
301 1     def test__produce_trp_link_characteristics_link_jitter_with_fewer_vims(self):
302         """
303         -test with fewer vims compared to pil, link jitter
304         """
305 1         content_expected = [0, 0, 0, 1200, 1200, 1400, 1400, 2400, 2400]
306 1         nspdf = NsPlacementDataFactory(self._produce_ut_vim_accounts_info(self.vim_accounts_fewer_vims),
307                                        self._produce_ut_vnf_price_list(),
308                                        nsd=None,
309                                        pil_info=self._populate_pil_info('pil_unittest1_keys.yaml'), pinning=None)
310 1         pil_latencies = nspdf._produce_trp_link_characteristics_data('pil_jitter')
311 1         content_produced = [i for row in pil_latencies for i in row]
312 1         self.assertEqual(Counter(content_expected), Counter(content_produced), 'trp_link_jitter incorrect')
313
314 1     def test__produce_trp_link_characteristics_link_jitter_with_more_vims(self):
315         """
316         -test with more vims compared to pil, link jitter
317         """
318 1         content_expected = [0, 0, 0, 0, 0, 1200, 1200, 1300, 1300, 1400, 1400, 2300,
319                             2300, 2400, 2400, 3400, 3400, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767]
320 1         nspdf = NsPlacementDataFactory(self._produce_ut_vim_accounts_info(self.vim_accounts_more_vims),
321                                        self._produce_ut_vnf_price_list(),
322                                        nsd=None,
323                                        pil_info=self._populate_pil_info('pil_unittest1_keys.yaml'), pinning=None)
324 1         pil_latencies = nspdf._produce_trp_link_characteristics_data('pil_jitter')
325 1         content_produced = [i for row in pil_latencies for i in row]
326 1         self.assertEqual(Counter(content_expected), Counter(content_produced), 'trp_link_jitter incorrect')
327
328 1     def test__produce_trp_link_characteristics_link_price(self):
329         """
330         -test with full set of vims as in pil
331         """
332 1         content_expected = [0, 0, 0, 0, 12, 12, 13, 13, 14, 14, 23, 23, 24, 24, 34, 34]
333 1         nspdf = NsPlacementDataFactory(self._produce_ut_vim_accounts_info(TestNsPlacementDataFactory.vim_accounts),
334                                        self._produce_ut_vnf_price_list(),
335                                        nsd=None,
336                                        pil_info=self._populate_pil_info('pil_unittest1_keys.yaml'), pinning=None)
337 1         pil_prices = nspdf._produce_trp_link_characteristics_data('pil_price')
338 1         content_produced = [i for row in pil_prices for i in row]
339 1         self.assertEqual(Counter(content_expected), Counter(content_produced), 'invalid trp link prices')
340
341 1     def test__produce_trp_link_characteristics_link_price_with_fewer_vims(self):
342         """
343         -test with fewer vims compared to pil
344         """
345 1         content_expected = [0, 0, 0, 12, 12, 14, 14, 24, 24]
346 1         nspdf = NsPlacementDataFactory(self._produce_ut_vim_accounts_info(self.vim_accounts_fewer_vims),
347                                        self._produce_ut_vnf_price_list(),
348                                        nsd=None,
349                                        pil_info=self._populate_pil_info('pil_unittest1_keys.yaml'), pinning=None)
350 1         pil_prices = nspdf._produce_trp_link_characteristics_data('pil_price')
351 1         content_produced = [i for row in pil_prices for i in row]
352 1         self.assertEqual(Counter(content_expected), Counter(content_produced), 'invalid trp link prices')
353
354 1     def test__produce_trp_link_characteristics_partly_constrained(self):
355 1         content_expected = [0, 0, 0, 0, 32767, 32767, 32767, 32767, 1200, 1200, 1400, 1400, 2400, 2400, 3400, 3400]
356 1         nspdf = NsPlacementDataFactory(self._produce_ut_vim_accounts_info(TestNsPlacementDataFactory.vim_accounts),
357                                        self._produce_ut_vnf_price_list(),
358                                        nsd=None,
359                                        pil_info=self._populate_pil_info('pil_unittest2_keys.yaml'), pinning=None)
360 1         pil_jitter = nspdf._produce_trp_link_characteristics_data('pil_jitter')
361 1         content_produced = [i for row in pil_jitter for i in row]
362 1         self.assertEqual(Counter(content_expected), Counter(content_produced),
363                          'invalid trp link jitter, partly constrained')
364
365 1     def test__produce_vld_desc_partly_constrained(self):
366 1         vld_desc_expected = [{'cp_refs': ['one', 'two'], 'jitter': 30},
367                              {'cp_refs': ['two', 'three'], 'latency': 120}]
368
369 1         nsd = self._get_ut_nsd_from_file('nsd_unittest2.yaml')
370 1         nsd = nsd['nsd']['nsd'][0]
371 1         nspdf = NsPlacementDataFactory(self._produce_ut_vim_accounts_info(TestNsPlacementDataFactory.vim_accounts),
372                                        self._produce_ut_vnf_price_list(),
373                                        nsd=nsd,
374                                        pil_info=None, pinning=None)
375 1         self.assertEqual(vld_desc_expected, nspdf._produce_vld_desc(),
376                          "vld_desc incorrect")
377
378 1     def test__produce_trp_link_characteristics_link_latency_not_yaml_conformant(self):
379         """
380         -test with invalid/corrupt pil configuration file (not yaml conformant)
381         """
382 1         with self.assertRaises(Exception) as e:
383 1             _ = NsPlacementDataFactory(self._produce_ut_vim_accounts_info(TestNsPlacementDataFactory.vim_accounts),
384                                        self._produce_ut_vnf_price_list(),
385                                        nsd=None,
386                                        pil_info=self._populate_pil_info('not_yaml_conformant.yaml'),
387                                        pinning=None)
388 1         self.assertRegex(str(e.exception), r'mapping values are not allowed here.*', "invalid exception content")
389
390 1     def test__produce_trp_link_characteristics_with_invalid_pil_config(self):
391         """
392         -test with invalid/corrupt pil configuration file (missing endpoint)
393         """
394 1         nspdf = NsPlacementDataFactory(self._produce_ut_vim_accounts_info(TestNsPlacementDataFactory.vim_accounts),
395                                        self._produce_ut_vnf_price_list(),
396                                        nsd=None,
397                                        pil_info=self._populate_pil_info('corrupt_pil_endpoints_config_unittest1.yaml'),
398                                        pinning=None)
399 1         with self.assertRaises(Exception) as e:
400 1             _ = nspdf._produce_trp_link_characteristics_data('pil_latency')
401 1         self.assertEqual('list index out of range', str(e.exception), "unexpected exception")
402
403 1     def test__produce_vld_desc_w_instantiate_override(self):
404
405 1         vld_desc_expected = [{'cp_refs': ['one', 'two'], 'latency': 150, 'jitter': 30},
406                              {'cp_refs': ['two', 'three'], 'latency': 90, 'jitter': 30}]
407
408 1         nsd = self._get_ut_nsd_from_file('nsd_unittest_no_vld_constraints.yaml')
409 1         nsd = nsd['nsd']['nsd'][0]
410 1         nspdf = NsPlacementDataFactory(self._produce_ut_vim_accounts_info(TestNsPlacementDataFactory.vim_accounts),
411                                        self._produce_ut_vnf_price_list(),
412                                        nsd=nsd,
413                                        pil_info=None, pinning=None,
414                                        order_constraints=None)
415
416 1         self.assertNotEqual(nspdf._produce_vld_desc(),
417                             vld_desc_expected, "vld_desc incorrect")
418
419 1     def test__produce_vld_desc_nsd_w_instantiate_wo(self):
420         """
421         nsd w/ constraints, instantiate w/o constraints
422         :return:
423         """
424 1         vld_desc_expected = [{'cp_refs': ['one', 'two'], 'latency': 150, 'jitter': 30},
425                              {'cp_refs': ['two', 'three'], 'latency': 90, 'jitter': 30}]
426
427 1         nsd = self._get_ut_nsd_from_file('nsd_unittest3.yaml')
428 1         nsd = nsd['nsd']['nsd'][0]
429 1         nspdf = NsPlacementDataFactory(self._produce_ut_vim_accounts_info(TestNsPlacementDataFactory.vim_accounts),
430                                        self._produce_ut_vnf_price_list(),
431                                        nsd=nsd,
432                                        pil_info=None, pinning=None,
433                                        order_constraints=None)
434
435 1         self.assertEqual(vld_desc_expected, nspdf._produce_vld_desc(),
436                          "vld_desc incorrect")
437
438 1     def test__produce_vld_desc_nsd_w_instantiate_w(self):
439         """
440         nsd w/ constraints, instantiate w/ constraints => override
441         :return:
442         """
443 1         vld_desc_expected = [{'cp_refs': ['one', 'two'], 'latency': 120, 'jitter': 21},
444                              {'cp_refs': ['two', 'three'], 'latency': 121, 'jitter': 22}]
445
446 1         nsd = self._get_ut_nsd_from_file('nsd_unittest3.yaml')
447 1         nsd = nsd['nsd']['nsd'][0]
448 1         nspdf = NsPlacementDataFactory(self._produce_ut_vim_accounts_info(TestNsPlacementDataFactory.vim_accounts),
449                                        self._produce_ut_vnf_price_list(),
450                                        nsd=nsd,
451                                        pil_info=None, pinning=None,
452                                        order_constraints={
453                                            'vld-constraints': [{'id': 'three_vnf_constrained_nsd_vld1',
454                                                                 'link-constraints': {'latency': 120,
455                                                                                      'jitter': 21}},
456                                                                {'id': 'three_vnf_constrained_nsd_vld2',
457                                                                 'link-constraints': {'latency': 121,
458                                                                                      'jitter': 22}}]})
459
460 1         self.assertEqual(vld_desc_expected, nspdf._produce_vld_desc(),
461                          "vld_desc incorrect")
462
463 1     def test__produce_vld_desc_nsd_wo_instantiate_wo(self):
464         """
465         nsd w/o constraints, instantiate w/o constraints = no constraints in model
466         :return:
467         """
468 1         vld_desc_expected = [{'cp_refs': ['one', 'two']},
469                              {'cp_refs': ['two', 'three']}]
470
471 1         nsd = self._get_ut_nsd_from_file('nsd_unittest_no_vld_constraints.yaml')
472 1         nsd = nsd['nsd']['nsd'][0]
473 1         nspdf = NsPlacementDataFactory(self._produce_ut_vim_accounts_info(TestNsPlacementDataFactory.vim_accounts),
474                                        self._produce_ut_vnf_price_list(),
475                                        nsd=nsd,
476                                        pil_info=None, pinning=None,
477                                        order_constraints=None)
478
479 1         self.assertEqual(vld_desc_expected, nspdf._produce_vld_desc(),
480                          "vld_desc incorrect")
481
482 1     def test__produce_vld_desc_nsd_wo_instantiate_w(self):
483         """
484         nsd w/o constraints, instantiate w/ constraints => add constraints
485         :return:
486         """
487 1         vld_desc_expected = [{'cp_refs': ['one', 'two'], 'latency': 140, 'jitter': 41},
488                              {'cp_refs': ['two', 'three'], 'latency': 141, 'jitter': 42}]
489
490 1         nsd = self._get_ut_nsd_from_file('nsd_unittest_no_vld_constraints.yaml')
491 1         nsd = nsd['nsd']['nsd'][0]
492 1         nspdf = NsPlacementDataFactory(self._produce_ut_vim_accounts_info(TestNsPlacementDataFactory.vim_accounts),
493                                        self._produce_ut_vnf_price_list(),
494                                        nsd=nsd,
495                                        pil_info=None, pinning=None,
496                                        order_constraints={
497                                            'vld-constraints': [{'id': 'three_vnf_constrained_nsd_vld1',
498                                                                 'link-constraints': {'latency': 140,
499                                                                                      'jitter': 41}},
500                                                                {'id': 'three_vnf_constrained_nsd_vld2',
501                                                                 'link-constraints': {'latency': 141,
502                                                                                      'jitter': 42}}]})
503
504 1         self.assertEqual(vld_desc_expected, nspdf._produce_vld_desc(),
505                          "vld_desc incorrect")
506
507 1     def test__produce_vld_desc_nsd_wo_instantiate_w_faulty_input(self):
508         """
509         nsd w/o constraints, instantiate w/ constraints => add constraints that can be parsed
510         :return:
511         """
512 1         vld_desc_expected = [{'cp_refs': ['one', 'two']},
513                              {'cp_refs': ['two', 'three'], 'latency': 151}]
514
515 1         nsd = self._get_ut_nsd_from_file('nsd_unittest_no_vld_constraints.yaml')
516 1         nsd = nsd['nsd']['nsd'][0]
517 1         nspdf = NsPlacementDataFactory(self._produce_ut_vim_accounts_info(TestNsPlacementDataFactory.vim_accounts),
518                                        self._produce_ut_vnf_price_list(),
519                                        nsd=nsd,
520                                        pil_info=None, pinning=None,
521                                        order_constraints={'vld-constraints': [{'id': 'not_included_vld',
522                                                                                'misspelled-constraints':
523                                                                                    {'latency': 120,
524                                                                                     'jitter': 20}},
525                                                                               {'id': 'three_vnf_constrained_nsd_vld2',
526                                                                                'link-constraints': {
527                                                                                    'latency': 151}}]})
528
529 1         self.assertEqual(vld_desc_expected, nspdf._produce_vld_desc(),
530                          "vld_desc incorrect")
531
532 1     def test__produce_vld_desc_nsd_wo_instantiate_w_faulty_input_again(self):
533         """
534         nsd w/o constraints, instantiate w/ faulty constraints => add constraints that can be parsed
535         :return:
536         """
537 1         vld_desc_expected = [{'cp_refs': ['one', 'two'], 'jitter': 21},
538                              {'cp_refs': ['two', 'three']}]
539
540 1         nsd = self._get_ut_nsd_from_file('nsd_unittest_no_vld_constraints.yaml')
541 1         nsd = nsd['nsd']['nsd'][0]
542 1         nspdf = NsPlacementDataFactory(self._produce_ut_vim_accounts_info(TestNsPlacementDataFactory.vim_accounts),
543                                        self._produce_ut_vnf_price_list(),
544                                        nsd=nsd,
545                                        pil_info=None, pinning=None,
546                                        order_constraints={
547                                            'vld-constraints': [{'id': 'three_vnf_constrained_nsd_vld1',
548                                                                 'link-constraints': {'delay': 120,
549                                                                                      'jitter': 21}},
550                                                                {'id': 'three_vnf_constrained_nsd_vld2',
551                                                                 'misspelled-constraints': {'latency': 121,
552                                                                                            'jitter': 22}}]})
553
554 1         self.assertEqual(vld_desc_expected, nspdf._produce_vld_desc(),
555                          "vld_desc incorrect")
556
557 1     def test__produce_vld_desc_mgmt_network(self):
558 1         vld_desc_expected = [{'cp_refs': ['1', '2'], 'latency': 120, 'jitter': 20},
559                              {'cp_refs': ['2', '4'], 'latency': 50, 'jitter': 10},
560                              {'cp_refs': ['2', '3'], 'latency': 20, 'jitter': 10}, ]
561
562 1         nsd = self._get_ut_nsd_from_file('test_five_nsd.yaml')
563 1         nsd = nsd['nsd']['nsd'][0]
564 1         nspdf = NsPlacementDataFactory(self._produce_ut_vim_accounts_info(TestNsPlacementDataFactory.vim_accounts),
565                                        self._produce_ut_vnf_price_list(),
566                                        nsd=nsd,
567                                        pil_info=None, pinning=None,
568                                        order_constraints=None)
569
570 1         self.assertEqual(vld_desc_expected, nspdf._produce_vld_desc(), "vld_desc incorrect")
571
572 1     def test__produce_vld_desc_single_vnf_nsd(self):
573 1         vld_desc_expected = []
574
575 1         nsd = self._get_ut_nsd_from_file('nsd_unittest4.yaml')
576 1         nsd = nsd['nsd']['nsd'][0]
577 1         nspdf = NsPlacementDataFactory(self._produce_ut_vim_accounts_info(TestNsPlacementDataFactory.vim_accounts),
578                                        self._produce_ut_vnf_price_list(),
579                                        nsd=nsd,
580                                        pil_info=None, pinning=None,
581                                        order_constraints=None)
582
583 1         self.assertEqual(vld_desc_expected, nspdf._produce_vld_desc(), "vld_desc_incorrect")
584
585 1     def test__produce_vld_desc_slice_nsd(self):
586 1         vld_desc_expected = []
587 1         nsd = self._get_ut_nsd_from_file('slice_hackfest_middle_nsd.yaml')
588 1         nsd = nsd['nsd']['nsd'][0]
589 1         nspdf = NsPlacementDataFactory(self._produce_ut_vim_accounts_info(TestNsPlacementDataFactory.vim_accounts),
590                                        self._produce_ut_vnf_price_list(),
591                                        nsd=nsd,
592                                        pil_info=None, pinning=None,
593                                        order_constraints=None)
594
595 1         self.assertEqual(vld_desc_expected, nspdf._produce_vld_desc(), "vld_desc_incorrect")
596
597 1     def test__produce_vld_desc(self):
598         """
599
600         :return:
601         """
602 1         vld_desc_expected = [{'cp_refs': ['one', 'two'], 'latency': 150, 'jitter': 30},
603                              {'cp_refs': ['two', 'three'], 'latency': 90, 'jitter': 30}]
604
605 1         nsd = self._get_ut_nsd_from_file('nsd_unittest3.yaml')
606 1         nsd = nsd['nsd']['nsd'][0]
607 1         nspdf = NsPlacementDataFactory(self._produce_ut_vim_accounts_info(TestNsPlacementDataFactory.vim_accounts),
608                                        self._produce_ut_vnf_price_list(),
609                                        nsd=nsd,
610                                        pil_info=None, pinning=None,
611                                        order_constraints=None)
612
613 1         self.assertEqual(vld_desc_expected, nspdf._produce_vld_desc(), "vld_desc incorrect")
614
615 1     def test__produce_ns_desc(self):
616         """
617         ToDo
618         - price list sheet with more vims than associated with session
619         - price list sheet with fewer vims than associated with session
620         - nsd with different vndfd-id-refs
621         - fault case scenarios with non-existing vims, non-existing vnfds
622         """
623 1         nsd = self._get_ut_nsd_from_file('nsd_unittest3.yaml')
624 1         nsd = nsd['nsd']['nsd'][0]
625 1         nspdf = NsPlacementDataFactory(self._produce_ut_vim_accounts_info(TestNsPlacementDataFactory.vim_accounts),
626                                        self._produce_ut_vnf_price_list(),
627                                        nsd=nsd,
628                                        pil_info=None,
629                                        pinning=None)
630
631 1         ns_desc = nspdf._produce_ns_desc()
632         # check that all expected member-vnf-index are present
633 1         vnfs = [e['vnf_id'] for e in ns_desc]
634 1         self.assertEqual(Counter(['one', 'two', 'three']), Counter(vnfs), 'vnf_id invalid')
635
636 1         expected_keys = ['vnf_id', 'vnf_price_per_vim']
637 1         for e in ns_desc:
638             # check that vnf_price_per_vim has proper values
639 1             self.assertEqual(Counter([5, 10, 30, 30]), Counter(e['vnf_price_per_vim']), 'vnf_price_per_vim invalid')
640             # check that no pinning directives included
641 1             self.assertEqual(Counter(expected_keys), Counter(e.keys()), 'pinning directive misplaced')
642
643 1     def test__produce_ns_desc_with_more_vims(self):
644 1         nsd = self._get_ut_nsd_from_file('nsd_unittest1.yaml')
645 1         nsd = nsd['nsd']['nsd'][0]
646 1         nspdf = NsPlacementDataFactory(self._produce_ut_vim_accounts_info(self.vim_accounts_more_vims),
647                                        self._produce_ut_vnf_test_price_list('vnf_price_list_more_vims.yaml'),
648                                        nsd=nsd,
649                                        pil_info=None,
650                                        pinning=None)
651
652 1         ns_desc = nspdf._produce_ns_desc()
653         # check that all expected member-vnf-index are present
654 1         vnfs = [e['vnf_id'] for e in ns_desc]
655 1         self.assertEqual(Counter({'1': 1, '2': 1, '3': 1}), Counter(vnfs), 'vnf_id invalid')
656
657 1         expected_keys = ['vnf_id', 'vnf_price_per_vim']
658 1         for e in ns_desc:
659             # check that vnf_price_per_vim has proper values
660 1             self.assertEqual(Counter([5, 10, 30, 30, 3]), Counter(e['vnf_price_per_vim']), 'vnf_price_per_vim invalid')
661             # check that no pinning directives included
662 1             self.assertEqual(Counter(expected_keys), Counter(e.keys()), 'pinning directive misplaced')
663
664 1     def test__produce_ns_desc_with_fewer_vims(self):
665 1         nsd = self._get_ut_nsd_from_file('nsd_unittest1.yaml')
666 1         nsd = nsd['nsd']['nsd'][0]
667 1         nspdf = NsPlacementDataFactory(self._produce_ut_vim_accounts_info(self.vim_accounts_fewer_vims),
668                                        self._produce_ut_vnf_price_list(),
669                                        nsd=nsd,
670                                        pil_info=None,
671                                        pinning=None)
672
673 1         ns_desc = nspdf._produce_ns_desc()
674         # check that all expected member-vnf-index are present
675 1         vnfs = [e['vnf_id'] for e in ns_desc]
676 1         self.assertEqual(Counter({'1': 1, '2': 1, '3': 1}), Counter(vnfs), 'vnf_id invalid')
677
678 1         expected_keys = ['vnf_id', 'vnf_price_per_vim']
679 1         for e in ns_desc:
680             # check that vnf_price_per_vim has proper values
681 1             self.assertEqual(Counter([5, 10, 30]), Counter(e['vnf_price_per_vim']), 'vnf_price_per_vim invalid')
682             # check that no pinning directives included
683 1             self.assertEqual(Counter(expected_keys), Counter(e.keys()), 'pinning directive misplaced')
684
685 1     def test__produce_ns_desc_w_pinning(self):
686 1         nsd = self._get_ut_nsd_from_file('nsd_unittest3.yaml')
687 1         nsd = nsd['nsd']['nsd'][0]
688 1         pinning = [{'member-vnf-index': 'two', 'vimAccountId': '331ffdec-44a8-4707-94a1-af7a292d9735'}]
689 1         nspdf = NsPlacementDataFactory(self._produce_ut_vim_accounts_info(TestNsPlacementDataFactory.vim_accounts),
690                                        self._produce_ut_vnf_price_list(),
691                                        nsd=nsd,
692                                        pil_info=None,
693                                        pinning=pinning)
694 1         ns_desc = nspdf._produce_ns_desc()
695         # check that all expected member-vnf-index are present
696 1         vnfs = [e['vnf_id'] for e in ns_desc]
697 1         self.assertEqual(Counter(['one', 'three', 'two']), Counter(vnfs), 'vnf_id invalid')
698
699 1         for e in ns_desc:
700             # check that vnf_price_per_vim has proper values
701 1             self.assertEqual(Counter([5, 10, 30, 30]), Counter(e['vnf_price_per_vim']), 'vnf_price_per_vim invalid')
702             # check that member-vnf-index 2 is pinned correctly
703 1             if e['vnf_id'] == 'two':
704 1                 self.assertTrue('vim_account' in e.keys(), 'missing pinning directive')
705 1                 self.assertTrue(pinning[0]['vimAccountId'] == e['vim_account'][3:].replace('_', '-'),
706                                 'invalid pinning vim-account')
707             else:
708 1                 self.assertTrue('vim-account' not in e.keys(), 'pinning directive misplaced')
709
710 1     @mock.patch.object(NsPlacementDataFactory, '_produce_trp_link_characteristics_data')
711 1     @mock.patch.object(NsPlacementDataFactory, '_produce_vld_desc')
712 1     @mock.patch.object(NsPlacementDataFactory, '_produce_ns_desc')
713     def test_create_ns_placement_data_wo_order(self, mock_prd_ns_desc, mock_prd_vld_desc, mock_prd_trp_link_char):
714         """
715         :return:
716         """
717 1         vim_accounts_expected = [v.replace('-', '_') for v in ['vim92b056a7-38f5-438d-b8ee-3f93b3531f87',
718                                                                'vim6618d412-d7fc-4eb0-a6f8-d2c258e0e900',
719                                                                'vim331ffdec-44a8-4707-94a1-af7a292d9735',
720                                                                'vimeda92f47-29b9-4007-9709-c1833dbfbe31']]
721
722 1         nsd = self._get_ut_nsd_from_file('nsd_unittest3.yaml')
723 1         nsd = nsd['nsd']['nsd'][0]
724 1         nspdf = NsPlacementDataFactory(self._produce_ut_vim_accounts_info(TestNsPlacementDataFactory.vim_accounts),
725                                        self._produce_ut_vnf_price_list(),
726                                        nsd=nsd,
727                                        pil_info=self._populate_pil_info('pil_unittest1.yaml'),
728                                        pinning=None,
729                                        order_constraints=None)
730 1         nspd = nspdf.create_ns_placement_data()
731 1         self.assertEqual(Counter(vim_accounts_expected), Counter(nspd['vim_accounts']),
732                          "vim_accounts incorrect")
733         # mock1.assert_called_once() Note for python > 3.5
734 1         self.assertTrue(mock_prd_ns_desc.called, '_produce_ns_desc not called')
735         # mock2.assert_called_once() Note for python > 3.5
736 1         self.assertTrue(mock_prd_vld_desc.called, ' _produce_vld_desc not called')
737 1         mock_prd_trp_link_char.assert_has_calls([call('pil_latency'), call('pil_jitter'), call('pil_price')])
738
739 1         regexps = [r"\{.*\}", r".*'file':.*mznplacement.py", r".*'time':.*datetime.datetime\(.*\)"]
740 1         generator_data = str(nspd['generator_data'])
741 1         for regex in regexps:
742 1             self.assertRegex(generator_data, regex, "generator data invalid")
743
744 1     @mock.patch.object(NsPlacementDataFactory, '_produce_trp_link_characteristics_data')
745 1     @mock.patch.object(NsPlacementDataFactory, '_produce_vld_desc')
746 1     @mock.patch.object(NsPlacementDataFactory, '_produce_ns_desc')
747     def test_create_ns_placement_data_w_order(self, mock_prd_ns_desc, mock_prd_vld_desc,
748                                               mock_prd_trp_link_char):
749         """
750         :return:
751         """
752 1         vim_accounts_expected = [v.replace('-', '_') for v in ['vim92b056a7-38f5-438d-b8ee-3f93b3531f87',
753                                                                'vim6618d412-d7fc-4eb0-a6f8-d2c258e0e900',
754                                                                'vim331ffdec-44a8-4707-94a1-af7a292d9735',
755                                                                'vimeda92f47-29b9-4007-9709-c1833dbfbe31']]
756
757 1         nsd = self._get_ut_nsd_from_file('nsd_unittest3.yaml')
758 1         nsd = nsd['nsd']['nsd'][0]
759 1         nspdf = NsPlacementDataFactory(self._produce_ut_vim_accounts_info(TestNsPlacementDataFactory.vim_accounts),
760                                        self._produce_ut_vnf_price_list(),
761                                        nsd=nsd,
762                                        pil_info=self._populate_pil_info('pil_unittest1.yaml'),
763                                        pinning=None,
764                                        order_constraints={
765                                            'vld-constraints': [{'id': 'three_vnf_constrained_nsd_vld1',
766                                                                 'link-constraints': {'latency': 120,
767                                                                                      'jitter': 21}},
768                                                                {'id': 'three_vnf_constrained_nsd_vld2',
769                                                                 'link-constraints': {'latency': 121,
770                                                                                      'jitter': 22}}]}
771                                        )
772 1         nspd = nspdf.create_ns_placement_data()
773 1         self.assertEqual(Counter(vim_accounts_expected), Counter(nspd['vim_accounts']),
774                          "vim_accounts incorrect")
775         # mock1.assert_called_once() Note for python > 3.5
776 1         self.assertTrue(mock_prd_ns_desc.called, '_produce_ns_desc not called')
777         # mock2.assert_called_once() Note for python > 3.5
778 1         self.assertTrue(mock_prd_vld_desc.called, ' _produce_vld_desc not called')
779 1         mock_prd_trp_link_char.assert_has_calls([call('pil_latency'), call('pil_jitter'), call('pil_price')])
780
781 1         regexps = [r"\{.*\}", r".*'file':.*mznplacement.py", r".*'time':.*datetime.datetime\(.*\)"]
782 1         generator_data = str(nspd['generator_data'])
783 1         for regex in regexps:
784 1             self.assertRegex(generator_data, regex, "generator data invalid")
785
786
787 1 if __name__ == "__main__":
788 0     if __name__ == '__main__':
789 0         unittest.main()