コード例 #1
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)
コード例 #2
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)
コード例 #3
0
ファイル: test_workflow_rerun.py プロジェクト: st2sandbox/st2
    def test_request_rerun_again_while_prev_rerun_is_still_running(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.
        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"]}
        wf_ex_db = workflow_service.request_rerun(ac_ex_db2, st2_ctx,
                                                  rerun_options)
        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)

        # Complete task1.
        self.run_workflow_step(wf_ex_db, "task1", 0)

        # Check workflow status and make sure it is still running.
        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)
        lv_ac_db2 = lv_db_access.LiveAction.get_by_id(str(lv_ac_db2.id))
        self.assertEqual(lv_ac_db2.status,
                         action_constants.LIVEACTION_STATUS_RUNNING)
        ac_ex_db2 = ex_db_access.ActionExecution.get_by_id(str(ac_ex_db2.id))
        self.assertEqual(ac_ex_db2.status,
                         action_constants.LIVEACTION_STATUS_RUNNING)

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

        # Request workflow execution rerun again.
        st2_ctx = self.mock_st2_context(ac_ex_db3, 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_db3,
            st2_ctx,
            rerun_options,
        )
コード例 #4
0
    def process(self, wf_ex_db):
        # Refresh record from the database in case the request is in the queue for too long.
        conductor, wf_ex_db = wf_svc.refresh_conductor(str(wf_ex_db.id))

        # Continue if workflow is still active.
        if conductor.get_workflow_state() not in states.COMPLETED_STATES:
            # Set workflow to running state.
            conductor.set_workflow_state(states.RUNNING)

        # Identify the next set of tasks to execute.
        next_tasks = conductor.get_next_tasks()

        # If there is no new tasks, update execution records to handle possible completion.
        if not next_tasks:
            # Update workflow execution and related liveaction and action execution.
            wf_svc.update_execution_records(wf_ex_db, conductor)

        # If workflow execution is no longer active, then stop processing here.
        if wf_ex_db.status in states.COMPLETED_STATES:
            return

        # Iterate while there are next tasks identified for processing. In the case for
        # task with no action execution defined, the task execution will complete
        # immediately with a new set of tasks available.
        while next_tasks:
            # Mark the tasks as running in the task flow before actual task execution.
            for task in next_tasks:
                conductor.update_task_flow(task['id'], states.RUNNING)

            # Update workflow execution and related liveaction and action execution.
            wf_svc.update_execution_records(wf_ex_db, conductor)

            # If workflow execution is no longer active, then stop processing here.
            if wf_ex_db.status in states.COMPLETED_STATES:
                break

            # Request task execution for the tasks.
            for task in next_tasks:
                try:
                    task_id, task_spec, task_ctx = task['id'], task[
                        'spec'], task['ctx']
                    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)
                except Exception as e:
                    wf_svc.fail_workflow_execution(str(wf_ex_db.id),
                                                   e,
                                                   task_id=task['id'])
                    return

            # Identify the next set of tasks to execute.
            conductor, wf_ex_db = wf_svc.refresh_conductor(str(wf_ex_db.id))
            next_tasks = conductor.get_next_tasks()
コード例 #5
0
ファイル: workflows.py プロジェクト: lyandut/st2
    def process(self, wf_ex_db):
        # Refresh record from the database in case the request is in the queue for too long.
        conductor, wf_ex_db = wf_svc.refresh_conductor(str(wf_ex_db.id))

        # Continue if workflow is still active.
        if conductor.get_workflow_state() not in states.COMPLETED_STATES:
            # Set workflow to running state.
            conductor.set_workflow_state(states.RUNNING)

        # Identify the next set of tasks to execute.
        next_tasks = conductor.get_next_tasks()

        # If there is no new tasks, update execution records to handle possible completion.
        if not next_tasks:
            # Update workflow execution and related liveaction and action execution.
            wf_svc.update_execution_records(wf_ex_db, conductor)

        # If workflow execution is no longer active, then stop processing here.
        if wf_ex_db.status in states.COMPLETED_STATES:
            return

        # Iterate while there are next tasks identified for processing. In the case for
        # task with no action execution defined, the task execution will complete
        # immediately with a new set of tasks available.
        while next_tasks:
            # Mark the tasks as running in the task flow before actual task execution.
            for task in next_tasks:
                conductor.update_task_flow(task['id'], states.RUNNING)

            # Update workflow execution and related liveaction and action execution.
            wf_svc.update_execution_records(wf_ex_db, conductor)

            # If workflow execution is no longer active, then stop processing here.
            if wf_ex_db.status in states.COMPLETED_STATES:
                break

            # Request task execution for the tasks.
            for task in next_tasks:
                try:
                    task_id, task_spec, task_ctx = task['id'], task['spec'], task['ctx']
                    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)
                except Exception as e:
                    wf_svc.fail_workflow_execution(str(wf_ex_db.id), e, task_id=task['id'])
                    return

            # Identify the next set of tasks to execute.
            conductor, wf_ex_db = wf_svc.refresh_conductor(str(wf_ex_db.id))
            next_tasks = conductor.get_next_tasks()
