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
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 )
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)
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)
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)
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)
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)
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)
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)
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)
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_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')
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)
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)
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)
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))
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)
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 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))
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)
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_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)
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)
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)
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)
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)
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)