Exemple #1
0
    def prep_wf_ex_for_rerun(self):
        wf_meta = self.get_wf_fixture_meta_data(TEST_PACK_PATH,
                                                'sequential.yaml')

        # Manually create the liveaction and action execution objects without publishing.
        lv_ac_db1 = lv_db_models.LiveActionDB(action=wf_meta['name'])
        lv_ac_db1, ac_ex_db1 = action_service.create_request(lv_ac_db1)

        # Request the workflow execution.
        wf_def = self.get_wf_def(TEST_PACK_PATH, wf_meta)
        st2_ctx = self.mock_st2_context(ac_ex_db1)
        wf_ex_db = workflow_service.request(wf_def, ac_ex_db1, st2_ctx)
        wf_ex_db = self.prep_wf_ex(wf_ex_db)

        # Fail workflow execution.
        self.run_workflow_step(
            wf_ex_db,
            'task1',
            0,
            expected_ac_ex_db_status=action_constants.LIVEACTION_STATUS_FAILED,
            expected_tk_ex_db_status=wf_statuses.FAILED)

        # Check workflow status.
        conductor, wf_ex_db = workflow_service.refresh_conductor(
            str(wf_ex_db.id))
        self.assertEqual(conductor.get_workflow_status(), wf_statuses.FAILED)
        self.assertEqual(wf_ex_db.status, wf_statuses.FAILED)
        lv_ac_db1 = lv_db_access.LiveAction.get_by_id(str(lv_ac_db1.id))
        self.assertEqual(lv_ac_db1.status,
                         action_constants.LIVEACTION_STATUS_FAILED)
        ac_ex_db1 = ex_db_access.ActionExecution.get_by_id(str(ac_ex_db1.id))
        self.assertEqual(ac_ex_db1.status,
                         action_constants.LIVEACTION_STATUS_FAILED)

        return wf_meta, lv_ac_db1, ac_ex_db1, wf_ex_db
Exemple #2
0
    def test_request_task_execution_bad_action(self):
        wf_meta = self.get_wf_fixture_meta_data(TEST_PACK_PATH, TEST_FIXTURES['workflows'][0])

        # Manually create the liveaction and action execution objects without publishing.
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta['name'])
        lv_ac_db, ac_ex_db = ac_svc.create_request(lv_ac_db)

        # Request the workflow execution.
        wf_def = self.get_wf_def(TEST_PACK_PATH, wf_meta)
        wf_ex_db = wf_svc.request(wf_def, ac_ex_db)

        # Manually request task execution.
        task_id = 'task1'
        spec_module = specs_loader.get_spec_module(wf_ex_db.spec['catalog'])
        wf_spec = spec_module.WorkflowSpec.deserialize(wf_ex_db.spec)
        task_spec = wf_spec.tasks.get_task(task_id)
        task_ctx = {'foo': 'bar'}
        st2_ctx = {'execution_id': wf_ex_db.action_execution}

        task_spec.action = 'mock.foobar'

        self.assertRaises(
            ac_exc.InvalidActionReferencedException,
            wf_svc.request_task_execution,
            wf_ex_db,
            task_id,
            task_spec,
            task_ctx,
            st2_ctx
        )
Exemple #3
0
    def start_workflow(self, action_parameters):
        # Read workflow definition from file.
        wf_def = self.get_workflow_definition(self.entry_point)

        try:
            # Request workflow execution.
            st2_ctx = self._construct_st2_context()
            notify_cfg = self._get_notify_config()
            wf_ex_db = wf_svc.request(wf_def,
                                      self.execution,
                                      st2_ctx,
                                      notify_cfg=notify_cfg)
        except wf_exc.WorkflowInspectionError as e:
            status = ac_const.LIVEACTION_STATUS_FAILED
            result = {'errors': e.args[1], 'output': None}
            return (status, result, self.context)
        except Exception as e:
            status = ac_const.LIVEACTION_STATUS_FAILED
            result = {
                'errors': [{
                    'message': six.text_type(e)
                }],
                'output': None
            }
            return (status, result, self.context)

        return self._handle_workflow_return_value(wf_ex_db)
Exemple #4
0
    def test_request_task_execution_bad_action(self):
        wf_meta = self.get_wf_fixture_meta_data(TEST_PACK_PATH,
                                                TEST_FIXTURES['workflows'][0])

        # Manually create the liveaction and action execution objects without publishing.
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta['name'])
        lv_ac_db, ac_ex_db = ac_svc.create_request(lv_ac_db)

        # Request the workflow execution.
        wf_def = self.get_wf_def(TEST_PACK_PATH, wf_meta)
        st2_ctx = self.mock_st2_context(ac_ex_db)
        wf_ex_db = wf_svc.request(wf_def, ac_ex_db, st2_ctx)

        # Manually request task execution.
        task_id = 'task1'
        spec_module = specs_loader.get_spec_module(wf_ex_db.spec['catalog'])
        wf_spec = spec_module.WorkflowSpec.deserialize(wf_ex_db.spec)
        task_spec = wf_spec.tasks.get_task(task_id)
        task_ctx = {'foo': 'bar'}
        st2_ctx = {'execution_id': wf_ex_db.action_execution}

        task_spec.action = 'mock.foobar'

        self.assertRaises(ac_exc.InvalidActionReferencedException,
                          wf_svc.request_task_execution, wf_ex_db, task_id,
                          task_spec, task_ctx, st2_ctx)
Exemple #5
0
    def test_request_with_input(self):
        wf_meta = self.get_wf_fixture_meta_data(TEST_PACK_PATH, 'sequential.yaml')

        # Manually create the liveaction and action execution objects without publishing.
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta['name'], parameters={'who': 'stan'})
        lv_ac_db, ac_ex_db = action_service.create_request(lv_ac_db)

        # Request the workflow execution.
        wf_def = self.get_wf_def(TEST_PACK_PATH, wf_meta)
        st2_ctx = self.mock_st2_context(ac_ex_db)
        wf_ex_db = workflow_service.request(wf_def, ac_ex_db, st2_ctx)

        # Check workflow execution is saved to the database.
        wf_ex_dbs = wf_db_access.WorkflowExecution.query(action_execution=str(ac_ex_db.id))
        self.assertEqual(len(wf_ex_dbs), 1)

        # Check required attributes.
        wf_ex_db = wf_ex_dbs[0]
        self.assertIsNotNone(wf_ex_db.id)
        self.assertGreater(wf_ex_db.rev, 0)
        self.assertEqual(wf_ex_db.action_execution, str(ac_ex_db.id))
        self.assertEqual(wf_ex_db.status, wf_statuses.REQUESTED)

        # Check input and context.
        expected_input = {
            'who': 'stan'
        }

        self.assertDictEqual(wf_ex_db.input, expected_input)