コード例 #6
0
ファイル: test_workflow_rerun.py プロジェクト: yetudada/st2
    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
コード例 #7
0
ファイル: test_workflow_rerun.py プロジェクト: yetudada/st2
    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)
コード例 #8
0
ファイル: test_workflow_rerun.py プロジェクト: yetudada/st2
    def test_request_rerun(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.
        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']}
        wf_ex_db = workflow_service.request_rerun(ac_ex_db2, st2_ctx,
                                                  rerun_options)
        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)

        # Complete task1.
        self.run_workflow_step(wf_ex_db, 'task1', 0)

        # Check workflow status and make sure it is still running.
        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)
        lv_ac_db2 = lv_db_access.LiveAction.get_by_id(str(lv_ac_db2.id))
        self.assertEqual(lv_ac_db2.status,
                         action_constants.LIVEACTION_STATUS_RUNNING)
        ac_ex_db2 = ex_db_access.ActionExecution.get_by_id(str(ac_ex_db2.id))
        self.assertEqual(ac_ex_db2.status,
                         action_constants.LIVEACTION_STATUS_RUNNING)
コード例 #9
0
ファイル: workflows.py プロジェクト: jamal-jiang/st2
    def handle_workflow_execution(self, wf_ex_db):
        iteration = 0
        wf_ac_ex_id = wf_ex_db.action_execution
        LOG.info('[%s] Processing request for workflow execution.',
                 wf_ac_ex_id)

        # Refresh record from the database in case the request is in the queue for too long.
        conductor, wf_ex_db = wf_svc.refresh_conductor(str(wf_ex_db.id))

        # Continue if workflow is still active and set workflow to running state.
        if conductor.get_workflow_state() not in states.COMPLETED_STATES:
            LOG.info(
                '[%s] Requesting conductor to start running workflow execution.',
                wf_ac_ex_id)
            conductor.request_workflow_state(states.RUNNING)

        # Identify the next set of tasks to execute.
        msg = '[%s] Identifying next set (%s) of tasks for workflow execution in state "%s".'
        LOG.info(msg, wf_ac_ex_id, str(iteration),
                 conductor.get_workflow_state())
        LOG.debug('[%s] %s', wf_ac_ex_id, conductor.serialize())
        next_tasks = conductor.get_next_tasks()

        # If there is no new tasks, update execution records to handle possible completion.
        if not next_tasks:
            # Update workflow execution and related liveaction and action execution.
            LOG.info('[%s] No tasks identified to execute next.', wf_ac_ex_id)
            wf_svc.update_execution_records(wf_ex_db, conductor)

        # If workflow execution is no longer active, then stop processing here.
        if wf_ex_db.status in states.COMPLETED_STATES:
            msg = '[%s] Workflow execution is in completed state "%s".'
            LOG.info(msg, wf_ac_ex_id, wf_ex_db.status)
            return

        # Iterate while there are next tasks identified for processing. In the case for
        # task with no action execution defined, the task execution will complete
        # immediately with a new set of tasks available.
        while next_tasks:
            msg = '[%s] Identified the following set of tasks to execute next: %s'
            LOG.info(msg, wf_ac_ex_id,
                     ', '.join([task['id'] for task in next_tasks]))

            # Mark the tasks as running in the task flow before actual task execution.
            for task in next_tasks:
                msg = '[%s] Mark task "%s" in conductor as running.'
                LOG.info(msg, wf_ac_ex_id, task['id'])
                ac_ex_event = events.ActionExecutionEvent(states.RUNNING)
                conductor.update_task_flow(task['id'], ac_ex_event)

            # Update workflow execution and related liveaction and action execution.
            wf_svc.update_execution_records(wf_ex_db, conductor)

            # If workflow execution is no longer active, then stop processing here.
            if wf_ex_db.status in states.COMPLETED_STATES:
                msg = '[%s] Workflow execution is in completed state "%s".'
                LOG.info(msg, wf_ac_ex_id, wf_ex_db.status)
                break

            # Request task execution for the tasks.
            for task in next_tasks:
                try:
                    LOG.info('[%s] Requesting execution for task "%s".',
                             wf_ac_ex_id, task['id'])
                    task_id, task_spec, task_ctx = task['id'], task[
                        'spec'], task['ctx']
                    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)
                except Exception as e:
                    LOG.exception('[%s] Failed task execution for "%s".',
                                  wf_ac_ex_id, task['id'])
                    wf_svc.fail_workflow_execution(str(wf_ex_db.id),
                                                   e,
                                                   task_id=task['id'])
                    return

            # Identify the next set of tasks to execute.
            iteration += 1
            conductor, wf_ex_db = wf_svc.refresh_conductor(str(wf_ex_db.id))
            msg = '[%s] Identifying next set (%s) of tasks for workflow execution in state "%s".'
            LOG.info(msg, wf_ac_ex_id, str(iteration),
                     conductor.get_workflow_state())
            LOG.debug('[%s] %s', wf_ac_ex_id, conductor.serialize())
            next_tasks = conductor.get_next_tasks()

            if not next_tasks:
                LOG.info('[%s] No tasks identified to execute next.',
                         wf_ac_ex_id)