blob: fe3c8dae6c2504c41258edfe8aec89d27962b4df [file] [log] [blame]
magnussonl2b0e2d72020-02-04 10:52:46 +01001# 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.
15import os
16import unittest
17from collections import Counter
18from pathlib import Path
19from unittest import TestCase, mock
20from unittest.mock import call
21
22import yaml
23
24from osm_pla.placement.mznplacement import NsPlacementDataFactory
25
26
27class 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"}]
68
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",
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 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 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 """
magnussonld8c1b392020-06-30 16:48:08 +0200172 return {_['name']: _['_id'] for _ in vim_accounts}
magnussonl2b0e2d72020-02-04 10:52:46 +0100173
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)
181 else:
182 return real_path
183
184 def _populate_pil_info(self, file):
185 """
186 Note str(Path()) is a 3.5 thing
187 """
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)
191
192 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 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)
209
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)
magnussonld8c1b392020-06-30 16:48:08 +0200214 return {i['vnfd']: {i1['vim_name']: i1['price'] for i1 in i['prices']} for i in next(price_list_data)}
magnussonl2b0e2d72020-02-04 10:52:46 +0100215
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)
magnussonld8c1b392020-06-30 16:48:08 +0200220 return {i['vnfd']: {i1['vim_name']: i1['price'] for i1 in i['prices']} for i in next(price_list_data)}
magnussonl2b0e2d72020-02-04 10:52:46 +0100221
222 def test__produce_trp_link_characteristics_link_latency_with_more_vims(self):
223 """
224 -test with more(other) vims compared to pil
225 """
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(),
231 nsd=None,
magnussonld8c1b392020-06-30 16:48:08 +0200232 pil_info=self._populate_pil_info('pil_unittest1_keys.yaml'),
magnussonl2b0e2d72020-02-04 10:52:46 +0100233 pinning=None)
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')
237
238 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 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(),
247 nsd=None,
magnussonld8c1b392020-06-30 16:48:08 +0200248 pil_info=self._populate_pil_info('pil_unittest1_keys.yaml'),
magnussonl2b0e2d72020-02-04 10:52:46 +0100249 pinning=None)
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')
253
254 def test__produce_trp_link_characteristic_not_supported(self):
255 """
256 - test with non-supported characteristic
257 """
258 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 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")
266
267 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 content_expected = [0, 0, 0, 0, 120, 120, 130, 130, 140, 140, 230, 230, 240, 240, 340, 340]
278
279 nspdf = NsPlacementDataFactory(self._produce_ut_vim_accounts_info(TestNsPlacementDataFactory.vim_accounts),
280 self._produce_ut_vnf_price_list(),
281 nsd=None,
magnussonld8c1b392020-06-30 16:48:08 +0200282 pil_info=self._populate_pil_info('pil_unittest1_keys.yaml'), pinning=None)
magnussonl2b0e2d72020-02-04 10:52:46 +0100283 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')
286
287 def test__produce_trp_link_characteristics_link_jitter(self):
288 """
289 -test with full set of vims as in pil
290 """
291 content_expected = [0, 0, 0, 0, 1200, 1200, 1300, 1300, 1400, 1400, 2300, 2300, 2400, 2400, 3400, 3400]
292
293 nspdf = NsPlacementDataFactory(self._produce_ut_vim_accounts_info(TestNsPlacementDataFactory.vim_accounts),
294 self._produce_ut_vnf_price_list(),
295 nsd=None,
magnussonld8c1b392020-06-30 16:48:08 +0200296 pil_info=self._populate_pil_info('pil_unittest1_keys.yaml'), pinning=None)
magnussonl2b0e2d72020-02-04 10:52:46 +0100297 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')
300
301 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 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(),
308 nsd=None,
magnussonld8c1b392020-06-30 16:48:08 +0200309 pil_info=self._populate_pil_info('pil_unittest1_keys.yaml'), pinning=None)
magnussonl2b0e2d72020-02-04 10:52:46 +0100310 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')
313
314 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 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(),
322 nsd=None,
magnussonld8c1b392020-06-30 16:48:08 +0200323 pil_info=self._populate_pil_info('pil_unittest1_keys.yaml'), pinning=None)
magnussonl2b0e2d72020-02-04 10:52:46 +0100324 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')
327
328 def test__produce_trp_link_characteristics_link_price(self):
329 """
330 -test with full set of vims as in pil
331 """
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(),
335 nsd=None,
magnussonld8c1b392020-06-30 16:48:08 +0200336 pil_info=self._populate_pil_info('pil_unittest1_keys.yaml'), pinning=None)
magnussonl2b0e2d72020-02-04 10:52:46 +0100337 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')
340
341 def test__produce_trp_link_characteristics_link_price_with_fewer_vims(self):
342 """
343 -test with fewer vims compared to pil
344 """
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(),
348 nsd=None,
magnussonld8c1b392020-06-30 16:48:08 +0200349 pil_info=self._populate_pil_info('pil_unittest1_keys.yaml'), pinning=None)
magnussonl2b0e2d72020-02-04 10:52:46 +0100350 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')
353
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(),
358 nsd=None,
magnussonld8c1b392020-06-30 16:48:08 +0200359 pil_info=self._populate_pil_info('pil_unittest2_keys.yaml'), pinning=None)
magnussonl2b0e2d72020-02-04 10:52:46 +0100360 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')
364
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}]
368
369 nsd = self._get_ut_nsd_from_file('nsd_unittest2.yaml')
garciaaleb2b0a442021-01-08 14:59:23 -0300370 nsd = nsd['nsd']['nsd'][0]
magnussonl2b0e2d72020-02-04 10:52:46 +0100371 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 self.assertEqual(vld_desc_expected, nspdf._produce_vld_desc(),
376 "vld_desc incorrect")
377
378 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 with self.assertRaises(Exception) as e:
383 _ = 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 self.assertRegex(str(e.exception), r'mapping values are not allowed here.*', "invalid exception content")
389
390 def test__produce_trp_link_characteristics_with_invalid_pil_config(self):
391 """
392 -test with invalid/corrupt pil configuration file (missing endpoint)
393 """
394 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 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")
402
403 def test__produce_vld_desc_w_instantiate_override(self):
404
405 vld_desc_expected = [{'cp_refs': ['one', 'two'], 'latency': 150, 'jitter': 30},
406 {'cp_refs': ['two', 'three'], 'latency': 90, 'jitter': 30}]
407
408 nsd = self._get_ut_nsd_from_file('nsd_unittest_no_vld_constraints.yaml')
garciaaleb2b0a442021-01-08 14:59:23 -0300409 nsd = nsd['nsd']['nsd'][0]
magnussonl2b0e2d72020-02-04 10:52:46 +0100410 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 self.assertNotEqual(nspdf._produce_vld_desc(),
417 vld_desc_expected, "vld_desc incorrect")
418
419 def test__produce_vld_desc_nsd_w_instantiate_wo(self):
420 """
421 nsd w/ constraints, instantiate w/o constraints
422 :return:
423 """
424 vld_desc_expected = [{'cp_refs': ['one', 'two'], 'latency': 150, 'jitter': 30},
425 {'cp_refs': ['two', 'three'], 'latency': 90, 'jitter': 30}]
426
427 nsd = self._get_ut_nsd_from_file('nsd_unittest3.yaml')
garciaaleb2b0a442021-01-08 14:59:23 -0300428 nsd = nsd['nsd']['nsd'][0]
magnussonl2b0e2d72020-02-04 10:52:46 +0100429 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 self.assertEqual(vld_desc_expected, nspdf._produce_vld_desc(),
436 "vld_desc incorrect")
437
438 def test__produce_vld_desc_nsd_w_instantiate_w(self):
439 """
440 nsd w/ constraints, instantiate w/ constraints => override
441 :return:
442 """
443 vld_desc_expected = [{'cp_refs': ['one', 'two'], 'latency': 120, 'jitter': 21},
444 {'cp_refs': ['two', 'three'], 'latency': 121, 'jitter': 22}]
445
446 nsd = self._get_ut_nsd_from_file('nsd_unittest3.yaml')
garciaaleb2b0a442021-01-08 14:59:23 -0300447 nsd = nsd['nsd']['nsd'][0]
magnussonl2b0e2d72020-02-04 10:52:46 +0100448 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 self.assertEqual(vld_desc_expected, nspdf._produce_vld_desc(),
461 "vld_desc incorrect")
462
463 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 vld_desc_expected = [{'cp_refs': ['one', 'two']},
469 {'cp_refs': ['two', 'three']}]
470
471 nsd = self._get_ut_nsd_from_file('nsd_unittest_no_vld_constraints.yaml')
garciaaleb2b0a442021-01-08 14:59:23 -0300472 nsd = nsd['nsd']['nsd'][0]
magnussonl2b0e2d72020-02-04 10:52:46 +0100473 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 self.assertEqual(vld_desc_expected, nspdf._produce_vld_desc(),
480 "vld_desc incorrect")
481
482 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 vld_desc_expected = [{'cp_refs': ['one', 'two'], 'latency': 140, 'jitter': 41},
488 {'cp_refs': ['two', 'three'], 'latency': 141, 'jitter': 42}]
489
490 nsd = self._get_ut_nsd_from_file('nsd_unittest_no_vld_constraints.yaml')
garciaaleb2b0a442021-01-08 14:59:23 -0300491 nsd = nsd['nsd']['nsd'][0]
magnussonl2b0e2d72020-02-04 10:52:46 +0100492 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 self.assertEqual(vld_desc_expected, nspdf._produce_vld_desc(),
505 "vld_desc incorrect")
506
507 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 vld_desc_expected = [{'cp_refs': ['one', 'two']},
513 {'cp_refs': ['two', 'three'], 'latency': 151}]
514
515 nsd = self._get_ut_nsd_from_file('nsd_unittest_no_vld_constraints.yaml')
garciaaleb2b0a442021-01-08 14:59:23 -0300516 nsd = nsd['nsd']['nsd'][0]
magnussonl2b0e2d72020-02-04 10:52:46 +0100517 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 self.assertEqual(vld_desc_expected, nspdf._produce_vld_desc(),
530 "vld_desc incorrect")
531
532 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 vld_desc_expected = [{'cp_refs': ['one', 'two'], 'jitter': 21},
538 {'cp_refs': ['two', 'three']}]
539
540 nsd = self._get_ut_nsd_from_file('nsd_unittest_no_vld_constraints.yaml')
garciaaleb2b0a442021-01-08 14:59:23 -0300541 nsd = nsd['nsd']['nsd'][0]
magnussonl2b0e2d72020-02-04 10:52:46 +0100542 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 self.assertEqual(vld_desc_expected, nspdf._produce_vld_desc(),
555 "vld_desc incorrect")
556
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}, ]
561
562 nsd = self._get_ut_nsd_from_file('test_five_nsd.yaml')
garciaaleb2b0a442021-01-08 14:59:23 -0300563 nsd = nsd['nsd']['nsd'][0]
magnussonl2b0e2d72020-02-04 10:52:46 +0100564 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 self.assertEqual(vld_desc_expected, nspdf._produce_vld_desc(), "vld_desc incorrect")
571
572 def test__produce_vld_desc_single_vnf_nsd(self):
573 vld_desc_expected = []
574
575 nsd = self._get_ut_nsd_from_file('nsd_unittest4.yaml')
garciaaleb2b0a442021-01-08 14:59:23 -0300576 nsd = nsd['nsd']['nsd'][0]
magnussonl2b0e2d72020-02-04 10:52:46 +0100577 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 self.assertEqual(vld_desc_expected, nspdf._produce_vld_desc(), "vld_desc_incorrect")
584
magnussonld8c1b392020-06-30 16:48:08 +0200585 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')
garciaaleb2b0a442021-01-08 14:59:23 -0300588 nsd = nsd['nsd']['nsd'][0]
magnussonld8c1b392020-06-30 16:48:08 +0200589 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 self.assertEqual(vld_desc_expected, nspdf._produce_vld_desc(), "vld_desc_incorrect")
596
magnussonl2b0e2d72020-02-04 10:52:46 +0100597 def test__produce_vld_desc(self):
598 """
599
600 :return:
601 """
602 vld_desc_expected = [{'cp_refs': ['one', 'two'], 'latency': 150, 'jitter': 30},
603 {'cp_refs': ['two', 'three'], 'latency': 90, 'jitter': 30}]
604
605 nsd = self._get_ut_nsd_from_file('nsd_unittest3.yaml')
garciaaleb2b0a442021-01-08 14:59:23 -0300606 nsd = nsd['nsd']['nsd'][0]
magnussonl2b0e2d72020-02-04 10:52:46 +0100607 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 self.assertEqual(vld_desc_expected, nspdf._produce_vld_desc(), "vld_desc incorrect")
614
615 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 nsd = self._get_ut_nsd_from_file('nsd_unittest3.yaml')
garciaaleb2b0a442021-01-08 14:59:23 -0300624 nsd = nsd['nsd']['nsd'][0]
magnussonl2b0e2d72020-02-04 10:52:46 +0100625 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 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')
635
636 expected_keys = ['vnf_id', 'vnf_price_per_vim']
637 for e in ns_desc:
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')
642
643 def test__produce_ns_desc_with_more_vims(self):
644 nsd = self._get_ut_nsd_from_file('nsd_unittest1.yaml')
garciaaleb2b0a442021-01-08 14:59:23 -0300645 nsd = nsd['nsd']['nsd'][0]
magnussonl2b0e2d72020-02-04 10:52:46 +0100646 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 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]
garciaaleb2b0a442021-01-08 14:59:23 -0300655 self.assertEqual(Counter({'1': 1, '2': 1, '3': 1}), Counter(vnfs), 'vnf_id invalid')
magnussonl2b0e2d72020-02-04 10:52:46 +0100656
657 expected_keys = ['vnf_id', 'vnf_price_per_vim']
658 for e in ns_desc:
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')
663
664 def test__produce_ns_desc_with_fewer_vims(self):
665 nsd = self._get_ut_nsd_from_file('nsd_unittest1.yaml')
garciaaleb2b0a442021-01-08 14:59:23 -0300666 nsd = nsd['nsd']['nsd'][0]
magnussonl2b0e2d72020-02-04 10:52:46 +0100667 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 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]
garciaaleb2b0a442021-01-08 14:59:23 -0300676 self.assertEqual(Counter({'1': 1, '2': 1, '3': 1}), Counter(vnfs), 'vnf_id invalid')
magnussonl2b0e2d72020-02-04 10:52:46 +0100677
678 expected_keys = ['vnf_id', 'vnf_price_per_vim']
679 for e in ns_desc:
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')
684
685 def test__produce_ns_desc_w_pinning(self):
686 nsd = self._get_ut_nsd_from_file('nsd_unittest3.yaml')
garciaaleb2b0a442021-01-08 14:59:23 -0300687 nsd = nsd['nsd']['nsd'][0]
magnussonl2b0e2d72020-02-04 10:52:46 +0100688 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(),
691 nsd=nsd,
692 pil_info=None,
693 pinning=pinning)
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')
698
699 for e in ns_desc:
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')
707 else:
708 self.assertTrue('vim-account' not in e.keys(), 'pinning directive misplaced')
709
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):
714 """
715 :return:
716 """
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']]
721
722 nsd = self._get_ut_nsd_from_file('nsd_unittest3.yaml')
garciaaleb2b0a442021-01-08 14:59:23 -0300723 nsd = nsd['nsd']['nsd'][0]
magnussonl2b0e2d72020-02-04 10:52:46 +0100724 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 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')])
738
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")
743
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):
749 """
750 :return:
751 """
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']]
756
757 nsd = self._get_ut_nsd_from_file('nsd_unittest3.yaml')
garciaaleb2b0a442021-01-08 14:59:23 -0300758 nsd = nsd['nsd']['nsd'][0]
magnussonl2b0e2d72020-02-04 10:52:46 +0100759 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 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')])
780
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")
785
786
787if __name__ == "__main__":
788 if __name__ == '__main__':
789 unittest.main()