Exemple #6
0
    def test_cancellation(self):
        # Manually create the liveaction and action execution objects without publishing.
        wf_meta = self.get_wf_fixture_meta_data(TEST_PACK_PATH,
                                                TEST_FIXTURES["workflows"][0])
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta["name"])
        lv_ac_db, ac_ex_db = ac_svc.create_request(lv_ac_db)

        # Request and pre-process the workflow execution.
        wf_def = self.get_wf_def(TEST_PACK_PATH, wf_meta)
        st2_ctx = self.mock_st2_context(ac_ex_db)
        wf_ex_db = wf_svc.request(wf_def, ac_ex_db, st2_ctx)
        wf_ex_db = self.prep_wf_ex(wf_ex_db)

        # Manually request task executions.
        task_route = 0
        self.run_workflow_step(wf_ex_db, "task1", task_route)
        self.assert_task_running("task2", task_route)

        # Cancel the workflow when there is still active task(s).
        wf_ex_db = wf_svc.request_cancellation(ac_ex_db)
        conductor, wf_ex_db = wf_svc.refresh_conductor(str(wf_ex_db.id))
        self.assertEqual(conductor.get_workflow_status(),
                         wf_statuses.CANCELING)
        self.assertEqual(wf_ex_db.status, wf_statuses.CANCELING)

        # Manually complete the task and ensure workflow is canceled.
        self.run_workflow_step(wf_ex_db, "task2", task_route)
        self.assert_task_not_started("task3", task_route)
        conductor, wf_ex_db = wf_svc.refresh_conductor(str(wf_ex_db.id))
        self.assertEqual(conductor.get_workflow_status(), wf_statuses.CANCELED)
        self.assertEqual(wf_ex_db.status, wf_statuses.CANCELED)
Exemple #7
0
    def test_request_with_input(self):
        wf_meta = self.get_wf_fixture_meta_data(TEST_PACK_PATH,
                                                'sequential.yaml')

        # Manually create the liveaction and action execution objects without publishing.
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta['name'],
                                             parameters={'who': 'stan'})
        lv_ac_db, ac_ex_db = action_service.create_request(lv_ac_db)

        # Request the workflow execution.
        wf_def = self.get_wf_def(TEST_PACK_PATH, wf_meta)
        st2_ctx = self.mock_st2_context(ac_ex_db)
        wf_ex_db = workflow_service.request(wf_def, ac_ex_db, st2_ctx)

        # Check workflow execution is saved to the database.
        wf_ex_dbs = wf_db_access.WorkflowExecution.query(
            action_execution=str(ac_ex_db.id))
        self.assertEqual(len(wf_ex_dbs), 1)

        # Check required attributes.
        wf_ex_db = wf_ex_dbs[0]
        self.assertIsNotNone(wf_ex_db.id)
        self.assertGreater(wf_ex_db.rev, 0)
        self.assertEqual(wf_ex_db.action_execution, str(ac_ex_db.id))
        self.assertEqual(wf_ex_db.status, wf_statuses.REQUESTED)

        # Check input and context.
        expected_input = {'who': 'stan'}

        self.assertDictEqual(wf_ex_db.input, expected_input)
Exemple #8
0
    def test_request_rerun_while_original_is_still_running(self):
        wf_meta = self.get_wf_fixture_meta_data(TEST_PACK_PATH,
                                                'sequential.yaml')

        # Manually create the liveaction and action execution objects without publishing.
        lv_ac_db1 = lv_db_models.LiveActionDB(action=wf_meta['name'])
        lv_ac_db1, ac_ex_db1 = action_service.create_request(lv_ac_db1)

        # Request the workflow execution.
        wf_def = self.get_wf_def(TEST_PACK_PATH, wf_meta)
        st2_ctx = self.mock_st2_context(ac_ex_db1)
        wf_ex_db = workflow_service.request(wf_def, ac_ex_db1, st2_ctx)
        wf_ex_db = self.prep_wf_ex(wf_ex_db)

        # Check workflow status.
        conductor, wf_ex_db = workflow_service.refresh_conductor(
            str(wf_ex_db.id))
        self.assertEqual(conductor.get_workflow_status(), wf_statuses.RUNNING)
        self.assertEqual(wf_ex_db.status, wf_statuses.RUNNING)

        # Manually create the liveaction and action execution objects for the rerun.
        lv_ac_db2 = lv_db_models.LiveActionDB(action=wf_meta['name'])
        lv_ac_db2, ac_ex_db2 = action_service.create_request(lv_ac_db2)

        # Request workflow execution rerun.
        st2_ctx = self.mock_st2_context(ac_ex_db2, ac_ex_db1.context)
        st2_ctx['workflow_execution_id'] = str(wf_ex_db.id)
        rerun_options = {'ref': str(ac_ex_db1.id), 'tasks': ['task1']}
        expected_error = ('^Unable to rerun workflow execution \".*\" '
                          'because it is not in a completed state.$')

        self.assertRaisesRegexp(wf_exc.WorkflowExecutionRerunException,
                                expected_error, workflow_service.request_rerun,
                                ac_ex_db2, st2_ctx, rerun_options)
    def test_cancellation(self):
        # Manually create the liveaction and action execution objects without publishing.
        wf_meta = self.get_wf_fixture_meta_data(TEST_PACK_PATH, TEST_FIXTURES['workflows'][0])
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta['name'])
        lv_ac_db, ac_ex_db = ac_svc.create_request(lv_ac_db)

        # Request and pre-process the workflow execution.
        wf_def = self.get_wf_def(TEST_PACK_PATH, wf_meta)
        st2_ctx = self.mock_st2_context(ac_ex_db)
        wf_ex_db = wf_svc.request(wf_def, ac_ex_db, st2_ctx)
        wf_ex_db = self.prep_wf_ex(wf_ex_db)

        # Manually request task executions.
        task_route = 0
        self.run_workflow_step(wf_ex_db, 'task1', task_route)
        self.assert_task_running('task2', task_route)

        # Cancel the workflow when there is still active task(s).
        wf_ex_db = wf_svc.request_cancellation(ac_ex_db)
        conductor, wf_ex_db = wf_svc.refresh_conductor(str(wf_ex_db.id))
        self.assertEqual(conductor.get_workflow_status(), wf_statuses.CANCELING)
        self.assertEqual(wf_ex_db.status, wf_statuses.CANCELING)

        # Manually complete the task and ensure workflow is canceled.
        self.run_workflow_step(wf_ex_db, 'task2', task_route)
        self.assert_task_not_started('task3', task_route)
        conductor, wf_ex_db = wf_svc.refresh_conductor(str(wf_ex_db.id))
        self.assertEqual(conductor.get_workflow_status(), wf_statuses.CANCELED)
        self.assertEqual(wf_ex_db.status, wf_statuses.CANCELED)
