Merge "Stop gating on sample generation check"
diff --git a/doc/source/index.rst b/doc/source/index.rst
index 93aca49..e9f2161 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -10,6 +10,7 @@
overview
HACKING
REVIEWING
+ plugin
------------
Field Guides
diff --git a/doc/source/plugin.rst b/doc/source/plugin.rst
new file mode 100644
index 0000000..4e97dbe
--- /dev/null
+++ b/doc/source/plugin.rst
@@ -0,0 +1,120 @@
+=============================
+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 which ever effort goes into
+ensuring backwards compatibility). You should not need to import anything from
+tempest itself except where explicitly noted. If there is an interface from
+tempest that you need to rely on in your plugin 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 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::
+
+ from tempest.test_discover import plugin
+
+ class MyPlugin(plugin.TempestPlugin):
+
+Then you need to ensure you locally define all of the methods in the abstract
+class, you can refer to the api doc below for a reference of what that entails.
+
+Also, note eventually this abstract class will likely live in tempest-lib, when
+that migration occurs a deprecation shim will be added to tempest so as to not
+break any existing plugins. But, when that occurs migrating to using tempest-lib
+as the source for the abstract class will be prudent.
+
+Abstract Plugin Class
+^^^^^^^^^^^^^^^^^^^^^
+
+.. autoclass:: tempest.test_discover.plugins.TempestPlugin
+ :members:
+
+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::
+
+ [entry_points]
+ tempest.test_plugins =
+ plugin_name = module.path:PluginClass
+
+Plugin Structure
+----------------
+
+While there are no hard and fast rules for the structure 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.
+
+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.
+
+Tempest also exposes a tox job, all-plugin, which will setup a tox virtualenv
+with system site-packages enabled. This will let you leverage tox without
+requiring to manually install plugins in the tox venv before running tests.
diff --git a/tempest/api/compute/admin/test_quotas_negative.py b/tempest/api/compute/admin/test_quotas_negative.py
index 9acf23b..8dcd0b2 100644
--- a/tempest/api/compute/admin/test_quotas_negative.py
+++ b/tempest/api/compute/admin/test_quotas_negative.py
@@ -170,4 +170,5 @@
# will be raised when out of quota
self.assertRaises((lib_exc.OverLimit, lib_exc.Forbidden),
self.sgr_client.create_security_group_rule,
- secgroup_id, ip_protocol, 1025, 1025)
+ parent_group_id=secgroup_id, ip_protocol=ip_protocol,
+ from_port=1025, to_port=1025)
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 2126787..b2effc2 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -279,7 +279,7 @@
if 'name' in kwargs:
name = kwargs.pop('name')
- image = cls.images_client.create_image(server_id, name)
+ image = cls.images_client.create_image(server_id, name=name)
image_id = data_utils.parse_image_id(image.response['location'])
cls.images.append(image_id)
diff --git a/tempest/api/compute/images/test_images_negative.py b/tempest/api/compute/images/test_images_negative.py
index 9721fa5..84a8258 100644
--- a/tempest/api/compute/images/test_images_negative.py
+++ b/tempest/api/compute/images/test_images_negative.py
@@ -93,7 +93,7 @@
snapshot_name = data_utils.rand_name('test-snap')
test_uuid = ('a' * 35)
self.assertRaises(lib_exc.NotFound, self.client.create_image,
- test_uuid, snapshot_name)
+ test_uuid, name=snapshot_name)
@test.attr(type=['negative'])
@test.idempotent_id('36741560-510e-4cc2-8641-55fe4dfb2437')
@@ -102,7 +102,7 @@
snapshot_name = data_utils.rand_name('test-snap')
test_uuid = ('a' * 37)
self.assertRaises(lib_exc.NotFound, self.client.create_image,
- test_uuid, snapshot_name)
+ test_uuid, name=snapshot_name)
@test.attr(type=['negative'])
@test.idempotent_id('381acb65-785a-4942-94ce-d8f8c84f1f0f')
diff --git a/tempest/api/compute/images/test_images_oneserver.py b/tempest/api/compute/images/test_images_oneserver.py
index 40a781c..06b7cac 100644
--- a/tempest/api/compute/images/test_images_oneserver.py
+++ b/tempest/api/compute/images/test_images_oneserver.py
@@ -80,7 +80,8 @@
# Create a new image
name = data_utils.rand_name('image')
meta = {'image_type': 'test'}
- body = self.client.create_image(self.server_id, name, meta)
+ body = self.client.create_image(self.server_id, name=name,
+ metadata=meta)
image_id = data_utils.parse_image_id(body.response['location'])
waiters.wait_for_image_status(self.client, image_id, 'ACTIVE')
@@ -112,6 +113,6 @@
# #1370954 in glance which will 500 if mysql is used as the
# backend and it attempts to store a 4 byte utf-8 character
utf8_name = data_utils.rand_name('\xe2\x82\xa1')
- body = self.client.create_image(self.server_id, utf8_name)
+ body = self.client.create_image(self.server_id, name=utf8_name)
image_id = data_utils.parse_image_id(body.response['location'])
self.addCleanup(self.client.delete_image, image_id)
diff --git a/tempest/api/compute/images/test_images_oneserver_negative.py b/tempest/api/compute/images/test_images_oneserver_negative.py
index 1a74e52..9ea62fb 100644
--- a/tempest/api/compute/images/test_images_oneserver_negative.py
+++ b/tempest/api/compute/images/test_images_oneserver_negative.py
@@ -93,7 +93,7 @@
snapshot_name = data_utils.rand_name('test-snap')
meta = {'': ''}
self.assertRaises(lib_exc.BadRequest, self.client.create_image,
- self.server_id, snapshot_name, meta)
+ self.server_id, name=snapshot_name, metadata=meta)
@test.attr(type=['negative'])
@test.idempotent_id('3d24d11f-5366-4536-bd28-cff32b748eca')
@@ -102,7 +102,7 @@
snapshot_name = data_utils.rand_name('test-snap')
meta = {'a' * 260: 'b' * 260}
self.assertRaises(lib_exc.BadRequest, self.client.create_image,
- self.server_id, snapshot_name, meta)
+ self.server_id, name=snapshot_name, metadata=meta)
@test.attr(type=['negative'])
@test.idempotent_id('0460efcf-ee88-4f94-acef-1bf658695456')
@@ -111,8 +111,7 @@
# Create first snapshot
snapshot_name = data_utils.rand_name('test-snap')
- body = self.client.create_image(self.server_id,
- snapshot_name)
+ body = self.client.create_image(self.server_id, name=snapshot_name)
image_id = data_utils.parse_image_id(body.response['location'])
self.image_ids.append(image_id)
self.addCleanup(self._reset_server)
@@ -120,7 +119,7 @@
# Create second snapshot
alt_snapshot_name = data_utils.rand_name('test-snap')
self.assertRaises(lib_exc.Conflict, self.client.create_image,
- self.server_id, alt_snapshot_name)
+ self.server_id, name=alt_snapshot_name)
@test.attr(type=['negative'])
@test.idempotent_id('084f0cbc-500a-4963-8a4e-312905862581')
@@ -129,7 +128,7 @@
snapshot_name = data_utils.rand_name('a' * 260)
self.assertRaises(lib_exc.BadRequest, self.client.create_image,
- self.server_id, snapshot_name)
+ self.server_id, name=snapshot_name)
@test.attr(type=['negative'])
@test.idempotent_id('0894954d-2db2-4195-a45b-ffec0bc0187e')
@@ -137,7 +136,7 @@
# Return an error while trying to delete an image what is creating
snapshot_name = data_utils.rand_name('test-snap')
- body = self.client.create_image(self.server_id, snapshot_name)
+ body = self.client.create_image(self.server_id, name=snapshot_name)
image_id = data_utils.parse_image_id(body.response['location'])
self.image_ids.append(image_id)
self.addCleanup(self._reset_server)
diff --git a/tempest/api/compute/security_groups/test_security_group_rules.py b/tempest/api/compute/security_groups/test_security_group_rules.py
index 4596e1f..b5eff70 100644
--- a/tempest/api/compute/security_groups/test_security_group_rules.py
+++ b/tempest/api/compute/security_groups/test_security_group_rules.py
@@ -69,11 +69,11 @@
security_group = self.create_security_group()
securitygroup_id = security_group['id']
# Adding rules to the created Security Group
- rule = \
- self.client.create_security_group_rule(securitygroup_id,
- self.ip_protocol,
- self.from_port,
- self.to_port)
+ rule = self.client.create_security_group_rule(
+ parent_group_id=securitygroup_id,
+ ip_protocol=self.ip_protocol,
+ from_port=self.from_port,
+ to_port=self.to_port)
self.expected['parent_group_id'] = securitygroup_id
self.expected['ip_range'] = {'cidr': '0.0.0.0/0'}
self._check_expected_response(rule)
@@ -91,12 +91,12 @@
# Adding rules to the created Security Group with optional cidr
cidr = '10.2.3.124/24'
- rule = \
- self.client.create_security_group_rule(parent_group_id,
- self.ip_protocol,
- self.from_port,
- self.to_port,
- cidr=cidr)
+ rule = self.client.create_security_group_rule(
+ parent_group_id=parent_group_id,
+ ip_protocol=self.ip_protocol,
+ from_port=self.from_port,
+ to_port=self.to_port,
+ cidr=cidr)
self.expected['parent_group_id'] = parent_group_id
self.expected['ip_range'] = {'cidr': cidr}
self._check_expected_response(rule)
@@ -118,12 +118,12 @@
group_name = security_group['name']
# Adding rules to the created Security Group with optional group_id
- rule = \
- self.client.create_security_group_rule(parent_group_id,
- self.ip_protocol,
- self.from_port,
- self.to_port,
- group_id=group_id)
+ rule = self.client.create_security_group_rule(
+ parent_group_id=parent_group_id,
+ ip_protocol=self.ip_protocol,
+ from_port=self.from_port,
+ to_port=self.to_port,
+ group_id=group_id)
self.expected['parent_group_id'] = parent_group_id
self.expected['group'] = {'tenant_id': self.client.tenant_id,
'name': group_name}
@@ -140,21 +140,22 @@
securitygroup_id = security_group['id']
# Add a first rule to the created Security Group
- rule = \
- self.client.create_security_group_rule(securitygroup_id,
- self.ip_protocol,
- self.from_port,
- self.to_port)
+ rule = self.client.create_security_group_rule(
+ parent_group_id=securitygroup_id,
+ ip_protocol=self.ip_protocol,
+ from_port=self.from_port,
+ to_port=self.to_port)
rule1_id = rule['id']
# Add a second rule to the created Security Group
ip_protocol2 = 'icmp'
from_port2 = -1
to_port2 = -1
- rule = \
- self.client.create_security_group_rule(securitygroup_id,
- ip_protocol2,
- from_port2, to_port2)
+ rule = self.client.create_security_group_rule(
+ parent_group_id=securitygroup_id,
+ ip_protocol=ip_protocol2,
+ from_port=from_port2,
+ to_port=to_port2)
rule2_id = rule['id']
# Delete the Security Group rule2 at the end of this method
self.addCleanup(self.client.delete_security_group_rule, rule2_id)
@@ -176,11 +177,12 @@
security_group = self.create_security_group()
sg2_id = security_group['id']
# Adding rules to the Group1
- self.client.create_security_group_rule(sg1_id,
- self.ip_protocol,
- self.from_port,
- self.to_port,
- group_id=sg2_id)
+ self.client.create_security_group_rule(
+ parent_group_id=sg1_id,
+ ip_protocol=self.ip_protocol,
+ from_port=self.from_port,
+ to_port=self.to_port,
+ group_id=sg2_id)
# Delete group2
self.security_groups_client.delete_security_group(sg2_id)
diff --git a/tempest/api/compute/security_groups/test_security_group_rules_negative.py b/tempest/api/compute/security_groups/test_security_group_rules_negative.py
index e2a1034..d12306a 100644
--- a/tempest/api/compute/security_groups/test_security_group_rules_negative.py
+++ b/tempest/api/compute/security_groups/test_security_group_rules_negative.py
@@ -51,7 +51,9 @@
to_port = 22
self.assertRaises(lib_exc.NotFound,
self.rules_client.create_security_group_rule,
- parent_group_id, ip_protocol, from_port, to_port)
+ parent_group_id=parent_group_id,
+ ip_protocol=ip_protocol, from_port=from_port,
+ to_port=to_port)
@test.attr(type=['negative'])
@test.idempotent_id('2244d7e4-adb7-4ecb-9930-2d77e123ce4f')
@@ -66,7 +68,9 @@
to_port = 22
self.assertRaises(lib_exc.BadRequest,
self.rules_client.create_security_group_rule,
- parent_group_id, ip_protocol, from_port, to_port)
+ parent_group_id=parent_group_id,
+ ip_protocol=ip_protocol, from_port=from_port,
+ to_port=to_port)
@test.attr(type=['negative'])
@test.idempotent_id('8bd56d02-3ffa-4d67-9933-b6b9a01d6089')
@@ -81,17 +85,17 @@
from_port = 22
to_port = 22
- rule = \
- self.rules_client.create_security_group_rule(parent_group_id,
- ip_protocol,
- from_port,
- to_port)
+ rule = self.rules_client.create_security_group_rule(
+ parent_group_id=parent_group_id, ip_protocol=ip_protocol,
+ from_port=from_port, to_port=to_port)
self.addCleanup(self.rules_client.delete_security_group_rule,
rule['id'])
# Add the same rule to the group should fail
self.assertRaises(lib_exc.BadRequest,
self.rules_client.create_security_group_rule,
- parent_group_id, ip_protocol, from_port, to_port)
+ parent_group_id=parent_group_id,
+ ip_protocol=ip_protocol, from_port=from_port,
+ to_port=to_port)
@test.attr(type=['negative'])
@test.idempotent_id('84c81249-9f6e-439c-9bbf-cbb0d2cddbdf')
@@ -109,7 +113,9 @@
self.assertRaises(lib_exc.BadRequest,
self.rules_client.create_security_group_rule,
- parent_group_id, ip_protocol, from_port, to_port)
+ parent_group_id=parent_group_id,
+ ip_protocol=ip_protocol, from_port=from_port,
+ to_port=to_port)
@test.attr(type=['negative'])
@test.idempotent_id('12bbc875-1045-4f7a-be46-751277baedb9')
@@ -126,7 +132,9 @@
to_port = 22
self.assertRaises(lib_exc.BadRequest,
self.rules_client.create_security_group_rule,
- parent_group_id, ip_protocol, from_port, to_port)
+ parent_group_id=parent_group_id,
+ ip_protocol=ip_protocol, from_port=from_port,
+ to_port=to_port)
@test.attr(type=['negative'])
@test.idempotent_id('ff88804d-144f-45d1-bf59-dd155838a43a')
@@ -143,7 +151,9 @@
to_port = data_utils.rand_int_id(start=65536)
self.assertRaises(lib_exc.BadRequest,
self.rules_client.create_security_group_rule,
- parent_group_id, ip_protocol, from_port, to_port)
+ parent_group_id=parent_group_id,
+ ip_protocol=ip_protocol, from_port=from_port,
+ to_port=to_port)
@test.attr(type=['negative'])
@test.idempotent_id('00296fa9-0576-496a-ae15-fbab843189e0')
@@ -160,7 +170,9 @@
to_port = 21
self.assertRaises(lib_exc.BadRequest,
self.rules_client.create_security_group_rule,
- secgroup_id, ip_protocol, from_port, to_port)
+ parent_group_id=secgroup_id,
+ ip_protocol=ip_protocol, from_port=from_port,
+ to_port=to_port)
@test.attr(type=['negative'])
@test.idempotent_id('56fddcca-dbb8-4494-a0db-96e9f869527c')
diff --git a/tempest/api/compute/test_authorization.py b/tempest/api/compute/test_authorization.py
index 1d7f7fa..e7111b0 100644
--- a/tempest/api/compute/test_authorization.py
+++ b/tempest/api/compute/test_authorization.py
@@ -90,7 +90,8 @@
from_port = 22
to_port = 22
cls.rule = cls.rule_client.create_security_group_rule(
- parent_group_id, ip_protocol, from_port, to_port)
+ parent_group_id=parent_group_id, ip_protocol=ip_protocol,
+ from_port=from_port, to_port=to_port)
@classmethod
def resource_cleanup(cls):
@@ -173,7 +174,7 @@
# A create image request for another user's server should fail
self.assertRaises(lib_exc.NotFound,
self.alt_images_client.create_image,
- self.server['id'], 'testImage')
+ self.server['id'], name='testImage')
@test.idempotent_id('95d445f6-babc-4f2e-aea3-aa24ec5e7f0d')
def test_create_server_with_unauthorized_image(self):
@@ -304,8 +305,9 @@
self.assertRaises(lib_exc.BadRequest,
self.alt_rule_client.
create_security_group_rule,
- parent_group_id, ip_protocol, from_port,
- to_port)
+ parent_group_id=parent_group_id,
+ ip_protocol=ip_protocol,
+ from_port=from_port, to_port=to_port)
finally:
# Next request the base_url is back to normal
if resp['status'] is not None:
diff --git a/tempest/cmd/init.py b/tempest/cmd/init.py
index 0396495..289b978 100644
--- a/tempest/cmd/init.py
+++ b/tempest/cmd/init.py
@@ -15,6 +15,7 @@
import os
import shutil
import subprocess
+import sys
from cliff import command
from oslo_log import log as logging
@@ -33,13 +34,44 @@
"""
+def get_tempest_default_config_dir():
+ """Returns the correct default config dir to support both cases of
+ tempest being or not installed in a virtualenv.
+ Cases considered:
+ - no virtual env, python2: real_prefix and base_prefix not set
+ - no virtual env, python3: real_prefix not set, base_prefix set and
+ identical to prefix
+ - virtualenv, python2: real_prefix and prefix are set and different
+ - virtualenv, python3: real_prefix not set, base_prefix and prefix are
+ set and identical
+ - pyvenv, any python version: real_prefix not set, base_prefix and prefix
+ are set and different
+
+ :return: default config dir
+ """
+ real_prefix = getattr(sys, 'real_prefix', None)
+ base_prefix = getattr(sys, 'base_prefix', None)
+ prefix = sys.prefix
+ if real_prefix is None and base_prefix is None:
+ # Not running in a virtual environnment of any kind
+ return '/etc/tempest'
+ elif (real_prefix is None and base_prefix is not None and
+ base_prefix == prefix):
+ # Probably not running in a virtual environment
+ # NOTE(andreaf) we cannot distinguish this case from the case of
+ # a virtual environment created with virtualenv, and running python3.
+ return '/etc/tempest'
+ else:
+ return os.path.join(sys.prefix, 'etc/tempest')
+
+
class TempestInit(command.Command):
"""Setup a local working environment for running tempest"""
def get_parser(self, prog_name):
parser = super(TempestInit, self).get_parser(prog_name)
parser.add_argument('dir', nargs='?', default=os.getcwd())
- parser.add_argument('--config-dir', '-c', default='/etc/tempest')
+ parser.add_argument('--config-dir', '-c', default=None)
return parser
def generate_testr_conf(self, local_path):
@@ -103,4 +135,5 @@
subprocess.call(['testr', 'init'], cwd=local_dir)
def take_action(self, parsed_args):
- self.create_working_dir(parsed_args.dir, parsed_args.config_dir)
+ config_dir = parsed_args.config_dir or get_tempest_default_config_dir()
+ self.create_working_dir(parsed_args.dir, config_dir)
diff --git a/tempest/cmd/javelin.py b/tempest/cmd/javelin.py
index 9402154..30fb38c 100755
--- a/tempest/cmd/javelin.py
+++ b/tempest/cmd/javelin.py
@@ -921,7 +921,8 @@
for rule in secgroup['rules']:
ip_proto, from_port, to_port, cidr = rule.split()
client.secrules.create_security_group_rule(
- secgroup_id, ip_proto, from_port, to_port, cidr=cidr)
+ parent_group_id=secgroup_id, ip_protocol=ip_proto,
+ from_port=from_port, to_port=to_port, cidr=cidr)
def destroy_secgroups(secgroups):
diff --git a/tempest/common/validation_resources.py b/tempest/common/validation_resources.py
index 15c452f..402638d 100644
--- a/tempest/common/validation_resources.py
+++ b/tempest/common/validation_resources.py
@@ -30,10 +30,12 @@
security_group_client.create_security_group(name=sg_name,
description=sg_description)
if add_rule:
- security_group_client.create_security_group_rule(security_group['id'],
- 'tcp', 22, 22)
- security_group_client.create_security_group_rule(security_group['id'],
- 'icmp', -1, -1)
+ security_group_client.create_security_group_rule(
+ parent_group_id=security_group['id'], ip_protocol='tcp',
+ from_port=22, to_port=22)
+ security_group_client.create_security_group_rule(
+ parent_group_id=security_group['id'], ip_protocol='icmp',
+ from_port=-1, to_port=-1)
LOG.debug("SSH Validation resource security group with tcp and icmp "
"rules %s created"
% sg_name)
diff --git a/tempest/config.py b/tempest/config.py
index ab503e3..48417c3 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -1224,7 +1224,10 @@
The purpose of this is to allow tools like the Oslo sample config file
generator to discover the options exposed to users.
"""
- return [(getattr(g, 'name', None), o) for g, o in _opts]
+ ext_plugins = plugins.TempestTestPluginManager()
+ opt_list = [(getattr(g, 'name', None), o) for g, o in _opts]
+ opt_list.extend(ext_plugins.get_plugin_options_list())
+ return opt_list
# this should never be called outside of this class
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index bb0ccdd..60bf7cb 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -233,14 +233,14 @@
rulesets = [
{
# ssh
- 'ip_proto': 'tcp',
+ 'ip_protocol': 'tcp',
'from_port': 22,
'to_port': 22,
'cidr': '0.0.0.0/0',
},
{
# ping
- 'ip_proto': 'icmp',
+ 'ip_protocol': 'icmp',
'from_port': -1,
'to_port': -1,
'cidr': '0.0.0.0/0',
@@ -248,8 +248,8 @@
]
rules = list()
for ruleset in rulesets:
- sg_rule = _client_rules.create_security_group_rule(secgroup_id,
- **ruleset)
+ sg_rule = _client_rules.create_security_group_rule(
+ parent_group_id=secgroup_id, **ruleset)
self.addCleanup(self.delete_wrapper,
_client_rules.delete_security_group_rule,
sg_rule['id'])
@@ -402,7 +402,7 @@
if name is None:
name = data_utils.rand_name('scenario-snapshot')
LOG.debug("Creating a snapshot image for server: %s", server['name'])
- image = _images_client.create_image(server['id'], name)
+ image = _images_client.create_image(server['id'], name=name)
image_id = image.response['location'].split('images/')[1]
_image_client.wait_for_image_status(image_id, 'active')
self.addCleanup_with_wait(
diff --git a/tempest/services/compute/json/images_client.py b/tempest/services/compute/json/images_client.py
index b0ce2dc..4e7e93f 100644
--- a/tempest/services/compute/json/images_client.py
+++ b/tempest/services/compute/json/images_client.py
@@ -23,18 +23,10 @@
class ImagesClient(service_client.ServiceClient):
- def create_image(self, server_id, name, meta=None):
+ def create_image(self, server_id, **kwargs):
"""Creates an image of the original server."""
- post_body = {
- 'createImage': {
- 'name': name,
- }
- }
-
- if meta is not None:
- post_body['createImage']['metadata'] = meta
-
+ post_body = {'createImage': kwargs}
post_body = json.dumps(post_body)
resp, body = self.post('servers/%s/action' % server_id,
post_body)
diff --git a/tempest/services/compute/json/security_group_rules_client.py b/tempest/services/compute/json/security_group_rules_client.py
index f570eb7..9a7c881 100644
--- a/tempest/services/compute/json/security_group_rules_client.py
+++ b/tempest/services/compute/json/security_group_rules_client.py
@@ -23,8 +23,7 @@
class SecurityGroupRulesClient(service_client.ServiceClient):
- def create_security_group_rule(self, parent_group_id, ip_proto, from_port,
- to_port, **kwargs):
+ def create_security_group_rule(self, **kwargs):
"""
Creating a new security group rules.
parent_group_id :ID of Security group
@@ -35,15 +34,7 @@
cidr : CIDR for address range.
group_id : ID of the Source group
"""
- post_body = {
- 'parent_group_id': parent_group_id,
- 'ip_protocol': ip_proto,
- 'from_port': from_port,
- 'to_port': to_port,
- 'cidr': kwargs.get('cidr'),
- 'group_id': kwargs.get('group_id'),
- }
- post_body = json.dumps({'security_group_rule': post_body})
+ post_body = json.dumps({'security_group_rule': kwargs})
url = 'os-security-group-rules'
resp, body = self.post(url, post_body)
body = json.loads(body)
diff --git a/tempest/stress/actions/ssh_floating.py b/tempest/stress/actions/ssh_floating.py
index 03a2d27..09e6d88 100644
--- a/tempest/stress/actions/ssh_floating.py
+++ b/tempest/stress/actions/ssh_floating.py
@@ -96,8 +96,10 @@
self.sec_grp = sec_grp_cli.create_security_group(
name=s_name, description=s_description)
create_rule = sec_grp_cli.create_security_group_rule
- create_rule(self.sec_grp['id'], 'tcp', 22, 22)
- create_rule(self.sec_grp['id'], 'icmp', -1, -1)
+ create_rule(parent_group_id=self.sec_grp['id'], ip_protocol='tcp',
+ from_port=22, to_port=22)
+ create_rule(parent_group_id=self.sec_grp['id'], ip_protocol='icmp',
+ from_port=-1, to_port=-1)
def _destroy_sec_grp(self):
sec_grp_cli = self.manager.security_groups_client
diff --git a/tempest/stress/actions/volume_attach_verify.py b/tempest/stress/actions/volume_attach_verify.py
index 93a443e..0e0141f 100644
--- a/tempest/stress/actions/volume_attach_verify.py
+++ b/tempest/stress/actions/volume_attach_verify.py
@@ -58,8 +58,10 @@
self.sec_grp = sec_grp_cli.create_security_group(
name=s_name, description=s_description)
create_rule = sec_grp_cli.create_security_group_rule
- create_rule(self.sec_grp['id'], 'tcp', 22, 22)
- create_rule(self.sec_grp['id'], 'icmp', -1, -1)
+ create_rule(parent_group_id=self.sec_grp['id'], ip_protocol='tcp',
+ from_port=22, to_port=22)
+ create_rule(parent_group_id=self.sec_grp['id'], ip_protocol='icmp',
+ from_port=-1, to_port=-1)
def _destroy_sec_grp(self):
sec_grp_cli = self.manager.security_groups_client
diff --git a/tempest/test_discover/plugins.py b/tempest/test_discover/plugins.py
index 45cd609..640b004 100644
--- a/tempest/test_discover/plugins.py
+++ b/tempest/test_discover/plugins.py
@@ -51,6 +51,16 @@
"""
return
+ @abc.abstractmethod
+ def get_opt_lists(self):
+ """Method to get a list of options for sample config generation
+
+ :return option_list: A list of tuples with the group name and options
+ in that group.
+ :rtype: list
+ """
+ return []
+
@misc.singleton
class TempestTestPluginManager(object):
@@ -79,3 +89,11 @@
def register_plugin_opts(self, conf):
for plug in self.ext_plugins:
plug.obj.register_opts(conf)
+
+ def get_plugin_options_list(self):
+ plugin_options = []
+ for plug in self.ext_plugins:
+ opt_list = plug.obj.get_opt_lists()
+ if opt_list:
+ plugin_options.extend(opt_list)
+ return plugin_options