Пример #1
0
    def test_fail_next_task_input_value_type(self):
        if six.PY3:
            msg = 'Value "{\'x\': \'foobar\'}" must either be a string or None. Got "dict".'
        else:
            msg = 'Value "{u\'x\': u\'foobar\'}" must either be a string or None. Got "dict".'

        msg = 'ValueError: ' + msg

        expected_errors = [
            {
                'type': 'error',
                'message': msg,
                'task_id': 'task2',
                'route': 0
            }
        ]

        expected_result = {'output': None, 'errors': expected_errors}

        wf_file = 'fail-task-input-value-type.yaml'
        wf_meta = base.get_wf_fixture_meta_data(TEST_PACK_PATH, wf_file)
        wf_input = {'var1': {'x': 'foobar'}}
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta['name'], parameters=wf_input)
        lv_ac_db, ac_ex_db = ac_svc.request(lv_ac_db)

        # Assert task1 is already completed and workflow execution is still running.
        wf_ex_db = wf_db_access.WorkflowExecution.query(action_execution=str(ac_ex_db.id))[0]
        tk1_ex_db = wf_db_access.TaskExecution.query(workflow_execution=str(wf_ex_db.id))[0]
        tk1_ac_ex_db = ex_db_access.ActionExecution.query(task_execution=str(tk1_ex_db.id))[0]
        tk1_lv_ac_db = lv_db_access.LiveAction.get_by_id(tk1_ac_ex_db.liveaction['id'])
        self.assertEqual(tk1_lv_ac_db.status, ac_const.LIVEACTION_STATUS_SUCCEEDED)
        self.assertEqual(wf_ex_db.status, wf_statuses.RUNNING)

        # Manually handle action execution completion for task1 which has an error in publish.
        wf_svc.handle_action_execution_completion(tk1_ac_ex_db)

        # Assert workflow execution and task2 execution failed.
        wf_ex_db = wf_db_access.WorkflowExecution.get_by_id(str(wf_ex_db.id))
        self.assertEqual(wf_ex_db.status, wf_statuses.FAILED)
        self.assertListEqual(self.sort_workflow_errors(wf_ex_db.errors), expected_errors)

        tk2_ex_db = wf_db_access.TaskExecution.query(task_id='task2')[0]
        self.assertEqual(tk2_ex_db.status, wf_statuses.FAILED)
        self.assertDictEqual(tk2_ex_db.result, {'errors': expected_errors})

        lv_ac_db = lv_db_access.LiveAction.get_by_id(str(lv_ac_db.id))
        self.assertEqual(lv_ac_db.status, ac_const.LIVEACTION_STATUS_FAILED)
        self.assertDictEqual(lv_ac_db.result, expected_result)

        ac_ex_db = ex_db_access.ActionExecution.get_by_id(str(ac_ex_db.id))
        self.assertEqual(ac_ex_db.status, ac_const.LIVEACTION_STATUS_FAILED)
        self.assertDictEqual(ac_ex_db.result, expected_result)
Пример #2
0
    def test_fail_next_task_input_expr_eval(self):
        expected_errors = [{
            "type":
            "error",
            "message":
            ("YaqlEvaluationException: Unable to evaluate expression "
             "'<% ctx().msg2.value %>'. NoFunctionRegisteredException: "
             'Unknown function "#property#value"'),
            "task_id":
            "task2",
            "route":
            0,
        }]

        expected_result = {"output": None, "errors": expected_errors}

        wf_meta = base.get_wf_fixture_meta_data(
            TEST_PACK_PATH, "fail-task-input-expr-eval.yaml")

        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta["name"])
        lv_ac_db, ac_ex_db = ac_svc.request(lv_ac_db)

        # Assert task1 is already completed.
        wf_ex_db = wf_db_access.WorkflowExecution.query(
            action_execution=str(ac_ex_db.id))[0]
        tk_ex_db = wf_db_access.TaskExecution.query(
            workflow_execution=str(wf_ex_db.id))[0]
        tk_ac_ex_db = ex_db_access.ActionExecution.query(
            task_execution=str(tk_ex_db.id))[0]
        tk_lv_ac_db = lv_db_access.LiveAction.get_by_id(
            tk_ac_ex_db.liveaction["id"])
        self.assertEqual(tk_lv_ac_db.status,
                         ac_const.LIVEACTION_STATUS_SUCCEEDED)

        # Manually handle action execution completion for task1 which has an error in publish.
        wf_svc.handle_action_execution_completion(tk_ac_ex_db)

        # Assert task1 succeeded but workflow failed.
        tk_ex_db = wf_db_access.TaskExecution.get_by_id(tk_ex_db.id)
        self.assertEqual(tk_ex_db.status, wf_statuses.SUCCEEDED)
        wf_ex_db = wf_db_access.WorkflowExecution.get_by_id(wf_ex_db.id)
        self.assertEqual(wf_ex_db.status, wf_statuses.FAILED)
        self.assertListEqual(self.sort_workflow_errors(wf_ex_db.errors),
                             expected_errors)

        lv_ac_db = lv_db_access.LiveAction.get_by_id(str(lv_ac_db.id))
        self.assertEqual(lv_ac_db.status, ac_const.LIVEACTION_STATUS_FAILED)
        self.assertDictEqual(lv_ac_db.result, expected_result)

        ac_ex_db = ex_db_access.ActionExecution.get_by_id(str(ac_ex_db.id))
        self.assertEqual(ac_ex_db.status, ac_const.LIVEACTION_STATUS_FAILED)
        self.assertDictEqual(ac_ex_db.result, expected_result)
