1 # Copyright 2020 ArctosLabs Scandinavia AB
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
7 # http://www.apache.org/licenses/LICENSE-2.0
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
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
17 from collections
import Counter
18 from pathlib
import Path
19 from unittest
import TestCase
, mock
20 from unittest
.mock
import call
24 from osm_pla
.placement
.mznplacement
import NsPlacementDataFactory
27 class TestNsPlacementDataFactory(TestCase
):
28 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"}]
69 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",
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"}]
106 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"}]
167 def _produce_ut_vim_accounts_info(self
, vim_accounts
):
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
172 return {_
['name']: _
['_id'] for _
in vim_accounts
}
174 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 path_component
= '/osm_pla/test/'
178 real_path
= os
.path
.realpath(file)
179 if path_component
not in real_path
:
180 return os
.path
.dirname(real_path
) + path_component
+ os
.path
.basename(real_path
)
184 def _populate_pil_info(self
, file):
186 Note str(Path()) is a 3.5 thing
188 with
open(str(Path(self
._adjust
_path
(file)))) as pp_fd
:
189 test_data
= yaml
.safe_load_all(pp_fd
)
190 return next(test_data
)
192 def _get_ut_nsd_from_file(self
, nsd_file_name
):
194 creates the structure representing the nsd.
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
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.
206 with
open(str(Path(self
._adjust
_path
(nsd_file_name
)))) as nsd_fd
:
207 test_data
= yaml
.safe_load_all(nsd_fd
)
208 return next(test_data
)
210 def _produce_ut_vnf_price_list(self
):
211 price_list_file
= "vnf_price_list.yaml"
212 with
open(str(Path(self
._adjust
_path
(price_list_file
)))) as pl_fd
:
213 price_list_data
= yaml
.safe_load_all(pl_fd
)
214 return {i
['vnfd']: {i1
['vim_name']: i1
['price'] for i1
in i
['prices']} for i
in next(price_list_data
)}
216 def _produce_ut_vnf_test_price_list(self
, price_list
):
217 price_list_file
= price_list
218 with
open(str(Path(self
._adjust
_path
(price_list_file
)))) as pl_fd
:
219 price_list_data
= yaml
.safe_load_all(pl_fd
)
220 return {i
['vnfd']: {i1
['vim_name']: i1
['price'] for i1
in i
['prices']} for i
in next(price_list_data
)}
222 def test__produce_trp_link_characteristics_link_latency_with_more_vims(self
):
224 -test with more(other) vims compared to pil
226 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 nspdf
= NsPlacementDataFactory(
229 self
._produce
_ut
_vim
_accounts
_info
(TestNsPlacementDataFactory
.vim_accounts_more_vims
),
230 self
._produce
_ut
_vnf
_price
_list
(),
232 pil_info
=self
._populate
_pil
_info
('pil_unittest1_keys.yaml'),
234 pil_latencies
= nspdf
._produce
_trp
_link
_characteristics
_data
('pil_latency')
235 content_produced
= [i
for row
in pil_latencies
for i
in row
]
236 self
.assertEqual(Counter(content_expected
), Counter(content_produced
), 'trp_link_latency incorrect')
238 def test__produce_trp_link_characteristics_link_latency_with_fewer_vims(self
):
240 -test with fewer vims compared to pil
243 content_expected
= [0, 0, 0, 120, 120, 140, 140, 240, 240]
244 nspdf
= NsPlacementDataFactory(
245 self
._produce
_ut
_vim
_accounts
_info
(TestNsPlacementDataFactory
.vim_accounts_fewer_vims
),
246 self
._produce
_ut
_vnf
_price
_list
(),
248 pil_info
=self
._populate
_pil
_info
('pil_unittest1_keys.yaml'),
250 pil_latencies
= nspdf
._produce
_trp
_link
_characteristics
_data
('pil_latency')
251 content_produced
= [i
for row
in pil_latencies
for i
in row
]
252 self
.assertEqual(Counter(content_expected
), Counter(content_produced
), 'trp_link_latency incorrect')
254 def test__produce_trp_link_characteristic_not_supported(self
):
256 - test with non-supported characteristic
258 nspdf
= NsPlacementDataFactory(self
._produce
_ut
_vim
_accounts
_info
(TestNsPlacementDataFactory
.vim_accounts
),
259 self
._produce
_ut
_vnf
_price
_list
(),
261 pil_info
=self
._populate
_pil
_info
('pil_unittest1.yaml'), pinning
=None)
263 with self
.assertRaises(Exception) as e
:
264 nspdf
._produce
_trp
_link
_characteristics
_data
('test_no_support')
265 self
.assertRegex(str(e
.exception
), r
'characteristic.*not supported', "invalid exception content")
267 def test__produce_trp_link_characteristics_link_latency(self
):
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
277 content_expected
= [0, 0, 0, 0, 120, 120, 130, 130, 140, 140, 230, 230, 240, 240, 340, 340]
279 nspdf
= NsPlacementDataFactory(self
._produce
_ut
_vim
_accounts
_info
(TestNsPlacementDataFactory
.vim_accounts
),
280 self
._produce
_ut
_vnf
_price
_list
(),
282 pil_info
=self
._populate
_pil
_info
('pil_unittest1_keys.yaml'), pinning
=None)
283 pil_latencies
= nspdf
._produce
_trp
_link
_characteristics
_data
('pil_latency')
284 content_produced
= [i
for row
in pil_latencies
for i
in row
]
285 self
.assertEqual(Counter(content_expected
), Counter(content_produced
), 'trp_link_latency incorrect')
287 def test__produce_trp_link_characteristics_link_jitter(self
):
289 -test with full set of vims as in pil
291 content_expected
= [0, 0, 0, 0, 1200, 1200, 1300, 1300, 1400, 1400, 2300, 2300, 2400, 2400, 3400, 3400]
293 nspdf
= NsPlacementDataFactory(self
._produce
_ut
_vim
_accounts
_info
(TestNsPlacementDataFactory
.vim_accounts
),
294 self
._produce
_ut
_vnf
_price
_list
(),
296 pil_info
=self
._populate
_pil
_info
('pil_unittest1_keys.yaml'), pinning
=None)
297 pil_jitter
= nspdf
._produce
_trp
_link
_characteristics
_data
('pil_jitter')
298 content_produced
= [i
for row
in pil_jitter
for i
in row
]
299 self
.assertEqual(Counter(content_expected
), Counter(content_produced
), 'trp_link_jitter incorrect')
301 def test__produce_trp_link_characteristics_link_jitter_with_fewer_vims(self
):
303 -test with fewer vims compared to pil, link jitter
305 content_expected
= [0, 0, 0, 1200, 1200, 1400, 1400, 2400, 2400]
306 nspdf
= NsPlacementDataFactory(self
._produce
_ut
_vim
_accounts
_info
(self
.vim_accounts_fewer_vims
),
307 self
._produce
_ut
_vnf
_price
_list
(),
309 pil_info
=self
._populate
_pil
_info
('pil_unittest1_keys.yaml'), pinning
=None)
310 pil_latencies
= nspdf
._produce
_trp
_link
_characteristics
_data
('pil_jitter')
311 content_produced
= [i
for row
in pil_latencies
for i
in row
]
312 self
.assertEqual(Counter(content_expected
), Counter(content_produced
), 'trp_link_jitter incorrect')
314 def test__produce_trp_link_characteristics_link_jitter_with_more_vims(self
):
316 -test with more vims compared to pil, link jitter
318 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 nspdf
= NsPlacementDataFactory(self
._produce
_ut
_vim
_accounts
_info
(self
.vim_accounts_more_vims
),
321 self
._produce
_ut
_vnf
_price
_list
(),
323 pil_info
=self
._populate
_pil
_info
('pil_unittest1_keys.yaml'), pinning
=None)
324 pil_latencies
= nspdf
._produce
_trp
_link
_characteristics
_data
('pil_jitter')
325 content_produced
= [i
for row
in pil_latencies
for i
in row
]
326 self
.assertEqual(Counter(content_expected
), Counter(content_produced
), 'trp_link_jitter incorrect')
328 def test__produce_trp_link_characteristics_link_price(self
):
330 -test with full set of vims as in pil
332 content_expected
= [0, 0, 0, 0, 12, 12, 13, 13, 14, 14, 23, 23, 24, 24, 34, 34]
333 nspdf
= NsPlacementDataFactory(self
._produce
_ut
_vim
_accounts
_info
(TestNsPlacementDataFactory
.vim_accounts
),
334 self
._produce
_ut
_vnf
_price
_list
(),
336 pil_info
=self
._populate
_pil
_info
('pil_unittest1_keys.yaml'), pinning
=None)
337 pil_prices
= nspdf
._produce
_trp
_link
_characteristics
_data
('pil_price')
338 content_produced
= [i
for row
in pil_prices
for i
in row
]
339 self
.assertEqual(Counter(content_expected
), Counter(content_produced
), 'invalid trp link prices')
341 def test__produce_trp_link_characteristics_link_price_with_fewer_vims(self
):
343 -test with fewer vims compared to pil
345 content_expected
= [0, 0, 0, 12, 12, 14, 14, 24, 24]
346 nspdf
= NsPlacementDataFactory(self
._produce
_ut
_vim
_accounts
_info
(self
.vim_accounts_fewer_vims
),
347 self
._produce
_ut
_vnf
_price
_list
(),
349 pil_info
=self
._populate
_pil
_info
('pil_unittest1_keys.yaml'), pinning
=None)
350 pil_prices
= nspdf
._produce
_trp
_link
_characteristics
_data
('pil_price')
351 content_produced
= [i
for row
in pil_prices
for i
in row
]
352 self
.assertEqual(Counter(content_expected
), Counter(content_produced
), 'invalid trp link prices')
354 def test__produce_trp_link_characteristics_partly_constrained(self
):
355 content_expected
= [0, 0, 0, 0, 32767, 32767, 32767, 32767, 1200, 1200, 1400, 1400, 2400, 2400, 3400, 3400]
356 nspdf
= NsPlacementDataFactory(self
._produce
_ut
_vim
_accounts
_info
(TestNsPlacementDataFactory
.vim_accounts
),
357 self
._produce
_ut
_vnf
_price
_list
(),
359 pil_info
=self
._populate
_pil
_info
('pil_unittest2_keys.yaml'), pinning
=None)
360 pil_jitter
= nspdf
._produce
_trp
_link
_characteristics
_data
('pil_jitter')
361 content_produced
= [i
for row
in pil_jitter
for i
in row
]
362 self
.assertEqual(Counter(content_expected
), Counter(content_produced
),
363 'invalid trp link jitter, partly constrained')
365 def test__produce_vld_desc_partly_constrained(self
):
366 vld_desc_expected
= [{'cp_refs': ['one', 'two'], 'jitter': 30},
367 {'cp_refs': ['two', 'three'], 'latency': 120}]
369 nsd
= self
._get
_ut
_nsd
_from
_file
('nsd_unittest2.yaml')
370 nsd
= nsd
['nsd']['nsd'][0]
371 nspdf
= NsPlacementDataFactory(self
._produce
_ut
_vim
_accounts
_info
(TestNsPlacementDataFactory
.vim_accounts
),
372 self
._produce
_ut
_vnf
_price
_list
(),
374 pil_info
=None, pinning
=None)
375 self
.assertEqual(vld_desc_expected
, nspdf
._produce
_vld
_desc
(),
376 "vld_desc incorrect")
378 def test__produce_trp_link_characteristics_link_latency_not_yaml_conformant(self
):
380 -test with invalid/corrupt pil configuration file (not yaml conformant)
382 with self
.assertRaises(Exception) as e
:
383 _
= NsPlacementDataFactory(self
._produce
_ut
_vim
_accounts
_info
(TestNsPlacementDataFactory
.vim_accounts
),
384 self
._produce
_ut
_vnf
_price
_list
(),
386 pil_info
=self
._populate
_pil
_info
('not_yaml_conformant.yaml'),
388 self
.assertRegex(str(e
.exception
), r
'mapping values are not allowed here.*', "invalid exception content")
390 def test__produce_trp_link_characteristics_with_invalid_pil_config(self
):
392 -test with invalid/corrupt pil configuration file (missing endpoint)
394 nspdf
= NsPlacementDataFactory(self
._produce
_ut
_vim
_accounts
_info
(TestNsPlacementDataFactory
.vim_accounts
),
395 self
._produce
_ut
_vnf
_price
_list
(),
397 pil_info
=self
._populate
_pil
_info
('corrupt_pil_endpoints_config_unittest1.yaml'),
399 with self
.assertRaises(Exception) as e
:
400 _
= nspdf
._produce
_trp
_link
_characteristics
_data
('pil_latency')
401 self
.assertEqual('list index out of range', str(e
.exception
), "unexpected exception")
403 def test__produce_vld_desc_w_instantiate_override(self
):
405 vld_desc_expected
= [{'cp_refs': ['one', 'two'], 'latency': 150, 'jitter': 30},
406 {'cp_refs': ['two', 'three'], 'latency': 90, 'jitter': 30}]
408 nsd
= self
._get
_ut
_nsd
_from
_file
('nsd_unittest_no_vld_constraints.yaml')
409 nsd
= nsd
['nsd']['nsd'][0]
410 nspdf
= NsPlacementDataFactory(self
._produce
_ut
_vim
_accounts
_info
(TestNsPlacementDataFactory
.vim_accounts
),
411 self
._produce
_ut
_vnf
_price
_list
(),
413 pil_info
=None, pinning
=None,
414 order_constraints
=None)
416 self
.assertNotEqual(nspdf
._produce
_vld
_desc
(),
417 vld_desc_expected
, "vld_desc incorrect")
419 def test__produce_vld_desc_nsd_w_instantiate_wo(self
):
421 nsd w/ constraints, instantiate w/o constraints
424 vld_desc_expected
= [{'cp_refs': ['one', 'two'], 'latency': 150, 'jitter': 30},
425 {'cp_refs': ['two', 'three'], 'latency': 90, 'jitter': 30}]
427 nsd
= self
._get
_ut
_nsd
_from
_file
('nsd_unittest3.yaml')
428 nsd
= nsd
['nsd']['nsd'][0]
429 nspdf
= NsPlacementDataFactory(self
._produce
_ut
_vim
_accounts
_info
(TestNsPlacementDataFactory
.vim_accounts
),
430 self
._produce
_ut
_vnf
_price
_list
(),
432 pil_info
=None, pinning
=None,
433 order_constraints
=None)
435 self
.assertEqual(vld_desc_expected
, nspdf
._produce
_vld
_desc
(),
436 "vld_desc incorrect")
438 def test__produce_vld_desc_nsd_w_instantiate_w(self
):
440 nsd w/ constraints, instantiate w/ constraints => override
443 vld_desc_expected
= [{'cp_refs': ['one', 'two'], 'latency': 120, 'jitter': 21},
444 {'cp_refs': ['two', 'three'], 'latency': 121, 'jitter': 22}]
446 nsd
= self
._get
_ut
_nsd
_from
_file
('nsd_unittest3.yaml')
447 nsd
= nsd
['nsd']['nsd'][0]
448 nspdf
= NsPlacementDataFactory(self
._produce
_ut
_vim
_accounts
_info
(TestNsPlacementDataFactory
.vim_accounts
),
449 self
._produce
_ut
_vnf
_price
_list
(),
451 pil_info
=None, pinning
=None,
453 'vld-constraints': [{'id': 'three_vnf_constrained_nsd_vld1',
454 'link-constraints': {'latency': 120,
456 {'id': 'three_vnf_constrained_nsd_vld2',
457 'link-constraints': {'latency': 121,
460 self
.assertEqual(vld_desc_expected
, nspdf
._produce
_vld
_desc
(),
461 "vld_desc incorrect")
463 def test__produce_vld_desc_nsd_wo_instantiate_wo(self
):
465 nsd w/o constraints, instantiate w/o constraints = no constraints in model
468 vld_desc_expected
= [{'cp_refs': ['one', 'two']},
469 {'cp_refs': ['two', 'three']}]
471 nsd
= self
._get
_ut
_nsd
_from
_file
('nsd_unittest_no_vld_constraints.yaml')
472 nsd
= nsd
['nsd']['nsd'][0]
473 nspdf
= NsPlacementDataFactory(self
._produce
_ut
_vim
_accounts
_info
(TestNsPlacementDataFactory
.vim_accounts
),
474 self
._produce
_ut
_vnf
_price
_list
(),
476 pil_info
=None, pinning
=None,
477 order_constraints
=None)
479 self
.assertEqual(vld_desc_expected
, nspdf
._produce
_vld
_desc
(),
480 "vld_desc incorrect")
482 def test__produce_vld_desc_nsd_wo_instantiate_w(self
):
484 nsd w/o constraints, instantiate w/ constraints => add constraints
487 vld_desc_expected
= [{'cp_refs': ['one', 'two'], 'latency': 140, 'jitter': 41},
488 {'cp_refs': ['two', 'three'], 'latency': 141, 'jitter': 42}]
490 nsd
= self
._get
_ut
_nsd
_from
_file
('nsd_unittest_no_vld_constraints.yaml')
491 nsd
= nsd
['nsd']['nsd'][0]
492 nspdf
= NsPlacementDataFactory(self
._produce
_ut
_vim
_accounts
_info
(TestNsPlacementDataFactory
.vim_accounts
),
493 self
._produce
_ut
_vnf
_price
_list
(),
495 pil_info
=None, pinning
=None,
497 'vld-constraints': [{'id': 'three_vnf_constrained_nsd_vld1',
498 'link-constraints': {'latency': 140,
500 {'id': 'three_vnf_constrained_nsd_vld2',
501 'link-constraints': {'latency': 141,
504 self
.assertEqual(vld_desc_expected
, nspdf
._produce
_vld
_desc
(),
505 "vld_desc incorrect")
507 def test__produce_vld_desc_nsd_wo_instantiate_w_faulty_input(self
):
509 nsd w/o constraints, instantiate w/ constraints => add constraints that can be parsed
512 vld_desc_expected
= [{'cp_refs': ['one', 'two']},
513 {'cp_refs': ['two', 'three'], 'latency': 151}]
515 nsd
= self
._get
_ut
_nsd
_from
_file
('nsd_unittest_no_vld_constraints.yaml')
516 nsd
= nsd
['nsd']['nsd'][0]
517 nspdf
= NsPlacementDataFactory(self
._produce
_ut
_vim
_accounts
_info
(TestNsPlacementDataFactory
.vim_accounts
),
518 self
._produce
_ut
_vnf
_price
_list
(),
520 pil_info
=None, pinning
=None,
521 order_constraints
={'vld-constraints': [{'id': 'not_included_vld',
522 'misspelled-constraints':
525 {'id': 'three_vnf_constrained_nsd_vld2',
526 'link-constraints': {
529 self
.assertEqual(vld_desc_expected
, nspdf
._produce
_vld
_desc
(),
530 "vld_desc incorrect")
532 def test__produce_vld_desc_nsd_wo_instantiate_w_faulty_input_again(self
):
534 nsd w/o constraints, instantiate w/ faulty constraints => add constraints that can be parsed
537 vld_desc_expected
= [{'cp_refs': ['one', 'two'], 'jitter': 21},
538 {'cp_refs': ['two', 'three']}]
540 nsd
= self
._get
_ut
_nsd
_from
_file
('nsd_unittest_no_vld_constraints.yaml')
541 nsd
= nsd
['nsd']['nsd'][0]
542 nspdf
= NsPlacementDataFactory(self
._produce
_ut
_vim
_accounts
_info
(TestNsPlacementDataFactory
.vim_accounts
),
543 self
._produce
_ut
_vnf
_price
_list
(),
545 pil_info
=None, pinning
=None,
547 'vld-constraints': [{'id': 'three_vnf_constrained_nsd_vld1',
548 'link-constraints': {'delay': 120,
550 {'id': 'three_vnf_constrained_nsd_vld2',
551 'misspelled-constraints': {'latency': 121,
554 self
.assertEqual(vld_desc_expected
, nspdf
._produce
_vld
_desc
(),
555 "vld_desc incorrect")
557 def test__produce_vld_desc_mgmt_network(self
):
558 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}, ]
562 nsd
= self
._get
_ut
_nsd
_from
_file
('test_five_nsd.yaml')
563 nsd
= nsd
['nsd']['nsd'][0]
564 nspdf
= NsPlacementDataFactory(self
._produce
_ut
_vim
_accounts
_info
(TestNsPlacementDataFactory
.vim_accounts
),
565 self
._produce
_ut
_vnf
_price
_list
(),
567 pil_info
=None, pinning
=None,
568 order_constraints
=None)
570 self
.assertEqual(vld_desc_expected
, nspdf
._produce
_vld
_desc
(), "vld_desc incorrect")
572 def test__produce_vld_desc_single_vnf_nsd(self
):
573 vld_desc_expected
= []
575 nsd
= self
._get
_ut
_nsd
_from
_file
('nsd_unittest4.yaml')
576 nsd
= nsd
['nsd']['nsd'][0]
577 nspdf
= NsPlacementDataFactory(self
._produce
_ut
_vim
_accounts
_info
(TestNsPlacementDataFactory
.vim_accounts
),
578 self
._produce
_ut
_vnf
_price
_list
(),
580 pil_info
=None, pinning
=None,
581 order_constraints
=None)
583 self
.assertEqual(vld_desc_expected
, nspdf
._produce
_vld
_desc
(), "vld_desc_incorrect")
585 def test__produce_vld_desc_slice_nsd(self
):
586 vld_desc_expected
= []
587 nsd
= self
._get
_ut
_nsd
_from
_file
('slice_hackfest_middle_nsd.yaml')
588 nsd
= nsd
['nsd']['nsd'][0]
589 nspdf
= NsPlacementDataFactory(self
._produce
_ut
_vim
_accounts
_info
(TestNsPlacementDataFactory
.vim_accounts
),
590 self
._produce
_ut
_vnf
_price
_list
(),
592 pil_info
=None, pinning
=None,
593 order_constraints
=None)
595 self
.assertEqual(vld_desc_expected
, nspdf
._produce
_vld
_desc
(), "vld_desc_incorrect")
597 def test__produce_vld_desc(self
):
602 vld_desc_expected
= [{'cp_refs': ['one', 'two'], 'latency': 150, 'jitter': 30},
603 {'cp_refs': ['two', 'three'], 'latency': 90, 'jitter': 30}]
605 nsd
= self
._get
_ut
_nsd
_from
_file
('nsd_unittest3.yaml')
606 nsd
= nsd
['nsd']['nsd'][0]
607 nspdf
= NsPlacementDataFactory(self
._produce
_ut
_vim
_accounts
_info
(TestNsPlacementDataFactory
.vim_accounts
),
608 self
._produce
_ut
_vnf
_price
_list
(),
610 pil_info
=None, pinning
=None,
611 order_constraints
=None)
613 self
.assertEqual(vld_desc_expected
, nspdf
._produce
_vld
_desc
(), "vld_desc incorrect")
615 def test__produce_ns_desc(self
):
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
623 nsd
= self
._get
_ut
_nsd
_from
_file
('nsd_unittest3.yaml')
624 nsd
= nsd
['nsd']['nsd'][0]
625 nspdf
= NsPlacementDataFactory(self
._produce
_ut
_vim
_accounts
_info
(TestNsPlacementDataFactory
.vim_accounts
),
626 self
._produce
_ut
_vnf
_price
_list
(),
631 ns_desc
= nspdf
._produce
_ns
_desc
()
632 # check that all expected member-vnf-index are present
633 vnfs
= [e
['vnf_id'] for e
in ns_desc
]
634 self
.assertEqual(Counter(['one', 'two', 'three']), Counter(vnfs
), 'vnf_id invalid')
636 expected_keys
= ['vnf_id', 'vnf_price_per_vim']
638 # check that vnf_price_per_vim has proper values
639 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 self
.assertEqual(Counter(expected_keys
), Counter(e
.keys()), 'pinning directive misplaced')
643 def test__produce_ns_desc_with_more_vims(self
):
644 nsd
= self
._get
_ut
_nsd
_from
_file
('nsd_unittest1.yaml')
645 nsd
= nsd
['nsd']['nsd'][0]
646 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'),
652 ns_desc
= nspdf
._produce
_ns
_desc
()
653 # check that all expected member-vnf-index are present
654 vnfs
= [e
['vnf_id'] for e
in ns_desc
]
655 self
.assertEqual(Counter({'1': 1, '2': 1, '3': 1}), Counter(vnfs
), 'vnf_id invalid')
657 expected_keys
= ['vnf_id', 'vnf_price_per_vim']
659 # check that vnf_price_per_vim has proper values
660 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 self
.assertEqual(Counter(expected_keys
), Counter(e
.keys()), 'pinning directive misplaced')
664 def test__produce_ns_desc_with_fewer_vims(self
):
665 nsd
= self
._get
_ut
_nsd
_from
_file
('nsd_unittest1.yaml')
666 nsd
= nsd
['nsd']['nsd'][0]
667 nspdf
= NsPlacementDataFactory(self
._produce
_ut
_vim
_accounts
_info
(self
.vim_accounts_fewer_vims
),
668 self
._produce
_ut
_vnf
_price
_list
(),
673 ns_desc
= nspdf
._produce
_ns
_desc
()
674 # check that all expected member-vnf-index are present
675 vnfs
= [e
['vnf_id'] for e
in ns_desc
]
676 self
.assertEqual(Counter({'1': 1, '2': 1, '3': 1}), Counter(vnfs
), 'vnf_id invalid')
678 expected_keys
= ['vnf_id', 'vnf_price_per_vim']
680 # check that vnf_price_per_vim has proper values
681 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 self
.assertEqual(Counter(expected_keys
), Counter(e
.keys()), 'pinning directive misplaced')
685 def test__produce_ns_desc_w_pinning(self
):
686 nsd
= self
._get
_ut
_nsd
_from
_file
('nsd_unittest3.yaml')
687 nsd
= nsd
['nsd']['nsd'][0]
688 pinning
= [{'member-vnf-index': 'two', 'vimAccountId': '331ffdec-44a8-4707-94a1-af7a292d9735'}]
689 nspdf
= NsPlacementDataFactory(self
._produce
_ut
_vim
_accounts
_info
(TestNsPlacementDataFactory
.vim_accounts
),
690 self
._produce
_ut
_vnf
_price
_list
(),
694 ns_desc
= nspdf
._produce
_ns
_desc
()
695 # check that all expected member-vnf-index are present
696 vnfs
= [e
['vnf_id'] for e
in ns_desc
]
697 self
.assertEqual(Counter(['one', 'three', 'two']), Counter(vnfs
), 'vnf_id invalid')
700 # check that vnf_price_per_vim has proper values
701 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 if e
['vnf_id'] == 'two':
704 self
.assertTrue('vim_account' in e
.keys(), 'missing pinning directive')
705 self
.assertTrue(pinning
[0]['vimAccountId'] == e
['vim_account'][3:].replace('_', '-'),
706 'invalid pinning vim-account')
708 self
.assertTrue('vim-account' not in e
.keys(), 'pinning directive misplaced')
710 @mock.patch
.object(NsPlacementDataFactory
, '_produce_trp_link_characteristics_data')
711 @mock.patch
.object(NsPlacementDataFactory
, '_produce_vld_desc')
712 @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
):
717 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']]
722 nsd
= self
._get
_ut
_nsd
_from
_file
('nsd_unittest3.yaml')
723 nsd
= nsd
['nsd']['nsd'][0]
724 nspdf
= NsPlacementDataFactory(self
._produce
_ut
_vim
_accounts
_info
(TestNsPlacementDataFactory
.vim_accounts
),
725 self
._produce
_ut
_vnf
_price
_list
(),
727 pil_info
=self
._populate
_pil
_info
('pil_unittest1.yaml'),
729 order_constraints
=None)
730 nspd
= nspdf
.create_ns_placement_data()
731 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 self
.assertTrue(mock_prd_ns_desc
.called
, '_produce_ns_desc not called')
735 # mock2.assert_called_once() Note for python > 3.5
736 self
.assertTrue(mock_prd_vld_desc
.called
, ' _produce_vld_desc not called')
737 mock_prd_trp_link_char
.assert_has_calls([call('pil_latency'), call('pil_jitter'), call('pil_price')])
739 regexps
= [r
"\{.*\}", r
".*'file':.*mznplacement.py", r
".*'time':.*datetime.datetime\(.*\)"]
740 generator_data
= str(nspd
['generator_data'])
741 for regex
in regexps
:
742 self
.assertRegex(generator_data
, regex
, "generator data invalid")
744 @mock.patch
.object(NsPlacementDataFactory
, '_produce_trp_link_characteristics_data')
745 @mock.patch
.object(NsPlacementDataFactory
, '_produce_vld_desc')
746 @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
):
752 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']]
757 nsd
= self
._get
_ut
_nsd
_from
_file
('nsd_unittest3.yaml')
758 nsd
= nsd
['nsd']['nsd'][0]
759 nspdf
= NsPlacementDataFactory(self
._produce
_ut
_vim
_accounts
_info
(TestNsPlacementDataFactory
.vim_accounts
),
760 self
._produce
_ut
_vnf
_price
_list
(),
762 pil_info
=self
._populate
_pil
_info
('pil_unittest1.yaml'),
765 'vld-constraints': [{'id': 'three_vnf_constrained_nsd_vld1',
766 'link-constraints': {'latency': 120,
768 {'id': 'three_vnf_constrained_nsd_vld2',
769 'link-constraints': {'latency': 121,
772 nspd
= nspdf
.create_ns_placement_data()
773 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 self
.assertTrue(mock_prd_ns_desc
.called
, '_produce_ns_desc not called')
777 # mock2.assert_called_once() Note for python > 3.5
778 self
.assertTrue(mock_prd_vld_desc
.called
, ' _produce_vld_desc not called')
779 mock_prd_trp_link_char
.assert_has_calls([call('pil_latency'), call('pil_jitter'), call('pil_price')])
781 regexps
= [r
"\{.*\}", r
".*'file':.*mznplacement.py", r
".*'time':.*datetime.datetime\(.*\)"]
782 generator_data
= str(nspd
['generator_data'])
783 for regex
in regexps
:
784 self
.assertRegex(generator_data
, regex
, "generator data invalid")
787 if __name__
== "__main__":
788 if __name__
== '__main__':