def get_model_from_ref(db_api, reference): if reference is None: raise db.StackStormDBObjectNotFoundError('No reference supplied.') model_id = reference.get('id', None) if model_id is not None: return db_api.get_by_id(model_id) model_name = reference.get('name', None) if model_name is None: raise db.StackStormDBObjectNotFoundError('Both name and id are None.') return db_api.get_by_name(model_name)
def get(self, *args, **kwargs): exclude_fields = kwargs.pop('exclude_fields', None) raise_exception = kwargs.pop('raise_exception', False) only_fields = kwargs.pop('only_fields', None) args = self._process_arg_filters(args) instances = self.model.objects(*args, **kwargs) if exclude_fields: instances = instances.exclude(*exclude_fields) if only_fields: try: instances = instances.only(*only_fields) except (mongoengine.errors.LookUpError, AttributeError) as e: msg = ( 'Invalid or unsupported include attribute specified: %s' % six.text_type(e)) raise ValueError(msg) instance = instances[0] if instances else None log_query_and_profile_data_for_queryset(queryset=instances) if not instance and raise_exception: msg = 'Unable to find the %s instance. %s' % (self.model.__name__, kwargs) raise db_exc.StackStormDBObjectNotFoundError(msg) return instance
def _get_one_by_id( self, id, requester_user, permission_type, exclude_fields=None, from_model_kwargs=None, ): """Override ResourceController._get_one_by_id to contain scope of Inquiries UID hack :param exclude_fields: A list of object fields to exclude. :type exclude_fields: ``list`` """ LOG.debug('Retrieving action execution for inquiry "%s".' % id) execution_db = self._get_by_id(resource_id=id, exclude_fields=exclude_fields) if not execution_db: raise db_exceptions.StackStormDBObjectNotFoundError() # Inquiry currently does not have it's own database model and share with ActionExecution. # The object uid is in the format of "execution:<id>". To allow RBAC to resolve correctly # for inquiries, we're overriding the "get_uid" function so the object uid can be set to # "inquiry:<id>". # # TODO (mierdin): All of this should be removed once Inquiries get their own DB model. if (execution_db and getattr(execution_db, "runner", None) and execution_db.runner.get("runner_module") == INQUIRY_RUNNER): execution_db.get_uid = get_uid LOG.debug('Checking permission on inquiry "%s".' % id) if permission_type: rbac_utils = get_rbac_backend().get_utils_class() rbac_utils.assert_user_has_resource_db_permission( user_db=requester_user, resource_db=execution_db, permission_type=permission_type, ) from_model_kwargs = from_model_kwargs or {} from_model_kwargs.update(self.from_model_kwargs) result = self.model.from_model(execution_db, **from_model_kwargs) return result
class MistralQuerierTest(DbTestCase): @classmethod def setUpClass(cls): super(MistralQuerierTest, cls).setUpClass() # Override the retry configuration here otherwise st2tests.config.parse_args # in DbTestCase.setUpClass will reset these overrides. cfg.CONF.set_override('retry_exp_msec', 100, group='mistral') cfg.CONF.set_override('retry_exp_max_msec', 200, group='mistral') cfg.CONF.set_override('retry_stop_max_msec', 200, group='mistral') # Register query module. cls.query_module = get_query_module('mistral-v2') def setUp(self): super(MistralQuerierTest, self).setUp() self.querier = self.query_module.get_instance() @mock.patch.object(ActionExecution, 'get', mock.MagicMock(side_effect=[ MOCK_ACTIONEXECUTION_RUNNING_CHILD_RUNNING, MOCK_CHILD_ACTIONEXECUTION_RUNNING ])) def test_determine_status_wf_running_exec_running_tasks_running(self): status = self.querier._determine_execution_status( MOCK_LIVEACTION_RUNNING, 'RUNNING', MOCK_WF_TASKS_RUNNING) self.assertEqual(action_constants.LIVEACTION_STATUS_RUNNING, status) @mock.patch.object(ActionExecution, 'get', mock.MagicMock(side_effect=[ MOCK_ACTIONEXECUTION_RUNNING_CHILD_SUCCEEDED, MOCK_CHILD_ACTIONEXECUTION_SUCCEEDED ])) def test_determine_status_wf_running_exec_running_tasks_completed(self): status = self.querier._determine_execution_status( MOCK_LIVEACTION_RUNNING, 'RUNNING', MOCK_WF_TASKS_SUCCEEDED) self.assertEqual(action_constants.LIVEACTION_STATUS_RUNNING, status) @mock.patch.object(ActionExecution, 'get', mock.MagicMock(side_effect=[ MOCK_ACTIONEXECUTION_RUNNING_CHILD_SUCCEEDED, MOCK_CHILD_ACTIONEXECUTION_SUCCEEDED ])) def test_determine_status_wf_running_exec_succeeded_tasks_completed(self): status = self.querier._determine_execution_status( MOCK_LIVEACTION_RUNNING, 'SUCCESS', MOCK_WF_TASKS_SUCCEEDED) self.assertEqual(action_constants.LIVEACTION_STATUS_SUCCEEDED, status) @mock.patch.object(ActionExecution, 'get', mock.MagicMock(side_effect=[ MOCK_ACTIONEXECUTION_RUNNING_CHILD_RUNNING, MOCK_CHILD_ACTIONEXECUTION_RUNNING ])) def test_determine_status_wf_running_exec_succeeded_tasks_running(self): status = self.querier._determine_execution_status( MOCK_LIVEACTION_RUNNING, 'SUCCESS', MOCK_WF_TASKS_RUNNING) self.assertEqual(action_constants.LIVEACTION_STATUS_RUNNING, status) @mock.patch.object(ActionExecution, 'get', mock.MagicMock(side_effect=[ MOCK_ACTIONEXECUTION_RUNNING_CHILD_RUNNING, MOCK_CHILD_ACTIONEXECUTION_RUNNING ])) def test_determine_status_wf_running_exec_succeeded_tasks_completed_child_running( self): status = self.querier._determine_execution_status( MOCK_LIVEACTION_RUNNING, 'SUCCESS', MOCK_WF_TASKS_SUCCEEDED) self.assertEqual(action_constants.LIVEACTION_STATUS_RUNNING, status) @mock.patch.object(ActionExecution, 'get', mock.MagicMock(side_effect=[ MOCK_ACTIONEXECUTION_RUNNING_CHILD_SUCCEEDED, MOCK_CHILD_ACTIONEXECUTION_SUCCEEDED ])) def test_determine_status_wf_running_exec_failed_tasks_completed(self): status = self.querier._determine_execution_status( MOCK_LIVEACTION_RUNNING, 'ERROR', MOCK_WF_TASKS_SUCCEEDED) self.assertEqual(action_constants.LIVEACTION_STATUS_FAILED, status) @mock.patch.object(ActionExecution, 'get', mock.MagicMock(side_effect=[ MOCK_ACTIONEXECUTION_RUNNING_CHILD_RUNNING, MOCK_CHILD_ACTIONEXECUTION_RUNNING ])) def test_determine_status_wf_running_exec_failed_tasks_running(self): status = self.querier._determine_execution_status( MOCK_LIVEACTION_RUNNING, 'ERROR', MOCK_WF_TASKS_RUNNING) self.assertEqual(action_constants.LIVEACTION_STATUS_RUNNING, status) @mock.patch.object(ActionExecution, 'get', mock.MagicMock(side_effect=[ MOCK_ACTIONEXECUTION_CANCELING_CHILD_SUCCEEDED, MOCK_CHILD_ACTIONEXECUTION_SUCCEEDED ])) def test_determine_status_wf_canceling_exec_canceled_tasks_completed(self): status = self.querier._determine_execution_status( MOCK_LIVEACTION_CANCELING, 'CANCELLED', MOCK_WF_TASKS_SUCCEEDED) self.assertEqual(action_constants.LIVEACTION_STATUS_CANCELED, status) @mock.patch.object(ActionExecution, 'get', mock.MagicMock(side_effect=[ MOCK_ACTIONEXECUTION_CANCELING_CHILD_RUNNING, MOCK_CHILD_ACTIONEXECUTION_RUNNING ])) def test_determine_status_wf_canceling_exec_canceled_tasks_running(self): status = self.querier._determine_execution_status( MOCK_LIVEACTION_CANCELING, 'CANCELLED', MOCK_WF_TASKS_RUNNING) self.assertEqual(action_constants.LIVEACTION_STATUS_CANCELING, status) @mock.patch.object(ActionExecution, 'get', mock.MagicMock(side_effect=[ MOCK_ACTIONEXECUTION_CANCELING_CHILD_SUCCEEDED, MOCK_CHILD_ACTIONEXECUTION_SUCCEEDED ])) def test_determine_status_wf_canceling_exec_canceled_tasks_waiting(self): status = self.querier._determine_execution_status( MOCK_LIVEACTION_CANCELING, 'CANCELLED', MOCK_WF_TASKS_WAITING) self.assertEqual(action_constants.LIVEACTION_STATUS_CANCELED, status) @mock.patch.object(ActionExecution, 'get', mock.MagicMock(side_effect=[ MOCK_ACTIONEXECUTION_CANCELING_CHILD_PAUSED, MOCK_CHILD_ACTIONEXECUTION_PAUSED ])) def test_determine_status_wf_canceling_exec_canceled_tasks_paused(self): status = self.querier._determine_execution_status( MOCK_LIVEACTION_CANCELING, 'CANCELLED', MOCK_WF_TASKS_PAUSED) self.assertEqual(action_constants.LIVEACTION_STATUS_CANCELED, status) @mock.patch.object(ActionExecution, 'get', mock.MagicMock(side_effect=[ MOCK_ACTIONEXECUTION_CANCELING_CHILD_SUCCEEDED, MOCK_CHILD_ACTIONEXECUTION_SUCCEEDED ])) def test_determine_status_wf_canceling_exec_running_tasks_completed(self): status = self.querier._determine_execution_status( MOCK_LIVEACTION_CANCELING, 'RUNNING', MOCK_WF_TASKS_SUCCEEDED) self.assertEqual(action_constants.LIVEACTION_STATUS_CANCELING, status) @mock.patch.object(ActionExecution, 'get', mock.MagicMock(side_effect=[ MOCK_ACTIONEXECUTION_CANCELING_CHILD_RUNNING, MOCK_CHILD_ACTIONEXECUTION_RUNNING ])) def test_determine_status_wf_canceling_exec_running_tasks_running(self): status = self.querier._determine_execution_status( MOCK_LIVEACTION_CANCELING, 'RUNNING', MOCK_WF_TASKS_RUNNING) self.assertEqual(action_constants.LIVEACTION_STATUS_CANCELING, status) @mock.patch.object(ActionExecution, 'get', mock.MagicMock(side_effect=[ MOCK_ACTIONEXECUTION_CANCELING_CHILD_SUCCEEDED, MOCK_CHILD_ACTIONEXECUTION_SUCCEEDED ])) def test_determine_status_wf_canceling_exec_running_tasks_waiting(self): status = self.querier._determine_execution_status( MOCK_LIVEACTION_CANCELING, 'RUNNING', MOCK_WF_TASKS_WAITING) self.assertEqual(action_constants.LIVEACTION_STATUS_CANCELING, status) @mock.patch.object(ActionExecution, 'get', mock.MagicMock(side_effect=[ MOCK_ACTIONEXECUTION_RUNNING_CHILD_RUNNING, MOCK_CHILD_ACTIONEXECUTION_RUNNING ])) def test_determine_status_wf_running_exec_cancelled_tasks_running(self): status = self.querier._determine_execution_status( MOCK_LIVEACTION_RUNNING, 'CANCELLED', MOCK_WF_TASKS_RUNNING) self.assertEqual(action_constants.LIVEACTION_STATUS_CANCELING, status) @mock.patch.object(ActionExecution, 'get', mock.MagicMock(side_effect=[ MOCK_ACTIONEXECUTION_PAUSING_CHILD_PAUSED, MOCK_CHILD_ACTIONEXECUTION_PAUSED ])) def test_determine_status_wf_pausing_exec_paused_tasks_completed(self): status = self.querier._determine_execution_status( MOCK_LIVEACTION_PAUSING, 'PAUSED', MOCK_WF_TASKS_SUCCEEDED) self.assertEqual(action_constants.LIVEACTION_STATUS_PAUSED, status) @mock.patch.object(ActionExecution, 'get', mock.MagicMock(side_effect=[ MOCK_ACTIONEXECUTION_PAUSING_CHILD_RUNNING, MOCK_CHILD_ACTIONEXECUTION_RUNNING ])) def test_determine_status_wf_pausing_exec_paused_tasks_completed_child_running( self): status = self.querier._determine_execution_status( MOCK_LIVEACTION_PAUSING, 'PAUSED', MOCK_WF_TASKS_SUCCEEDED) self.assertEqual(action_constants.LIVEACTION_STATUS_PAUSING, status) @mock.patch.object(ActionExecution, 'get', mock.MagicMock(side_effect=[ MOCK_ACTIONEXECUTION_PAUSING_CHILD_RUNNING, MOCK_CHILD_ACTIONEXECUTION_RUNNING ])) def test_determine_status_wf_pausing_exec_paused_tasks_running(self): status = self.querier._determine_execution_status( MOCK_LIVEACTION_PAUSING, 'PAUSED', MOCK_WF_TASKS_RUNNING) self.assertEqual(action_constants.LIVEACTION_STATUS_PAUSING, status) @mock.patch.object(ActionExecution, 'get', mock.MagicMock(side_effect=[ MOCK_ACTIONEXECUTION_PAUSING_CHILD_PAUSED, MOCK_CHILD_ACTIONEXECUTION_PAUSED ])) def test_determine_status_wf_pausing_exec_paused_tasks_paused(self): status = self.querier._determine_execution_status( MOCK_LIVEACTION_PAUSING, 'PAUSED', MOCK_WF_TASKS_PAUSED) self.assertEqual(action_constants.LIVEACTION_STATUS_PAUSED, status) @mock.patch.object(ActionExecution, 'get', mock.MagicMock(side_effect=[ MOCK_ACTIONEXECUTION_PAUSING_CHILD_RUNNING, MOCK_CHILD_ACTIONEXECUTION_RUNNING ])) def test_determine_status_wf_pausing_exec_running_tasks_running(self): status = self.querier._determine_execution_status( MOCK_LIVEACTION_PAUSING, 'RUNNING', MOCK_WF_TASKS_RUNNING) self.assertEqual(action_constants.LIVEACTION_STATUS_PAUSING, status) @mock.patch.object(ActionExecution, 'get', mock.MagicMock(side_effect=[ MOCK_ACTIONEXECUTION_RUNNING_CHILD_SUCCEEDED, MOCK_CHILD_ACTIONEXECUTION_SUCCEEDED ])) def test_determine_status_wf_running_exec_paused_tasks_completed(self): status = self.querier._determine_execution_status( MOCK_LIVEACTION_RUNNING, 'PAUSED', MOCK_WF_TASKS_SUCCEEDED) self.assertEqual(action_constants.LIVEACTION_STATUS_PAUSED, status) @mock.patch.object(ActionExecution, 'get', mock.MagicMock(side_effect=[ MOCK_ACTIONEXECUTION_RUNNING_CHILD_RUNNING, MOCK_CHILD_ACTIONEXECUTION_RUNNING ])) def test_determine_status_wf_running_exec_paused_tasks_running(self): status = self.querier._determine_execution_status( MOCK_LIVEACTION_RUNNING, 'PAUSED', MOCK_WF_TASKS_RUNNING) self.assertEqual(action_constants.LIVEACTION_STATUS_PAUSING, status) @mock.patch.object(ActionExecution, 'get', mock.MagicMock(side_effect=[ MOCK_ACTIONEXECUTION_RESUMING_CHILD_SUCCEEDED, MOCK_CHILD_ACTIONEXECUTION_SUCCEEDED ])) def test_determine_status_wf_resuming_exec_paused_tasks_completed(self): status = self.querier._determine_execution_status( MOCK_LIVEACTION_RESUMING, 'PAUSED', MOCK_WF_TASKS_SUCCEEDED) self.assertEqual(action_constants.LIVEACTION_STATUS_RESUMING, status) @mock.patch.object(ActionExecution, 'get', mock.MagicMock(side_effect=[ MOCK_ACTIONEXECUTION_RESUMING_CHILD_SUCCEEDED, MOCK_CHILD_ACTIONEXECUTION_SUCCEEDED ])) def test_determine_status_wf_resuming_exec_running_tasks_completed(self): status = self.querier._determine_execution_status( MOCK_LIVEACTION_RESUMING, 'RUNNING', MOCK_WF_TASKS_SUCCEEDED) self.assertEqual(action_constants.LIVEACTION_STATUS_RUNNING, status) @mock.patch.object(ActionExecution, 'get', mock.MagicMock(side_effect=[ MOCK_ACTIONEXECUTION_RESUMING_CHILD_RUNNING, MOCK_CHILD_ACTIONEXECUTION_RUNNING ])) def test_determine_status_wf_resuming_exec_running_tasks_running(self): status = self.querier._determine_execution_status( MOCK_LIVEACTION_RESUMING, 'RUNNING', MOCK_WF_TASKS_RUNNING) self.assertEqual(action_constants.LIVEACTION_STATUS_RUNNING, status) @mock.patch.object(ActionExecution, 'get', mock.MagicMock(side_effect=[ MOCK_ACTIONEXECUTION_RESUMING_CHILD_RUNNING, MOCK_CHILD_ACTIONEXECUTION_RUNNING ])) def test_determine_status_wf_resuming_exec_paused_tasks_running(self): status = self.querier._determine_execution_status( MOCK_LIVEACTION_RESUMING, 'PAUSED', MOCK_WF_TASKS_RUNNING) self.assertEqual(action_constants.LIVEACTION_STATUS_PAUSING, status) @mock.patch.object(ActionExecution, 'get', mock.MagicMock(side_effect=[ MOCK_ACTIONEXECUTION_RESUMING_CHILD_RUNNING, MOCK_CHILD_ACTIONEXECUTION_RUNNING ])) def test_determine_status_wf_resuming_exec_canceled_tasks_running(self): status = self.querier._determine_execution_status( MOCK_LIVEACTION_RESUMING, 'CANCELLED', MOCK_WF_TASKS_RUNNING) self.assertEqual(action_constants.LIVEACTION_STATUS_CANCELING, status) @mock.patch.object(executions.ExecutionManager, 'get', mock.MagicMock(return_value=MOCK_WF_EX)) def test_get_workflow_result(self): result = self.querier._get_workflow_result(uuid.uuid4().hex, uuid.uuid4().hex) expected = { 'k1': 'v1', 'extra': { 'state': MOCK_WF_EX.state, 'state_info': MOCK_WF_EX.state_info } } self.assertDictEqual(expected, result) @mock.patch.object(tasks.TaskManager, 'list', mock.MagicMock(return_value=MOCK_WF_EX_TASKS)) @mock.patch.object( tasks.TaskManager, 'get', mock.MagicMock(side_effect=[MOCK_WF_EX_TASKS[0], MOCK_WF_EX_TASKS[1]])) def test_get_workflow_tasks(self): tasks = self.querier._get_workflow_tasks(uuid.uuid4().hex, uuid.uuid4().hex) expected = copy.deepcopy(MOCK_WF_EX_TASKS_DATA) for task in expected: task['input'] = json.loads(task['input']) task['result'] = json.loads(task['result']) task['published'] = json.loads(task['published']) for i in range(0, len(tasks)): self.assertDictEqual(expected[i], tasks[i]) @mock.patch.object(action_utils, 'get_liveaction_by_id', mock.MagicMock(return_value=MOCK_LIVEACTION_RUNNING)) @mock.patch.object(executions.ExecutionManager, 'get', mock.MagicMock(return_value=MOCK_WF_EX)) @mock.patch.object(tasks.TaskManager, 'list', mock.MagicMock(return_value=MOCK_WF_EX_TASKS)) @mock.patch.object( tasks.TaskManager, 'get', mock.MagicMock(side_effect=[MOCK_WF_EX_TASKS[0], MOCK_WF_EX_TASKS[1]])) @mock.patch.object(ActionExecution, 'get', mock.MagicMock(side_effect=[ MOCK_ACTIONEXECUTION_RUNNING_CHILD_SUCCEEDED, MOCK_CHILD_ACTIONEXECUTION_SUCCEEDED ])) def test_query(self): (status, result) = self.querier.query(uuid.uuid4().hex, MOCK_QRY_CONTEXT) expected = { 'k1': 'v1', 'tasks': copy.deepcopy(MOCK_WF_EX_TASKS_DATA), 'extra': { 'state': MOCK_WF_EX.state, 'state_info': MOCK_WF_EX.state_info } } for task in expected['tasks']: task['input'] = json.loads(task['input']) task['result'] = json.loads(task['result']) task['published'] = json.loads(task['published']) self.assertEqual(action_constants.LIVEACTION_STATUS_SUCCEEDED, status) self.assertDictEqual(expected, result) @mock.patch.object( action_utils, 'get_liveaction_by_id', mock.MagicMock( return_value=MOCK_LIVEACTION_RUNNING_WITH_STREAMING_RESULT)) @mock.patch.object(executions.ExecutionManager, 'get', mock.MagicMock(return_value=MOCK_WF_EX)) @mock.patch.object(tasks.TaskManager, 'list', mock.MagicMock(return_value=[MOCK_WF_EX_TASKS[1]])) @mock.patch.object(tasks.TaskManager, 'get', mock.MagicMock(return_value=MOCK_WF_EX_TASKS[1])) @mock.patch.object(ActionExecution, 'get', mock.MagicMock(side_effect=[ MOCK_ACTIONEXECUTION_RUNNING_CHILD_SUCCEEDED, MOCK_CHILD_ACTIONEXECUTION_SUCCEEDED ])) def test_query_with_last_query_time(self): last_query_time = time.time() - 3 (status, result) = self.querier.query(uuid.uuid4().hex, MOCK_QRY_CONTEXT, last_query_time=last_query_time) expected = { 'k1': 'v1', 'tasks': copy.deepcopy(MOCK_WF_EX_TASKS_DATA), 'extra': { 'state': MOCK_WF_EX.state, 'state_info': MOCK_WF_EX.state_info } } for task in expected['tasks']: task['input'] = json.loads(task['input']) task['result'] = json.loads(task['result']) task['published'] = json.loads(task['published']) self.assertEqual(action_constants.LIVEACTION_STATUS_SUCCEEDED, status) self.assertDictEqual(expected, result) @mock.patch.object( action_utils, 'get_liveaction_by_id', mock.MagicMock(side_effect=db_exc.StackStormDBObjectNotFoundError())) def test_query_liveaction_not_found(self): self.assertRaises(db_exc.StackStormDBObjectNotFoundError, self.querier.query, uuid.uuid4().hex, MOCK_QRY_CONTEXT) @mock.patch.object(action_utils, 'get_liveaction_by_id', mock.MagicMock(return_value=MOCK_LIVEACTION_RUNNING)) @mock.patch.object( executions.ExecutionManager, 'get', mock.MagicMock( side_effect=[requests.exceptions.ConnectionError(), MOCK_WF_EX])) @mock.patch.object(tasks.TaskManager, 'list', mock.MagicMock(return_value=MOCK_WF_EX_TASKS)) @mock.patch.object( tasks.TaskManager, 'get', mock.MagicMock(side_effect=[MOCK_WF_EX_TASKS[0], MOCK_WF_EX_TASKS[1]])) @mock.patch.object(ActionExecution, 'get', mock.MagicMock(side_effect=[ MOCK_ACTIONEXECUTION_RUNNING_CHILD_SUCCEEDED, MOCK_CHILD_ACTIONEXECUTION_SUCCEEDED ])) def test_query_get_workflow_retry(self): (status, result) = self.querier.query(uuid.uuid4().hex, MOCK_QRY_CONTEXT) expected = { 'k1': 'v1', 'tasks': copy.deepcopy(MOCK_WF_EX_TASKS_DATA), 'extra': { 'state': MOCK_WF_EX.state, 'state_info': MOCK_WF_EX.state_info } } for task in expected['tasks']: task['input'] = json.loads(task['input']) task['result'] = json.loads(task['result']) task['published'] = json.loads(task['published']) self.assertEqual(action_constants.LIVEACTION_STATUS_SUCCEEDED, status) self.assertDictEqual(expected, result) calls = [ call(MOCK_QRY_CONTEXT['mistral']['execution_id']) for i in range(0, 2) ] executions.ExecutionManager.get.assert_has_calls(calls) @mock.patch.object(action_utils, 'get_liveaction_by_id', mock.MagicMock(return_value=MOCK_LIVEACTION_RUNNING)) @mock.patch.object( executions.ExecutionManager, 'get', mock.MagicMock(side_effect=[requests.exceptions.ConnectionError()] * 4) ) def test_query_get_workflow_retry_exhausted(self): self.assertRaises(requests.exceptions.ConnectionError, self.querier.query, uuid.uuid4().hex, MOCK_QRY_CONTEXT) calls = [ call(MOCK_QRY_CONTEXT['mistral']['execution_id']) for i in range(0, 2) ] executions.ExecutionManager.get.assert_has_calls(calls) @mock.patch.object(action_utils, 'get_liveaction_by_id', mock.MagicMock(return_value=MOCK_LIVEACTION_RUNNING)) @mock.patch.object( executions.ExecutionManager, 'get', mock.MagicMock(side_effect=mistralclient_base.APIException( error_code=404, error_message='Workflow not found.'))) def test_query_get_workflow_not_found(self): (status, result) = self.querier.query(uuid.uuid4().hex, MOCK_QRY_CONTEXT) self.assertEqual(action_constants.LIVEACTION_STATUS_FAILED, status) self.assertEqual('Workflow not found.', result) @mock.patch.object(action_utils, 'get_liveaction_by_id', mock.MagicMock(return_value=MOCK_LIVEACTION_RUNNING)) @mock.patch.object(executions.ExecutionManager, 'get', mock.MagicMock(return_value=MOCK_WF_EX)) @mock.patch.object( tasks.TaskManager, 'list', mock.MagicMock(side_effect=[ requests.exceptions.ConnectionError(), MOCK_WF_EX_TASKS ])) @mock.patch.object( tasks.TaskManager, 'get', mock.MagicMock(side_effect=[MOCK_WF_EX_TASKS[0], MOCK_WF_EX_TASKS[1]])) @mock.patch.object(ActionExecution, 'get', mock.MagicMock(side_effect=[ MOCK_ACTIONEXECUTION_RUNNING_CHILD_SUCCEEDED, MOCK_CHILD_ACTIONEXECUTION_SUCCEEDED ])) def test_query_list_workflow_tasks_retry(self): (status, result) = self.querier.query(uuid.uuid4().hex, MOCK_QRY_CONTEXT) expected = { 'k1': 'v1', 'tasks': copy.deepcopy(MOCK_WF_EX_TASKS_DATA), 'extra': { 'state': MOCK_WF_EX.state, 'state_info': MOCK_WF_EX.state_info } } for task in expected['tasks']: task['input'] = json.loads(task['input']) task['result'] = json.loads(task['result']) task['published'] = json.loads(task['published']) self.assertEqual(action_constants.LIVEACTION_STATUS_SUCCEEDED, status) self.assertDictEqual(expected, result) mock_call = call( workflow_execution_id=MOCK_QRY_CONTEXT['mistral']['execution_id']) calls = [mock_call for i in range(0, 2)] tasks.TaskManager.list.assert_has_calls(calls) calls = [call(MOCK_WF_EX_TASKS[0].id), call(MOCK_WF_EX_TASKS[1].id)] tasks.TaskManager.get.assert_has_calls(calls) @mock.patch.object(action_utils, 'get_liveaction_by_id', mock.MagicMock(return_value=MOCK_LIVEACTION_RUNNING)) @mock.patch.object(executions.ExecutionManager, 'get', mock.MagicMock(return_value=MOCK_WF_EX)) @mock.patch.object(tasks.TaskManager, 'list', mock.MagicMock(return_value=MOCK_WF_EX_TASKS)) @mock.patch.object(tasks.TaskManager, 'get', mock.MagicMock(side_effect=[ requests.exceptions.ConnectionError(), MOCK_WF_EX_TASKS[0], MOCK_WF_EX_TASKS[1] ])) @mock.patch.object(ActionExecution, 'get', mock.MagicMock(side_effect=[ MOCK_ACTIONEXECUTION_RUNNING_CHILD_SUCCEEDED, MOCK_CHILD_ACTIONEXECUTION_SUCCEEDED ])) def test_query_get_workflow_tasks_retry(self): (status, result) = self.querier.query(uuid.uuid4().hex, MOCK_QRY_CONTEXT) expected = { 'k1': 'v1', 'tasks': copy.deepcopy(MOCK_WF_EX_TASKS_DATA), 'extra': { 'state': MOCK_WF_EX.state, 'state_info': MOCK_WF_EX.state_info } } for task in expected['tasks']: task['input'] = json.loads(task['input']) task['result'] = json.loads(task['result']) task['published'] = json.loads(task['published']) self.assertEqual(action_constants.LIVEACTION_STATUS_SUCCEEDED, status) self.assertDictEqual(expected, result) calls = [ call(MOCK_WF_EX_TASKS[0].id), call(MOCK_WF_EX_TASKS[0].id), call(MOCK_WF_EX_TASKS[1].id) ] tasks.TaskManager.get.assert_has_calls(calls) @mock.patch.object(action_utils, 'get_liveaction_by_id', mock.MagicMock(return_value=MOCK_LIVEACTION_RUNNING)) @mock.patch.object(executions.ExecutionManager, 'get', mock.MagicMock(return_value=MOCK_WF_EX)) @mock.patch.object( tasks.TaskManager, 'list', mock.MagicMock(side_effect=[requests.exceptions.ConnectionError()] * 4) ) def test_query_list_workflow_tasks_retry_exhausted(self): self.assertRaises(requests.exceptions.ConnectionError, self.querier.query, uuid.uuid4().hex, MOCK_QRY_CONTEXT) mock_call = call( workflow_execution_id=MOCK_QRY_CONTEXT['mistral']['execution_id']) calls = [mock_call for i in range(0, 2)] tasks.TaskManager.list.assert_has_calls(calls) @mock.patch.object(action_utils, 'get_liveaction_by_id', mock.MagicMock(return_value=MOCK_LIVEACTION_RUNNING)) @mock.patch.object(executions.ExecutionManager, 'get', mock.MagicMock(return_value=MOCK_WF_EX)) @mock.patch.object(tasks.TaskManager, 'list', mock.MagicMock(return_value=MOCK_WF_EX_TASKS)) @mock.patch.object( tasks.TaskManager, 'get', mock.MagicMock(side_effect=[requests.exceptions.ConnectionError()] * 4) ) def test_query_get_workflow_tasks_retry_exhausted(self): self.assertRaises(requests.exceptions.ConnectionError, self.querier.query, uuid.uuid4().hex, MOCK_QRY_CONTEXT) calls = [call(MOCK_WF_EX_TASKS[0].id), call(MOCK_WF_EX_TASKS[0].id)] tasks.TaskManager.get.assert_has_calls(calls) @mock.patch.object(action_utils, 'get_liveaction_by_id', mock.MagicMock(return_value=MOCK_LIVEACTION_RUNNING)) @mock.patch.object(executions.ExecutionManager, 'get', mock.MagicMock(return_value=MOCK_WF_EX)) @mock.patch.object(tasks.TaskManager, 'list', mock.MagicMock(return_value=MOCK_WF_EX_TASKS)) @mock.patch.object( tasks.TaskManager, 'get', mock.MagicMock(side_effect=mistralclient_base.APIException( error_code=404, error_message='Task not found.'))) def test_query_get_workflow_tasks_not_found(self): (status, result) = self.querier.query(uuid.uuid4().hex, MOCK_QRY_CONTEXT) self.assertEqual(action_constants.LIVEACTION_STATUS_FAILED, status) self.assertEqual('Task not found.', result) def test_query_missing_context(self): self.assertRaises(Exception, self.querier.query, uuid.uuid4().hex, {}) def test_query_missing_mistral_execution_id(self): self.assertRaises(Exception, self.querier.query, uuid.uuid4().hex, {'mistral': {}}) @mock.patch.object( action_utils, 'get_liveaction_by_id', mock.MagicMock( return_value= MOCK_LIVEACTION_RUNNING_WITH_OUTDATED_INCOMPLETE_TASKS_STREAMING_RESULT )) @mock.patch.object(executions.ExecutionManager, 'get', mock.MagicMock(return_value=MOCK_WF_EX)) @mock.patch.object(tasks.TaskManager, 'list', mock.MagicMock(return_value=MOCK_WF_EX_INCOMPLETE_TASKS) ) @mock.patch.object(tasks.TaskManager, 'get', mock.MagicMock(side_effect=MOCK_WF_EX_INCOMPLETE_TASKS)) @mock.patch.object(ActionExecution, 'get', mock.MagicMock(side_effect=[ MOCK_ACTIONEXECUTION_RUNNING_CHILD_SUCCEEDED, MOCK_CHILD_ACTIONEXECUTION_SUCCEEDED ])) def test_query_with_outdated_tasks_in_liveaction_result(self): last_query_time = time.time() + 3 (status, result) = self.querier.query(uuid.uuid4().hex, MOCK_QRY_CONTEXT, last_query_time=last_query_time) expected = { 'k1': 'v1', 'tasks': copy.deepcopy(MOCK_WF_EX_INCOMPLETE_TASKS_DATA), 'extra': { 'state': MOCK_WF_EX.state, 'state_info': MOCK_WF_EX.state_info } } for task in expected['tasks']: task['input'] = json.loads(task['input']) task['result'] = json.loads(task['result']) task['published'] = json.loads(task['published']) self.assertEqual(action_constants.LIVEACTION_STATUS_RUNNING, status) self.assertDictEqual(expected, result) @mock.patch.object( action_utils, 'get_liveaction_by_id', mock.MagicMock( return_value= MOCK_LIVEACTION_RUNNING_WITH_UP_TO_DATE_INCOMPLETE_TASKS_STREAMING_RESULT )) @mock.patch.object(executions.ExecutionManager, 'get', mock.MagicMock(return_value=MOCK_WF_EX)) @mock.patch.object(tasks.TaskManager, 'list', mock.MagicMock(return_value=MOCK_WF_EX_INCOMPLETE_TASKS) ) @mock.patch.object( tasks.TaskManager, 'get', mock.MagicMock(return_value=MOCK_WF_EX_INCOMPLETE_TASKS[1])) @mock.patch.object(ActionExecution, 'get', mock.MagicMock(side_effect=[ MOCK_ACTIONEXECUTION_RUNNING_CHILD_SUCCEEDED, MOCK_CHILD_ACTIONEXECUTION_SUCCEEDED ])) def test_query_with_up_to_date_tasks_in_liveaction_result(self): last_query_time = time.time() + 3 (status, result) = self.querier.query(uuid.uuid4().hex, MOCK_QRY_CONTEXT, last_query_time=last_query_time) expected = { 'k1': 'v1', 'tasks': copy.deepcopy(MOCK_WF_EX_INCOMPLETE_TASKS_DATA), 'extra': { 'state': MOCK_WF_EX.state, 'state_info': MOCK_WF_EX.state_info } } for task in expected['tasks']: task['input'] = json.loads(task['input']) task['result'] = json.loads(task['result']) task['published'] = json.loads(task['published']) self.assertEqual(action_constants.LIVEACTION_STATUS_RUNNING, status) self.assertDictEqual(expected, result) @mock.patch.object(action_utils, 'get_liveaction_by_id', mock.MagicMock(return_value=MOCK_LIVEACTION_RUNNING)) @mock.patch.object(executions.ExecutionManager, 'get', mock.MagicMock(return_value=MOCK_WF_EX)) @mock.patch.object(tasks.TaskManager, 'list', mock.MagicMock(return_value=MOCK_WF_EX_TASKS)) @mock.patch.object( tasks.TaskManager, 'get', mock.MagicMock(side_effect=[MOCK_WF_EX_TASKS[0], MOCK_WF_EX_TASKS[1]])) @mock.patch.object(ActionExecution, 'get', mock.MagicMock(side_effect=[ MOCK_ACTIONEXECUTION_RUNNING_CHILD_REQUESTED, MOCK_CHILD_ACTIONEXECUTION_REQUESTED ])) def test_orphaned_execution_child_in_requested_state(self): (status, result) = self.querier.query(uuid.uuid4().hex, MOCK_QRY_CONTEXT) expected = { 'k1': 'v1', 'tasks': copy.deepcopy(MOCK_WF_EX_TASKS_DATA), 'extra': { 'state': MOCK_WF_EX.state, 'state_info': MOCK_WF_EX.state_info } } for task in expected['tasks']: task['input'] = json.loads(task['input']) task['result'] = json.loads(task['result']) task['published'] = json.loads(task['published']) self.assertEqual(action_constants.LIVEACTION_STATUS_SUCCEEDED, status) self.assertDictEqual(expected, result)