Пример #3
0
    def test_fail_next_task_action(self):
        expected_errors = [{
            'type':
            'error',
            'message':
            ('YaqlEvaluationException: Unable to evaluate expression '
             '\'<% ctx().func.value %>\'. NoFunctionRegisteredException: '
             'Unknown function "#property#value"'),
            'task_id':
            'task2',
            'route':
            0
        }]

        expected_result = {'output': None, 'errors': expected_errors}

        wf_meta = base.get_wf_fixture_meta_data(TEST_PACK_PATH,
                                                'fail-task-action.yaml')

        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta['name'])
        lv_ac_db, ac_ex_db = ac_svc.request(lv_ac_db)

        # Assert task1 is already completed.
        wf_ex_db = wf_db_access.WorkflowExecution.query(
            action_execution=str(ac_ex_db.id))[0]
        tk_ex_db = wf_db_access.TaskExecution.query(
            workflow_execution=str(wf_ex_db.id))[0]
        tk_ac_ex_db = ex_db_access.ActionExecution.query(
            task_execution=str(tk_ex_db.id))[0]
        tk_lv_ac_db = lv_db_access.LiveAction.get_by_id(
            tk_ac_ex_db.liveaction['id'])
        self.assertEqual(tk_lv_ac_db.status,
                         ac_const.LIVEACTION_STATUS_SUCCEEDED)

        # Manually handle action execution completion for task1 which has an error in publish.
        wf_svc.handle_action_execution_completion(tk_ac_ex_db)

        # Assert task1 succeeded but workflow failed.
        tk_ex_db = wf_db_access.TaskExecution.get_by_id(tk_ex_db.id)
        self.assertEqual(tk_ex_db.status, wf_statuses.SUCCEEDED)
        wf_ex_db = wf_db_access.WorkflowExecution.get_by_id(wf_ex_db.id)
        self.assertEqual(wf_ex_db.status, wf_statuses.FAILED)
        self.assertListEqual(self.sort_wf_runtime_errors(wf_ex_db.errors),
                             expected_errors)

        lv_ac_db = lv_db_access.LiveAction.get_by_id(str(lv_ac_db.id))
        self.assertEqual(lv_ac_db.status, ac_const.LIVEACTION_STATUS_FAILED)
        self.assertDictEqual(lv_ac_db.result, expected_result)

        ac_ex_db = ex_db_access.ActionExecution.get_by_id(str(ac_ex_db.id))
        self.assertEqual(ac_ex_db.status, ac_const.LIVEACTION_STATUS_FAILED)
        self.assertDictEqual(ac_ex_db.result, expected_result)
Пример #4
0
    def test_fail_task_transition(self):
        expected_errors = [{
            "type":
            "error",
            "message":
            ("YaqlEvaluationException: Unable to resolve key 'foobar' in expression "
             "'<% succeeded() and result().foobar %>' from context."),
            "task_transition_id":
            "task2__t0",
            "task_id":
            "task1",
            "route":
            0,
        }]

        expected_result = {"output": None, "errors": expected_errors}

        wf_meta = base.get_wf_fixture_meta_data(TEST_PACK_PATH,
                                                "fail-task-transition.yaml")
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta["name"])
        lv_ac_db, ac_ex_db = ac_svc.request(lv_ac_db)

        # Assert task1 is already completed.
        wf_ex_db = wf_db_access.WorkflowExecution.query(
            action_execution=str(ac_ex_db.id))[0]
        tk_ex_db = wf_db_access.TaskExecution.query(
            workflow_execution=str(wf_ex_db.id))[0]
        tk_ac_ex_db = ex_db_access.ActionExecution.query(
            task_execution=str(tk_ex_db.id))[0]
        tk_lv_ac_db = lv_db_access.LiveAction.get_by_id(
            tk_ac_ex_db.liveaction["id"])
        self.assertEqual(tk_lv_ac_db.status,
                         ac_const.LIVEACTION_STATUS_SUCCEEDED)

        # Manually handle action execution completion for task1 which has an error in publish.
        wf_svc.handle_action_execution_completion(tk_ac_ex_db)

        # Assert task1 succeeded but workflow failed.
        tk_ex_db = wf_db_access.TaskExecution.get_by_id(tk_ex_db.id)
        self.assertEqual(tk_ex_db.status, wf_statuses.SUCCEEDED)
        wf_ex_db = wf_db_access.WorkflowExecution.get_by_id(wf_ex_db.id)
        self.assertEqual(wf_ex_db.status, wf_statuses.FAILED)
        self.assertListEqual(self.sort_workflow_errors(wf_ex_db.errors),
                             expected_errors)

        lv_ac_db = lv_db_access.LiveAction.get_by_id(str(lv_ac_db.id))
        self.assertEqual(lv_ac_db.status, ac_const.LIVEACTION_STATUS_FAILED)
        self.assertDictEqual(lv_ac_db.result, expected_result)

        ac_ex_db = ex_db_access.ActionExecution.get_by_id(str(ac_ex_db.id))
        self.assertEqual(ac_ex_db.status, ac_const.LIVEACTION_STATUS_FAILED)
        self.assertDictEqual(ac_ex_db.result, expected_result)
Пример #5
0
    def test_runtime_context(self):
        wf_meta = base.get_wf_fixture_meta_data(TEST_PACK_PATH, "runtime-context.yaml")
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta["name"])
        lv_ac_db, ac_ex_db = ac_svc.request(lv_ac_db)
        lv_ac_db = lv_db_access.LiveAction.get_by_id(str(lv_ac_db.id))
        self.assertEqual(
            lv_ac_db.status, ac_const.LIVEACTION_STATUS_RUNNING, lv_ac_db.result
        )

        # Identify the records for the workflow.
        wf_ex_db = wf_db_access.WorkflowExecution.query(
            action_execution=str(ac_ex_db.id)
        )[0]
        t1_ex_db = wf_db_access.TaskExecution.query(
            workflow_execution=str(wf_ex_db.id)
        )[0]
        t1_ac_ex_db = ex_db_access.ActionExecution.query(
            task_execution=str(t1_ex_db.id)
        )[0]

        # Complete the worklfow.
        wf_svc.handle_action_execution_completion(t1_ac_ex_db)
        t1_ex_db = wf_db_access.TaskExecution.get_by_id(str(t1_ex_db.id))
        wf_ex_db = wf_db_access.WorkflowExecution.get_by_id(str(wf_ex_db.id))
        lv_ac_db = lv_db_access.LiveAction.get_by_id(str(lv_ac_db.id))
        self.assertEqual(t1_ex_db.status, wf_statuses.SUCCEEDED)
        self.assertEqual(wf_ex_db.status, wf_statuses.SUCCEEDED)
        self.assertEqual(lv_ac_db.status, ac_const.LIVEACTION_STATUS_SUCCEEDED)

        # Check result.
        expected_st2_ctx = {
            "action_execution_id": str(ac_ex_db.id),
            "api_url": "http://127.0.0.1/v1",
            "user": "******",
            "pack": "orquesta_tests",
            "action": "orquesta_tests.runtime-context",
            "runner": "orquesta",
        }

        expected_st2_ctx_with_wf_ex_id = copy.deepcopy(expected_st2_ctx)
        expected_st2_ctx_with_wf_ex_id["workflow_execution_id"] = str(wf_ex_db.id)

        expected_output = {
            "st2_ctx_at_input": expected_st2_ctx,
            "st2_ctx_at_vars": expected_st2_ctx,
            "st2_ctx_at_publish": expected_st2_ctx_with_wf_ex_id,
            "st2_ctx_at_output": expected_st2_ctx_with_wf_ex_id,
        }

        expected_result = {"output": expected_output}

        self.assertDictEqual(lv_ac_db.result, expected_result)
