blob: 29653a65d889546ac898033c0d26f7a698194898 [file] [log] [blame]
Matthew Treinish3a851dc2015-07-30 11:34:03 -04001=============================
2Tempest Test Plugin Interface
3=============================
4
5Tempest has an external test plugin interface which enables anyone to integrate
6an external test suite as part of a tempest run. This will let any project
7leverage being run with the rest of the tempest suite while not requiring the
8tests live in the tempest tree.
9
10Creating a plugin
11=================
12
13Creating a plugin is fairly straightforward and doesn't require much additional
14effort on top of creating a test suite using tempest-lib. One thing to note with
15doing this is that the interfaces exposed by tempest are not considered stable
16(with the exception of configuration variables which ever effort goes into
17ensuring backwards compatibility). You should not need to import anything from
18tempest itself except where explicitly noted. If there is an interface from
19tempest that you need to rely on in your plugin it likely needs to be migrated
20to tempest-lib. In that situation, file a bug, push a migration patch, etc. to
21expedite providing the interface in a reliable manner.
22
Marc Koderer66210aa2015-10-26 10:52:32 +010023Plugin Cookiecutter
24-------------------
25
26In order to create the basic structure with base classes and test directories
27you can use the tempest-plugin-cookiecutter project::
28
Yuiko Takadaccb2bbf2015-11-17 10:09:44 +090029 > pip install -U cookiecutter && cookiecutter https://git.openstack.org/openstack/tempest-plugin-cookiecutter
Marc Koderer66210aa2015-10-26 10:52:32 +010030
31 Cloning into 'tempest-plugin-cookiecutter'...
32 remote: Counting objects: 17, done.
33 remote: Compressing objects: 100% (13/13), done.
34 remote: Total 17 (delta 1), reused 14 (delta 1)
35 Unpacking objects: 100% (17/17), done.
36 Checking connectivity... done.
37 project (default is "sample")? foo
38 testclass (default is "SampleTempestPlugin")? FooTempestPlugin
39
40This would create a folder called ``foo_tempest_plugin/`` with all necessary
41basic classes. You only need to move/create your test in
42``foo_tempest_plugin/tests``.
43
44Entry Point
45-----------
46
47Once you've created your plugin class you need to add an entry point to your
48project to enable tempest to find the plugin. The entry point must be added
49to the "tempest.test_plugins" namespace.
50
51If you are using pbr this is fairly straightforward, in the setup.cfg just add
52something like the following::
53
54 [entry_points]
55 tempest.test_plugins =
56 plugin_name = module.path:PluginClass
57
Matthew Treinish3a851dc2015-07-30 11:34:03 -040058Plugin Class
Marc Koderer66210aa2015-10-26 10:52:32 +010059============
Matthew Treinish3a851dc2015-07-30 11:34:03 -040060
61To provide tempest with all the required information it needs to be able to run
62your plugin you need to create a plugin class which tempest will load and call
63to get information when it needs. To simplify creating this tempest provides an
64abstract class that should be used as the parent for your plugin. To use this
65you would do something like the following::
66
YAMAMOTO Takashicb2ac6e2015-10-19 15:54:42 +090067 from tempest.test_discover import plugins
Matthew Treinish3a851dc2015-07-30 11:34:03 -040068
YAMAMOTO Takashicb2ac6e2015-10-19 15:54:42 +090069 class MyPlugin(plugins.TempestPlugin):
Matthew Treinish3a851dc2015-07-30 11:34:03 -040070
71Then you need to ensure you locally define all of the methods in the abstract
72class, you can refer to the api doc below for a reference of what that entails.
73
74Also, note eventually this abstract class will likely live in tempest-lib, when
75that migration occurs a deprecation shim will be added to tempest so as to not
76break any existing plugins. But, when that occurs migrating to using tempest-lib
77as the source for the abstract class will be prudent.
78
79Abstract Plugin Class
Marc Koderer66210aa2015-10-26 10:52:32 +010080---------------------
Matthew Treinish3a851dc2015-07-30 11:34:03 -040081
82.. autoclass:: tempest.test_discover.plugins.TempestPlugin
83 :members:
84
Matthew Treinish3a851dc2015-07-30 11:34:03 -040085Plugin Structure
Marc Koderer66210aa2015-10-26 10:52:32 +010086================
Matthew Treinish3a851dc2015-07-30 11:34:03 -040087While there are no hard and fast rules for the structure a plugin, there are
88basically no constraints on what the plugin looks like as long as the 2 steps
89above are done. However, there are some recommended patterns to follow to make
90it easy for people to contribute and work with your plugin. For example, if you
91create a directory structure with something like::
92
93 plugin_dir/
94 config.py
95 plugin.py
96 tests/
97 api/
98 scenario/
99 services/
100 client.py
101
102That will mirror what people expect from tempest. The file
103
104* **config.py**: contains any plugin specific configuration variables
105* **plugin.py**: contains the plugin class used for the entry point
106* **tests**: the directory where test discovery will be run, all tests should
107 be under this dir
108* **services**: where the plugin specific service clients are
109
110Additionally, when you're creating the plugin you likely want to follow all
111of the tempest developer and reviewer documentation to ensure that the tests
112being added in the plugin act and behave like the rest of tempest.
113
Matthew Treinish9392a832015-08-24 10:00:49 -0400114Dealing with configuration options
Marc Koderer66210aa2015-10-26 10:52:32 +0100115----------------------------------
Matthew Treinish9392a832015-08-24 10:00:49 -0400116
117Historically Tempest didn't provide external guarantees on its configuration
118options. However, with the introduction of the plugin interface this is no
119longer the case. An external plugin can rely on using any configuration option
120coming from Tempest, there will be at least a full deprecation cycle for any
121option before it's removed. However, just the options provided by Tempest
122may not be sufficient for the plugin. If you need to add any plugin specific
123configuration options you should use the ``register_opts`` and
124``get_opt_lists`` methods to pass them to Tempest when the plugin is loaded.
125When adding configuration options the ``register_opts`` method gets passed the
126CONF object from tempest. This enables the plugin to add options to both
127existing sections and also create new configuration sections for new options.
128
Matthew Treinish3a851dc2015-07-30 11:34:03 -0400129Using Plugins
130=============
131
132Tempest will automatically discover any installed plugins when it is run. So by
133just installing the python packages which contain your plugin you'll be using
134them with tempest, nothing else is really required.
135
136However, you should take care when installing plugins. By their very nature
137there are no guarantees when running tempest with plugins enabled about the
138quality of the plugin. Additionally, while there is no limitation on running
139with multiple plugins it's worth noting that poorly written plugins might not
140properly isolate their tests which could cause unexpected cross interactions
141between plugins.
142
143Notes for using plugins with virtualenvs
144----------------------------------------
145
146When using a tempest inside a virtualenv (like when running under tox) you have
147to ensure that the package that contains your plugin is either installed in the
148venv too or that you have system site-packages enabled. The virtualenv will
149isolate the tempest install from the rest of your system so just installing the
150plugin package on your system and then running tempest inside a venv will not
151work.
152
153Tempest also exposes a tox job, all-plugin, which will setup a tox virtualenv
154with system site-packages enabled. This will let you leverage tox without
155requiring to manually install plugins in the tox venv before running tests.