From 9fa0435711ccac1866915d437ce6114c6d2854d8 Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Fri, 7 Jul 2023 07:43:53 -0300 Subject: [PATCH] Call VDU instantiate in parallel Change-Id: I813f57f241e0932ada2a21d64d13d096ac9ade30 Signed-off-by: Daniel Arndt --- osm_lcm/temporal/vnf_workflows.py | 25 ++- osm_lcm/tests/test_vnf_workflows.py | 262 ++++++++++++---------------- 2 files changed, 131 insertions(+), 156 deletions(-) diff --git a/osm_lcm/temporal/vnf_workflows.py b/osm_lcm/temporal/vnf_workflows.py index 940eeb9..3da7f43 100644 --- a/osm_lcm/temporal/vnf_workflows.py +++ b/osm_lcm/temporal/vnf_workflows.py @@ -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( diff --git a/osm_lcm/tests/test_vnf_workflows.py b/osm_lcm/tests/test_vnf_workflows.py index 45e70c9..6265e83 100644 --- a/osm_lcm/tests/test_vnf_workflows.py +++ b/osm_lcm/tests/test_vnf_workflows.py @@ -14,17 +14,15 @@ # 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, -- 2.25.1