Пример #6
0
    def test_request_wf_def_with_unregistered_action(self):
        wf_meta = self.get_wf_fixture_meta_data(
            TEST_PACK_PATH, 'fail-inspection-action-db.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)

        # Exception is expected on request of workflow execution.
        self.assertRaises(orquesta_exc.WorkflowInspectionError,
                          workflow_service.request,
                          self.get_wf_def(TEST_PACK_PATH, wf_meta), ac_ex_db,
                          self.mock_st2_context(ac_ex_db))
Пример #7
0
    def test_no_notify(self):
        wf_meta = base.get_wf_fixture_meta_data(TEST_PACK_PATH, 'sequential.yaml')
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta['name'])
        lv_ac_db, ac_ex_db = action_service.request(lv_ac_db)

        # Assert action execution is running.
        lv_ac_db = lv_db_access.LiveAction.get_by_id(str(lv_ac_db.id))
        self.assertEqual(lv_ac_db.status, action_constants.LIVEACTION_STATUS_RUNNING)
        wf_ex_db = wf_db_access.WorkflowExecution.query(action_execution=str(ac_ex_db.id))[0]
        self.assertEqual(wf_ex_db.status, action_constants.LIVEACTION_STATUS_RUNNING)

        # Check that notify is setup correctly in the db record.
        self.assertDictEqual(wf_ex_db.notify, {})
Пример #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,
        )
Пример #9
0
    def test_cancel(self):
        wf_meta = base.get_wf_fixture_meta_data(TEST_PACK_PATH,
                                                'sequential.yaml')
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta['name'])
        lv_ac_db, ac_ex_db = ac_svc.request(lv_ac_db)
        lv_ac_db = lv_db_access.LiveAction.get_by_id(str(lv_ac_db.id))
        self.assertEqual(lv_ac_db.status, ac_const.LIVEACTION_STATUS_RUNNING,
                         lv_ac_db.result)

        requester = cfg.CONF.system_user.user
        lv_ac_db, ac_ex_db = ac_svc.request_cancellation(lv_ac_db, requester)
        lv_ac_db = lv_db_access.LiveAction.get_by_id(str(lv_ac_db.id))
        self.assertEqual(lv_ac_db.status, ac_const.LIVEACTION_STATUS_CANCELING)
Пример #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_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)
Пример #11
0
    def _execute_workflow(self, wf_name, expected_task_sequence, expected_output,
                          expected_status=wf_statuses.SUCCEEDED, expected_errors=None):
        wf_file = wf_name + '.yaml'
        wf_meta = base.get_wf_fixture_meta_data(TEST_PACK_PATH, wf_file)
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta['name'])
        lv_ac_db, ac_ex_db = ac_svc.request(lv_ac_db)

        # Assert action execution is running.
        lv_ac_db = lv_db_access.LiveAction.get_by_id(str(lv_ac_db.id))
        self.assertEqual(lv_ac_db.status, ac_const.LIVEACTION_STATUS_RUNNING, lv_ac_db.result)
        wf_ex_db = wf_db_access.WorkflowExecution.query(action_execution=str(ac_ex_db.id))[0]
        self.assertEqual(wf_ex_db.status, ac_const.LIVEACTION_STATUS_RUNNING)

        for task_id, route in expected_task_sequence:
            tk_ex_dbs = wf_db_access.TaskExecution.query(
                workflow_execution=str(wf_ex_db.id),
                task_id=task_id,
                task_route=route
            )

            if len(tk_ex_dbs) <= 0:
                break

            tk_ex_db = sorted(tk_ex_dbs, key=lambda x: x.start_timestamp)[len(tk_ex_dbs) - 1]
            tk_ac_ex_db = ex_db_access.ActionExecution.query(task_execution=str(tk_ex_db.id))[0]
            tk_lv_ac_db = lv_db_access.LiveAction.get_by_id(tk_ac_ex_db.liveaction['id'])

            self.assertEqual(tk_lv_ac_db.status, ac_const.LIVEACTION_STATUS_SUCCEEDED)
            self.assertTrue(wf_svc.is_action_execution_under_workflow_context(tk_ac_ex_db))

            wf_svc.handle_action_execution_completion(tk_ac_ex_db)

        # Assert workflow is completed.
        wf_ex_db = wf_db_access.WorkflowExecution.get_by_id(wf_ex_db.id)
        self.assertEqual(wf_ex_db.status, expected_status)
        lv_ac_db = lv_db_access.LiveAction.get_by_id(str(lv_ac_db.id))
        self.assertEqual(lv_ac_db.status, expected_status)
        ac_ex_db = ex_db_access.ActionExecution.get_by_id(str(ac_ex_db.id))
        self.assertEqual(ac_ex_db.status, expected_status)

        # Check workflow output, liveaction result, and action execution result.
        expected_result = {'output': expected_output}

        if expected_errors is not None:
            expected_result['errors'] = expected_errors

        if expected_output is not None:
            self.assertDictEqual(wf_ex_db.output, expected_output)

        self.assertDictEqual(lv_ac_db.result, expected_result)
        self.assertDictEqual(ac_ex_db.result, expected_result)
