.. _tempest_plugin:

=============================
Tempest Test Plugin Interface
=============================

Tempest has an external test plugin interface which enables anyone to integrate
an external test suite as part of a Tempest run. This will let any project
leverage being run with the rest of the Tempest suite while not requiring the
tests live in the Tempest tree.

Creating a plugin
=================

Creating a plugin is fairly straightforward and doesn't require much additional
effort on top of creating a test suite using tempest.lib. One thing to note with
doing this is that the interfaces exposed by Tempest are not considered stable
(with the exception of configuration variables whichever effort goes into
ensuring backward compatibility). You should not need to import anything from
Tempest itself except where explicitly noted.

Stable Tempest APIs plugins may use
-----------------------------------

As noted above, several Tempest APIs are acceptable to use from plugins, while
others are not. A list of stable APIs available to plugins is provided below:

* tempest.lib.*
* tempest.config
* tempest.test_discover.plugins
* tempest.common.credentials_factory
* tempest.clients
* tempest.test
* tempest.scenario.manager

If there is an interface from Tempest that you need to rely on in your plugin
which is not listed above, it likely needs to be migrated to tempest.lib. In
that situation, file a bug, push a migration patch, etc. to expedite providing
the interface in a reliable manner.

Plugin Cookiecutter
-------------------

In order to create the basic structure with base classes and test directories
you can use the tempest-plugin-cookiecutter project::

  > pip install -U cookiecutter && cookiecutter https://opendev.org/openstack/tempest-plugin-cookiecutter.git

  Cloning into 'tempest-plugin-cookiecutter'...
  remote: Counting objects: 17, done.
  remote: Compressing objects: 100% (13/13), done.
  remote: Total 17 (delta 1), reused 14 (delta 1)
  Unpacking objects: 100% (17/17), done.
  Checking connectivity... done.
  project (default is "sample")? foo
  testclass (default is "SampleTempestPlugin")? FooTempestPlugin

This would create a folder called ``foo_tempest_plugin/`` with all necessary
basic classes. You only need to move/create your test in
``foo_tempest_plugin/tests``.

Entry Point
-----------

Once you've created your plugin class you need to add an entry point to your
project to enable Tempest to find the plugin. The entry point must be added
to the "tempest.test_plugins" namespace.

If you are using pbr this is fairly straightforward, in the setup.cfg just add
something like the following:

.. code-block:: ini

  [entry_points]
  tempest.test_plugins =
      plugin_name = module.path:PluginClass

Standalone Plugin vs In-repo Plugin
-----------------------------------

Since all that's required for a plugin to be detected by Tempest is a valid
setuptools entry point in the proper namespace there is no difference from the
Tempest perspective on either creating a separate Python package to
house the plugin or adding the code to an existing Python project. However,
there are tradeoffs to consider when deciding which approach to take when
creating a new plugin.

If you create a separate Python project for your plugin this makes a lot of
things much easier. Firstly it makes packaging and versioning much simpler, you
can easily decouple the requirements for the plugin from the requirements for
the other project. It lets you version the plugin independently and maintain a
single version of the test code across project release boundaries (see the
`Branchless Tempest Spec`_ for more details on this). It also greatly
simplifies the install time story for external users. Instead of having to
install the right version of a project in the same Python namespace as Tempest
they simply need to pip install the plugin in that namespace. It also means
that users don't have to worry about inadvertently installing a Tempest plugin
when they install another package.

.. _Branchless Tempest Spec: https://specs.openstack.org/openstack/qa-specs/specs/tempest/implemented/branchless-tempest.html

The sole advantage of integrating a plugin into an existing Python project is
that it enables you to land code changes at the same time you land test changes
in the plugin. This reduces some of the burden on contributors by not having
to land 2 changes to add a new API feature and then test it, and do it as a
single combined commit instead.


Plugin Class
============

To provide Tempest with all the required information it needs to be able to run
your plugin you need to create a plugin class which Tempest will load and call
to get information when it needs. To simplify creating this Tempest provides an
abstract class that should be used as the parent for your plugin. To use this
you would do something like the following:

.. code-block:: python

  from tempest.test_discover import plugins

  class MyPlugin(plugins.TempestPlugin):

Then you need to ensure you locally define all of the mandatory methods in the
abstract class, you can refer to the API doc below for a reference of what that
entails.

Abstract Plugin Class
---------------------

.. autoclass:: tempest.test_discover.plugins.TempestPlugin
   :members:

Plugin Structure
================
While there are no hard and fast rules for the structure of a plugin, there are
basically no constraints on what the plugin looks like as long as the 2 steps
above are done. However, there are some recommended patterns to follow to make
it easy for people to contribute and work with your plugin. For example, if you
create a directory structure with something like::

    plugin_dir/
      config.py
      plugin.py
      tests/
        api/
        scenario/
      services/
        client.py

That will mirror what people expect from Tempest. The file

* **config.py**: contains any plugin specific configuration variables
* **plugin.py**: contains the plugin class used for the entry point
* **tests**: the directory where test discovery will be run, all tests should
             be under this dir
* **services**: where the plugin specific service clients are

Additionally, when you're creating the plugin you likely want to follow all
of the Tempest developer and reviewer documentation to ensure that the tests
being added in the plugin act and behave like the rest of Tempest.

Dealing with configuration options
----------------------------------

Historically, Tempest didn't provide external guarantees on its configuration
options. However, with the introduction of the plugin interface, this is no
longer the case. An external plugin can rely on using any configuration option
coming from Tempest, there will be at least a full deprecation cycle for any
option before it's removed. However, just the options provided by Tempest
may not be sufficient for the plugin. If you need to add any plugin specific
configuration options you should use the ``register_opts`` and
``get_opt_lists`` methods to pass them to Tempest when the plugin is loaded.
When adding configuration options the ``register_opts`` method gets passed the
CONF object from Tempest. This enables the plugin to add options to both
existing sections and also create new configuration sections for new options.

