From 625a654ee8e3b159df6341713de8f7e9fdbf4546 Mon Sep 17 00:00:00 2001 From: Gulsum Atici Date: Tue, 18 Apr 2023 15:27:18 +0300 Subject: [PATCH] OSMENG-1006 Implement Instantiate VNF Workflow Change-Id: I12ce8268b949e4f5e901001059a088edb230258b Signed-off-by: Gulsum Atici Signed-off-by: Mark Beierl --- osm_lcm/temporal/ns_activities.py | 4 +- osm_lcm/temporal/ns_workflows.py | 9 +- osm_lcm/temporal/vnf_activities.py | 6 +- osm_lcm/temporal/vnf_workflows.py | 20 +- osm_lcm/tests/test_vnf_workflows.py | 503 +++++++++++++++++++++++++++- 5 files changed, 507 insertions(+), 35 deletions(-) diff --git a/osm_lcm/temporal/ns_activities.py b/osm_lcm/temporal/ns_activities.py index 3ea7dcf..2e08f91 100644 --- a/osm_lcm/temporal/ns_activities.py +++ b/osm_lcm/temporal/ns_activities.py @@ -38,8 +38,8 @@ class NsOperations: async def get_vnf_records( self, get_vnf_records_input: GetVnfRecordIdsInput ) -> GetVnfRecordIdsOutput: - # TODO: [OSMENG-1043] Implement Get VNF Records - return GetVnfRecordIdsOutput(vnfr_ids=[""]) + vnfrs = self.db.get_list("vnfrs", {"nsr-id-ref": get_vnf_records_input.ns_uuid}) + return GetVnfRecordIdsOutput(vnfr_ids=[vnfr["id"] for vnfr in vnfrs]) class NsDbActivity: diff --git a/osm_lcm/temporal/ns_workflows.py b/osm_lcm/temporal/ns_workflows.py index e78392e..7f13810 100644 --- a/osm_lcm/temporal/ns_workflows.py +++ b/osm_lcm/temporal/ns_workflows.py @@ -14,8 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import asyncio - from osm_common.dataclasses.temporal_dataclasses import ( GetVnfRecordIdsInput, GetVnfRecordIdsOutput, @@ -75,14 +73,13 @@ class NsInstantiateWorkflow(LcmOperationWorkflow): retry_policy=LcmOperationWorkflow.no_retry_policy, ), ) - asyncio.gather( - workflow.execute_child_workflow( + + for vnfr_uuid in vnf_record_ids_output.vnfr_ids: + await workflow.execute_child_workflow( workflow=WORKFLOW_VNF_INSTANTIATE, arg=VnfInstantiateInput(vnfr_uuid=vnfr_uuid, model_name=model_name), id=f"{WORKFLOW_VNF_INSTANTIATE}-{vnfr_uuid}", ) - for vnfr_uuid in vnf_record_ids_output.vnfr_ids - ) except ActivityError as e: await self.update_ns_state(ns_uuid, NsState.INSTANTIATED, e.cause.message) diff --git a/osm_lcm/temporal/vnf_activities.py b/osm_lcm/temporal/vnf_activities.py index 16cc93c..95b4232 100644 --- a/osm_lcm/temporal/vnf_activities.py +++ b/osm_lcm/temporal/vnf_activities.py @@ -67,7 +67,7 @@ class VnfOperations: """ vnfr = self.db.get_one("vnfrs", {"_id": get_task_queue_input.vnfr_uuid}) vim_record = self.db.get_one("vim_accounts", {"_id": vnfr["vim-account-id"]}) - task_queue = VIM_TYPE_TASK_QUEUE_MAPPINGS[vim_record["vim-type"]] + task_queue = VIM_TYPE_TASK_QUEUE_MAPPINGS[vim_record["vim_type"]] self.logger.debug(f"Got the task queue {task_queue} for VNF operations.") return GetTaskQueueOutput(task_queue) @@ -213,7 +213,9 @@ class VnfSendNotifications: self.logger = logging.getLogger(f"lcm.act.{self.__class__.__name__}") @activity.defn(name=ACTIVITY_SEND_NOTIFICATION_FOR_VNF) - async def send_notification_for_vnf(self) -> None: + async def send_notification_for_vnf( + self, input: ChangeVnfInstantiationStateInput + ) -> None: """If VNF LCM operation state changes, send notification updates. This activity does nothing. diff --git a/osm_lcm/temporal/vnf_workflows.py b/osm_lcm/temporal/vnf_workflows.py index 4469c46..ed81a8e 100644 --- a/osm_lcm/temporal/vnf_workflows.py +++ b/osm_lcm/temporal/vnf_workflows.py @@ -73,11 +73,11 @@ class VnfInstantiateWorkflow: vnf_state = ChangeVnfStateInput( vnfr_uuid=input.vnfr_uuid, state=VnfState.STOPPED ) - await self.update_states( - vnf_instantiation_state=vnf_instantiation_state, - vnf_state=vnf_state, - ) try: + await self.update_states( + vnf_instantiation_state=vnf_instantiation_state, + vnf_state=vnf_state, + ) vnf_task_queue = value_to_type( GetTaskQueueOutput, await workflow.execute_activity( @@ -154,11 +154,13 @@ class VnfInstantiateWorkflow: ) @staticmethod - async def send_notification_for_vnf(): + async def send_notification_for_vnf( + vnf_instantiation_state: ChangeVnfInstantiationStateInput, + ): await workflow.execute_activity( activity=ACTIVITY_SEND_NOTIFICATION_FOR_VNF, - arg=None, - activity_id=f"{ACTIVITY_SEND_NOTIFICATION_FOR_VNF}", + arg=vnf_instantiation_state, + activity_id=f"{ACTIVITY_SEND_NOTIFICATION_FOR_VNF}-{vnf_instantiation_state.vnfr_uuid}", task_queue=LCM_TASK_QUEUE, schedule_to_close_timeout=default_schedule_to_close_timeout, retry_policy=retry_policy, @@ -187,7 +189,7 @@ class VnfInstantiateWorkflow: vdu_instantiate_input = VduInstantiateInput(vim_id, model_name, vdu_info) vdu_instantiate_workflow_id = ( vdu_instantiate_input.model_name - + "_" + + "-" + vdu_instantiate_input.charm_info.app_name ) return vdu_instantiate_input, vdu_instantiate_workflow_id @@ -199,7 +201,7 @@ class VnfInstantiateWorkflow: ): await self.update_vnf_instantiation_state(vnf_instantiation_state) await self.update_vnf_state(vnf_state) - await self.send_notification_for_vnf() + await self.send_notification_for_vnf(vnf_instantiation_state) @workflow.defn(name=WORKFLOW_VNF_PREPARE, sandboxed=_SANDBOXED) diff --git a/osm_lcm/tests/test_vnf_workflows.py b/osm_lcm/tests/test_vnf_workflows.py index c5be1e7..633d113 100644 --- a/osm_lcm/tests/test_vnf_workflows.py +++ b/osm_lcm/tests/test_vnf_workflows.py @@ -14,49 +14,520 @@ # See the License for the specific language governing permissions and # limitations under the License. - import asynctest -import logging -from osm_common.dataclasses.temporal_dataclasses import VnfInstantiateInput +from temporalio import activity +from temporalio import workflow +from temporalio.client import WorkflowFailureError +from temporalio.testing import WorkflowEnvironment +from temporalio.worker import Worker +from unittest.mock import Mock + +from osm_common.dataclasses.temporal_dataclasses import ( + ChangeVnfInstantiationStateInput, + ChangeVnfStateInput, + CharmInfo, + GetTaskQueueInput, + GetTaskQueueOutput, + GetVnfDetailsInput, + GetVnfDetailsOutput, + VduInstantiateInput, + VnfInstantiateInput, + VnfInstantiationState, + VnfState, +) from osm_common.temporal_constants import ( - LCM_TASK_QUEUE, + ACTIVITY_CHANGE_VNF_STATE, + ACTIVITY_CHANGE_VNF_INSTANTIATION_STATE, + ACTIVITY_GET_TASK_QUEUE, + ACTIVITY_GET_VNF_DETAILS, + ACTIVITY_SEND_NOTIFICATION_FOR_VNF, ACTIVITY_SET_VNF_MODEL, + LCM_TASK_QUEUE, + WORKFLOW_VDU_INSTANTIATE, WORKFLOW_VNF_PREPARE, ) -from osm_lcm.temporal.vnf_workflows import VnfPrepareWorkflow -from temporalio import activity -from temporalio.testing import WorkflowEnvironment -from temporalio.worker import Worker +from osm_lcm.temporal.vnf_workflows import VnfInstantiateWorkflow, VnfPrepareWorkflow wf_input = VnfInstantiateInput( vnfr_uuid="86b53d92-4f5a-402e-8ac2-585ec6b64698", model_name="a-model-name", ) +juju_task_queue = "juju_task_queue" +vnfr_uuid = "9f472177-95c0-4335-b357-5cdc17a79965" +sample_vnfr = { + "_id": vnfr_uuid, + "id": vnfr_uuid, + "nsr-id-ref": "dcf4c922-5a73-41bf-a6ca-870c22d6336c", + "vnfd-ref": "jar_vnfd_scalable", + "vnfd-id": "f1b38eac-190c-485d-9a74-c6e169c929d8", + "vim-account-id": "9b0bedc3-ea8e-42fd-acc9-dd03f4dee73c", +} +vdu = { + "id": "hackfest_basic-VM", + "name": "hackfest_basic-VM", + "sw-image-desc": "ubuntu18.04", + "virtual-compute-desc": "hackfest_basic-VM-compute", + "virtual-storage-desc": ["hackfest_basic-VM-storage"], +} +vnfd_id = "97784f19-d254-4252-946c-cf92d85443ca" +sample_vnfd = { + "_id": vnfd_id, + "id": "sol006-vnf", + "provider": "Canonical", + "product-name": "test-vnf", + "software-version": "1.0", + "vdu": [vdu], +} +SANDBOXED = False +DEBUG_MODE = True + +class TestException(Exception): + pass + +# Mock Activities @activity.defn(name=ACTIVITY_SET_VNF_MODEL) -async def set_vnf_model_mocked(set_vnf_model_input: VnfInstantiateInput) -> None: - logging.debug( - f"VNF {set_vnf_model_input.vnfr_uuid} model name is updated to {set_vnf_model_input.model_name}." - ) +async def mock_set_vnf_model(set_vnf_model_input: VnfInstantiateInput) -> None: + pass + + +@activity.defn(name=ACTIVITY_SET_VNF_MODEL) +async def mock_set_vnf_model_raise_exception( + set_vnf_model_input: VnfInstantiateInput, +) -> None: + raise TestException(f"{ACTIVITY_SET_VNF_MODEL} failed.") + + +@activity.defn(name=ACTIVITY_GET_TASK_QUEUE) +async def mock_get_task_queue( + get_task_queue_input: GetTaskQueueInput, +) -> GetTaskQueueOutput: + return GetTaskQueueOutput(LCM_TASK_QUEUE) + + +@activity.defn(name=ACTIVITY_GET_TASK_QUEUE) +async def mock_get_different_task_queue( + get_task_queue_input: GetTaskQueueInput, +) -> GetTaskQueueOutput: + return GetTaskQueueOutput(juju_task_queue) + + +@activity.defn(name=ACTIVITY_GET_TASK_QUEUE) +async def mock_get_task_queue_raise_exception( + get_task_queue_input: GetTaskQueueInput, +) -> GetTaskQueueOutput: + raise TestException(f"{ACTIVITY_GET_TASK_QUEUE} failed.") + + +@activity.defn(name=ACTIVITY_GET_VNF_DETAILS) +async def mock_get_vnf_details( + get_vnf_details_input: GetVnfDetailsInput, +) -> GetVnfDetailsOutput: + return GetVnfDetailsOutput(vnfr=sample_vnfr, vnfd=sample_vnfd) + + +@activity.defn(name=ACTIVITY_GET_VNF_DETAILS) +async def mock_get_vnf_details_empty_output( + get_vnf_details_input: GetVnfDetailsInput, +) -> GetVnfDetailsOutput: + return GetVnfDetailsOutput(vnfr={}, vnfd={}) + + +@activity.defn(name=ACTIVITY_GET_VNF_DETAILS) +async def mock_get_vnf_details_raise_exception( + get_vnf_details_input: GetVnfDetailsInput, +) -> GetVnfDetailsOutput: + raise TestException(f"{ACTIVITY_GET_VNF_DETAILS} failed.") + + +# Mock Workflowa +@workflow.defn(name=WORKFLOW_VNF_PREPARE, sandboxed=SANDBOXED) +class MockPrepareVnfWorkflow: + @workflow.run + async def run(self, input: VnfInstantiateInput) -> None: + pass + + +@workflow.defn(name=WORKFLOW_VDU_INSTANTIATE, sandboxed=SANDBOXED) +class MockVduInstantiateWorkflow: + @workflow.run + async def run(self, input: VduInstantiateInput) -> None: + pass class TestVnfPrepareWorkflow(asynctest.TestCase): async def setUp(self): self.env = await WorkflowEnvironment.start_time_skipping() self.client = self.env.client + self.task_queue = LCM_TASK_QUEUE - async def test_vnf_prepare_workflow(self): + async def test_vnf_prepare_workflow_successful(self): async with self.env: async with Worker( self.client, - task_queue=LCM_TASK_QUEUE, + debug_mode=DEBUG_MODE, + task_queue=self.task_queue, workflows=[VnfPrepareWorkflow], - activities=[set_vnf_model_mocked], + activities=[mock_set_vnf_model], ): await self.client.execute_workflow( VnfPrepareWorkflow.run, arg=wf_input, id=f"{WORKFLOW_VNF_PREPARE}-{wf_input.vnfr_uuid}", - task_queue=LCM_TASK_QUEUE, + task_queue=self.task_queue, ) + + async def test_vnf_prepare_workflow_fails(self): + async with self.env: + async with Worker( + self.client, + debug_mode=DEBUG_MODE, + task_queue=self.task_queue, + workflows=[VnfPrepareWorkflow], + activities=[mock_set_vnf_model_raise_exception], + ): + with self.assertRaises(WorkflowFailureError) as err: + await self.client.execute_workflow( + VnfPrepareWorkflow.run, + arg=wf_input, + id=f"{WORKFLOW_VNF_PREPARE}-{wf_input.vnfr_uuid}", + task_queue=self.task_queue, + ) + self.assertEqual(str(err.exception), "Workflow execution failed") + self.assertEqual( + str(err.exception.cause.cause.message), + "set-vnf-model failed.", + ) + + +class TestVnfInstantiateWorkflow(asynctest.TestCase): + async def setUp(self): + self.env = await WorkflowEnvironment.start_time_skipping() + self.client = self.env.client + self.mock_change_vnf_instantiation_state_tracker = Mock() + self.mock_change_vnf_state_tracker = Mock() + self.mock_send_notification_for_vnf_tracker = Mock() + self.workflows = [ + VnfInstantiateWorkflow, + MockPrepareVnfWorkflow, + MockVduInstantiateWorkflow, + ] + self.task_queue = LCM_TASK_QUEUE + + def get_worker(self, task_queue: str, workflows: list, activities: list) -> Worker: + return Worker( + self.client, + task_queue=task_queue, + workflows=workflows, + activities=activities, + debug_mode=DEBUG_MODE, + ) + + async def execute_workflow(self): + return await self.client.execute_workflow( + VnfInstantiateWorkflow.run, + arg=VnfInstantiateInput(vnfr_uuid=vnfr_uuid, model_name="a-model-name"), + id="wf1", + task_queue=self.task_queue, + ) + + def check_state_change_call_counts(self): + self.assertEqual(self.mock_change_vnf_instantiation_state_tracker.call_count, 2) + self.assertEqual(self.mock_change_vnf_state_tracker.call_count, 2) + self.assertEqual(self.mock_send_notification_for_vnf_tracker.call_count, 2) + + def workflow_is_succeeded(self): + call_mock_change_vnf_instantiation_state_tracker = ( + self.mock_change_vnf_instantiation_state_tracker.call_args_list + ) + call_mock_change_vnf_state_tracker = ( + self.mock_change_vnf_state_tracker.call_args_list + ) + self.assertEqual( + call_mock_change_vnf_instantiation_state_tracker[1].args[0], + ChangeVnfInstantiationStateInput( + vnfr_uuid=vnfr_uuid, state=VnfInstantiationState.INSTANTIATED + ), + ) + self.assertEqual( + call_mock_change_vnf_state_tracker[1].args[0], + ChangeVnfStateInput(vnfr_uuid=vnfr_uuid, state=VnfState.STARTED), + ) + + def workflow_is_failed(self, error): + call_mock_change_vnf_instantiation_state_tracker = ( + self.mock_change_vnf_instantiation_state_tracker.call_args_list + ) + call_mock_change_vnf_state_tracker = ( + self.mock_change_vnf_state_tracker.call_args_list + ) + self.assertEqual( + call_mock_change_vnf_instantiation_state_tracker[1].args[0], + ChangeVnfInstantiationStateInput( + vnfr_uuid=vnfr_uuid, state=VnfInstantiationState.NOT_INSTANTIATED + ), + ) + self.assertEqual( + call_mock_change_vnf_state_tracker[1].args[0], + ChangeVnfStateInput(vnfr_uuid=vnfr_uuid, state=VnfState.STOPPED), + ) + self.assertEqual(str(error.exception), "Workflow execution failed") + + @activity.defn(name=ACTIVITY_CHANGE_VNF_STATE) + async def mock_change_vnf_state(self, nf_state_input: ChangeVnfStateInput) -> None: + self.mock_change_vnf_state_tracker(nf_state_input) + + @activity.defn(name=ACTIVITY_CHANGE_VNF_STATE) + async def mock_change_vnf_state_exception( + self, nf_state_input: ChangeVnfStateInput + ) -> None: + self.mock_change_vnf_state_tracker(nf_state_input) + raise TestException(f"{ACTIVITY_CHANGE_VNF_STATE} failed.") + + @activity.defn(name=ACTIVITY_CHANGE_VNF_INSTANTIATION_STATE) + async def mock_change_vnf_instantiation_state( + self, + nf_instantiation_state_input: ChangeVnfInstantiationStateInput, + ) -> None: + self.mock_change_vnf_instantiation_state_tracker(nf_instantiation_state_input) + + @activity.defn(name=ACTIVITY_CHANGE_VNF_INSTANTIATION_STATE) + async def mock_change_vnf_instantiation_state_exception( + self, + nf_instantiation_state_input: ChangeVnfInstantiationStateInput, + ) -> None: + self.mock_change_vnf_instantiation_state_tracker(nf_instantiation_state_input) + raise TestException(f"{ACTIVITY_CHANGE_VNF_INSTANTIATION_STATE} failed.") + + @activity.defn(name=ACTIVITY_SEND_NOTIFICATION_FOR_VNF) + async def mock_send_notification_for_vnf(self, input) -> None: + self.mock_send_notification_for_vnf_tracker() + + @asynctest.mock.patch( + "osm_lcm.temporal.vnf_workflows.VnfInstantiateWorkflow.instantiate_vdus" + ) + async def test_vnf_instantiate_workflow_successful(self, mock_instantiate_vdus): + 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_details, + ] + async with self.env, self.get_worker( + self.task_queue, self.workflows, activities + ): + await self.execute_workflow() + self.check_state_change_call_counts() + self.workflow_is_succeeded() + mock_instantiate_vdus.assert_called_once_with( + sample_vnfr, sample_vnfd, LCM_TASK_QUEUE + ) + + @asynctest.mock.patch( + "osm_lcm.temporal.vnf_workflows.VnfInstantiateWorkflow.instantiate_vdus" + ) + async def test_vnf_instantiate_workflow_change_vnf_instantiation_state_exception( + self, mock_instantiate_vdus + ): + activities = [ + mock_get_task_queue, + self.mock_change_vnf_instantiation_state_exception, + self.mock_change_vnf_state, + self.mock_send_notification_for_vnf, + mock_set_vnf_model, + mock_get_vnf_details, + ] + async with self.env, self.get_worker( + self.task_queue, self.workflows, activities + ): + with self.assertRaises(WorkflowFailureError) as err: + await self.execute_workflow() + self.assertEqual(self.mock_change_vnf_instantiation_state_tracker.call_count, 6) + self.assertEqual(self.mock_change_vnf_state_tracker.call_count, 0) + self.assertEqual(self.mock_send_notification_for_vnf_tracker.call_count, 0) + call_mock_change_vnf_instantiation_state_tracker = ( + self.mock_change_vnf_instantiation_state_tracker.call_args_list + ) + self.assertEqual( + call_mock_change_vnf_instantiation_state_tracker[1].args[0], + ChangeVnfInstantiationStateInput( + vnfr_uuid=vnfr_uuid, state=VnfInstantiationState.NOT_INSTANTIATED + ), + ) + mock_instantiate_vdus.assert_not_called() + self.assertEqual(str(err.exception), "Workflow execution failed") + self.assertEqual( + str(err.exception.cause.cause.message), + "change-vnf-instantiation-state failed.", + ) + + @asynctest.mock.patch( + "osm_lcm.temporal.vnf_workflows.VnfInstantiateWorkflow.instantiate_vdus" + ) + async def test_vnf_instantiate_workflow_change_vnf_state_exception( + self, mock_instantiate_vdus + ): + activities = [ + mock_get_task_queue, + self.mock_change_vnf_instantiation_state, + self.mock_change_vnf_state_exception, + self.mock_send_notification_for_vnf, + mock_set_vnf_model, + mock_get_vnf_details, + ] + async with self.env, self.get_worker( + self.task_queue, self.workflows, activities + ): + with self.assertRaises(WorkflowFailureError) as err: + await self.execute_workflow() + self.assertEqual(self.mock_change_vnf_instantiation_state_tracker.call_count, 2) + self.assertEqual(self.mock_change_vnf_state_tracker.call_count, 6) + self.assertEqual(self.mock_send_notification_for_vnf_tracker.call_count, 0) + self.workflow_is_failed(err) + mock_instantiate_vdus.assert_not_called() + self.assertEqual( + str(err.exception.cause.cause.message), + "change-vnf-state failed.", + ) + + @asynctest.mock.patch( + "osm_lcm.temporal.vnf_workflows.VnfInstantiateWorkflow.instantiate_vdus" + ) + async def test_vnf_instantiate_workflow_empty_vnf_details( + self, mock_instantiate_vdus + ): + 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_details_empty_output, + ] + async with self.env, self.get_worker( + self.task_queue, self.workflows, activities + ): + await self.execute_workflow() + self.check_state_change_call_counts() + self.workflow_is_succeeded() + mock_instantiate_vdus.assert_called_once_with({}, {}, LCM_TASK_QUEUE) + + @asynctest.mock.patch( + "osm_lcm.temporal.vnf_workflows.VnfInstantiateWorkflow.instantiate_vdus" + ) + async def test_vnf_instantiate_workflow_get_task_queue_raises_exception( + self, mock_instantiate_vdus + ): + activities = [ + mock_get_task_queue_raise_exception, + self.mock_change_vnf_instantiation_state, + self.mock_change_vnf_state, + self.mock_send_notification_for_vnf, + mock_set_vnf_model, + mock_get_vnf_details, + ] + async with self.env, self.get_worker( + self.task_queue, self.workflows, activities + ): + with self.assertRaises(WorkflowFailureError) as err: + await self.execute_workflow() + self.check_state_change_call_counts() + self.workflow_is_failed(err) + mock_instantiate_vdus.assert_not_called() + self.assertEqual( + str(err.exception.cause.cause.message), + "get_task_queue failed.", + ) + + @asynctest.mock.patch( + "osm_lcm.temporal.vnf_workflows.VnfInstantiateWorkflow.instantiate_vdus" + ) + async def test_vnf_instantiate_workflow_get_vnf_details_raises_exception( + self, mock_instantiate_vdus + ): + workflows = [VnfInstantiateWorkflow, MockPrepareVnfWorkflow] + 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_details_raise_exception, + ] + async with self.env, self.get_worker(self.task_queue, workflows, activities): + with self.assertRaises(WorkflowFailureError) as err: + await self.execute_workflow() + self.check_state_change_call_counts() + self.workflow_is_failed(err) + mock_instantiate_vdus.assert_not_called() + self.assertEqual( + str(err.exception.cause.cause.message), + "get_vnf_details failed.", + ) + + @asynctest.mock.patch( + "osm_lcm.temporal.vnf_workflows.VnfInstantiateWorkflow.get_vdu_instantiate_input" + ) + async def test_vnf_instantiate_workflow_calls_vdu_instantiate_workflow( + self, mock_vdu_instantiate_input + ): + mock_vdu_instantiate_input.return_value = ( + VduInstantiateInput( + vim_uuid="123", + model_name="a-model-name", + charm_info=CharmInfo( + app_name="my-app", channel="latest", entity_url="my-url" + ), + ), + "vdu_instantiate_workflow_id", + ) + 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_details, + ] + async with self.env, self.get_worker( + self.task_queue, self.workflows, activities + ): + await self.execute_workflow() + self.check_state_change_call_counts() + self.workflow_is_succeeded() + call_mock_vdu_instantiate_input = mock_vdu_instantiate_input.call_args + self.assertEqual(call_mock_vdu_instantiate_input.args[0], sample_vnfr) + self.assertEqual(call_mock_vdu_instantiate_input.args[1], sample_vnfd) + self.assertEqual(call_mock_vdu_instantiate_input.args[2], vdu) + + @asynctest.mock.patch( + "osm_lcm.temporal.vnf_workflows.VnfInstantiateWorkflow.instantiate_vdus" + ) + async def test_vnf_instantiate_workflow_successful_use_different_task_queue( + self, mock_instantiate_vdus + ): + workflows = [VnfInstantiateWorkflow, MockPrepareVnfWorkflow] + activities = [ + mock_get_different_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_details, + ] + async with self.env, self.get_worker( + self.task_queue, workflows, activities + ), self.get_worker(juju_task_queue, workflows, activities): + await self.execute_workflow() + self.check_state_change_call_counts() + self.workflow_is_succeeded() + mock_instantiate_vdus.assert_called_once_with( + sample_vnfr, sample_vnfd, juju_task_queue + ) + + +if __name__ == "__main__": + asynctest.main() -- 2.25.1