Пример #12
0
    def test_fail_incorrect_output_schema(self):
        wf_meta = base.get_wf_fixture_meta_data(
            TEST_PACK_PATH, "sequential_with_broken_schema.yaml"
        )
        wf_input = {"who": "Thanos"}
        lv_ac_db = lv_db_models.LiveActionDB(
            action=wf_meta["name"], parameters=wf_input
        )
        lv_ac_db, ac_ex_db = ac_svc.request(lv_ac_db)
        lv_ac_db = lv_db_access.LiveAction.get_by_id(str(lv_ac_db.id))
        wf_ex_dbs = wf_db_access.WorkflowExecution.query(
            action_execution=str(ac_ex_db.id)
        )
        wf_ex_db = wf_ex_dbs[0]
        query_filters = {"workflow_execution": str(wf_ex_db.id), "task_id": "task1"}
        tk1_ex_db = wf_db_access.TaskExecution.query(**query_filters)[0]
        tk1_ac_ex_db = ex_db_access.ActionExecution.query(
            task_execution=str(tk1_ex_db.id)
        )[0]
        wf_svc.handle_action_execution_completion(tk1_ac_ex_db)
        tk1_ex_db = wf_db_access.TaskExecution.get_by_id(tk1_ex_db.id)
        wf_ex_db = wf_db_access.WorkflowExecution.get_by_id(wf_ex_db.id)
        query_filters = {"workflow_execution": str(wf_ex_db.id), "task_id": "task2"}
        tk2_ex_db = wf_db_access.TaskExecution.query(**query_filters)[0]
        tk2_ac_ex_db = ex_db_access.ActionExecution.query(
            task_execution=str(tk2_ex_db.id)
        )[0]
        wf_svc.handle_action_execution_completion(tk2_ac_ex_db)
        tk2_ex_db = wf_db_access.TaskExecution.get_by_id(tk2_ex_db.id)
        wf_ex_db = wf_db_access.WorkflowExecution.get_by_id(wf_ex_db.id)
        query_filters = {"workflow_execution": str(wf_ex_db.id), "task_id": "task3"}
        tk3_ex_db = wf_db_access.TaskExecution.query(**query_filters)[0]
        tk3_ac_ex_db = ex_db_access.ActionExecution.query(
            task_execution=str(tk3_ex_db.id)
        )[0]
        wf_svc.handle_action_execution_completion(tk3_ac_ex_db)
        wf_ex_db = wf_db_access.WorkflowExecution.get_by_id(wf_ex_db.id)
        lv_ac_db = lv_db_access.LiveAction.get_by_id(str(lv_ac_db.id))
        ac_ex_db = ex_db_access.ActionExecution.get_by_id(str(ac_ex_db.id))

        self.assertEqual(lv_ac_db.status, ac_const.LIVEACTION_STATUS_FAILED)
        self.assertEqual(ac_ex_db.status, ac_const.LIVEACTION_STATUS_FAILED)

        expected_result = {
            "error": "Additional properties are not allowed",
            "message": "Error validating output. See error output for more details.",
        }

        self.assertIn(expected_result["error"], ac_ex_db.result["error"])
        self.assertEqual(expected_result["message"], ac_ex_db.result["message"])
Пример #13
0
    def test_notify_task_list_item_value(self):
        wf_meta = base.get_wf_fixture_meta_data(TEST_PACK_PATH, "sequential.yaml")
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta["name"])
        lv_ac_db.notify = notify_api_models.NotificationsHelper.to_model(MOCK_NOTIFY)

        expected_schema_success_test_cases = [[], ["task1"], ["task1", "task2"]]

        for notify_tasks in expected_schema_success_test_cases:
            lv_ac_db.parameters = {"notify": notify_tasks}
            lv_ac_db, ac_ex_db = action_service.request(lv_ac_db)
            lv_ac_db = lv_db_access.LiveAction.get_by_id(str(lv_ac_db.id))
            self.assertEqual(
                lv_ac_db.status, action_constants.LIVEACTION_STATUS_RUNNING
            )
Пример #14
0
    def test_process_error_handling(self):
        expected_errors = [
            {
                "message": "Execution failed. See result for details.",
                "type": "error",
                "task_id": "task1",
            },
            {
                "type": "error",
                "message": "ToozConnectionError: foobar",
                "task_id": "task1",
                "route": 0,
            },
        ]

        wf_meta = self.get_wf_fixture_meta_data(TEST_PACK_PATH,
                                                "sequential.yaml")
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta["name"])
        lv_ac_db, ac_ex_db = action_service.request(lv_ac_db)

        # Assert action execution is running.
        lv_ac_db = lv_db_access.LiveAction.get_by_id(str(lv_ac_db.id))
        self.assertEqual(lv_ac_db.status,
                         action_constants.LIVEACTION_STATUS_RUNNING)
        wf_ex_db = wf_db_access.WorkflowExecution.query(
            action_execution=str(ac_ex_db.id))[0]
        self.assertEqual(wf_ex_db.status,
                         action_constants.LIVEACTION_STATUS_RUNNING)

        # Process task1.
        query_filters = {
            "workflow_execution": str(wf_ex_db.id),
            "task_id": "task1"
        }
        t1_ex_db = wf_db_access.TaskExecution.query(**query_filters)[0]
        t1_ac_ex_db = ex_db_access.ActionExecution.query(
            task_execution=str(t1_ex_db.id))[0]
        workflows.get_engine().process(t1_ac_ex_db)

        # Assert the task is marked as failed.
        t1_ex_db = wf_db_access.TaskExecution.get_by_id(str(t1_ex_db.id))
        self.assertEqual(t1_ex_db.status, wf_statuses.FAILED)

        # Assert the workflow has failed with expected errors.
        wf_ex_db = wf_db_access.WorkflowExecution.get_by_id(wf_ex_db.id)
        self.assertEqual(wf_ex_db.status, wf_statuses.FAILED)
        self.assertListEqual(wf_ex_db.errors, expected_errors)
        lv_ac_db = lv_db_access.LiveAction.get_by_id(str(lv_ac_db.id))
        self.assertEqual(lv_ac_db.status,
                         action_constants.LIVEACTION_STATUS_FAILED)
    def test_fail_inspection(self):
        wf_meta = base.get_wf_fixture_meta_data(TEST_PACK_PATH, 'fail-inspection.yaml')
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta['name'])
        lv_ac_db, ac_ex_db = ac_svc.request(lv_ac_db)
        lv_ac_db = lv_db_access.LiveAction.get_by_id(str(lv_ac_db.id))

        self.assertEqual(lv_ac_db.status, ac_const.LIVEACTION_STATUS_FAILED)
        self.assertIn('errors', lv_ac_db.result)
        self.assertIn('expressions', lv_ac_db.result['errors'])
        self.assertGreater(len(lv_ac_db.result['errors']['expressions']), 0)
        self.assertIn('context', lv_ac_db.result['errors'])
        self.assertGreater(len(lv_ac_db.result['errors']['context']), 0)
        self.assertIn('syntax', lv_ac_db.result['errors'])
        self.assertGreater(len(lv_ac_db.result['errors']['syntax']), 0)
