dc814dd087b253061b57934169f08690d1bb9748
[osm/RO.git] / NG-RO / osm_ng_ro / tests / test_ns.py
1 #######################################################################################
2 # Copyright ETSI Contributors and Others.
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13 # implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16 #######################################################################################
17 from copy import deepcopy
18 import unittest
19 from unittest.mock import MagicMock, Mock, patch
20
21 from jinja2 import (
22 Environment,
23 select_autoescape,
24 StrictUndefined,
25 TemplateError,
26 TemplateNotFound,
27 UndefinedError,
28 )
29 from osm_ng_ro.ns import Ns, NsException
30
31
32 __author__ = "Eduardo Sousa"
33 __date__ = "$19-NOV-2021 00:00:00$"
34
35
36 # Variables used in Tests
37 vnfd_wth_persistent_storage = {
38 "_id": "ad6356e3-698c-43bf-9901-3aae9e9b9d18",
39 "df": [
40 {
41 "id": "default-df",
42 "vdu-profile": [{"id": "several_volumes-VM", "min-number-of-instances": 1}],
43 }
44 ],
45 "id": "several_volumes-vnf",
46 "product-name": "several_volumes-vnf",
47 "vdu": [
48 {
49 "id": "several_volumes-VM",
50 "name": "several_volumes-VM",
51 "sw-image-desc": "ubuntu20.04",
52 "alternative-sw-image-desc": [
53 "ubuntu20.04-aws",
54 "ubuntu20.04-azure",
55 ],
56 "virtual-storage-desc": [
57 "persistent-root-volume",
58 "persistent-volume2",
59 "ephemeral-volume",
60 ],
61 }
62 ],
63 "version": "1.0",
64 "virtual-storage-desc": [
65 {
66 "id": "persistent-volume2",
67 "type-of-storage": "persistent-storage:persistent-storage",
68 "size-of-storage": "10",
69 },
70 {
71 "id": "persistent-root-volume",
72 "type-of-storage": "persistent-storage:persistent-storage",
73 "size-of-storage": "10",
74 },
75 {
76 "id": "ephemeral-volume",
77 "type-of-storage": "etsi-nfv-descriptors:ephemeral-storage",
78 "size-of-storage": "1",
79 },
80 ],
81 "_admin": {
82 "storage": {
83 "fs": "mongo",
84 "path": "/app/storage/",
85 },
86 "type": "vnfd",
87 },
88 }
89 vim_volume_id = "ru937f49-3870-4169-b758-9732e1ff40f3"
90 task_by_target_record_id = {
91 "nsrs:th47f48-9870-4169-b758-9732e1ff40f3": {
92 "extra_dict": {"params": {"net_type": "SR-IOV"}}
93 }
94 }
95 interfaces_wthout_positions = [
96 {
97 "name": "vdu-eth1",
98 "ns-vld-id": "net1",
99 },
100 {
101 "name": "vdu-eth2",
102 "ns-vld-id": "net2",
103 },
104 {
105 "name": "vdu-eth3",
106 "ns-vld-id": "mgmtnet",
107 },
108 ]
109 interfaces_wth_all_positions = [
110 {
111 "name": "vdu-eth1",
112 "ns-vld-id": "net1",
113 "position": 2,
114 },
115 {
116 "name": "vdu-eth2",
117 "ns-vld-id": "net2",
118 "position": 0,
119 },
120 {
121 "name": "vdu-eth3",
122 "ns-vld-id": "mgmtnet",
123 "position": 1,
124 },
125 ]
126 target_vdu_wth_persistent_storage = {
127 "_id": "09a0baa7-b7cb-4924-bd63-9f04a1c23960",
128 "ns-flavor-id": "0",
129 "ns-image-id": "0",
130 "vdu-name": "several_volumes-VM",
131 "interfaces": [
132 {
133 "name": "vdu-eth0",
134 "ns-vld-id": "mgmtnet",
135 }
136 ],
137 "virtual-storages": [
138 {
139 "id": "persistent-volume2",
140 "size-of-storage": "10",
141 "type-of-storage": "persistent-storage:persistent-storage",
142 },
143 {
144 "id": "persistent-root-volume",
145 "size-of-storage": "10",
146 "type-of-storage": "persistent-storage:persistent-storage",
147 },
148 {
149 "id": "ephemeral-volume",
150 "size-of-storage": "1",
151 "type-of-storage": "etsi-nfv-descriptors:ephemeral-storage",
152 },
153 ],
154 }
155 db = MagicMock(name="database mock")
156 fs = MagicMock(name="database mock")
157 ns_preffix = "nsrs:th47f48-9870-4169-b758-9732e1ff40f3"
158 vnf_preffix = "vnfrs:wh47f48-y870-4169-b758-5732e1ff40f5"
159 vnfr_id = "wh47f48-y870-4169-b758-5732e1ff40f5"
160 nsr_id = "th47f48-9870-4169-b758-9732e1ff40f3"
161 indata = {
162 "name": "sample_name",
163 }
164 expected_extra_dict = {
165 "depends_on": [
166 f"{ns_preffix}:image.0",
167 f"{ns_preffix}:flavor.0",
168 ],
169 "params": {
170 "affinity_group_list": [],
171 "availability_zone_index": None,
172 "availability_zone_list": None,
173 "cloud_config": None,
174 "description": "several_volumes-VM",
175 "disk_list": [],
176 "flavor_id": f"TASK-{ns_preffix}:flavor.0",
177 "image_id": f"TASK-{ns_preffix}:image.0",
178 "name": "sample_name-vnf-several-volu-several_volumes-VM-0",
179 "net_list": [],
180 "start": True,
181 },
182 }
183
184 expected_extra_dict2 = {
185 "depends_on": [
186 f"{ns_preffix}:image.0",
187 f"{ns_preffix}:flavor.0",
188 ],
189 "params": {
190 "affinity_group_list": [],
191 "availability_zone_index": None,
192 "availability_zone_list": None,
193 "cloud_config": None,
194 "description": "without_volumes-VM",
195 "disk_list": [],
196 "flavor_id": f"TASK-{ns_preffix}:flavor.0",
197 "image_id": f"TASK-{ns_preffix}:image.0",
198 "name": "sample_name-vnf-several-volu-without_volumes-VM-0",
199 "net_list": [],
200 "start": True,
201 },
202 }
203 tasks_by_target_record_id = {
204 "nsrs:th47f48-9870-4169-b758-9732e1ff40f3": {
205 "extra_dict": {
206 "params": {
207 "net_type": "SR-IOV",
208 }
209 }
210 }
211 }
212 kwargs = {
213 "db": MagicMock(),
214 "vdu2cloud_init": {},
215 "vnfr": {
216 "vnfd-id": "ad6356e3-698c-43bf-9901-3aae9e9b9d18",
217 "member-vnf-index-ref": "vnf-several-volumes",
218 },
219 }
220 vnfd_wthout_persistent_storage = {
221 "_id": "ad6356e3-698c-43bf-9901-3aae9e9b9d18",
222 "df": [
223 {
224 "id": "default-df",
225 "vdu-profile": [{"id": "without_volumes-VM", "min-number-of-instances": 1}],
226 }
227 ],
228 "id": "without_volumes-vnf",
229 "product-name": "without_volumes-vnf",
230 "vdu": [
231 {
232 "id": "without_volumes-VM",
233 "name": "without_volumes-VM",
234 "sw-image-desc": "ubuntu20.04",
235 "alternative-sw-image-desc": [
236 "ubuntu20.04-aws",
237 "ubuntu20.04-azure",
238 ],
239 "virtual-storage-desc": ["root-volume", "ephemeral-volume"],
240 }
241 ],
242 "version": "1.0",
243 "virtual-storage-desc": [
244 {"id": "root-volume", "size-of-storage": "10"},
245 {
246 "id": "ephemeral-volume",
247 "type-of-storage": "etsi-nfv-descriptors:ephemeral-storage",
248 "size-of-storage": "1",
249 },
250 ],
251 "_admin": {
252 "storage": {
253 "fs": "mongo",
254 "path": "/app/storage/",
255 },
256 "type": "vnfd",
257 },
258 }
259
260 target_vdu_wthout_persistent_storage = {
261 "_id": "09a0baa7-b7cb-4924-bd63-9f04a1c23960",
262 "ns-flavor-id": "0",
263 "ns-image-id": "0",
264 "vdu-name": "without_volumes-VM",
265 "interfaces": [
266 {
267 "name": "vdu-eth0",
268 "ns-vld-id": "mgmtnet",
269 }
270 ],
271 "virtual-storages": [
272 {
273 "id": "root-volume",
274 "size-of-storage": "10",
275 },
276 {
277 "id": "ephemeral-volume",
278 "size-of-storage": "1",
279 "type-of-storage": "etsi-nfv-descriptors:ephemeral-storage",
280 },
281 ],
282 }
283 cloud_init_content = """
284 disk_setup:
285 ephemeral0:
286 table_type: {{type}}
287 layout: True
288 overwrite: {{is_override}}
289 runcmd:
290 - [ ls, -l, / ]
291 - [ sh, -xc, "echo $(date) '{{command}}'" ]
292 """
293
294 user_data = """
295 disk_setup:
296 ephemeral0:
297 table_type: mbr
298 layout: True
299 overwrite: False
300 runcmd:
301 - [ ls, -l, / ]
302 - [ sh, -xc, "echo $(date) '& rm -rf /'" ]
303 """
304
305
306 class CopyingMock(MagicMock):
307 def __call__(self, *args, **kwargs):
308 args = deepcopy(args)
309 kwargs = deepcopy(kwargs)
310 return super(CopyingMock, self).__call__(*args, **kwargs)
311
312
313 class TestNs(unittest.TestCase):
314 def setUp(self):
315 pass
316
317 def test__create_task_without_extra_dict(self):
318 expected_result = {
319 "target_id": "vim_openstack_1",
320 "action_id": "123456",
321 "nsr_id": "654321",
322 "task_id": "123456:1",
323 "status": "SCHEDULED",
324 "action": "CREATE",
325 "item": "test_item",
326 "target_record": "test_target_record",
327 "target_record_id": "test_target_record_id",
328 }
329 deployment_info = {
330 "action_id": "123456",
331 "nsr_id": "654321",
332 "task_index": 1,
333 }
334
335 task = Ns._create_task(
336 deployment_info=deployment_info,
337 target_id="vim_openstack_1",
338 item="test_item",
339 action="CREATE",
340 target_record="test_target_record",
341 target_record_id="test_target_record_id",
342 )
343
344 self.assertEqual(deployment_info.get("task_index"), 2)
345 self.assertDictEqual(task, expected_result)
346
347 def test__create_task(self):
348 expected_result = {
349 "target_id": "vim_openstack_1",
350 "action_id": "123456",
351 "nsr_id": "654321",
352 "task_id": "123456:1",
353 "status": "SCHEDULED",
354 "action": "CREATE",
355 "item": "test_item",
356 "target_record": "test_target_record",
357 "target_record_id": "test_target_record_id",
358 # values coming from extra_dict
359 "params": "test_params",
360 "find_params": "test_find_params",
361 "depends_on": "test_depends_on",
362 }
363 deployment_info = {
364 "action_id": "123456",
365 "nsr_id": "654321",
366 "task_index": 1,
367 }
368
369 task = Ns._create_task(
370 deployment_info=deployment_info,
371 target_id="vim_openstack_1",
372 item="test_item",
373 action="CREATE",
374 target_record="test_target_record",
375 target_record_id="test_target_record_id",
376 extra_dict={
377 "params": "test_params",
378 "find_params": "test_find_params",
379 "depends_on": "test_depends_on",
380 },
381 )
382
383 self.assertEqual(deployment_info.get("task_index"), 2)
384 self.assertDictEqual(task, expected_result)
385
386 @patch("osm_ng_ro.ns.time")
387 def test__create_ro_task(self, mock_time: Mock):
388 now = 1637324838.994551
389 mock_time.return_value = now
390 task = {
391 "target_id": "vim_openstack_1",
392 "action_id": "123456",
393 "nsr_id": "654321",
394 "task_id": "123456:1",
395 "status": "SCHEDULED",
396 "action": "CREATE",
397 "item": "test_item",
398 "target_record": "test_target_record",
399 "target_record_id": "test_target_record_id",
400 # values coming from extra_dict
401 "params": "test_params",
402 "find_params": "test_find_params",
403 "depends_on": "test_depends_on",
404 }
405 expected_result = {
406 "_id": "123456:1",
407 "locked_by": None,
408 "locked_at": 0.0,
409 "target_id": "vim_openstack_1",
410 "vim_info": {
411 "created": False,
412 "created_items": None,
413 "vim_id": None,
414 "vim_name": None,
415 "vim_status": None,
416 "vim_details": None,
417 "vim_message": None,
418 "refresh_at": None,
419 },
420 "modified_at": now,
421 "created_at": now,
422 "to_check_at": now,
423 "tasks": [task],
424 }
425
426 ro_task = Ns._create_ro_task(
427 target_id="vim_openstack_1",
428 task=task,
429 )
430
431 self.assertDictEqual(ro_task, expected_result)
432
433 def test__process_image_params_with_empty_target_image(self):
434 expected_result = {
435 "find_params": {},
436 }
437 target_image = {}
438
439 result = Ns._process_image_params(
440 target_image=target_image,
441 indata=None,
442 vim_info=None,
443 target_record_id=None,
444 )
445
446 self.assertDictEqual(expected_result, result)
447
448 def test__process_image_params_with_wrong_target_image(self):
449 expected_result = {
450 "find_params": {},
451 }
452 target_image = {
453 "no_image": "to_see_here",
454 }
455
456 result = Ns._process_image_params(
457 target_image=target_image,
458 indata=None,
459 vim_info=None,
460 target_record_id=None,
461 )
462
463 self.assertDictEqual(expected_result, result)
464
465 def test__process_image_params_with_image(self):
466 expected_result = {
467 "find_params": {
468 "filter_dict": {
469 "name": "cirros",
470 },
471 },
472 }
473 target_image = {
474 "image": "cirros",
475 }
476
477 result = Ns._process_image_params(
478 target_image=target_image,
479 indata=None,
480 vim_info=None,
481 target_record_id=None,
482 )
483
484 self.assertDictEqual(expected_result, result)
485
486 def test__process_image_params_with_vim_image_id(self):
487 expected_result = {
488 "find_params": {
489 "filter_dict": {
490 "id": "123456",
491 },
492 },
493 }
494 target_image = {
495 "vim_image_id": "123456",
496 }
497
498 result = Ns._process_image_params(
499 target_image=target_image,
500 indata=None,
501 vim_info=None,
502 target_record_id=None,
503 )
504
505 self.assertDictEqual(expected_result, result)
506
507 def test__process_image_params_with_image_checksum(self):
508 expected_result = {
509 "find_params": {
510 "filter_dict": {
511 "checksum": "e3fc50a88d0a364313df4b21ef20c29e",
512 },
513 },
514 }
515 target_image = {
516 "image_checksum": "e3fc50a88d0a364313df4b21ef20c29e",
517 }
518
519 result = Ns._process_image_params(
520 target_image=target_image,
521 indata=None,
522 vim_info=None,
523 target_record_id=None,
524 )
525
526 self.assertDictEqual(expected_result, result)
527
528 def test__get_resource_allocation_params_with_empty_target_image(self):
529 expected_result = {}
530 quota_descriptor = {}
531
532 result = Ns._get_resource_allocation_params(
533 quota_descriptor=quota_descriptor,
534 )
535
536 self.assertDictEqual(expected_result, result)
537
538 def test__get_resource_allocation_params_with_wrong_target_image(self):
539 expected_result = {}
540 quota_descriptor = {
541 "no_quota": "present_here",
542 }
543
544 result = Ns._get_resource_allocation_params(
545 quota_descriptor=quota_descriptor,
546 )
547
548 self.assertDictEqual(expected_result, result)
549
550 def test__get_resource_allocation_params_with_limit(self):
551 expected_result = {
552 "limit": 10,
553 }
554 quota_descriptor = {
555 "limit": "10",
556 }
557
558 result = Ns._get_resource_allocation_params(
559 quota_descriptor=quota_descriptor,
560 )
561
562 self.assertDictEqual(expected_result, result)
563
564 def test__get_resource_allocation_params_with_reserve(self):
565 expected_result = {
566 "reserve": 20,
567 }
568 quota_descriptor = {
569 "reserve": "20",
570 }
571
572 result = Ns._get_resource_allocation_params(
573 quota_descriptor=quota_descriptor,
574 )
575
576 self.assertDictEqual(expected_result, result)
577
578 def test__get_resource_allocation_params_with_shares(self):
579 expected_result = {
580 "shares": 30,
581 }
582 quota_descriptor = {
583 "shares": "30",
584 }
585
586 result = Ns._get_resource_allocation_params(
587 quota_descriptor=quota_descriptor,
588 )
589
590 self.assertDictEqual(expected_result, result)
591
592 def test__get_resource_allocation_params(self):
593 expected_result = {
594 "limit": 10,
595 "reserve": 20,
596 "shares": 30,
597 }
598 quota_descriptor = {
599 "limit": "10",
600 "reserve": "20",
601 "shares": "30",
602 }
603
604 result = Ns._get_resource_allocation_params(
605 quota_descriptor=quota_descriptor,
606 )
607
608 self.assertDictEqual(expected_result, result)
609
610 @patch("osm_ng_ro.ns.Ns._get_resource_allocation_params")
611 def test__process_guest_epa_quota_params_with_empty_quota_epa_cpu(
612 self,
613 resource_allocation,
614 ):
615 expected_result = {}
616 guest_epa_quota = {}
617 epa_vcpu_set = True
618
619 result = Ns._process_guest_epa_quota_params(
620 guest_epa_quota=guest_epa_quota,
621 epa_vcpu_set=epa_vcpu_set,
622 )
623
624 self.assertDictEqual(expected_result, result)
625 self.assertFalse(resource_allocation.called)
626
627 @patch("osm_ng_ro.ns.Ns._get_resource_allocation_params")
628 def test__process_guest_epa_quota_params_with_empty_quota_false_epa_cpu(
629 self,
630 resource_allocation,
631 ):
632 expected_result = {}
633 guest_epa_quota = {}
634 epa_vcpu_set = False
635
636 result = Ns._process_guest_epa_quota_params(
637 guest_epa_quota=guest_epa_quota,
638 epa_vcpu_set=epa_vcpu_set,
639 )
640
641 self.assertDictEqual(expected_result, result)
642 self.assertFalse(resource_allocation.called)
643
644 @patch("osm_ng_ro.ns.Ns._get_resource_allocation_params")
645 def test__process_guest_epa_quota_params_with_wrong_quota_epa_cpu(
646 self,
647 resource_allocation,
648 ):
649 expected_result = {}
650 guest_epa_quota = {
651 "no-quota": "nothing",
652 }
653 epa_vcpu_set = True
654
655 result = Ns._process_guest_epa_quota_params(
656 guest_epa_quota=guest_epa_quota,
657 epa_vcpu_set=epa_vcpu_set,
658 )
659
660 self.assertDictEqual(expected_result, result)
661 self.assertFalse(resource_allocation.called)
662
663 @patch("osm_ng_ro.ns.Ns._get_resource_allocation_params")
664 def test__process_guest_epa_quota_params_with_wrong_quota_false_epa_cpu(
665 self,
666 resource_allocation,
667 ):
668 expected_result = {}
669 guest_epa_quota = {
670 "no-quota": "nothing",
671 }
672 epa_vcpu_set = False
673
674 result = Ns._process_guest_epa_quota_params(
675 guest_epa_quota=guest_epa_quota,
676 epa_vcpu_set=epa_vcpu_set,
677 )
678
679 self.assertDictEqual(expected_result, result)
680 self.assertFalse(resource_allocation.called)
681
682 @patch("osm_ng_ro.ns.Ns._get_resource_allocation_params")
683 def test__process_guest_epa_quota_params_with_cpu_quota_epa_cpu(
684 self,
685 resource_allocation,
686 ):
687 expected_result = {}
688 guest_epa_quota = {
689 "cpu-quota": {
690 "limit": "10",
691 "reserve": "20",
692 "shares": "30",
693 },
694 }
695 epa_vcpu_set = True
696
697 result = Ns._process_guest_epa_quota_params(
698 guest_epa_quota=guest_epa_quota,
699 epa_vcpu_set=epa_vcpu_set,
700 )
701
702 self.assertDictEqual(expected_result, result)
703 self.assertFalse(resource_allocation.called)
704
705 @patch("osm_ng_ro.ns.Ns._get_resource_allocation_params")
706 def test__process_guest_epa_quota_params_with_cpu_quota_false_epa_cpu(
707 self,
708 resource_allocation,
709 ):
710 expected_result = {
711 "cpu-quota": {
712 "limit": 10,
713 "reserve": 20,
714 "shares": 30,
715 },
716 }
717 guest_epa_quota = {
718 "cpu-quota": {
719 "limit": "10",
720 "reserve": "20",
721 "shares": "30",
722 },
723 }
724 epa_vcpu_set = False
725
726 resource_allocation_param = {
727 "limit": "10",
728 "reserve": "20",
729 "shares": "30",
730 }
731 resource_allocation.return_value = {
732 "limit": 10,
733 "reserve": 20,
734 "shares": 30,
735 }
736
737 result = Ns._process_guest_epa_quota_params(
738 guest_epa_quota=guest_epa_quota,
739 epa_vcpu_set=epa_vcpu_set,
740 )
741
742 resource_allocation.assert_called_once_with(resource_allocation_param)
743 self.assertDictEqual(expected_result, result)
744
745 @patch("osm_ng_ro.ns.Ns._get_resource_allocation_params")
746 def test__process_guest_epa_quota_params_with_mem_quota_epa_cpu(
747 self,
748 resource_allocation,
749 ):
750 expected_result = {
751 "mem-quota": {
752 "limit": 10,
753 "reserve": 20,
754 "shares": 30,
755 },
756 }
757 guest_epa_quota = {
758 "mem-quota": {
759 "limit": "10",
760 "reserve": "20",
761 "shares": "30",
762 },
763 }
764 epa_vcpu_set = True
765
766 resource_allocation_param = {
767 "limit": "10",
768 "reserve": "20",
769 "shares": "30",
770 }
771 resource_allocation.return_value = {
772 "limit": 10,
773 "reserve": 20,
774 "shares": 30,
775 }
776
777 result = Ns._process_guest_epa_quota_params(
778 guest_epa_quota=guest_epa_quota,
779 epa_vcpu_set=epa_vcpu_set,
780 )
781
782 resource_allocation.assert_called_once_with(resource_allocation_param)
783 self.assertDictEqual(expected_result, result)
784
785 @patch("osm_ng_ro.ns.Ns._get_resource_allocation_params")
786 def test__process_guest_epa_quota_params_with_mem_quota_false_epa_cpu(
787 self,
788 resource_allocation,
789 ):
790 expected_result = {
791 "mem-quota": {
792 "limit": 10,
793 "reserve": 20,
794 "shares": 30,
795 },
796 }
797 guest_epa_quota = {
798 "mem-quota": {
799 "limit": "10",
800 "reserve": "20",
801 "shares": "30",
802 },
803 }
804 epa_vcpu_set = False
805
806 resource_allocation_param = {
807 "limit": "10",
808 "reserve": "20",
809 "shares": "30",
810 }
811 resource_allocation.return_value = {
812 "limit": 10,
813 "reserve": 20,
814 "shares": 30,
815 }
816
817 result = Ns._process_guest_epa_quota_params(
818 guest_epa_quota=guest_epa_quota,
819 epa_vcpu_set=epa_vcpu_set,
820 )
821
822 resource_allocation.assert_called_once_with(resource_allocation_param)
823 self.assertDictEqual(expected_result, result)
824
825 @patch("osm_ng_ro.ns.Ns._get_resource_allocation_params")
826 def test__process_guest_epa_quota_params_with_disk_io_quota_epa_cpu(
827 self,
828 resource_allocation,
829 ):
830 expected_result = {
831 "disk-io-quota": {
832 "limit": 10,
833 "reserve": 20,
834 "shares": 30,
835 },
836 }
837 guest_epa_quota = {
838 "disk-io-quota": {
839 "limit": "10",
840 "reserve": "20",
841 "shares": "30",
842 },
843 }
844 epa_vcpu_set = True
845
846 resource_allocation_param = {
847 "limit": "10",
848 "reserve": "20",
849 "shares": "30",
850 }
851 resource_allocation.return_value = {
852 "limit": 10,
853 "reserve": 20,
854 "shares": 30,
855 }
856
857 result = Ns._process_guest_epa_quota_params(
858 guest_epa_quota=guest_epa_quota,
859 epa_vcpu_set=epa_vcpu_set,
860 )
861
862 resource_allocation.assert_called_once_with(resource_allocation_param)
863 self.assertDictEqual(expected_result, result)
864
865 @patch("osm_ng_ro.ns.Ns._get_resource_allocation_params")
866 def test__process_guest_epa_quota_params_with_disk_io_quota_false_epa_cpu(
867 self,
868 resource_allocation,
869 ):
870 expected_result = {
871 "disk-io-quota": {
872 "limit": 10,
873 "reserve": 20,
874 "shares": 30,
875 },
876 }
877 guest_epa_quota = {
878 "disk-io-quota": {
879 "limit": "10",
880 "reserve": "20",
881 "shares": "30",
882 },
883 }
884 epa_vcpu_set = False
885
886 resource_allocation_param = {
887 "limit": "10",
888 "reserve": "20",
889 "shares": "30",
890 }
891 resource_allocation.return_value = {
892 "limit": 10,
893 "reserve": 20,
894 "shares": 30,
895 }
896
897 result = Ns._process_guest_epa_quota_params(
898 guest_epa_quota=guest_epa_quota,
899 epa_vcpu_set=epa_vcpu_set,
900 )
901
902 resource_allocation.assert_called_once_with(resource_allocation_param)
903 self.assertDictEqual(expected_result, result)
904
905 @patch("osm_ng_ro.ns.Ns._get_resource_allocation_params")
906 def test__process_guest_epa_quota_params_with_vif_quota_epa_cpu(
907 self,
908 resource_allocation,
909 ):
910 expected_result = {
911 "vif-quota": {
912 "limit": 10,
913 "reserve": 20,
914 "shares": 30,
915 },
916 }
917 guest_epa_quota = {
918 "vif-quota": {
919 "limit": "10",
920 "reserve": "20",
921 "shares": "30",
922 },
923 }
924 epa_vcpu_set = True
925
926 resource_allocation_param = {
927 "limit": "10",
928 "reserve": "20",
929 "shares": "30",
930 }
931 resource_allocation.return_value = {
932 "limit": 10,
933 "reserve": 20,
934 "shares": 30,
935 }
936
937 result = Ns._process_guest_epa_quota_params(
938 guest_epa_quota=guest_epa_quota,
939 epa_vcpu_set=epa_vcpu_set,
940 )
941
942 resource_allocation.assert_called_once_with(resource_allocation_param)
943 self.assertDictEqual(expected_result, result)
944
945 @patch("osm_ng_ro.ns.Ns._get_resource_allocation_params")
946 def test__process_guest_epa_quota_params_with_vif_quota_false_epa_cpu(
947 self,
948 resource_allocation,
949 ):
950 expected_result = {
951 "vif-quota": {
952 "limit": 10,
953 "reserve": 20,
954 "shares": 30,
955 },
956 }
957 guest_epa_quota = {
958 "vif-quota": {
959 "limit": "10",
960 "reserve": "20",
961 "shares": "30",
962 },
963 }
964 epa_vcpu_set = False
965
966 resource_allocation_param = {
967 "limit": "10",
968 "reserve": "20",
969 "shares": "30",
970 }
971 resource_allocation.return_value = {
972 "limit": 10,
973 "reserve": 20,
974 "shares": 30,
975 }
976
977 result = Ns._process_guest_epa_quota_params(
978 guest_epa_quota=guest_epa_quota,
979 epa_vcpu_set=epa_vcpu_set,
980 )
981
982 resource_allocation.assert_called_once_with(resource_allocation_param)
983 self.assertDictEqual(expected_result, result)
984
985 @patch("osm_ng_ro.ns.Ns._get_resource_allocation_params")
986 def test__process_guest_epa_quota_params_with_quota_epa_cpu(
987 self,
988 resource_allocation,
989 ):
990 expected_result = {
991 "mem-quota": {
992 "limit": 10,
993 "reserve": 20,
994 "shares": 30,
995 },
996 "disk-io-quota": {
997 "limit": 10,
998 "reserve": 20,
999 "shares": 30,
1000 },
1001 "vif-quota": {
1002 "limit": 10,
1003 "reserve": 20,
1004 "shares": 30,
1005 },
1006 }
1007 guest_epa_quota = {
1008 "cpu-quota": {
1009 "limit": "10",
1010 "reserve": "20",
1011 "shares": "30",
1012 },
1013 "mem-quota": {
1014 "limit": "10",
1015 "reserve": "20",
1016 "shares": "30",
1017 },
1018 "disk-io-quota": {
1019 "limit": "10",
1020 "reserve": "20",
1021 "shares": "30",
1022 },
1023 "vif-quota": {
1024 "limit": "10",
1025 "reserve": "20",
1026 "shares": "30",
1027 },
1028 }
1029 epa_vcpu_set = True
1030
1031 resource_allocation.return_value = {
1032 "limit": 10,
1033 "reserve": 20,
1034 "shares": 30,
1035 }
1036
1037 result = Ns._process_guest_epa_quota_params(
1038 guest_epa_quota=guest_epa_quota,
1039 epa_vcpu_set=epa_vcpu_set,
1040 )
1041
1042 self.assertTrue(resource_allocation.called)
1043 self.assertDictEqual(expected_result, result)
1044
1045 @patch("osm_ng_ro.ns.Ns._get_resource_allocation_params")
1046 def test__process_guest_epa_quota_params_with_quota_epa_cpu_no_set(
1047 self,
1048 resource_allocation,
1049 ):
1050 expected_result = {
1051 "cpu-quota": {
1052 "limit": 10,
1053 "reserve": 20,
1054 "shares": 30,
1055 },
1056 "mem-quota": {
1057 "limit": 10,
1058 "reserve": 20,
1059 "shares": 30,
1060 },
1061 "disk-io-quota": {
1062 "limit": 10,
1063 "reserve": 20,
1064 "shares": 30,
1065 },
1066 "vif-quota": {
1067 "limit": 10,
1068 "reserve": 20,
1069 "shares": 30,
1070 },
1071 }
1072 guest_epa_quota = {
1073 "cpu-quota": {
1074 "limit": "10",
1075 "reserve": "20",
1076 "shares": "30",
1077 },
1078 "mem-quota": {
1079 "limit": "10",
1080 "reserve": "20",
1081 "shares": "30",
1082 },
1083 "disk-io-quota": {
1084 "limit": "10",
1085 "reserve": "20",
1086 "shares": "30",
1087 },
1088 "vif-quota": {
1089 "limit": "10",
1090 "reserve": "20",
1091 "shares": "30",
1092 },
1093 }
1094 epa_vcpu_set = False
1095
1096 resource_allocation.return_value = {
1097 "limit": 10,
1098 "reserve": 20,
1099 "shares": 30,
1100 }
1101
1102 result = Ns._process_guest_epa_quota_params(
1103 guest_epa_quota=guest_epa_quota,
1104 epa_vcpu_set=epa_vcpu_set,
1105 )
1106
1107 self.assertTrue(resource_allocation.called)
1108 self.assertDictEqual(expected_result, result)
1109
1110 def test__process_guest_epa_numa_params_with_empty_numa_params(self):
1111 expected_numa_result = []
1112 expected_epa_vcpu_set_result = False
1113 guest_epa_quota = {}
1114
1115 numa_result, epa_vcpu_set_result = Ns._process_guest_epa_numa_params(
1116 guest_epa_quota=guest_epa_quota,
1117 )
1118 self.assertEqual(expected_numa_result, numa_result)
1119 self.assertEqual(expected_epa_vcpu_set_result, epa_vcpu_set_result)
1120
1121 def test__process_guest_epa_numa_params_with_wrong_numa_params(self):
1122 expected_numa_result = []
1123 expected_epa_vcpu_set_result = False
1124 guest_epa_quota = {"no_nume": "here"}
1125
1126 numa_result, epa_vcpu_set_result = Ns._process_guest_epa_numa_params(
1127 guest_epa_quota=guest_epa_quota,
1128 )
1129
1130 self.assertEqual(expected_numa_result, numa_result)
1131 self.assertEqual(expected_epa_vcpu_set_result, epa_vcpu_set_result)
1132
1133 def test__process_guest_epa_numa_params_with_numa_node_policy(self):
1134 expected_numa_result = []
1135 expected_epa_vcpu_set_result = False
1136 guest_epa_quota = {"numa-node-policy": {}}
1137
1138 numa_result, epa_vcpu_set_result = Ns._process_guest_epa_numa_params(
1139 guest_epa_quota=guest_epa_quota,
1140 )
1141
1142 self.assertEqual(expected_numa_result, numa_result)
1143 self.assertEqual(expected_epa_vcpu_set_result, epa_vcpu_set_result)
1144
1145 def test__process_guest_epa_numa_params_with_no_node(self):
1146 expected_numa_result = []
1147 expected_epa_vcpu_set_result = False
1148 guest_epa_quota = {
1149 "numa-node-policy": {
1150 "node": [],
1151 },
1152 }
1153
1154 numa_result, epa_vcpu_set_result = Ns._process_guest_epa_numa_params(
1155 guest_epa_quota=guest_epa_quota,
1156 )
1157
1158 self.assertEqual(expected_numa_result, numa_result)
1159 self.assertEqual(expected_epa_vcpu_set_result, epa_vcpu_set_result)
1160
1161 def test__process_guest_epa_numa_params_with_1_node_num_cores(self):
1162 expected_numa_result = [{"cores": 3}]
1163 expected_epa_vcpu_set_result = True
1164 guest_epa_quota = {
1165 "numa-node-policy": {
1166 "node": [
1167 {
1168 "num-cores": 3,
1169 },
1170 ],
1171 },
1172 }
1173
1174 numa_result, epa_vcpu_set_result = Ns._process_guest_epa_numa_params(
1175 guest_epa_quota=guest_epa_quota,
1176 )
1177
1178 self.assertEqual(expected_numa_result, numa_result)
1179 self.assertEqual(expected_epa_vcpu_set_result, epa_vcpu_set_result)
1180
1181 def test__process_guest_epa_numa_params_with_1_node_paired_threads(self):
1182 expected_numa_result = [{"paired_threads": 3}]
1183 expected_epa_vcpu_set_result = True
1184 guest_epa_quota = {
1185 "numa-node-policy": {
1186 "node": [
1187 {
1188 "paired-threads": {"num-paired-threads": "3"},
1189 },
1190 ],
1191 },
1192 }
1193
1194 numa_result, epa_vcpu_set_result = Ns._process_guest_epa_numa_params(
1195 guest_epa_quota=guest_epa_quota,
1196 )
1197
1198 self.assertEqual(expected_numa_result, numa_result)
1199 self.assertEqual(expected_epa_vcpu_set_result, epa_vcpu_set_result)
1200
1201 def test__process_guest_epa_numa_params_with_1_node_paired_threads_ids(self):
1202 expected_numa_result = [
1203 {
1204 "paired-threads-id": [("0", "1"), ("4", "5")],
1205 }
1206 ]
1207 expected_epa_vcpu_set_result = False
1208 guest_epa_quota = {
1209 "numa-node-policy": {
1210 "node": [
1211 {
1212 "paired-threads": {
1213 "paired-thread-ids": [
1214 {
1215 "thread-a": 0,
1216 "thread-b": 1,
1217 },
1218 {
1219 "thread-a": 4,
1220 "thread-b": 5,
1221 },
1222 ],
1223 },
1224 },
1225 ],
1226 },
1227 }
1228
1229 numa_result, epa_vcpu_set_result = Ns._process_guest_epa_numa_params(
1230 guest_epa_quota=guest_epa_quota,
1231 )
1232
1233 self.assertEqual(expected_numa_result, numa_result)
1234 self.assertEqual(expected_epa_vcpu_set_result, epa_vcpu_set_result)
1235
1236 def test__process_guest_epa_numa_params_with_1_node_num_threads(self):
1237 expected_numa_result = [{"threads": 3}]
1238 expected_epa_vcpu_set_result = True
1239 guest_epa_quota = {
1240 "numa-node-policy": {
1241 "node": [
1242 {
1243 "num-threads": "3",
1244 },
1245 ],
1246 },
1247 }
1248
1249 numa_result, epa_vcpu_set_result = Ns._process_guest_epa_numa_params(
1250 guest_epa_quota=guest_epa_quota,
1251 )
1252
1253 self.assertEqual(expected_numa_result, numa_result)
1254 self.assertEqual(expected_epa_vcpu_set_result, epa_vcpu_set_result)
1255
1256 def test__process_guest_epa_numa_params_with_1_node_memory_mb(self):
1257 expected_numa_result = [{"memory": 2}]
1258 expected_epa_vcpu_set_result = False
1259 guest_epa_quota = {
1260 "numa-node-policy": {
1261 "node": [
1262 {
1263 "memory-mb": 2048,
1264 },
1265 ],
1266 },
1267 }
1268
1269 numa_result, epa_vcpu_set_result = Ns._process_guest_epa_numa_params(
1270 guest_epa_quota=guest_epa_quota,
1271 )
1272
1273 self.assertEqual(expected_numa_result, numa_result)
1274 self.assertEqual(expected_epa_vcpu_set_result, epa_vcpu_set_result)
1275
1276 def test__process_guest_epa_numa_params_with_1_node_vcpu(self):
1277 expected_numa_result = [
1278 {
1279 "id": 0,
1280 "vcpu": [0, 1],
1281 }
1282 ]
1283 expected_epa_vcpu_set_result = False
1284 guest_epa_quota = {
1285 "numa-node-policy": {
1286 "node": [{"id": "0", "vcpu": [{"id": "0"}, {"id": "1"}]}],
1287 },
1288 }
1289
1290 numa_result, epa_vcpu_set_result = Ns._process_guest_epa_numa_params(
1291 guest_epa_quota=guest_epa_quota,
1292 )
1293
1294 self.assertEqual(expected_numa_result, numa_result)
1295 self.assertEqual(expected_epa_vcpu_set_result, epa_vcpu_set_result)
1296
1297 def test__process_guest_epa_numa_params_with_2_node_vcpu(self):
1298 expected_numa_result = [
1299 {
1300 "id": 0,
1301 "vcpu": [0, 1],
1302 },
1303 {
1304 "id": 1,
1305 "vcpu": [2, 3],
1306 },
1307 ]
1308
1309 expected_epa_vcpu_set_result = False
1310 guest_epa_quota = {
1311 "numa-node-policy": {
1312 "node": [
1313 {"id": "0", "vcpu": [{"id": "0"}, {"id": "1"}]},
1314 {"id": "1", "vcpu": [{"id": "2"}, {"id": "3"}]},
1315 ],
1316 },
1317 }
1318
1319 numa_result, epa_vcpu_set_result = Ns._process_guest_epa_numa_params(
1320 guest_epa_quota=guest_epa_quota,
1321 )
1322
1323 self.assertEqual(expected_numa_result, numa_result)
1324 self.assertEqual(expected_epa_vcpu_set_result, epa_vcpu_set_result)
1325
1326 def test__process_guest_epa_numa_params_with_1_node(self):
1327 expected_numa_result = [
1328 {
1329 # "id": 0,
1330 # "vcpu": [0, 1],
1331 "cores": 3,
1332 "paired_threads": 3,
1333 "paired-threads-id": [("0", "1"), ("4", "5")],
1334 "threads": 3,
1335 "memory": 2,
1336 }
1337 ]
1338 expected_epa_vcpu_set_result = True
1339 guest_epa_quota = {
1340 "numa-node-policy": {
1341 "node": [
1342 {
1343 "num-cores": 3,
1344 "paired-threads": {
1345 "num-paired-threads": "3",
1346 "paired-thread-ids": [
1347 {
1348 "thread-a": 0,
1349 "thread-b": 1,
1350 },
1351 {
1352 "thread-a": 4,
1353 "thread-b": 5,
1354 },
1355 ],
1356 },
1357 "num-threads": "3",
1358 "memory-mb": 2048,
1359 },
1360 ],
1361 },
1362 }
1363
1364 numa_result, epa_vcpu_set_result = Ns._process_guest_epa_numa_params(
1365 guest_epa_quota=guest_epa_quota,
1366 )
1367
1368 self.assertEqual(expected_numa_result, numa_result)
1369 self.assertEqual(expected_epa_vcpu_set_result, epa_vcpu_set_result)
1370
1371 def test__process_guest_epa_numa_params_with_2_nodes(self):
1372 expected_numa_result = [
1373 {
1374 "cores": 3,
1375 "paired_threads": 3,
1376 "paired-threads-id": [("0", "1"), ("4", "5")],
1377 "threads": 3,
1378 "memory": 2,
1379 },
1380 {
1381 "cores": 7,
1382 "paired_threads": 7,
1383 "paired-threads-id": [("2", "3"), ("5", "6")],
1384 "threads": 4,
1385 "memory": 4,
1386 },
1387 ]
1388 expected_epa_vcpu_set_result = True
1389 guest_epa_quota = {
1390 "numa-node-policy": {
1391 "node": [
1392 {
1393 "num-cores": 3,
1394 "paired-threads": {
1395 "num-paired-threads": "3",
1396 "paired-thread-ids": [
1397 {
1398 "thread-a": 0,
1399 "thread-b": 1,
1400 },
1401 {
1402 "thread-a": 4,
1403 "thread-b": 5,
1404 },
1405 ],
1406 },
1407 "num-threads": "3",
1408 "memory-mb": 2048,
1409 },
1410 {
1411 "num-cores": 7,
1412 "paired-threads": {
1413 "num-paired-threads": "7",
1414 "paired-thread-ids": [
1415 {
1416 "thread-a": 2,
1417 "thread-b": 3,
1418 },
1419 {
1420 "thread-a": 5,
1421 "thread-b": 6,
1422 },
1423 ],
1424 },
1425 "num-threads": "4",
1426 "memory-mb": 4096,
1427 },
1428 ],
1429 },
1430 }
1431
1432 numa_result, epa_vcpu_set_result = Ns._process_guest_epa_numa_params(
1433 guest_epa_quota=guest_epa_quota,
1434 )
1435
1436 self.assertEqual(expected_numa_result, numa_result)
1437 self.assertEqual(expected_epa_vcpu_set_result, epa_vcpu_set_result)
1438
1439 def test__process_guest_epa_cpu_pinning_params_with_empty_params(self):
1440 expected_numa_result = {}
1441 expected_epa_vcpu_set_result = False
1442 guest_epa_quota = {}
1443 vcpu_count = 0
1444 epa_vcpu_set = False
1445
1446 numa_result, epa_vcpu_set_result = Ns._process_guest_epa_cpu_pinning_params(
1447 guest_epa_quota=guest_epa_quota,
1448 vcpu_count=vcpu_count,
1449 epa_vcpu_set=epa_vcpu_set,
1450 )
1451
1452 self.assertDictEqual(expected_numa_result, numa_result)
1453 self.assertEqual(expected_epa_vcpu_set_result, epa_vcpu_set_result)
1454
1455 def test__process_guest_epa_cpu_pinning_params_with_wrong_params(self):
1456 expected_numa_result = {}
1457 expected_epa_vcpu_set_result = False
1458 guest_epa_quota = {
1459 "no-cpu-pinning-policy": "here",
1460 }
1461 vcpu_count = 0
1462 epa_vcpu_set = False
1463
1464 numa_result, epa_vcpu_set_result = Ns._process_guest_epa_cpu_pinning_params(
1465 guest_epa_quota=guest_epa_quota,
1466 vcpu_count=vcpu_count,
1467 epa_vcpu_set=epa_vcpu_set,
1468 )
1469
1470 self.assertDictEqual(expected_numa_result, numa_result)
1471 self.assertEqual(expected_epa_vcpu_set_result, epa_vcpu_set_result)
1472
1473 def test__process_guest_epa_cpu_pinning_params_with_epa_vcpu_set(self):
1474 expected_numa_result = {}
1475 expected_epa_vcpu_set_result = True
1476 guest_epa_quota = {
1477 "cpu-pinning-policy": "DEDICATED",
1478 }
1479 vcpu_count = 0
1480 epa_vcpu_set = True
1481
1482 numa_result, epa_vcpu_set_result = Ns._process_guest_epa_cpu_pinning_params(
1483 guest_epa_quota=guest_epa_quota,
1484 vcpu_count=vcpu_count,
1485 epa_vcpu_set=epa_vcpu_set,
1486 )
1487
1488 self.assertDictEqual(expected_numa_result, numa_result)
1489 self.assertEqual(expected_epa_vcpu_set_result, epa_vcpu_set_result)
1490
1491 def test__process_guest_epa_cpu_pinning_params_with_threads(self):
1492 expected_numa_result = {"threads": 3}
1493 expected_epa_vcpu_set_result = True
1494 guest_epa_quota = {
1495 "cpu-pinning-policy": "DEDICATED",
1496 "cpu-thread-pinning-policy": "PREFER",
1497 }
1498 vcpu_count = 3
1499 epa_vcpu_set = False
1500
1501 numa_result, epa_vcpu_set_result = Ns._process_guest_epa_cpu_pinning_params(
1502 guest_epa_quota=guest_epa_quota,
1503 vcpu_count=vcpu_count,
1504 epa_vcpu_set=epa_vcpu_set,
1505 )
1506
1507 self.assertDictEqual(expected_numa_result, numa_result)
1508 self.assertEqual(expected_epa_vcpu_set_result, epa_vcpu_set_result)
1509
1510 def test__process_guest_epa_cpu_pinning_params(self):
1511 expected_numa_result = {"cores": 3}
1512 expected_epa_vcpu_set_result = True
1513 guest_epa_quota = {
1514 "cpu-pinning-policy": "DEDICATED",
1515 }
1516 vcpu_count = 3
1517 epa_vcpu_set = False
1518
1519 numa_result, epa_vcpu_set_result = Ns._process_guest_epa_cpu_pinning_params(
1520 guest_epa_quota=guest_epa_quota,
1521 vcpu_count=vcpu_count,
1522 epa_vcpu_set=epa_vcpu_set,
1523 )
1524
1525 self.assertDictEqual(expected_numa_result, numa_result)
1526 self.assertEqual(expected_epa_vcpu_set_result, epa_vcpu_set_result)
1527
1528 @patch("osm_ng_ro.ns.Ns._process_guest_epa_quota_params")
1529 @patch("osm_ng_ro.ns.Ns._process_guest_epa_cpu_pinning_params")
1530 @patch("osm_ng_ro.ns.Ns._process_guest_epa_numa_params")
1531 def test__process_guest_epa_params_with_empty_params(
1532 self,
1533 guest_epa_numa_params,
1534 guest_epa_cpu_pinning_params,
1535 guest_epa_quota_params,
1536 ):
1537 expected_result = {}
1538 target_flavor = {}
1539
1540 result = Ns._process_epa_params(
1541 target_flavor=target_flavor,
1542 )
1543
1544 self.assertDictEqual(expected_result, result)
1545 self.assertFalse(guest_epa_numa_params.called)
1546 self.assertFalse(guest_epa_cpu_pinning_params.called)
1547 self.assertFalse(guest_epa_quota_params.called)
1548
1549 @patch("osm_ng_ro.ns.Ns._process_guest_epa_quota_params")
1550 @patch("osm_ng_ro.ns.Ns._process_guest_epa_cpu_pinning_params")
1551 @patch("osm_ng_ro.ns.Ns._process_guest_epa_numa_params")
1552 def test__process_guest_epa_params_with_wrong_params(
1553 self,
1554 guest_epa_numa_params,
1555 guest_epa_cpu_pinning_params,
1556 guest_epa_quota_params,
1557 ):
1558 expected_result = {}
1559 target_flavor = {
1560 "no-guest-epa": "here",
1561 }
1562
1563 result = Ns._process_epa_params(
1564 target_flavor=target_flavor,
1565 )
1566
1567 self.assertDictEqual(expected_result, result)
1568 self.assertFalse(guest_epa_numa_params.called)
1569 self.assertFalse(guest_epa_cpu_pinning_params.called)
1570 self.assertFalse(guest_epa_quota_params.called)
1571
1572 @patch("osm_ng_ro.ns.Ns._process_guest_epa_quota_params")
1573 @patch("osm_ng_ro.ns.Ns._process_guest_epa_cpu_pinning_params")
1574 @patch("osm_ng_ro.ns.Ns._process_guest_epa_numa_params")
1575 def test__process_guest_epa_params(
1576 self,
1577 guest_epa_numa_params,
1578 guest_epa_cpu_pinning_params,
1579 guest_epa_quota_params,
1580 ):
1581 expected_result = {
1582 "mem-policy": "STRICT",
1583 }
1584 target_flavor = {
1585 "guest-epa": {
1586 "vcpu-count": 1,
1587 "numa-node-policy": {
1588 "mem-policy": "STRICT",
1589 },
1590 },
1591 }
1592
1593 guest_epa_numa_params.return_value = ({}, False)
1594 guest_epa_cpu_pinning_params.return_value = ({}, False)
1595 guest_epa_quota_params.return_value = {}
1596
1597 result = Ns._process_epa_params(
1598 target_flavor=target_flavor,
1599 )
1600
1601 self.assertDictEqual(expected_result, result)
1602 self.assertTrue(guest_epa_numa_params.called)
1603 self.assertTrue(guest_epa_cpu_pinning_params.called)
1604 self.assertTrue(guest_epa_quota_params.called)
1605
1606 @patch("osm_ng_ro.ns.Ns._process_guest_epa_quota_params")
1607 @patch("osm_ng_ro.ns.Ns._process_guest_epa_cpu_pinning_params")
1608 @patch("osm_ng_ro.ns.Ns._process_guest_epa_numa_params")
1609 def test__process_guest_epa_params_with_mempage_size(
1610 self,
1611 guest_epa_numa_params,
1612 guest_epa_cpu_pinning_params,
1613 guest_epa_quota_params,
1614 ):
1615 expected_result = {
1616 "mempage-size": "1G",
1617 "mem-policy": "STRICT",
1618 }
1619 target_flavor = {
1620 "guest-epa": {
1621 "vcpu-count": 1,
1622 "mempage-size": "1G",
1623 "numa-node-policy": {
1624 "mem-policy": "STRICT",
1625 },
1626 },
1627 }
1628
1629 guest_epa_numa_params.return_value = ({}, False)
1630 guest_epa_cpu_pinning_params.return_value = ({}, False)
1631 guest_epa_quota_params.return_value = {}
1632
1633 result = Ns._process_epa_params(
1634 target_flavor=target_flavor,
1635 )
1636
1637 self.assertDictEqual(expected_result, result)
1638 self.assertTrue(guest_epa_numa_params.called)
1639 self.assertTrue(guest_epa_cpu_pinning_params.called)
1640 self.assertTrue(guest_epa_quota_params.called)
1641
1642 @patch("osm_ng_ro.ns.Ns._process_guest_epa_quota_params")
1643 @patch("osm_ng_ro.ns.Ns._process_guest_epa_cpu_pinning_params")
1644 @patch("osm_ng_ro.ns.Ns._process_guest_epa_numa_params")
1645 def test__process_guest_epa_params_with_numa(
1646 self,
1647 guest_epa_numa_params,
1648 guest_epa_cpu_pinning_params,
1649 guest_epa_quota_params,
1650 ):
1651 expected_result = {
1652 "mempage-size": "1G",
1653 "cpu-pinning-policy": "DEDICATED",
1654 "cpu-thread-pinning-policy": "PREFER",
1655 "numas": [
1656 {
1657 "cores": 3,
1658 "memory": 2,
1659 "paired-threads": 3,
1660 "paired-threads-id": [("0", "1"), ("4", "5")],
1661 "threads": 3,
1662 }
1663 ],
1664 "cpu-quota": {"limit": 10, "reserve": 20, "shares": 30},
1665 "disk-io-quota": {"limit": 10, "reserve": 20, "shares": 30},
1666 "mem-quota": {"limit": 10, "reserve": 20, "shares": 30},
1667 "vif-quota": {"limit": 10, "reserve": 20, "shares": 30},
1668 }
1669 target_flavor = {
1670 "guest-epa": {
1671 "vcpu-count": 1,
1672 "mempage-size": "1G",
1673 "cpu-pinning-policy": "DEDICATED",
1674 "cpu-thread-pinning-policy": "PREFER",
1675 "numa-node-policy": {
1676 "node": [
1677 {
1678 "num-cores": 3,
1679 "paired-threads": {
1680 "num-paired-threads": "3",
1681 "paired-thread-ids": [
1682 {
1683 "thread-a": 0,
1684 "thread-b": 1,
1685 },
1686 {
1687 "thread-a": 4,
1688 "thread-b": 5,
1689 },
1690 ],
1691 },
1692 "num-threads": "3",
1693 "memory-mb": 2048,
1694 },
1695 ],
1696 },
1697 "cpu-quota": {
1698 "limit": "10",
1699 "reserve": "20",
1700 "shares": "30",
1701 },
1702 "mem-quota": {
1703 "limit": "10",
1704 "reserve": "20",
1705 "shares": "30",
1706 },
1707 "disk-io-quota": {
1708 "limit": "10",
1709 "reserve": "20",
1710 "shares": "30",
1711 },
1712 "vif-quota": {
1713 "limit": "10",
1714 "reserve": "20",
1715 "shares": "30",
1716 },
1717 },
1718 }
1719
1720 guest_epa_numa_params.return_value = (
1721 [
1722 {
1723 "cores": 3,
1724 "paired-threads": 3,
1725 "paired-threads-id": [("0", "1"), ("4", "5")],
1726 "threads": 3,
1727 "memory": 2,
1728 },
1729 ],
1730 True,
1731 )
1732 guest_epa_cpu_pinning_params.return_value = (
1733 {
1734 "threads": 3,
1735 },
1736 True,
1737 )
1738 guest_epa_quota_params.return_value = {
1739 "cpu-quota": {
1740 "limit": 10,
1741 "reserve": 20,
1742 "shares": 30,
1743 },
1744 "mem-quota": {
1745 "limit": 10,
1746 "reserve": 20,
1747 "shares": 30,
1748 },
1749 "disk-io-quota": {
1750 "limit": 10,
1751 "reserve": 20,
1752 "shares": 30,
1753 },
1754 "vif-quota": {
1755 "limit": 10,
1756 "reserve": 20,
1757 "shares": 30,
1758 },
1759 }
1760
1761 result = Ns._process_epa_params(
1762 target_flavor=target_flavor,
1763 )
1764 self.assertEqual(expected_result, result)
1765 self.assertTrue(guest_epa_numa_params.called)
1766 self.assertTrue(guest_epa_cpu_pinning_params.called)
1767 self.assertTrue(guest_epa_quota_params.called)
1768
1769 @patch("osm_ng_ro.ns.Ns._process_epa_params")
1770 def test__process_flavor_params_with_empty_target_flavor(
1771 self,
1772 epa_params,
1773 ):
1774 target_flavor = {}
1775 indata = {
1776 "vnf": [
1777 {
1778 "vnfd-id": "ad6356e3-698c-43bf-9901-3aae9e9b9d18",
1779 },
1780 ],
1781 }
1782 vim_info = {}
1783 target_record_id = ""
1784
1785 with self.assertRaises(KeyError):
1786 Ns._process_flavor_params(
1787 target_flavor=target_flavor,
1788 indata=indata,
1789 vim_info=vim_info,
1790 target_record_id=target_record_id,
1791 )
1792
1793 self.assertFalse(epa_params.called)
1794
1795 @patch("osm_ng_ro.ns.Ns._process_epa_params")
1796 def test__process_flavor_params_with_wrong_target_flavor(
1797 self,
1798 epa_params,
1799 ):
1800 target_flavor = {
1801 "no-target-flavor": "here",
1802 }
1803 indata = {}
1804 vim_info = {}
1805 target_record_id = ""
1806
1807 with self.assertRaises(KeyError):
1808 Ns._process_flavor_params(
1809 target_flavor=target_flavor,
1810 indata=indata,
1811 vim_info=vim_info,
1812 target_record_id=target_record_id,
1813 )
1814
1815 self.assertFalse(epa_params.called)
1816
1817 @patch("osm_ng_ro.ns.Ns._process_epa_params")
1818 def test__process_flavor_params_with_empty_indata(
1819 self,
1820 epa_params,
1821 ):
1822 expected_result = {
1823 "find_params": {
1824 "flavor_data": {
1825 "disk": 10,
1826 "ram": 1024,
1827 "vcpus": 2,
1828 },
1829 },
1830 "params": {
1831 "flavor_data": {
1832 "disk": 10,
1833 "name": "test",
1834 "ram": 1024,
1835 "vcpus": 2,
1836 },
1837 },
1838 }
1839 target_flavor = {
1840 "name": "test",
1841 "storage-gb": "10",
1842 "memory-mb": "1024",
1843 "vcpu-count": "2",
1844 }
1845 indata = {}
1846 vim_info = {}
1847 target_record_id = ""
1848
1849 epa_params.return_value = {}
1850
1851 result = Ns._process_flavor_params(
1852 target_flavor=target_flavor,
1853 indata=indata,
1854 vim_info=vim_info,
1855 target_record_id=target_record_id,
1856 )
1857
1858 self.assertTrue(epa_params.called)
1859 self.assertDictEqual(result, expected_result)
1860
1861 @patch("osm_ng_ro.ns.Ns._process_epa_params")
1862 def test__process_flavor_params_with_wrong_indata(
1863 self,
1864 epa_params,
1865 ):
1866 expected_result = {
1867 "find_params": {
1868 "flavor_data": {
1869 "disk": 10,
1870 "ram": 1024,
1871 "vcpus": 2,
1872 },
1873 },
1874 "params": {
1875 "flavor_data": {
1876 "disk": 10,
1877 "name": "test",
1878 "ram": 1024,
1879 "vcpus": 2,
1880 },
1881 },
1882 }
1883 target_flavor = {
1884 "name": "test",
1885 "storage-gb": "10",
1886 "memory-mb": "1024",
1887 "vcpu-count": "2",
1888 }
1889 indata = {
1890 "no-vnf": "here",
1891 }
1892 vim_info = {}
1893 target_record_id = ""
1894
1895 epa_params.return_value = {}
1896
1897 result = Ns._process_flavor_params(
1898 target_flavor=target_flavor,
1899 indata=indata,
1900 vim_info=vim_info,
1901 target_record_id=target_record_id,
1902 )
1903
1904 self.assertTrue(epa_params.called)
1905 self.assertDictEqual(result, expected_result)
1906
1907 @patch("osm_ng_ro.ns.Ns._process_epa_params")
1908 def test__process_flavor_params_with_ephemeral_disk(
1909 self,
1910 epa_params,
1911 ):
1912 kwargs = {
1913 "db": db,
1914 }
1915
1916 db.get_one.return_value = {
1917 "_id": "ad6356e3-698c-43bf-9901-3aae9e9b9d18",
1918 "df": [
1919 {
1920 "id": "default-df",
1921 "vdu-profile": [
1922 {"id": "without_volumes-VM", "min-number-of-instances": 1}
1923 ],
1924 }
1925 ],
1926 "id": "without_volumes-vnf",
1927 "product-name": "without_volumes-vnf",
1928 "vdu": [
1929 {
1930 "id": "without_volumes-VM",
1931 "name": "without_volumes-VM",
1932 "sw-image-desc": "ubuntu20.04",
1933 "alternative-sw-image-desc": [
1934 "ubuntu20.04-aws",
1935 "ubuntu20.04-azure",
1936 ],
1937 "virtual-storage-desc": ["root-volume", "ephemeral-volume"],
1938 }
1939 ],
1940 "version": "1.0",
1941 "virtual-storage-desc": [
1942 {"id": "root-volume", "size-of-storage": "10"},
1943 {
1944 "id": "ephemeral-volume",
1945 "type-of-storage": "etsi-nfv-descriptors:ephemeral-storage",
1946 "size-of-storage": "1",
1947 },
1948 ],
1949 "_admin": {
1950 "storage": {
1951 "fs": "mongo",
1952 "path": "/app/storage/",
1953 },
1954 "type": "vnfd",
1955 },
1956 }
1957 expected_result = {
1958 "find_params": {
1959 "flavor_data": {
1960 "disk": 10,
1961 "ram": 1024,
1962 "vcpus": 2,
1963 "ephemeral": 10,
1964 },
1965 },
1966 "params": {
1967 "flavor_data": {
1968 "disk": 10,
1969 "name": "test",
1970 "ram": 1024,
1971 "vcpus": 2,
1972 "ephemeral": 10,
1973 },
1974 },
1975 }
1976 target_flavor = {
1977 "id": "test_id",
1978 "name": "test",
1979 "storage-gb": "10",
1980 "memory-mb": "1024",
1981 "vcpu-count": "2",
1982 }
1983 indata = {
1984 "vnf": [
1985 {
1986 "vdur": [
1987 {
1988 "ns-flavor-id": "test_id",
1989 "virtual-storages": [
1990 {
1991 "type-of-storage": "etsi-nfv-descriptors:ephemeral-storage",
1992 "size-of-storage": "10",
1993 },
1994 ],
1995 },
1996 ],
1997 "vnfd-id": "ad6356e3-698c-43bf-9901-3aae9e9b9d18",
1998 },
1999 ],
2000 }
2001 vim_info = {}
2002 target_record_id = ""
2003
2004 epa_params.return_value = {}
2005
2006 result = Ns._process_flavor_params(
2007 target_flavor=target_flavor,
2008 indata=indata,
2009 vim_info=vim_info,
2010 target_record_id=target_record_id,
2011 **kwargs,
2012 )
2013
2014 self.assertTrue(epa_params.called)
2015 self.assertDictEqual(result, expected_result)
2016
2017 @patch("osm_ng_ro.ns.Ns._process_epa_params")
2018 def test__process_flavor_params_with_swap_disk(
2019 self,
2020 epa_params,
2021 ):
2022 expected_result = {
2023 "find_params": {
2024 "flavor_data": {
2025 "disk": 10,
2026 "ram": 1024,
2027 "vcpus": 2,
2028 "swap": 20,
2029 },
2030 },
2031 "params": {
2032 "flavor_data": {
2033 "disk": 10,
2034 "name": "test",
2035 "ram": 1024,
2036 "vcpus": 2,
2037 "swap": 20,
2038 },
2039 },
2040 }
2041 target_flavor = {
2042 "id": "test_id",
2043 "name": "test",
2044 "storage-gb": "10",
2045 "memory-mb": "1024",
2046 "vcpu-count": "2",
2047 }
2048 indata = {
2049 "vnf": [
2050 {
2051 "vdur": [
2052 {
2053 "ns-flavor-id": "test_id",
2054 "virtual-storages": [
2055 {
2056 "type-of-storage": "etsi-nfv-descriptors:swap-storage",
2057 "size-of-storage": "20",
2058 },
2059 ],
2060 },
2061 ],
2062 "vnfd-id": "ad6356e3-698c-43bf-9901-3aae9e9b9d18",
2063 },
2064 ],
2065 }
2066 vim_info = {}
2067 target_record_id = ""
2068
2069 epa_params.return_value = {}
2070
2071 result = Ns._process_flavor_params(
2072 target_flavor=target_flavor,
2073 indata=indata,
2074 vim_info=vim_info,
2075 target_record_id=target_record_id,
2076 )
2077
2078 self.assertTrue(epa_params.called)
2079 self.assertDictEqual(result, expected_result)
2080
2081 @patch("osm_ng_ro.ns.Ns._process_epa_params")
2082 def test__process_flavor_params_with_persistent_root_disk(
2083 self,
2084 epa_params,
2085 ):
2086 kwargs = {
2087 "db": db,
2088 }
2089
2090 db.get_one.return_value = {
2091 "_id": "ad6356e3-698c-43bf-9901-3aae9e9b9d18",
2092 "df": [
2093 {
2094 "id": "default-df",
2095 "vdu-profile": [
2096 {"id": "several_volumes-VM", "min-number-of-instances": 1}
2097 ],
2098 }
2099 ],
2100 "id": "several_volumes-vnf",
2101 "product-name": "several_volumes-vnf",
2102 "vdu": [
2103 {
2104 "id": "several_volumes-VM",
2105 "name": "several_volumes-VM",
2106 "sw-image-desc": "ubuntu20.04",
2107 "alternative-sw-image-desc": [
2108 "ubuntu20.04-aws",
2109 "ubuntu20.04-azure",
2110 ],
2111 "virtual-storage-desc": [
2112 "persistent-root-volume",
2113 ],
2114 }
2115 ],
2116 "version": "1.0",
2117 "virtual-storage-desc": [
2118 {
2119 "id": "persistent-root-volume",
2120 "type-of-storage": "persistent-storage:persistent-storage",
2121 "size-of-storage": "10",
2122 },
2123 ],
2124 "_admin": {
2125 "storage": {
2126 "fs": "mongo",
2127 "path": "/app/storage/",
2128 },
2129 "type": "vnfd",
2130 },
2131 }
2132 expected_result = {
2133 "find_params": {
2134 "flavor_data": {
2135 "disk": 0,
2136 "ram": 1024,
2137 "vcpus": 2,
2138 },
2139 },
2140 "params": {
2141 "flavor_data": {
2142 "disk": 0,
2143 "name": "test",
2144 "ram": 1024,
2145 "vcpus": 2,
2146 },
2147 },
2148 }
2149 target_flavor = {
2150 "id": "test_id",
2151 "name": "test",
2152 "storage-gb": "10",
2153 "memory-mb": "1024",
2154 "vcpu-count": "2",
2155 }
2156 indata = {
2157 "vnf": [
2158 {
2159 "vdur": [
2160 {
2161 "vdu-name": "several_volumes-VM",
2162 "ns-flavor-id": "test_id",
2163 "virtual-storages": [
2164 {
2165 "type-of-storage": "persistent-storage:persistent-storage",
2166 "size-of-storage": "10",
2167 },
2168 ],
2169 },
2170 ],
2171 "vnfd-id": "ad6356e3-698c-43bf-9901-3aae9e9b9d18",
2172 },
2173 ],
2174 }
2175 vim_info = {}
2176 target_record_id = ""
2177
2178 epa_params.return_value = {}
2179
2180 result = Ns._process_flavor_params(
2181 target_flavor=target_flavor,
2182 indata=indata,
2183 vim_info=vim_info,
2184 target_record_id=target_record_id,
2185 **kwargs,
2186 )
2187
2188 self.assertTrue(epa_params.called)
2189 self.assertDictEqual(result, expected_result)
2190
2191 @patch("osm_ng_ro.ns.Ns._process_epa_params")
2192 def test__process_flavor_params_with_epa_params(
2193 self,
2194 epa_params,
2195 ):
2196 expected_result = {
2197 "find_params": {
2198 "flavor_data": {
2199 "disk": 10,
2200 "ram": 1024,
2201 "vcpus": 2,
2202 "extended": {
2203 "numa": "there-is-numa-here",
2204 },
2205 },
2206 },
2207 "params": {
2208 "flavor_data": {
2209 "disk": 10,
2210 "name": "test",
2211 "ram": 1024,
2212 "vcpus": 2,
2213 "extended": {
2214 "numa": "there-is-numa-here",
2215 },
2216 },
2217 },
2218 }
2219 target_flavor = {
2220 "id": "test_id",
2221 "name": "test",
2222 "storage-gb": "10",
2223 "memory-mb": "1024",
2224 "vcpu-count": "2",
2225 }
2226 indata = {
2227 "vnf": [
2228 {
2229 "vdur": [
2230 {
2231 "ns-flavor-id": "test_id",
2232 },
2233 ],
2234 "vnfd-id": "ad6356e3-698c-43bf-9901-3aae9e9b9d18",
2235 },
2236 ],
2237 }
2238 vim_info = {}
2239 target_record_id = ""
2240
2241 epa_params.return_value = {
2242 "numa": "there-is-numa-here",
2243 }
2244
2245 result = Ns._process_flavor_params(
2246 target_flavor=target_flavor,
2247 indata=indata,
2248 vim_info=vim_info,
2249 target_record_id=target_record_id,
2250 )
2251
2252 self.assertTrue(epa_params.called)
2253 self.assertDictEqual(result, expected_result)
2254
2255 @patch("osm_ng_ro.ns.Ns._process_epa_params")
2256 def test__process_flavor_params(
2257 self,
2258 epa_params,
2259 ):
2260 kwargs = {
2261 "db": db,
2262 }
2263
2264 db.get_one.return_value = {
2265 "_id": "ad6356e3-698c-43bf-9901-3aae9e9b9d18",
2266 "df": [
2267 {
2268 "id": "default-df",
2269 "vdu-profile": [
2270 {"id": "without_volumes-VM", "min-number-of-instances": 1}
2271 ],
2272 }
2273 ],
2274 "id": "without_volumes-vnf",
2275 "product-name": "without_volumes-vnf",
2276 "vdu": [
2277 {
2278 "id": "without_volumes-VM",
2279 "name": "without_volumes-VM",
2280 "sw-image-desc": "ubuntu20.04",
2281 "alternative-sw-image-desc": [
2282 "ubuntu20.04-aws",
2283 "ubuntu20.04-azure",
2284 ],
2285 "virtual-storage-desc": ["root-volume", "ephemeral-volume"],
2286 }
2287 ],
2288 "version": "1.0",
2289 "virtual-storage-desc": [
2290 {"id": "root-volume", "size-of-storage": "10"},
2291 {
2292 "id": "ephemeral-volume",
2293 "type-of-storage": "etsi-nfv-descriptors:ephemeral-storage",
2294 "size-of-storage": "1",
2295 },
2296 ],
2297 "_admin": {
2298 "storage": {
2299 "fs": "mongo",
2300 "path": "/app/storage/",
2301 },
2302 "type": "vnfd",
2303 },
2304 }
2305
2306 expected_result = {
2307 "find_params": {
2308 "flavor_data": {
2309 "disk": 10,
2310 "ram": 1024,
2311 "vcpus": 2,
2312 "ephemeral": 10,
2313 "swap": 20,
2314 "extended": {
2315 "numa": "there-is-numa-here",
2316 },
2317 },
2318 },
2319 "params": {
2320 "flavor_data": {
2321 "disk": 10,
2322 "name": "test",
2323 "ram": 1024,
2324 "vcpus": 2,
2325 "ephemeral": 10,
2326 "swap": 20,
2327 "extended": {
2328 "numa": "there-is-numa-here",
2329 },
2330 },
2331 },
2332 }
2333 target_flavor = {
2334 "id": "test_id",
2335 "name": "test",
2336 "storage-gb": "10",
2337 "memory-mb": "1024",
2338 "vcpu-count": "2",
2339 }
2340 indata = {
2341 "vnf": [
2342 {
2343 "vdur": [
2344 {
2345 "ns-flavor-id": "test_id",
2346 "virtual-storages": [
2347 {
2348 "type-of-storage": "etsi-nfv-descriptors:ephemeral-storage",
2349 "size-of-storage": "10",
2350 },
2351 {
2352 "type-of-storage": "etsi-nfv-descriptors:swap-storage",
2353 "size-of-storage": "20",
2354 },
2355 ],
2356 },
2357 ],
2358 "vnfd-id": "ad6356e3-698c-43bf-9901-3aae9e9b9d18",
2359 },
2360 ],
2361 }
2362 vim_info = {}
2363 target_record_id = ""
2364
2365 epa_params.return_value = {
2366 "numa": "there-is-numa-here",
2367 }
2368
2369 result = Ns._process_flavor_params(
2370 target_flavor=target_flavor,
2371 indata=indata,
2372 vim_info=vim_info,
2373 target_record_id=target_record_id,
2374 **kwargs,
2375 )
2376
2377 self.assertTrue(epa_params.called)
2378 self.assertDictEqual(result, expected_result)
2379
2380 def test__ip_profile_to_ro_with_none(self):
2381 ip_profile = None
2382
2383 result = Ns._ip_profile_to_ro(
2384 ip_profile=ip_profile,
2385 )
2386
2387 self.assertIsNone(result)
2388
2389 def test__ip_profile_to_ro_with_empty_profile(self):
2390 ip_profile = {}
2391
2392 result = Ns._ip_profile_to_ro(
2393 ip_profile=ip_profile,
2394 )
2395
2396 self.assertIsNone(result)
2397
2398 def test__ip_profile_to_ro_with_wrong_profile(self):
2399 ip_profile = {
2400 "no-profile": "here",
2401 }
2402 expected_result = {
2403 "ip_version": "IPv4",
2404 "subnet_address": None,
2405 "gateway_address": None,
2406 "dhcp_enabled": False,
2407 "dhcp_start_address": None,
2408 "dhcp_count": None,
2409 }
2410
2411 result = Ns._ip_profile_to_ro(
2412 ip_profile=ip_profile,
2413 )
2414
2415 self.assertDictEqual(expected_result, result)
2416
2417 def test__ip_profile_to_ro_with_ipv4_profile(self):
2418 ip_profile = {
2419 "ip-version": "ipv4",
2420 "subnet-address": "192.168.0.0/24",
2421 "gateway-address": "192.168.0.254",
2422 "dhcp-params": {
2423 "enabled": True,
2424 "start-address": "192.168.0.10",
2425 "count": 25,
2426 },
2427 }
2428 expected_result = {
2429 "ip_version": "IPv4",
2430 "subnet_address": "192.168.0.0/24",
2431 "gateway_address": "192.168.0.254",
2432 "dhcp_enabled": True,
2433 "dhcp_start_address": "192.168.0.10",
2434 "dhcp_count": 25,
2435 }
2436
2437 result = Ns._ip_profile_to_ro(
2438 ip_profile=ip_profile,
2439 )
2440
2441 self.assertDictEqual(expected_result, result)
2442
2443 def test__ip_profile_to_ro_with_ipv6_profile(self):
2444 ip_profile = {
2445 "ip-version": "ipv6",
2446 "subnet-address": "2001:0200:0001::/48",
2447 "gateway-address": "2001:0200:0001:ffff:ffff:ffff:ffff:fffe",
2448 "dhcp-params": {
2449 "enabled": True,
2450 "start-address": "2001:0200:0001::0010",
2451 "count": 25,
2452 },
2453 }
2454 expected_result = {
2455 "ip_version": "IPv6",
2456 "subnet_address": "2001:0200:0001::/48",
2457 "gateway_address": "2001:0200:0001:ffff:ffff:ffff:ffff:fffe",
2458 "dhcp_enabled": True,
2459 "dhcp_start_address": "2001:0200:0001::0010",
2460 "dhcp_count": 25,
2461 }
2462
2463 result = Ns._ip_profile_to_ro(
2464 ip_profile=ip_profile,
2465 )
2466
2467 self.assertDictEqual(expected_result, result)
2468
2469 def test__ip_profile_to_ro_with_dns_server(self):
2470 ip_profile = {
2471 "ip-version": "ipv4",
2472 "subnet-address": "192.168.0.0/24",
2473 "gateway-address": "192.168.0.254",
2474 "dhcp-params": {
2475 "enabled": True,
2476 "start-address": "192.168.0.10",
2477 "count": 25,
2478 },
2479 "dns-server": [
2480 {
2481 "address": "8.8.8.8",
2482 },
2483 {
2484 "address": "1.1.1.1",
2485 },
2486 {
2487 "address": "1.0.0.1",
2488 },
2489 ],
2490 }
2491 expected_result = {
2492 "ip_version": "IPv4",
2493 "subnet_address": "192.168.0.0/24",
2494 "gateway_address": "192.168.0.254",
2495 "dhcp_enabled": True,
2496 "dhcp_start_address": "192.168.0.10",
2497 "dhcp_count": 25,
2498 "dns_address": "8.8.8.8;1.1.1.1;1.0.0.1",
2499 }
2500
2501 result = Ns._ip_profile_to_ro(
2502 ip_profile=ip_profile,
2503 )
2504
2505 self.assertDictEqual(expected_result, result)
2506
2507 def test__ip_profile_to_ro_with_security_group(self):
2508 ip_profile = {
2509 "ip-version": "ipv4",
2510 "subnet-address": "192.168.0.0/24",
2511 "gateway-address": "192.168.0.254",
2512 "dhcp-params": {
2513 "enabled": True,
2514 "start-address": "192.168.0.10",
2515 "count": 25,
2516 },
2517 "security-group": {
2518 "some-security-group": "here",
2519 },
2520 }
2521 expected_result = {
2522 "ip_version": "IPv4",
2523 "subnet_address": "192.168.0.0/24",
2524 "gateway_address": "192.168.0.254",
2525 "dhcp_enabled": True,
2526 "dhcp_start_address": "192.168.0.10",
2527 "dhcp_count": 25,
2528 "security_group": {
2529 "some-security-group": "here",
2530 },
2531 }
2532
2533 result = Ns._ip_profile_to_ro(
2534 ip_profile=ip_profile,
2535 )
2536
2537 self.assertDictEqual(expected_result, result)
2538
2539 def test__ip_profile_to_ro(self):
2540 ip_profile = {
2541 "ip-version": "ipv4",
2542 "subnet-address": "192.168.0.0/24",
2543 "gateway-address": "192.168.0.254",
2544 "dhcp-params": {
2545 "enabled": True,
2546 "start-address": "192.168.0.10",
2547 "count": 25,
2548 },
2549 "dns-server": [
2550 {
2551 "address": "8.8.8.8",
2552 },
2553 {
2554 "address": "1.1.1.1",
2555 },
2556 {
2557 "address": "1.0.0.1",
2558 },
2559 ],
2560 "security-group": {
2561 "some-security-group": "here",
2562 },
2563 }
2564 expected_result = {
2565 "ip_version": "IPv4",
2566 "subnet_address": "192.168.0.0/24",
2567 "gateway_address": "192.168.0.254",
2568 "dhcp_enabled": True,
2569 "dhcp_start_address": "192.168.0.10",
2570 "dhcp_count": 25,
2571 "dns_address": "8.8.8.8;1.1.1.1;1.0.0.1",
2572 "security_group": {
2573 "some-security-group": "here",
2574 },
2575 }
2576
2577 result = Ns._ip_profile_to_ro(
2578 ip_profile=ip_profile,
2579 )
2580
2581 self.assertDictEqual(expected_result, result)
2582
2583 @patch("osm_ng_ro.ns.Ns._ip_profile_to_ro")
2584 def test__process_net_params_with_empty_params(
2585 self,
2586 ip_profile_to_ro,
2587 ):
2588 target_vld = {
2589 "name": "vld-name",
2590 }
2591 indata = {
2592 "name": "ns-name",
2593 }
2594 vim_info = {
2595 "provider_network": "some-profile-here",
2596 }
2597 target_record_id = ""
2598 expected_result = {
2599 "params": {
2600 "net_name": "ns-name-vld-name",
2601 "net_type": "bridge",
2602 "ip_profile": {
2603 "some_ip_profile": "here",
2604 },
2605 "provider_network_profile": "some-profile-here",
2606 }
2607 }
2608
2609 ip_profile_to_ro.return_value = {
2610 "some_ip_profile": "here",
2611 }
2612
2613 result = Ns._process_net_params(
2614 target_vld=target_vld,
2615 indata=indata,
2616 vim_info=vim_info,
2617 target_record_id=target_record_id,
2618 )
2619
2620 self.assertDictEqual(expected_result, result)
2621 self.assertTrue(ip_profile_to_ro.called)
2622
2623 @patch("osm_ng_ro.ns.Ns._ip_profile_to_ro")
2624 def test__process_net_params_with_vim_info_sdn(
2625 self,
2626 ip_profile_to_ro,
2627 ):
2628 target_vld = {
2629 "name": "vld-name",
2630 }
2631 indata = {
2632 "name": "ns-name",
2633 }
2634 vim_info = {
2635 "sdn": "some-sdn",
2636 "sdn-ports": ["some", "ports", "here"],
2637 "vlds": ["some", "vlds", "here"],
2638 "type": "sdn-type",
2639 }
2640 target_record_id = "vld.sdn.something"
2641 expected_result = {
2642 "params": {
2643 "sdn-ports": ["some", "ports", "here"],
2644 "vlds": ["some", "vlds", "here"],
2645 "type": "sdn-type",
2646 }
2647 }
2648
2649 result = Ns._process_net_params(
2650 target_vld=target_vld,
2651 indata=indata,
2652 vim_info=vim_info,
2653 target_record_id=target_record_id,
2654 )
2655
2656 self.assertDictEqual(expected_result, result)
2657 self.assertFalse(ip_profile_to_ro.called)
2658
2659 @patch("osm_ng_ro.ns.Ns._ip_profile_to_ro")
2660 def test__process_net_params_with_vim_info_sdn_target_vim(
2661 self,
2662 ip_profile_to_ro,
2663 ):
2664 target_vld = {
2665 "name": "vld-name",
2666 }
2667 indata = {
2668 "name": "ns-name",
2669 }
2670 vim_info = {
2671 "sdn": "some-sdn",
2672 "sdn-ports": ["some", "ports", "here"],
2673 "vlds": ["some", "vlds", "here"],
2674 "target_vim": "some-vim",
2675 "type": "sdn-type",
2676 }
2677 target_record_id = "vld.sdn.something"
2678 expected_result = {
2679 "depends_on": ["some-vim vld.sdn"],
2680 "params": {
2681 "sdn-ports": ["some", "ports", "here"],
2682 "vlds": ["some", "vlds", "here"],
2683 "target_vim": "some-vim",
2684 "type": "sdn-type",
2685 },
2686 }
2687
2688 result = Ns._process_net_params(
2689 target_vld=target_vld,
2690 indata=indata,
2691 vim_info=vim_info,
2692 target_record_id=target_record_id,
2693 )
2694
2695 self.assertDictEqual(expected_result, result)
2696 self.assertFalse(ip_profile_to_ro.called)
2697
2698 @patch("osm_ng_ro.ns.Ns._ip_profile_to_ro")
2699 def test__process_net_params_with_vim_network_name(
2700 self,
2701 ip_profile_to_ro,
2702 ):
2703 target_vld = {
2704 "name": "vld-name",
2705 }
2706 indata = {
2707 "name": "ns-name",
2708 }
2709 vim_info = {
2710 "vim_network_name": "some-network-name",
2711 }
2712 target_record_id = "vld.sdn.something"
2713 expected_result = {
2714 "find_params": {
2715 "filter_dict": {
2716 "name": "some-network-name",
2717 },
2718 },
2719 }
2720
2721 result = Ns._process_net_params(
2722 target_vld=target_vld,
2723 indata=indata,
2724 vim_info=vim_info,
2725 target_record_id=target_record_id,
2726 )
2727
2728 self.assertDictEqual(expected_result, result)
2729 self.assertFalse(ip_profile_to_ro.called)
2730
2731 @patch("osm_ng_ro.ns.Ns._ip_profile_to_ro")
2732 def test__process_net_params_with_vim_network_id(
2733 self,
2734 ip_profile_to_ro,
2735 ):
2736 target_vld = {
2737 "name": "vld-name",
2738 }
2739 indata = {
2740 "name": "ns-name",
2741 }
2742 vim_info = {
2743 "vim_network_id": "some-network-id",
2744 }
2745 target_record_id = "vld.sdn.something"
2746 expected_result = {
2747 "find_params": {
2748 "filter_dict": {
2749 "id": "some-network-id",
2750 },
2751 },
2752 }
2753
2754 result = Ns._process_net_params(
2755 target_vld=target_vld,
2756 indata=indata,
2757 vim_info=vim_info,
2758 target_record_id=target_record_id,
2759 )
2760
2761 self.assertDictEqual(expected_result, result)
2762 self.assertFalse(ip_profile_to_ro.called)
2763
2764 @patch("osm_ng_ro.ns.Ns._ip_profile_to_ro")
2765 def test__process_net_params_with_mgmt_network(
2766 self,
2767 ip_profile_to_ro,
2768 ):
2769 target_vld = {
2770 "id": "vld-id",
2771 "name": "vld-name",
2772 "mgmt-network": "some-mgmt-network",
2773 }
2774 indata = {
2775 "name": "ns-name",
2776 }
2777 vim_info = {}
2778 target_record_id = "vld.sdn.something"
2779 expected_result = {
2780 "find_params": {
2781 "mgmt": True,
2782 "name": "vld-id",
2783 },
2784 }
2785
2786 result = Ns._process_net_params(
2787 target_vld=target_vld,
2788 indata=indata,
2789 vim_info=vim_info,
2790 target_record_id=target_record_id,
2791 )
2792
2793 self.assertDictEqual(expected_result, result)
2794 self.assertFalse(ip_profile_to_ro.called)
2795
2796 @patch("osm_ng_ro.ns.Ns._ip_profile_to_ro")
2797 def test__process_net_params_with_underlay_eline(
2798 self,
2799 ip_profile_to_ro,
2800 ):
2801 target_vld = {
2802 "name": "vld-name",
2803 "underlay": "some-underlay-here",
2804 "type": "ELINE",
2805 }
2806 indata = {
2807 "name": "ns-name",
2808 }
2809 vim_info = {
2810 "provider_network": "some-profile-here",
2811 }
2812 target_record_id = ""
2813 expected_result = {
2814 "params": {
2815 "ip_profile": {
2816 "some_ip_profile": "here",
2817 },
2818 "net_name": "ns-name-vld-name",
2819 "net_type": "ptp",
2820 "provider_network_profile": "some-profile-here",
2821 }
2822 }
2823
2824 ip_profile_to_ro.return_value = {
2825 "some_ip_profile": "here",
2826 }
2827
2828 result = Ns._process_net_params(
2829 target_vld=target_vld,
2830 indata=indata,
2831 vim_info=vim_info,
2832 target_record_id=target_record_id,
2833 )
2834
2835 self.assertDictEqual(expected_result, result)
2836 self.assertTrue(ip_profile_to_ro.called)
2837
2838 @patch("osm_ng_ro.ns.Ns._ip_profile_to_ro")
2839 def test__process_net_params_with_underlay_elan(
2840 self,
2841 ip_profile_to_ro,
2842 ):
2843 target_vld = {
2844 "name": "vld-name",
2845 "underlay": "some-underlay-here",
2846 "type": "ELAN",
2847 }
2848 indata = {
2849 "name": "ns-name",
2850 }
2851 vim_info = {
2852 "provider_network": "some-profile-here",
2853 }
2854 target_record_id = ""
2855 expected_result = {
2856 "params": {
2857 "ip_profile": {
2858 "some_ip_profile": "here",
2859 },
2860 "net_name": "ns-name-vld-name",
2861 "net_type": "data",
2862 "provider_network_profile": "some-profile-here",
2863 }
2864 }
2865
2866 ip_profile_to_ro.return_value = {
2867 "some_ip_profile": "here",
2868 }
2869
2870 result = Ns._process_net_params(
2871 target_vld=target_vld,
2872 indata=indata,
2873 vim_info=vim_info,
2874 target_record_id=target_record_id,
2875 )
2876
2877 self.assertDictEqual(expected_result, result)
2878 self.assertTrue(ip_profile_to_ro.called)
2879
2880 def test__get_cloud_init_exception(self):
2881 db_mock = MagicMock(name="database mock")
2882 fs_mock = None
2883
2884 location = ""
2885
2886 with self.assertRaises(NsException):
2887 Ns._get_cloud_init(db=db_mock, fs=fs_mock, location=location)
2888
2889 def test__get_cloud_init_file_fs_exception(self):
2890 db_mock = MagicMock(name="database mock")
2891 fs_mock = None
2892
2893 location = "vnfr_id_123456:file:test_file"
2894 db_mock.get_one.return_value = {
2895 "_admin": {
2896 "storage": {
2897 "folder": "/home/osm",
2898 "pkg-dir": "vnfr_test_dir",
2899 },
2900 },
2901 }
2902
2903 with self.assertRaises(NsException):
2904 Ns._get_cloud_init(db=db_mock, fs=fs_mock, location=location)
2905
2906 def test__get_cloud_init_file(self):
2907 db_mock = MagicMock(name="database mock")
2908 fs_mock = MagicMock(name="filesystem mock")
2909 file_mock = MagicMock(name="file mock")
2910
2911 location = "vnfr_id_123456:file:test_file"
2912 cloud_init_content = "this is a cloud init file content"
2913
2914 db_mock.get_one.return_value = {
2915 "_admin": {
2916 "storage": {
2917 "folder": "/home/osm",
2918 "pkg-dir": "vnfr_test_dir",
2919 },
2920 },
2921 }
2922 fs_mock.file_open.return_value = file_mock
2923 file_mock.__enter__.return_value.read.return_value = cloud_init_content
2924
2925 result = Ns._get_cloud_init(db=db_mock, fs=fs_mock, location=location)
2926
2927 self.assertEqual(cloud_init_content, result)
2928
2929 def test__get_cloud_init_vdu(self):
2930 db_mock = MagicMock(name="database mock")
2931 fs_mock = None
2932
2933 location = "vnfr_id_123456:vdu:0"
2934 cloud_init_content = "this is a cloud init file content"
2935
2936 db_mock.get_one.return_value = {
2937 "vdu": {
2938 0: {
2939 "cloud-init": cloud_init_content,
2940 },
2941 },
2942 }
2943
2944 result = Ns._get_cloud_init(db=db_mock, fs=fs_mock, location=location)
2945
2946 self.assertEqual(cloud_init_content, result)
2947
2948 @patch("jinja2.Environment.__init__")
2949 def test__parse_jinja2_undefined_error(self, env_mock: Mock):
2950 cloud_init_content = None
2951 params = None
2952 context = None
2953
2954 env_mock.side_effect = UndefinedError("UndefinedError occurred.")
2955
2956 with self.assertRaises(NsException):
2957 Ns._parse_jinja2(
2958 cloud_init_content=cloud_init_content, params=params, context=context
2959 )
2960
2961 @patch("jinja2.Environment.__init__")
2962 def test__parse_jinja2_template_error(self, env_mock: Mock):
2963 cloud_init_content = None
2964 params = None
2965 context = None
2966
2967 env_mock.side_effect = TemplateError("TemplateError occurred.")
2968
2969 with self.assertRaises(NsException):
2970 Ns._parse_jinja2(
2971 cloud_init_content=cloud_init_content, params=params, context=context
2972 )
2973
2974 @patch("jinja2.Environment.__init__")
2975 def test__parse_jinja2_template_not_found(self, env_mock: Mock):
2976 cloud_init_content = None
2977 params = None
2978 context = None
2979
2980 env_mock.side_effect = TemplateNotFound("TemplateNotFound occurred.")
2981
2982 with self.assertRaises(NsException):
2983 Ns._parse_jinja2(
2984 cloud_init_content=cloud_init_content, params=params, context=context
2985 )
2986
2987 def test_rendering_jinja2_temp_without_special_characters(self):
2988 cloud_init_content = """
2989 disk_setup:
2990 ephemeral0:
2991 table_type: {{type}}
2992 layout: True
2993 overwrite: {{is_override}}
2994 runcmd:
2995 - [ ls, -l, / ]
2996 - [ sh, -xc, "echo $(date) '{{command}}'" ]
2997 """
2998 params = {
2999 "type": "mbr",
3000 "is_override": "False",
3001 "command": "; mkdir abc",
3002 }
3003 context = "cloud-init for VM"
3004 expected_result = """
3005 disk_setup:
3006 ephemeral0:
3007 table_type: mbr
3008 layout: True
3009 overwrite: False
3010 runcmd:
3011 - [ ls, -l, / ]
3012 - [ sh, -xc, "echo $(date) '; mkdir abc'" ]
3013 """
3014 result = Ns._parse_jinja2(
3015 cloud_init_content=cloud_init_content, params=params, context=context
3016 )
3017 self.assertEqual(result, expected_result)
3018
3019 def test_rendering_jinja2_temp_with_special_characters(self):
3020 cloud_init_content = """
3021 disk_setup:
3022 ephemeral0:
3023 table_type: {{type}}
3024 layout: True
3025 overwrite: {{is_override}}
3026 runcmd:
3027 - [ ls, -l, / ]
3028 - [ sh, -xc, "echo $(date) '{{command}}'" ]
3029 """
3030 params = {
3031 "type": "mbr",
3032 "is_override": "False",
3033 "command": "& rm -rf",
3034 }
3035 context = "cloud-init for VM"
3036 expected_result = """
3037 disk_setup:
3038 ephemeral0:
3039 table_type: mbr
3040 layout: True
3041 overwrite: False
3042 runcmd:
3043 - [ ls, -l, / ]
3044 - [ sh, -xc, "echo $(date) '& rm -rf /'" ]
3045 """
3046 result = Ns._parse_jinja2(
3047 cloud_init_content=cloud_init_content, params=params, context=context
3048 )
3049 self.assertNotEqual(result, expected_result)
3050
3051 def test_rendering_jinja2_temp_with_special_characters_autoescape_is_false(self):
3052 with patch("osm_ng_ro.ns.Environment") as mock_environment:
3053 mock_environment.return_value = Environment(
3054 undefined=StrictUndefined,
3055 autoescape=select_autoescape(default_for_string=False, default=False),
3056 )
3057 cloud_init_content = """
3058 disk_setup:
3059 ephemeral0:
3060 table_type: {{type}}
3061 layout: True
3062 overwrite: {{is_override}}
3063 runcmd:
3064 - [ ls, -l, / ]
3065 - [ sh, -xc, "echo $(date) '{{command}}'" ]
3066 """
3067 params = {
3068 "type": "mbr",
3069 "is_override": "False",
3070 "command": "& rm -rf /",
3071 }
3072 context = "cloud-init for VM"
3073 expected_result = """
3074 disk_setup:
3075 ephemeral0:
3076 table_type: mbr
3077 layout: True
3078 overwrite: False
3079 runcmd:
3080 - [ ls, -l, / ]
3081 - [ sh, -xc, "echo $(date) '& rm -rf /'" ]
3082 """
3083 result = Ns._parse_jinja2(
3084 cloud_init_content=cloud_init_content,
3085 params=params,
3086 context=context,
3087 )
3088 self.assertEqual(result, expected_result)
3089
3090 @patch("osm_ng_ro.ns.Ns._assign_vim")
3091 def test__rebuild_start_stop_task(self, assign_vim):
3092 self.ns = Ns()
3093 extra_dict = {}
3094 actions = ["start", "stop", "rebuild"]
3095 vdu_id = "bb9c43f9-10a2-4569-a8a8-957c3528b6d1"
3096 vnf_id = "665b4165-ce24-4320-bf19-b9a45bade49f"
3097 vdu_index = "0"
3098 action_id = "bb937f49-3870-4169-b758-9732e1ff40f3"
3099 nsr_id = "993166fe-723e-4680-ac4b-b1af2541ae31"
3100 task_index = 0
3101 target_vim = "vim:f9f370ac-0d44-41a7-9000-457f2332bc35"
3102 t = "vnfrs:665b4165-ce24-4320-bf19-b9a45bade49f:vdur.bb9c43f9-10a2-4569-a8a8-957c3528b6d1"
3103 for action in actions:
3104 expected_result = {
3105 "target_id": "vim:f9f370ac-0d44-41a7-9000-457f2332bc35",
3106 "action_id": "bb937f49-3870-4169-b758-9732e1ff40f3",
3107 "nsr_id": "993166fe-723e-4680-ac4b-b1af2541ae31",
3108 "task_id": "bb937f49-3870-4169-b758-9732e1ff40f3:0",
3109 "status": "SCHEDULED",
3110 "action": "EXEC",
3111 "item": "update",
3112 "target_record": "vnfrs:665b4165-ce24-4320-bf19-b9a45bade49f:vdur.0",
3113 "target_record_id": t,
3114 "params": {
3115 "vim_vm_id": "f37b18ef-3caa-4dc9-ab91-15c669b16396",
3116 "action": action,
3117 },
3118 }
3119 extra_dict["params"] = {
3120 "vim_vm_id": "f37b18ef-3caa-4dc9-ab91-15c669b16396",
3121 "action": action,
3122 }
3123 task = self.ns.rebuild_start_stop_task(
3124 vdu_id,
3125 vnf_id,
3126 vdu_index,
3127 action_id,
3128 nsr_id,
3129 task_index,
3130 target_vim,
3131 extra_dict,
3132 )
3133 self.assertEqual(task.get("action_id"), action_id)
3134 self.assertEqual(task.get("nsr_id"), nsr_id)
3135 self.assertEqual(task.get("target_id"), target_vim)
3136 self.assertDictEqual(task, expected_result)
3137
3138 @patch("osm_ng_ro.ns.Ns._assign_vim")
3139 def test_verticalscale_task(self, assign_vim):
3140 self.ns = Ns()
3141 extra_dict = {}
3142 vdu_index = "1"
3143 action_id = "bb937f49-3870-4169-b758-9732e1ff40f3"
3144 nsr_id = "993166fe-723e-4680-ac4b-b1af2541ae31"
3145 task_index = 1
3146 target_record_id = (
3147 "vnfrs:665b4165-ce24-4320-bf19-b9a45bade49f:"
3148 "vdur.bb9c43f9-10a2-4569-a8a8-957c3528b6d1"
3149 )
3150
3151 expected_result = {
3152 "target_id": "vim:f9f370ac-0d44-41a7-9000-457f2332bc35",
3153 "action_id": "bb937f49-3870-4169-b758-9732e1ff40f3",
3154 "nsr_id": "993166fe-723e-4680-ac4b-b1af2541ae31",
3155 "task_id": "bb937f49-3870-4169-b758-9732e1ff40f3:1",
3156 "status": "SCHEDULED",
3157 "action": "EXEC",
3158 "item": "verticalscale",
3159 "target_record": "vnfrs:665b4165-ce24-4320-bf19-b9a45bade49f:vdur.1",
3160 "target_record_id": target_record_id,
3161 "params": {
3162 "vim_vm_id": "f37b18ef-3caa-4dc9-ab91-15c669b16396",
3163 "flavor_dict": "flavor_dict",
3164 },
3165 }
3166 vdu = {
3167 "id": "bb9c43f9-10a2-4569-a8a8-957c3528b6d1",
3168 "vim_info": {
3169 "vim:f9f370ac-0d44-41a7-9000-457f2332bc35": {"interfaces": []}
3170 },
3171 }
3172 vnf = {"_id": "665b4165-ce24-4320-bf19-b9a45bade49f"}
3173 extra_dict["params"] = {
3174 "vim_vm_id": "f37b18ef-3caa-4dc9-ab91-15c669b16396",
3175 "flavor_dict": "flavor_dict",
3176 }
3177 task = self.ns.verticalscale_task(
3178 vdu, vnf, vdu_index, action_id, nsr_id, task_index, extra_dict
3179 )
3180
3181 self.assertDictEqual(task, expected_result)
3182
3183 @patch("osm_ng_ro.ns.Ns._assign_vim")
3184 def test_migrate_task(self, assign_vim):
3185 self.ns = Ns()
3186 extra_dict = {}
3187 vdu_index = "1"
3188 action_id = "bb937f49-3870-4169-b758-9732e1ff40f3"
3189 nsr_id = "993166fe-723e-4680-ac4b-b1af2541ae31"
3190 task_index = 1
3191 target_record_id = (
3192 "vnfrs:665b4165-ce24-4320-bf19-b9a45bade49f:"
3193 "vdur.bb9c43f9-10a2-4569-a8a8-957c3528b6d1"
3194 )
3195
3196 expected_result = {
3197 "target_id": "vim:f9f370ac-0d44-41a7-9000-457f2332bc35",
3198 "action_id": "bb937f49-3870-4169-b758-9732e1ff40f3",
3199 "nsr_id": "993166fe-723e-4680-ac4b-b1af2541ae31",
3200 "task_id": "bb937f49-3870-4169-b758-9732e1ff40f3:1",
3201 "status": "SCHEDULED",
3202 "action": "EXEC",
3203 "item": "migrate",
3204 "target_record": "vnfrs:665b4165-ce24-4320-bf19-b9a45bade49f:vdur.1",
3205 "target_record_id": target_record_id,
3206 "params": {
3207 "vim_vm_id": "f37b18ef-3caa-4dc9-ab91-15c669b16396",
3208 "migrate_host": "migrateToHost",
3209 },
3210 }
3211 vdu = {
3212 "id": "bb9c43f9-10a2-4569-a8a8-957c3528b6d1",
3213 "vim_info": {
3214 "vim:f9f370ac-0d44-41a7-9000-457f2332bc35": {"interfaces": []}
3215 },
3216 }
3217 vnf = {"_id": "665b4165-ce24-4320-bf19-b9a45bade49f"}
3218 extra_dict["params"] = {
3219 "vim_vm_id": "f37b18ef-3caa-4dc9-ab91-15c669b16396",
3220 "migrate_host": "migrateToHost",
3221 }
3222 task = self.ns.migrate_task(
3223 vdu, vnf, vdu_index, action_id, nsr_id, task_index, extra_dict
3224 )
3225
3226 self.assertDictEqual(task, expected_result)
3227
3228
3229 class TestProcessVduParams(unittest.TestCase):
3230 def setUp(self):
3231 self.ns = Ns()
3232 self.logger = CopyingMock(autospec=True)
3233
3234 def test_find_persistent_root_volumes_empty_instantiation_vol_list(self):
3235 """Find persistent root volume, instantiation_vol_list is empty."""
3236 vnfd = deepcopy(vnfd_wth_persistent_storage)
3237 target_vdu = target_vdu_wth_persistent_storage
3238 vdu_instantiation_volumes_list = []
3239 disk_list = []
3240 expected_persist_root_disk = {
3241 "persistent-root-volume": {
3242 "image_id": "ubuntu20.04",
3243 "size": "10",
3244 }
3245 }
3246 expected_disk_list = [
3247 {
3248 "image_id": "ubuntu20.04",
3249 "size": "10",
3250 },
3251 ]
3252 persist_root_disk = self.ns.find_persistent_root_volumes(
3253 vnfd, target_vdu, vdu_instantiation_volumes_list, disk_list
3254 )
3255 self.assertEqual(persist_root_disk, expected_persist_root_disk)
3256 self.assertEqual(disk_list, expected_disk_list)
3257 self.assertEqual(len(disk_list), 1)
3258
3259 def test_find_persistent_root_volumes_always_selects_first_vsd_as_root(self):
3260 """Find persistent root volume, always selects the first vsd as root volume."""
3261 vnfd = deepcopy(vnfd_wth_persistent_storage)
3262 vnfd["vdu"][0]["virtual-storage-desc"] = [
3263 "persistent-volume2",
3264 "persistent-root-volume",
3265 "ephemeral-volume",
3266 ]
3267 target_vdu = target_vdu_wth_persistent_storage
3268 vdu_instantiation_volumes_list = []
3269 disk_list = []
3270 expected_persist_root_disk = {
3271 "persistent-volume2": {
3272 "image_id": "ubuntu20.04",
3273 "size": "10",
3274 }
3275 }
3276 expected_disk_list = [
3277 {
3278 "image_id": "ubuntu20.04",
3279 "size": "10",
3280 },
3281 ]
3282 persist_root_disk = self.ns.find_persistent_root_volumes(
3283 vnfd, target_vdu, vdu_instantiation_volumes_list, disk_list
3284 )
3285 self.assertEqual(persist_root_disk, expected_persist_root_disk)
3286 self.assertEqual(disk_list, expected_disk_list)
3287 self.assertEqual(len(disk_list), 1)
3288
3289 def test_find_persistent_root_volumes_empty_size_of_storage(self):
3290 """Find persistent root volume, size of storage is empty."""
3291 vnfd = deepcopy(vnfd_wth_persistent_storage)
3292 vnfd["virtual-storage-desc"][0]["size-of-storage"] = ""
3293 vnfd["vdu"][0]["virtual-storage-desc"] = [
3294 "persistent-volume2",
3295 "persistent-root-volume",
3296 "ephemeral-volume",
3297 ]
3298 target_vdu = target_vdu_wth_persistent_storage
3299 vdu_instantiation_volumes_list = []
3300 disk_list = []
3301 persist_root_disk = self.ns.find_persistent_root_volumes(
3302 vnfd, target_vdu, vdu_instantiation_volumes_list, disk_list
3303 )
3304 self.assertEqual(persist_root_disk, None)
3305 self.assertEqual(disk_list, [])
3306
3307 def test_find_persistent_root_empty_disk_list(self):
3308 """Find persistent root volume, empty disk list."""
3309 vnfd = deepcopy(vnfd_wth_persistent_storage)
3310 target_vdu = target_vdu_wth_persistent_storage
3311 vdu_instantiation_volumes_list = []
3312 disk_list = []
3313 expected_persist_root_disk = {
3314 "persistent-root-volume": {
3315 "image_id": "ubuntu20.04",
3316 "size": "10",
3317 }
3318 }
3319 expected_disk_list = [
3320 {
3321 "image_id": "ubuntu20.04",
3322 "size": "10",
3323 },
3324 ]
3325 persist_root_disk = self.ns.find_persistent_root_volumes(
3326 vnfd, target_vdu, vdu_instantiation_volumes_list, disk_list
3327 )
3328 self.assertEqual(persist_root_disk, expected_persist_root_disk)
3329 self.assertEqual(disk_list, expected_disk_list)
3330 self.assertEqual(len(disk_list), 1)
3331
3332 def test_find_persistent_root_volumes_target_vdu_mismatch(self):
3333 """Find persistent root volume, target vdu name is not matching."""
3334 vnfd = deepcopy(vnfd_wth_persistent_storage)
3335 vnfd["vdu"][0]["name"] = "Several_Volumes-VM"
3336 target_vdu = target_vdu_wth_persistent_storage
3337 vdu_instantiation_volumes_list = []
3338 disk_list = []
3339 result = self.ns.find_persistent_root_volumes(
3340 vnfd, target_vdu, vdu_instantiation_volumes_list, disk_list
3341 )
3342 self.assertEqual(result, None)
3343 self.assertEqual(disk_list, [])
3344 self.assertEqual(len(disk_list), 0)
3345
3346 def test_find_persistent_root_volumes_with_instantiation_vol_list(self):
3347 """Find persistent root volume, existing volume needs to be used."""
3348 vnfd = deepcopy(vnfd_wth_persistent_storage)
3349 target_vdu = target_vdu_wth_persistent_storage
3350 vdu_instantiation_volumes_list = [
3351 {
3352 "vim-volume-id": vim_volume_id,
3353 "name": "persistent-root-volume",
3354 }
3355 ]
3356 disk_list = []
3357 expected_persist_root_disk = {
3358 "persistent-root-volume": {
3359 "vim_volume_id": vim_volume_id,
3360 "image_id": "ubuntu20.04",
3361 },
3362 }
3363 expected_disk_list = [
3364 {
3365 "vim_volume_id": vim_volume_id,
3366 "image_id": "ubuntu20.04",
3367 },
3368 ]
3369 persist_root_disk = self.ns.find_persistent_root_volumes(
3370 vnfd, target_vdu, vdu_instantiation_volumes_list, disk_list
3371 )
3372 self.assertEqual(persist_root_disk, expected_persist_root_disk)
3373 self.assertEqual(disk_list, expected_disk_list)
3374 self.assertEqual(len(disk_list), 1)
3375
3376 def test_find_persistent_root_volumes_invalid_instantiation_params(self):
3377 """Find persistent root volume, existing volume id keyword is invalid."""
3378 vnfd = deepcopy(vnfd_wth_persistent_storage)
3379 target_vdu = target_vdu_wth_persistent_storage
3380 vdu_instantiation_volumes_list = [
3381 {
3382 "volume-id": vim_volume_id,
3383 "name": "persistent-root-volume",
3384 }
3385 ]
3386 disk_list = []
3387 with self.assertRaises(KeyError):
3388 self.ns.find_persistent_root_volumes(
3389 vnfd, target_vdu, vdu_instantiation_volumes_list, disk_list
3390 )
3391
3392 self.assertEqual(disk_list, [])
3393 self.assertEqual(len(disk_list), 0)
3394
3395 def test_find_persistent_volumes_vdu_wth_persistent_root_disk_wthout_inst_vol_list(
3396 self,
3397 ):
3398 """Find persistent ordinary volume, there is persistent root disk and instatiation volume list is empty."""
3399 persistent_root_disk = {
3400 "persistent-root-volume": {
3401 "image_id": "ubuntu20.04",
3402 "size": "10",
3403 }
3404 }
3405
3406 target_vdu = target_vdu_wth_persistent_storage
3407 vdu_instantiation_volumes_list = []
3408 disk_list = [
3409 {
3410 "image_id": "ubuntu20.04",
3411 "size": "10",
3412 },
3413 ]
3414
3415 expected_disk_list = [
3416 {
3417 "image_id": "ubuntu20.04",
3418 "size": "10",
3419 },
3420 {
3421 "size": "10",
3422 },
3423 ]
3424 self.ns.find_persistent_volumes(
3425 persistent_root_disk, target_vdu, vdu_instantiation_volumes_list, disk_list
3426 )
3427 self.assertEqual(disk_list, expected_disk_list)
3428
3429 def test_find_persistent_volumes_vdu_wth_inst_vol_list(self):
3430 """Find persistent ordinary volume, vim-volume-id is given as instantiation parameter."""
3431 persistent_root_disk = {
3432 "persistent-root-volume": {
3433 "image_id": "ubuntu20.04",
3434 "size": "10",
3435 }
3436 }
3437 vdu_instantiation_volumes_list = [
3438 {
3439 "vim-volume-id": vim_volume_id,
3440 "name": "persistent-volume2",
3441 }
3442 ]
3443 target_vdu = target_vdu_wth_persistent_storage
3444 disk_list = [
3445 {
3446 "image_id": "ubuntu20.04",
3447 "size": "10",
3448 },
3449 ]
3450 expected_disk_list = [
3451 {
3452 "image_id": "ubuntu20.04",
3453 "size": "10",
3454 },
3455 {
3456 "vim_volume_id": vim_volume_id,
3457 },
3458 ]
3459 self.ns.find_persistent_volumes(
3460 persistent_root_disk, target_vdu, vdu_instantiation_volumes_list, disk_list
3461 )
3462 self.assertEqual(disk_list, expected_disk_list)
3463
3464 def test_find_persistent_volumes_vdu_wthout_persistent_storage(self):
3465 """Find persistent ordinary volume, there is not any persistent disk."""
3466 persistent_root_disk = {}
3467 vdu_instantiation_volumes_list = []
3468 target_vdu = target_vdu_wthout_persistent_storage
3469 disk_list = []
3470 self.ns.find_persistent_volumes(
3471 persistent_root_disk, target_vdu, vdu_instantiation_volumes_list, disk_list
3472 )
3473 self.assertEqual(disk_list, disk_list)
3474
3475 def test_find_persistent_volumes_vdu_wth_persistent_root_disk_wthout_ordinary_disk(
3476 self,
3477 ):
3478 """There is persistent root disk, but there is not ordinary persistent disk."""
3479 persistent_root_disk = {
3480 "persistent-root-volume": {
3481 "image_id": "ubuntu20.04",
3482 "size": "10",
3483 }
3484 }
3485 vdu_instantiation_volumes_list = []
3486 target_vdu = deepcopy(target_vdu_wth_persistent_storage)
3487 target_vdu["virtual-storages"] = [
3488 {
3489 "id": "persistent-root-volume",
3490 "size-of-storage": "10",
3491 "type-of-storage": "persistent-storage:persistent-storage",
3492 },
3493 {
3494 "id": "ephemeral-volume",
3495 "size-of-storage": "1",
3496 "type-of-storage": "etsi-nfv-descriptors:ephemeral-storage",
3497 },
3498 ]
3499 disk_list = [
3500 {
3501 "image_id": "ubuntu20.04",
3502 "size": "10",
3503 },
3504 ]
3505 self.ns.find_persistent_volumes(
3506 persistent_root_disk, target_vdu, vdu_instantiation_volumes_list, disk_list
3507 )
3508 self.assertEqual(disk_list, disk_list)
3509
3510 def test_find_persistent_volumes_wth_inst_vol_list_disk_id_mismatch(self):
3511 """Find persistent ordinary volume, volume id is not persistent_root_disk dict,
3512 vim-volume-id is given as instantiation parameter but disk id is not matching.
3513 """
3514 vdu_instantiation_volumes_list = [
3515 {
3516 "vim-volume-id": vim_volume_id,
3517 "name": "persistent-volume3",
3518 }
3519 ]
3520 persistent_root_disk = {
3521 "persistent-root-volume": {
3522 "image_id": "ubuntu20.04",
3523 "size": "10",
3524 }
3525 }
3526 disk_list = [
3527 {
3528 "image_id": "ubuntu20.04",
3529 "size": "10",
3530 },
3531 ]
3532 expected_disk_list = [
3533 {
3534 "image_id": "ubuntu20.04",
3535 "size": "10",
3536 },
3537 {
3538 "size": "10",
3539 },
3540 ]
3541
3542 target_vdu = target_vdu_wth_persistent_storage
3543 self.ns.find_persistent_volumes(
3544 persistent_root_disk, target_vdu, vdu_instantiation_volumes_list, disk_list
3545 )
3546 self.assertEqual(disk_list, expected_disk_list)
3547
3548 def test_sort_vdu_interfaces_position_all_wth_positions(self):
3549 """Interfaces are sorted according to position, all have positions."""
3550 target_vdu = deepcopy(target_vdu_wth_persistent_storage)
3551 target_vdu["interfaces"] = [
3552 {
3553 "name": "vdu-eth1",
3554 "ns-vld-id": "datanet",
3555 "position": 2,
3556 },
3557 {
3558 "name": "vdu-eth0",
3559 "ns-vld-id": "mgmtnet",
3560 "position": 1,
3561 },
3562 ]
3563 sorted_interfaces = [
3564 {
3565 "name": "vdu-eth0",
3566 "ns-vld-id": "mgmtnet",
3567 "position": 1,
3568 },
3569 {
3570 "name": "vdu-eth1",
3571 "ns-vld-id": "datanet",
3572 "position": 2,
3573 },
3574 ]
3575 self.ns._sort_vdu_interfaces(target_vdu)
3576 self.assertEqual(target_vdu["interfaces"], sorted_interfaces)
3577
3578 def test_sort_vdu_interfaces_position_some_wth_position(self):
3579 """Interfaces are sorted according to position, some of them have positions."""
3580 target_vdu = deepcopy(target_vdu_wth_persistent_storage)
3581 target_vdu["interfaces"] = [
3582 {
3583 "name": "vdu-eth0",
3584 "ns-vld-id": "mgmtnet",
3585 },
3586 {
3587 "name": "vdu-eth1",
3588 "ns-vld-id": "datanet",
3589 "position": 1,
3590 },
3591 ]
3592 sorted_interfaces = [
3593 {
3594 "name": "vdu-eth1",
3595 "ns-vld-id": "datanet",
3596 "position": 1,
3597 },
3598 {
3599 "name": "vdu-eth0",
3600 "ns-vld-id": "mgmtnet",
3601 },
3602 ]
3603 self.ns._sort_vdu_interfaces(target_vdu)
3604 self.assertEqual(target_vdu["interfaces"], sorted_interfaces)
3605
3606 def test_sort_vdu_interfaces_position_empty_interface_list(self):
3607 """Interface list is empty."""
3608 target_vdu = deepcopy(target_vdu_wth_persistent_storage)
3609 target_vdu["interfaces"] = []
3610 sorted_interfaces = []
3611 self.ns._sort_vdu_interfaces(target_vdu)
3612 self.assertEqual(target_vdu["interfaces"], sorted_interfaces)
3613
3614 def test_partially_locate_vdu_interfaces(self):
3615 """Some interfaces have positions."""
3616 target_vdu = deepcopy(target_vdu_wth_persistent_storage)
3617 target_vdu["interfaces"] = [
3618 {
3619 "name": "vdu-eth1",
3620 "ns-vld-id": "net1",
3621 },
3622 {"name": "vdu-eth2", "ns-vld-id": "net2", "position": 3},
3623 {
3624 "name": "vdu-eth3",
3625 "ns-vld-id": "mgmtnet",
3626 },
3627 {
3628 "name": "vdu-eth1",
3629 "ns-vld-id": "datanet",
3630 "position": 1,
3631 },
3632 ]
3633 self.ns._partially_locate_vdu_interfaces(target_vdu)
3634 self.assertDictEqual(
3635 target_vdu["interfaces"][0],
3636 {
3637 "name": "vdu-eth1",
3638 "ns-vld-id": "datanet",
3639 "position": 1,
3640 },
3641 )
3642 self.assertDictEqual(
3643 target_vdu["interfaces"][2],
3644 {"name": "vdu-eth2", "ns-vld-id": "net2", "position": 3},
3645 )
3646
3647 def test_partially_locate_vdu_interfaces_position_start_from_0(self):
3648 """Some interfaces have positions, position start from 0."""
3649 target_vdu = deepcopy(target_vdu_wth_persistent_storage)
3650 target_vdu["interfaces"] = [
3651 {
3652 "name": "vdu-eth1",
3653 "ns-vld-id": "net1",
3654 },
3655 {"name": "vdu-eth2", "ns-vld-id": "net2", "position": 3},
3656 {
3657 "name": "vdu-eth3",
3658 "ns-vld-id": "mgmtnet",
3659 },
3660 {
3661 "name": "vdu-eth1",
3662 "ns-vld-id": "datanet",
3663 "position": 0,
3664 },
3665 ]
3666 self.ns._partially_locate_vdu_interfaces(target_vdu)
3667 self.assertDictEqual(
3668 target_vdu["interfaces"][0],
3669 {
3670 "name": "vdu-eth1",
3671 "ns-vld-id": "datanet",
3672 "position": 0,
3673 },
3674 )
3675 self.assertDictEqual(
3676 target_vdu["interfaces"][3],
3677 {"name": "vdu-eth2", "ns-vld-id": "net2", "position": 3},
3678 )
3679
3680 def test_partially_locate_vdu_interfaces_wthout_position(self):
3681 """Interfaces do not have positions."""
3682 target_vdu = deepcopy(target_vdu_wth_persistent_storage)
3683 target_vdu["interfaces"] = interfaces_wthout_positions
3684 expected_result = deepcopy(target_vdu["interfaces"])
3685 self.ns._partially_locate_vdu_interfaces(target_vdu)
3686 self.assertEqual(target_vdu["interfaces"], expected_result)
3687
3688 def test_partially_locate_vdu_interfaces_all_has_position(self):
3689 """All interfaces have position."""
3690 target_vdu = deepcopy(target_vdu_wth_persistent_storage)
3691 target_vdu["interfaces"] = interfaces_wth_all_positions
3692 expected_interfaces = [
3693 {
3694 "name": "vdu-eth2",
3695 "ns-vld-id": "net2",
3696 "position": 0,
3697 },
3698 {
3699 "name": "vdu-eth3",
3700 "ns-vld-id": "mgmtnet",
3701 "position": 1,
3702 },
3703 {
3704 "name": "vdu-eth1",
3705 "ns-vld-id": "net1",
3706 "position": 2,
3707 },
3708 ]
3709 self.ns._partially_locate_vdu_interfaces(target_vdu)
3710 self.assertEqual(target_vdu["interfaces"], expected_interfaces)
3711
3712 @patch("osm_ng_ro.ns.Ns._get_cloud_init")
3713 @patch("osm_ng_ro.ns.Ns._parse_jinja2")
3714 def test_prepare_vdu_cloud_init(self, mock_parse_jinja2, mock_get_cloud_init):
3715 """Target_vdu has cloud-init and boot-data-drive."""
3716 target_vdu = deepcopy(target_vdu_wth_persistent_storage)
3717 target_vdu["cloud-init"] = "sample-cloud-init-path"
3718 target_vdu["boot-data-drive"] = "vda"
3719 vdu2cloud_init = {}
3720 mock_get_cloud_init.return_value = cloud_init_content
3721 mock_parse_jinja2.return_value = user_data
3722 expected_result = {
3723 "user-data": user_data,
3724 "boot-data-drive": "vda",
3725 }
3726 result = self.ns._prepare_vdu_cloud_init(target_vdu, vdu2cloud_init, db, fs)
3727 self.assertDictEqual(result, expected_result)
3728 mock_get_cloud_init.assert_called_once_with(
3729 db=db, fs=fs, location="sample-cloud-init-path"
3730 )
3731 mock_parse_jinja2.assert_called_once_with(
3732 cloud_init_content=cloud_init_content,
3733 params=None,
3734 context="sample-cloud-init-path",
3735 )
3736
3737 @patch("osm_ng_ro.ns.Ns._get_cloud_init")
3738 @patch("osm_ng_ro.ns.Ns._parse_jinja2")
3739 def test_prepare_vdu_cloud_init_get_cloud_init_raise_exception(
3740 self, mock_parse_jinja2, mock_get_cloud_init
3741 ):
3742 """Target_vdu has cloud-init and boot-data-drive, get_cloud_init method raises exception."""
3743 target_vdu = deepcopy(target_vdu_wth_persistent_storage)
3744 target_vdu["cloud-init"] = "sample-cloud-init-path"
3745 target_vdu["boot-data-drive"] = "vda"
3746 vdu2cloud_init = {}
3747 mock_get_cloud_init.side_effect = NsException(
3748 "Mismatch descriptor for cloud init."
3749 )
3750
3751 with self.assertRaises(NsException) as err:
3752 self.ns._prepare_vdu_cloud_init(target_vdu, vdu2cloud_init, db, fs)
3753 self.assertEqual(str(err.exception), "Mismatch descriptor for cloud init.")
3754
3755 mock_get_cloud_init.assert_called_once_with(
3756 db=db, fs=fs, location="sample-cloud-init-path"
3757 )
3758 mock_parse_jinja2.assert_not_called()
3759
3760 @patch("osm_ng_ro.ns.Ns._get_cloud_init")
3761 @patch("osm_ng_ro.ns.Ns._parse_jinja2")
3762 def test_prepare_vdu_cloud_init_parse_jinja2_raise_exception(
3763 self, mock_parse_jinja2, mock_get_cloud_init
3764 ):
3765 """Target_vdu has cloud-init and boot-data-drive, parse_jinja2 method raises exception."""
3766 target_vdu = deepcopy(target_vdu_wth_persistent_storage)
3767 target_vdu["cloud-init"] = "sample-cloud-init-path"
3768 target_vdu["boot-data-drive"] = "vda"
3769 vdu2cloud_init = {}
3770 mock_get_cloud_init.return_value = cloud_init_content
3771 mock_parse_jinja2.side_effect = NsException("Error parsing cloud-init content.")
3772
3773 with self.assertRaises(NsException) as err:
3774 self.ns._prepare_vdu_cloud_init(target_vdu, vdu2cloud_init, db, fs)
3775 self.assertEqual(str(err.exception), "Error parsing cloud-init content.")
3776 mock_get_cloud_init.assert_called_once_with(
3777 db=db, fs=fs, location="sample-cloud-init-path"
3778 )
3779 mock_parse_jinja2.assert_called_once_with(
3780 cloud_init_content=cloud_init_content,
3781 params=None,
3782 context="sample-cloud-init-path",
3783 )
3784
3785 @patch("osm_ng_ro.ns.Ns._get_cloud_init")
3786 @patch("osm_ng_ro.ns.Ns._parse_jinja2")
3787 def test_prepare_vdu_cloud_init_vdu_wthout_boot_data_drive(
3788 self, mock_parse_jinja2, mock_get_cloud_init
3789 ):
3790 """Target_vdu has cloud-init but do not have boot-data-drive."""
3791 target_vdu = deepcopy(target_vdu_wth_persistent_storage)
3792 target_vdu["cloud-init"] = "sample-cloud-init-path"
3793 vdu2cloud_init = {}
3794 mock_get_cloud_init.return_value = cloud_init_content
3795 mock_parse_jinja2.return_value = user_data
3796 expected_result = {
3797 "user-data": user_data,
3798 }
3799 result = self.ns._prepare_vdu_cloud_init(target_vdu, vdu2cloud_init, db, fs)
3800 self.assertDictEqual(result, expected_result)
3801 mock_get_cloud_init.assert_called_once_with(
3802 db=db, fs=fs, location="sample-cloud-init-path"
3803 )
3804 mock_parse_jinja2.assert_called_once_with(
3805 cloud_init_content=cloud_init_content,
3806 params=None,
3807 context="sample-cloud-init-path",
3808 )
3809
3810 @patch("osm_ng_ro.ns.Ns._get_cloud_init")
3811 @patch("osm_ng_ro.ns.Ns._parse_jinja2")
3812 def test_prepare_vdu_cloud_init_exists_in_vdu2cloud_init(
3813 self, mock_parse_jinja2, mock_get_cloud_init
3814 ):
3815 """Target_vdu has cloud-init, vdu2cloud_init dict has cloud-init_content."""
3816 target_vdu = deepcopy(target_vdu_wth_persistent_storage)
3817 target_vdu["cloud-init"] = "sample-cloud-init-path"
3818 target_vdu["boot-data-drive"] = "vda"
3819 vdu2cloud_init = {"sample-cloud-init-path": cloud_init_content}
3820 mock_parse_jinja2.return_value = user_data
3821 expected_result = {
3822 "user-data": user_data,
3823 "boot-data-drive": "vda",
3824 }
3825 result = self.ns._prepare_vdu_cloud_init(target_vdu, vdu2cloud_init, db, fs)
3826 self.assertDictEqual(result, expected_result)
3827 mock_get_cloud_init.assert_not_called()
3828 mock_parse_jinja2.assert_called_once_with(
3829 cloud_init_content=cloud_init_content,
3830 params=None,
3831 context="sample-cloud-init-path",
3832 )
3833
3834 @patch("osm_ng_ro.ns.Ns._get_cloud_init")
3835 @patch("osm_ng_ro.ns.Ns._parse_jinja2")
3836 def test_prepare_vdu_cloud_init_no_cloud_init(
3837 self, mock_parse_jinja2, mock_get_cloud_init
3838 ):
3839 """Target_vdu do not have cloud-init."""
3840 target_vdu = deepcopy(target_vdu_wth_persistent_storage)
3841 target_vdu["boot-data-drive"] = "vda"
3842 vdu2cloud_init = {}
3843 expected_result = {
3844 "boot-data-drive": "vda",
3845 }
3846 result = self.ns._prepare_vdu_cloud_init(target_vdu, vdu2cloud_init, db, fs)
3847 self.assertDictEqual(result, expected_result)
3848 mock_get_cloud_init.assert_not_called()
3849 mock_parse_jinja2.assert_not_called()
3850
3851 def test_check_vld_information_of_interfaces_ns_vld_vnf_vld_both_exist(self):
3852 """ns_vld and vnf_vld both exist."""
3853 interface = {
3854 "name": "vdu-eth0",
3855 "ns-vld-id": "mgmtnet",
3856 "vnf-vld-id": "mgmt_cp_int",
3857 }
3858 expected_result = f"{ns_preffix}:vld.mgmtnet"
3859 result = self.ns._check_vld_information_of_interfaces(
3860 interface, ns_preffix, vnf_preffix
3861 )
3862 self.assertEqual(result, expected_result)
3863
3864 def test_check_vld_information_of_interfaces_empty_interfaces(self):
3865 """Interface dict is empty."""
3866 interface = {}
3867 result = self.ns._check_vld_information_of_interfaces(
3868 interface, ns_preffix, vnf_preffix
3869 )
3870 self.assertEqual(result, "")
3871
3872 def test_check_vld_information_of_interfaces_has_only_vnf_vld(self):
3873 """Interface dict has only vnf_vld."""
3874 interface = {
3875 "name": "vdu-eth0",
3876 "vnf-vld-id": "mgmt_cp_int",
3877 }
3878 expected_result = f"{vnf_preffix}:vld.mgmt_cp_int"
3879 result = self.ns._check_vld_information_of_interfaces(
3880 interface, ns_preffix, vnf_preffix
3881 )
3882 self.assertEqual(result, expected_result)
3883
3884 def test_check_vld_information_of_interfaces_has_vnf_vld_wthout_vnf_prefix(
3885 self,
3886 ):
3887 """Interface dict has only vnf_vld but vnf_preffix does not exist."""
3888 interface = {
3889 "name": "vdu-eth0",
3890 "vnf-vld-id": "mgmt_cp_int",
3891 }
3892 vnf_preffix = None
3893 with self.assertRaises(Exception) as err:
3894 self.ns._check_vld_information_of_interfaces(
3895 interface, ns_preffix, vnf_preffix
3896 )
3897 self.assertEqual(type(err), TypeError)
3898
3899 def test_prepare_interface_port_security_has_security_details(self):
3900 """Interface dict has port security details."""
3901 interface = {
3902 "name": "vdu-eth0",
3903 "ns-vld-id": "mgmtnet",
3904 "vnf-vld-id": "mgmt_cp_int",
3905 "port-security-enabled": True,
3906 "port-security-disable-strategy": "allow-address-pairs",
3907 }
3908 expected_interface = {
3909 "name": "vdu-eth0",
3910 "ns-vld-id": "mgmtnet",
3911 "vnf-vld-id": "mgmt_cp_int",
3912 "port_security": True,
3913 "port_security_disable_strategy": "allow-address-pairs",
3914 }
3915 self.ns._prepare_interface_port_security(interface)
3916 self.assertDictEqual(interface, expected_interface)
3917
3918 def test_prepare_interface_port_security_empty_interfaces(self):
3919 """Interface dict is empty."""
3920 interface = {}
3921 expected_interface = {}
3922 self.ns._prepare_interface_port_security(interface)
3923 self.assertDictEqual(interface, expected_interface)
3924
3925 def test_prepare_interface_port_security_wthout_port_security(self):
3926 """Interface dict does not have port security details."""
3927 interface = {
3928 "name": "vdu-eth0",
3929 "ns-vld-id": "mgmtnet",
3930 "vnf-vld-id": "mgmt_cp_int",
3931 }
3932 expected_interface = {
3933 "name": "vdu-eth0",
3934 "ns-vld-id": "mgmtnet",
3935 "vnf-vld-id": "mgmt_cp_int",
3936 }
3937 self.ns._prepare_interface_port_security(interface)
3938 self.assertDictEqual(interface, expected_interface)
3939
3940 def test_create_net_item_of_interface_floating_ip_port_security(self):
3941 """Interface dict has floating ip, port-security details."""
3942 interface = {
3943 "name": "vdu-eth0",
3944 "vcpi": "sample_vcpi",
3945 "port_security": True,
3946 "port_security_disable_strategy": "allow-address-pairs",
3947 "floating_ip": "10.1.1.12",
3948 "ns-vld-id": "mgmtnet",
3949 "vnf-vld-id": "mgmt_cp_int",
3950 }
3951 net_text = f"{ns_preffix}"
3952 expected_net_item = {
3953 "name": "vdu-eth0",
3954 "port_security": True,
3955 "port_security_disable_strategy": "allow-address-pairs",
3956 "floating_ip": "10.1.1.12",
3957 "net_id": f"TASK-{ns_preffix}",
3958 "type": "virtual",
3959 }
3960 result = self.ns._create_net_item_of_interface(interface, net_text)
3961 self.assertDictEqual(result, expected_net_item)
3962
3963 def test_create_net_item_of_interface_invalid_net_text(self):
3964 """net-text is invalid."""
3965 interface = {
3966 "name": "vdu-eth0",
3967 "vcpi": "sample_vcpi",
3968 "port_security": True,
3969 "port_security_disable_strategy": "allow-address-pairs",
3970 "floating_ip": "10.1.1.12",
3971 "ns-vld-id": "mgmtnet",
3972 "vnf-vld-id": "mgmt_cp_int",
3973 }
3974 net_text = None
3975 with self.assertRaises(TypeError):
3976 self.ns._create_net_item_of_interface(interface, net_text)
3977
3978 def test_create_net_item_of_interface_empty_interface(self):
3979 """Interface dict is empty."""
3980 interface = {}
3981 net_text = ns_preffix
3982 expected_net_item = {
3983 "net_id": f"TASK-{ns_preffix}",
3984 "type": "virtual",
3985 }
3986 result = self.ns._create_net_item_of_interface(interface, net_text)
3987 self.assertDictEqual(result, expected_net_item)
3988
3989 @patch("osm_ng_ro.ns.deep_get")
3990 def test_prepare_type_of_interface_type_sriov(self, mock_deep_get):
3991 """Interface type is SR-IOV."""
3992 interface = {
3993 "name": "vdu-eth0",
3994 "vcpi": "sample_vcpi",
3995 "port_security": True,
3996 "port_security_disable_strategy": "allow-address-pairs",
3997 "floating_ip": "10.1.1.12",
3998 "ns-vld-id": "mgmtnet",
3999 "vnf-vld-id": "mgmt_cp_int",
4000 "type": "SR-IOV",
4001 }
4002 mock_deep_get.return_value = "SR-IOV"
4003 net_text = ns_preffix
4004 net_item = {}
4005 expected_net_item = {
4006 "use": "data",
4007 "model": "SR-IOV",
4008 "type": "SR-IOV",
4009 }
4010 self.ns._prepare_type_of_interface(
4011 interface, tasks_by_target_record_id, net_text, net_item
4012 )
4013 self.assertDictEqual(net_item, expected_net_item)
4014 self.assertEqual(
4015 "data",
4016 tasks_by_target_record_id[net_text]["extra_dict"]["params"]["net_type"],
4017 )
4018 mock_deep_get.assert_called_once_with(
4019 tasks_by_target_record_id, net_text, "extra_dict", "params", "net_type"
4020 )
4021
4022 @patch("osm_ng_ro.ns.deep_get")
4023 def test_prepare_type_of_interface_type_pic_passthrough_deep_get_return_empty_dict(
4024 self, mock_deep_get
4025 ):
4026 """Interface type is PCI-PASSTHROUGH, deep_get method return empty dict."""
4027 interface = {
4028 "name": "vdu-eth0",
4029 "vcpi": "sample_vcpi",
4030 "port_security": True,
4031 "port_security_disable_strategy": "allow-address-pairs",
4032 "floating_ip": "10.1.1.12",
4033 "ns-vld-id": "mgmtnet",
4034 "vnf-vld-id": "mgmt_cp_int",
4035 "type": "PCI-PASSTHROUGH",
4036 }
4037 mock_deep_get.return_value = {}
4038 tasks_by_target_record_id = {}
4039 net_text = ns_preffix
4040 net_item = {}
4041 expected_net_item = {
4042 "use": "data",
4043 "model": "PCI-PASSTHROUGH",
4044 "type": "PCI-PASSTHROUGH",
4045 }
4046 self.ns._prepare_type_of_interface(
4047 interface, tasks_by_target_record_id, net_text, net_item
4048 )
4049 self.assertDictEqual(net_item, expected_net_item)
4050 mock_deep_get.assert_called_once_with(
4051 tasks_by_target_record_id, net_text, "extra_dict", "params", "net_type"
4052 )
4053
4054 @patch("osm_ng_ro.ns.deep_get")
4055 def test_prepare_type_of_interface_type_mgmt(self, mock_deep_get):
4056 """Interface type is mgmt."""
4057 interface = {
4058 "name": "vdu-eth0",
4059 "vcpi": "sample_vcpi",
4060 "port_security": True,
4061 "port_security_disable_strategy": "allow-address-pairs",
4062 "floating_ip": "10.1.1.12",
4063 "ns-vld-id": "mgmtnet",
4064 "vnf-vld-id": "mgmt_cp_int",
4065 "type": "OM-MGMT",
4066 }
4067 tasks_by_target_record_id = {}
4068 net_text = ns_preffix
4069 net_item = {}
4070 expected_net_item = {
4071 "use": "mgmt",
4072 }
4073 self.ns._prepare_type_of_interface(
4074 interface, tasks_by_target_record_id, net_text, net_item
4075 )
4076 self.assertDictEqual(net_item, expected_net_item)
4077 mock_deep_get.assert_not_called()
4078
4079 @patch("osm_ng_ro.ns.deep_get")
4080 def test_prepare_type_of_interface_type_bridge(self, mock_deep_get):
4081 """Interface type is bridge."""
4082 interface = {
4083 "name": "vdu-eth0",
4084 "vcpi": "sample_vcpi",
4085 "port_security": True,
4086 "port_security_disable_strategy": "allow-address-pairs",
4087 "floating_ip": "10.1.1.12",
4088 "ns-vld-id": "mgmtnet",
4089 "vnf-vld-id": "mgmt_cp_int",
4090 }
4091 tasks_by_target_record_id = {}
4092 net_text = ns_preffix
4093 net_item = {}
4094 expected_net_item = {
4095 "use": "bridge",
4096 "model": None,
4097 }
4098 self.ns._prepare_type_of_interface(
4099 interface, tasks_by_target_record_id, net_text, net_item
4100 )
4101 self.assertDictEqual(net_item, expected_net_item)
4102 mock_deep_get.assert_not_called()
4103
4104 @patch("osm_ng_ro.ns.Ns._check_vld_information_of_interfaces")
4105 @patch("osm_ng_ro.ns.Ns._prepare_interface_port_security")
4106 @patch("osm_ng_ro.ns.Ns._create_net_item_of_interface")
4107 @patch("osm_ng_ro.ns.Ns._prepare_type_of_interface")
4108 def test_prepare_vdu_interfaces(
4109 self,
4110 mock_type_of_interface,
4111 mock_item_of_interface,
4112 mock_port_security,
4113 mock_vld_information_of_interface,
4114 ):
4115 """Prepare vdu interfaces successfully."""
4116 target_vdu = deepcopy(target_vdu_wth_persistent_storage)
4117 interface_1 = {
4118 "name": "vdu-eth1",
4119 "ns-vld-id": "net1",
4120 "ip-address": "13.2.12.31",
4121 "mgmt-interface": True,
4122 }
4123 interface_2 = {
4124 "name": "vdu-eth2",
4125 "vnf-vld-id": "net2",
4126 "mac-address": "d0:94:66:ed:fc:e2",
4127 }
4128 interface_3 = {
4129 "name": "vdu-eth3",
4130 "ns-vld-id": "mgmtnet",
4131 }
4132 target_vdu["interfaces"] = [interface_1, interface_2, interface_3]
4133 extra_dict = {
4134 "params": "test_params",
4135 "find_params": "test_find_params",
4136 "depends_on": [],
4137 }
4138
4139 net_text_1 = f"{ns_preffix}:net1"
4140 net_text_2 = f"{vnf_preffix}:net2"
4141 net_text_3 = f"{ns_preffix}:mgmtnet"
4142 net_item_1 = {
4143 "name": "vdu-eth1",
4144 "net_id": f"TASK-{ns_preffix}",
4145 "type": "virtual",
4146 }
4147 net_item_2 = {
4148 "name": "vdu-eth2",
4149 "net_id": f"TASK-{ns_preffix}",
4150 "type": "virtual",
4151 }
4152 net_item_3 = {
4153 "name": "vdu-eth3",
4154 "net_id": f"TASK-{ns_preffix}",
4155 "type": "virtual",
4156 }
4157 mock_item_of_interface.side_effect = [net_item_1, net_item_2, net_item_3]
4158 mock_vld_information_of_interface.side_effect = [
4159 net_text_1,
4160 net_text_2,
4161 net_text_3,
4162 ]
4163 net_list = []
4164 expected_extra_dict = {
4165 "params": "test_params",
4166 "find_params": "test_find_params",
4167 "depends_on": [net_text_1, net_text_2, net_text_3],
4168 "mgmt_vdu_interface": 0,
4169 }
4170 updated_net_item1 = deepcopy(net_item_1)
4171 updated_net_item1.update({"ip_address": "13.2.12.31"})
4172 updated_net_item2 = deepcopy(net_item_2)
4173 updated_net_item2.update({"mac_address": "d0:94:66:ed:fc:e2"})
4174 expected_net_list = [updated_net_item1, updated_net_item2, net_item_3]
4175 self.ns._prepare_vdu_interfaces(
4176 target_vdu,
4177 extra_dict,
4178 ns_preffix,
4179 vnf_preffix,
4180 self.logger,
4181 tasks_by_target_record_id,
4182 net_list,
4183 )
4184 _call_mock_vld_information_of_interface = (
4185 mock_vld_information_of_interface.call_args_list
4186 )
4187 self.assertEqual(
4188 _call_mock_vld_information_of_interface[0][0],
4189 (interface_1, ns_preffix, vnf_preffix),
4190 )
4191 self.assertEqual(
4192 _call_mock_vld_information_of_interface[1][0],
4193 (interface_2, ns_preffix, vnf_preffix),
4194 )
4195 self.assertEqual(
4196 _call_mock_vld_information_of_interface[2][0],
4197 (interface_3, ns_preffix, vnf_preffix),
4198 )
4199
4200 _call_mock_port_security = mock_port_security.call_args_list
4201 self.assertEqual(_call_mock_port_security[0].args[0], interface_1)
4202 self.assertEqual(_call_mock_port_security[1].args[0], interface_2)
4203 self.assertEqual(_call_mock_port_security[2].args[0], interface_3)
4204
4205 _call_mock_item_of_interface = mock_item_of_interface.call_args_list
4206 self.assertEqual(_call_mock_item_of_interface[0][0], (interface_1, net_text_1))
4207 self.assertEqual(_call_mock_item_of_interface[1][0], (interface_2, net_text_2))
4208 self.assertEqual(_call_mock_item_of_interface[2][0], (interface_3, net_text_3))
4209
4210 _call_mock_type_of_interface = mock_type_of_interface.call_args_list
4211 self.assertEqual(
4212 _call_mock_type_of_interface[0][0],
4213 (interface_1, tasks_by_target_record_id, net_text_1, net_item_1),
4214 )
4215 self.assertEqual(
4216 _call_mock_type_of_interface[1][0],
4217 (interface_2, tasks_by_target_record_id, net_text_2, net_item_2),
4218 )
4219 self.assertEqual(
4220 _call_mock_type_of_interface[2][0],
4221 (interface_3, tasks_by_target_record_id, net_text_3, net_item_3),
4222 )
4223 self.assertEqual(net_list, expected_net_list)
4224 self.assertEqual(extra_dict, expected_extra_dict)
4225 self.logger.error.assert_not_called()
4226
4227 @patch("osm_ng_ro.ns.Ns._check_vld_information_of_interfaces")
4228 @patch("osm_ng_ro.ns.Ns._prepare_interface_port_security")
4229 @patch("osm_ng_ro.ns.Ns._create_net_item_of_interface")
4230 @patch("osm_ng_ro.ns.Ns._prepare_type_of_interface")
4231 def test_prepare_vdu_interfaces_create_net_item_raise_exception(
4232 self,
4233 mock_type_of_interface,
4234 mock_item_of_interface,
4235 mock_port_security,
4236 mock_vld_information_of_interface,
4237 ):
4238 """Prepare vdu interfaces, create_net_item_of_interface method raise exception."""
4239 target_vdu = deepcopy(target_vdu_wth_persistent_storage)
4240 interface_1 = {
4241 "name": "vdu-eth1",
4242 "ns-vld-id": "net1",
4243 "ip-address": "13.2.12.31",
4244 "mgmt-interface": True,
4245 }
4246 interface_2 = {
4247 "name": "vdu-eth2",
4248 "vnf-vld-id": "net2",
4249 "mac-address": "d0:94:66:ed:fc:e2",
4250 }
4251 interface_3 = {
4252 "name": "vdu-eth3",
4253 "ns-vld-id": "mgmtnet",
4254 }
4255 target_vdu["interfaces"] = [interface_1, interface_2, interface_3]
4256 extra_dict = {
4257 "params": "test_params",
4258 "find_params": "test_find_params",
4259 "depends_on": [],
4260 }
4261 net_text_1 = f"{ns_preffix}:net1"
4262 mock_item_of_interface.side_effect = [TypeError, TypeError, TypeError]
4263
4264 mock_vld_information_of_interface.side_effect = [net_text_1]
4265 net_list = []
4266 expected_extra_dict = {
4267 "params": "test_params",
4268 "find_params": "test_find_params",
4269 "depends_on": [net_text_1],
4270 }
4271 with self.assertRaises(TypeError):
4272 self.ns._prepare_vdu_interfaces(
4273 target_vdu,
4274 extra_dict,
4275 ns_preffix,
4276 vnf_preffix,
4277 self.logger,
4278 tasks_by_target_record_id,
4279 net_list,
4280 )
4281
4282 _call_mock_vld_information_of_interface = (
4283 mock_vld_information_of_interface.call_args_list
4284 )
4285 self.assertEqual(
4286 _call_mock_vld_information_of_interface[0][0],
4287 (interface_1, ns_preffix, vnf_preffix),
4288 )
4289
4290 _call_mock_port_security = mock_port_security.call_args_list
4291 self.assertEqual(_call_mock_port_security[0].args[0], interface_1)
4292
4293 _call_mock_item_of_interface = mock_item_of_interface.call_args_list
4294 self.assertEqual(_call_mock_item_of_interface[0][0], (interface_1, net_text_1))
4295
4296 mock_type_of_interface.assert_not_called()
4297 self.logger.error.assert_not_called()
4298 self.assertEqual(net_list, [])
4299 self.assertEqual(extra_dict, expected_extra_dict)
4300
4301 @patch("osm_ng_ro.ns.Ns._check_vld_information_of_interfaces")
4302 @patch("osm_ng_ro.ns.Ns._prepare_interface_port_security")
4303 @patch("osm_ng_ro.ns.Ns._create_net_item_of_interface")
4304 @patch("osm_ng_ro.ns.Ns._prepare_type_of_interface")
4305 def test_prepare_vdu_interfaces_vld_information_is_empty(
4306 self,
4307 mock_type_of_interface,
4308 mock_item_of_interface,
4309 mock_port_security,
4310 mock_vld_information_of_interface,
4311 ):
4312 """Prepare vdu interfaces, check_vld_information_of_interface method returns empty result."""
4313 target_vdu = deepcopy(target_vdu_wth_persistent_storage)
4314 interface_1 = {
4315 "name": "vdu-eth1",
4316 "ns-vld-id": "net1",
4317 "ip-address": "13.2.12.31",
4318 "mgmt-interface": True,
4319 }
4320 interface_2 = {
4321 "name": "vdu-eth2",
4322 "vnf-vld-id": "net2",
4323 "mac-address": "d0:94:66:ed:fc:e2",
4324 }
4325 interface_3 = {
4326 "name": "vdu-eth3",
4327 "ns-vld-id": "mgmtnet",
4328 }
4329 target_vdu["interfaces"] = [interface_1, interface_2, interface_3]
4330 extra_dict = {
4331 "params": "test_params",
4332 "find_params": "test_find_params",
4333 "depends_on": [],
4334 }
4335 mock_vld_information_of_interface.side_effect = ["", "", ""]
4336 net_list = []
4337 self.ns._prepare_vdu_interfaces(
4338 target_vdu,
4339 extra_dict,
4340 ns_preffix,
4341 vnf_preffix,
4342 self.logger,
4343 tasks_by_target_record_id,
4344 net_list,
4345 )
4346
4347 _call_mock_vld_information_of_interface = (
4348 mock_vld_information_of_interface.call_args_list
4349 )
4350 self.assertEqual(
4351 _call_mock_vld_information_of_interface[0][0],
4352 (interface_1, ns_preffix, vnf_preffix),
4353 )
4354 self.assertEqual(
4355 _call_mock_vld_information_of_interface[1][0],
4356 (interface_2, ns_preffix, vnf_preffix),
4357 )
4358 self.assertEqual(
4359 _call_mock_vld_information_of_interface[2][0],
4360 (interface_3, ns_preffix, vnf_preffix),
4361 )
4362
4363 _call_logger = self.logger.error.call_args_list
4364 self.assertEqual(
4365 _call_logger[0][0],
4366 ("Interface 0 from vdu several_volumes-VM not connected to any vld",),
4367 )
4368 self.assertEqual(
4369 _call_logger[1][0],
4370 ("Interface 1 from vdu several_volumes-VM not connected to any vld",),
4371 )
4372 self.assertEqual(
4373 _call_logger[2][0],
4374 ("Interface 2 from vdu several_volumes-VM not connected to any vld",),
4375 )
4376 self.assertEqual(net_list, [])
4377 self.assertEqual(
4378 extra_dict,
4379 {
4380 "params": "test_params",
4381 "find_params": "test_find_params",
4382 "depends_on": [],
4383 },
4384 )
4385
4386 mock_item_of_interface.assert_not_called()
4387 mock_port_security.assert_not_called()
4388 mock_type_of_interface.assert_not_called()
4389
4390 @patch("osm_ng_ro.ns.Ns._check_vld_information_of_interfaces")
4391 @patch("osm_ng_ro.ns.Ns._prepare_interface_port_security")
4392 @patch("osm_ng_ro.ns.Ns._create_net_item_of_interface")
4393 @patch("osm_ng_ro.ns.Ns._prepare_type_of_interface")
4394 def test_prepare_vdu_interfaces_empty_interface_list(
4395 self,
4396 mock_type_of_interface,
4397 mock_item_of_interface,
4398 mock_port_security,
4399 mock_vld_information_of_interface,
4400 ):
4401 """Prepare vdu interfaces, interface list is empty."""
4402 target_vdu = deepcopy(target_vdu_wth_persistent_storage)
4403 target_vdu["interfaces"] = []
4404 extra_dict = {}
4405 net_list = []
4406 self.ns._prepare_vdu_interfaces(
4407 target_vdu,
4408 extra_dict,
4409 ns_preffix,
4410 vnf_preffix,
4411 self.logger,
4412 tasks_by_target_record_id,
4413 net_list,
4414 )
4415 mock_type_of_interface.assert_not_called()
4416 mock_vld_information_of_interface.assert_not_called()
4417 mock_item_of_interface.assert_not_called()
4418 mock_port_security.assert_not_called()
4419
4420 def test_prepare_vdu_ssh_keys(self):
4421 """Target_vdu has ssh-keys and ro_nsr_public_key exists."""
4422 target_vdu = deepcopy(target_vdu_wth_persistent_storage)
4423 target_vdu["ssh-keys"] = ["sample-ssh-key"]
4424 ro_nsr_public_key = {"public_key": "path_of_public_key"}
4425 target_vdu["ssh-access-required"] = True
4426 cloud_config = {}
4427 expected_cloud_config = {
4428 "key-pairs": ["sample-ssh-key", {"public_key": "path_of_public_key"}]
4429 }
4430 self.ns._prepare_vdu_ssh_keys(target_vdu, ro_nsr_public_key, cloud_config)
4431 self.assertDictEqual(cloud_config, expected_cloud_config)
4432
4433 def test_prepare_vdu_ssh_keys_target_vdu_wthout_ssh_keys(self):
4434 """Target_vdu does not have ssh-keys."""
4435 target_vdu = deepcopy(target_vdu_wth_persistent_storage)
4436 ro_nsr_public_key = {"public_key": "path_of_public_key"}
4437 target_vdu["ssh-access-required"] = True
4438 cloud_config = {}
4439 expected_cloud_config = {"key-pairs": [{"public_key": "path_of_public_key"}]}
4440 self.ns._prepare_vdu_ssh_keys(target_vdu, ro_nsr_public_key, cloud_config)
4441 self.assertDictEqual(cloud_config, expected_cloud_config)
4442
4443 def test_prepare_vdu_ssh_keys_ssh_access_is_not_required(self):
4444 """Target_vdu has ssh-keys, ssh-access is not required."""
4445 target_vdu = deepcopy(target_vdu_wth_persistent_storage)
4446 target_vdu["ssh-keys"] = ["sample-ssh-key"]
4447 ro_nsr_public_key = {"public_key": "path_of_public_key"}
4448 target_vdu["ssh-access-required"] = False
4449 cloud_config = {}
4450 expected_cloud_config = {"key-pairs": ["sample-ssh-key"]}
4451 self.ns._prepare_vdu_ssh_keys(target_vdu, ro_nsr_public_key, cloud_config)
4452 self.assertDictEqual(cloud_config, expected_cloud_config)
4453
4454 @patch("osm_ng_ro.ns.Ns._select_persistent_root_disk")
4455 def test_add_persistent_root_disk_to_disk_list(
4456 self, mock_select_persistent_root_disk
4457 ):
4458 """Add persistent root disk to disk_list"""
4459 root_disk = {
4460 "id": "persistent-root-volume",
4461 "type-of-storage": "persistent-storage:persistent-storage",
4462 "size-of-storage": "10",
4463 }
4464 mock_select_persistent_root_disk.return_value = root_disk
4465 vnfd = deepcopy(vnfd_wth_persistent_storage)
4466 vnfd["virtual-storage-desc"][1] = root_disk
4467 target_vdu = deepcopy(target_vdu_wth_persistent_storage)
4468 persistent_root_disk = {}
4469 disk_list = []
4470 expected_disk_list = [
4471 {
4472 "image_id": "ubuntu20.04",
4473 "size": "10",
4474 }
4475 ]
4476 self.ns._add_persistent_root_disk_to_disk_list(
4477 vnfd, target_vdu, persistent_root_disk, disk_list
4478 )
4479 self.assertEqual(disk_list, expected_disk_list)
4480 mock_select_persistent_root_disk.assert_called_once()
4481
4482 @patch("osm_ng_ro.ns.Ns._select_persistent_root_disk")
4483 def test_add_persistent_root_disk_to_disk_list_select_persistent_root_disk_raises(
4484 self, mock_select_persistent_root_disk
4485 ):
4486 """Add persistent root disk to disk_list"""
4487 root_disk = {
4488 "id": "persistent-root-volume",
4489 "type-of-storage": "persistent-storage:persistent-storage",
4490 "size-of-storage": "10",
4491 }
4492 mock_select_persistent_root_disk.side_effect = AttributeError
4493 vnfd = deepcopy(vnfd_wth_persistent_storage)
4494 vnfd["virtual-storage-desc"][1] = root_disk
4495 target_vdu = deepcopy(target_vdu_wth_persistent_storage)
4496 persistent_root_disk = {}
4497 disk_list = []
4498 with self.assertRaises(AttributeError):
4499 self.ns._add_persistent_root_disk_to_disk_list(
4500 vnfd, target_vdu, persistent_root_disk, disk_list
4501 )
4502 self.assertEqual(disk_list, [])
4503 mock_select_persistent_root_disk.assert_called_once()
4504
4505 def test_add_persistent_ordinary_disk_to_disk_list(self):
4506 """Add persistent ordinary disk to disk_list"""
4507 target_vdu = deepcopy(target_vdu_wth_persistent_storage)
4508 persistent_root_disk = {
4509 "persistent-root-volume": {
4510 "image_id": "ubuntu20.04",
4511 "size": "10",
4512 }
4513 }
4514 persistent_ordinary_disk = {}
4515 disk_list = []
4516 expected_disk_list = [
4517 {
4518 "size": "10",
4519 }
4520 ]
4521 self.ns._add_persistent_ordinary_disks_to_disk_list(
4522 target_vdu, persistent_root_disk, persistent_ordinary_disk, disk_list
4523 )
4524 self.assertEqual(disk_list, expected_disk_list)
4525
4526 def test_add_persistent_ordinary_disk_to_disk_list_vsd_id_in_root_disk_dict(self):
4527 """Add persistent ordinary disk, vsd id is in root_disk dict."""
4528 target_vdu = deepcopy(target_vdu_wth_persistent_storage)
4529 persistent_root_disk = {
4530 "persistent-root-volume": {
4531 "image_id": "ubuntu20.04",
4532 "size": "10",
4533 },
4534 "persistent-volume2": {
4535 "size": "10",
4536 },
4537 }
4538 persistent_ordinary_disk = {}
4539 disk_list = []
4540
4541 self.ns._add_persistent_ordinary_disks_to_disk_list(
4542 target_vdu, persistent_root_disk, persistent_ordinary_disk, disk_list
4543 )
4544 self.assertEqual(disk_list, [])
4545
4546 @patch("osm_ng_ro.ns.Ns._select_persistent_root_disk")
4547 def test_add_persistent_root_disk_to_disk_list_vnfd_wthout_persistent_storage(
4548 self, mock_select_persistent_root_disk
4549 ):
4550 """VNFD does not have persistent storage."""
4551 vnfd = deepcopy(vnfd_wthout_persistent_storage)
4552 target_vdu = deepcopy(target_vdu_wthout_persistent_storage)
4553 mock_select_persistent_root_disk.return_value = None
4554 persistent_root_disk = {}
4555 disk_list = []
4556 self.ns._add_persistent_root_disk_to_disk_list(
4557 vnfd, target_vdu, persistent_root_disk, disk_list
4558 )
4559 self.assertEqual(disk_list, [])
4560 self.assertEqual(mock_select_persistent_root_disk.call_count, 2)
4561
4562 @patch("osm_ng_ro.ns.Ns._select_persistent_root_disk")
4563 def test_add_persistent_root_disk_to_disk_list_wthout_persistent_root_disk(
4564 self, mock_select_persistent_root_disk
4565 ):
4566 """Persistent_root_disk dict is empty."""
4567 vnfd = deepcopy(vnfd_wthout_persistent_storage)
4568 target_vdu = deepcopy(target_vdu_wthout_persistent_storage)
4569 mock_select_persistent_root_disk.return_value = None
4570 persistent_root_disk = {}
4571 disk_list = []
4572 self.ns._add_persistent_root_disk_to_disk_list(
4573 vnfd, target_vdu, persistent_root_disk, disk_list
4574 )
4575 self.assertEqual(disk_list, [])
4576 self.assertEqual(mock_select_persistent_root_disk.call_count, 2)
4577
4578 def test_prepare_vdu_affinity_group_list_invalid_extra_dict(self):
4579 """Invalid extra dict."""
4580 target_vdu = deepcopy(target_vdu_wth_persistent_storage)
4581 target_vdu["affinity-or-anti-affinity-group-id"] = "sample_affinity-group-id"
4582 extra_dict = {}
4583 ns_preffix = "nsrs:th47f48-9870-4169-b758-9732e1ff40f3"
4584 with self.assertRaises(NsException) as err:
4585 self.ns._prepare_vdu_affinity_group_list(target_vdu, extra_dict, ns_preffix)
4586 self.assertEqual(str(err.exception), "Invalid extra_dict format.")
4587
4588 def test_prepare_vdu_affinity_group_list_one_affinity_group(self):
4589 """There is one affinity-group."""
4590 target_vdu = deepcopy(target_vdu_wth_persistent_storage)
4591 target_vdu["affinity-or-anti-affinity-group-id"] = ["sample_affinity-group-id"]
4592 extra_dict = {"depends_on": []}
4593 ns_preffix = "nsrs:th47f48-9870-4169-b758-9732e1ff40f3"
4594 affinity_group_txt = "nsrs:th47f48-9870-4169-b758-9732e1ff40f3:affinity-or-anti-affinity-group.sample_affinity-group-id"
4595 expected_result = [{"affinity_group_id": "TASK-" + affinity_group_txt}]
4596 expected_extra_dict = {"depends_on": [affinity_group_txt]}
4597 result = self.ns._prepare_vdu_affinity_group_list(
4598 target_vdu, extra_dict, ns_preffix
4599 )
4600 self.assertDictEqual(extra_dict, expected_extra_dict)
4601 self.assertEqual(result, expected_result)
4602
4603 def test_prepare_vdu_affinity_group_list_several_affinity_groups(self):
4604 """There are two affinity-groups."""
4605 target_vdu = deepcopy(target_vdu_wth_persistent_storage)
4606 target_vdu["affinity-or-anti-affinity-group-id"] = [
4607 "affinity-group-id1",
4608 "affinity-group-id2",
4609 ]
4610 extra_dict = {"depends_on": []}
4611 ns_preffix = "nsrs:th47f48-9870-4169-b758-9732e1ff40f3"
4612 affinity_group_txt1 = "nsrs:th47f48-9870-4169-b758-9732e1ff40f3:affinity-or-anti-affinity-group.affinity-group-id1"
4613 affinity_group_txt2 = "nsrs:th47f48-9870-4169-b758-9732e1ff40f3:affinity-or-anti-affinity-group.affinity-group-id2"
4614 expected_result = [
4615 {"affinity_group_id": "TASK-" + affinity_group_txt1},
4616 {"affinity_group_id": "TASK-" + affinity_group_txt2},
4617 ]
4618 expected_extra_dict = {"depends_on": [affinity_group_txt1, affinity_group_txt2]}
4619 result = self.ns._prepare_vdu_affinity_group_list(
4620 target_vdu, extra_dict, ns_preffix
4621 )
4622 self.assertDictEqual(extra_dict, expected_extra_dict)
4623 self.assertEqual(result, expected_result)
4624
4625 def test_prepare_vdu_affinity_group_list_no_affinity_group(self):
4626 """There is not any affinity-group."""
4627 target_vdu = deepcopy(target_vdu_wth_persistent_storage)
4628 extra_dict = {"depends_on": []}
4629 ns_preffix = "nsrs:th47f48-9870-4169-b758-9732e1ff40f3"
4630 result = self.ns._prepare_vdu_affinity_group_list(
4631 target_vdu, extra_dict, ns_preffix
4632 )
4633 self.assertDictEqual(extra_dict, {"depends_on": []})
4634 self.assertEqual(result, [])
4635
4636 @patch("osm_ng_ro.ns.Ns._sort_vdu_interfaces")
4637 @patch("osm_ng_ro.ns.Ns._partially_locate_vdu_interfaces")
4638 @patch("osm_ng_ro.ns.Ns._prepare_vdu_interfaces")
4639 @patch("osm_ng_ro.ns.Ns._prepare_vdu_cloud_init")
4640 @patch("osm_ng_ro.ns.Ns._prepare_vdu_ssh_keys")
4641 @patch("osm_ng_ro.ns.Ns.find_persistent_root_volumes")
4642 @patch("osm_ng_ro.ns.Ns.find_persistent_volumes")
4643 @patch("osm_ng_ro.ns.Ns._add_persistent_root_disk_to_disk_list")
4644 @patch("osm_ng_ro.ns.Ns._add_persistent_ordinary_disks_to_disk_list")
4645 @patch("osm_ng_ro.ns.Ns._prepare_vdu_affinity_group_list")
4646 def test_process_vdu_params_with_inst_vol_list(
4647 self,
4648 mock_prepare_vdu_affinity_group_list,
4649 mock_add_persistent_ordinary_disks_to_disk_list,
4650 mock_add_persistent_root_disk_to_disk_list,
4651 mock_find_persistent_volumes,
4652 mock_find_persistent_root_volumes,
4653 mock_prepare_vdu_ssh_keys,
4654 mock_prepare_vdu_cloud_init,
4655 mock_prepare_vdu_interfaces,
4656 mock_locate_vdu_interfaces,
4657 mock_sort_vdu_interfaces,
4658 ):
4659 """Instantiation volume list is empty."""
4660 target_vdu = deepcopy(target_vdu_wth_persistent_storage)
4661
4662 target_vdu["interfaces"] = interfaces_wth_all_positions
4663
4664 vdu_instantiation_vol_list = [
4665 {
4666 "vim-volume-id": vim_volume_id,
4667 "name": "persistent-volume2",
4668 }
4669 ]
4670 target_vdu["additionalParams"] = {
4671 "OSM": {"vdu_volumes": vdu_instantiation_vol_list}
4672 }
4673 mock_prepare_vdu_cloud_init.return_value = {}
4674 mock_prepare_vdu_affinity_group_list.return_value = []
4675 persistent_root_disk = {
4676 "persistent-root-volume": {
4677 "image_id": "ubuntu20.04",
4678 "size": "10",
4679 }
4680 }
4681 mock_find_persistent_root_volumes.return_value = persistent_root_disk
4682
4683 new_kwargs = deepcopy(kwargs)
4684 new_kwargs.update(
4685 {
4686 "vnfr_id": vnfr_id,
4687 "nsr_id": nsr_id,
4688 "tasks_by_target_record_id": {},
4689 "logger": "logger",
4690 }
4691 )
4692 expected_extra_dict_copy = deepcopy(expected_extra_dict)
4693 vnfd = deepcopy(vnfd_wth_persistent_storage)
4694 db.get_one.return_value = vnfd
4695 result = Ns._process_vdu_params(
4696 target_vdu, indata, vim_info=None, target_record_id=None, **new_kwargs
4697 )
4698 mock_sort_vdu_interfaces.assert_called_once_with(target_vdu)
4699 mock_locate_vdu_interfaces.assert_not_called()
4700 mock_prepare_vdu_cloud_init.assert_called_once()
4701 mock_add_persistent_root_disk_to_disk_list.assert_not_called()
4702 mock_add_persistent_ordinary_disks_to_disk_list.assert_not_called()
4703 mock_prepare_vdu_interfaces.assert_called_once_with(
4704 target_vdu,
4705 expected_extra_dict_copy,
4706 ns_preffix,
4707 vnf_preffix,
4708 "logger",
4709 {},
4710 [],
4711 )
4712 self.assertDictEqual(result, expected_extra_dict_copy)
4713 mock_prepare_vdu_ssh_keys.assert_called_once_with(target_vdu, None, {})
4714 mock_prepare_vdu_affinity_group_list.assert_called_once()
4715 mock_find_persistent_volumes.assert_called_once_with(
4716 persistent_root_disk, target_vdu, vdu_instantiation_vol_list, []
4717 )
4718
4719 @patch("osm_ng_ro.ns.Ns._sort_vdu_interfaces")
4720 @patch("osm_ng_ro.ns.Ns._partially_locate_vdu_interfaces")
4721 @patch("osm_ng_ro.ns.Ns._prepare_vdu_interfaces")
4722 @patch("osm_ng_ro.ns.Ns._prepare_vdu_cloud_init")
4723 @patch("osm_ng_ro.ns.Ns._prepare_vdu_ssh_keys")
4724 @patch("osm_ng_ro.ns.Ns.find_persistent_root_volumes")
4725 @patch("osm_ng_ro.ns.Ns.find_persistent_volumes")
4726 @patch("osm_ng_ro.ns.Ns._add_persistent_root_disk_to_disk_list")
4727 @patch("osm_ng_ro.ns.Ns._add_persistent_ordinary_disks_to_disk_list")
4728 @patch("osm_ng_ro.ns.Ns._prepare_vdu_affinity_group_list")
4729 def test_process_vdu_params_wth_affinity_groups(
4730 self,
4731 mock_prepare_vdu_affinity_group_list,
4732 mock_add_persistent_ordinary_disks_to_disk_list,
4733 mock_add_persistent_root_disk_to_disk_list,
4734 mock_find_persistent_volumes,
4735 mock_find_persistent_root_volumes,
4736 mock_prepare_vdu_ssh_keys,
4737 mock_prepare_vdu_cloud_init,
4738 mock_prepare_vdu_interfaces,
4739 mock_locate_vdu_interfaces,
4740 mock_sort_vdu_interfaces,
4741 ):
4742 """There is cloud-config."""
4743 target_vdu = deepcopy(target_vdu_wthout_persistent_storage)
4744
4745 self.maxDiff = None
4746 target_vdu["interfaces"] = interfaces_wth_all_positions
4747 mock_prepare_vdu_cloud_init.return_value = {}
4748 mock_prepare_vdu_affinity_group_list.return_value = [
4749 "affinity_group_1",
4750 "affinity_group_2",
4751 ]
4752
4753 new_kwargs = deepcopy(kwargs)
4754 new_kwargs.update(
4755 {
4756 "vnfr_id": vnfr_id,
4757 "nsr_id": nsr_id,
4758 "tasks_by_target_record_id": {},
4759 "logger": "logger",
4760 }
4761 )
4762 expected_extra_dict3 = deepcopy(expected_extra_dict2)
4763 expected_extra_dict3["params"]["affinity_group_list"] = [
4764 "affinity_group_1",
4765 "affinity_group_2",
4766 ]
4767 vnfd = deepcopy(vnfd_wth_persistent_storage)
4768 db.get_one.return_value = vnfd
4769 result = Ns._process_vdu_params(
4770 target_vdu, indata, vim_info=None, target_record_id=None, **new_kwargs
4771 )
4772 self.assertDictEqual(result, expected_extra_dict3)
4773 mock_sort_vdu_interfaces.assert_called_once_with(target_vdu)
4774 mock_locate_vdu_interfaces.assert_not_called()
4775 mock_prepare_vdu_cloud_init.assert_called_once()
4776 mock_add_persistent_root_disk_to_disk_list.assert_called_once()
4777 mock_add_persistent_ordinary_disks_to_disk_list.assert_called_once()
4778 mock_prepare_vdu_interfaces.assert_called_once_with(
4779 target_vdu,
4780 expected_extra_dict3,
4781 ns_preffix,
4782 vnf_preffix,
4783 "logger",
4784 {},
4785 [],
4786 )
4787
4788 mock_prepare_vdu_ssh_keys.assert_called_once_with(target_vdu, None, {})
4789 mock_prepare_vdu_affinity_group_list.assert_called_once()
4790 mock_find_persistent_volumes.assert_not_called()
4791
4792 @patch("osm_ng_ro.ns.Ns._sort_vdu_interfaces")
4793 @patch("osm_ng_ro.ns.Ns._partially_locate_vdu_interfaces")
4794 @patch("osm_ng_ro.ns.Ns._prepare_vdu_interfaces")
4795 @patch("osm_ng_ro.ns.Ns._prepare_vdu_cloud_init")
4796 @patch("osm_ng_ro.ns.Ns._prepare_vdu_ssh_keys")
4797 @patch("osm_ng_ro.ns.Ns.find_persistent_root_volumes")
4798 @patch("osm_ng_ro.ns.Ns.find_persistent_volumes")
4799 @patch("osm_ng_ro.ns.Ns._add_persistent_root_disk_to_disk_list")
4800 @patch("osm_ng_ro.ns.Ns._add_persistent_ordinary_disks_to_disk_list")
4801 @patch("osm_ng_ro.ns.Ns._prepare_vdu_affinity_group_list")
4802 def test_process_vdu_params_wth_cloud_config(
4803 self,
4804 mock_prepare_vdu_affinity_group_list,
4805 mock_add_persistent_ordinary_disks_to_disk_list,
4806 mock_add_persistent_root_disk_to_disk_list,
4807 mock_find_persistent_volumes,
4808 mock_find_persistent_root_volumes,
4809 mock_prepare_vdu_ssh_keys,
4810 mock_prepare_vdu_cloud_init,
4811 mock_prepare_vdu_interfaces,
4812 mock_locate_vdu_interfaces,
4813 mock_sort_vdu_interfaces,
4814 ):
4815 """There is cloud-config."""
4816 target_vdu = deepcopy(target_vdu_wthout_persistent_storage)
4817
4818 self.maxDiff = None
4819 target_vdu["interfaces"] = interfaces_wth_all_positions
4820 mock_prepare_vdu_cloud_init.return_value = {
4821 "user-data": user_data,
4822 "boot-data-drive": "vda",
4823 }
4824 mock_prepare_vdu_affinity_group_list.return_value = []
4825
4826 new_kwargs = deepcopy(kwargs)
4827 new_kwargs.update(
4828 {
4829 "vnfr_id": vnfr_id,
4830 "nsr_id": nsr_id,
4831 "tasks_by_target_record_id": {},
4832 "logger": "logger",
4833 }
4834 )
4835 expected_extra_dict3 = deepcopy(expected_extra_dict2)
4836 expected_extra_dict3["params"]["cloud_config"] = {
4837 "user-data": user_data,
4838 "boot-data-drive": "vda",
4839 }
4840 vnfd = deepcopy(vnfd_wth_persistent_storage)
4841 db.get_one.return_value = vnfd
4842 result = Ns._process_vdu_params(
4843 target_vdu, indata, vim_info=None, target_record_id=None, **new_kwargs
4844 )
4845 mock_sort_vdu_interfaces.assert_called_once_with(target_vdu)
4846 mock_locate_vdu_interfaces.assert_not_called()
4847 mock_prepare_vdu_cloud_init.assert_called_once()
4848 mock_add_persistent_root_disk_to_disk_list.assert_called_once()
4849 mock_add_persistent_ordinary_disks_to_disk_list.assert_called_once()
4850 mock_prepare_vdu_interfaces.assert_called_once_with(
4851 target_vdu,
4852 expected_extra_dict3,
4853 ns_preffix,
4854 vnf_preffix,
4855 "logger",
4856 {},
4857 [],
4858 )
4859 self.assertDictEqual(result, expected_extra_dict3)
4860 mock_prepare_vdu_ssh_keys.assert_called_once_with(
4861 target_vdu, None, {"user-data": user_data, "boot-data-drive": "vda"}
4862 )
4863 mock_prepare_vdu_affinity_group_list.assert_called_once()
4864 mock_find_persistent_volumes.assert_not_called()
4865
4866 @patch("osm_ng_ro.ns.Ns._sort_vdu_interfaces")
4867 @patch("osm_ng_ro.ns.Ns._partially_locate_vdu_interfaces")
4868 @patch("osm_ng_ro.ns.Ns._prepare_vdu_interfaces")
4869 @patch("osm_ng_ro.ns.Ns._prepare_vdu_cloud_init")
4870 @patch("osm_ng_ro.ns.Ns._prepare_vdu_ssh_keys")
4871 @patch("osm_ng_ro.ns.Ns.find_persistent_root_volumes")
4872 @patch("osm_ng_ro.ns.Ns.find_persistent_volumes")
4873 @patch("osm_ng_ro.ns.Ns._add_persistent_root_disk_to_disk_list")
4874 @patch("osm_ng_ro.ns.Ns._add_persistent_ordinary_disks_to_disk_list")
4875 @patch("osm_ng_ro.ns.Ns._prepare_vdu_affinity_group_list")
4876 def test_process_vdu_params_wthout_persistent_storage(
4877 self,
4878 mock_prepare_vdu_affinity_group_list,
4879 mock_add_persistent_ordinary_disks_to_disk_list,
4880 mock_add_persistent_root_disk_to_disk_list,
4881 mock_find_persistent_volumes,
4882 mock_find_persistent_root_volumes,
4883 mock_prepare_vdu_ssh_keys,
4884 mock_prepare_vdu_cloud_init,
4885 mock_prepare_vdu_interfaces,
4886 mock_locate_vdu_interfaces,
4887 mock_sort_vdu_interfaces,
4888 ):
4889 """There is not any persistent storage."""
4890 target_vdu = deepcopy(target_vdu_wthout_persistent_storage)
4891
4892 self.maxDiff = None
4893 target_vdu["interfaces"] = interfaces_wth_all_positions
4894 mock_prepare_vdu_cloud_init.return_value = {}
4895 mock_prepare_vdu_affinity_group_list.return_value = []
4896
4897 new_kwargs = deepcopy(kwargs)
4898 new_kwargs.update(
4899 {
4900 "vnfr_id": vnfr_id,
4901 "nsr_id": nsr_id,
4902 "tasks_by_target_record_id": {},
4903 "logger": "logger",
4904 }
4905 )
4906 expected_extra_dict_copy = deepcopy(expected_extra_dict2)
4907 vnfd = deepcopy(vnfd_wthout_persistent_storage)
4908 db.get_one.return_value = vnfd
4909 result = Ns._process_vdu_params(
4910 target_vdu, indata, vim_info=None, target_record_id=None, **new_kwargs
4911 )
4912 mock_sort_vdu_interfaces.assert_called_once_with(target_vdu)
4913 mock_locate_vdu_interfaces.assert_not_called()
4914 mock_prepare_vdu_cloud_init.assert_called_once()
4915 mock_add_persistent_root_disk_to_disk_list.assert_called_once()
4916 mock_add_persistent_ordinary_disks_to_disk_list.assert_called_once()
4917 mock_prepare_vdu_interfaces.assert_called_once_with(
4918 target_vdu,
4919 expected_extra_dict_copy,
4920 ns_preffix,
4921 vnf_preffix,
4922 "logger",
4923 {},
4924 [],
4925 )
4926 self.assertDictEqual(result, expected_extra_dict_copy)
4927 mock_prepare_vdu_ssh_keys.assert_called_once_with(target_vdu, None, {})
4928 mock_prepare_vdu_affinity_group_list.assert_called_once()
4929 mock_find_persistent_volumes.assert_not_called()
4930
4931 @patch("osm_ng_ro.ns.Ns._sort_vdu_interfaces")
4932 @patch("osm_ng_ro.ns.Ns._partially_locate_vdu_interfaces")
4933 @patch("osm_ng_ro.ns.Ns._prepare_vdu_interfaces")
4934 @patch("osm_ng_ro.ns.Ns._prepare_vdu_cloud_init")
4935 @patch("osm_ng_ro.ns.Ns._prepare_vdu_ssh_keys")
4936 @patch("osm_ng_ro.ns.Ns.find_persistent_root_volumes")
4937 @patch("osm_ng_ro.ns.Ns.find_persistent_volumes")
4938 @patch("osm_ng_ro.ns.Ns._add_persistent_root_disk_to_disk_list")
4939 @patch("osm_ng_ro.ns.Ns._add_persistent_ordinary_disks_to_disk_list")
4940 @patch("osm_ng_ro.ns.Ns._prepare_vdu_affinity_group_list")
4941 def test_process_vdu_params_interfaces_partially_located(
4942 self,
4943 mock_prepare_vdu_affinity_group_list,
4944 mock_add_persistent_ordinary_disks_to_disk_list,
4945 mock_add_persistent_root_disk_to_disk_list,
4946 mock_find_persistent_volumes,
4947 mock_find_persistent_root_volumes,
4948 mock_prepare_vdu_ssh_keys,
4949 mock_prepare_vdu_cloud_init,
4950 mock_prepare_vdu_interfaces,
4951 mock_locate_vdu_interfaces,
4952 mock_sort_vdu_interfaces,
4953 ):
4954 """Some interfaces have position."""
4955 target_vdu = deepcopy(target_vdu_wth_persistent_storage)
4956
4957 self.maxDiff = None
4958 target_vdu["interfaces"] = [
4959 {
4960 "name": "vdu-eth1",
4961 "ns-vld-id": "net1",
4962 },
4963 {"name": "vdu-eth2", "ns-vld-id": "net2", "position": 2},
4964 {
4965 "name": "vdu-eth3",
4966 "ns-vld-id": "mgmtnet",
4967 },
4968 ]
4969 mock_prepare_vdu_cloud_init.return_value = {}
4970 mock_prepare_vdu_affinity_group_list.return_value = []
4971 persistent_root_disk = {
4972 "persistent-root-volume": {
4973 "image_id": "ubuntu20.04",
4974 "size": "10",
4975 }
4976 }
4977 mock_find_persistent_root_volumes.return_value = persistent_root_disk
4978
4979 new_kwargs = deepcopy(kwargs)
4980 new_kwargs.update(
4981 {
4982 "vnfr_id": vnfr_id,
4983 "nsr_id": nsr_id,
4984 "tasks_by_target_record_id": {},
4985 "logger": "logger",
4986 }
4987 )
4988
4989 vnfd = deepcopy(vnfd_wth_persistent_storage)
4990 db.get_one.return_value = vnfd
4991 result = Ns._process_vdu_params(
4992 target_vdu, indata, vim_info=None, target_record_id=None, **new_kwargs
4993 )
4994 expected_extra_dict_copy = deepcopy(expected_extra_dict)
4995 mock_sort_vdu_interfaces.assert_not_called()
4996 mock_locate_vdu_interfaces.assert_called_once_with(target_vdu)
4997 mock_prepare_vdu_cloud_init.assert_called_once()
4998 mock_add_persistent_root_disk_to_disk_list.assert_called_once()
4999 mock_add_persistent_ordinary_disks_to_disk_list.assert_called_once()
5000 mock_prepare_vdu_interfaces.assert_called_once_with(
5001 target_vdu,
5002 expected_extra_dict_copy,
5003 ns_preffix,
5004 vnf_preffix,
5005 "logger",
5006 {},
5007 [],
5008 )
5009 self.assertDictEqual(result, expected_extra_dict_copy)
5010 mock_prepare_vdu_ssh_keys.assert_called_once_with(target_vdu, None, {})
5011 mock_prepare_vdu_affinity_group_list.assert_called_once()
5012 mock_find_persistent_volumes.assert_not_called()
5013 mock_find_persistent_root_volumes.assert_not_called()
5014
5015 @patch("osm_ng_ro.ns.Ns._sort_vdu_interfaces")
5016 @patch("osm_ng_ro.ns.Ns._partially_locate_vdu_interfaces")
5017 @patch("osm_ng_ro.ns.Ns._prepare_vdu_interfaces")
5018 @patch("osm_ng_ro.ns.Ns._prepare_vdu_cloud_init")
5019 @patch("osm_ng_ro.ns.Ns._prepare_vdu_ssh_keys")
5020 @patch("osm_ng_ro.ns.Ns.find_persistent_root_volumes")
5021 @patch("osm_ng_ro.ns.Ns.find_persistent_volumes")
5022 @patch("osm_ng_ro.ns.Ns._add_persistent_root_disk_to_disk_list")
5023 @patch("osm_ng_ro.ns.Ns._add_persistent_ordinary_disks_to_disk_list")
5024 @patch("osm_ng_ro.ns.Ns._prepare_vdu_affinity_group_list")
5025 def test_process_vdu_params_no_interface_position(
5026 self,
5027 mock_prepare_vdu_affinity_group_list,
5028 mock_add_persistent_ordinary_disks_to_disk_list,
5029 mock_add_persistent_root_disk_to_disk_list,
5030 mock_find_persistent_volumes,
5031 mock_find_persistent_root_volumes,
5032 mock_prepare_vdu_ssh_keys,
5033 mock_prepare_vdu_cloud_init,
5034 mock_prepare_vdu_interfaces,
5035 mock_locate_vdu_interfaces,
5036 mock_sort_vdu_interfaces,
5037 ):
5038 """Interfaces do not have position."""
5039 target_vdu = deepcopy(target_vdu_wth_persistent_storage)
5040
5041 self.maxDiff = None
5042 target_vdu["interfaces"] = interfaces_wthout_positions
5043 mock_prepare_vdu_cloud_init.return_value = {}
5044 mock_prepare_vdu_affinity_group_list.return_value = []
5045 persistent_root_disk = {
5046 "persistent-root-volume": {
5047 "image_id": "ubuntu20.04",
5048 "size": "10",
5049 }
5050 }
5051 mock_find_persistent_root_volumes.return_value = persistent_root_disk
5052 new_kwargs = deepcopy(kwargs)
5053 new_kwargs.update(
5054 {
5055 "vnfr_id": vnfr_id,
5056 "nsr_id": nsr_id,
5057 "tasks_by_target_record_id": {},
5058 "logger": "logger",
5059 }
5060 )
5061
5062 vnfd = deepcopy(vnfd_wth_persistent_storage)
5063 db.get_one.return_value = vnfd
5064 result = Ns._process_vdu_params(
5065 target_vdu, indata, vim_info=None, target_record_id=None, **new_kwargs
5066 )
5067 expected_extra_dict_copy = deepcopy(expected_extra_dict)
5068 mock_sort_vdu_interfaces.assert_not_called()
5069 mock_locate_vdu_interfaces.assert_called_once_with(target_vdu)
5070 mock_prepare_vdu_cloud_init.assert_called_once()
5071 mock_add_persistent_root_disk_to_disk_list.assert_called_once()
5072 mock_add_persistent_ordinary_disks_to_disk_list.assert_called_once()
5073 mock_prepare_vdu_interfaces.assert_called_once_with(
5074 target_vdu,
5075 expected_extra_dict_copy,
5076 ns_preffix,
5077 vnf_preffix,
5078 "logger",
5079 {},
5080 [],
5081 )
5082 self.assertDictEqual(result, expected_extra_dict_copy)
5083 mock_prepare_vdu_ssh_keys.assert_called_once_with(target_vdu, None, {})
5084 mock_prepare_vdu_affinity_group_list.assert_called_once()
5085 mock_find_persistent_volumes.assert_not_called()
5086 mock_find_persistent_root_volumes.assert_not_called()
5087
5088 @patch("osm_ng_ro.ns.Ns._sort_vdu_interfaces")
5089 @patch("osm_ng_ro.ns.Ns._partially_locate_vdu_interfaces")
5090 @patch("osm_ng_ro.ns.Ns._prepare_vdu_interfaces")
5091 @patch("osm_ng_ro.ns.Ns._prepare_vdu_cloud_init")
5092 @patch("osm_ng_ro.ns.Ns._prepare_vdu_ssh_keys")
5093 @patch("osm_ng_ro.ns.Ns.find_persistent_root_volumes")
5094 @patch("osm_ng_ro.ns.Ns.find_persistent_volumes")
5095 @patch("osm_ng_ro.ns.Ns._add_persistent_root_disk_to_disk_list")
5096 @patch("osm_ng_ro.ns.Ns._add_persistent_ordinary_disks_to_disk_list")
5097 @patch("osm_ng_ro.ns.Ns._prepare_vdu_affinity_group_list")
5098 def test_process_vdu_params_prepare_vdu_interfaces_raises_exception(
5099 self,
5100 mock_prepare_vdu_affinity_group_list,
5101 mock_add_persistent_ordinary_disks_to_disk_list,
5102 mock_add_persistent_root_disk_to_disk_list,
5103 mock_find_persistent_volumes,
5104 mock_find_persistent_root_volumes,
5105 mock_prepare_vdu_ssh_keys,
5106 mock_prepare_vdu_cloud_init,
5107 mock_prepare_vdu_interfaces,
5108 mock_locate_vdu_interfaces,
5109 mock_sort_vdu_interfaces,
5110 ):
5111 """Prepare vdu interfaces method raises exception."""
5112 target_vdu = deepcopy(target_vdu_wth_persistent_storage)
5113
5114 self.maxDiff = None
5115 target_vdu["interfaces"] = interfaces_wthout_positions
5116 mock_prepare_vdu_cloud_init.return_value = {}
5117 mock_prepare_vdu_affinity_group_list.return_value = []
5118 persistent_root_disk = {
5119 "persistent-root-volume": {
5120 "image_id": "ubuntu20.04",
5121 "size": "10",
5122 }
5123 }
5124 mock_find_persistent_root_volumes.return_value = persistent_root_disk
5125 new_kwargs = deepcopy(kwargs)
5126 new_kwargs.update(
5127 {
5128 "vnfr_id": vnfr_id,
5129 "nsr_id": nsr_id,
5130 "tasks_by_target_record_id": {},
5131 "logger": "logger",
5132 }
5133 )
5134 mock_prepare_vdu_interfaces.side_effect = TypeError
5135
5136 vnfd = deepcopy(vnfd_wth_persistent_storage)
5137 db.get_one.return_value = vnfd
5138 with self.assertRaises(Exception) as err:
5139 Ns._process_vdu_params(
5140 target_vdu, indata, vim_info=None, target_record_id=None, **new_kwargs
5141 )
5142 self.assertEqual(type(err), TypeError)
5143 mock_sort_vdu_interfaces.assert_not_called()
5144 mock_locate_vdu_interfaces.assert_called_once_with(target_vdu)
5145 mock_prepare_vdu_cloud_init.assert_not_called()
5146 mock_add_persistent_root_disk_to_disk_list.assert_not_called()
5147 mock_add_persistent_ordinary_disks_to_disk_list.assert_not_called()
5148 mock_prepare_vdu_interfaces.assert_called_once()
5149 mock_prepare_vdu_ssh_keys.assert_not_called()
5150 mock_prepare_vdu_affinity_group_list.assert_not_called()
5151 mock_find_persistent_volumes.assert_not_called()
5152 mock_find_persistent_root_volumes.assert_not_called()
5153
5154 @patch("osm_ng_ro.ns.Ns._sort_vdu_interfaces")
5155 @patch("osm_ng_ro.ns.Ns._partially_locate_vdu_interfaces")
5156 @patch("osm_ng_ro.ns.Ns._prepare_vdu_interfaces")
5157 @patch("osm_ng_ro.ns.Ns._prepare_vdu_cloud_init")
5158 @patch("osm_ng_ro.ns.Ns._prepare_vdu_ssh_keys")
5159 @patch("osm_ng_ro.ns.Ns.find_persistent_root_volumes")
5160 @patch("osm_ng_ro.ns.Ns.find_persistent_volumes")
5161 @patch("osm_ng_ro.ns.Ns._add_persistent_root_disk_to_disk_list")
5162 @patch("osm_ng_ro.ns.Ns._add_persistent_ordinary_disks_to_disk_list")
5163 @patch("osm_ng_ro.ns.Ns._prepare_vdu_affinity_group_list")
5164 def test_process_vdu_params_add_persistent_root_disk_raises_exception(
5165 self,
5166 mock_prepare_vdu_affinity_group_list,
5167 mock_add_persistent_ordinary_disks_to_disk_list,
5168 mock_add_persistent_root_disk_to_disk_list,
5169 mock_find_persistent_volumes,
5170 mock_find_persistent_root_volumes,
5171 mock_prepare_vdu_ssh_keys,
5172 mock_prepare_vdu_cloud_init,
5173 mock_prepare_vdu_interfaces,
5174 mock_locate_vdu_interfaces,
5175 mock_sort_vdu_interfaces,
5176 ):
5177 """Add persistent root disk method raises exception."""
5178 target_vdu = deepcopy(target_vdu_wth_persistent_storage)
5179
5180 self.maxDiff = None
5181 target_vdu["interfaces"] = interfaces_wthout_positions
5182 mock_prepare_vdu_cloud_init.return_value = {}
5183 mock_prepare_vdu_affinity_group_list.return_value = []
5184 mock_add_persistent_root_disk_to_disk_list.side_effect = KeyError
5185 new_kwargs = deepcopy(kwargs)
5186 new_kwargs.update(
5187 {
5188 "vnfr_id": vnfr_id,
5189 "nsr_id": nsr_id,
5190 "tasks_by_target_record_id": {},
5191 "logger": "logger",
5192 }
5193 )
5194
5195 vnfd = deepcopy(vnfd_wth_persistent_storage)
5196 db.get_one.return_value = vnfd
5197 with self.assertRaises(Exception) as err:
5198 Ns._process_vdu_params(
5199 target_vdu, indata, vim_info=None, target_record_id=None, **new_kwargs
5200 )
5201 self.assertEqual(type(err), KeyError)
5202 mock_sort_vdu_interfaces.assert_not_called()
5203 mock_locate_vdu_interfaces.assert_called_once_with(target_vdu)
5204 mock_prepare_vdu_cloud_init.assert_called_once()
5205 mock_add_persistent_root_disk_to_disk_list.assert_called_once()
5206 mock_add_persistent_ordinary_disks_to_disk_list.assert_not_called()
5207 mock_prepare_vdu_interfaces.assert_called_once_with(
5208 target_vdu,
5209 {
5210 "depends_on": [
5211 f"{ns_preffix}:image.0",
5212 f"{ns_preffix}:flavor.0",
5213 ]
5214 },
5215 ns_preffix,
5216 vnf_preffix,
5217 "logger",
5218 {},
5219 [],
5220 )
5221
5222 mock_prepare_vdu_ssh_keys.assert_called_once_with(target_vdu, None, {})
5223 mock_prepare_vdu_affinity_group_list.assert_not_called()
5224 mock_find_persistent_volumes.assert_not_called()
5225 mock_find_persistent_root_volumes.assert_not_called()
5226
5227 def test_select_persistent_root_disk(self):
5228 vdu = deepcopy(target_vdu_wth_persistent_storage)
5229 vdu["virtual-storage-desc"] = [
5230 "persistent-root-volume",
5231 "persistent-volume2",
5232 "ephemeral-volume",
5233 ]
5234 vsd = deepcopy(vnfd_wth_persistent_storage)["virtual-storage-desc"][1]
5235 expected_result = vsd
5236 result = Ns._select_persistent_root_disk(vsd, vdu)
5237 self.assertEqual(result, expected_result)
5238
5239 def test_select_persistent_root_disk_first_vsd_is_different(self):
5240 """VDU first virtual-storage-desc is different than vsd id."""
5241 vdu = deepcopy(target_vdu_wth_persistent_storage)
5242 vdu["virtual-storage-desc"] = [
5243 "persistent-volume2",
5244 "persistent-root-volume",
5245 "ephemeral-volume",
5246 ]
5247 vsd = deepcopy(vnfd_wth_persistent_storage)["virtual-storage-desc"][1]
5248 expected_result = None
5249 result = Ns._select_persistent_root_disk(vsd, vdu)
5250 self.assertEqual(result, expected_result)
5251
5252 def test_select_persistent_root_disk_vsd_is_not_persistent(self):
5253 """vsd type is not persistent."""
5254 vdu = deepcopy(target_vdu_wth_persistent_storage)
5255 vdu["virtual-storage-desc"] = [
5256 "persistent-volume2",
5257 "persistent-root-volume",
5258 "ephemeral-volume",
5259 ]
5260 vsd = deepcopy(vnfd_wth_persistent_storage)["virtual-storage-desc"][1]
5261 vsd["type-of-storage"] = "etsi-nfv-descriptors:ephemeral-storage"
5262 expected_result = None
5263 result = Ns._select_persistent_root_disk(vsd, vdu)
5264 self.assertEqual(result, expected_result)
5265
5266 def test_select_persistent_root_disk_vsd_does_not_have_size(self):
5267 """vsd size is None."""
5268 vdu = deepcopy(target_vdu_wth_persistent_storage)
5269 vdu["virtual-storage-desc"] = [
5270 "persistent-volume2",
5271 "persistent-root-volume",
5272 "ephemeral-volume",
5273 ]
5274 vsd = deepcopy(vnfd_wth_persistent_storage)["virtual-storage-desc"][1]
5275 vsd["size-of-storage"] = None
5276 expected_result = None
5277 result = Ns._select_persistent_root_disk(vsd, vdu)
5278 self.assertEqual(result, expected_result)
5279
5280 def test_select_persistent_root_disk_vdu_wthout_vsd(self):
5281 """VDU does not have virtual-storage-desc."""
5282 vdu = deepcopy(target_vdu_wth_persistent_storage)
5283 vsd = deepcopy(vnfd_wth_persistent_storage)["virtual-storage-desc"][1]
5284 expected_result = None
5285 result = Ns._select_persistent_root_disk(vsd, vdu)
5286 self.assertEqual(result, expected_result)
5287
5288 def test_select_persistent_root_disk_invalid_vsd_type(self):
5289 """vsd is list, expected to be a dict."""
5290 vdu = deepcopy(target_vdu_wth_persistent_storage)
5291 vsd = deepcopy(vnfd_wth_persistent_storage)["virtual-storage-desc"]
5292 with self.assertRaises(AttributeError):
5293 Ns._select_persistent_root_disk(vsd, vdu)