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

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 

16import asyncio 

17import logging 

18from unittest.mock import Mock, MagicMock 

19from unittest.mock import patch 

20 

21 

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 

36 

37 

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) 

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 

82class 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 

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() 

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 

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)) 

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 

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() 

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 

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() 

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 

398class 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 

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() 

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 )