Пример #16
0
    def test_cancel_subworkflow_cascade_up_to_workflow(self):
        wf_meta = base.get_wf_fixture_meta_data(TEST_PACK_PATH,
                                                'subworkflow.yaml')
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta['name'])
        lv_ac_db, ac_ex_db = ac_svc.request(lv_ac_db)
        lv_ac_db = lv_db_access.LiveAction.get_by_id(str(lv_ac_db.id))
        self.assertEqual(lv_ac_db.status, ac_const.LIVEACTION_STATUS_RUNNING,
                         lv_ac_db.result)

        # Identify the records for the subworkflow.
        wf_ex_dbs = wf_db_access.WorkflowExecution.query(
            action_execution=str(ac_ex_db.id))
        self.assertEqual(len(wf_ex_dbs), 1)

        tk_ex_dbs = wf_db_access.TaskExecution.query(
            workflow_execution=str(wf_ex_dbs[0].id))
        self.assertEqual(len(tk_ex_dbs), 1)

        tk_ac_ex_dbs = ex_db_access.ActionExecution.query(
            task_execution=str(tk_ex_dbs[0].id))
        self.assertEqual(len(tk_ac_ex_dbs), 1)

        tk_lv_ac_db = lv_db_access.LiveAction.get_by_id(
            tk_ac_ex_dbs[0].liveaction['id'])
        self.assertEqual(tk_lv_ac_db.status,
                         ac_const.LIVEACTION_STATUS_RUNNING)

        # Cancel the subworkflow.
        requester = cfg.CONF.system_user.user
        tk_lv_ac_db, tk_ac_ex_db = ac_svc.request_cancellation(
            tk_lv_ac_db, requester)
        self.assertEqual(tk_lv_ac_db.status,
                         ac_const.LIVEACTION_STATUS_CANCELING)

        # Assert the subworkflow is canceled.
        tk_lv_ac_db = lv_db_access.LiveAction.get_by_id(str(tk_lv_ac_db.id))
        self.assertEqual(tk_lv_ac_db.status,
                         ac_const.LIVEACTION_STATUS_CANCELED)

        # Manually handle action execution completion for the task.
        tk_ac_ex_db = ex_db_access.ActionExecution.get_by_id(
            str(tk_ac_ex_db.id))
        self.assertEqual(tk_ac_ex_db.status,
                         ac_const.LIVEACTION_STATUS_CANCELED)
        wf_svc.handle_action_execution_completion(tk_ac_ex_db)

        # Assert the main workflow is canceled.
        lv_ac_db = lv_db_access.LiveAction.get_by_id(str(lv_ac_db.id))
        self.assertEqual(lv_ac_db.status, ac_const.LIVEACTION_STATUS_CANCELED)
Пример #17
0
    def test_fail_inspection(self):
        expected_errors = [{
            'type': 'content',
            'message':
            'The action "std.noop" is not registered in the database.',
            'schema_path':
            'properties.tasks.patternProperties.^\w+$.properties.action',
            'spec_path': 'tasks.task3.action'
        }, {
            'type': 'context',
            'language': 'yaql',
            'expression': '<% ctx().foobar %>',
            'message': 'Variable "foobar" is referenced before assignment.',
            'schema_path':
            'properties.tasks.patternProperties.^\w+$.properties.input',
            'spec_path': 'tasks.task1.input',
        }, {
            'type':
            'expression',
            'language':
            'yaql',
            'expression':
            '<% <% succeeded() %>',
            'message': ('Parse error: unexpected \'<\' at '
                        'position 0 of expression \'<% succeeded()\''),
            'schema_path': ('properties.tasks.patternProperties.^\w+$.'
                            'properties.next.items.properties.when'),
            'spec_path':
            'tasks.task2.next[0].when'
        }, {
            'type':
            'syntax',
            'message': ('[{\'cmd\': \'echo <% ctx().macro %>\'}] is '
                        'not valid under any of the given schemas'),
            'schema_path':
            'properties.tasks.patternProperties.^\w+$.properties.input.oneOf',
            'spec_path':
            'tasks.task2.input'
        }]

        wf_meta = base.get_wf_fixture_meta_data(TEST_PACK_PATH,
                                                'fail-inspection.yaml')
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta['name'])
        lv_ac_db, ac_ex_db = ac_svc.request(lv_ac_db)
        lv_ac_db = lv_db_access.LiveAction.get_by_id(str(lv_ac_db.id))

        self.assertEqual(lv_ac_db.status, ac_const.LIVEACTION_STATUS_FAILED)
        self.assertIn('errors', lv_ac_db.result)
        self.assertListEqual(lv_ac_db.result['errors'], expected_errors)
Пример #18
0
    def test_fail_manually(self):
        wf_meta = base.get_wf_fixture_meta_data(TEST_PACK_PATH, 'fail-manually.yaml')
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta['name'])
        lv_ac_db, ac_ex_db = ac_svc.request(lv_ac_db)
        wf_ex_db = wf_db_access.WorkflowExecution.query(action_execution=str(ac_ex_db.id))[0]

        # Assert task1 and workflow execution failed due to fail in the task transition.
        query_filters = {'workflow_execution': str(wf_ex_db.id), 'task_id': 'task1'}
        tk1_ex_db = wf_db_access.TaskExecution.query(**query_filters)[0]
        tk1_ac_ex_db = ex_db_access.ActionExecution.query(task_execution=str(tk1_ex_db.id))[0]
        tk1_lv_ac_db = lv_db_access.LiveAction.get_by_id(tk1_ac_ex_db.liveaction['id'])
        self.assertEqual(tk1_lv_ac_db.status, ac_const.LIVEACTION_STATUS_FAILED)
        wf_svc.handle_action_execution_completion(tk1_ac_ex_db)
        wf_ex_db = wf_db_access.WorkflowExecution.get_by_id(wf_ex_db.id)
        self.assertEqual(wf_ex_db.status, wf_statuses.FAILED)

        # Assert log task is scheduled even though the workflow execution failed manually.
        query_filters = {'workflow_execution': str(wf_ex_db.id), 'task_id': 'log'}
        tk2_ex_db = wf_db_access.TaskExecution.query(**query_filters)[0]
        tk2_ac_ex_db = ex_db_access.ActionExecution.query(task_execution=str(tk2_ex_db.id))[0]
        tk2_lv_ac_db = lv_db_access.LiveAction.get_by_id(tk2_ac_ex_db.liveaction['id'])
        self.assertEqual(tk2_lv_ac_db.status, ac_const.LIVEACTION_STATUS_SUCCEEDED)
        wf_svc.handle_action_execution_completion(tk2_ac_ex_db)
        wf_ex_db = wf_db_access.WorkflowExecution.get_by_id(wf_ex_db.id)
        self.assertEqual(wf_ex_db.status, wf_statuses.FAILED)

        # Check errors and output.
        expected_errors = [
            {
                'task_id': 'fail',
                'type': 'error',
                'message': 'Execution failed. See result for details.'
            },
            {
                'task_id': 'task1',
                'type': 'error',
                'message': 'Execution failed. See result for details.',
                'result': {
                    'failed': True,
                    'return_code': 1,
                    'stderr': '',
                    'stdout': '',
                    'succeeded': False
                }
            }
        ]

        self.assertListEqual(self.sort_workflow_errors(wf_ex_db.errors), expected_errors)