Service Clients
---------------

If a plugin defines a service client, it is beneficial for it to implement the
``get_service_clients`` method in the plugin class. All service clients which
are exposed via this interface will be automatically configured and be
available in any instance of the service clients class, defined in
``tempest.lib.services.clients.ServiceClients``. In case multiple plugins are
installed, all service clients from all plugins will be registered, making it
easy to write tests which rely on multiple APIs whose service clients are in
different plugins.

Example implementation of ``get_service_clients``:

.. code-block:: python

    def get_service_clients(self):
        # Example implementation with two service clients
        my_service1_config = config.service_client_config('my_service')
        params_my_service1 = {
            'name': 'my_service_v1',
            'service_version': 'my_service.v1',
            'module_path': 'plugin_tempest_tests.services.my_service.v1',
            'client_names': ['API1Client', 'API2Client'],
        }
        params_my_service1.update(my_service_config)
        my_service2_config = config.service_client_config('my_service')
        params_my_service2 = {
            'name': 'my_service_v2',
            'service_version': 'my_service.v2',
            'module_path': 'plugin_tempest_tests.services.my_service.v2',
            'client_names': ['API1Client', 'API2Client'],
        }
        params_my_service2.update(my_service2_config)
        return [params_my_service1, params_my_service2]

Parameters:

* **name**: Name of the attribute used to access the ``ClientsFactory`` from
  the ``ServiceClients`` instance. See the example below.
* **service_version**: Tempest enforces a single implementation for each
  service client. Available service clients are held in a ``ClientsRegistry``
  singleton, and registered with ``service_version``, which means that
  ``service_version`` must be unique and it should represent the service API
  and version implemented by the service client.
* **module_path**: Relative to the service client module, from the root of the
  plugin.
* **client_names**: Name of the classes that implement service clients in the
  service clients module.

Example usage of the service clients in tests:

.. code-block:: python

   # my_creds is an instance of tempest.lib.auth.Credentials
   # identity_uri is v2 or v3 depending on the configuration
   from tempest.lib.services import clients

   my_clients = clients.ServiceClients(my_creds, identity_uri)
   my_service1_api1_client = my_clients.my_service_v1.API1Client()
   my_service2_api1_client = my_clients.my_service_v2.API1Client(my_args='any')

Automatic configuration and registration of service clients imposes some extra
constraints on the structure of the configuration options exposed by the
plugin.

Firstly, ``service_version`` should be in the format `service_config[.version]`.
The `.version` part is optional, and should only be used if there are multiple
versions of the same API available. The `service_config` must match the name of
a configuration options group defined by the plugin. Different versions of one
API must share the same configuration group.

Secondly, the configuration options group `service_config` must contain the
following options:

* `catalog_type`: corresponds to `service` in the catalog
* `endpoint_type`

The following options will be honoured if defined, but they are not mandatory,
as they do not necessarily apply to all service clients.

* `region`: default to identity.region
* `build_timeout`: default to compute.build_timeout
* `build_interval`: default to compute.build_interval

Thirdly, the service client classes should inherit from ``RestClient``, should
accept generic keyword arguments, and should pass those arguments to the
``__init__`` method of ``RestClient``. Extra arguments can be added. For
instance:

.. code-block:: python

   class MyAPIClient(rest_client.RestClient):

       def __init__(self, auth_provider, service, region,
                    my_arg, my_arg2=True, **kwargs):
           super(MyAPIClient, self).__init__(
               auth_provider, service, region, **kwargs)
           self.my_arg = my_arg
           self.my_args2 = my_arg

Finally, the service client should be structured in a Python module, so that all
service client classes are importable from it. Each major API version should
have its own module.

The following folder and module structure is recommended for a single major
API version::

    plugin_dir/
      services/
        __init__.py
        client_api_1.py
        client_api_2.py

The content of __init__.py module should be:

.. code-block:: python

   from client_api_1.py import API1Client
   from client_api_2.py import API2Client

   __all__ = ['API1Client', 'API2Client']

The following folder and module structure is recommended for multiple major
API versions::

    plugin_dir/
      services/
        v1/
           __init__.py
           client_api_1.py
           client_api_2.py
        v2/
           __init__.py
           client_api_1.py
           client_api_2.py

The content each of __init__.py module under vN should be:

.. code-block:: python

   from client_api_1.py import API1Client
   from client_api_2.py import API2Client

   __all__ = ['API1Client', 'API2Client']

Using Plugins
=============

Tempest will automatically discover any installed plugins when it is run. So by
just installing the Python packages, which contain your plugin, you'll be using
them with Tempest, nothing else is really required.

However, you should take care when installing plugins. By their very nature,
there are no guarantees when running Tempest with plugins enabled about the
quality of the plugin. Additionally, while there is no limitation on running
with multiple plugins, it's worth noting that poorly written plugins might not
properly isolate their tests which could cause unexpected cross-interactions
between plugins.

Notes for using plugins with virtualenvs
----------------------------------------

When using a Tempest inside a virtualenv (like when running under tox) you have
to ensure that the package that contains your plugin is either installed in the
venv too or that you have system site-packages enabled. The virtualenv will
isolate the Tempest install from the rest of your system so just installing the
plugin package on your system and then running Tempest inside a venv will not
work.

For example, you can use tox to install and run tests from a tempest plugin like
this::

    [~/tempest] $ tox -e venv-tempest -- pip install (path to the plugin directory)
    [~/tempest] $ tox -e all