Exemple #10
0
    def test_request_task_execution(self):
        wf_meta = self.get_wf_fixture_meta_data(TEST_PACK_PATH,
                                                'sequential.yaml')

        # Manually create the liveaction and action execution objects without publishing.
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta['name'])
        lv_ac_db, ac_ex_db = action_service.create_request(lv_ac_db)

        # Request the workflow execution.
        wf_def = self.get_wf_def(TEST_PACK_PATH, wf_meta)
        st2_ctx = self.mock_st2_context(ac_ex_db)
        wf_ex_db = workflow_service.request(wf_def, ac_ex_db, st2_ctx)
        spec_module = specs_loader.get_spec_module(wf_ex_db.spec['catalog'])
        wf_spec = spec_module.WorkflowSpec.deserialize(wf_ex_db.spec)

        # Manually request task execution.
        task_id = 'task1'
        task_spec = wf_spec.tasks.get_task(task_id)
        task_ctx = {'foo': 'bar'}
        st2_ctx = {'execution_id': wf_ex_db.action_execution}

        task_ex_req = {
            'id':
            task_id,
            'spec':
            task_spec,
            'ctx':
            task_ctx,
            'actions': [{
                'action': 'core.echo',
                'input': {
                    'message': 'Veni, vidi, vici.'
                }
            }]
        }

        workflow_service.request_task_execution(wf_ex_db, st2_ctx, task_ex_req)

        # Check task execution is saved to the database.
        task_ex_dbs = wf_db_access.TaskExecution.query(
            workflow_execution=str(wf_ex_db.id))
        self.assertEqual(len(task_ex_dbs), 1)

        # Check required attributes.
        task_ex_db = task_ex_dbs[0]
        self.assertIsNotNone(task_ex_db.id)
        self.assertGreater(task_ex_db.rev, 0)
        self.assertEqual(task_ex_db.workflow_execution, str(wf_ex_db.id))
        self.assertEqual(task_ex_db.status, wf_states.RUNNING)

        # Check action execution for the task query with task execution ID.
        ac_ex_dbs = ex_db_access.ActionExecution.query(
            task_execution=str(task_ex_db.id))
        self.assertEqual(len(ac_ex_dbs), 1)

        # Check action execution for the task query with workflow execution ID.
        ac_ex_dbs = ex_db_access.ActionExecution.query(
            workflow_execution=str(wf_ex_db.id))
        self.assertEqual(len(ac_ex_dbs), 1)
Exemple #11
0
    def test_request_task_execution(self):
        wf_meta = self.get_wf_fixture_meta_data(TEST_PACK_PATH, 'sequential.yaml')

        # Manually create the liveaction and action execution objects without publishing.
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta['name'])
        lv_ac_db, ac_ex_db = action_service.create_request(lv_ac_db)

        # Request the workflow execution.
        wf_def = self.get_wf_def(TEST_PACK_PATH, wf_meta)
        st2_ctx = self.mock_st2_context(ac_ex_db)
        wf_ex_db = workflow_service.request(wf_def, ac_ex_db, st2_ctx)
        spec_module = specs_loader.get_spec_module(wf_ex_db.spec['catalog'])
        wf_spec = spec_module.WorkflowSpec.deserialize(wf_ex_db.spec)

        # Manually request task execution.
        task_route = 0
        task_id = 'task1'
        task_spec = wf_spec.tasks.get_task(task_id)
        task_ctx = {'foo': 'bar'}
        st2_ctx = {'execution_id': wf_ex_db.action_execution}

        task_ex_req = {
            'id': task_id,
            'route': task_route,
            'spec': task_spec,
            'ctx': task_ctx,
            'actions': [
                {'action': 'core.echo', 'input': {'message': 'Veni, vidi, vici.'}}
            ]
        }

        workflow_service.request_task_execution(wf_ex_db, st2_ctx, task_ex_req)

        # Check task execution is saved to the database.
        task_ex_dbs = wf_db_access.TaskExecution.query(workflow_execution=str(wf_ex_db.id))
        self.assertEqual(len(task_ex_dbs), 1)

        # Check required attributes.
        task_ex_db = task_ex_dbs[0]
        self.assertIsNotNone(task_ex_db.id)
        self.assertGreater(task_ex_db.rev, 0)
        self.assertEqual(task_ex_db.workflow_execution, str(wf_ex_db.id))
        self.assertEqual(task_ex_db.status, wf_statuses.RUNNING)

        # Check action execution for the task query with task execution ID.
        ac_ex_dbs = ex_db_access.ActionExecution.query(task_execution=str(task_ex_db.id))
        self.assertEqual(len(ac_ex_dbs), 1)

        # Check action execution for the task query with workflow execution ID.
        ac_ex_dbs = ex_db_access.ActionExecution.query(workflow_execution=str(wf_ex_db.id))
        self.assertEqual(len(ac_ex_dbs), 1)