Пример #19
0
    def test_with_items_failure(self):
        num_items = 10

        wf_meta = base.get_wf_fixture_meta_data(TEST_PACK_PATH,
                                                'with-items-failure.yaml')
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta['name'])
        lv_ac_db, ac_ex_db = action_service.request(lv_ac_db)

        # Assert action execution is running.
        lv_ac_db = lv_db_access.LiveAction.get_by_id(str(lv_ac_db.id))
        self.assertEqual(lv_ac_db.status,
                         action_constants.LIVEACTION_STATUS_RUNNING)
        wf_ex_db = wf_db_access.WorkflowExecution.query(
            action_execution=str(ac_ex_db.id))[0]
        self.assertEqual(wf_ex_db.status,
                         action_constants.LIVEACTION_STATUS_RUNNING)

        # Process the with items task.
        query_filters = {
            'workflow_execution': str(wf_ex_db.id),
            'task_id': 'task1'
        }
        t1_ex_db = wf_db_access.TaskExecution.query(**query_filters)[0]
        t1_ac_ex_dbs = ex_db_access.ActionExecution.query(
            task_execution=str(t1_ex_db.id))

        self.assertEqual(len(t1_ac_ex_dbs), num_items)

        for i in range(0, num_items):
            if not i % 2:
                expected_status = action_constants.LIVEACTION_STATUS_SUCCEEDED
            else:
                expected_status = action_constants.LIVEACTION_STATUS_FAILED

            self.assertEqual(t1_ac_ex_dbs[i].status, expected_status)

        for t1_ac_ex_db in t1_ac_ex_dbs:
            workflows.get_engine().process(t1_ac_ex_db)

        t1_ex_db = wf_db_access.TaskExecution.get_by_id(t1_ex_db.id)
        self.assertEqual(t1_ex_db.status, wf_statuses.FAILED)

        # Assert the main workflow is completed.
        wf_ex_db = wf_db_access.WorkflowExecution.get_by_id(wf_ex_db.id)
        self.assertEqual(wf_ex_db.status, wf_statuses.FAILED)
        lv_ac_db = lv_db_access.LiveAction.get_by_id(str(lv_ac_db.id))
        self.assertEqual(lv_ac_db.status,
                         action_constants.LIVEACTION_STATUS_FAILED)
Пример #20
0
    def test_runtime_context(self):
        wf_meta = base.get_wf_fixture_meta_data(TEST_PACK_PATH,
                                                'runtime-context.yaml')
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta['name'])
        lv_ac_db, ac_ex_db = ac_svc.request(lv_ac_db)
        lv_ac_db = lv_db_access.LiveAction.get_by_id(str(lv_ac_db.id))
        self.assertEqual(lv_ac_db.status, ac_const.LIVEACTION_STATUS_RUNNING,
                         lv_ac_db.result)

        # Identify the records for the workflow.
        wf_ex_db = wf_db_access.WorkflowExecution.query(
            action_execution=str(ac_ex_db.id))[0]
        t1_ex_db = wf_db_access.TaskExecution.query(
            workflow_execution=str(wf_ex_db.id))[0]
        t1_ac_ex_db = ex_db_access.ActionExecution.query(
            task_execution=str(t1_ex_db.id))[0]

        # Complete the worklfow.
        wf_svc.handle_action_execution_completion(t1_ac_ex_db)
        t1_ex_db = wf_db_access.TaskExecution.get_by_id(str(t1_ex_db.id))
        wf_ex_db = wf_db_access.WorkflowExecution.get_by_id(str(wf_ex_db.id))
        lv_ac_db = lv_db_access.LiveAction.get_by_id(str(lv_ac_db.id))
        self.assertEqual(t1_ex_db.status, wf_statuses.SUCCEEDED)
        self.assertEqual(wf_ex_db.status, wf_statuses.SUCCEEDED)
        self.assertEqual(lv_ac_db.status, ac_const.LIVEACTION_STATUS_SUCCEEDED)

        # Check result.
        expected_st2_ctx = {
            'action_execution_id': str(ac_ex_db.id),
            'api_url': 'http://127.0.0.1/v1',
            'user': '******',
            'pack': 'orquesta_tests'
        }

        expected_st2_ctx_with_wf_ex_id = copy.deepcopy(expected_st2_ctx)
        expected_st2_ctx_with_wf_ex_id['workflow_execution_id'] = str(
            wf_ex_db.id)

        expected_output = {
            'st2_ctx_at_input': expected_st2_ctx,
            'st2_ctx_at_vars': expected_st2_ctx,
            'st2_ctx_at_publish': expected_st2_ctx_with_wf_ex_id,
            'st2_ctx_at_output': expected_st2_ctx_with_wf_ex_id
        }

        expected_result = {'output': expected_output}

        self.assertDictEqual(lv_ac_db.result, expected_result)
Пример #21
0
    def test_process_error_handling_has_error(self):
        wf_meta = self.get_wf_fixture_meta_data(TEST_PACK_PATH,
                                                'sequential.yaml')
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta['name'])
        lv_ac_db, ac_ex_db = action_service.request(lv_ac_db)

        # Assert action execution is running.
        lv_ac_db = lv_db_access.LiveAction.get_by_id(str(lv_ac_db.id))
        self.assertEqual(lv_ac_db.status,
                         action_constants.LIVEACTION_STATUS_RUNNING)
        wf_ex_db = wf_db_access.WorkflowExecution.query(
            action_execution=str(ac_ex_db.id))[0]
        self.assertEqual(wf_ex_db.status,
                         action_constants.LIVEACTION_STATUS_RUNNING)

        # Process task1.
        query_filters = {
            'workflow_execution': str(wf_ex_db.id),
            'task_id': 'task1'
        }
        t1_ex_db = wf_db_access.TaskExecution.query(**query_filters)[0]
        t1_ac_ex_db = ex_db_access.ActionExecution.query(
            task_execution=str(t1_ex_db.id))[0]

        self.assertRaisesRegexp(Exception, 'Unexpected error.',
                                workflows.get_engine().process, t1_ac_ex_db)

        self.assertTrue(
            workflows.WorkflowExecutionHandler.fail_workflow_execution.called)

        # Since error handling failed, the workflow will have status of running.
        wf_ex_db = wf_db_access.WorkflowExecution.get_by_id(wf_ex_db.id)
        self.assertEqual(wf_ex_db.status, wf_statuses.RUNNING)
        lv_ac_db = lv_db_access.LiveAction.get_by_id(str(lv_ac_db.id))
        self.assertEqual(lv_ac_db.status,
                         action_constants.LIVEACTION_STATUS_RUNNING)

        # Sleep up to the test config gc_max_idle_sec before running gc.
        eventlet.sleep(cfg.CONF.workflow_engine.gc_max_idle_sec)

        # Run garbage collection.
        gc = garbage_collector.GarbageCollectorService()
        gc._purge_orphaned_workflow_executions()

        # Assert workflow execution is cleaned up and canceled.
        lv_ac_db = lv_db_access.LiveAction.get_by_id(str(lv_ac_db.id))
        self.assertEqual(lv_ac_db.status,
                         action_constants.LIVEACTION_STATUS_CANCELED)
