1 # Copyright 2020 Canonical Ltd.
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
18 from unittest
.mock
import Mock
, MagicMock
19 from unittest
.mock
import patch
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
,
30 JujuApplicationNotFound
,
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
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")
44 mock_base64_to_cacert
=None,
45 mock_get_connection
=None,
48 self
.loop
= asyncio
.get_event_loop()
50 mock_base64_to_cacert
.return_value
= """
51 -----BEGIN CERTIFICATE-----
53 -----END CERTIFICATE-----"""
54 mock_store
.return_value
= AsyncMock()
55 mock_vca_connection
= Mock()
56 mock_get_connection
.return_value
= mock_vca_connection
57 mock_vca_connection
.data
.return_value
= ConnectionData(
59 "endpoints": ["1.2.3.4:17070"],
65 "lxd-credentials": "credentials",
66 "k8s-cloud": "k8s_cloud",
67 "k8s-credentials": "k8s_credentials",
69 "api-proxy": "api_proxy",
72 logging
.disable(logging
.CRITICAL
)
74 N2VCJujuConnector
.get_public_key
= Mock()
75 self
.n2vc
= N2VCJujuConnector(
82 N2VCJujuConnector
.get_public_key
.assert_not_called()
83 self
.n2vc
.libjuju
= Mock()
86 class GetMetricssTest(N2VCJujuConnTestCase
):
88 super(GetMetricssTest
, self
).setUp()
89 self
.n2vc
.libjuju
.get_metrics
= AsyncMock()
91 def test_success(self
):
92 _
= self
.loop
.run_until_complete(self
.n2vc
.get_metrics("model", "application"))
93 self
.n2vc
.libjuju
.get_metrics
.assert_called_once()
95 def test_except(self
):
96 self
.n2vc
.libjuju
.get_metrics
.side_effect
= Exception()
97 with self
.assertRaises(Exception):
98 _
= self
.loop
.run_until_complete(
99 self
.n2vc
.get_metrics("model", "application")
101 self
.n2vc
.libjuju
.get_metrics
.assert_called_once()
104 class UpdateVcaStatusTest(N2VCJujuConnTestCase
):
106 super(UpdateVcaStatusTest
, self
).setUp()
107 self
.n2vc
.libjuju
.get_controller
= AsyncMock()
108 self
.n2vc
.libjuju
.get_model
= AsyncMock()
109 self
.n2vc
.libjuju
.get_executed_actions
= AsyncMock()
110 self
.n2vc
.libjuju
.get_actions
= AsyncMock()
111 self
.n2vc
.libjuju
.get_application_configs
= AsyncMock()
112 self
.n2vc
.libjuju
._get
_application
= AsyncMock()
117 self
.loop
.run_until_complete(
118 self
.n2vc
.update_vca_status(
119 {"model": {"applications": {"app": {"actions": {}}}}}
122 self
.n2vc
.libjuju
.get_executed_actions
.assert_called_once()
123 self
.n2vc
.libjuju
.get_actions
.assert_called_once()
124 self
.n2vc
.libjuju
.get_application_configs
.assert_called_once()
126 def test_exception(self
):
127 self
.n2vc
.libjuju
.get_model
.return_value
= None
128 self
.n2vc
.libjuju
.get_executed_actions
.side_effect
= Exception()
129 with self
.assertRaises(Exception):
130 self
.loop
.run_until_complete(
131 self
.n2vc
.update_vca_status(
132 {"model": {"applications": {"app": {"actions": {}}}}}
135 self
.n2vc
.libjuju
.get_executed_actions
.assert_not_called()
136 self
.n2vc
.libjuju
.get_actions
.assert_not_called_once()
137 self
.n2vc
.libjuju
.get_application_configs
.assert_not_called_once()
140 class K8sProxyCharmsTest(N2VCJujuConnTestCase
):
142 super(K8sProxyCharmsTest
, self
).setUp()
143 self
.n2vc
.libjuju
.model_exists
= AsyncMock()
144 self
.n2vc
.libjuju
.add_model
= AsyncMock()
145 self
.n2vc
.libjuju
.deploy_charm
= AsyncMock()
146 self
.n2vc
.libjuju
.model_exists
.return_value
= False
148 self
.fs
= fslocal
.FsLocal()
150 self
.n2vc
.fs
= self
.fs
151 self
.n2vc
.db
= self
.db
152 self
.db
.create_list("nsrs", yaml
.safe_load(descriptors
.db_nsrs_text
))
153 self
.db
.create_list("vnfrs", yaml
.safe_load(descriptors
.db_vnfrs_text
))
156 "n2vc.n2vc_juju_conn.generate_random_alfanum_string",
157 **{"return_value": "random"}
161 mock_generate_random_alfanum_string
,
163 self
.n2vc
.fs
.file_exists
= MagicMock(create_autospec
=True)
164 self
.n2vc
.fs
.file_exists
.return_value
= True
165 ee_id
= self
.loop
.run_until_complete(
166 self
.n2vc
.install_k8s_proxy_charm(
168 ".dbfbd751-3de4-4e68-bd40-ec5ae0a53898.1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0",
174 self
.n2vc
.libjuju
.add_model
.assert_called_once()
175 self
.n2vc
.libjuju
.deploy_charm
.assert_called_once_with(
176 model_name
="dbfbd751-3de4-4e68-bd40-ec5ae0a53898-k8s",
177 application_name
="simple-ee-z0-vnf1-vnf",
181 progress_timeout
=None,
186 ee_id
, "dbfbd751-3de4-4e68-bd40-ec5ae0a53898-k8s.simple-ee-z0-vnf1-vnf.k8s"
189 def test_no_artifact_path(
192 with self
.assertRaises(N2VCBadArgumentsException
):
193 ee_id
= self
.loop
.run_until_complete(
194 self
.n2vc
.install_k8s_proxy_charm(
196 ".dbfbd751-3de4-4e68-bd40-ec5ae0a53898.1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0",
201 self
.assertIsNone(ee_id
)
206 with self
.assertRaises(N2VCBadArgumentsException
):
207 ee_id
= self
.loop
.run_until_complete(
208 self
.n2vc
.install_k8s_proxy_charm(
210 ".dbfbd751-3de4-4e68-bd40-ec5ae0a53898.1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0",
215 self
.assertIsNone(ee_id
)
217 def test_file_not_exists(
220 self
.n2vc
.fs
.file_exists
= MagicMock(create_autospec
=True)
221 self
.n2vc
.fs
.file_exists
.return_value
= False
222 with self
.assertRaises(N2VCBadArgumentsException
):
223 ee_id
= self
.loop
.run_until_complete(
224 self
.n2vc
.install_k8s_proxy_charm(
226 ".dbfbd751-3de4-4e68-bd40-ec5ae0a53898.1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0",
231 self
.assertIsNone(ee_id
)
236 self
.n2vc
.fs
.file_exists
= MagicMock(create_autospec
=True)
237 self
.n2vc
.fs
.file_exists
.return_value
= True
238 self
.n2vc
.fs
.path
= MagicMock(create_autospec
=True)
239 self
.n2vc
.fs
.path
.return_value
= "path"
240 self
.n2vc
.libjuju
.deploy_charm
.side_effect
= Exception()
241 with self
.assertRaises(N2VCException
):
242 ee_id
= self
.loop
.run_until_complete(
243 self
.n2vc
.install_k8s_proxy_charm(
245 ".dbfbd751-3de4-4e68-bd40-ec5ae0a53898.1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0",
250 self
.assertIsNone(ee_id
)
253 class AddRelationTest(N2VCJujuConnTestCase
):
255 super(AddRelationTest
, self
).setUp()
256 self
.n2vc
.libjuju
.add_relation
= AsyncMock()
257 self
.n2vc
.libjuju
.offer
= AsyncMock()
258 self
.n2vc
.libjuju
.get_controller
= AsyncMock()
259 self
.n2vc
.libjuju
.consume
= AsyncMock()
261 def test_standard_relation(self
):
262 relation_endpoint_1
= RelationEndpoint("model-1.app1.0", None, "endpoint")
263 relation_endpoint_2
= RelationEndpoint("model-1.app2.1", None, "endpoint")
264 self
.loop
.run_until_complete(
265 self
.n2vc
.add_relation(relation_endpoint_1
, relation_endpoint_2
)
267 self
.n2vc
.libjuju
.add_relation
.assert_called_once_with(
268 model_name
="model-1", endpoint_1
="app1:endpoint", endpoint_2
="app2:endpoint"
270 self
.n2vc
.libjuju
.offer
.assert_not_called()
271 self
.n2vc
.libjuju
.consume
.assert_not_called()
273 def test_cmr_relation_same_controller(self
):
274 relation_endpoint_1
= RelationEndpoint("model-1.app1.0", None, "endpoint")
275 relation_endpoint_2
= RelationEndpoint("model-2.app2.1", None, "endpoint")
276 offer
= Offer("admin/model-1.app1")
277 self
.n2vc
.libjuju
.offer
.return_value
= offer
278 self
.n2vc
.libjuju
.consume
.return_value
= "saas"
279 self
.loop
.run_until_complete(
280 self
.n2vc
.add_relation(relation_endpoint_1
, relation_endpoint_2
)
282 self
.n2vc
.libjuju
.offer
.assert_called_once_with(relation_endpoint_1
)
283 self
.n2vc
.libjuju
.consume
.assert_called_once()
284 self
.n2vc
.libjuju
.add_relation
.assert_called_once_with(
285 "model-2", "app2:endpoint", "saas"
288 def test_relation_exception(self
):
289 relation_endpoint_1
= RelationEndpoint("model-1.app1.0", None, "endpoint")
290 relation_endpoint_2
= RelationEndpoint("model-2.app2.1", None, "endpoint")
291 self
.n2vc
.libjuju
.offer
.side_effect
= Exception()
292 with self
.assertRaises(N2VCException
):
293 self
.loop
.run_until_complete(
294 self
.n2vc
.add_relation(relation_endpoint_1
, relation_endpoint_2
)
298 class UpgradeCharmTest(N2VCJujuConnTestCase
):
300 super(UpgradeCharmTest
, self
).setUp()
301 self
.n2vc
._get
_libjuju
= AsyncMock(return_value
=self
.n2vc
.libjuju
)
302 N2VCJujuConnector
._get
_ee
_id
_components
= Mock()
303 self
.n2vc
.libjuju
.upgrade_charm
= AsyncMock()
305 def test_empty_ee_id(self
):
306 with self
.assertRaises(N2VCBadArgumentsException
):
307 self
.loop
.run_until_complete(
308 self
.n2vc
.upgrade_charm(
309 "", "/sample_charm_path", "sample_charm_id", "native-charm", None
312 self
.n2vc
._get
_libjuju
.assert_called()
313 self
.n2vc
._get
_ee
_id
_components
.assert_not_called()
314 self
.n2vc
.libjuju
.upgrade_charm
.assert_not_called()
316 def test_wrong_ee_id(self
):
317 N2VCJujuConnector
._get
_ee
_id
_components
.side_effect
= Exception
318 with self
.assertRaises(N2VCBadArgumentsException
):
319 self
.loop
.run_until_complete(
320 self
.n2vc
.upgrade_charm(
321 "ns-id-k8s.app-vnf-vnf-id-vdu-vdu-random.k8s",
322 "/sample_charm_path",
328 self
.n2vc
._get
_libjuju
.assert_called()
329 self
.n2vc
._get
_ee
_id
_components
.assert_called()
330 self
.n2vc
.libjuju
.upgrade_charm
.assert_not_called()
332 def test_charm_upgrade_succeded(self
):
333 N2VCJujuConnector
._get
_ee
_id
_components
.return_value
= (
338 self
.loop
.run_until_complete(
339 self
.n2vc
.upgrade_charm(
340 "ns-id-k8s.app-vnf-vnf-id-vdu-vdu-random.k8s",
341 "/sample_charm_path",
347 self
.n2vc
._get
_libjuju
.assert_called()
348 self
.n2vc
._get
_ee
_id
_components
.assert_called()
349 self
.n2vc
.libjuju
.upgrade_charm
.assert_called_with(
350 application_name
="sample_app",
351 path
="/sample_charm_path",
352 model_name
="sample_model",
356 def test_charm_upgrade_failed(self
):
357 N2VCJujuConnector
._get
_ee
_id
_components
.return_value
= (
362 self
.n2vc
.libjuju
.upgrade_charm
.side_effect
= JujuApplicationNotFound
363 with self
.assertRaises(N2VCException
):
364 self
.loop
.run_until_complete(
365 self
.n2vc
.upgrade_charm(
366 "ns-id-k8s.app-vnf-vnf-id-vdu-vdu-random.k8s",
367 "/sample_charm_path",
373 self
.n2vc
._get
_libjuju
.assert_called()
374 self
.n2vc
._get
_ee
_id
_components
.assert_called()
375 self
.n2vc
.libjuju
.upgrade_charm
.assert_called_with(
376 application_name
="sample_app",
377 path
="/sample_charm_path",
378 model_name
="sample_model",
383 class GenerateApplicationNameTest(N2VCJujuConnTestCase
):
385 vnf_id
= "dbfbd751-3de4-4e68-bd40-ec5ae0a53898"
388 super(GenerateApplicationNameTest
, self
).setUp()
389 self
.db
= MagicMock(DbMemory
)
392 "n2vc.n2vc_juju_conn.generate_random_alfanum_string",
393 **{"return_value": "random"}
395 def test_generate_backward_compatible_application_name(
396 self
, mock_generate_random_alfanum
400 expected_result
= "app-vnf-ec5ae0a53898-vdu-mgmtVM-cnt-0-random"
402 application_name
= self
.n2vc
._generate
_backward
_compatible
_application
_name
(
403 GenerateApplicationNameTest
.vnf_id
, vdu_id
, vdu_count
405 self
.assertEqual(application_name
, expected_result
)
408 "n2vc.n2vc_juju_conn.generate_random_alfanum_string",
409 **{"return_value": "random"}
411 def test_generate_backward_compatible_application_name_without_vnf_id_vdu_id(
412 self
, mock_generate_random_alfanum
417 expected_result
= "app--random"
418 application_name
= self
.n2vc
._generate
_backward
_compatible
_application
_name
(
419 vnf_id
, vdu_id
, vdu_count
422 self
.assertEqual(application_name
, expected_result
)
423 self
.assertLess(len(application_name
), 50)
425 def test_find_charm_level_with_vnf_id(self
):
427 expected_result
= "vnf-level"
428 charm_level
= self
.n2vc
._find
_charm
_level
(
429 GenerateApplicationNameTest
.vnf_id
, vdu_id
431 self
.assertEqual(charm_level
, expected_result
)
433 def test_find_charm_level_with_vdu_id(self
):
436 with self
.assertRaises(N2VCException
):
437 self
.n2vc
._find
_charm
_level
(vnf_id
, vdu_id
)
439 def test_find_charm_level_with_vnf_id_and_vdu_id(self
):
441 expected_result
= "vdu-level"
442 charm_level
= self
.n2vc
._find
_charm
_level
(
443 GenerateApplicationNameTest
.vnf_id
, vdu_id
445 self
.assertEqual(charm_level
, expected_result
)
447 def test_find_charm_level_without_vnf_id_and_vdu_id(self
):
450 expected_result
= "ns-level"
451 charm_level
= self
.n2vc
._find
_charm
_level
(vnf_id
, vdu_id
)
452 self
.assertEqual(charm_level
, expected_result
)
454 def test_generate_application_name_ns_charm(self
):
455 charm_level
= "ns-level"
459 "target_element": "ns",
460 "member-vnf-index": "",
463 "vdu_count_index": None,
466 "type": "proxy_charm",
467 "ee_descriptor_id": None,
468 "charm_name": "simple-ns-charm-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh",
471 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
476 expected_result
= "simple-ns-charm-abc-000-rrrr-nnnn-4444-h-ns"
477 application_name
= self
.n2vc
._generate
_application
_name
(
484 self
.assertEqual(application_name
, expected_result
)
485 self
.assertLess(len(application_name
), 50)
487 def test_generate_application_name_ns_charm_empty_vca_records(self
):
488 charm_level
= "ns-level"
493 with self
.assertRaises(N2VCException
):
494 self
.n2vc
._generate
_application
_name
(
502 def test_generate_application_name_vnf_charm(self
):
503 charm_level
= "vnf-level"
505 "member-vnf-index-ref": "vnf111-xxx-yyy-zzz",
509 "target_element": "vnf/vnf1",
510 "member-vnf-index": "vnf111-xxx-yyy-zzz",
511 "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
512 "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
514 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
519 expected_result
= "simple-ee-ab-1-vnf111-xxx-y-vnf"
520 application_name
= self
.n2vc
._generate
_application
_name
(
527 self
.assertEqual(application_name
, expected_result
)
528 self
.assertLess(len(application_name
), 50)
530 def test_generate_application_name_vdu_charm(self
):
531 charm_level
= "vdu-level"
533 "member-vnf-index-ref": "vnf111-xxx-yyy-zzz",
535 {"_id": "38912ff7-5bdd-4228-911f-c2bee259c44a", "vdu-id-ref": "mgmtVM"},
536 {"_id": "45512ff7-5bdd-4228-911f-c2bee259c44a", "vdu-id-ref": "dataVM"},
541 "target_element": "vnf/vnf1/mgmtvm",
542 "member-vnf-index": "vnf111-xxx-yyy-zzz",
543 "vdu_id": "38912ff7-5bdd-4228-911f-c2bee259c44a",
545 "vdu_count_index": None,
546 "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
547 "vdu_name": "mgmtvm",
548 "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
550 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
553 "target_element": "vnf/vnf1/datavm",
554 "member-vnf-index": "vnf111-xxx-yyy-zzz",
555 "vdu_id": "45512ff7-5bdd-4228-911f-c2bee259c44a",
557 "vdu_count_index": None,
558 "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
559 "vdu_name": "datavm",
560 "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-8888-hhh-3333-yyyy-888-hhh-ttt-444",
562 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
567 expected_result
= "simple-ee-ab-2-vnf111-xxx-y-mgmtVM-0-vdu"
568 application_name
= self
.n2vc
._generate
_application
_name
(
575 self
.assertEqual(application_name
, expected_result
)
576 self
.assertLess(len(application_name
), 50)
578 def test_generate_application_name_vdu_charm_wrong_vnfrs(self
):
579 charm_level
= "vdu-level"
581 "member-vnf-index-ref": "vnf111-xxx-yyy-zzz",
585 "target_element": "vnf/vnf1/mgmtvm",
586 "member-vnf-index": "vnf111-xxx-yyy-zzz",
587 "vdu_id": "38912ff7-5bdd-4228-911f-c2bee259c44a",
589 "vdu_count_index": None,
590 "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
591 "vdu_name": "mgmtvm",
592 "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
594 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
599 with self
.assertRaises(KeyError):
600 self
.n2vc
._generate
_application
_name
(
608 def test_get_vnf_count_db_vnfr_ns_charm(self
):
609 self
.db
.get_one
.return_value
= {"member-vnf-index-ref": "sample-ref"}
610 charm_level
= "ns-level"
611 vnf_id_and_count
= "m7fbd751-3de4-4e68-bd40-ec5ae0a53898-4"
612 with patch
.object(self
.n2vc
, "db", self
.db
):
613 vnf_count
, db_vnfr
= self
.n2vc
._get
_vnf
_count
_and
_record
(
614 charm_level
, vnf_id_and_count
616 self
.assertEqual(vnf_count
, "")
617 self
.assertEqual(db_vnfr
, {})
619 def test_get_vnf_count_db_vnfr_vnf_charm(self
):
620 self
.db
.get_one
.return_value
= {"member-vnf-index-ref": "sample-ref"}
621 charm_level
= "vnf-level"
622 vnf_id_and_count
= "m7fbd751-3de4-4e68-bd40-ec5ae0a53898-4"
623 with patch
.object(self
.n2vc
, "db", self
.db
):
624 vnf_count
, db_vnfr
= self
.n2vc
._get
_vnf
_count
_and
_record
(
625 charm_level
, vnf_id_and_count
627 self
.assertEqual(vnf_count
, "4")
628 self
.assertEqual(db_vnfr
, {"member-vnf-index-ref": "sample-ref"})
630 def test_get_vnf_count_db_vnfr_vdu_charm(self
):
631 self
.db
.get_one
.return_value
= {"member-vnf-index-ref": "sample-ref"}
632 charm_level
= "vdu-level"
633 vnf_id_and_count
= "m7fbd751-3de4-4e68-bd40-ec5ae0a53898-2"
634 with patch
.object(self
.n2vc
, "db", self
.db
):
635 vnf_count
, db_vnfr
= self
.n2vc
._get
_vnf
_count
_and
_record
(
636 charm_level
, vnf_id_and_count
638 self
.assertEqual(vnf_count
, "2")
639 self
.assertEqual(db_vnfr
, {"member-vnf-index-ref": "sample-ref"})
641 def test_get_vca_records_vdu_charm(self
):
642 charm_level
= "vdu-level"
644 "member-vnf-index-ref": "vnf111-xxx-yyy-zzz",
646 {"_id": "38912ff7-5bdd-4228-911f-c2bee259c44a", "vdu-id-ref": "mgmtVM"},
647 {"_id": "45512ff7-5bdd-4228-911f-c2bee259c44a", "vdu-id-ref": "dataVM"},
655 "target_element": "vnf/vnf1/mgmtvm",
656 "member-vnf-index": "vnf111-xxx-yyy-zzz",
657 "vdu_id": "38912ff7-5bdd-4228-911f-c2bee259c44a",
659 "vdu_count_index": None,
660 "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
661 "vdu_name": "mgmtvm",
662 "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
664 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
667 "target_element": "vnf/vnf2/datavm",
668 "member-vnf-index": "vnf222-xxx-yyy-zzz",
669 "vdu_id": "45512ff7-5bdd-4228-911f-c2bee259c44a",
671 "vdu_count_index": None,
672 "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
673 "vdu_name": "datavm",
674 "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-8888-hhh-3333-yyyy-888-hhh-ttt-444",
676 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
684 "target_element": "vnf/vnf1/mgmtvm",
685 "member-vnf-index": "vnf111-xxx-yyy-zzz",
686 "vdu_id": "38912ff7-5bdd-4228-911f-c2bee259c44a",
688 "vdu_count_index": None,
689 "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
690 "vdu_name": "mgmtvm",
691 "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
693 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
696 vca_records
= self
.n2vc
._get
_vca
_records
(charm_level
, db_nsr
, db_vnfr
)
697 self
.assertEqual(vca_records
, expected_result
)
699 def test_get_vca_records_vnf_charm_member_vnf_index_mismatch(self
):
700 charm_level
= "vnf-level"
702 "member-vnf-index-ref": "vnf222-xxx-yyy-zzz",
709 "target_element": "vnf/vnf1/mgmtvm",
710 "member-vnf-index": "vnf111-xxx-yyy-zzz",
711 "vdu_id": "38912ff7-5bdd-4228-911f-c2bee259c44a",
713 "vdu_count_index": None,
714 "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
715 "vdu_name": "mgmtvm",
716 "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
718 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
721 "target_element": "vnf/vnf1/mgmtvm",
722 "member-vnf-index": "vnf111-xxx-yyy-zzz",
723 "vdu_id": "45512ff7-5bdd-4228-911f-c2bee259c44a",
725 "vdu_count_index": None,
726 "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
727 "vdu_name": "datavm",
728 "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-8888-hhh-3333-yyyy-888-hhh-ttt-444",
730 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
737 vca_records
= self
.n2vc
._get
_vca
_records
(charm_level
, db_nsr
, db_vnfr
)
738 self
.assertEqual(vca_records
, expected_result
)
740 def test_get_vca_records_ns_charm(self
):
741 charm_level
= "ns-level"
743 "member-vnf-index-ref": "vnf222-xxx-yyy-zzz",
750 "target_element": "vnf/vnf1/mgmtvm",
751 "member-vnf-index": "vnf111-xxx-yyy-zzz",
752 "vdu_id": "38912ff7-5bdd-4228-911f-c2bee259c44a",
754 "vdu_count_index": None,
755 "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
756 "vdu_name": "mgmtvm",
757 "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
759 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
762 "target_element": "ns",
763 "member-vnf-index": None,
766 "vdu_count_index": None,
769 "ee_descriptor_id": "",
770 "charm_name": "simple-ns-charm-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
771 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
779 "target_element": "ns",
780 "member-vnf-index": None,
783 "vdu_count_index": None,
786 "ee_descriptor_id": "",
787 "charm_name": "simple-ns-charm-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
788 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
791 vca_records
= self
.n2vc
._get
_vca
_records
(charm_level
, db_nsr
, db_vnfr
)
792 self
.assertEqual(vca_records
, expected_result
)
794 def test_get_vca_records_ns_charm_empty_charm_name(self
):
795 charm_level
= "ns-level"
797 "member-vnf-index-ref": "vnf222-xxx-yyy-zzz",
804 "target_element": "vnf/vnf1/mgmtvm",
805 "member-vnf-index": "vnf111-xxx-yyy-zzz",
806 "vdu_id": "38912ff7-5bdd-4228-911f-c2bee259c44a",
808 "vdu_count_index": None,
809 "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
810 "vdu_name": "mgmtvm",
811 "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
813 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
816 "target_element": "ns",
817 "member-vnf-index": None,
820 "vdu_count_index": None,
823 "ee_descriptor_id": "",
825 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
833 "target_element": "ns",
834 "member-vnf-index": None,
837 "vdu_count_index": None,
840 "ee_descriptor_id": "",
842 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
845 vca_records
= self
.n2vc
._get
_vca
_records
(charm_level
, db_nsr
, db_vnfr
)
846 self
.assertEqual(vca_records
, expected_result
)
848 def test_get_application_name_vnf_charm(self
):
849 namespace
= ".dbfbd751-3de4-4e68-bd40-ec5ae0a53898.1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0"
850 self
.db
.get_one
.return_value
= {
855 "target_element": "vnf/vnf1/mgmtvm",
856 "member-vnf-index": "vnf111-xxx-yyy-zzz",
857 "vdu_id": "38912ff7-5bdd-4228-911f-c2bee259c44a",
859 "vdu_count_index": None,
860 "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
861 "vdu_name": "mgmtvm",
862 "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
864 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
867 "target_element": "ns",
868 "member-vnf-index": None,
871 "vdu_count_index": None,
874 "ee_descriptor_id": "",
876 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
882 mock_vnf_count_and_record
= MagicMock()
884 "member-vnf-index-ref": "vnf111-xxx-yyy-zzz",
887 mock_vnf_count_and_record
.return_value
= (vnf_count
, db_vnfr
)
888 expected_result
= "simple-ee-ab-z0-vnf111-xxx-y-vnf"
889 with patch
.object(self
.n2vc
, "db", self
.db
), patch
.object(
890 self
.n2vc
, "_get_vnf_count_and_record", mock_vnf_count_and_record
892 application_name
= self
.n2vc
._get
_application
_name
(namespace
)
893 self
.assertEqual(application_name
, expected_result
)
894 self
.assertLess(len(application_name
), 50)
895 mock_vnf_count_and_record
.assert_called_once_with(
896 "vnf-level", "1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0"
898 self
.db
.get_one
.assert_called_once()
901 "n2vc.n2vc_juju_conn.generate_random_alfanum_string",
902 **{"return_value": "random"}
904 def test_get_application_name_vnf_charm_old_naming(
905 self
, mock_generate_random_alfanum
907 namespace
= ".dbfbd751-3de4-4e68-bd40-ec5ae0a53898.1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0"
908 self
.db
.get_one
.return_value
= {
913 "target_element": "vnf/vnf1/mgmtvm",
914 "member-vnf-index": "vnf111-xxx-yyy-zzz",
915 "vdu_id": "38912ff7-5bdd-4228-911f-c2bee259c44a",
917 "vdu_count_index": None,
918 "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
919 "vdu_name": "mgmtvm",
920 "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
921 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
924 "target_element": "ns",
925 "member-vnf-index": None,
928 "vdu_count_index": None,
931 "ee_descriptor_id": "",
932 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
938 mock_vnf_count_and_record
= MagicMock()
940 "member-vnf-index-ref": "vnf111-xxx-yyy-zzz",
943 mock_vnf_count_and_record
.return_value
= (vnf_count
, db_vnfr
)
944 expected_result
= "app-vnf-eb3161eec0-z0-random"
945 with patch
.object(self
.n2vc
, "db", self
.db
), patch
.object(
946 self
.n2vc
, "_get_vnf_count_and_record", mock_vnf_count_and_record
948 application_name
= self
.n2vc
._get
_application
_name
(namespace
)
949 self
.assertEqual(application_name
, expected_result
)
950 mock_vnf_count_and_record
.assert_called_once_with(
951 "vnf-level", "1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0"
953 self
.db
.get_one
.assert_called_once()
955 def test_get_application_name_vnf_charm_vnf_index_ref_mismatch(self
):
956 namespace
= ".dbfbd751-3de4-4e68-bd40-ec5ae0a53898.1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0"
957 self
.db
.get_one
.return_value
= {
962 "target_element": "vnf/vnf1/mgmtvm",
963 "member-vnf-index": "vnf111-xxx-yyy-zzz",
964 "vdu_id": "38912ff7-5bdd-4228-911f-c2bee259c44a",
966 "vdu_count_index": None,
967 "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
968 "vdu_name": "mgmtvm",
969 "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
971 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
974 "target_element": "ns",
975 "member-vnf-index": None,
978 "vdu_count_index": None,
981 "ee_descriptor_id": "",
983 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
989 mock_vnf_count_and_record
= MagicMock()
991 "member-vnf-index-ref": "vnf222-xxx-yyy-zzz",
994 mock_vnf_count_and_record
.return_value
= (vnf_count
, db_vnfr
)
995 with patch
.object(self
.n2vc
, "db", self
.db
), patch
.object(
996 self
.n2vc
, "_get_vnf_count_and_record", mock_vnf_count_and_record
998 with self
.assertRaises(N2VCException
):
999 self
.n2vc
._get
_application
_name
(namespace
)
1000 mock_vnf_count_and_record
.assert_called_once_with(
1001 "vnf-level", "1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0"
1003 self
.db
.get_one
.assert_called_once()
1005 def test_get_application_name_vdu_charm(self
):
1006 namespace
= ".dbfbd751-3de4-4e68-bd40-ec5ae0a53898.1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0.mgmtVM-0"
1007 self
.db
.get_one
.return_value
= {
1012 "target_element": "vnf/vnf1/mgmtvm",
1013 "member-vnf-index": "vnf111-xxx-yyy-zzz",
1014 "vdu_id": "38912ff7-5bdd-4228-911f-c2bee259c44a",
1016 "vdu_count_index": None,
1017 "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
1018 "vdu_name": "mgmtvm",
1019 "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
1021 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
1024 "target_element": "ns",
1025 "member-vnf-index": None,
1028 "vdu_count_index": None,
1031 "ee_descriptor_id": "",
1033 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
1039 mock_vnf_count_and_record
= MagicMock()
1041 "member-vnf-index-ref": "vnf111-xxx-yyy-zzz",
1043 {"_id": "38912ff7-5bdd-4228-911f-c2bee259c44a", "vdu-id-ref": "mgmtVM"},
1044 {"_id": "45512ff7-5bdd-4228-911f-c2bee259c44a", "vdu-id-ref": "dataVM"},
1048 mock_vnf_count_and_record
.return_value
= (vnf_count
, db_vnfr
)
1049 expected_result
= "simple-ee-ab-z0-vnf111-xxx-y-mgmtvm-z0-vdu"
1050 with patch
.object(self
.n2vc
, "db", self
.db
), patch
.object(
1051 self
.n2vc
, "_get_vnf_count_and_record", mock_vnf_count_and_record
1053 application_name
= self
.n2vc
._get
_application
_name
(namespace
)
1054 self
.assertEqual(application_name
, expected_result
)
1055 self
.assertLess(len(application_name
), 50)
1056 mock_vnf_count_and_record
.assert_called_once_with(
1057 "vdu-level", "1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0"
1059 self
.db
.get_one
.assert_called_once()
1061 def test_get_application_name_kdu_charm(self
):
1062 namespace
= ".82b11965-e580-47c0-9ee0-329f318a305b.1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0.ldap"
1063 self
.db
.get_one
.return_value
= {
1068 "target_element": "vnf/openldap/kdu/ldap",
1069 "member-vnf-index": "openldap",
1072 "vdu_count_index": 0,
1073 "operational-status": "init",
1074 "detailed-status": "",
1075 "step": "initial-deploy",
1076 "vnfd_id": "openldap_knf",
1078 "type": "lxc_proxy_charm",
1079 "ee_descriptor_id": "openldap-ee",
1082 "application": "openldap-ee-z0-openldap-vdu",
1083 "model": "82b11965-e580-47c0-9ee0-329f318a305b",
1084 "config_sw_installed": True,
1090 mock_vnf_count_and_record
= MagicMock()
1092 "member-vnf-index-ref": "openldap",
1096 mock_vnf_count_and_record
.return_value
= (vnf_count
, db_vnfr
)
1097 expected_result
= "openldap-ee-z0-openldap-vdu"
1098 with patch
.object(self
.n2vc
, "db", self
.db
), patch
.object(
1099 self
.n2vc
, "_get_vnf_count_and_record", mock_vnf_count_and_record
1101 application_name
= self
.n2vc
._get
_application
_name
(namespace
)
1102 self
.assertEqual(application_name
, expected_result
)
1103 self
.assertLess(len(application_name
), 50)
1104 mock_vnf_count_and_record
.assert_called_once_with(
1105 "vdu-level", "1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0"
1107 self
.db
.get_one
.assert_called_once()
1110 "n2vc.n2vc_juju_conn.generate_random_alfanum_string",
1111 **{"return_value": "random"}
1113 def test_get_application_name_vdu_charm_old_naming(
1114 self
, mock_generate_random_alfanum
1116 namespace
= ".dbfbd751-3de4-4e68-bd40-ec5ae0a53898.1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0.mgmtVM-0"
1117 self
.db
.get_one
.return_value
= {
1122 "target_element": "vnf/vnf1/mgmtvm",
1123 "member-vnf-index": "vnf111-xxx-yyy-zzz",
1124 "vdu_id": "38912ff7-5bdd-4228-911f-c2bee259c44a",
1126 "vdu_count_index": None,
1127 "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
1128 "vdu_name": "mgmtvm",
1129 "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
1130 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
1133 "target_element": "ns",
1134 "member-vnf-index": None,
1137 "vdu_count_index": None,
1140 "ee_descriptor_id": "",
1141 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
1147 mock_vnf_count_and_record
= MagicMock()
1149 "member-vnf-index-ref": "vnf111-xxx-yyy-zzz",
1151 {"_id": "38912ff7-5bdd-4228-911f-c2bee259c44a", "vdu-id-ref": "mgmtVM"},
1152 {"_id": "45512ff7-5bdd-4228-911f-c2bee259c44a", "vdu-id-ref": "dataVM"},
1156 mock_vnf_count_and_record
.return_value
= (vnf_count
, db_vnfr
)
1157 expected_result
= "app-vnf-eb3161eec0-z0-vdu-mgmtvm-cnt-z0-random"
1159 with patch
.object(self
.n2vc
, "db", self
.db
), patch
.object(
1160 self
.n2vc
, "_get_vnf_count_and_record", mock_vnf_count_and_record
1162 application_name
= self
.n2vc
._get
_application
_name
(namespace
)
1163 self
.assertEqual(application_name
, expected_result
)
1164 self
.assertLess(len(application_name
), 50)
1165 mock_vnf_count_and_record
.assert_called_once_with(
1166 "vdu-level", "1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0"
1168 self
.db
.get_one
.assert_called_once()
1170 def test_get_application_name_ns_charm(self
):
1171 namespace
= ".dbfbd751-3de4-4e68-bd40-ec5ae0a53898"
1172 self
.db
.get_one
.return_value
= {
1177 "target_element": "ns",
1178 "member-vnf-index": None,
1181 "vdu_count_index": None,
1184 "ee_descriptor_id": "",
1185 "charm_name": "simple-ns-charm-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
1186 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
1192 mock_vnf_count_and_record
= MagicMock()
1195 mock_vnf_count_and_record
.return_value
= (vnf_count
, db_vnfr
)
1196 expected_result
= "simple-ns-charm-abc-z000-rrrr-nnnn-z4444-h-ns"
1197 with patch
.object(self
.n2vc
, "db", self
.db
), patch
.object(
1198 self
.n2vc
, "_get_vnf_count_and_record", mock_vnf_count_and_record
1200 application_name
= self
.n2vc
._get
_application
_name
(namespace
)
1201 self
.assertEqual(application_name
, expected_result
)
1202 self
.assertLess(len(application_name
), 50)
1203 mock_vnf_count_and_record
.assert_called_once_with("ns-level", None)
1204 self
.db
.get_one
.assert_called_once()
1206 def test_get_application_name_ns_charm_empty_charm_name(self
):
1207 namespace
= ".dbfbd751-3de4-4e68-bd40-ec5ae0a53898"
1208 self
.db
.get_one
.return_value
= {
1213 "target_element": "ns",
1214 "member-vnf-index": None,
1217 "vdu_count_index": None,
1220 "ee_descriptor_id": "",
1222 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
1228 mock_vnf_count_and_record
= MagicMock()
1231 mock_vnf_count_and_record
.return_value
= (vnf_count
, db_vnfr
)
1232 with patch
.object(self
.n2vc
, "db", self
.db
), patch
.object(
1233 self
.n2vc
, "_get_vnf_count_and_record", mock_vnf_count_and_record
1235 with self
.assertRaises(N2VCException
):
1236 self
.n2vc
._get
_application
_name
(namespace
)
1237 mock_vnf_count_and_record
.assert_called_once_with("ns-level", None)
1238 self
.db
.get_one
.assert_called_once()
1241 "n2vc.n2vc_juju_conn.generate_random_alfanum_string",
1242 **{"return_value": "random"}
1244 def test_get_application_name_ns_charm_old_naming(
1245 self
, mock_generate_random_alfanum
1247 namespace
= ".dbfbd751-3de4-4e68-bd40-ec5ae0a53898"
1248 self
.db
.get_one
.return_value
= {
1253 "target_element": "ns",
1254 "member-vnf-index": None,
1257 "vdu_count_index": None,
1260 "ee_descriptor_id": "",
1261 "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
1267 mock_vnf_count_and_record
= MagicMock()
1270 mock_vnf_count_and_record
.return_value
= (vnf_count
, db_vnfr
)
1271 expected_result
= "app-random"
1272 with patch
.object(self
.n2vc
, "db", self
.db
), patch
.object(
1273 self
.n2vc
, "_get_vnf_count_and_record", mock_vnf_count_and_record
1275 application_name
= self
.n2vc
._get
_application
_name
(namespace
)
1276 self
.assertEqual(application_name
, expected_result
)
1277 self
.assertLess(len(application_name
), 50)
1278 mock_vnf_count_and_record
.assert_called_once_with("ns-level", None)
1279 self
.db
.get_one
.assert_called_once()