Exemple #12
0
    def test_request_task_execution_bad_action(self):
        wf_meta = self.get_wf_fixture_meta_data(TEST_PACK_PATH,
                                                "sequential.yaml")

        # Manually create the liveaction and action execution objects without publishing.
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta["name"])
        lv_ac_db, ac_ex_db = action_service.create_request(lv_ac_db)

        # Request the workflow execution.
        wf_def = self.get_wf_def(TEST_PACK_PATH, wf_meta)
        st2_ctx = self.mock_st2_context(ac_ex_db)
        wf_ex_db = workflow_service.request(wf_def, ac_ex_db, st2_ctx)
        spec_module = specs_loader.get_spec_module(wf_ex_db.spec["catalog"])
        wf_spec = spec_module.WorkflowSpec.deserialize(wf_ex_db.spec)

        # Manually request task execution.
        task_route = 0
        task_id = "task1"
        task_spec = wf_spec.tasks.get_task(task_id)
        task_ctx = {"foo": "bar"}
        st2_ctx = {"execution_id": wf_ex_db.action_execution}

        task_ex_req = {
            "id":
            task_id,
            "route":
            task_route,
            "spec":
            task_spec,
            "ctx":
            task_ctx,
            "actions": [{
                "action": "mock.echo",
                "input": {
                    "message": "Veni, vidi, vici."
                }
            }],
        }

        self.assertRaises(
            action_exc.InvalidActionReferencedException,
            workflow_service.request_task_execution,
            wf_ex_db,
            st2_ctx,
            task_ex_req,
        )
Exemple #13
0
    def test_handle_action_execution_completion(self):
        wf_meta = self.get_wf_fixture_meta_data(TEST_PACK_PATH, TEST_FIXTURES['workflows'][0])

        # Manually create the liveaction and action execution objects without publishing.
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta['name'])
        lv_ac_db, ac_ex_db = ac_svc.create_request(lv_ac_db)

        # Request and pre-process the workflow execution.
        wf_def = self.get_wf_def(TEST_PACK_PATH, wf_meta)
        wf_ex_db = wf_svc.request(wf_def, ac_ex_db)
        wf_ex_db = self.prep_wf_ex(wf_ex_db)

        # Manually request task execution.
        self.run_workflow_step(wf_ex_db, 'task1', ctx={'foo': 'bar'})

        # Check that a new task is executed.
        self.assert_task_running('task2')
Exemple #14
0
    def test_handle_action_execution_completion(self):
        wf_meta = self.get_wf_fixture_meta_data(TEST_PACK_PATH, 'sequential.yaml')

        # Manually create the liveaction and action execution objects without publishing.
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta['name'])
        lv_ac_db, ac_ex_db = action_service.create_request(lv_ac_db)

        # Request and pre-process the workflow execution.
        wf_def = self.get_wf_def(TEST_PACK_PATH, wf_meta)
        st2_ctx = self.mock_st2_context(ac_ex_db)
        wf_ex_db = workflow_service.request(wf_def, ac_ex_db, st2_ctx)
        wf_ex_db = self.prep_wf_ex(wf_ex_db)

        # Manually request task execution.
        self.run_workflow_step(wf_ex_db, 'task1', 0, ctx={'foo': 'bar'})

        # Check that a new task is executed.
        self.assert_task_running('task2', 0)
Exemple #15
0
    def test_request_task_execution(self):
        wf_meta = self.get_wf_fixture_meta_data(TEST_PACK_PATH,
                                                TEST_FIXTURES['workflows'][0])

        # Manually create the liveaction and action execution objects without publishing.
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta['name'])
        lv_ac_db, ac_ex_db = ac_svc.create_request(lv_ac_db)

        # Request the workflow execution.
        wf_def = self.get_wf_def(TEST_PACK_PATH, wf_meta)
        st2_ctx = self.mock_st2_context(ac_ex_db)
        wf_ex_db = wf_svc.request(wf_def, ac_ex_db, st2_ctx)

        # Manually request task execution.
        task_id = 'task1'
        spec_module = specs_loader.get_spec_module(wf_ex_db.spec['catalog'])
        wf_spec = spec_module.WorkflowSpec.deserialize(wf_ex_db.spec)
        task_spec = wf_spec.tasks.get_task(task_id)
        task_ctx = {'foo': 'bar'}
        st2_ctx = {'execution_id': wf_ex_db.action_execution}
        wf_svc.request_task_execution(wf_ex_db, task_id, task_spec, task_ctx,
                                      st2_ctx)

        # Check task execution is saved to the database.
        task_ex_dbs = wf_db_access.TaskExecution.query(
            workflow_execution=str(wf_ex_db.id))
        self.assertEqual(len(task_ex_dbs), 1)

        # Check required attributes.
        task_ex_db = task_ex_dbs[0]
        self.assertIsNotNone(task_ex_db.id)
        self.assertGreater(task_ex_db.rev, 0)
        self.assertEqual(task_ex_db.workflow_execution, str(wf_ex_db.id))
        self.assertEqual(task_ex_db.status, wf_lib_states.RUNNING)

        # Check action execution for the task query with task execution ID.
        ac_ex_dbs = ex_db_access.ActionExecution.query(
            task_execution=str(task_ex_db.id))
        self.assertEqual(len(ac_ex_dbs), 1)

        # Check action execution for the task query with workflow execution ID.
        ac_ex_dbs = ex_db_access.ActionExecution.query(
            workflow_execution=str(wf_ex_db.id))
        self.assertEqual(len(ac_ex_dbs), 1)
Exemple #16
0
    def run(self, action_parameters):
        # Read workflow definition from file.
        wf_def = self.get_workflow_definition(self.entry_point)

        try:
            # Request workflow execution.
            st2_ctx = self._construct_st2_context()
            notify_cfg = self._get_notify_config()
            wf_ex_db = wf_svc.request(wf_def, self.execution, st2_ctx,
                                      notify_cfg)
        except wf_exc.WorkflowInspectionError as e:
            status = ac_const.LIVEACTION_STATUS_FAILED
            result = {'errors': e.args[1], 'output': None}
            return (status, result, self.context)
        except Exception as e:
            status = ac_const.LIVEACTION_STATUS_FAILED
            result = {
                'errors': [{
                    'message': six.text_type(e)
                }],
                'output': None
            }
            return (status, result, self.context)

        if wf_ex_db.status in wf_statuses.COMPLETED_STATUSES:
            status = wf_ex_db.status
            result = {'output': wf_ex_db.output or None}

            if wf_ex_db.status in wf_statuses.ABENDED_STATUSES:
                result['errors'] = wf_ex_db.errors

            for wf_ex_error in wf_ex_db.errors:
                msg = '[%s] Workflow execution completed with errors.'
                LOG.error(msg, str(self.execution.id), extra=wf_ex_error)

            return (status, result, self.context)

        # Set return values.
        status = ac_const.LIVEACTION_STATUS_RUNNING
        partial_results = {}
        ctx = self._construct_context(wf_ex_db)

        return (status, partial_results, ctx)
