diff --git a/st2actions/tests/test_runner_container.py b/st2actions/tests/test_runner_container.py index 588639a523..5ac7495ca0 100644 --- a/st2actions/tests/test_runner_container.py +++ b/st2actions/tests/test_runner_container.py @@ -1,5 +1,11 @@ -from st2common.models.db.action import RunnerTypeDB +import datetime + +from st2common.models.db.action import (ActionDB, ActionExecutionDB) +from st2common.models.api.action import RunnerTypeAPI +from st2common.models.api.actionrunner import LiveActionAPI +from st2common.persistence.action import (Action, ActionExecution, RunnerType) from st2tests.base import DbTestCase + import tests.config as tests_config tests_config.parse_args() @@ -10,11 +16,112 @@ class RunnerContainerTest(DbTestCase): + action_db = None + runnertype_db = None + + @classmethod + def setUpClass(cls): + super(DbTestCase, cls).setUpClass() + RunnerContainerTest._setup_test_models() def test_get_runner_module(self): - runner_type_db = RunnerTypeDB() - runner_type_db.name = 'run-local' - runner_type_db.runner_module = 'st2actions.runners.fabricrunner' + runnertype_db = RunnerContainerTest.runnertype_db + runner_container = RunnerContainer() + runner = runner_container._get_runner(runnertype_db) + self.assertTrue(runner is not None, 'TestRunner must be valid.') + + def test_dispatch(self): + runner_container = RunnerContainer() + runnertype_db = RunnerContainerTest.runnertype_db + action_db = RunnerContainerTest.action_db + params = { + 'actionstr': 'bar' + } + actionexec_db = self._get_action_exec_db_model(params) + actionexec_db = ActionExecution.add_or_update(actionexec_db) + liveaction_db = self._get_live_action_db_model(actionexec_db.id) + # Assert that execution ran successfully. + self.assertTrue(runner_container.dispatch(liveaction_db, runnertype_db, + action_db, actionexec_db)) + actionexec_db = ActionExecution.get_by_id(actionexec_db.id) + result = actionexec_db.result + self.assertTrue(result.get('action_params').get('actionint') == 10) + self.assertTrue(result.get('action_params').get('actionstr') == 'bar') + + def test_dispatch_override_default_action_params(self): runner_container = RunnerContainer() - runner = runner_container._get_runner(runner_type_db) - self.assertTrue(runner is not None, 'Runner must be valid.') + runnertype_db = RunnerContainerTest.runnertype_db + action_db = RunnerContainerTest.action_db + params = { + 'actionstr': 'foo', + 'actionint': 20 + } + actionexec_db = self._get_action_exec_db_model(params) + actionexec_db = ActionExecution.add_or_update(actionexec_db) + liveactionapi = LiveActionAPI(**{'actionexecution_id': str(actionexec_db.id)}) + liveaction_db = LiveActionAPI.to_model(liveactionapi) + + # Assert that execution ran successfully. + self.assertTrue(runner_container.dispatch(liveaction_db, runnertype_db, + action_db, actionexec_db)) + actionexec_db = ActionExecution.get_by_id(actionexec_db.id) + result = actionexec_db.result + self.assertTrue(result.get('action_params').get('actionint') == 20) + self.assertTrue(result.get('action_params').get('actionstr') == 'foo') + + def _get_action_exec_db_model(self, params): + actionexec_db = ActionExecutionDB() + actionexec_db.status = 'initializing' + actionexec_db.start_timestamp = datetime.datetime.now() + actionexec_db.action = {'name': RunnerContainerTest.action_db.name} + actionexec_db.parameters = params + return actionexec_db + + def _get_live_action_db_model(self, actionexec_id): + liveactionapi = LiveActionAPI(**{'actionexecution_id': actionexec_id}) + liveaction_db = LiveActionAPI.to_model(liveactionapi) + return liveaction_db + + @classmethod + def _setup_test_models(cls): + RunnerContainerTest.setup_runner() + RunnerContainerTest.setup_action_models() + + @classmethod + def setup_runner(cls): + test_runner = { + 'name': 'test-runner', + 'description': 'A test runner.', + 'enabled': True, + 'runner_parameters': { + 'runnerstr': { + 'description': 'Foo str param.', + 'type': 'string', + 'default': 'defaultfoo' + }, + 'runnerint': { + 'description': 'Foo int param.', + 'type': 'number' + } + }, + 'runner_module': 'tests.testrunner' + } + runnertype_api = RunnerTypeAPI(**test_runner) + RunnerContainerTest.runnertype_db = RunnerType.add_or_update( + RunnerTypeAPI.to_model(runnertype_api)) + + @classmethod + def setup_action_models(cls): + action_db = ActionDB() + action_db.name = 'action-1' + action_db.description = 'awesomeness' + action_db.enabled = True + action_db.content_pack = 'wolfpack' + action_db.entry_point = '' + action_db.runner_type = {'name': 'test-runner'} + action_db.parameters = { + 'actionstr': {'type': 'string'}, + 'actionint': {'type': 'number', 'default': 10}, + } + action_db.required_parameters = ['actionstr'] + RunnerContainerTest.action_db = Action.add_or_update(action_db) diff --git a/st2actions/tests/testrunner.py b/st2actions/tests/testrunner.py new file mode 100644 index 0000000000..941f8bf155 --- /dev/null +++ b/st2actions/tests/testrunner.py @@ -0,0 +1,32 @@ +try: + import simplejson as json +except: + import json + +from st2actions.runners import ActionRunner + + +def get_runner(): + return TestRunner() + + +class TestRunner(ActionRunner): + def __init__(self): + self.pre_run_called = False + self.run_called = False + self.post_run_called = False + + def pre_run(self): + self.pre_run_called = True + + def run(self, action_params): + self.run_called = True + result = { + 'ran': True, + 'action_params': action_params + } + self.container_service.report_result(json.dumps(result)) + self.container_service.report_status(0) + + def post_run(self): + self.post_run_called = True diff --git a/st2tests/st2tests/base.py b/st2tests/st2tests/base.py index 9aa5ef5154..11b760dc95 100644 --- a/st2tests/st2tests/base.py +++ b/st2tests/st2tests/base.py @@ -55,7 +55,8 @@ def setUpClass(cls): @classmethod def tearDownClass(cls): cls.drop_collections() - DbTestCase.db_connection.drop_database(cfg.CONF.database.db_name) + if DbTestCase.db_connection is not None: + DbTestCase.db_connection.drop_database(cfg.CONF.database.db_name) db_teardown() DbTestCase.db_connection = None