Coverage for n2vc/tests/unit/test_n2vc_juju_conn.py: 98%
527 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-05-07 06:04 +0000
« prev ^ index » next coverage.py v7.6.12, created at 2025-05-07 06:04 +0000
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.
16import asyncio
17import logging
18from unittest.mock import Mock, MagicMock
19from unittest.mock import patch
22import asynctest
23from n2vc.definitions import Offer, RelationEndpoint
24from n2vc.n2vc_juju_conn import N2VCJujuConnector
25from osm_common import fslocal
26from osm_common.dbmemory import DbMemory
27from n2vc.exceptions import (
28 N2VCBadArgumentsException,
29 N2VCException,
30 JujuApplicationNotFound,
31)
32from n2vc.tests.unit.utils import AsyncMock
33from n2vc.vca.connection_data import ConnectionData
34from n2vc.tests.unit.testdata import test_db_descriptors as descriptors
35import yaml
38class 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)
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()
82class GetMetricssTest(N2VCJujuConnTestCase):
83 def setUp(self):
84 super(GetMetricssTest, self).setUp()
85 self.n2vc.libjuju.get_metrics = AsyncMock()
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()
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()
100class 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()
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()
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()
136class 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))
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 )
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 )
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)
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)
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)
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)
246class 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()
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()
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 )
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 )
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 )
313class 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()
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()
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()
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 )
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 )
398class GenerateApplicationNameTest(N2VCJujuConnTestCase):
399 vnf_id = "dbfbd751-3de4-4e68-bd40-ec5ae0a53898"
401 def setUp(self):
402 super(GenerateApplicationNameTest, self).setUp()
403 self.db = MagicMock(DbMemory)
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"
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)
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 )
436 self.assertEqual(application_name, expected_result)
437 self.assertLess(len(application_name), 50)
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)
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)
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)
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)
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)
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 )
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)
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)
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)
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 )
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 )
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 )
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)
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, {})
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"})
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"})
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)
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)
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)
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)
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()
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()
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()
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()
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()
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"
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()
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()
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()
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()
1435class 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()
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 )
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()
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 )