Exemple #17
0
    def test_request_task_execution_bad_action(self):
        wf_meta = self.get_wf_fixture_meta_data(TEST_PACK_PATH,
                                                'sequential.yaml')

        # Manually create the liveaction and action execution objects without publishing.
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta['name'])
        lv_ac_db, ac_ex_db = action_service.create_request(lv_ac_db)

        # Request the workflow execution.
        wf_def = self.get_wf_def(TEST_PACK_PATH, wf_meta)
        st2_ctx = self.mock_st2_context(ac_ex_db)
        wf_ex_db = workflow_service.request(wf_def, ac_ex_db, st2_ctx)
        spec_module = specs_loader.get_spec_module(wf_ex_db.spec['catalog'])
        wf_spec = spec_module.WorkflowSpec.deserialize(wf_ex_db.spec)

        # Manually request task execution.
        task_route = 0
        task_id = 'task1'
        task_spec = wf_spec.tasks.get_task(task_id)
        task_ctx = {'foo': 'bar'}
        st2_ctx = {'execution_id': wf_ex_db.action_execution}

        task_ex_req = {
            'id':
            task_id,
            'route':
            task_route,
            'spec':
            task_spec,
            'ctx':
            task_ctx,
            'actions': [{
                'action': 'mock.echo',
                'input': {
                    'message': 'Veni, vidi, vici.'
                }
            }]
        }

        self.assertRaises(action_exc.InvalidActionReferencedException,
                          workflow_service.request_task_execution, wf_ex_db,
                          st2_ctx, task_ex_req)
    def test_retry_on_write_conflict(self):
        # Create a temporary file which will be used to signal
        # which task(s) to mock the DB write conflict.
        temp_file_path = TEMP_DIR_PATH + '/task4'
        if not os.path.exists(temp_file_path):
            with open(temp_file_path, 'w'):
                pass

        # Manually create the liveaction and action execution objects without publishing.
        wf_meta = self.get_wf_fixture_meta_data(TEST_PACK_PATH,
                                                TEST_FIXTURES['workflows'][0])
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta['name'])
        lv_ac_db, ac_ex_db = ac_svc.create_request(lv_ac_db)

        # Request and pre-process the workflow execution.
        wf_def = self.get_wf_def(TEST_PACK_PATH, wf_meta)
        st2_ctx = self.mock_st2_context(ac_ex_db)
        wf_ex_db = wf_svc.request(wf_def, ac_ex_db, st2_ctx)
        wf_ex_db = self.prep_wf_ex(wf_ex_db)

        # Manually request task executions.
        task_route = 0
        self.run_workflow_step(wf_ex_db, 'task1', task_route)
        self.assert_task_running('task2', task_route)
        self.assert_task_running('task4', task_route)
        self.run_workflow_step(wf_ex_db, 'task2', task_route)
        self.assert_task_running('task3', task_route)
        self.run_workflow_step(wf_ex_db, 'task4', task_route)
        self.assert_task_running('task5', task_route)
        self.run_workflow_step(wf_ex_db, 'task3', task_route)
        self.assert_task_not_started('task6', task_route)
        self.run_workflow_step(wf_ex_db, 'task5', task_route)
        self.assert_task_running('task6', task_route)
        self.run_workflow_step(wf_ex_db, 'task6', task_route)
        self.assert_task_running('task7', task_route)
        self.run_workflow_step(wf_ex_db, 'task7', task_route)
        self.assert_workflow_completed(str(wf_ex_db.id),
                                       status=wf_statuses.SUCCEEDED)

        # Ensure retry happened.
        self.assertFalse(os.path.exists(temp_file_path))
Exemple #19
0
    def test_request(self):
        wf_meta = self.get_wf_fixture_meta_data(TEST_PACK_PATH, TEST_FIXTURES['workflows'][0])

        # Manually create the liveaction and action execution objects without publishing.
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta['name'])
        lv_ac_db, ac_ex_db = ac_svc.create_request(lv_ac_db)

        # Request the workflow execution.
        wf_def = self.get_wf_def(TEST_PACK_PATH, wf_meta)
        wf_ex_db = wf_svc.request(wf_def, ac_ex_db)

        # Check workflow execution is saved to the database.
        wf_ex_dbs = wf_db_access.WorkflowExecution.query(action_execution=str(ac_ex_db.id))
        self.assertEqual(len(wf_ex_dbs), 1)

        # Check required attributes.
        wf_ex_db = wf_ex_dbs[0]
        self.assertIsNotNone(wf_ex_db.id)
        self.assertGreater(wf_ex_db.rev, 0)
        self.assertEqual(wf_ex_db.action_execution, str(ac_ex_db.id))
        self.assertEqual(wf_ex_db.status, wf_lib_states.REQUESTED)
Exemple #20
0
    def run(self, action_parameters):
        # Read workflow definition from file.
        wf_def = self.get_workflow_definition(self.entry_point)

        try:
            # Request workflow execution.
            wf_ex_db = wf_svc.request(wf_def, self.execution)
        except wf_exc.WorkflowInspectionError as e:
            status = ac_const.LIVEACTION_STATUS_FAILED
            result = {'errors': e.args[1], 'output': None}
            return (status, result, self.context)
        except Exception as e:
            status = ac_const.LIVEACTION_STATUS_FAILED
            result = {'errors': str(e), 'output': None}
            return (status, result, self.context)

        # Set return values.
        status = ac_const.LIVEACTION_STATUS_RUNNING
        partial_results = {}
        ctx = self._construct_context(wf_ex_db)

        return (status, partial_results, ctx)
