Pin black version in tox.ini to 23.12.1
[osm/N2VC.git] / n2vc / tests / unit / test_n2vc_juju_conn.py
1 # Copyright 2020 Canonical Ltd.
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 implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15
16 import asyncio
17 import logging
18 from unittest.mock import Mock, MagicMock
19 from unittest.mock import patch
20
21
22 import asynctest
23 from n2vc.definitions import Offer, RelationEndpoint
24 from n2vc.n2vc_juju_conn import N2VCJujuConnector
25 from osm_common import fslocal
26 from osm_common.dbmemory import DbMemory
27 from n2vc.exceptions import (
28 N2VCBadArgumentsException,
29 N2VCException,
30 JujuApplicationNotFound,
31 )
32 from n2vc.tests.unit.utils import AsyncMock
33 from n2vc.vca.connection_data import ConnectionData
34 from n2vc.tests.unit.testdata import test_db_descriptors as descriptors
35 import yaml
36
37
38 class N2VCJujuConnTestCase(asynctest.TestCase):
39 @asynctest.mock.patch("n2vc.n2vc_juju_conn.MotorStore")
40 @asynctest.mock.patch("n2vc.n2vc_juju_conn.get_connection")
41 @asynctest.mock.patch("n2vc.vca.connection_data.base64_to_cacert")
42 def setUp(
43 self, mock_base64_to_cacert=None, mock_get_connection=None, mock_store=None
44 ):
45 self.loop = asyncio.get_event_loop()
46 self.db = Mock()
47 mock_base64_to_cacert.return_value = """
48 -----BEGIN CERTIFICATE-----
49 SOMECERT
50 -----END CERTIFICATE-----"""
51 mock_store.return_value = AsyncMock()
52 mock_vca_connection = Mock()
53 mock_get_connection.return_value = mock_vca_connection
54 mock_vca_connection.data.return_value = ConnectionData(
55 **{
56 "endpoints": ["1.2.3.4:17070"],
57 "user": "user",
58 "secret": "secret",
59 "cacert": "cacert",
60 "pubkey": "pubkey",
61 "lxd-cloud": "cloud",
62 "lxd-credentials": "credentials",
63 "k8s-cloud": "k8s_cloud",
64 "k8s-credentials": "k8s_credentials",
65 "model-config": {},
66 "api-proxy": "api_proxy",
67 }
68 )
69 logging.disable(logging.CRITICAL)
70
71 N2VCJujuConnector.get_public_key = Mock()
72 self.n2vc = N2VCJujuConnector(
73 db=self.db,
74 fs=fslocal.FsLocal(),
75 log=None,
76 on_update_db=None,
77 )
78 N2VCJujuConnector.get_public_key.assert_not_called()
79 self.n2vc.libjuju = Mock()
80
81
82 class GetMetricssTest(N2VCJujuConnTestCase):
83 def setUp(self):
84 super(GetMetricssTest, self).setUp()
85 self.n2vc.libjuju.get_metrics = AsyncMock()
86
87 def test_success(self):
88 _ = self.loop.run_until_complete(self.n2vc.get_metrics("model", "application"))
89 self.n2vc.libjuju.get_metrics.assert_called_once()
90
91 def test_except(self):
92 self.n2vc.libjuju.get_metrics.side_effect = Exception()
93 with self.assertRaises(Exception):
94 _ = self.loop.run_until_complete(
95 self.n2vc.get_metrics("model", "application")
96 )
97 self.n2vc.libjuju.get_metrics.assert_called_once()
98
99
100 class UpdateVcaStatusTest(N2VCJujuConnTestCase):
101 def setUp(self):
102 super(UpdateVcaStatusTest, self).setUp()
103 self.n2vc.libjuju.get_controller = AsyncMock()
104 self.n2vc.libjuju.get_model = AsyncMock()
105 self.n2vc.libjuju.get_executed_actions = AsyncMock()
106 self.n2vc.libjuju.get_actions = AsyncMock()
107 self.n2vc.libjuju.get_application_configs = AsyncMock()
108 self.n2vc.libjuju._get_application = AsyncMock()
109
110 def test_success(
111 self,
112 ):
113 self.loop.run_until_complete(
114 self.n2vc.update_vca_status(
115 {"model": {"applications": {"app": {"actions": {}}}}}
116 )
117 )
118 self.n2vc.libjuju.get_executed_actions.assert_called_once()
119 self.n2vc.libjuju.get_actions.assert_called_once()
120 self.n2vc.libjuju.get_application_configs.assert_called_once()
121
122 def test_exception(self):
123 self.n2vc.libjuju.get_model.return_value = None
124 self.n2vc.libjuju.get_executed_actions.side_effect = Exception()
125 with self.assertRaises(Exception):
126 self.loop.run_until_complete(
127 self.n2vc.update_vca_status(
128 {"model": {"applications": {"app": {"actions": {}}}}}
129 )
130 )
131 self.n2vc.libjuju.get_executed_actions.assert_not_called()
132 self.n2vc.libjuju.get_actions.assert_not_called_once()
133 self.n2vc.libjuju.get_application_configs.assert_not_called_once()
134
135
136 class K8sProxyCharmsTest(N2VCJujuConnTestCase):
137 def setUp(self):
138 super(K8sProxyCharmsTest, self).setUp()
139 self.n2vc.libjuju.model_exists = AsyncMock()
140 self.n2vc.libjuju.add_model = AsyncMock()
141 self.n2vc.libjuju.deploy_charm = AsyncMock()
142 self.n2vc.libjuju.model_exists.return_value = False
143 self.db = DbMemory()
144 self.fs = fslocal.FsLocal()
145 self.fs.path = "/"
146 self.n2vc.fs = self.fs
147 self.n2vc.db = self.db
148 self.db.create_list("nsrs", yaml.safe_load(descriptors.db_nsrs_text))
149 self.db.create_list("vnfrs", yaml.safe_load(descriptors.db_vnfrs_text))
150
151 @patch(
152 "n2vc.n2vc_juju_conn.generate_random_alfanum_string",
153 **{"return_value": "random"}
154 )
155 def test_success(self, mock_generate_random_alfanum_string):
156 self.n2vc.fs.file_exists = MagicMock(create_autospec=True)
157 self.n2vc.fs.file_exists.return_value = True
158 ee_id = self.loop.run_until_complete(
159 self.n2vc.install_k8s_proxy_charm(
160 "simple",
161 ".dbfbd751-3de4-4e68-bd40-ec5ae0a53898.1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0",
162 "path",
163 {},
164 )
165 )
166
167 self.n2vc.libjuju.add_model.assert_called_once()
168 self.n2vc.libjuju.deploy_charm.assert_called_once_with(
169 model_name="dbfbd751-3de4-4e68-bd40-ec5ae0a53898-k8s",
170 application_name="simple-ee-z0-vnf1-vnf",
171 path="//path",
172 machine_id=None,
173 db_dict={},
174 progress_timeout=None,
175 total_timeout=None,
176 config=None,
177 )
178 self.assertEqual(
179 ee_id, "dbfbd751-3de4-4e68-bd40-ec5ae0a53898-k8s.simple-ee-z0-vnf1-vnf.k8s"
180 )
181
182 def test_no_artifact_path(
183 self,
184 ):
185 with self.assertRaises(N2VCBadArgumentsException):
186 ee_id = self.loop.run_until_complete(
187 self.n2vc.install_k8s_proxy_charm(
188 "simple",
189 ".dbfbd751-3de4-4e68-bd40-ec5ae0a53898.1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0",
190 "",
191 {},
192 )
193 )
194 self.assertIsNone(ee_id)
195
196 def test_no_db(
197 self,
198 ):
199 with self.assertRaises(N2VCBadArgumentsException):
200 ee_id = self.loop.run_until_complete(
201 self.n2vc.install_k8s_proxy_charm(
202 "simple",
203 ".dbfbd751-3de4-4e68-bd40-ec5ae0a53898.1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0",
204 "path",
205 None,
206 )
207 )
208 self.assertIsNone(ee_id)
209
210 def test_file_not_exists(
211 self,
212 ):
213 self.n2vc.fs.file_exists = MagicMock(create_autospec=True)
214 self.n2vc.fs.file_exists.return_value = False
215 with self.assertRaises(N2VCBadArgumentsException):
216 ee_id = self.loop.run_until_complete(
217 self.n2vc.install_k8s_proxy_charm(
218 "simple",
219 ".dbfbd751-3de4-4e68-bd40-ec5ae0a53898.1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0",
220 "path",
221 {},
222 )
223 )
224 self.assertIsNone(ee_id)
225
226 def test_exception(
227 self,
228 ):
229 self.n2vc.fs.file_exists = MagicMock(create_autospec=True)
230 self.n2vc.fs.file_exists.return_value = True
231 self.n2vc.fs.path = MagicMock(create_autospec=True)
232 self.n2vc.fs.path.return_value = "path"
233 self.n2vc.libjuju.deploy_charm.side_effect = Exception()
234 with self.assertRaises(N2VCException):
235 ee_id = self.loop.run_until_complete(
236 self.n2vc.install_k8s_proxy_charm(
237 "simple",
238 ".dbfbd751-3de4-4e68-bd40-ec5ae0a53898.1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0",
239 "path",
240 {},
241 )
242 )
243 self.assertIsNone(ee_id)
244
245
246 class AddRelationTest(N2VCJujuConnTestCase):
247 def setUp(self):
248 super(AddRelationTest, self).setUp()
249 self.n2vc.libjuju.add_relation = AsyncMock()
250 self.n2vc.libjuju.offer = AsyncMock()
251 self.n2vc.libjuju.get_controller = AsyncMock()
252 self.n2vc.libjuju.consume = AsyncMock()
253
254 def test_standard_relation_same_model_and_controller(self):
255 relation_endpoint_1 = RelationEndpoint("model-1.app1.0", None, "endpoint1")
256 relation_endpoint_2 = RelationEndpoint("model-1.app2.1", None, "endpoint2")
257 self.loop.run_until_complete(
258 self.n2vc.add_relation(relation_endpoint_1, relation_endpoint_2)
259 )
260 self.n2vc.libjuju.add_relation.assert_called_once_with(
261 model_name="model-1",
262 endpoint_1="app1:endpoint1",
263 endpoint_2="app2:endpoint2",
264 )
265 self.n2vc.libjuju.offer.assert_not_called()
266 self.n2vc.libjuju.consume.assert_not_called()
267
268 def test_cmr_relation_same_controller(self):
269 relation_endpoint_1 = RelationEndpoint("model-1.app1.0", None, "endpoint")
270 relation_endpoint_2 = RelationEndpoint("model-2.app2.1", None, "endpoint")
271 offer = Offer("admin/model-1.app1")
272 self.n2vc.libjuju.offer.return_value = offer
273 self.n2vc.libjuju.consume.return_value = "saas"
274 self.loop.run_until_complete(
275 self.n2vc.add_relation(relation_endpoint_1, relation_endpoint_2)
276 )
277 self.n2vc.libjuju.offer.assert_called_once_with(relation_endpoint_1)
278 self.n2vc.libjuju.consume.assert_called_once()
279 self.n2vc.libjuju.add_relation.assert_called_once_with(
280 "model-2", "app2:endpoint", "saas"
281 )
282
283 def test_cmr_relation_different_controller(self):
284 self.n2vc._get_libjuju = AsyncMock(return_value=self.n2vc.libjuju)
285 relation_endpoint_1 = RelationEndpoint(
286 "model-1.app1.0", "vca-id-1", "endpoint1"
287 )
288 relation_endpoint_2 = RelationEndpoint(
289 "model-1.app2.1", "vca-id-2", "endpoint2"
290 )
291 offer = Offer("admin/model-1.app1")
292 self.n2vc.libjuju.offer.return_value = offer
293 self.n2vc.libjuju.consume.return_value = "saas"
294 self.loop.run_until_complete(
295 self.n2vc.add_relation(relation_endpoint_1, relation_endpoint_2)
296 )
297 self.n2vc.libjuju.offer.assert_called_once_with(relation_endpoint_1)
298 self.n2vc.libjuju.consume.assert_called_once()
299 self.n2vc.libjuju.add_relation.assert_called_once_with(
300 "model-1", "app2:endpoint2", "saas"
301 )
302
303 def test_relation_exception(self):
304 relation_endpoint_1 = RelationEndpoint("model-1.app1.0", None, "endpoint")
305 relation_endpoint_2 = RelationEndpoint("model-2.app2.1", None, "endpoint")
306 self.n2vc.libjuju.offer.side_effect = Exception()
307 with self.assertRaises(N2VCException):
308 self.loop.run_until_complete(
309 self.n2vc.add_relation(relation_endpoint_1, relation_endpoint_2)
310 )
311
312
313 class UpgradeCharmTest(N2VCJujuConnTestCase):
314 def setUp(self):
315 super(UpgradeCharmTest, self).setUp()
316 self.n2vc._get_libjuju = AsyncMock(return_value=self.n2vc.libjuju)
317 N2VCJujuConnector._get_ee_id_components = Mock()
318 self.n2vc.libjuju.upgrade_charm = AsyncMock()
319
320 def test_empty_ee_id(self):
321 with self.assertRaises(N2VCBadArgumentsException):
322 self.loop.run_until_complete(
323 self.n2vc.upgrade_charm(
324 "", "/sample_charm_path", "sample_charm_id", "native-charm", None
325 )
326 )
327 self.n2vc._get_libjuju.assert_called()
328 self.n2vc._get_ee_id_components.assert_not_called()
329 self.n2vc.libjuju.upgrade_charm.assert_not_called()
330
331 def test_wrong_ee_id(self):
332 N2VCJujuConnector._get_ee_id_components.side_effect = Exception
333 with self.assertRaises(N2VCBadArgumentsException):
334 self.loop.run_until_complete(
335 self.n2vc.upgrade_charm(
336 "ns-id-k8s.app-vnf-vnf-id-vdu-vdu-random.k8s",
337 "/sample_charm_path",
338 "sample_charm_id",
339 "native-charm",
340 500,
341 )
342 )
343 self.n2vc._get_libjuju.assert_called()
344 self.n2vc._get_ee_id_components.assert_called()
345 self.n2vc.libjuju.upgrade_charm.assert_not_called()
346
347 def test_charm_upgrade_succeded(self):
348 N2VCJujuConnector._get_ee_id_components.return_value = (
349 "sample_model",
350 "sample_app",
351 "sample_machine_id",
352 )
353 self.loop.run_until_complete(
354 self.n2vc.upgrade_charm(
355 "ns-id-k8s.app-vnf-vnf-id-vdu-vdu-random.k8s",
356 "/sample_charm_path",
357 "sample_charm_id",
358 "native-charm",
359 500,
360 )
361 )
362 self.n2vc._get_libjuju.assert_called()
363 self.n2vc._get_ee_id_components.assert_called()
364 self.n2vc.libjuju.upgrade_charm.assert_called_with(
365 application_name="sample_app",
366 path="/sample_charm_path",
367 model_name="sample_model",
368 total_timeout=500,
369 )
370
371 def test_charm_upgrade_failed(self):
372 N2VCJujuConnector._get_ee_id_components.return_value = (
373 "sample_model",
374 "sample_app",
375 "sample_machine_id",
376 )
377 self.n2vc.libjuju.upgrade_charm.side_effect = JujuApplicationNotFound
378 with self.assertRaises(N2VCException):
379 self.loop.run_until_complete(
380 self.n2vc.upgrade_charm(
381 "ns-id-k8s.app-vnf-vnf-id-vdu-vdu-random.k8s",
382 "/sample_charm_path",
383 "sample_charm_id",
384 "native-charm",
385 None,
386 )
387 )
388 self.n2vc._get_libjuju.assert_called()
389 self.n2vc._get_ee_id_components.assert_called()
390 self.n2vc.libjuju.upgrade_charm.assert_called_with(
391 application_name="sample_app",
392 path="/sample_charm_path",
393 model_name="sample_model",
394 total_timeout=None,
395 )
396
397
398 class GenerateApplicationNameTest(N2VCJujuConnTestCase):
399 vnf_id = "dbfbd751-3de4-4e68-bd40-ec5ae0a53898"
400
401 def setUp(self):
402 super(GenerateApplicationNameTest, self).setUp()
403 self.db = MagicMock(DbMemory)
404
405 @patch(
406 "n2vc.n2vc_juju_conn.generate_random_alfanum_string",
407 **{"return_value": "random"}
408 )
409 def test_generate_backward_compatible_application_name(
410 self, mock_generate_random_alfanum
411 ):
412 vdu_id = "mgmtVM"
413 vdu_count = "0"
414 expected_result = "app-vnf-ec5ae0a53898-vdu-mgmtVM-cnt-0-random"
415
416 application_name = self.n2vc._generate_backward_compatible_application_name(
417 GenerateApplicationNameTest.vnf_id, vdu_id, vdu_count
418 )
419 self.assertEqual(application_name, expected_result)
420
421 @patch(
422 "n2vc.n2vc_juju_conn.generate_random_alfanum_string",
423 **{"return_value": "random"}
424 )
425 def test_generate_backward_compatible_application_name_without_vnf_id_vdu_id(
426 self, mock_generate_random_alfanum
427 ):
428 vnf_id = None
429 vdu_id = ""
430 vdu_count = None
431 expected_result = "app--random"
432 application_name = self.n2vc._generate_backward_compatible_application_name(
433 vnf_id, vdu_id, vdu_count
434 )
435
436 self.assertEqual(application_name, expected_result)
437 self.assertLess(len(application_name), 50)
438
439 def test_find_charm_level_with_vnf_id(self):
440 vdu_id = ""
441 expected_result = "vnf-level"
442 charm_level = self.n2vc._find_charm_level(
443 GenerateApplicationNameTest.vnf_id, vdu_id
444 )
445 self.assertEqual(charm_level, expected_result)
446
447 def test_find_charm_level_with_vdu_id(self):
448 vnf_id = ""
449 vdu_id = "mgmtVM"
450 with self.assertRaises(N2VCException):
451 self.n2vc._find_charm_level(vnf_id, vdu_id)
452
453 def test_find_charm_level_with_vnf_id_and_vdu_id(self):
454 vdu_id = "mgmtVM"
455 expected_result = "vdu-level"
456 charm_level = self.n2vc._find_charm_level(
457 GenerateApplicationNameTest.vnf_id, vdu_id
458 )
459 self.assertEqual(charm_level, expected_result)
460
461 def test_find_charm_level_without_vnf_id_and_vdu_id(self):
462 vnf_id = ""
463 vdu_id = ""
464 expected_result = "ns-level"
465 charm_level = self.n2vc._find_charm_level(vnf_id, vdu_id)
466 self.assertEqual(charm_level, expected_result)
467
468 def test_generate_application_name_ns_charm(self):
469 charm_level = "ns-level"
470 vnfrs = {}
471 vca_records = [
472 {
473 "target_element": "ns",
474 "member-vnf-index": "",
475 "vdu_id": None,
476 "kdu_name": None,
477 "vdu_count_index": None,
478 "vnfd_id": None,
479 "vdu_name": None,
480 "type": "proxy_charm",
481 "ee_descriptor_id": None,
482 "charm_name": "simple-ns-charm-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh",
483 "ee_id": None,
484 "application": "",
485 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
486 }
487 ]
488 vnf_count = ""
489 vdu_count = ""
490 vdu_id = None
491 expected_result = "simple-ns-charm-abc-000-rrrr-nnnn-4444-h-ns"
492 application_name = self.n2vc._generate_application_name(
493 charm_level,
494 vnfrs,
495 vca_records,
496 vnf_count=vnf_count,
497 vdu_id=vdu_id,
498 vdu_count=vdu_count,
499 )
500 self.assertEqual(application_name, expected_result)
501 self.assertLess(len(application_name), 50)
502
503 def test_generate_application_name_ns_charm_empty_vca_records(self):
504 charm_level = "ns-level"
505 vnfrs = {}
506 vca_records = []
507 vnf_count = ""
508 vdu_count = ""
509 vdu_id = None
510 with self.assertRaises(N2VCException):
511 self.n2vc._generate_application_name(
512 charm_level,
513 vnfrs,
514 vca_records,
515 vnf_count=vnf_count,
516 vdu_id=vdu_id,
517 vdu_count=vdu_count,
518 )
519
520 def test_generate_application_name_vnf_charm(self):
521 charm_level = "vnf-level"
522 vnfrs = {"member-vnf-index-ref": "vnf111-xxx-yyy-zzz"}
523 vca_records = [
524 {
525 "target_element": "vnf/vnf1",
526 "member-vnf-index": "vnf111-xxx-yyy-zzz",
527 "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
528 "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
529 "charm_name": "",
530 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
531 }
532 ]
533 vnf_count = "1"
534 vdu_count = ""
535 vdu_id = None
536 expected_result = "simple-ee-ab-1-vnf111-xxx-y-vnf"
537 application_name = self.n2vc._generate_application_name(
538 charm_level,
539 vnfrs,
540 vca_records,
541 vnf_count=vnf_count,
542 vdu_id=vdu_id,
543 vdu_count=vdu_count,
544 )
545 self.assertEqual(application_name, expected_result)
546 self.assertLess(len(application_name), 50)
547
548 def test_generate_application_name_vdu_charm_kdu_name_in_vca_record_is_none(self):
549 charm_level = "vdu-level"
550 vnfrs = {
551 "member-vnf-index-ref": "vnf111-xxx-yyy-zzz",
552 "vdur": [
553 {"_id": "38912ff7-5bdd-4228-911f-c2bee259c44a", "vdu-id-ref": "mgmtVM"},
554 {"_id": "45512ff7-5bdd-4228-911f-c2bee259c44a", "vdu-id-ref": "dataVM"},
555 ],
556 }
557 vca_records = [
558 {
559 "target_element": "vnf/vnf1/mgmtvm",
560 "member-vnf-index": "vnf111-xxx-yyy-zzz",
561 "vdu_id": "mgmtVM",
562 "kdu_name": None,
563 "vdu_count_index": None,
564 "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
565 "vdu_name": "mgmtvm",
566 "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
567 "charm_name": "",
568 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
569 },
570 {
571 "target_element": "vnf/vnf1/dataVM",
572 "member-vnf-index": "vnf111-xxx-yyy-zzz",
573 "vdu_id": "dataVM",
574 "kdu_name": None,
575 "vdu_count_index": None,
576 "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
577 "vdu_name": "datavm",
578 "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-8888-hhh-3333-yyyy-888-hhh-ttt-444",
579 "charm_name": "",
580 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
581 },
582 ]
583 vnf_count = "2"
584 vdu_count = "0"
585 vdu_id = "mgmtVM"
586 expected_result = "simple-ee-ab-2-vnf111-xxx-y-mgmtVM-0-vdu"
587 application_name = self.n2vc._generate_application_name(
588 charm_level,
589 vnfrs,
590 vca_records,
591 vnf_count=vnf_count,
592 vdu_id=vdu_id,
593 vdu_count=vdu_count,
594 )
595 self.assertEqual(application_name, expected_result)
596 self.assertLess(len(application_name), 50)
597
598 def test_generate_application_name_vdu_charm_vdu_id_kdu_name_in_vca_record_are_both_set(
599 self,
600 ):
601 charm_level = "vdu-level"
602 vnfrs = {
603 "member-vnf-index-ref": "vnf111-xxx-yyy-zzz",
604 "vdur": [
605 {"_id": "38912ff7-5bdd-4228-911f-c2bee259c44a", "vdu-id-ref": "mgmtVM"},
606 {"_id": "45512ff7-5bdd-4228-911f-c2bee259c44a", "vdu-id-ref": "dataVM"},
607 ],
608 }
609 vca_records = [
610 {
611 "target_element": "vnf/vnf1/mgmtVM",
612 "member-vnf-index": "vnf111-xxx-yyy-zzz",
613 "vdu_id": "mgmtVM",
614 "kdu_name": "mgmtVM",
615 "vdu_count_index": None,
616 "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
617 "vdu_name": "mgmtvm",
618 "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
619 "charm_name": "",
620 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
621 },
622 {
623 "target_element": "vnf/vnf1/dataVM",
624 "member-vnf-index": "vnf111-xxx-yyy-zzz",
625 "vdu_id": "dataVM",
626 "kdu_name": None,
627 "vdu_count_index": None,
628 "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
629 "vdu_name": "datavm",
630 "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-8888-hhh-3333-yyyy-888-hhh-ttt-444",
631 "charm_name": "",
632 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
633 },
634 ]
635 vnf_count = "2"
636 vdu_count = "0"
637 vdu_id = "mgmtVM"
638 expected_result = "simple-ee-ab-2-vnf111-xxx-y-mgmtVM-0-vdu"
639 application_name = self.n2vc._generate_application_name(
640 charm_level,
641 vnfrs,
642 vca_records,
643 vnf_count=vnf_count,
644 vdu_id=vdu_id,
645 vdu_count=vdu_count,
646 )
647 self.assertEqual(application_name, expected_result)
648 self.assertLess(len(application_name), 50)
649
650 def test_generate_application_name_vdu_charm_both_vdu_id_kdu_name_in_vca_record_are_none(
651 self,
652 ):
653 charm_level = "vdu-level"
654 vnfrs = {"member-vnf-index-ref": "vnf111-xxx-yyy-zzz"}
655 vca_records = [
656 {
657 "target_element": "vnf/vnf1/mgmtVM",
658 "member-vnf-index": "vnf111-xxx-yyy-zzz",
659 "vdu_id": None,
660 "kdu_name": None,
661 "vdu_count_index": None,
662 "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
663 "vdu_name": "mgmtvm",
664 "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
665 "charm_name": "",
666 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
667 }
668 ]
669 vnf_count = "2"
670 vdu_count = "0"
671 vdu_id = "mgmtVM"
672 with self.assertRaises(KeyError):
673 self.n2vc._generate_application_name(
674 charm_level,
675 vnfrs,
676 vca_records,
677 vnf_count=vnf_count,
678 vdu_id=vdu_id,
679 vdu_count=vdu_count,
680 )
681
682 def test_generate_application_name_vdu_charm_given_vdu_id_is_none(self):
683 charm_level = "vdu-level"
684 vnfrs = {"member-vnf-index-ref": "vnf111-xxx-yyy-zzz"}
685 vca_records = [
686 {
687 "target_element": "vnf/vnf1/mgmtvVM",
688 "member-vnf-index": "vnf111-xxx-yyy-zzz",
689 "vdu_id": None,
690 "kdu_name": "mgmtVM",
691 "vdu_count_index": None,
692 "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
693 "vdu_name": "mgmtvm",
694 "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
695 "charm_name": "",
696 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
697 }
698 ]
699 vnf_count = "2"
700 vdu_count = "0"
701 vdu_id = None
702 with self.assertRaises(N2VCException):
703 self.n2vc._generate_application_name(
704 charm_level,
705 vnfrs,
706 vca_records,
707 vnf_count=vnf_count,
708 vdu_id=vdu_id,
709 vdu_count=vdu_count,
710 )
711
712 def test_generate_application_name_vdu_charm_vdu_id_does_not_match_with_the_key_in_vca_record(
713 self,
714 ):
715 charm_level = "vdu-level"
716 vnfrs = {"member-vnf-index-ref": "vnf111-xxx-yyy-zzz"}
717 vca_records = [
718 {
719 "target_element": "vnf/vnf1/mgmtVM",
720 "member-vnf-index": "vnf111-xxx-yyy-zzz",
721 "vdu_id": None,
722 "kdu_name": "mgmtVM",
723 "vdu_count_index": None,
724 "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
725 "vdu_name": "mgmtvm",
726 "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
727 "charm_name": "",
728 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
729 }
730 ]
731 vnf_count = "2"
732 vdu_count = "0"
733 vdu_id = "mgmtvm"
734 with self.assertRaises(KeyError):
735 self.n2vc._generate_application_name(
736 charm_level,
737 vnfrs,
738 vca_records,
739 vnf_count=vnf_count,
740 vdu_id=vdu_id,
741 vdu_count=vdu_count,
742 )
743
744 def test_generate_application_name_vdu_charm_vdu_id_in_vca_record_is_none(self):
745 charm_level = "vdu-level"
746 vnfrs = {"member-vnf-index-ref": "vnf111-xxx-yyy-zzz"}
747 vca_records = [
748 {
749 "target_element": "vnf/vnf1/mgmtVM",
750 "member-vnf-index": "vnf111-xxx-yyy-zzz",
751 "vdu_id": None,
752 "kdu_name": "mgmtVM",
753 "vdu_count_index": None,
754 "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
755 "vdu_name": "mgmtvm",
756 "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
757 "charm_name": "",
758 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
759 }
760 ]
761 vnf_count = "2"
762 vdu_count = "0"
763 vdu_id = "mgmtVM"
764 expected_result = "simple-ee-ab-2-vnf111-xxx-y-mgmtVM-0-vdu"
765 application_name = self.n2vc._generate_application_name(
766 charm_level,
767 vnfrs,
768 vca_records,
769 vnf_count=vnf_count,
770 vdu_id=vdu_id,
771 vdu_count=vdu_count,
772 )
773 self.assertEqual(application_name, expected_result)
774 self.assertLess(len(application_name), 50)
775
776 def test_get_vnf_count_db_vnfr_ns_charm(self):
777 self.db.get_one.return_value = {"member-vnf-index-ref": "sample-ref"}
778 charm_level = "ns-level"
779 vnf_id_and_count = "m7fbd751-3de4-4e68-bd40-ec5ae0a53898-4"
780 with patch.object(self.n2vc, "db", self.db):
781 vnf_count, db_vnfr = self.n2vc._get_vnf_count_and_record(
782 charm_level, vnf_id_and_count
783 )
784 self.assertEqual(vnf_count, "")
785 self.assertEqual(db_vnfr, {})
786
787 def test_get_vnf_count_db_vnfr_vnf_charm(self):
788 self.db.get_one.return_value = {"member-vnf-index-ref": "sample-ref"}
789 charm_level = "vnf-level"
790 vnf_id_and_count = "m7fbd751-3de4-4e68-bd40-ec5ae0a53898-4"
791 with patch.object(self.n2vc, "db", self.db):
792 vnf_count, db_vnfr = self.n2vc._get_vnf_count_and_record(
793 charm_level, vnf_id_and_count
794 )
795 self.assertEqual(vnf_count, "4")
796 self.assertEqual(db_vnfr, {"member-vnf-index-ref": "sample-ref"})
797
798 def test_get_vnf_count_db_vnfr_vdu_charm(self):
799 self.db.get_one.return_value = {"member-vnf-index-ref": "sample-ref"}
800 charm_level = "vdu-level"
801 vnf_id_and_count = "m7fbd751-3de4-4e68-bd40-ec5ae0a53898-2"
802 with patch.object(self.n2vc, "db", self.db):
803 vnf_count, db_vnfr = self.n2vc._get_vnf_count_and_record(
804 charm_level, vnf_id_and_count
805 )
806 self.assertEqual(vnf_count, "2")
807 self.assertEqual(db_vnfr, {"member-vnf-index-ref": "sample-ref"})
808
809 def test_get_vca_records_vdu_charm(self):
810 charm_level = "vdu-level"
811 db_vnfr = {
812 "member-vnf-index-ref": "vnf111-xxx-yyy-zzz",
813 "vdur": [
814 {"_id": "38912ff7-5bdd-4228-911f-c2bee259c44a", "vdu-id-ref": "mgmtVM"},
815 {"_id": "45512ff7-5bdd-4228-911f-c2bee259c44a", "vdu-id-ref": "dataVM"},
816 ],
817 }
818 db_nsr = {
819 "_admin": {
820 "deployed": {
821 "VCA": [
822 {
823 "target_element": "vnf/vnf1/mgmtvm",
824 "member-vnf-index": "vnf111-xxx-yyy-zzz",
825 "vdu_id": "38912ff7-5bdd-4228-911f-c2bee259c44a",
826 "kdu_name": None,
827 "vdu_count_index": None,
828 "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
829 "vdu_name": "mgmtvm",
830 "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
831 "charm_name": "",
832 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
833 },
834 {
835 "target_element": "vnf/vnf2/datavm",
836 "member-vnf-index": "vnf222-xxx-yyy-zzz",
837 "vdu_id": "45512ff7-5bdd-4228-911f-c2bee259c44a",
838 "kdu_name": None,
839 "vdu_count_index": None,
840 "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
841 "vdu_name": "datavm",
842 "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-8888-hhh-3333-yyyy-888-hhh-ttt-444",
843 "charm_name": "",
844 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
845 },
846 ]
847 }
848 }
849 }
850 expected_result = [
851 {
852 "target_element": "vnf/vnf1/mgmtvm",
853 "member-vnf-index": "vnf111-xxx-yyy-zzz",
854 "vdu_id": "38912ff7-5bdd-4228-911f-c2bee259c44a",
855 "kdu_name": None,
856 "vdu_count_index": None,
857 "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
858 "vdu_name": "mgmtvm",
859 "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
860 "charm_name": "",
861 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
862 }
863 ]
864 vca_records = self.n2vc._get_vca_records(charm_level, db_nsr, db_vnfr)
865 self.assertEqual(vca_records, expected_result)
866
867 def test_get_vca_records_vnf_charm_member_vnf_index_mismatch(self):
868 charm_level = "vnf-level"
869 db_vnfr = {"member-vnf-index-ref": "vnf222-xxx-yyy-zzz"}
870 db_nsr = {
871 "_admin": {
872 "deployed": {
873 "VCA": [
874 {
875 "target_element": "vnf/vnf1/mgmtvm",
876 "member-vnf-index": "vnf111-xxx-yyy-zzz",
877 "vdu_id": "38912ff7-5bdd-4228-911f-c2bee259c44a",
878 "kdu_name": None,
879 "vdu_count_index": None,
880 "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
881 "vdu_name": "mgmtvm",
882 "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
883 "charm_name": "",
884 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
885 },
886 {
887 "target_element": "vnf/vnf1/mgmtvm",
888 "member-vnf-index": "vnf111-xxx-yyy-zzz",
889 "vdu_id": "45512ff7-5bdd-4228-911f-c2bee259c44a",
890 "kdu_name": None,
891 "vdu_count_index": None,
892 "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
893 "vdu_name": "datavm",
894 "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-8888-hhh-3333-yyyy-888-hhh-ttt-444",
895 "charm_name": "",
896 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
897 },
898 ]
899 }
900 }
901 }
902 expected_result = []
903 vca_records = self.n2vc._get_vca_records(charm_level, db_nsr, db_vnfr)
904 self.assertEqual(vca_records, expected_result)
905
906 def test_get_vca_records_ns_charm(self):
907 charm_level = "ns-level"
908 db_vnfr = {"member-vnf-index-ref": "vnf222-xxx-yyy-zzz"}
909 db_nsr = {
910 "_admin": {
911 "deployed": {
912 "VCA": [
913 {
914 "target_element": "vnf/vnf1/mgmtvm",
915 "member-vnf-index": "vnf111-xxx-yyy-zzz",
916 "vdu_id": "38912ff7-5bdd-4228-911f-c2bee259c44a",
917 "kdu_name": None,
918 "vdu_count_index": None,
919 "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
920 "vdu_name": "mgmtvm",
921 "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
922 "charm_name": "",
923 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
924 },
925 {
926 "target_element": "ns",
927 "member-vnf-index": None,
928 "vdu_id": None,
929 "kdu_name": None,
930 "vdu_count_index": None,
931 "vnfd_id": "",
932 "vdu_name": "",
933 "ee_descriptor_id": "",
934 "charm_name": "simple-ns-charm-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
935 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
936 },
937 ]
938 }
939 }
940 }
941 expected_result = [
942 {
943 "target_element": "ns",
944 "member-vnf-index": None,
945 "vdu_id": None,
946 "kdu_name": None,
947 "vdu_count_index": None,
948 "vnfd_id": "",
949 "vdu_name": "",
950 "ee_descriptor_id": "",
951 "charm_name": "simple-ns-charm-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
952 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
953 }
954 ]
955 vca_records = self.n2vc._get_vca_records(charm_level, db_nsr, db_vnfr)
956 self.assertEqual(vca_records, expected_result)
957
958 def test_get_vca_records_ns_charm_empty_charm_name(self):
959 charm_level = "ns-level"
960 db_vnfr = {"member-vnf-index-ref": "vnf222-xxx-yyy-zzz"}
961 db_nsr = {
962 "_admin": {
963 "deployed": {
964 "VCA": [
965 {
966 "target_element": "vnf/vnf1/mgmtvm",
967 "member-vnf-index": "vnf111-xxx-yyy-zzz",
968 "vdu_id": "38912ff7-5bdd-4228-911f-c2bee259c44a",
969 "kdu_name": None,
970 "vdu_count_index": None,
971 "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
972 "vdu_name": "mgmtvm",
973 "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
974 "charm_name": "",
975 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
976 },
977 {
978 "target_element": "ns",
979 "member-vnf-index": None,
980 "vdu_id": None,
981 "kdu_name": None,
982 "vdu_count_index": None,
983 "vnfd_id": "",
984 "vdu_name": "",
985 "ee_descriptor_id": "",
986 "charm_name": "",
987 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
988 },
989 ]
990 }
991 }
992 }
993 expected_result = [
994 {
995 "target_element": "ns",
996 "member-vnf-index": None,
997 "vdu_id": None,
998 "kdu_name": None,
999 "vdu_count_index": None,
1000 "vnfd_id": "",
1001 "vdu_name": "",
1002 "ee_descriptor_id": "",
1003 "charm_name": "",
1004 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
1005 }
1006 ]
1007 vca_records = self.n2vc._get_vca_records(charm_level, db_nsr, db_vnfr)
1008 self.assertEqual(vca_records, expected_result)
1009
1010 def test_get_application_name_vnf_charm(self):
1011 namespace = ".dbfbd751-3de4-4e68-bd40-ec5ae0a53898.1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0"
1012 self.db.get_one.return_value = {
1013 "_admin": {
1014 "deployed": {
1015 "VCA": [
1016 {
1017 "target_element": "vnf/vnf1/mgmtvm",
1018 "member-vnf-index": "vnf111-xxx-yyy-zzz",
1019 "vdu_id": "38912ff7-5bdd-4228-911f-c2bee259c44a",
1020 "kdu_name": None,
1021 "vdu_count_index": None,
1022 "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
1023 "vdu_name": "mgmtvm",
1024 "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
1025 "charm_name": "",
1026 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
1027 },
1028 {
1029 "target_element": "ns",
1030 "member-vnf-index": None,
1031 "vdu_id": None,
1032 "kdu_name": None,
1033 "vdu_count_index": None,
1034 "vnfd_id": "",
1035 "vdu_name": "",
1036 "ee_descriptor_id": "",
1037 "charm_name": "",
1038 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
1039 },
1040 ]
1041 }
1042 }
1043 }
1044 mock_vnf_count_and_record = MagicMock()
1045 db_vnfr = {"member-vnf-index-ref": "vnf111-xxx-yyy-zzz"}
1046 vnf_count = "0"
1047 mock_vnf_count_and_record.return_value = (vnf_count, db_vnfr)
1048 expected_result = "simple-ee-ab-z0-vnf111-xxx-y-vnf"
1049 with patch.object(self.n2vc, "db", self.db), patch.object(
1050 self.n2vc, "_get_vnf_count_and_record", mock_vnf_count_and_record
1051 ):
1052 application_name = self.n2vc._get_application_name(namespace)
1053 self.assertEqual(application_name, expected_result)
1054 self.assertLess(len(application_name), 50)
1055 mock_vnf_count_and_record.assert_called_once_with(
1056 "vnf-level", "1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0"
1057 )
1058 self.db.get_one.assert_called_once()
1059
1060 @patch(
1061 "n2vc.n2vc_juju_conn.generate_random_alfanum_string",
1062 **{"return_value": "random"}
1063 )
1064 def test_get_application_name_vnf_charm_old_naming(
1065 self, mock_generate_random_alfanum
1066 ):
1067 namespace = ".dbfbd751-3de4-4e68-bd40-ec5ae0a53898.1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0"
1068 self.db.get_one.return_value = {
1069 "_admin": {
1070 "deployed": {
1071 "VCA": [
1072 {
1073 "target_element": "vnf/vnf1/mgmtvm",
1074 "member-vnf-index": "vnf111-xxx-yyy-zzz",
1075 "vdu_id": "38912ff7-5bdd-4228-911f-c2bee259c44a",
1076 "kdu_name": None,
1077 "vdu_count_index": None,
1078 "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
1079 "vdu_name": "mgmtvm",
1080 "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
1081 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
1082 },
1083 {
1084 "target_element": "ns",
1085 "member-vnf-index": None,
1086 "vdu_id": None,
1087 "kdu_name": None,
1088 "vdu_count_index": None,
1089 "vnfd_id": "",
1090 "vdu_name": "",
1091 "ee_descriptor_id": "",
1092 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
1093 },
1094 ]
1095 }
1096 }
1097 }
1098 mock_vnf_count_and_record = MagicMock()
1099 db_vnfr = {"member-vnf-index-ref": "vnf111-xxx-yyy-zzz"}
1100 vnf_count = "0"
1101 mock_vnf_count_and_record.return_value = (vnf_count, db_vnfr)
1102 expected_result = "app-vnf-eb3161eec0-z0-random"
1103 with patch.object(self.n2vc, "db", self.db), patch.object(
1104 self.n2vc, "_get_vnf_count_and_record", mock_vnf_count_and_record
1105 ):
1106 application_name = self.n2vc._get_application_name(namespace)
1107 self.assertEqual(application_name, expected_result)
1108 mock_vnf_count_and_record.assert_called_once_with(
1109 "vnf-level", "1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0"
1110 )
1111 self.db.get_one.assert_called_once()
1112
1113 def test_get_application_name_vnf_charm_vnf_index_ref_mismatch(self):
1114 namespace = ".dbfbd751-3de4-4e68-bd40-ec5ae0a53898.1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0"
1115 self.db.get_one.return_value = {
1116 "_admin": {
1117 "deployed": {
1118 "VCA": [
1119 {
1120 "target_element": "vnf/vnf1/mgmtvm",
1121 "member-vnf-index": "vnf111-xxx-yyy-zzz",
1122 "vdu_id": "38912ff7-5bdd-4228-911f-c2bee259c44a",
1123 "kdu_name": None,
1124 "vdu_count_index": None,
1125 "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
1126 "vdu_name": "mgmtvm",
1127 "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
1128 "charm_name": "",
1129 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
1130 },
1131 {
1132 "target_element": "ns",
1133 "member-vnf-index": None,
1134 "vdu_id": None,
1135 "kdu_name": None,
1136 "vdu_count_index": None,
1137 "vnfd_id": "",
1138 "vdu_name": "",
1139 "ee_descriptor_id": "",
1140 "charm_name": "",
1141 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
1142 },
1143 ]
1144 }
1145 }
1146 }
1147 mock_vnf_count_and_record = MagicMock()
1148 db_vnfr = {"member-vnf-index-ref": "vnf222-xxx-yyy-zzz"}
1149 vnf_count = "0"
1150 mock_vnf_count_and_record.return_value = (vnf_count, db_vnfr)
1151 with patch.object(self.n2vc, "db", self.db), patch.object(
1152 self.n2vc, "_get_vnf_count_and_record", mock_vnf_count_and_record
1153 ):
1154 with self.assertRaises(N2VCException):
1155 self.n2vc._get_application_name(namespace)
1156 mock_vnf_count_and_record.assert_called_once_with(
1157 "vnf-level", "1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0"
1158 )
1159 self.db.get_one.assert_called_once()
1160
1161 def test_get_application_name_vdu_charm(self):
1162 namespace = ".dbfbd751-3de4-4e68-bd40-ec5ae0a53898.1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0.mgmtVM-0"
1163 self.db.get_one.return_value = {
1164 "_admin": {
1165 "deployed": {
1166 "VCA": [
1167 {
1168 "target_element": "vnf/vnf1/mgmtvm",
1169 "member-vnf-index": "vnf111-xxx-yyy-zzz",
1170 "vdu_id": "mgmtVM",
1171 "kdu_name": None,
1172 "vdu_count_index": None,
1173 "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
1174 "vdu_name": "mgmtvm",
1175 "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
1176 "charm_name": "",
1177 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
1178 },
1179 {
1180 "target_element": "ns",
1181 "member-vnf-index": None,
1182 "vdu_id": None,
1183 "kdu_name": None,
1184 "vdu_count_index": None,
1185 "vnfd_id": "",
1186 "vdu_name": "",
1187 "ee_descriptor_id": "",
1188 "charm_name": "",
1189 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
1190 },
1191 ]
1192 }
1193 }
1194 }
1195 mock_vnf_count_and_record = MagicMock()
1196 db_vnfr = {
1197 "member-vnf-index-ref": "vnf111-xxx-yyy-zzz",
1198 "vdur": [
1199 {"_id": "38912ff7-5bdd-4228-911f-c2bee259c44a", "vdu-id-ref": "mgmtVM"},
1200 {"_id": "45512ff7-5bdd-4228-911f-c2bee259c44a", "vdu-id-ref": "dataVM"},
1201 ],
1202 }
1203 vnf_count = "0"
1204 mock_vnf_count_and_record.return_value = (vnf_count, db_vnfr)
1205 expected_result = "simple-ee-ab-z0-vnf111-xxx-y-mgmtvm-z0-vdu"
1206 with patch.object(self.n2vc, "db", self.db), patch.object(
1207 self.n2vc, "_get_vnf_count_and_record", mock_vnf_count_and_record
1208 ):
1209 application_name = self.n2vc._get_application_name(namespace)
1210 self.assertEqual(application_name, expected_result)
1211 self.assertLess(len(application_name), 50)
1212 mock_vnf_count_and_record.assert_called_once_with(
1213 "vdu-level", "1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0"
1214 )
1215 self.db.get_one.assert_called_once()
1216
1217 def test_get_application_name_kdu_charm(self):
1218 namespace = ".82b11965-e580-47c0-9ee0-329f318a305b.1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0.ldap"
1219 self.db.get_one.return_value = {
1220 "_admin": {
1221 "deployed": {
1222 "VCA": [
1223 {
1224 "target_element": "vnf/openldap/kdu/ldap",
1225 "member-vnf-index": "openldap",
1226 "vdu_id": None,
1227 "kdu_name": "ldap",
1228 "vdu_count_index": 0,
1229 "operational-status": "init",
1230 "detailed-status": "",
1231 "step": "initial-deploy",
1232 "vnfd_id": "openldap_knf",
1233 "vdu_name": None,
1234 "type": "lxc_proxy_charm",
1235 "ee_descriptor_id": "openldap-ee",
1236 "charm_name": "",
1237 "ee_id": "",
1238 "application": "openldap-ee-z0-openldap-vdu",
1239 "model": "82b11965-e580-47c0-9ee0-329f318a305b",
1240 "config_sw_installed": True,
1241 }
1242 ]
1243 }
1244 }
1245 }
1246 mock_vnf_count_and_record = MagicMock()
1247 db_vnfr = {"member-vnf-index-ref": "openldap", "vdur": {}}
1248 vnf_count = "0"
1249 mock_vnf_count_and_record.return_value = (vnf_count, db_vnfr)
1250 expected_result = "openldap-ee-z0-openldap-ldap-vdu"
1251 with patch.object(self.n2vc, "db", self.db), patch.object(
1252 self.n2vc, "_get_vnf_count_and_record", mock_vnf_count_and_record
1253 ):
1254 application_name = self.n2vc._get_application_name(namespace)
1255 self.assertEqual(application_name, expected_result)
1256 self.assertLess(len(application_name), 50)
1257 mock_vnf_count_and_record.assert_called_once_with(
1258 "vdu-level", "1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0"
1259 )
1260 self.db.get_one.assert_called_once()
1261
1262 @patch(
1263 "n2vc.n2vc_juju_conn.generate_random_alfanum_string",
1264 **{"return_value": "random"}
1265 )
1266 def test_get_application_name_vdu_charm_old_naming(
1267 self, mock_generate_random_alfanum
1268 ):
1269 namespace = ".dbfbd751-3de4-4e68-bd40-ec5ae0a53898.1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0.mgmtVM-0"
1270 self.db.get_one.return_value = {
1271 "_admin": {
1272 "deployed": {
1273 "VCA": [
1274 {
1275 "target_element": "vnf/vnf1/mgmtVM",
1276 "member-vnf-index": "vnf111-xxx-yyy-zzz",
1277 "vdu_id": "mgmtVM",
1278 "kdu_name": None,
1279 "vdu_count_index": None,
1280 "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
1281 "vdu_name": "mgmtvm",
1282 "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
1283 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
1284 },
1285 {
1286 "target_element": "ns",
1287 "member-vnf-index": None,
1288 "vdu_id": None,
1289 "kdu_name": None,
1290 "vdu_count_index": None,
1291 "vnfd_id": "",
1292 "vdu_name": "",
1293 "ee_descriptor_id": "",
1294 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
1295 },
1296 ]
1297 }
1298 }
1299 }
1300 mock_vnf_count_and_record = MagicMock()
1301 db_vnfr = {
1302 "member-vnf-index-ref": "vnf111-xxx-yyy-zzz",
1303 "vdur": [
1304 {"_id": "38912ff7-5bdd-4228-911f-c2bee259c44a", "vdu-id-ref": "mgmtVM"},
1305 {"_id": "45512ff7-5bdd-4228-911f-c2bee259c44a", "vdu-id-ref": "dataVM"},
1306 ],
1307 }
1308 vnf_count = "0"
1309 mock_vnf_count_and_record.return_value = (vnf_count, db_vnfr)
1310 expected_result = "app-vnf-eb3161eec0-z0-vdu-mgmtvm-cnt-z0-random"
1311
1312 with patch.object(self.n2vc, "db", self.db), patch.object(
1313 self.n2vc, "_get_vnf_count_and_record", mock_vnf_count_and_record
1314 ):
1315 application_name = self.n2vc._get_application_name(namespace)
1316 self.assertEqual(application_name, expected_result)
1317 self.assertLess(len(application_name), 50)
1318 mock_vnf_count_and_record.assert_called_once_with(
1319 "vdu-level", "1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0"
1320 )
1321 self.db.get_one.assert_called_once()
1322
1323 def test_get_application_name_ns_charm(self):
1324 namespace = ".dbfbd751-3de4-4e68-bd40-ec5ae0a53898"
1325 self.db.get_one.return_value = {
1326 "_admin": {
1327 "deployed": {
1328 "VCA": [
1329 {
1330 "target_element": "ns",
1331 "member-vnf-index": None,
1332 "vdu_id": None,
1333 "kdu_name": None,
1334 "vdu_count_index": None,
1335 "vnfd_id": "",
1336 "vdu_name": "",
1337 "ee_descriptor_id": "",
1338 "charm_name": "simple-ns-charm-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
1339 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
1340 }
1341 ]
1342 }
1343 }
1344 }
1345 mock_vnf_count_and_record = MagicMock()
1346 db_vnfr = {}
1347 vnf_count = ""
1348 mock_vnf_count_and_record.return_value = (vnf_count, db_vnfr)
1349 expected_result = "simple-ns-charm-abc-z000-rrrr-nnnn-z4444-h-ns"
1350 with patch.object(self.n2vc, "db", self.db), patch.object(
1351 self.n2vc, "_get_vnf_count_and_record", mock_vnf_count_and_record
1352 ):
1353 application_name = self.n2vc._get_application_name(namespace)
1354 self.assertEqual(application_name, expected_result)
1355 self.assertLess(len(application_name), 50)
1356 mock_vnf_count_and_record.assert_called_once_with("ns-level", None)
1357 self.db.get_one.assert_called_once()
1358
1359 def test_get_application_name_ns_charm_empty_charm_name(self):
1360 namespace = ".dbfbd751-3de4-4e68-bd40-ec5ae0a53898"
1361 self.db.get_one.return_value = {
1362 "_admin": {
1363 "deployed": {
1364 "VCA": [
1365 {
1366 "target_element": "ns",
1367 "member-vnf-index": None,
1368 "vdu_id": None,
1369 "kdu_name": None,
1370 "vdu_count_index": None,
1371 "vnfd_id": "",
1372 "vdu_name": "",
1373 "ee_descriptor_id": "",
1374 "charm_name": "",
1375 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
1376 }
1377 ]
1378 }
1379 }
1380 }
1381 mock_vnf_count_and_record = MagicMock()
1382 db_vnfr = {}
1383 vnf_count = ""
1384 mock_vnf_count_and_record.return_value = (vnf_count, db_vnfr)
1385 with patch.object(self.n2vc, "db", self.db), patch.object(
1386 self.n2vc, "_get_vnf_count_and_record", mock_vnf_count_and_record
1387 ):
1388 with self.assertRaises(N2VCException):
1389 self.n2vc._get_application_name(namespace)
1390 mock_vnf_count_and_record.assert_called_once_with("ns-level", None)
1391 self.db.get_one.assert_called_once()
1392
1393 @patch(
1394 "n2vc.n2vc_juju_conn.generate_random_alfanum_string",
1395 **{"return_value": "random"}
1396 )
1397 def test_get_application_name_ns_charm_old_naming(
1398 self, mock_generate_random_alfanum
1399 ):
1400 namespace = ".dbfbd751-3de4-4e68-bd40-ec5ae0a53898"
1401 self.db.get_one.return_value = {
1402 "_admin": {
1403 "deployed": {
1404 "VCA": [
1405 {
1406 "target_element": "ns",
1407 "member-vnf-index": None,
1408 "vdu_id": None,
1409 "kdu_name": None,
1410 "vdu_count_index": None,
1411 "vnfd_id": "",
1412 "vdu_name": "",
1413 "ee_descriptor_id": "",
1414 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
1415 }
1416 ]
1417 }
1418 }
1419 }
1420 mock_vnf_count_and_record = MagicMock()
1421 db_vnfr = {}
1422 vnf_count = ""
1423 mock_vnf_count_and_record.return_value = (vnf_count, db_vnfr)
1424 expected_result = "app-random"
1425 with patch.object(self.n2vc, "db", self.db), patch.object(
1426 self.n2vc, "_get_vnf_count_and_record", mock_vnf_count_and_record
1427 ):
1428 application_name = self.n2vc._get_application_name(namespace)
1429 self.assertEqual(application_name, expected_result)
1430 self.assertLess(len(application_name), 50)
1431 mock_vnf_count_and_record.assert_called_once_with("ns-level", None)
1432 self.db.get_one.assert_called_once()
1433
1434
1435 class DeleteExecutionEnvironmentTest(N2VCJujuConnTestCase):
1436 def setUp(self):
1437 super(DeleteExecutionEnvironmentTest, self).setUp()
1438 self.n2vc.libjuju.get_controller = AsyncMock()
1439 self.n2vc.libjuju.destroy_model = AsyncMock()
1440 self.n2vc.libjuju.destroy_application = AsyncMock()
1441
1442 def test_remove_ee__target_application_exists__model_is_deleted(self):
1443 get_ee_id_components = MagicMock()
1444 get_ee_id_components.return_value = ("my_model", "my_app", None)
1445 model = MagicMock(create_autospec=True)
1446 model.applications = {}
1447 self.n2vc.libjuju.get_model = AsyncMock()
1448 self.n2vc.libjuju.get_model.return_value = model
1449 with patch.object(self.n2vc, "_get_ee_id_components", get_ee_id_components):
1450 self.loop.run_until_complete(
1451 self.n2vc.delete_execution_environment(
1452 "my_ee", application_to_delete="my_app"
1453 )
1454 )
1455 self.n2vc.libjuju.destroy_application.assert_called_with(
1456 model_name="my_model",
1457 application_name="my_app",
1458 total_timeout=None,
1459 )
1460 self.n2vc.libjuju.destroy_model.assert_called_with(
1461 model_name="my_model",
1462 total_timeout=None,
1463 )
1464
1465 def test_remove_ee__multiple_applications_exist__model_is_not_deleted(self):
1466 get_ee_id_components = MagicMock()
1467 get_ee_id_components.return_value = ("my_model", "my_app", None)
1468 model = MagicMock(create_autospec=True)
1469 model.applications = {MagicMock(create_autospec=True)}
1470 self.n2vc.libjuju.get_model = AsyncMock()
1471 self.n2vc.libjuju.get_model.return_value = model
1472 with patch.object(self.n2vc, "_get_ee_id_components", get_ee_id_components):
1473 self.loop.run_until_complete(
1474 self.n2vc.delete_execution_environment(
1475 "my_ee", application_to_delete="my_app"
1476 )
1477 )
1478 self.n2vc.libjuju.destroy_application.assert_called_with(
1479 model_name="my_model",
1480 application_name="my_app",
1481 total_timeout=None,
1482 )
1483 self.n2vc.libjuju.destroy_model.assert_not_called()
1484
1485 def test_remove_ee__target_application_does_not_exist__model_is_deleted(self):
1486 get_ee_id_components = MagicMock()
1487 get_ee_id_components.return_value = ("my_model", "my_app", None)
1488 with patch.object(self.n2vc, "_get_ee_id_components", get_ee_id_components):
1489 self.loop.run_until_complete(
1490 self.n2vc.delete_execution_environment("my_ee")
1491 )
1492 self.n2vc.libjuju.destroy_model.assert_called_with(
1493 model_name="my_model",
1494 total_timeout=None,
1495 )