Пример #22
0
    def test_fail_task_transition(self):
        expected_errors = [{
            'message':
            ("Unable to resolve key 'foobar' in expression "
             "'<% succeeded() and result().foobar %>' from context."),
            'task_transition_id':
            'task2__0',
            'task_id':
            'task1'
        }]

        expected_result = {'output': None, 'errors': expected_errors}

        wf_meta = base.get_wf_fixture_meta_data(TEST_PACK_PATH,
                                                'fail-task-transition.yaml')
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta['name'])
        lv_ac_db, ac_ex_db = ac_svc.request(lv_ac_db)

        # Assert task1 is already completed.
        wf_ex_db = wf_db_access.WorkflowExecution.query(
            action_execution=str(ac_ex_db.id))[0]
        tk_ex_db = wf_db_access.TaskExecution.query(
            workflow_execution=str(wf_ex_db.id))[0]
        tk_ac_ex_db = ex_db_access.ActionExecution.query(
            task_execution=str(tk_ex_db.id))[0]
        tk_lv_ac_db = lv_db_access.LiveAction.get_by_id(
            tk_ac_ex_db.liveaction['id'])
        self.assertEqual(tk_lv_ac_db.status,
                         ac_const.LIVEACTION_STATUS_SUCCEEDED)

        # Manually handle action execution completion for task1 which has an error in publish.
        wf_svc.handle_action_execution_completion(tk_ac_ex_db)

        # Assert task1 succeeded but workflow failed.
        tk_ex_db = wf_db_access.TaskExecution.get_by_id(tk_ex_db.id)
        self.assertEqual(tk_ex_db.status, wf_states.SUCCEEDED)
        wf_ex_db = wf_db_access.WorkflowExecution.get_by_id(wf_ex_db.id)
        self.assertEqual(wf_ex_db.status, wf_states.FAILED)
        self.assertListEqual(self.sort_wf_runtime_errors(wf_ex_db.errors),
                             expected_errors)

        lv_ac_db = lv_db_access.LiveAction.get_by_id(str(lv_ac_db.id))
        self.assertEqual(lv_ac_db.status, ac_const.LIVEACTION_STATUS_FAILED)
        self.assertDictEqual(lv_ac_db.result, expected_result)

        ac_ex_db = ex_db_access.ActionExecution.get_by_id(str(ac_ex_db.id))
        self.assertEqual(ac_ex_db.status, ac_const.LIVEACTION_STATUS_FAILED)
        self.assertDictEqual(ac_ex_db.result, expected_result)
Пример #23
0
    def test_cancel_before_wf_ex_db_created(self):
        wf_meta = base.get_wf_fixture_meta_data(TEST_PACK_PATH, 'sequential.yaml')
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta['name'])
        lv_ac_db, ac_ex_db = ac_svc.request(lv_ac_db)
        lv_ac_db = lv_db_access.LiveAction.get_by_id(str(lv_ac_db.id))
        self.assertEqual(lv_ac_db.status, ac_const.LIVEACTION_STATUS_RUNNING, lv_ac_db.result)

        # Delete the workfow execution to mock issue where the record has not been created yet.
        wf_ex_db = wf_db_access.WorkflowExecution.query(action_execution=str(ac_ex_db.id))[0]
        wf_db_access.WorkflowExecution.delete(wf_ex_db, publish=False, dispatch_trigger=False)

        # Cancel the action execution.
        requester = cfg.CONF.system_user.user
        lv_ac_db, ac_ex_db = ac_svc.request_cancellation(lv_ac_db, requester)
        lv_ac_db = lv_db_access.LiveAction.get_by_id(str(lv_ac_db.id))
        self.assertEqual(lv_ac_db.status, ac_const.LIVEACTION_STATUS_CANCELED)
Пример #24
0
    def test_with_items(self):
        num_items = 3

        wf_meta = base.get_wf_fixture_meta_data(TEST_PACK_PATH,
                                                "with-items.yaml")
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta["name"])
        lv_ac_db, ac_ex_db = action_service.request(lv_ac_db)

        # Assert action execution is running.
        lv_ac_db = lv_db_access.LiveAction.get_by_id(str(lv_ac_db.id))
        self.assertEqual(lv_ac_db.status,
                         action_constants.LIVEACTION_STATUS_RUNNING)
        wf_ex_db = wf_db_access.WorkflowExecution.query(
            action_execution=str(ac_ex_db.id))[0]
        self.assertEqual(wf_ex_db.status,
                         action_constants.LIVEACTION_STATUS_RUNNING)

        # Process the with items task.
        query_filters = {
            "workflow_execution": str(wf_ex_db.id),
            "task_id": "task1"
        }
        t1_ex_db = wf_db_access.TaskExecution.query(**query_filters)[0]
        t1_ac_ex_dbs = ex_db_access.ActionExecution.query(
            task_execution=str(t1_ex_db.id))

        self.assertEqual(len(t1_ac_ex_dbs), num_items)

        status = [
            ac_ex.status == action_constants.LIVEACTION_STATUS_SUCCEEDED
            for ac_ex in t1_ac_ex_dbs
        ]

        self.assertTrue(all(status))

        for t1_ac_ex_db in t1_ac_ex_dbs:
            workflows.get_engine().process(t1_ac_ex_db)

        t1_ex_db = wf_db_access.TaskExecution.get_by_id(t1_ex_db.id)
        self.assertEqual(t1_ex_db.status, wf_statuses.SUCCEEDED)

        # Assert the main workflow is completed.
        wf_ex_db = wf_db_access.WorkflowExecution.get_by_id(wf_ex_db.id)
        self.assertEqual(wf_ex_db.status, wf_statuses.SUCCEEDED)
        lv_ac_db = lv_db_access.LiveAction.get_by_id(str(lv_ac_db.id))
        self.assertEqual(lv_ac_db.status,
                         action_constants.LIVEACTION_STATUS_SUCCEEDED)