Exemple #21
0
    def run(self, action_parameters):
        # Read workflow definition from file.
        wf_def = self.get_workflow_definition(self.entry_point)

        try:
            # Request workflow execution.
            wf_ex_db = wf_svc.request(wf_def, self.execution)
        except wf_exc.WorkflowInspectionError as e:
            status = ac_const.LIVEACTION_STATUS_FAILED
            result = {'errors': e.args[1], 'output': None}
            return (status, result, self.context)
        except Exception as e:
            status = ac_const.LIVEACTION_STATUS_FAILED
            result = {'errors': str(e), 'output': None}
            return (status, result, self.context)

        # Set return values.
        status = ac_const.LIVEACTION_STATUS_RUNNING
        partial_results = {}
        ctx = self._construct_context(wf_ex_db)

        return (status, partial_results, ctx)
    def test_retry_on_write_conflict(self):
        # Create a temporary file which will be used to signal
        # which task(s) to mock the DB write conflict.
        temp_file_path = TEMP_DIR_PATH + '/task4'
        if not os.path.exists(temp_file_path):
            with open(temp_file_path, 'w'):
                pass

        # Manually create the liveaction and action execution objects without publishing.
        wf_meta = self.get_wf_fixture_meta_data(TEST_PACK_PATH, TEST_FIXTURES['workflows'][0])
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta['name'])
        lv_ac_db, ac_ex_db = ac_svc.create_request(lv_ac_db)

        # Request and pre-process the workflow execution.
        wf_def = self.get_wf_def(TEST_PACK_PATH, wf_meta)
        st2_ctx = self.mock_st2_context(ac_ex_db)
        wf_ex_db = wf_svc.request(wf_def, ac_ex_db, st2_ctx)
        wf_ex_db = self.prep_wf_ex(wf_ex_db)

        # Manually request task executions.
        task_route = 0
        self.run_workflow_step(wf_ex_db, 'task1', task_route)
        self.assert_task_running('task2', task_route)
        self.assert_task_running('task4', task_route)
        self.run_workflow_step(wf_ex_db, 'task2', task_route)
        self.assert_task_running('task3', task_route)
        self.run_workflow_step(wf_ex_db, 'task4', task_route)
        self.assert_task_running('task5', task_route)
        self.run_workflow_step(wf_ex_db, 'task3', task_route)
        self.assert_task_not_started('task6', task_route)
        self.run_workflow_step(wf_ex_db, 'task5', task_route)
        self.assert_task_running('task6', task_route)
        self.run_workflow_step(wf_ex_db, 'task6', task_route)
        self.assert_task_running('task7', task_route)
        self.run_workflow_step(wf_ex_db, 'task7', task_route)
        self.assert_workflow_completed(str(wf_ex_db.id), status=wf_statuses.SUCCEEDED)

        # Ensure retry happened.
        self.assertFalse(os.path.exists(temp_file_path))
Exemple #23
0
    def test_request_task_execution(self):
        wf_meta = self.get_wf_fixture_meta_data(TEST_PACK_PATH, TEST_FIXTURES['workflows'][0])

        # Manually create the liveaction and action execution objects without publishing.
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta['name'])
        lv_ac_db, ac_ex_db = ac_svc.create_request(lv_ac_db)

        # Request the workflow execution.
        wf_def = self.get_wf_def(TEST_PACK_PATH, wf_meta)
        wf_ex_db = wf_svc.request(wf_def, ac_ex_db)

        # Manually request task execution.
        task_id = 'task1'
        spec_module = specs_loader.get_spec_module(wf_ex_db.spec['catalog'])
        wf_spec = spec_module.WorkflowSpec.deserialize(wf_ex_db.spec)
        task_spec = wf_spec.tasks.get_task(task_id)
        task_ctx = {'foo': 'bar'}
        st2_ctx = {'execution_id': wf_ex_db.action_execution}
        wf_svc.request_task_execution(wf_ex_db, task_id, task_spec, task_ctx, st2_ctx)

        # Check task execution is saved to the database.
        task_ex_dbs = wf_db_access.TaskExecution.query(workflow_execution=str(wf_ex_db.id))
        self.assertEqual(len(task_ex_dbs), 1)

        # Check required attributes.
        task_ex_db = task_ex_dbs[0]
        self.assertIsNotNone(task_ex_db.id)
        self.assertGreater(task_ex_db.rev, 0)
        self.assertEqual(task_ex_db.workflow_execution, str(wf_ex_db.id))
        self.assertEqual(task_ex_db.status, wf_lib_states.RUNNING)

        # Check action execution for the task query with task execution ID.
        ac_ex_dbs = ex_db_access.ActionExecution.query(task_execution=str(task_ex_db.id))
        self.assertEqual(len(ac_ex_dbs), 1)

        # Check action execution for the task query with workflow execution ID.
        ac_ex_dbs = ex_db_access.ActionExecution.query(workflow_execution=str(wf_ex_db.id))
        self.assertEqual(len(ac_ex_dbs), 1)
Exemple #24
0
    def test_request_task_execution_bad_action(self):
        wf_meta = self.get_wf_fixture_meta_data(TEST_PACK_PATH, 'sequential.yaml')

        # Manually create the liveaction and action execution objects without publishing.
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta['name'])
        lv_ac_db, ac_ex_db = action_service.create_request(lv_ac_db)

        # Request the workflow execution.
        wf_def = self.get_wf_def(TEST_PACK_PATH, wf_meta)
        st2_ctx = self.mock_st2_context(ac_ex_db)
        wf_ex_db = workflow_service.request(wf_def, ac_ex_db, st2_ctx)
        spec_module = specs_loader.get_spec_module(wf_ex_db.spec['catalog'])
        wf_spec = spec_module.WorkflowSpec.deserialize(wf_ex_db.spec)

        # Manually request task execution.
        task_route = 0
        task_id = 'task1'
        task_spec = wf_spec.tasks.get_task(task_id)
        task_ctx = {'foo': 'bar'}
        st2_ctx = {'execution_id': wf_ex_db.action_execution}

        task_ex_req = {
            'id': task_id,
            'route': task_route,
            'spec': task_spec,
            'ctx': task_ctx,
            'actions': [
                {'action': 'mock.echo', 'input': {'message': 'Veni, vidi, vici.'}}
            ]
        }

        self.assertRaises(
            action_exc.InvalidActionReferencedException,
            workflow_service.request_task_execution,
            wf_ex_db,
            st2_ctx,
            task_ex_req
        )
Exemple #25
0
    def test_request(self):
        wf_meta = self.get_wf_fixture_meta_data(TEST_PACK_PATH,
                                                TEST_FIXTURES['workflows'][0])

        # Manually create the liveaction and action execution objects without publishing.
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta['name'])
        lv_ac_db, ac_ex_db = ac_svc.create_request(lv_ac_db)

        # Request the workflow execution.
        wf_def = self.get_wf_def(TEST_PACK_PATH, wf_meta)
        wf_ex_db = wf_svc.request(wf_def, ac_ex_db)

        # Check workflow execution is saved to the database.
        wf_ex_dbs = wf_db_access.WorkflowExecution.query(
            action_execution=str(ac_ex_db.id))
        self.assertEqual(len(wf_ex_dbs), 1)

        # Check required attributes.
        wf_ex_db = wf_ex_dbs[0]
        self.assertIsNotNone(wf_ex_db.id)
        self.assertGreater(wf_ex_db.rev, 0)
        self.assertEqual(wf_ex_db.action_execution, str(ac_ex_db.id))
        self.assertEqual(wf_ex_db.status, wf_lib_states.REQUESTED)
