diff --git a/docs/source/actions.rst b/docs/source/actions.rst index d382c8b11..6d39cfe71 100644 --- a/docs/source/actions.rst +++ b/docs/source/actions.rst @@ -544,13 +544,19 @@ For example: else: self.logger.error('Action failed...') -Datastore -~~~~~~~~~ +Action Service +~~~~~~~~~~~~~~ -Actions can utilize the datastore to store data between executions. +Similar to sensors, ``action_service`` is available on each action instance +after instantiation. -The datastore service provides the same methods available on the sensor service. -More detail can be found in the :ref:`sensor datastore management documentation`. +Action service provides different services to the actiona via public methods. +Right now it supports datastore management methods. This allows actions to +utilize datastore to store arbitrary data between executions. + +The action service provides the same datastore management methods as the ones +available on the sensor service. You can find more details in the +:ref:`sensor datastore management documentation`. Example storing a dict as JSON: @@ -560,15 +566,14 @@ Example storing a dict as JSON: data = {'somedata': 'foobar'} # Add a value to the datastore - self.datastore.set_value(name='cache', value=json.dumps(data)) + self.action_service.set_value(name='cache', value=json.dumps(data)) # Retrieve a value - value = self.datastore.get_value('cache') + value = self.action_service.get_value('cache') retrieved_data = json.loads(value) # Delete a value - self.datastore.delete_value('cache') - + self.action_service.delete_value('cache') Pre-defined actions ^^^^^^^^^^^^^^^^^^^ diff --git a/docs/source/development/pack_testing.rst b/docs/source/development/pack_testing.rst index 89df7c471..17185a912 100644 --- a/docs/source/development/pack_testing.rst +++ b/docs/source/development/pack_testing.rst @@ -46,7 +46,9 @@ Base Test Classes populated, method for asserting that trigger has been dispatched (``assertTriggerDispatched``) and more. * ``st2tests.base.BaseActionTestCase`` - Base class for all the action test - cases. + cases. This class provides utility methods for making action testing easier + such as returning an action class with ``action_service`` correctly + populated, etc. Mock Classes ~~~~~~~~~~~~ @@ -59,8 +61,13 @@ in the tests. from the ``run`` method. * ``st2tests.mocks.sensor.MockSensorWrapper`` - Mock ``SensorWrapper`` class. * ``st2tests.mocks.sensor.MockSensorService`` - Mock ``SensorService`` class. - This class mock methods which operate on the datastore items (``get_logger`, + This class mocks methods which operate on the datastore items (``get_logger`, ``list_values``, ``get_value``, ``set_value``, ``delete_value``). +* ``st2tests.mocks.action.MockActionWrapper`` - Mock ``PythonActionWrapper`` + class. +* ``st2tests.mocks.action.MockActionService`` - Mock ``ActionService`` class. + This class mocks methods which operate on the datastore items (``list_values``, + ``get_value``, ``set_value``, ``delete_value``). Dependencies ------------ @@ -76,8 +83,8 @@ In addition those dependencies, sensors (``/sensors/``) and actions (``/actions/``) directory is added to PYTHONPATH meaning you can import sensor and action modules directly in your code. -For example, if you have an action named ``actions/parse_xml.py`` you can do the -following inside your test module: +For example, if you have an action file named ``actions/parse_xml.py`` you can +do the following inside your test module: .. sourcecode:: python @@ -86,6 +93,51 @@ following inside your test module: Keep in mind that both sensor and action modules are not namespaced which means sensor and action module names need to be unique to avoid conflicts. +Instantiating and obtaining class instances +------------------------------------------- + +When obtaining a sensor or an action class instance you should use +``get_sensor_instance`` and ``get_action_instance`` methods provided on the base +test class instead of directly instantiating the sensor / action class yourself. + +This is important because those two methods mimic the class initialization +process which is otherwise performed inside the action / sensor wrapper. + +You can find an example on how to do that below. + +Sensor tests: + +.. sourcecode:: python + + class MySensorSensorTestCase(BaseSensorTestCase): + sensor_cls = MySensor + + def test_method(self): + sensor = self.get_sensor_instance(config={'foo': 'bar'}) + sensor.poll() + # ... + + +Action tests: + +.. sourcecode:: python + + class MyActionActionTestBase(BaseActionTestCase): + action_cls = MyAction + + def test_method(self): + action = self.get_action_instance(config={'foo': 'bar'}) + result = action.run() + # ... + +Sample Tests +------------ + +You can find some sample tests on the links below. + +* Sensor - `test_sensor_docker_sensor `_ +* Action - `test_action_parse `_ + Running Tests ------------- @@ -117,16 +169,8 @@ st2workroom), you can safely pass ``-x`` flag to the script since a virtual environment should already be created and all the necessary |st2| dependencies should be available in ``PYTHONPATH``. -Sample Tests ------------- - -You can find some sample tests on the links below. - -* Sensor - `test_sensor_docker_sensor `_ -* Action - `test_action_parse `_ - Continous Integration --------------------- -By default tests for all the packs are ran on every commit to ``st2contrib`` -repository. +By default tests for all the packs are ran on every commit to ``st2`` and +``st2contrib`` repository.