Merge "Add unit test for server_groups_client"
diff --git a/.gitignore b/.gitignore
index f584532..efba45e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,4 +19,4 @@
.coverage*
!.coveragerc
cover/
-doc/source/_static/tempest.conf
+doc/source/_static/tempest.conf.sample
diff --git a/REVIEWING.rst b/REVIEWING.rst
index 12ccb75..f7334ad 100644
--- a/REVIEWING.rst
+++ b/REVIEWING.rst
@@ -51,6 +51,19 @@
whether to skip or not.
+Configuration Options
+---------------------
+With the introduction of the tempest external test plugin interface we needed
+to provide a stable contract for tempest's configuration options. This means
+we can no longer simply remove a configuration option when it's no longer used.
+Patches proposed that remove options without a deprecation cycle should not
+be approved. Similarly when changing default values with configuration we need
+to similarly be careful that we don't break existing functionality. Also, when
+adding options, just as before, we need to weigh the benefit of adding an
+additional option against the complexity and maintenance overhead having it
+costs.
+
+
Test Documentation
------------------
When a new test is being added refer to the :ref:`TestDocumentation` section in
diff --git a/doc/source/conf.py b/doc/source/conf.py
index 3ec25ea..f85899b 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -15,18 +15,6 @@
import os
import subprocess
-# Build a tempest sample config file:
-def build_sample_config(app):
- root_dir = os.path.dirname(
- os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
- subprocess.call(["oslo-config-generator", "--config-file",
- "tools/config/config-generator.tempest.conf",
- "--output-file", "doc/source/_static/tempest.conf"],
- cwd=root_dir)
-
-def setup(app):
- app.connect('builder-inited', build_sample_config)
-
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
@@ -42,9 +30,13 @@
extensions = ['sphinx.ext.autodoc',
'sphinx.ext.todo',
'sphinx.ext.viewcode',
- 'oslosphinx'
+ 'oslosphinx',
+ 'oslo_config.sphinxconfiggen',
]
+config_generator_config_file = '../../tools/config/config-generator.tempest.conf'
+sample_config_basename = '_static/tempest'
+
todo_include_todos = True
# Add any paths that contain templates here, relative to this directory.
diff --git a/doc/source/sampleconf.rst b/doc/source/sampleconf.rst
index 2a72971..c290140 100644
--- a/doc/source/sampleconf.rst
+++ b/doc/source/sampleconf.rst
@@ -8,7 +8,6 @@
if you are having issues with an option, please compare your version of
Tempest with the version of this documentation.
-The sample configuration can also be viewed in `file form <_static/tempest.conf>`_.
+The sample configuration can also be viewed in `file form <_static/tempest.conf.sample>`_.
-.. include:: _static/tempest.conf
- :code:
+.. literalinclude:: _static/tempest.conf.sample
diff --git a/requirements.txt b/requirements.txt
index 5ebcb65..b25b9d3 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,7 +1,7 @@
# The order of packages is significant, because pip processes them in the order
# of appearance. Changing the order has an impact on the overall integration
# process, which may cause wedges in the gate later.
-pbr<2.0,>=1.4
+pbr<2.0,>=1.6
cliff>=1.14.0 # Apache-2.0
anyjson>=0.3.3
httplib2>=0.7.5
@@ -9,11 +9,11 @@
testtools>=1.4.0
boto>=2.32.1
paramiko>=1.13.0
-netaddr>=0.7.12,!=0.7.16
+netaddr!=0.7.16,>=0.7.12
testrepository>=0.0.18
pyOpenSSL>=0.14
oslo.concurrency>=2.3.0 # Apache-2.0
-oslo.config>=2.1.0 # Apache-2.0
+oslo.config>=2.3.0 # Apache-2.0
oslo.i18n>=1.5.0 # Apache-2.0
oslo.log>=1.8.0 # Apache-2.0
oslo.serialization>=1.4.0 # Apache-2.0
diff --git a/tempest/api/compute/admin/test_floating_ips_bulk.py b/tempest/api/compute/admin/test_floating_ips_bulk.py
index c8ca938..e979616 100644
--- a/tempest/api/compute/admin/test_floating_ips_bulk.py
+++ b/tempest/api/compute/admin/test_floating_ips_bulk.py
@@ -80,5 +80,6 @@
self.assertNotEqual(0, len(ips_list))
for ip in netaddr.IPNetwork(self.ip_range).iter_hosts():
self.assertIn(str(ip), map(lambda x: x['address'], ips_list))
- body = self.client.delete_floating_ips_bulk(self.ip_range)
- self.assertEqual(self.ip_range, body.data)
+ body = (self.client.delete_floating_ips_bulk(self.ip_range)
+ ['floating_ips_bulk_delete'])
+ self.assertEqual(self.ip_range, body)
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 2624fca..1f53f9a 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -75,7 +75,6 @@
cls.networks_client = cls.os.networks_client
cls.limits_client = cls.os.limits_client
cls.volumes_extensions_client = cls.os.volumes_extensions_client
- cls.volumes_client = cls.os.volumes_client
cls.interfaces_client = cls.os.interfaces_client
cls.fixed_ips_client = cls.os.fixed_ips_client
cls.availability_zone_client = cls.os.availability_zone_client
@@ -91,6 +90,11 @@
cls.os.security_group_default_rules_client)
cls.versions_client = cls.os.compute_versions_client
+ if CONF.volume_feature_enabled.api_v1:
+ cls.volumes_client = cls.os.volumes_client
+ else:
+ cls.volumes_client = cls.os.volumes_v2_client
+
@classmethod
def resource_setup(cls):
super(BaseComputeTest, cls).resource_setup()
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 3c22d28..9aa59f7 100644
--- a/tempest/api/compute/security_groups/test_security_group_rules.py
+++ b/tempest/api/compute/security_groups/test_security_group_rules.py
@@ -161,8 +161,8 @@
self.addCleanup(self.client.delete_security_group_rule, rule2_id)
# Get rules of the created Security Group
- rules = (self.client.list_security_group_rules(securitygroup_id)
- ['rules'])
+ rules = self.security_groups_client.show_security_group(
+ securitygroup_id)['security_group']['rules']
self.assertTrue(any([i for i in rules if i['id'] == rule1_id]))
self.assertTrue(any([i for i in rules if i['id'] == rule2_id]))
@@ -187,6 +187,7 @@
# Delete group2
self.security_groups_client.delete_security_group(sg2_id)
# Get rules of the Group1
- rules = self.client.list_security_group_rules(sg1_id)['rules']
+ rules = (self.security_groups_client.show_security_group(sg1_id)
+ ['security_group']['rules'])
# The group1 has no rules because group2 has deleted
self.assertEqual(0, len(rules))
diff --git a/tempest/api/compute/servers/test_delete_server.py b/tempest/api/compute/servers/test_delete_server.py
index d7b4470..5d461ab 100644
--- a/tempest/api/compute/servers/test_delete_server.py
+++ b/tempest/api/compute/servers/test_delete_server.py
@@ -117,7 +117,8 @@
device = '/dev/%s' % CONF.compute.volume_device_name
server = self.create_test_server(wait_until='ACTIVE')
- volume = volumes_client.create_volume(size=CONF.volume.volume_size)
+ volume = (volumes_client.create_volume(size=CONF.volume.volume_size)
+ ['volume'])
self.addCleanup(volumes_client.delete_volume, volume['id'])
waiters.wait_for_volume_status(volumes_client,
volume['id'], 'available')
diff --git a/tempest/api/compute/servers/test_server_rescue_negative.py b/tempest/api/compute/servers/test_server_rescue_negative.py
index 9d06188..f8567cf 100644
--- a/tempest/api/compute/servers/test_server_rescue_negative.py
+++ b/tempest/api/compute/servers/test_server_rescue_negative.py
@@ -62,7 +62,7 @@
def _create_volume(self):
volume = self.volumes_extensions_client.create_volume(
size=CONF.volume.volume_size, display_name=data_utils.rand_name(
- self.__class__.__name__ + '_volume'))
+ self.__class__.__name__ + '_volume'))['volume']
self.addCleanup(self.delete_volume, volume['id'])
waiters.wait_for_volume_status(self.volumes_extensions_client,
volume['id'], 'available')
diff --git a/tempest/api/compute/volumes/test_volumes_get.py b/tempest/api/compute/volumes/test_volumes_get.py
index f05a5a3..6074054 100644
--- a/tempest/api/compute/volumes/test_volumes_get.py
+++ b/tempest/api/compute/volumes/test_volumes_get.py
@@ -48,7 +48,7 @@
# Create volume
volume = self.client.create_volume(size=CONF.volume.volume_size,
display_name=v_name,
- metadata=metadata)
+ metadata=metadata)['volume']
self.addCleanup(self.delete_volume, volume['id'])
self.assertIn('id', volume)
self.assertIn('displayName', volume)
@@ -60,7 +60,7 @@
# Wait for Volume status to become ACTIVE
waiters.wait_for_volume_status(self.client, volume['id'], 'available')
# GET Volume
- fetched_volume = self.client.show_volume(volume['id'])
+ fetched_volume = self.client.show_volume(volume['id'])['volume']
# Verification of details of fetched Volume
self.assertEqual(v_name,
fetched_volume['displayName'],
diff --git a/tempest/api/compute/volumes/test_volumes_list.py b/tempest/api/compute/volumes/test_volumes_list.py
index 421d96f..f0ed141 100644
--- a/tempest/api/compute/volumes/test_volumes_list.py
+++ b/tempest/api/compute/volumes/test_volumes_list.py
@@ -56,10 +56,10 @@
try:
volume = cls.client.create_volume(size=CONF.volume.volume_size,
display_name=v_name,
- metadata=metadata)
+ metadata=metadata)['volume']
waiters.wait_for_volume_status(cls.client,
volume['id'], 'available')
- volume = cls.client.show_volume(volume['id'])
+ volume = cls.client.show_volume(volume['id'])['volume']
cls.volume_list.append(volume)
cls.volume_id_list.append(volume['id'])
except Exception:
@@ -89,7 +89,7 @@
def test_volume_list(self):
# Should return the list of Volumes
# Fetch all Volumes
- fetched_list = self.client.list_volumes()
+ fetched_list = self.client.list_volumes()['volumes']
# Now check if all the Volumes created in setup are in fetched list
missing_volumes = [
v for v in self.volume_list if v not in fetched_list
@@ -104,7 +104,7 @@
def test_volume_list_with_details(self):
# Should return the list of Volumes with details
# Fetch all Volumes
- fetched_list = self.client.list_volumes(detail=True)
+ fetched_list = self.client.list_volumes(detail=True)['volumes']
# Now check if all the Volumes created in setup are in fetched list
missing_volumes = [
v for v in self.volume_list if v not in fetched_list
@@ -119,7 +119,7 @@
def test_volume_list_param_limit(self):
# Return the list of volumes based on limit set
params = {'limit': 2}
- fetched_vol_list = self.client.list_volumes(**params)
+ fetched_vol_list = self.client.list_volumes(**params)['volumes']
self.assertEqual(len(fetched_vol_list), params['limit'],
"Failed to list volumes by limit set")
@@ -128,7 +128,8 @@
def test_volume_list_with_detail_param_limit(self):
# Return the list of volumes with details based on limit set.
params = {'limit': 2}
- fetched_vol_list = self.client.list_volumes(detail=True, **params)
+ fetched_vol_list = self.client.list_volumes(detail=True,
+ **params)['volumes']
self.assertEqual(len(fetched_vol_list), params['limit'],
"Failed to list volume details by limit set")
@@ -137,9 +138,9 @@
def test_volume_list_param_offset_and_limit(self):
# Return the list of volumes based on offset and limit set.
# get all volumes list
- all_vol_list = self.client.list_volumes()
+ all_vol_list = self.client.list_volumes()['volumes']
params = {'offset': 1, 'limit': 1}
- fetched_vol_list = self.client.list_volumes(**params)
+ fetched_vol_list = self.client.list_volumes(**params)['volumes']
# Validating length of the fetched volumes
self.assertEqual(len(fetched_vol_list), params['limit'],
@@ -154,9 +155,10 @@
def test_volume_list_with_detail_param_offset_and_limit(self):
# Return the list of volumes details based on offset and limit set.
# get all volumes list
- all_vol_list = self.client.list_volumes(detail=True)
+ all_vol_list = self.client.list_volumes(detail=True)['volumes']
params = {'offset': 1, 'limit': 1}
- fetched_vol_list = self.client.list_volumes(detail=True, **params)
+ fetched_vol_list = self.client.list_volumes(detail=True,
+ **params)['volumes']
# Validating length of the fetched volumes
self.assertEqual(len(fetched_vol_list), params['limit'],
diff --git a/tempest/api/identity/admin/v3/test_tokens.py b/tempest/api/identity/admin/v3/test_tokens.py
index 5681ac6..b5f86da 100644
--- a/tempest/api/identity/admin/v3/test_tokens.py
+++ b/tempest/api/identity/admin/v3/test_tokens.py
@@ -92,7 +92,6 @@
token_id = token_auth.response['x-subject-token']
orig_expires_at = token_auth['token']['expires_at']
- orig_issued_at = token_auth['token']['issued_at']
orig_user = token_auth['token']['user']
self.assertIsInstance(token_auth['token']['expires_at'], unicode)
@@ -117,7 +116,6 @@
self.assertEqual(orig_expires_at, token_auth['token']['expires_at'],
'Expiration time should match original token')
self.assertIsInstance(token_auth['token']['issued_at'], unicode)
- self.assertNotEqual(orig_issued_at, token_auth['token']['issued_at'])
self.assertEqual(set(['password', 'token']),
set(token_auth['token']['methods']))
self.assertEqual(orig_user, token_auth['token']['user'],
diff --git a/tempest/api/telemetry/test_telemetry_notification_api.py b/tempest/api/telemetry/test_telemetry_notification_api.py
index 71a00c9..31eff9d 100644
--- a/tempest/api/telemetry/test_telemetry_notification_api.py
+++ b/tempest/api/telemetry/test_telemetry_notification_api.py
@@ -22,13 +22,6 @@
class TelemetryNotificationAPITestJSON(base.BaseTelemetryTest):
- @classmethod
- def skip_checks(cls):
- super(TelemetryNotificationAPITestJSON, cls).skip_checks()
- if CONF.telemetry.too_slow_to_test:
- raise cls.skipException("Ceilometer feature for fast work mysql "
- "is disabled")
-
@test.idempotent_id('d7f8c1c8-d470-4731-8604-315d3956caad')
@test.services('compute')
def test_check_nova_notification(self):
@@ -75,13 +68,6 @@
class TelemetryNotificationAdminAPITestJSON(base.BaseTelemetryAdminTest):
- @classmethod
- def skip_checks(cls):
- super(TelemetryNotificationAdminAPITestJSON, cls).skip_checks()
- if CONF.telemetry.too_slow_to_test:
- raise cls.skipException("Ceilometer feature for fast work mysql "
- "is disabled")
-
@test.idempotent_id('29604198-8b45-4fc0-8af8-1cae4f94ebe9')
@test.services('compute')
@decorators.skip_because(bug='1480490')
diff --git a/tempest/api/volume/admin/test_volume_quotas.py b/tempest/api/volume/admin/test_volume_quotas.py
index 1a48204..f9117ed 100644
--- a/tempest/api/volume/admin/test_volume_quotas.py
+++ b/tempest/api/volume/admin/test_volume_quotas.py
@@ -32,14 +32,15 @@
@test.idempotent_id('59eada70-403c-4cef-a2a3-a8ce2f1b07a0')
def test_list_quotas(self):
- quotas = self.quotas_client.show_quota_set(self.demo_tenant_id)
+ quotas = (self.quotas_client.show_quota_set(self.demo_tenant_id)
+ ['quota_set'])
for key in QUOTA_KEYS:
self.assertIn(key, quotas)
@test.idempotent_id('2be020a2-5fdd-423d-8d35-a7ffbc36e9f7')
def test_list_default_quotas(self):
quotas = self.quotas_client.show_default_quota_set(
- self.demo_tenant_id)
+ self.demo_tenant_id)['quota_set']
for key in QUOTA_KEYS:
self.assertIn(key, quotas)
@@ -47,7 +48,7 @@
def test_update_all_quota_resources_for_tenant(self):
# Admin can update all the resource quota limits for a tenant
default_quota_set = self.quotas_client.show_default_quota_set(
- self.demo_tenant_id)
+ self.demo_tenant_id)['quota_set']
new_quota_set = {'gigabytes': 1009,
'volumes': 11,
'snapshots': 11}
@@ -55,7 +56,7 @@
# Update limits for all quota resources
quota_set = self.quotas_client.update_quota_set(
self.demo_tenant_id,
- **new_quota_set)
+ **new_quota_set)['quota_set']
cleanup_quota_set = dict(
(k, v) for k, v in six.iteritems(default_quota_set)
@@ -70,7 +71,7 @@
@test.idempotent_id('18c51ae9-cb03-48fc-b234-14a19374dbed')
def test_show_quota_usage(self):
quota_usage = self.quotas_client.show_quota_usage(
- self.os_adm.credentials.tenant_id)
+ self.os_adm.credentials.tenant_id)['quota_set']
for key in QUOTA_KEYS:
self.assertIn(key, quota_usage)
for usage_key in QUOTA_USAGE_KEYS:
@@ -79,14 +80,14 @@
@test.idempotent_id('ae8b6091-48ad-4bfa-a188-bbf5cc02115f')
def test_quota_usage(self):
quota_usage = self.quotas_client.show_quota_usage(
- self.demo_tenant_id)
+ self.demo_tenant_id)['quota_set']
volume = self.create_volume()
self.addCleanup(self.admin_volume_client.delete_volume,
volume['id'])
new_quota_usage = self.quotas_client.show_quota_usage(
- self.demo_tenant_id)
+ self.demo_tenant_id)['quota_set']
self.assertEqual(quota_usage['volumes']['in_use'] + 1,
new_quota_usage['volumes']['in_use'])
@@ -104,14 +105,15 @@
tenant_id = tenant['id']
self.addCleanup(identity_client.delete_tenant, tenant_id)
quota_set_default = self.quotas_client.show_default_quota_set(
- tenant_id)
+ tenant_id)['quota_set']
volume_default = quota_set_default['volumes']
self.quotas_client.update_quota_set(tenant_id,
volumes=(int(volume_default) + 5))
self.quotas_client.delete_quota_set(tenant_id)
- quota_set_new = self.quotas_client.show_quota_set(tenant_id)
+ quota_set_new = (self.quotas_client.show_quota_set(tenant_id)
+ ['quota_set'])
self.assertEqual(volume_default, quota_set_new['volumes'])
diff --git a/tempest/api_schema/response/compute/v2_1/versions.py b/tempest/api_schema/response/compute/v2_1/versions.py
index a01dd41..f08695c 100644
--- a/tempest/api_schema/response/compute/v2_1/versions.py
+++ b/tempest/api_schema/response/compute/v2_1/versions.py
@@ -12,6 +12,33 @@
# License for the specific language governing permissions and limitations
# under the License.
+_version = {
+ 'type': 'object',
+ 'properties': {
+ 'id': {'type': 'string'},
+ 'links': {
+ 'type': 'array',
+ 'items': {
+ 'type': 'object',
+ 'properties': {
+ 'href': {'type': 'string', 'format': 'uri'},
+ 'rel': {'type': 'string'},
+ },
+ 'required': ['href', 'rel'],
+ 'additionalProperties': False
+ }
+ },
+ 'status': {'type': 'string'},
+ 'updated': {'type': 'string', 'format': 'date-time'},
+ 'version': {'type': 'string'},
+ 'min_version': {'type': 'string'}
+ },
+ # NOTE: version and min_version have been added since Kilo,
+ # so they should not be required.
+ 'required': ['id', 'links', 'status', 'updated'],
+ 'additionalProperties': False
+}
+
list_versions = {
'status_code': [200],
'response_body': {
@@ -19,33 +46,7 @@
'properties': {
'versions': {
'type': 'array',
- 'items': {
- 'type': 'object',
- 'properties': {
- 'id': {'type': 'string'},
- 'links': {
- 'type': 'array',
- 'items': {
- 'type': 'object',
- 'properties': {
- 'href': {'type': 'string',
- 'format': 'uri'},
- 'rel': {'type': 'string'},
- },
- 'required': ['href', 'rel'],
- 'additionalProperties': False
- }
- },
- 'status': {'type': 'string'},
- 'updated': {'type': 'string', 'format': 'date-time'},
- 'version': {'type': 'string'},
- 'min_version': {'type': 'string'}
- },
- # NOTE: version and min_version have been added since Kilo,
- # so they should not be required.
- 'required': ['id', 'links', 'status', 'updated'],
- 'additionalProperties': False
- }
+ 'items': _version
}
},
'required': ['versions'],
diff --git a/tempest/cmd/account_generator.py b/tempest/cmd/account_generator.py
index 3d24547..ce7728e 100755
--- a/tempest/cmd/account_generator.py
+++ b/tempest/cmd/account_generator.py
@@ -90,7 +90,7 @@
import yaml
from tempest import config
-from tempest import exceptions
+from tempest import exceptions as exc
from tempest.services.identity.v2.json import identity_client
from tempest.services.network.json import network_client
import tempest_lib.auth
@@ -155,11 +155,10 @@
for r in u.get('roles', ()):
try:
role = filter(lambda r_: r_['name'] == r, roles)[0]
- u['role_ids'] += [role['id']]
except IndexError:
- raise exceptions.TempestException(
- "Role: %s - doesn't exist" % r
- )
+ msg = "Role: %s doesn't exist" % r
+ raise exc.InvalidConfiguration(msg)
+ u['role_ids'] += [role['id']]
existing = [x['name'] for x in identity_admin.list_tenants()['tenants']]
for tenant in resources['tenants']:
if tenant not in existing:
@@ -285,17 +284,21 @@
{'number': 1,
'prefix': 'alt',
'roles': (CONF.auth.tempest_roles +
- [CONF.object_storage.operator_role])},
- {'number': 1,
- 'prefix': 'swift_admin',
- 'roles': (CONF.auth.tempest_roles +
- [CONF.object_storage.operator_role,
- CONF.object_storage.reseller_admin_role])},
- {'number': 1,
- 'prefix': 'stack_owner',
- 'roles': (CONF.auth.tempest_roles +
- [CONF.orchestration.stack_owner_role])},
- ]
+ [CONF.object_storage.operator_role])}]
+ if CONF.service_available.swift:
+ spec.append({'number': 1,
+ 'prefix': 'swift_operator',
+ 'roles': (CONF.auth.tempest_roles +
+ [CONF.object_storage.operator_role])})
+ spec.append({'number': 1,
+ 'prefix': 'swift_reseller_admin',
+ 'roles': (CONF.auth.tempest_roles +
+ [CONF.object_storage.reseller_admin_role])})
+ if CONF.service_available.heat:
+ spec.append({'number': 1,
+ 'prefix': 'stack_owner',
+ 'roles': (CONF.auth.tempest_roles +
+ [CONF.orchestration.stack_owner_role])})
if opts.admin:
spec.append({
'number': 1,
diff --git a/tempest/cmd/cleanup_service.py b/tempest/cmd/cleanup_service.py
index 8c4687b..6d4e3a9 100644
--- a/tempest/cmd/cleanup_service.py
+++ b/tempest/cmd/cleanup_service.py
@@ -353,7 +353,7 @@
LOG.exception("Delete Volume Quotas exception.")
def dry_run(self):
- quotas = self.client.show_quota_usage(self.tenant_id)
+ quotas = self.client.show_quota_usage(self.tenant_id)['quota_set']
self.data['volume_quotas'] = quotas
diff --git a/tempest/cmd/verify_tempest_config.py b/tempest/cmd/verify_tempest_config.py
index 9e7d894..6d53b59 100755
--- a/tempest/cmd/verify_tempest_config.py
+++ b/tempest/cmd/verify_tempest_config.py
@@ -144,6 +144,12 @@
'neutron': os.network_client,
'swift': os.account_client,
}
+ # NOTE (e0ne): Use Cinder API v2 by default because v1 is deprecated
+ if CONF.volume_feature_enabled.api_v2:
+ extensions_client['cinder'] = os.volumes_v2_extension_client
+ else:
+ extensions_client['cinder'] = os.volumes_extension_client
+
if service not in extensions_client:
print('No tempest extensions client for %s' % service)
exit(1)
diff --git a/tempest/common/waiters.py b/tempest/common/waiters.py
index b0afcc1..248513e 100644
--- a/tempest/common/waiters.py
+++ b/tempest/common/waiters.py
@@ -162,20 +162,13 @@
def wait_for_volume_status(client, volume_id, status):
"""Waits for a Volume to reach a given status."""
- body = client.show_volume(volume_id)
- if 'volume' in body:
- body = body['volume']
+ body = client.show_volume(volume_id)['volume']
volume_status = body['status']
start = int(time.time())
while volume_status != status:
time.sleep(client.build_interval)
- body = client.show_volume(volume_id)
- # TODO(jswarren) always extract 'volume' value
- # once the compute clients also return the full
- # response.
- if 'volume' in body:
- body = body['volume']
+ body = client.show_volume(volume_id)['volume']
volume_status = body['status']
if volume_status == 'error':
raise exceptions.VolumeBuildErrorException(volume_id=volume_id)
diff --git a/tempest/config.py b/tempest/config.py
index b6daa2e..295b74d 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -117,9 +117,7 @@
choices=['public', 'admin', 'internal',
'publicURL', 'adminURL', 'internalURL'],
help="The admin endpoint type to use for OpenStack Identity "
- "(Keystone) API v2",
- deprecated_opts=[cfg.DeprecatedOpt('endpoint_type',
- group='identity')]),
+ "(Keystone) API v2"),
cfg.StrOpt('v2_public_endpoint_type',
default='publicURL',
choices=['public', 'admin', 'internal',
@@ -133,9 +131,7 @@
choices=['public', 'admin', 'internal',
'publicURL', 'adminURL', 'internalURL'],
help="The endpoint type to use for OpenStack Identity "
- "(Keystone) API v3",
- deprecated_opts=[cfg.DeprecatedOpt('endpoint_type',
- group='identity')]),
+ "(Keystone) API v3"),
cfg.StrOpt('username',
help="Username to use for Nova API requests."),
cfg.StrOpt('tenant_name',
@@ -611,6 +607,12 @@
' validation resources to enable remote access',
deprecated_opts=[cfg.DeprecatedOpt('run_ssh',
group='compute')]),
+ cfg.BoolOpt('security_group',
+ default=True,
+ help='Enable/disable security groups.'),
+ cfg.BoolOpt('security_group_rules',
+ default=True,
+ help='Enable/disable security group rules.'),
cfg.StrOpt('connect_method',
default='floating',
choices=['fixed', 'floating'],
@@ -860,6 +862,7 @@
help="The endpoint type to use for the telemetry service."),
cfg.BoolOpt('too_slow_to_test',
default=True,
+ deprecated_for_removal=True,
help="This variable is used as flag to enable "
"notification tests")
]
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 644e551..4f113d3 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -58,14 +58,19 @@
cls.security_group_rules_client = (
cls.manager.security_group_rules_client)
cls.servers_client = cls.manager.servers_client
- cls.volumes_client = cls.manager.volumes_client
- cls.snapshots_client = cls.manager.snapshots_client
cls.interface_client = cls.manager.interfaces_client
# Neutron network client
cls.network_client = cls.manager.network_client
# Heat client
cls.orchestration_client = cls.manager.orchestration_client
+ if CONF.volume_feature_enabled.api_v1:
+ cls.volumes_client = cls.manager.volumes_client
+ cls.snapshots_client = cls.manager.snapshots_client
+ else:
+ cls.volumes_client = cls.manager.volumes_v2_client
+ cls.snapshots_client = cls.manager.snapshots_v2_client
+
# ## Methods to handle sync and async deletes
def setUp(self):
@@ -216,7 +221,11 @@
cleanup_callable=self.delete_wrapper,
cleanup_args=[self.volumes_client.delete_volume, volume['id']])
- self.assertEqual(name, volume['display_name'])
+ # NOTE(e0ne): Cinder API v2 uses name instead of display_name
+ if 'display_name' in volume:
+ self.assertEqual(name, volume['display_name'])
+ else:
+ self.assertEqual(name, volume['name'])
self.volumes_client.wait_for_volume_status(volume['id'], 'available')
# The volume retrieved on creation has a non-up-to-date status.
# Retrieval after it becomes active ensures correct details.
@@ -1291,7 +1300,10 @@
@classmethod
def setup_clients(cls):
super(EncryptionScenarioTest, cls).setup_clients()
- cls.admin_volume_types_client = cls.os_adm.volume_types_client
+ if CONF.volume_feature_enabled.api_v1:
+ cls.admin_volume_types_client = cls.os_adm.volume_types_client
+ else:
+ cls.admin_volume_types_client = cls.os_adm.volume_types_v2_client
def _wait_for_volume_status(self, status):
self.status_timeout(
diff --git a/tempest/scenario/test_swift_telemetry_middleware.py b/tempest/scenario/test_swift_telemetry_middleware.py
index 29ce1a0..c5a0e7c 100644
--- a/tempest/scenario/test_swift_telemetry_middleware.py
+++ b/tempest/scenario/test_swift_telemetry_middleware.py
@@ -50,9 +50,6 @@
skip_msg = ("%s skipped as ceilometer is not available" %
cls.__name__)
raise cls.skipException(skip_msg)
- elif CONF.telemetry.too_slow_to_test:
- skip_msg = "Ceilometer feature for fast work mysql is disabled"
- raise cls.skipException(skip_msg)
@classmethod
def setup_clients(cls):
diff --git a/tempest/scenario/test_volume_boot_pattern.py b/tempest/scenario/test_volume_boot_pattern.py
index 82f8b4c..ba419a6 100644
--- a/tempest/scenario/test_volume_boot_pattern.py
+++ b/tempest/scenario/test_volume_boot_pattern.py
@@ -83,7 +83,13 @@
self.snapshots_client.wait_for_resource_deletion, snap['id'])
self.addCleanup(self.snapshots_client.delete_snapshot, snap['id'])
self.snapshots_client.wait_for_snapshot_status(snap['id'], 'available')
- self.assertEqual(snap_name, snap['display_name'])
+
+ # NOTE(e0ne): Cinder API v2 uses name instead of display_name
+ if 'display_name' in snap:
+ self.assertEqual(snap_name, snap['display_name'])
+ else:
+ self.assertEqual(snap_name, snap['name'])
+
return snap
def _create_volume_from_snapshot(self, snap_id):
diff --git a/tempest/services/compute/json/floating_ips_bulk_client.py b/tempest/services/compute/json/floating_ips_bulk_client.py
index cabeeb1..dfe69f0 100644
--- a/tempest/services/compute/json/floating_ips_bulk_client.py
+++ b/tempest/services/compute/json/floating_ips_bulk_client.py
@@ -47,5 +47,4 @@
resp, body = self.put('os-floating-ips-bulk/delete', post_body)
body = json.loads(body)
self.validate_response(schema.delete_floating_ips_bulk, resp, body)
- data = body['floating_ips_bulk_delete']
- return service_client.ResponseBodyData(resp, data)
+ return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/compute/json/security_group_rules_client.py b/tempest/services/compute/json/security_group_rules_client.py
index c1c6b1a..9626f60 100644
--- a/tempest/services/compute/json/security_group_rules_client.py
+++ b/tempest/services/compute/json/security_group_rules_client.py
@@ -14,7 +14,6 @@
# under the License.
from oslo_serialization import jsonutils as json
-from tempest_lib import exceptions as lib_exc
from tempest.api_schema.response.compute.v2_1 import security_groups as schema
from tempest.common import service_client
@@ -46,13 +45,3 @@
group_rule_id)
self.validate_response(schema.delete_security_group_rule, resp, body)
return service_client.ResponseBody(resp, body)
-
- def list_security_group_rules(self, security_group_id):
- """List all rules for a security group."""
- resp, body = self.get('os-security-groups')
- body = json.loads(body)
- self.validate_response(schema.list_security_groups, resp, body)
- for sg in body['security_groups']:
- if sg['id'] == security_group_id:
- return service_client.ResponseBody(resp, sg)
- raise lib_exc.NotFound('No such Security Group')
diff --git a/tempest/services/compute/json/volumes_extensions_client.py b/tempest/services/compute/json/volumes_extensions_client.py
index c86aaff..db92351 100644
--- a/tempest/services/compute/json/volumes_extensions_client.py
+++ b/tempest/services/compute/json/volumes_extensions_client.py
@@ -35,7 +35,7 @@
resp, body = self.get(url)
body = json.loads(body)
self.validate_response(schema.list_volumes, resp, body)
- return service_client.ResponseBodyList(resp, body['volumes'])
+ return service_client.ResponseBody(resp, body)
def show_volume(self, volume_id):
"""Returns the details of a single volume."""
@@ -43,7 +43,7 @@
resp, body = self.get(url)
body = json.loads(body)
self.validate_response(schema.create_get_volume, resp, body)
- return service_client.ResponseBody(resp, body['volume'])
+ return service_client.ResponseBody(resp, body)
def create_volume(self, **kwargs):
"""
@@ -57,7 +57,7 @@
resp, body = self.post('os-volumes', post_body)
body = json.loads(body)
self.validate_response(schema.create_get_volume, resp, body)
- return service_client.ResponseBody(resp, body['volume'])
+ return service_client.ResponseBody(resp, body)
def delete_volume(self, volume_id):
"""Deletes the Specified Volume."""
diff --git a/tempest/services/image/v2/json/image_client.py b/tempest/services/image/v2/json/image_client.py
index c5aa41a..6cad746 100644
--- a/tempest/services/image/v2/json/image_client.py
+++ b/tempest/services/image/v2/json/image_client.py
@@ -71,7 +71,8 @@
"-json-patch"}
resp, body = self.patch('v2/images/%s' % image_id, data, headers)
self.expected_success(200, resp.status)
- return service_client.ResponseBody(resp, self._parse_resp(body))
+ body = json.loads(body)
+ return service_client.ResponseBody(resp, body)
def create_image(self, name, container_format, disk_format, **kwargs):
params = {
diff --git a/tempest/services/volume/json/admin/volume_quotas_client.py b/tempest/services/volume/json/admin/volume_quotas_client.py
index a979523..207554d 100644
--- a/tempest/services/volume/json/admin/volume_quotas_client.py
+++ b/tempest/services/volume/json/admin/volume_quotas_client.py
@@ -31,7 +31,8 @@
url = 'os-quota-sets/%s/defaults' % tenant_id
resp, body = self.get(url)
self.expected_success(200, resp.status)
- return service_client.ResponseBody(resp, self._parse_resp(body))
+ body = jsonutils.loads(body)
+ return service_client.ResponseBody(resp, body)
def show_quota_set(self, tenant_id, params=None):
"""List the quota set for a tenant."""
@@ -42,7 +43,8 @@
resp, body = self.get(url)
self.expected_success(200, resp.status)
- return service_client.ResponseBody(resp, self._parse_resp(body))
+ body = jsonutils.loads(body)
+ return service_client.ResponseBody(resp, body)
def show_quota_usage(self, tenant_id):
"""List the quota set for a tenant."""
@@ -66,7 +68,8 @@
post_body = jsonutils.dumps({'quota_set': post_body})
resp, body = self.put('os-quota-sets/%s' % tenant_id, post_body)
self.expected_success(200, resp.status)
- return service_client.ResponseBody(resp, self._parse_resp(body))
+ body = jsonutils.loads(body)
+ return service_client.ResponseBody(resp, body)
def delete_quota_set(self, tenant_id):
"""Delete the tenant's quota set."""
diff --git a/tempest/test.py b/tempest/test.py
index df6b30d..b664b47 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -530,9 +530,10 @@
else:
floating_ip = False
if security_group is None:
- security_group = True
+ security_group = CONF.validation.security_group
if security_group_rules is None:
- security_group_rules = True
+ security_group_rules = CONF.validation.security_group_rules
+
if not cls.validation_resources:
cls.validation_resources = {
'keypair': keypair,
diff --git a/tempest/tests/cmd/test_verify_tempest_config.py b/tempest/tests/cmd/test_verify_tempest_config.py
index 6bc96f2..2de5802 100644
--- a/tempest/tests/cmd/test_verify_tempest_config.py
+++ b/tempest/tests/cmd/test_verify_tempest_config.py
@@ -240,7 +240,10 @@
{'alias': 'fake2'},
{'alias': 'not_fake'}]}
fake_os = mock.MagicMock()
+ # NOTE (e0ne): mock both v1 and v2 APIs
fake_os.volumes_extension_client.list_extensions = fake_list_extensions
+ fake_os.volumes_v2_extension_client.list_extensions = (
+ fake_list_extensions)
self.useFixture(mockpatch.PatchObject(
verify_tempest_config, 'get_enabled_extensions',
return_value=(['fake1', 'fake2', 'fake3'])))
@@ -262,7 +265,10 @@
{'alias': 'fake2'},
{'alias': 'not_fake'}]}
fake_os = mock.MagicMock()
+ # NOTE (e0ne): mock both v1 and v2 APIs
fake_os.volumes_extension_client.list_extensions = fake_list_extensions
+ fake_os.volumes_v2_extension_client.list_extensions = (
+ fake_list_extensions)
self.useFixture(mockpatch.PatchObject(
verify_tempest_config, 'get_enabled_extensions',
return_value=(['all'])))
diff --git a/tempest/tests/common/test_accounts.py b/tempest/tests/common/test_accounts.py
index 1acef8a..9bf8059 100644
--- a/tempest/tests/common/test_accounts.py
+++ b/tempest/tests/common/test_accounts.py
@@ -41,7 +41,7 @@
self.useFixture(fake_config.ConfigFixture())
self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakePrivate)
self.fake_http = fake_http.fake_httplib2(return_type=200)
- self.stubs.Set(token_client.TokenClientJSON, 'raw_request',
+ self.stubs.Set(token_client.TokenClient, 'raw_request',
fake_identity._fake_v2_response)
self.useFixture(lockutils_fixtures.ExternalLockFixture())
self.test_accounts = [
@@ -86,7 +86,7 @@
return hash_list
def test_get_hash(self):
- self.stubs.Set(token_client.TokenClientJSON, 'raw_request',
+ self.stubs.Set(token_client.TokenClient, 'raw_request',
fake_identity._fake_v2_response)
test_account_class = accounts.Accounts('v2', 'test_name')
hash_list = self._get_hash_list(self.test_accounts)
diff --git a/tempest/tests/common/test_cred_provider.py b/tempest/tests/common/test_cred_provider.py
index ed3f931..1bc7147 100644
--- a/tempest/tests/common/test_cred_provider.py
+++ b/tempest/tests/common/test_cred_provider.py
@@ -36,7 +36,7 @@
identity_response = fake_identity._fake_v2_response
credentials_class = auth.KeystoneV2Credentials
- tokenclient_class = v2_client.TokenClientJSON
+ tokenclient_class = v2_client.TokenClient
identity_version = 'v2'
def setUp(self):
@@ -114,7 +114,7 @@
credentials_class = auth.KeystoneV3Credentials
identity_response = fake_identity._fake_v3_response
- tokenclient_class = v3_client.V3TokenClientJSON
+ tokenclient_class = v3_client.V3TokenClient
identity_version = 'v3'
def setUp(self):
diff --git a/tempest/tests/fake_tempest_plugin.py b/tempest/tests/fake_tempest_plugin.py
new file mode 100644
index 0000000..f718d0b
--- /dev/null
+++ b/tempest/tests/fake_tempest_plugin.py
@@ -0,0 +1,40 @@
+# Copyright (c) 2015 Deutsche Telekom AG
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from tempest.test_discover import plugins
+
+
+class FakePlugin(plugins.TempestPlugin):
+ expected_load_test = ["my/test/path", "/home/dir"]
+
+ def load_tests(self):
+ return self.expected_load_test
+
+ def register_opts(self, conf):
+ return
+
+ def get_opt_lists(self):
+ return []
+
+
+class FakeStevedoreObj(object):
+ obj = FakePlugin()
+
+ @property
+ def name(self):
+ return self._name
+
+ def __init__(self, name='Test1'):
+ self._name = name
diff --git a/tempest/tests/services/compute/test_agents_client.py b/tempest/tests/services/compute/test_agents_client.py
index 9493a32..01035ab 100644
--- a/tempest/tests/services/compute/test_agents_client.py
+++ b/tempest/tests/services/compute/test_agents_client.py
@@ -56,6 +56,12 @@
'tempest.common.service_client.ServiceClient.get',
{"agents": []},
bytes_body)
+ self.check_service_client_function(
+ self.client.list_agents,
+ 'tempest.common.service_client.ServiceClient.get',
+ {"agents": []},
+ bytes_body,
+ hypervisor="kvm")
def _test_create_agent(self, bytes_body=False):
self.check_service_client_function(
diff --git a/tempest/tests/services/compute/test_baremetal_nodes_client.py b/tempest/tests/services/compute/test_baremetal_nodes_client.py
new file mode 100644
index 0000000..edf9014
--- /dev/null
+++ b/tempest/tests/services/compute/test_baremetal_nodes_client.py
@@ -0,0 +1,74 @@
+# Copyright 2015 NEC Corporation. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import copy
+
+from tempest.services.compute.json import baremetal_nodes_client
+from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
+
+
+class TestBareMetalNodesClient(base.BaseComputeServiceTest):
+
+ FAKE_NODE_INFO = {'cpus': '8',
+ 'disk_gb': '64',
+ 'host': '10.0.2.15',
+ 'id': 'Identifier',
+ 'instance_uuid': "null",
+ 'interfaces': [
+ {
+ "address": "20::01",
+ "datapath_id": "null",
+ "id": 1,
+ "port_no": None
+ }
+ ],
+ 'memory_mb': '8192',
+ 'task_state': None}
+
+ def setUp(self):
+ super(TestBareMetalNodesClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.baremetal_nodes_client = (baremetal_nodes_client.
+ BaremetalNodesClient
+ (fake_auth, 'compute',
+ 'regionOne'))
+
+ def _test_bareMetal_nodes(self, operation='list', bytes_body=False):
+ if operation != 'list':
+ expected = {"node": self.FAKE_NODE_INFO}
+ function = self.baremetal_nodes_client.show_baremetal_node
+ else:
+ node_info = copy.deepcopy(self.FAKE_NODE_INFO)
+ del node_info['instance_uuid']
+ expected = {"nodes": [node_info]}
+ function = self.baremetal_nodes_client.list_baremetal_nodes
+
+ self.check_service_client_function(
+ function,
+ 'tempest.common.service_client.ServiceClient.get',
+ expected, bytes_body, 200,
+ baremetal_node_id='Identifier')
+
+ def test_list_bareMetal_nodes_with_str_body(self):
+ self._test_bareMetal_nodes()
+
+ def test_list_bareMetal_nodes_with_bytes_body(self):
+ self._test_bareMetal_nodes(bytes_body=True)
+
+ def test_show_bareMetal_node_with_str_body(self):
+ self._test_bareMetal_nodes('show')
+
+ def test_show_bareMetal_node_with_bytes_body(self):
+ self._test_bareMetal_nodes('show', True)
diff --git a/tempest/tests/services/compute/test_certificates_client.py b/tempest/tests/services/compute/test_certificates_client.py
index 51c3e85..c926fce 100644
--- a/tempest/tests/services/compute/test_certificates_client.py
+++ b/tempest/tests/services/compute/test_certificates_client.py
@@ -13,17 +13,13 @@
# under the License.
import copy
-import httplib2
-
-from oslo_serialization import jsonutils as json
-from oslotest import mockpatch
from tempest.services.compute.json import certificates_client
-from tempest.tests import base
from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
-class TestCertificatesClient(base.TestCase):
+class TestCertificatesClient(base.BaseComputeServiceTest):
FAKE_CERTIFICATE = {
"certificate": {
@@ -39,16 +35,12 @@
fake_auth, 'compute', 'regionOne')
def _test_show_certificate(self, bytes_body=False):
- serialized_body = json.dumps(self.FAKE_CERTIFICATE)
- if bytes_body:
- serialized_body = serialized_body.encode('utf-8')
-
- mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
- self.useFixture(mockpatch.Patch(
+ self.check_service_client_function(
+ self.client.show_certificate,
'tempest.common.service_client.ServiceClient.get',
- return_value=mocked_resp))
- resp = self.client.show_certificate("fake-id")
- self.assertEqual(self.FAKE_CERTIFICATE, resp)
+ self.FAKE_CERTIFICATE,
+ bytes_body,
+ certificate_id="fake-id")
def test_show_certificate_with_str_body(self):
self._test_show_certificate()
@@ -59,16 +51,11 @@
def _test_create_certificate(self, bytes_body=False):
cert = copy.deepcopy(self.FAKE_CERTIFICATE)
cert['certificate']['private_key'] = "my_private_key"
- serialized_body = json.dumps(cert)
- if bytes_body:
- serialized_body = serialized_body.encode('utf-8')
-
- mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
- self.useFixture(mockpatch.Patch(
+ self.check_service_client_function(
+ self.client.create_certificate,
'tempest.common.service_client.ServiceClient.post',
- return_value=mocked_resp))
- resp = self.client.create_certificate()
- self.assertEqual(cert, resp)
+ cert,
+ bytes_body)
def test_create_certificate_with_str_body(self):
self._test_create_certificate()
diff --git a/tempest/tests/services/compute/test_floating_ip_pools_client.py b/tempest/tests/services/compute/test_floating_ip_pools_client.py
new file mode 100644
index 0000000..0d19b7b
--- /dev/null
+++ b/tempest/tests/services/compute/test_floating_ip_pools_client.py
@@ -0,0 +1,47 @@
+# Copyright 2015 NEC Corporation. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+
+from tempest.services.compute.json import floating_ip_pools_client
+from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
+
+
+class TestFloatingIPPoolsClient(base.BaseComputeServiceTest):
+
+ FAKE_FLOATING_IP_POOLS = {
+ "floating_ip_pools":
+ [
+ {"name": u'\u3042'},
+ {"name": u'\u3044'}
+ ]
+ }
+
+ def setUp(self):
+ super(TestFloatingIPPoolsClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.client = floating_ip_pools_client.FloatingIPPoolsClient(
+ fake_auth, 'compute', 'regionOne')
+
+ def test_list_floating_ip_pools_with_str_body(self):
+ self.check_service_client_function(
+ self.client.list_floating_ip_pools,
+ 'tempest.common.service_client.ServiceClient.get',
+ self.FAKE_FLOATING_IP_POOLS)
+
+ def test_list_floating_ip_pools_with_bytes_body(self):
+ self.check_service_client_function(
+ self.client.list_floating_ip_pools,
+ 'tempest.common.service_client.ServiceClient.get',
+ self.FAKE_FLOATING_IP_POOLS, to_utf=True)
diff --git a/tempest/tests/services/compute/test_floating_ips_bulk_client.py b/tempest/tests/services/compute/test_floating_ips_bulk_client.py
new file mode 100644
index 0000000..6cf1b17
--- /dev/null
+++ b/tempest/tests/services/compute/test_floating_ips_bulk_client.py
@@ -0,0 +1,87 @@
+# Copyright 2015 NEC Corporation. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from tempest.services.compute.json import floating_ips_bulk_client
+from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
+
+
+class TestFloatingIPsBulkClient(base.BaseComputeServiceTest):
+
+ FAKE_FIP_BULK_LIST = {"floating_ip_info": [{
+ "address": "10.10.10.1",
+ "instance_uuid": None,
+ "fixed_ip": None,
+ "interface": "eth0",
+ "pool": "nova",
+ "project_id": None
+ },
+ {
+ "address": "10.10.10.2",
+ "instance_uuid": None,
+ "fixed_ip": None,
+ "interface": "eth0",
+ "pool": "nova",
+ "project_id": None
+ }]}
+
+ def setUp(self):
+ super(TestFloatingIPsBulkClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.client = floating_ips_bulk_client.FloatingIPsBulkClient(
+ fake_auth, 'compute', 'regionOne')
+
+ def _test_list_floating_ips_bulk(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.list_floating_ips_bulk,
+ 'tempest.common.service_client.ServiceClient.get',
+ self.FAKE_FIP_BULK_LIST,
+ to_utf=bytes_body)
+
+ def _test_create_floating_ips_bulk(self, bytes_body=False):
+ fake_fip_create_data = {"floating_ips_bulk_create": {
+ "ip_range": "192.168.1.0/24", "pool": "nova", "interface": "eth0"}}
+ self.check_service_client_function(
+ self.client.create_floating_ips_bulk,
+ 'tempest.common.service_client.ServiceClient.post',
+ fake_fip_create_data,
+ to_utf=bytes_body,
+ ip_range="192.168.1.0/24", pool="nova", interface="eth0")
+
+ def _test_delete_floating_ips_bulk(self, bytes_body=False):
+ fake_fip_delete_data = {"floating_ips_bulk_delete": "192.168.1.0/24"}
+ self.check_service_client_function(
+ self.client.delete_floating_ips_bulk,
+ 'tempest.common.service_client.ServiceClient.put',
+ fake_fip_delete_data,
+ to_utf=bytes_body,
+ ip_range="192.168.1.0/24")
+
+ def test_list_floating_ips_bulk_with_str_body(self):
+ self._test_list_floating_ips_bulk()
+
+ def test_list_floating_ips_bulk_with_bytes_body(self):
+ self._test_list_floating_ips_bulk(True)
+
+ def test_create_floating_ips_bulk_with_str_body(self):
+ self._test_create_floating_ips_bulk()
+
+ def test_create_floating_ips_bulk_with_bytes_body(self):
+ self._test_create_floating_ips_bulk(True)
+
+ def test_delete_floating_ips_bulk_with_str_body(self):
+ self._test_delete_floating_ips_bulk()
+
+ def test_delete_floating_ips_bulk_with_bytes_body(self):
+ self._test_delete_floating_ips_bulk(True)
diff --git a/tempest/tests/services/compute/test_instance_usage_audit_log_client.py b/tempest/tests/services/compute/test_instance_usage_audit_log_client.py
index 07efeca..d4bc889 100644
--- a/tempest/tests/services/compute/test_instance_usage_audit_log_client.py
+++ b/tempest/tests/services/compute/test_instance_usage_audit_log_client.py
@@ -13,17 +13,13 @@
# under the License.
import datetime
-import httplib2
-
-from oslo_serialization import jsonutils as json
-from oslotest import mockpatch
from tempest.services.compute.json import instance_usage_audit_log_client
-from tempest.tests import base
from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
-class TestInstanceUsagesAuditLogClient(base.TestCase):
+class TestInstanceUsagesAuditLogClient(base.BaseComputeServiceTest):
FAKE_AUDIT_LOG = {
"hosts_not_run": [
@@ -49,18 +45,11 @@
'regionOne'))
def _test_list_instance_usage_audit_logs(self, bytes_body=False):
- serialized_body = json.dumps({"instance_usage_audit_logs":
- self.FAKE_AUDIT_LOG})
- if bytes_body:
- serialized_body = serialized_body.encode('utf-8')
-
- mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
- self.useFixture(mockpatch.Patch(
+ self.check_service_client_function(
+ self.client.list_instance_usage_audit_logs,
'tempest.common.service_client.ServiceClient.get',
- return_value=mocked_resp))
- resp = self.client.list_instance_usage_audit_logs()
- self.assertEqual({"instance_usage_audit_logs": self.FAKE_AUDIT_LOG},
- resp)
+ {"instance_usage_audit_logs": self.FAKE_AUDIT_LOG},
+ bytes_body)
def test_list_instance_usage_audit_logs_with_str_body(self):
self._test_list_instance_usage_audit_logs()
@@ -70,18 +59,12 @@
def _test_show_instance_usage_audit_log(self, bytes_body=False):
before_time = datetime.datetime(2012, 12, 1, 0, 0)
- serialized_body = json.dumps({"instance_usage_audit_log":
- self.FAKE_AUDIT_LOG})
- if bytes_body:
- serialized_body = serialized_body.encode('utf-8')
-
- mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
- self.useFixture(mockpatch.Patch(
+ self.check_service_client_function(
+ self.client.show_instance_usage_audit_log,
'tempest.common.service_client.ServiceClient.get',
- return_value=mocked_resp))
- resp = self.client.show_instance_usage_audit_log(before_time)
- self.assertEqual({"instance_usage_audit_log": self.FAKE_AUDIT_LOG},
- resp)
+ {"instance_usage_audit_log": self.FAKE_AUDIT_LOG},
+ bytes_body,
+ time_before=before_time)
def test_show_instance_usage_audit_log_with_str_body(self):
self._test_show_instance_usage_audit_log()
diff --git a/tempest/tests/services/compute/test_networks_client.py b/tempest/tests/services/compute/test_networks_client.py
index 49a2344..b47430b 100644
--- a/tempest/tests/services/compute/test_networks_client.py
+++ b/tempest/tests/services/compute/test_networks_client.py
@@ -82,7 +82,7 @@
self.check_service_client_function(
self.client.show_network,
'tempest.common.service_client.ServiceClient.get',
- {"network": self.FAKE_NETWORKS},
+ {"network": self.FAKE_NETWORK},
bytes_body,
network_id=self.network_id
)
diff --git a/tempest/tests/services/compute/test_security_group_default_rules_client.py b/tempest/tests/services/compute/test_security_group_default_rules_client.py
new file mode 100644
index 0000000..75fa1cb
--- /dev/null
+++ b/tempest/tests/services/compute/test_security_group_default_rules_client.py
@@ -0,0 +1,88 @@
+# Copyright 2015 NEC Corporation. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from tempest.services.compute.json import security_group_default_rules_client
+from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
+
+
+class TestSecurityGroupDefaultRulesClient(base.BaseComputeServiceTest):
+ FAKE_RULE = {
+ "from_port": 80,
+ "id": 1,
+ "ip_protocol": "TCP",
+ "ip_range": {
+ "cidr": "10.10.10.0/24"
+ },
+ "to_port": 80
+ }
+
+ def setUp(self):
+ super(TestSecurityGroupDefaultRulesClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.client = (security_group_default_rules_client.
+ SecurityGroupDefaultRulesClient(fake_auth, 'compute',
+ 'regionOne'))
+
+ def _test_list_security_group_default_rules(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.list_security_group_default_rules,
+ 'tempest.common.service_client.ServiceClient.get',
+ {"security_group_default_rules": [self.FAKE_RULE]},
+ to_utf=bytes_body)
+
+ def test_list_security_group_default_rules_with_str_body(self):
+ self._test_list_security_group_default_rules()
+
+ def test_list_security_group_default_rules_with_bytes_body(self):
+ self._test_list_security_group_default_rules(bytes_body=True)
+
+ def _test_show_security_group_default_rule(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.show_security_group_default_rule,
+ 'tempest.common.service_client.ServiceClient.get',
+ {"security_group_default_rule": self.FAKE_RULE},
+ to_utf=bytes_body,
+ security_group_default_rule_id=1)
+
+ def test_show_security_group_default_rule_with_str_body(self):
+ self._test_show_security_group_default_rule()
+
+ def test_show_security_group_default_rule_with_bytes_body(self):
+ self._test_show_security_group_default_rule(bytes_body=True)
+
+ def _test_create_security_default_group_rule(self, bytes_body=False):
+ request_body = {
+ "to_port": 80,
+ "from_port": 80,
+ "ip_protocol": "TCP",
+ "cidr": "10.10.10.0/24"
+ }
+ self.check_service_client_function(
+ self.client.create_security_default_group_rule,
+ 'tempest.common.service_client.ServiceClient.post',
+ {"security_group_default_rule": self.FAKE_RULE},
+ to_utf=bytes_body, **request_body)
+
+ def test_create_security_default_group_rule_with_str_body(self):
+ self._test_create_security_default_group_rule()
+
+ def test_create_security_default_group_rule_with_bytes_body(self):
+ self._test_create_security_default_group_rule(bytes_body=True)
+
+ def test_delete_security_group_default_rule(self):
+ self.check_service_client_function(
+ self.client.delete_security_group_default_rule,
+ 'tempest.common.service_client.ServiceClient.delete',
+ {}, status=204, security_group_default_rule_id=1)
diff --git a/tempest/tests/services/compute/test_security_groups_client.py b/tempest/tests/services/compute/test_security_groups_client.py
new file mode 100644
index 0000000..7a39048
--- /dev/null
+++ b/tempest/tests/services/compute/test_security_groups_client.py
@@ -0,0 +1,113 @@
+# Copyright 2015 NEC Corporation. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from oslotest import mockpatch
+from tempest_lib import exceptions as lib_exc
+
+from tempest.services.compute.json import security_groups_client
+from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
+
+
+class TestSecurityGroupsClient(base.BaseComputeServiceTest):
+
+ FAKE_SECURITY_GROUP_INFO = [{
+ "description": "default",
+ "id": "3fb26eb3-581b-4420-9963-b0879a026506",
+ "name": "default",
+ "rules": [],
+ "tenant_id": "openstack"
+ }]
+
+ def setUp(self):
+ super(TestSecurityGroupsClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.client = security_groups_client.SecurityGroupsClient(
+ fake_auth, 'compute', 'regionOne')
+
+ def _test_list_security_groups(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.list_security_groups,
+ 'tempest.common.service_client.ServiceClient.get',
+ {"security_groups": self.FAKE_SECURITY_GROUP_INFO},
+ to_utf=bytes_body)
+
+ def test_list_security_groups_with_str_body(self):
+ self._test_list_security_groups()
+
+ def test_list_security_groups_with_bytes_body(self):
+ self._test_list_security_groups(bytes_body=True)
+
+ def _test_show_security_group(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.show_security_group,
+ 'tempest.common.service_client.ServiceClient.get',
+ {"security_group": self.FAKE_SECURITY_GROUP_INFO[0]},
+ to_utf=bytes_body,
+ security_group_id='fake-id')
+
+ def test_show_security_group_with_str_body(self):
+ self._test_show_security_group()
+
+ def test_show_security_group_with_bytes_body(self):
+ self._test_show_security_group(bytes_body=True)
+
+ def _test_create_security_group(self, bytes_body=False):
+ post_body = {"name": "test", "description": "test_group"}
+ self.check_service_client_function(
+ self.client.create_security_group,
+ 'tempest.common.service_client.ServiceClient.post',
+ {"security_group": self.FAKE_SECURITY_GROUP_INFO[0]},
+ to_utf=bytes_body,
+ kwargs=post_body)
+
+ def test_create_security_group_with_str_body(self):
+ self._test_create_security_group()
+
+ def test_create_security_group_with_bytes_body(self):
+ self._test_create_security_group(bytes_body=True)
+
+ def _test_update_security_group(self, bytes_body=False):
+ req_body = {"name": "test", "description": "test_group"}
+ self.check_service_client_function(
+ self.client.update_security_group,
+ 'tempest.common.service_client.ServiceClient.put',
+ {"security_group": self.FAKE_SECURITY_GROUP_INFO[0]},
+ to_utf=bytes_body,
+ security_group_id='fake-id',
+ kwargs=req_body)
+
+ def test_update_security_group_with_str_body(self):
+ self._test_update_security_group()
+
+ def test_update_security_group_with_bytes_body(self):
+ self._test_update_security_group(bytes_body=True)
+
+ def test_delete_security_group(self):
+ self.check_service_client_function(
+ self.client.delete_security_group,
+ 'tempest.common.service_client.ServiceClient.delete',
+ {}, status=202, security_group_id='fake-id')
+
+ def test_is_resource_deleted_true(self):
+ mod = ('tempest.services.compute.json.security_groups_client.'
+ 'SecurityGroupsClient.show_security_group')
+ self.useFixture(mockpatch.Patch(mod, side_effect=lib_exc.NotFound))
+ self.assertTrue(self.client.is_resource_deleted('fake-id'))
+
+ def test_is_resource_deleted_false(self):
+ mod = ('tempest.services.compute.json.security_groups_client.'
+ 'SecurityGroupsClient.show_security_group')
+ self.useFixture(mockpatch.Patch(mod, return_value='success'))
+ self.assertFalse(self.client.is_resource_deleted('fake-id'))
diff --git a/tempest/tests/services/compute/test_services_client.py b/tempest/tests/services/compute/test_services_client.py
index fe63de9..e5a25ab 100644
--- a/tempest/tests/services/compute/test_services_client.py
+++ b/tempest/tests/services/compute/test_services_client.py
@@ -81,14 +81,14 @@
fake_service["service"]["status"] = "disable"
self.check_service_client_function(
- self.client.enable_service,
+ self.client.disable_service,
'tempest.common.service_client.ServiceClient.put',
fake_service,
bytes_body,
host_name="nova-conductor", binary="controller")
def test_disable_service_with_str_body(self):
- self._test_enable_service()
+ self._test_disable_service()
def test_disable_service_with_bytes_body(self):
- self._test_enable_service(bytes_body=True)
+ self._test_disable_service(bytes_body=True)
diff --git a/tempest/tests/services/compute/test_tenant_networks_client.py b/tempest/tests/services/compute/test_tenant_networks_client.py
index d7c85f0..dc2de00 100644
--- a/tempest/tests/services/compute/test_tenant_networks_client.py
+++ b/tempest/tests/services/compute/test_tenant_networks_client.py
@@ -12,17 +12,12 @@
# License for the specific language governing permissions and limitations
# under the License.
-import httplib2
-
-from oslo_serialization import jsonutils as json
-from oslotest import mockpatch
-
from tempest.services.compute.json import tenant_networks_client
-from tempest.tests import base
from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
-class TestTenantNetworksClient(base.TestCase):
+class TestTenantNetworksClient(base.BaseComputeServiceTest):
FAKE_NETWORK = {
"cidr": "None",
@@ -41,16 +36,11 @@
fake_auth, 'compute', 'regionOne')
def _test_list_tenant_networks(self, bytes_body=False):
- serialized_body = json.dumps({"networks": self.FAKE_NETWORKS})
- if bytes_body:
- serialized_body = serialized_body.encode('utf-8')
-
- mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
- self.useFixture(mockpatch.Patch(
+ self.check_service_client_function(
+ self.client.list_tenant_networks,
'tempest.common.service_client.ServiceClient.get',
- return_value=mocked_resp))
- resp = self.client.list_tenant_networks()
- self.assertEqual({"networks": self.FAKE_NETWORKS}, resp)
+ {"networks": self.FAKE_NETWORKS},
+ bytes_body)
def test_list_tenant_networks_with_str_body(self):
self._test_list_tenant_networks()
@@ -59,16 +49,12 @@
self._test_list_tenant_networks(bytes_body=True)
def _test_show_tenant_network(self, bytes_body=False):
- serialized_body = json.dumps({"network": self.FAKE_NETWORK})
- if bytes_body:
- serialized_body = serialized_body.encode('utf-8')
-
- mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
- self.useFixture(mockpatch.Patch(
+ self.check_service_client_function(
+ self.client.show_tenant_network,
'tempest.common.service_client.ServiceClient.get',
- return_value=mocked_resp))
- resp = self.client.show_tenant_network(self.NETWORK_ID)
- self.assertEqual({"network": self.FAKE_NETWORK}, resp)
+ {"network": self.FAKE_NETWORK},
+ bytes_body,
+ network_id=self.NETWORK_ID)
def test_show_tenant_network_with_str_body(self):
self._test_show_tenant_network()
diff --git a/tempest/tests/test_tempest_plugin.py b/tempest/tests/test_tempest_plugin.py
new file mode 100644
index 0000000..c07e98c
--- /dev/null
+++ b/tempest/tests/test_tempest_plugin.py
@@ -0,0 +1,44 @@
+# Copyright (c) 2015 Deutsche Telekom AG
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from tempest.test_discover import plugins
+from tempest.tests import base
+from tempest.tests import fake_tempest_plugin as fake_plugin
+
+
+class TestPluginDiscovery(base.TestCase):
+ def test_load_tests_with_one_plugin(self):
+ # we can't mock stevedore since it's a singleton and already executed
+ # during test discovery. So basically this test covers the plugin loop
+ # and the abstract plugin interface.
+ manager = plugins.TempestTestPluginManager()
+ fake_obj = fake_plugin.FakeStevedoreObj()
+ manager.ext_plugins = [fake_obj]
+ result = manager.get_plugin_load_tests_tuple()
+
+ self.assertEqual(fake_plugin.FakePlugin.expected_load_test,
+ result[fake_obj.name])
+
+ def test_load_tests_with_two_plugins(self):
+ manager = plugins.TempestTestPluginManager()
+ obj1 = fake_plugin.FakeStevedoreObj('fake01')
+ obj2 = fake_plugin.FakeStevedoreObj('fake02')
+ manager.ext_plugins = [obj1, obj2]
+ result = manager.get_plugin_load_tests_tuple()
+
+ self.assertEqual(fake_plugin.FakePlugin.expected_load_test,
+ result['fake01'])
+ self.assertEqual(fake_plugin.FakePlugin.expected_load_test,
+ result['fake02'])
diff --git a/tempest/tests/test_tenant_isolation.py b/tempest/tests/test_tenant_isolation.py
index fa1b6f7..7bdc1d7 100644
--- a/tempest/tests/test_tenant_isolation.py
+++ b/tempest/tests/test_tenant_isolation.py
@@ -37,7 +37,7 @@
self.useFixture(fake_config.ConfigFixture())
self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakePrivate)
self.fake_http = fake_http.fake_httplib2(return_type=200)
- self.stubs.Set(json_token_client.TokenClientJSON, 'raw_request',
+ self.stubs.Set(json_token_client.TokenClient, 'raw_request',
fake_identity._fake_v2_response)
cfg.CONF.set_default('operator_role', 'FakeRole',
group='object-storage')