Call VDU instantiate in parallel 36/13636/16
authorDaniel Arndt <daniel.arndt@canonical.com>
Fri, 7 Jul 2023 10:43:53 +0000 (07:43 -0300)
committerDaniel Arndt <daniel.arndt@canonical.com>
Tue, 11 Jul 2023 11:04:38 +0000 (08:04 -0300)
Change-Id: I813f57f241e0932ada2a21d64d13d096ac9ade30
Signed-off-by: Daniel Arndt <daniel.arndt@canonical.com>
osm_lcm/temporal/vnf_workflows.py
osm_lcm/tests/test_vnf_workflows.py

index 940eeb9..3da7f43 100644 (file)
@@ -89,7 +89,7 @@ class VnfInstantiateWorkflowImpl(VnfInstantiateWorkflow):
                 id=f"{VnfPrepareWorkflow.__name__}-{workflow_input.vnfr_uuid}",
             )
 
-            get_vnf_record = value_to_type(
+            get_vnf_record: GetVnfRecord.Output = value_to_type(
                 GetVnfRecord.Output,
                 await workflow.execute_activity(
                     activity=GetVnfRecord.__name__,
@@ -118,9 +118,12 @@ class VnfInstantiateWorkflowImpl(VnfInstantiateWorkflow):
                     retry_policy=retry_policy,
                 ),
             )
-            get_vnf_descriptor, get_cloud = value_to_type(
+            get_vnf_descriptor: GetVnfDescriptor.Output = value_to_type(
                 GetVnfDescriptor.Output, activities_results[0]
-            ), value_to_type(GetVimCloud.Output, activities_results[1])
+            )
+            get_cloud: GetVimCloud.Output = value_to_type(
+                GetVimCloud.Output, activities_results[1]
+            )
 
             await self.instantiate_vdus(
                 vnfr=get_vnf_record.vnfr,
@@ -264,7 +267,8 @@ class VnfInstantiateWorkflowImpl(VnfInstantiateWorkflow):
         cloud: str,
         vnf_instantiation_config: dict,
     ):
-        for vdu in vnfd.get("vdu"):
+        child_workflow_handles = []
+        for vdu in vnfd.get("vdu", []):
             (
                 vdu_instantiate_input,
                 vdu_instantiate_workflow_id,
@@ -275,12 +279,15 @@ class VnfInstantiateWorkflowImpl(VnfInstantiateWorkflow):
                 cloud=cloud,
                 vnf_instantiation_config=vnf_instantiation_config,
             )
-            await workflow.execute_child_workflow(
-                workflow=VduInstantiateWorkflow.__name__,
-                arg=vdu_instantiate_input,
-                task_queue=task_queue,
-                id=vdu_instantiate_workflow_id,
+            child_workflow_handles.append(
+                workflow.execute_child_workflow(
+                    workflow=VduInstantiateWorkflow.__name__,
+                    arg=vdu_instantiate_input,
+                    task_queue=task_queue,
+                    id=vdu_instantiate_workflow_id,
+                )
             )
+        return await asyncio.gather(*child_workflow_handles)
 
     @staticmethod
     def _get_vdu_instantiate_input(
index 45e70c9..6265e83 100644 (file)
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import asynctest
-from asynctest.mock import patch
+import uuid
 from copy import deepcopy
 from datetime import timedelta
-from unittest.mock import Mock
-import uuid
 
-from osm_common.temporal_task_queues.task_queues_mappings import LCM_TASK_QUEUE
+import asynctest
+from asynctest import CoroutineMock, Mock, patch
 from osm_common.temporal.activities.vnf import (
-    ChangeVnfState,
     ChangeVnfInstantiationState,
+    ChangeVnfState,
     GetTaskQueue,
     GetVimCloud,
     GetVnfDescriptor,
@@ -33,24 +31,25 @@ from osm_common.temporal.activities.vnf import (
     SetVnfModel,
 )
 from osm_common.temporal.dataclasses_common import CharmInfo, VduComputeConstraints
-from osm_common.temporal.workflows.vnf import VnfPrepareWorkflow
+from osm_common.temporal.states import VnfInstantiationState, VnfState
 from osm_common.temporal.workflows.vdu import VduInstantiateWorkflow
-from osm_common.temporal.states import VnfState, VnfInstantiationState
+from osm_common.temporal.workflows.vnf import VnfPrepareWorkflow
+from osm_common.temporal_task_queues.task_queues_mappings import LCM_TASK_QUEUE
+from temporalio import activity, workflow
+from temporalio.client import WorkflowFailureError
+from temporalio.exceptions import ActivityError, ChildWorkflowError, RetryState
+from temporalio.testing import WorkflowEnvironment
+from temporalio.worker import Worker
+
 from osm_lcm.temporal.vnf_workflows import (
     VnfInstantiateWorkflowImpl,
     VnfPrepareWorkflowImpl,
 )
-from temporalio import activity
-from temporalio import workflow
-from temporalio.client import WorkflowFailureError
-from temporalio.exceptions import (
-    ActivityError,
-    ChildWorkflowError,
-    RetryState,
-)
-from temporalio.testing import WorkflowEnvironment
-from temporalio.worker import Worker
 
+SANDBOXED = False
+DEBUG_MODE = True
+TASK_TIMEOUT = timedelta(seconds=5)
+EXECUTION_TIMEOUT = timedelta(seconds=10)
 
 # The variables used in the tests
 model_name = "my-model-name"
@@ -148,11 +147,6 @@ sample_vdu_instantiate_input_with_config = VduInstantiateWorkflow.Input(
     config=app_config,
 )
 
-SANDBOXED = False
-DEBUG_MODE = True
-TASK_TIMEOUT = timedelta(seconds=0.5)
-EXECUTION_TIMEOUT = timedelta(seconds=1)
-
 
 class TestException(Exception):
     pass
@@ -409,7 +403,7 @@ class TestVnfInstantiateWorkflow(asynctest.TestCase):
             execution_timeout=EXECUTION_TIMEOUT,
         )
 
-    def vnf_instantiation_state_is_updated(self, state):
+    def validate_vnf_instantiation_state_is_updated(self, state):
         call_mock_change_vnf_instantiation_state_tracker = (
             self.mock_change_vnf_instantiation_state_tracker.call_args_list
         )
@@ -486,7 +480,9 @@ class TestVnfInstantiateWorkflow(asynctest.TestCase):
             self.task_queue, workflows, activities
         ), self.get_worker(self.task_queue, workflows, activities):
             await self.execute_workflow()
-        self.vnf_instantiation_state_is_updated(VnfInstantiationState.INSTANTIATED)
+        self.validate_vnf_instantiation_state_is_updated(
+            VnfInstantiationState.INSTANTIATED
+        )
 
     @patch(
         "osm_lcm.temporal.vnf_workflows.VnfInstantiateWorkflowImpl._get_vdu_instantiate_input"
@@ -517,7 +513,49 @@ class TestVnfInstantiateWorkflow(asynctest.TestCase):
             self.task_queue, workflows, activities
         ), self.get_worker(self.task_queue, workflows, activities):
             await self.execute_workflow()
-        self.vnf_instantiation_state_is_updated(VnfState.STARTED)
+        self.validate_vnf_instantiation_state_is_updated(VnfState.STARTED)
+
+    @patch(
+        "osm_lcm.temporal.vnf_workflows.VnfInstantiateWorkflowImpl._get_vdu_instantiate_input"
+    )
+    @patch(
+        "temporalio.workflow.execute_child_workflow",
+        wraps=workflow.execute_child_workflow,
+    )
+    async def test_vnf_instantiate_workflow__successful__executes_child_workflow(
+        self,
+        mock_execute_child_workflow: CoroutineMock,
+        mock_get_vdu_instantiate_input,
+    ):
+        workflows = [
+            VnfInstantiateWorkflowImpl,
+            MockPrepareVnfWorkflow,
+            MockVduInstantiateWorkflow,
+        ]
+        activities = [
+            mock_get_task_queue,
+            self.mock_change_vnf_instantiation_state,
+            self.mock_change_vnf_state,
+            self.mock_send_notification_for_vnf,
+            mock_set_vnf_model,
+            mock_get_vnf_descriptor,
+            mock_get_vnf_record,
+            mock_get_vim_cloud,
+        ]
+        mock_get_vdu_instantiate_input.return_value = (
+            sample_vdu_instantiate_input_with_config,
+            sample_vdu_instantiate_wf_id_1,
+        )
+        async with self.env, self.get_worker(self.task_queue, workflows, activities):
+            await self.execute_workflow()
+        self.assertTrue(mock_execute_child_workflow.called)
+        self.assertEquals(mock_execute_child_workflow.call_count, 2)
+        # Check that PrepareVnfWorkflow is executed
+        call_args = mock_execute_child_workflow.call_args_list[0].kwargs["workflow"]
+        self.assertEquals(call_args, VnfPrepareWorkflow.__name__)
+        # Check that VduInstantiateWorkflow is executed
+        call_args = mock_execute_child_workflow.call_args_list[1].kwargs["workflow"]
+        self.assertEquals(call_args, VduInstantiateWorkflow.__name__)
 
     async def test_vnf_instantiate_workflow__activity_change_vnf_instantiation_state_failed__raise_activity_error(
         self,
@@ -743,7 +781,9 @@ class TestInstantiateVdus(asynctest.TestCase):
     @patch(
         "osm_lcm.temporal.vnf_workflows.VnfInstantiateWorkflowImpl._get_vdu_instantiate_input"
     )
-    @patch("temporalio.workflow.execute_child_workflow")
+    @patch(
+        "temporalio.workflow.execute_child_workflow",
+    )
     async def test_instantiate_vdus__empty_vnf_instantiation_config__child_wf_executed_with_expected_vdu_instantiate_input(
         self,
         mock_execute_child_workflow,
@@ -839,18 +879,12 @@ class TestInstantiateVdus(asynctest.TestCase):
 
 
 class TestGetVduInstantiateInfo(asynctest.TestCase):
-    @asynctest.mock.patch(
-        "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_application_config"
-    )
-    @asynctest.mock.patch(
+    @patch("osm_lcm.temporal.vnf_activities.VnfSpecifications.get_application_config")
+    @patch(
         "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_vdu_instantiation_params"
     )
-    @asynctest.mock.patch(
-        "osm_lcm.temporal.juju_paas_activities.CharmInfoUtils.get_charm_info"
-    )
-    @asynctest.mock.patch(
-        "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_compute_constraints"
-    )
+    @patch("osm_lcm.temporal.juju_paas_activities.CharmInfoUtils.get_charm_info")
+    @patch("osm_lcm.temporal.vnf_activities.VnfSpecifications.get_compute_constraints")
     async def test_get_vdu_instantiate_input__empty_vnf_instantiation_config__get_expected_vdu_inst_input_and_wf_id(
         self,
         mock_get_compute_constraints,
@@ -877,18 +911,12 @@ class TestGetVduInstantiateInfo(asynctest.TestCase):
             (sample_vdu_instantiate_input, "my-model-name-my-app"),
         )
 
-    @asynctest.mock.patch(
-        "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_application_config"
-    )
-    @asynctest.mock.patch(
+    @patch("osm_lcm.temporal.vnf_activities.VnfSpecifications.get_application_config")
+    @patch(
         "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_vdu_instantiation_params"
     )
-    @asynctest.mock.patch(
-        "osm_lcm.temporal.juju_paas_activities.CharmInfoUtils.get_charm_info"
-    )
-    @asynctest.mock.patch(
-        "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_compute_constraints"
-    )
+    @patch("osm_lcm.temporal.juju_paas_activities.CharmInfoUtils.get_charm_info")
+    @patch("osm_lcm.temporal.vnf_activities.VnfSpecifications.get_compute_constraints")
     async def test_get_vdu_instantiate_input__with_vnf_instantiation_config__get_expected_vdu_inst_input_and_wf_id(
         self,
         mock_get_compute_constraints,
@@ -915,18 +943,12 @@ class TestGetVduInstantiateInfo(asynctest.TestCase):
             (sample_vdu_instantiate_input_with_config, "my-model-name-my-app"),
         )
 
-    @asynctest.mock.patch(
-        "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_application_config"
-    )
-    @asynctest.mock.patch(
+    @patch("osm_lcm.temporal.vnf_activities.VnfSpecifications.get_application_config")
+    @patch(
         "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_vdu_instantiation_params"
     )
-    @asynctest.mock.patch(
-        "osm_lcm.temporal.juju_paas_activities.CharmInfoUtils.get_charm_info"
-    )
-    @asynctest.mock.patch(
-        "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_compute_constraints"
-    )
+    @patch("osm_lcm.temporal.juju_paas_activities.CharmInfoUtils.get_charm_info")
+    @patch("osm_lcm.temporal.vnf_activities.VnfSpecifications.get_compute_constraints")
     async def test_get_vdu_instantiate_input__vnfr_without_namespace__raise_type_error(
         self,
         mock_get_compute_constraints,
@@ -947,18 +969,12 @@ class TestGetVduInstantiateInfo(asynctest.TestCase):
                 vnf_instantiation_config={},
             )
 
-    @asynctest.mock.patch(
-        "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_application_config"
-    )
-    @asynctest.mock.patch(
+    @patch("osm_lcm.temporal.vnf_activities.VnfSpecifications.get_application_config")
+    @patch(
         "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_vdu_instantiation_params"
     )
-    @asynctest.mock.patch(
-        "osm_lcm.temporal.juju_paas_activities.CharmInfoUtils.get_charm_info"
-    )
-    @asynctest.mock.patch(
-        "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_compute_constraints"
-    )
+    @patch("osm_lcm.temporal.juju_paas_activities.CharmInfoUtils.get_charm_info")
+    @patch("osm_lcm.temporal.vnf_activities.VnfSpecifications.get_compute_constraints")
     async def test_get_vdu_instantiate_input__app_name_is_empty__expected_wf_id(
         self,
         mock_get_compute_constraints,
@@ -982,18 +998,12 @@ class TestGetVduInstantiateInfo(asynctest.TestCase):
         )
         self.assertEqual(vdu_instantiate_workflow_id, "my-model-name-")
 
-    @asynctest.mock.patch(
-        "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_application_config"
-    )
-    @asynctest.mock.patch(
+    @patch("osm_lcm.temporal.vnf_activities.VnfSpecifications.get_application_config")
+    @patch(
         "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_vdu_instantiation_params"
     )
-    @asynctest.mock.patch(
-        "osm_lcm.temporal.juju_paas_activities.CharmInfoUtils.get_charm_info"
-    )
-    @asynctest.mock.patch(
-        "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_compute_constraints"
-    )
+    @patch("osm_lcm.temporal.juju_paas_activities.CharmInfoUtils.get_charm_info")
+    @patch("osm_lcm.temporal.vnf_activities.VnfSpecifications.get_compute_constraints")
     async def test_get_vdu_instantiate_input__get_compute_constraints_failed__no_vdu_inst_wf_input_and_vdu_wf_id(
         self,
         mock_get_compute_constraints,
@@ -1020,18 +1030,12 @@ class TestGetVduInstantiateInfo(asynctest.TestCase):
                 (vdu_instantiate_input, vdu_instantiate_workflow_id), (None, None)
             )
 
-    @asynctest.mock.patch(
-        "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_application_config"
-    )
-    @asynctest.mock.patch(
+    @patch("osm_lcm.temporal.vnf_activities.VnfSpecifications.get_application_config")
+    @patch(
         "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_vdu_instantiation_params"
     )
-    @asynctest.mock.patch(
-        "osm_lcm.temporal.juju_paas_activities.CharmInfoUtils.get_charm_info"
-    )
-    @asynctest.mock.patch(
-        "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_compute_constraints"
-    )
+    @patch("osm_lcm.temporal.juju_paas_activities.CharmInfoUtils.get_charm_info")
+    @patch("osm_lcm.temporal.vnf_activities.VnfSpecifications.get_compute_constraints")
     async def test_get_vdu_instantiate_input__get_compute_constraints_failed__raise_compute_constraints_exception(
         self,
         mock_get_compute_constraints,
@@ -1052,18 +1056,12 @@ class TestGetVduInstantiateInfo(asynctest.TestCase):
                 vnf_instantiation_config={},
             )
 
-    @asynctest.mock.patch(
-        "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_application_config"
-    )
-    @asynctest.mock.patch(
+    @patch("osm_lcm.temporal.vnf_activities.VnfSpecifications.get_application_config")
+    @patch(
         "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_vdu_instantiation_params"
     )
-    @asynctest.mock.patch(
-        "osm_lcm.temporal.juju_paas_activities.CharmInfoUtils.get_charm_info"
-    )
-    @asynctest.mock.patch(
-        "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_compute_constraints"
-    )
+    @patch("osm_lcm.temporal.juju_paas_activities.CharmInfoUtils.get_charm_info")
+    @patch("osm_lcm.temporal.vnf_activities.VnfSpecifications.get_compute_constraints")
     async def test_get_vdu_instantiate_input__get_charm_info_failed__raise_get_charm_info_exception(
         self,
         mock_get_compute_constraints,
@@ -1084,18 +1082,12 @@ class TestGetVduInstantiateInfo(asynctest.TestCase):
                 vnf_instantiation_config={},
             )
 
-    @asynctest.mock.patch(
-        "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_application_config"
-    )
-    @asynctest.mock.patch(
+    @patch("osm_lcm.temporal.vnf_activities.VnfSpecifications.get_application_config")
+    @patch(
         "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_vdu_instantiation_params"
     )
-    @asynctest.mock.patch(
-        "osm_lcm.temporal.juju_paas_activities.CharmInfoUtils.get_charm_info"
-    )
-    @asynctest.mock.patch(
-        "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_compute_constraints"
-    )
+    @patch("osm_lcm.temporal.juju_paas_activities.CharmInfoUtils.get_charm_info")
+    @patch("osm_lcm.temporal.vnf_activities.VnfSpecifications.get_compute_constraints")
     async def test_get_vdu_instantiate_input__get_charm_info_failed__no_vdu_inst_wf_input_and_vdu_wf_id(
         self,
         mock_get_compute_constraints,
@@ -1122,18 +1114,12 @@ class TestGetVduInstantiateInfo(asynctest.TestCase):
                 (vdu_instantiate_input, vdu_instantiate_workflow_id), (None, None)
             )
 
-    @asynctest.mock.patch(
-        "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_application_config"
-    )
-    @asynctest.mock.patch(
+    @patch("osm_lcm.temporal.vnf_activities.VnfSpecifications.get_application_config")
+    @patch(
         "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_vdu_instantiation_params"
     )
-    @asynctest.mock.patch(
-        "osm_lcm.temporal.juju_paas_activities.CharmInfoUtils.get_charm_info"
-    )
-    @asynctest.mock.patch(
-        "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_compute_constraints"
-    )
+    @patch("osm_lcm.temporal.juju_paas_activities.CharmInfoUtils.get_charm_info")
+    @patch("osm_lcm.temporal.vnf_activities.VnfSpecifications.get_compute_constraints")
     async def test_get_vdu_instantiate_input__get_vdu_instantiation_params_failed__raise_get_vdu_instantiation_params_exception(
         self,
         mock_get_compute_constraints,
@@ -1156,18 +1142,12 @@ class TestGetVduInstantiateInfo(asynctest.TestCase):
                 vnf_instantiation_config={},
             )
 
-    @asynctest.mock.patch(
-        "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_application_config"
-    )
-    @asynctest.mock.patch(
+    @patch("osm_lcm.temporal.vnf_activities.VnfSpecifications.get_application_config")
+    @patch(
         "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_vdu_instantiation_params"
     )
-    @asynctest.mock.patch(
-        "osm_lcm.temporal.juju_paas_activities.CharmInfoUtils.get_charm_info"
-    )
-    @asynctest.mock.patch(
-        "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_compute_constraints"
-    )
+    @patch("osm_lcm.temporal.juju_paas_activities.CharmInfoUtils.get_charm_info")
+    @patch("osm_lcm.temporal.vnf_activities.VnfSpecifications.get_compute_constraints")
     async def test_get_vdu_instantiate_input__get_vdu_instantiation_params_failed__no_vdu_inst_wf_input_and_vdu_wf_id(
         self,
         mock_get_compute_constraints,
@@ -1197,18 +1177,12 @@ class TestGetVduInstantiateInfo(asynctest.TestCase):
                 (vdu_instantiate_input, vdu_instantiate_workflow_id), (None, None)
             )
 
-    @asynctest.mock.patch(
-        "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_application_config"
-    )
-    @asynctest.mock.patch(
+    @patch("osm_lcm.temporal.vnf_activities.VnfSpecifications.get_application_config")
+    @patch(
         "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_vdu_instantiation_params"
     )
-    @asynctest.mock.patch(
-        "osm_lcm.temporal.juju_paas_activities.CharmInfoUtils.get_charm_info"
-    )
-    @asynctest.mock.patch(
-        "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_compute_constraints"
-    )
+    @patch("osm_lcm.temporal.juju_paas_activities.CharmInfoUtils.get_charm_info")
+    @patch("osm_lcm.temporal.vnf_activities.VnfSpecifications.get_compute_constraints")
     async def test_get_vdu_instantiate_input__get_application_config_failed__raise_get_application_config_exception(
         self,
         mock_get_compute_constraints,
@@ -1231,18 +1205,12 @@ class TestGetVduInstantiateInfo(asynctest.TestCase):
                 vnf_instantiation_config={},
             )
 
-    @asynctest.mock.patch(
-        "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_application_config"
-    )
-    @asynctest.mock.patch(
+    @patch("osm_lcm.temporal.vnf_activities.VnfSpecifications.get_application_config")
+    @patch(
         "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_vdu_instantiation_params"
     )
-    @asynctest.mock.patch(
-        "osm_lcm.temporal.juju_paas_activities.CharmInfoUtils.get_charm_info"
-    )
-    @asynctest.mock.patch(
-        "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_compute_constraints"
-    )
+    @patch("osm_lcm.temporal.juju_paas_activities.CharmInfoUtils.get_charm_info")
+    @patch("osm_lcm.temporal.vnf_activities.VnfSpecifications.get_compute_constraints")
     async def test_get_vdu_instantiate_input__get_application_config_failed__no_vdu_inst_wf_input_and_vdu_wf_id(
         self,
         mock_get_compute_constraints,