def _delete_state_object(self, query_context): state_db = ActionExecutionState.get_by_id(query_context.id) if state_db is not None: try: ActionExecutionState.delete(state_db) except: LOG.exception('Failed clearing state object: %s', state_db)
def test_execution_cancellation(self): tracker = self._get_tracker() querier = tracker.get_querier('test_querymodule') querier._delete_state_object = mock.Mock(return_value=None) runners_utils.invoke_post_run = mock.Mock(return_value=None) # Ensure state objects are present. state1 = ActionExecutionState.get_by_id(ResultsTrackerTests.states['state1.yaml'].id) state2 = ActionExecutionState.get_by_id(ResultsTrackerTests.states['state2.yaml'].id) self.assertIsNotNone(state1) self.assertIsNotNone(state2) with mock.patch.object( querier.__class__, 'query', mock.MagicMock(return_value=(action_constants.LIVEACTION_STATUS_CANCELED, {}))): tracker._bootstrap() eventlet.sleep(2) exec_id = str(ResultsTrackerTests.states['state1.yaml'].execution_id) exec_db = LiveAction.get_by_id(exec_id) self.assertDictEqual(exec_db.result, {}) exec_id = str(ResultsTrackerTests.states['state2.yaml'].execution_id) exec_db = LiveAction.get_by_id(exec_id) self.assertDictEqual(exec_db.result, {}) tracker.shutdown() # Ensure deletes are called. self.assertEqual(2, querier._delete_state_object.call_count) # Ensure invoke_post_run is called. self.assertEqual(2, runners_utils.invoke_post_run.call_count)
def _delete_state_object(self, query_context): state_db = ActionExecutionState.get_by_id(query_context.id) if state_db is not None: try: ActionExecutionState.delete(state_db) except: LOG.exception('Failed clearing state object: %s', state_db)
def test_keep_state_object_on_error_at_update_result(self): tracker = results_tracker.get_tracker() querier = tracker.get_querier('test_querymodule') querier._delete_state_object = mock.Mock(return_value=None) querier.delete_state_object_on_error = False # Ensure state objects are present. state1 = ActionExecutionState.get_by_id( ResultsTrackerTests.states['state1.yaml'].id) state2 = ActionExecutionState.get_by_id( ResultsTrackerTests.states['state2.yaml'].id) self.assertIsNotNone(state1) self.assertIsNotNone(state2) with mock.patch.object( querier.__class__, '_update_action_results', mock.MagicMock( side_effect=Exception('Mock update exception.'))): tracker._bootstrap() eventlet.sleep(1) exec_id = str( ResultsTrackerTests.states['state1.yaml'].execution_id) exec_db = LiveAction.get_by_id(exec_id) self.assertDictEqual(exec_db.result, {}) exec_id = str( ResultsTrackerTests.states['state2.yaml'].execution_id) exec_db = LiveAction.get_by_id(exec_id) self.assertDictEqual(exec_db.result, {}) tracker.shutdown() # Ensure deletes are not called. querier._delete_state_object.assert_not_called()
def test_keep_state_object_on_error_at_update_result(self): tracker = self._get_tracker() querier = tracker.get_querier('test_querymodule') querier._delete_state_object = mock.Mock(return_value=None) querier.delete_state_object_on_error = False # Ensure state objects are present. state1 = ActionExecutionState.get_by_id(ResultsTrackerTests.states['state1.yaml'].id) state2 = ActionExecutionState.get_by_id(ResultsTrackerTests.states['state2.yaml'].id) self.assertIsNotNone(state1) self.assertIsNotNone(state2) with mock.patch.object( querier.__class__, '_update_action_results', mock.MagicMock(side_effect=Exception('Mock update exception.'))): tracker._bootstrap() eventlet.sleep(1) exec_id = str(ResultsTrackerTests.states['state1.yaml'].execution_id) exec_db = LiveAction.get_by_id(exec_id) self.assertDictEqual(exec_db.result, {}) exec_id = str(ResultsTrackerTests.states['state2.yaml'].execution_id) exec_db = LiveAction.get_by_id(exec_id) self.assertDictEqual(exec_db.result, {}) tracker.shutdown() # Ensure deletes are not called. querier._delete_state_object.assert_not_called()
def _update_state_models(cls): states = ResultsTrackerTests.states state1 = ActionExecutionState.get_by_id(states['state1.yaml'].id) state1.execution_id = ResultsTrackerTests.liveactions['liveaction1.yaml'].id state2 = ActionExecutionState.get_by_id(states['state2.yaml'].id) state2.execution_id = ResultsTrackerTests.liveactions['liveaction2.yaml'].id ResultsTrackerTests.states['state1.yaml'] = ActionExecutionState.add_or_update(state1) ResultsTrackerTests.states['state2.yaml'] = ActionExecutionState.add_or_update(state2)
def _update_state_models(cls): states = ResultsTrackerTests.states state1 = ActionExecutionState.get_by_id(states['state1.yaml'].id) state1.execution_id = ResultsTrackerTests.liveactions['liveaction1.yaml'].id state2 = ActionExecutionState.get_by_id(states['state2.yaml'].id) state2.execution_id = ResultsTrackerTests.liveactions['liveaction2.yaml'].id ResultsTrackerTests.states['state1.yaml'] = ActionExecutionState.add_or_update(state1) ResultsTrackerTests.states['state2.yaml'] = ActionExecutionState.add_or_update(state2)
def remove_query(liveaction_id): state_db = ActionExecutionState.query(execution_id=liveaction_id) if not state_db: return False ActionExecutionState.delete(state_db, publish=False, dispatch_trigger=False) return True
def setup_query(liveaction_id, runnertype_db, query_context): if not getattr(runnertype_db, 'query_module', None): raise Exception('The runner "%s" does not have a query module.' % runnertype_db.name) state_db = ActionExecutionStateDB(execution_id=liveaction_id, query_module=runnertype_db.query_module, query_context=query_context) ActionExecutionState.add_or_update(state_db)
def test_state_crud(self): saved = ActionExecutionStateTests._create_save_actionstate() retrieved = ActionExecutionState.get_by_id(saved.id) self.assertDictEqual(saved.query_context, retrieved.query_context) self.assertEqual(saved.query_module, retrieved.query_module) ActionExecutionStateTests._delete(model_objects=[retrieved]) try: retrieved = ActionExecutionState.get_by_id(saved.id) except StackStormDBObjectNotFoundError: retrieved = None self.assertIsNone(retrieved, 'managed to retrieve after failure.')
def setup_query(liveaction_id, runnertype_db, query_context): if not getattr(runnertype_db, 'query_module', None): raise Exception('The runner "%s" does not have a query module.' % runnertype_db.name) state_db = ActionExecutionStateDB( execution_id=liveaction_id, query_module=runnertype_db.query_module, query_context=query_context ) ActionExecutionState.add_or_update(state_db)
def _delete_state_object(self, query_context): state_db = None try: state_db = ActionExecutionState.get_by_id(query_context.id) except db_exc.StackStormDBObjectNotFoundError: pass if state_db is not None: try: LOG.info('Clearing state object: %s', state_db) ActionExecutionState.delete(state_db) except: LOG.exception('Failed clearing state object: %s', state_db)
def test_state_db_created_for_polling_async_actions(self): runner_container = get_runner_container() params = {"actionstr": "foo", "actionint": 20, "async_test": True} liveaction_db = self._get_liveaction_model( RunnerContainerTest.polling_async_action_db, params) liveaction_db = LiveAction.add_or_update(liveaction_db) executions.create_execution_object(liveaction_db) # Assert that execution ran without exceptions. with mock.patch( "st2actions.container.base.get_runner", mock.Mock(return_value=polling_async_runner.get_runner()), ): runner_container.dispatch(liveaction_db) states = ActionExecutionState.get_all() found = [ state for state in states if state.execution_id == liveaction_db.id ] self.assertTrue(len(found) > 0, "There should be a state db object.") self.assertTrue( len(found) == 1, "There should only be one state db object.") self.assertIsNotNone(found[0].query_context) self.assertIsNotNone(found[0].query_module)
def test_state_db_created_for_polling_async_actions(self): runner_container = get_runner_container() params = { 'actionstr': 'foo', 'actionint': 20, 'async_test': True } liveaction_db = self._get_liveaction_model( RunnerContainerTest.polling_async_action_db, params ) liveaction_db = LiveAction.add_or_update(liveaction_db) executions.create_execution_object(liveaction_db) # Assert that execution ran without exceptions. runner_container.dispatch(liveaction_db) states = ActionExecutionState.get_all() found = [state for state in states if state.execution_id == liveaction_db.id] self.assertTrue(len(found) > 0, 'There should be a state db object.') self.assertTrue(len(found) == 1, 'There should only be one state db object.') self.assertTrue(found[0].query_context is not None) self.assertTrue(found[0].query_module is not None)
def _is_state_object_exist(self, query_context): state_db = None try: state_db = ActionExecutionState.get_by_id(query_context.id) except db_exc.StackStormDBObjectNotFoundError: pass return (state_db is not None)
def _create_execution_state(self, liveaction_id, runnertype_db, query_context): state_db = ActionExecutionStateDB( execution_id=liveaction_id, query_module=runnertype_db.query_module, query_context=query_context ) try: return ActionExecutionState.add_or_update(state_db) except: LOG.exception("Unable to create execution state db for liveaction_id %s." % liveaction_id) return None
def _create_execution_state(self, liveaction_id, runnertype_db, query_context): state_db = ActionExecutionStateDB( execution_id=liveaction_id, query_module=runnertype_db.query_module, query_context=query_context) try: return ActionExecutionState.add_or_update(state_db) except: LOG.exception('Unable to create execution state db for liveaction_id %s.' % liveaction_id) return None
def test_query_process(self): tracker = results_tracker.get_tracker() runners_utils.invoke_post_run = mock.Mock(return_value=None) # Ensure state objects are present. state1 = ActionExecutionState.get_by_id(ResultsTrackerTests.states['state1.yaml'].id) state2 = ActionExecutionState.get_by_id(ResultsTrackerTests.states['state2.yaml'].id) self.assertIsNotNone(state1) self.assertIsNotNone(state2) # Process the state objects. tracker._bootstrap() eventlet.sleep(1) exec_id = str(ResultsTrackerTests.states['state1.yaml'].execution_id) exec_db = LiveAction.get_by_id(exec_id) self.assertTrue(exec_db.result['called_with'][exec_id] is not None, exec_db.result) exec_id = str(ResultsTrackerTests.states['state2.yaml'].execution_id) exec_db = LiveAction.get_by_id(exec_id) self.assertTrue(exec_db.result['called_with'][exec_id] is not None, exec_db.result) tracker.shutdown() # Ensure state objects are deleted. self.assertRaises( StackStormDBObjectNotFoundError, ActionExecutionState.get_by_id, ResultsTrackerTests.states['state1.yaml'].id ) self.assertRaises( StackStormDBObjectNotFoundError, ActionExecutionState.get_by_id, ResultsTrackerTests.states['state2.yaml'].id ) # Ensure invoke_post_run is called. self.assertEqual(2, runners_utils.invoke_post_run.call_count)
def test_action_deleted(self): tracker = self._get_tracker() action_db_utils.get_runnertype_by_name = mock.Mock(return_value=None) # Ensure state objects are present. state1 = ActionExecutionState.get_by_id(ResultsTrackerTests.states['state1.yaml'].id) state2 = ActionExecutionState.get_by_id(ResultsTrackerTests.states['state2.yaml'].id) self.assertIsNotNone(state1) self.assertIsNotNone(state2) # Process the state objects. tracker._bootstrap() eventlet.sleep(1) exec_id = str(ResultsTrackerTests.states['state1.yaml'].execution_id) exec_db = LiveAction.get_by_id(exec_id) self.assertTrue(exec_db.result['called_with'][exec_id] is not None, exec_db.result) exec_id = str(ResultsTrackerTests.states['state2.yaml'].execution_id) exec_db = LiveAction.get_by_id(exec_id) self.assertTrue(exec_db.result['called_with'][exec_id] is not None, exec_db.result) tracker.shutdown() # Ensure state objects are deleted. self.assertRaises( StackStormDBObjectNotFoundError, ActionExecutionState.get_by_id, ResultsTrackerTests.states['state1.yaml'].id ) self.assertRaises( StackStormDBObjectNotFoundError, ActionExecutionState.get_by_id, ResultsTrackerTests.states['state2.yaml'].id ) # Ensure get_runnertype_by_name in invoke_post_run is not called. action_db_utils.get_runnertype_by_name.assert_not_called()
def test_query_process(self): tracker = results_tracker.get_tracker() querier = tracker.get_querier('test_querymodule') querier._invoke_post_run = mock.Mock(return_value=None) # Ensure state objects are present. state1 = ActionExecutionState.get_by_id( ResultsTrackerTests.states['state1.yaml'].id) state2 = ActionExecutionState.get_by_id( ResultsTrackerTests.states['state2.yaml'].id) self.assertIsNotNone(state1) self.assertIsNotNone(state2) # Process the state objects. tracker._bootstrap() eventlet.sleep(1) exec_id = str(ResultsTrackerTests.states['state1.yaml'].execution_id) exec_db = LiveAction.get_by_id(exec_id) self.assertTrue(exec_db.result['called_with'][exec_id] is not None, exec_db.result) exec_id = str(ResultsTrackerTests.states['state2.yaml'].execution_id) exec_db = LiveAction.get_by_id(exec_id) self.assertTrue(exec_db.result['called_with'][exec_id] is not None, exec_db.result) tracker.shutdown() # Ensure state objects are deleted. self.assertRaises(StackStormDBObjectNotFoundError, ActionExecutionState.get_by_id, ResultsTrackerTests.states['state1.yaml'].id) self.assertRaises(StackStormDBObjectNotFoundError, ActionExecutionState.get_by_id, ResultsTrackerTests.states['state2.yaml'].id) # Ensure invoke_post_run is called. self.assertEqual(2, querier._invoke_post_run.call_count)
def test_execution_cancellation(self): tracker = results_tracker.get_tracker() querier = tracker.get_querier('test_querymodule') querier._delete_state_object = mock.Mock(return_value=None) runners_utils.invoke_post_run = mock.Mock(return_value=None) # Ensure state objects are present. state1 = ActionExecutionState.get_by_id( ResultsTrackerTests.states['state1.yaml'].id) state2 = ActionExecutionState.get_by_id( ResultsTrackerTests.states['state2.yaml'].id) self.assertIsNotNone(state1) self.assertIsNotNone(state2) with mock.patch.object( querier.__class__, 'query', mock.MagicMock( return_value=(action_constants.LIVEACTION_STATUS_CANCELED, {}))): tracker._bootstrap() eventlet.sleep(2) exec_id = str( ResultsTrackerTests.states['state1.yaml'].execution_id) exec_db = LiveAction.get_by_id(exec_id) self.assertDictEqual(exec_db.result, {}) exec_id = str( ResultsTrackerTests.states['state2.yaml'].execution_id) exec_db = LiveAction.get_by_id(exec_id) self.assertDictEqual(exec_db.result, {}) tracker.shutdown() # Ensure deletes are called. self.assertEqual(2, querier._delete_state_object.call_count) # Ensure invoke_post_run is called. self.assertEqual(2, runners_utils.invoke_post_run.call_count)
def test_action_deleted(self): tracker = results_tracker.get_tracker() action_db_utils.get_runnertype_by_name = mock.Mock(return_value=None) # Ensure state objects are present. state1 = ActionExecutionState.get_by_id( ResultsTrackerTests.states['state1.yaml'].id) state2 = ActionExecutionState.get_by_id( ResultsTrackerTests.states['state2.yaml'].id) self.assertIsNotNone(state1) self.assertIsNotNone(state2) # Process the state objects. tracker._bootstrap() eventlet.sleep(1) exec_id = str(ResultsTrackerTests.states['state1.yaml'].execution_id) exec_db = LiveAction.get_by_id(exec_id) self.assertTrue(exec_db.result['called_with'][exec_id] is not None, exec_db.result) exec_id = str(ResultsTrackerTests.states['state2.yaml'].execution_id) exec_db = LiveAction.get_by_id(exec_id) self.assertTrue(exec_db.result['called_with'][exec_id] is not None, exec_db.result) tracker.shutdown() # Ensure state objects are deleted. self.assertRaises(StackStormDBObjectNotFoundError, ActionExecutionState.get_by_id, ResultsTrackerTests.states['state1.yaml'].id) self.assertRaises(StackStormDBObjectNotFoundError, ActionExecutionState.get_by_id, ResultsTrackerTests.states['state2.yaml'].id) # Ensure get_runnertype_by_name in invoke_post_run is not called. action_db_utils.get_runnertype_by_name.assert_not_called()
def test_state_db_creation_async_actions(self): runner_container = get_runner_container() params = {"actionstr": "foo", "actionint": 20, "async_test": True} liveaction_db = self._get_action_exec_db_model(RunnerContainerTest.async_action_db, params) liveaction_db = LiveAction.add_or_update(liveaction_db) executions.create_execution_object(liveaction_db) # Assert that execution ran without exceptions. runner_container.dispatch(liveaction_db) states = ActionExecutionState.get_all() found = None for state in states: if state.execution_id == liveaction_db.id: found = state self.assertTrue(found is not None, "There should be a state db object.") self.assertTrue(found.query_context is not None) self.assertTrue(found.query_module is not None)
def test_state_db_not_created_for_async_actions(self): runner_container = get_runner_container() params = {"actionstr": "foo", "actionint": 20, "async_test": True} liveaction_db = self._get_liveaction_model( RunnerContainerTest.async_action_db, params) liveaction_db = LiveAction.add_or_update(liveaction_db) executions.create_execution_object(liveaction_db) # Assert that execution ran without exceptions. runner_container.dispatch(liveaction_db) states = ActionExecutionState.get_all() found = [ state for state in states if state.execution_id == liveaction_db.id ] self.assertTrue( len(found) == 0, "There should not be a state db object.")
def _bootstrap(self): all_states = ActionExecutionState.get_all() LOG.info('Found %d pending states in db.' % len(all_states)) query_contexts_dict = defaultdict(list) for state_db in all_states: try: context = QueryContext.from_model(state_db) except: LOG.exception('Invalid state object: %s', state_db) continue query_module_name = state_db.query_module querier = self.get_querier(query_module_name) if querier is not None: query_contexts_dict[querier].append(context) for querier, contexts in six.iteritems(query_contexts_dict): LOG.info('Found %d pending actions for query module %s', len(contexts), querier) querier.add_queries(query_contexts=contexts)
def _bootstrap(self): all_states = ActionExecutionState.get_all() LOG.info('Found %d pending states in db.' % len(all_states)) query_contexts_dict = defaultdict(list) for state_db in all_states: try: context = QueryContext.from_model(state_db) except: LOG.exception('Invalid state object: %s', state_db) continue query_module_name = state_db.query_module querier = self.get_querier(query_module_name) if querier is not None: query_contexts_dict[querier].append(context) for querier, contexts in six.iteritems(query_contexts_dict): LOG.info('Found %d pending actions for query module %s', len(contexts), querier) querier.add_queries(query_contexts=contexts)
def _create_save_actionstate(): created = ActionExecutionStateDB() created.query_context = {'id': 'some_external_service_id'} created.query_module = 'dummy.modules.query1' created.execution_id = bson.ObjectId() return ActionExecutionState.add_or_update(created)
def get_state(cls, exec_db): state = ActionExecutionStateDB(execution_id=str(exec_db.id), query_context={'id': 'foo'}, query_module='test_querymodule') return ActionExecutionState.add_or_update(state)
def get_state(cls, exec_db): state = ActionExecutionStateDB(execution_id=str(exec_db.id), query_context={'id': 'foo'}, query_module='test_querymodule') return ActionExecutionState.add_or_update(state)