Exemple #26
0
    def run(self, action_parameters):
        # Read workflow definition from file.
        wf_def = self.get_workflow_definition(self.entry_point)

        try:
            # Request workflow execution.
            st2_ctx = self._construct_st2_context()
            notify_cfg = self._get_notify_config()
            wf_ex_db = wf_svc.request(wf_def, self.execution, st2_ctx, notify_cfg)
        except wf_exc.WorkflowInspectionError as e:
            status = ac_const.LIVEACTION_STATUS_FAILED
            result = {'errors': e.args[1], 'output': None}
            return (status, result, self.context)
        except Exception as e:
            status = ac_const.LIVEACTION_STATUS_FAILED
            result = {'errors': [{'message': six.text_type(e)}], 'output': None}
            return (status, result, self.context)

        if wf_ex_db.status in wf_statuses.COMPLETED_STATUSES:
            status = wf_ex_db.status
            result = {'output': wf_ex_db.output or None}

            if wf_ex_db.status in wf_statuses.ABENDED_STATUSES:
                result['errors'] = wf_ex_db.errors

            for wf_ex_error in wf_ex_db.errors:
                msg = '[%s] Workflow execution completed with errors.'
                LOG.error(msg, str(self.execution.id), extra=wf_ex_error)

            return (status, result, self.context)

        # Set return values.
        status = ac_const.LIVEACTION_STATUS_RUNNING
        partial_results = {}
        ctx = self._construct_context(wf_ex_db)

        return (status, partial_results, ctx)
Exemple #27
0
    def test_request_action_execution_render(self):
        # Manually create ConfigDB
        output = 'Testing'
        value = {"config_item_one": output}
        config_db = pk_db_models.ConfigDB(pack=PACK_7, values=value)
        config = pk_db_access.Config.add_or_update(config_db)
        self.assertEqual(len(config), 3)

        wf_meta = self.get_wf_fixture_meta_data(TEST_PACK_PATH,
                                                'render_config_context.yaml')

        # Manually create the liveaction and action execution objects without publishing.
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta['name'])
        lv_ac_db, ac_ex_db = action_service.create_request(lv_ac_db)

        # Request the workflow execution.
        wf_def = self.get_wf_def(TEST_PACK_PATH, wf_meta)
        st2_ctx = self.mock_st2_context(ac_ex_db)
        wf_ex_db = workflow_service.request(wf_def, ac_ex_db, st2_ctx)
        spec_module = specs_loader.get_spec_module(wf_ex_db.spec['catalog'])
        wf_spec = spec_module.WorkflowSpec.deserialize(wf_ex_db.spec)

        # Pass down appropriate st2 context to the task and action execution(s).
        root_st2_ctx = wf_ex_db.context.get('st2', {})
        st2_ctx = {
            'execution_id': wf_ex_db.action_execution,
            'user': root_st2_ctx.get('user'),
            'pack': root_st2_ctx.get('pack')
        }

        # Manually request task execution.
        task_route = 0
        task_id = 'task1'
        task_spec = wf_spec.tasks.get_task(task_id)
        task_ctx = {'foo': 'bar'}

        task_ex_req = {
            'id':
            task_id,
            'route':
            task_route,
            'spec':
            task_spec,
            'ctx':
            task_ctx,
            'actions': [{
                'action': 'dummy_pack_7.render_config_context',
                'input': None
            }]
        }
        workflow_service.request_task_execution(wf_ex_db, st2_ctx, task_ex_req)

        # Check task execution is saved to the database.
        task_ex_dbs = wf_db_access.TaskExecution.query(
            workflow_execution=str(wf_ex_db.id))
        self.assertEqual(len(task_ex_dbs), 1)
        workflow_service.request_task_execution(wf_ex_db, st2_ctx, task_ex_req)

        # Manually request action execution
        task_ex_db = task_ex_dbs[0]
        action_ex_db = workflow_service.request_action_execution(
            wf_ex_db, task_ex_db, st2_ctx, task_ex_req['actions'][0])

        # Check required attributes.
        self.assertIsNotNone(str(action_ex_db.id))
        self.assertEqual(task_ex_db.workflow_execution, str(wf_ex_db.id))
        expected_parameters = {'value1': output}
        self.assertEqual(expected_parameters, action_ex_db.parameters)
Exemple #28
0
    def test_request_action_execution_render(self):
        # Manually create ConfigDB
        output = "Testing"
        value = {"config_item_one": output}
        config_db = pk_db_models.ConfigDB(pack=PACK_7, values=value)
        config = pk_db_access.Config.add_or_update(config_db)
        self.assertEqual(len(config), 3)

        wf_meta = self.get_wf_fixture_meta_data(TEST_PACK_PATH,
                                                "render_config_context.yaml")

        # Manually create the liveaction and action execution objects without publishing.
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta["name"])
        lv_ac_db, ac_ex_db = action_service.create_request(lv_ac_db)

        # Request the workflow execution.
        wf_def = self.get_wf_def(TEST_PACK_PATH, wf_meta)
        st2_ctx = self.mock_st2_context(ac_ex_db)
        wf_ex_db = workflow_service.request(wf_def, ac_ex_db, st2_ctx)
        spec_module = specs_loader.get_spec_module(wf_ex_db.spec["catalog"])
        wf_spec = spec_module.WorkflowSpec.deserialize(wf_ex_db.spec)

        # Pass down appropriate st2 context to the task and action execution(s).
        root_st2_ctx = wf_ex_db.context.get("st2", {})
        st2_ctx = {
            "execution_id": wf_ex_db.action_execution,
            "user": root_st2_ctx.get("user"),
            "pack": root_st2_ctx.get("pack"),
        }

        # Manually request task execution.
        task_route = 0
        task_id = "task1"
        task_spec = wf_spec.tasks.get_task(task_id)
        task_ctx = {"foo": "bar"}

        task_ex_req = {
            "id":
            task_id,
            "route":
            task_route,
            "spec":
            task_spec,
            "ctx":
            task_ctx,
            "actions": [{
                "action": "dummy_pack_7.render_config_context",
                "input": None
            }],
        }
        workflow_service.request_task_execution(wf_ex_db, st2_ctx, task_ex_req)

        # Check task execution is saved to the database.
        task_ex_dbs = wf_db_access.TaskExecution.query(
            workflow_execution=str(wf_ex_db.id))
        self.assertEqual(len(task_ex_dbs), 1)
        workflow_service.request_task_execution(wf_ex_db, st2_ctx, task_ex_req)

        # Manually request action execution
        task_ex_db = task_ex_dbs[0]
        action_ex_db = workflow_service.request_action_execution(
            wf_ex_db, task_ex_db, st2_ctx, task_ex_req["actions"][0])

        # Check required attributes.
        self.assertIsNotNone(str(action_ex_db.id))
        self.assertEqual(task_ex_db.workflow_execution, str(wf_ex_db.id))
        expected_parameters = {"value1": output}
        self.assertEqual(expected_parameters, action_ex_db.parameters)