Пример #25
0
    def test_fail_task_execution(self):
        expected_errors = [{
            "type": "error",
            "message": "Execution failed. See result for details.",
            "task_id": "task1",
            "result": {
                "stdout": "",
                "stderr": "boom!",
                "return_code": 1,
                "failed": True,
                "succeeded": False,
            },
        }]

        expected_result = {"output": None, "errors": expected_errors}

        wf_meta = base.get_wf_fixture_meta_data(TEST_PACK_PATH,
                                                "fail-task-execution.yaml")
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta["name"])
        lv_ac_db, ac_ex_db = ac_svc.request(lv_ac_db)

        # Process task1.
        wf_ex_db = wf_db_access.WorkflowExecution.query(
            action_execution=str(ac_ex_db.id))[0]
        tk1_ex_db = wf_db_access.TaskExecution.query(
            workflow_execution=str(wf_ex_db.id))[0]
        tk1_ac_ex_db = ex_db_access.ActionExecution.query(
            task_execution=str(tk1_ex_db.id))[0]
        tk1_lv_ac_db = lv_db_access.LiveAction.get_by_id(
            tk1_ac_ex_db.liveaction["id"])
        self.assertEqual(tk1_lv_ac_db.status,
                         ac_const.LIVEACTION_STATUS_FAILED)
        wf_svc.handle_action_execution_completion(tk1_ac_ex_db)

        # Assert workflow state and result.
        wf_ex_db = wf_db_access.WorkflowExecution.get_by_id(str(wf_ex_db.id))
        self.assertEqual(wf_ex_db.status, wf_statuses.FAILED)
        self.assertListEqual(self.sort_workflow_errors(wf_ex_db.errors),
                             expected_errors)

        lv_ac_db = lv_db_access.LiveAction.get_by_id(str(lv_ac_db.id))
        self.assertEqual(lv_ac_db.status, ac_const.LIVEACTION_STATUS_FAILED)
        self.assertDictEqual(lv_ac_db.result, expected_result)

        ac_ex_db = ex_db_access.ActionExecution.get_by_id(str(ac_ex_db.id))
        self.assertEqual(ac_ex_db.status, ac_const.LIVEACTION_STATUS_FAILED)
        self.assertDictEqual(ac_ex_db.result, expected_result)
Пример #26
0
    def test_fail_task_execution(self):
        expected_errors = [{
            'type': 'error',
            'message': 'Execution failed. See result for details.',
            'task_id': 'task1',
            'result': {
                'stdout': '',
                'stderr': 'boom!',
                'return_code': 1,
                'failed': True,
                'succeeded': False
            }
        }]

        expected_result = {'output': None, 'errors': expected_errors}

        wf_meta = base.get_wf_fixture_meta_data(TEST_PACK_PATH,
                                                'fail-task-execution.yaml')
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta['name'])
        lv_ac_db, ac_ex_db = ac_svc.request(lv_ac_db)

        # Process task1.
        wf_ex_db = wf_db_access.WorkflowExecution.query(
            action_execution=str(ac_ex_db.id))[0]
        tk1_ex_db = wf_db_access.TaskExecution.query(
            workflow_execution=str(wf_ex_db.id))[0]
        tk1_ac_ex_db = ex_db_access.ActionExecution.query(
            task_execution=str(tk1_ex_db.id))[0]
        tk1_lv_ac_db = lv_db_access.LiveAction.get_by_id(
            tk1_ac_ex_db.liveaction['id'])
        self.assertEqual(tk1_lv_ac_db.status,
                         ac_const.LIVEACTION_STATUS_FAILED)
        wf_svc.handle_action_execution_completion(tk1_ac_ex_db)

        # Assert workflow state and result.
        wf_ex_db = wf_db_access.WorkflowExecution.get_by_id(str(wf_ex_db.id))
        self.assertEqual(wf_ex_db.status, wf_statuses.FAILED)
        self.assertListEqual(self.sort_wf_runtime_errors(wf_ex_db.errors),
                             expected_errors)

        lv_ac_db = lv_db_access.LiveAction.get_by_id(str(lv_ac_db.id))
        self.assertEqual(lv_ac_db.status, ac_const.LIVEACTION_STATUS_FAILED)
        self.assertDictEqual(lv_ac_db.result, expected_result)

        ac_ex_db = ex_db_access.ActionExecution.get_by_id(str(ac_ex_db.id))
        self.assertEqual(ac_ex_db.status, ac_const.LIVEACTION_STATUS_FAILED)
        self.assertDictEqual(ac_ex_db.result, expected_result)
Пример #27
0
    def test_request_rerun_with_missing_workflow_execution_id(self):
        # Create and return a failed workflow execution.
        wf_meta, lv_ac_db1, ac_ex_db1, wf_ex_db = self.prep_wf_ex_for_rerun()

        # 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 without workflow_execution_id.
        st2_ctx = self.mock_st2_context(ac_ex_db2, ac_ex_db1.context)
        rerun_options = {'ref': str(ac_ex_db1.id), 'tasks': ['task1']}
        expected_error = ('Unable to rerun workflow execution because '
                          'workflow_execution_id is not provided.')

        self.assertRaisesRegexp(wf_exc.WorkflowExecutionRerunException,
                                expected_error, workflow_service.request_rerun,
                                ac_ex_db2, st2_ctx, rerun_options)
Пример #28
0
    def test_request_rerun_with_bad_task_name(self):
        # Create and return a failed workflow execution.
        wf_meta, lv_ac_db1, ac_ex_db1, wf_ex_db = self.prep_wf_ex_for_rerun()

        # 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.
        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': ['task5354']}
        expected_error = '^Unable to rerun workflow because one or more tasks is not found: .*$'

        self.assertRaisesRegexp(wf_exc.WorkflowExecutionRerunException,
                                expected_error, workflow_service.request_rerun,
                                ac_ex_db2, st2_ctx, rerun_options)
Пример #29
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,
        )
Пример #30
0
    def test_request_wf_def_with_missing_required_action_param(self):
        wf_name = "fail-inspection-missing-required-action-param"
        wf_meta = self.get_wf_fixture_meta_data(TEST_PACK_PATH,
                                                wf_name + ".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)

        # Exception is expected on request of workflow execution.
        self.assertRaises(
            orquesta_exc.WorkflowInspectionError,
            workflow_service.request,
            self.get_wf_def(TEST_PACK_PATH, wf_meta),
            ac_ex_db,
            self.mock_st2_context(ac_ex_db),
        )