Exemple #29
0
    def test_request_action_execution_render(self):
        # Manually create ConfigDB
        output = 'Testing'
        value = {
            "config_item_one": output
        }
        config_db = pk_db_models.ConfigDB(pack=PACK_7, values=value)
        config = pk_db_access.Config.add_or_update(config_db)
        self.assertEqual(len(config), 3)

        wf_meta = self.get_wf_fixture_meta_data(TEST_PACK_PATH, 'render_config_context.yaml')

        # Manually create the liveaction and action execution objects without publishing.
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta['name'])
        lv_ac_db, ac_ex_db = action_service.create_request(lv_ac_db)

        # Request the workflow execution.
        wf_def = self.get_wf_def(TEST_PACK_PATH, wf_meta)
        st2_ctx = self.mock_st2_context(ac_ex_db)
        wf_ex_db = workflow_service.request(wf_def, ac_ex_db, st2_ctx)
        spec_module = specs_loader.get_spec_module(wf_ex_db.spec['catalog'])
        wf_spec = spec_module.WorkflowSpec.deserialize(wf_ex_db.spec)

        # Pass down appropriate st2 context to the task and action execution(s).
        root_st2_ctx = wf_ex_db.context.get('st2', {})
        st2_ctx = {
            'execution_id': wf_ex_db.action_execution,
            'user': root_st2_ctx.get('user'),
            'pack': root_st2_ctx.get('pack')
        }

        # Manually request task execution.
        task_route = 0
        task_id = 'task1'
        task_spec = wf_spec.tasks.get_task(task_id)
        task_ctx = {'foo': 'bar'}

        task_ex_req = {
            'id': task_id,
            'route': task_route,
            'spec': task_spec,
            'ctx': task_ctx,
            'actions': [
                {'action': 'dummy_pack_7.render_config_context', 'input': None}
            ]
        }
        workflow_service.request_task_execution(wf_ex_db, st2_ctx, task_ex_req)

        # Check task execution is saved to the database.
        task_ex_dbs = wf_db_access.TaskExecution.query(workflow_execution=str(wf_ex_db.id))
        self.assertEqual(len(task_ex_dbs), 1)
        workflow_service.request_task_execution(wf_ex_db, st2_ctx, task_ex_req)

        # Manually request action execution
        task_ex_db = task_ex_dbs[0]
        action_ex_db = workflow_service.request_action_execution(wf_ex_db, task_ex_db, st2_ctx,
                                                                 task_ex_req['actions'][0])

        # Check required attributes.
        self.assertIsNotNone(str(action_ex_db.id))
        self.assertEqual(task_ex_db.workflow_execution, str(wf_ex_db.id))
        expected_parameters = {'value1': output}
        self.assertEqual(expected_parameters, action_ex_db.parameters)
Exemple #30
0
    def test_request_task_execution(self):
        wf_meta = self.get_wf_fixture_meta_data(TEST_PACK_PATH,
                                                "sequential.yaml")

        # Manually create the liveaction and action execution objects without publishing.
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta["name"])
        lv_ac_db, ac_ex_db = action_service.create_request(lv_ac_db)

        # Request the workflow execution.
        wf_def = self.get_wf_def(TEST_PACK_PATH, wf_meta)
        st2_ctx = self.mock_st2_context(ac_ex_db)
        wf_ex_db = workflow_service.request(wf_def, ac_ex_db, st2_ctx)
        spec_module = specs_loader.get_spec_module(wf_ex_db.spec["catalog"])
        wf_spec = spec_module.WorkflowSpec.deserialize(wf_ex_db.spec)

        # Manually request task execution.
        task_route = 0
        task_id = "task1"
        task_spec = wf_spec.tasks.get_task(task_id)
        task_ctx = {"foo": "bar"}
        st2_ctx = {"execution_id": wf_ex_db.action_execution}

        task_ex_req = {
            "id":
            task_id,
            "route":
            task_route,
            "spec":
            task_spec,
            "ctx":
            task_ctx,
            "actions": [{
                "action": "core.echo",
                "input": {
                    "message": "Veni, vidi, vici."
                }
            }],
        }

        workflow_service.request_task_execution(wf_ex_db, st2_ctx, task_ex_req)

        # Check task execution is saved to the database.
        task_ex_dbs = wf_db_access.TaskExecution.query(
            workflow_execution=str(wf_ex_db.id))
        self.assertEqual(len(task_ex_dbs), 1)

        # Check required attributes.
        task_ex_db = task_ex_dbs[0]
        self.assertIsNotNone(task_ex_db.id)
        self.assertGreater(task_ex_db.rev, 0)
        self.assertEqual(task_ex_db.workflow_execution, str(wf_ex_db.id))
        self.assertEqual(task_ex_db.status, wf_statuses.RUNNING)

        # Check action execution for the task query with task execution ID.
        ac_ex_dbs = ex_db_access.ActionExecution.query(
            task_execution=str(task_ex_db.id))
        self.assertEqual(len(ac_ex_dbs), 1)

        # Check action execution for the task query with workflow execution ID.
        ac_ex_dbs = ex_db_access.ActionExecution.query(
            workflow_execution=str(wf_ex_db.id))
        self.assertEqual(len(ac_ex_dbs), 1)