Merge "Fix broken compute api ref links"
diff --git a/.zuul.yaml b/.zuul.yaml
index b51babb..2c066ae 100644
--- a/.zuul.yaml
+++ b/.zuul.yaml
@@ -32,6 +32,22 @@
ENABLE_FILE_INJECTION: True
- job:
+ name: tempest-full-py3
+ parent: tempest-full
+ vars:
+ devstack_localrc:
+ USE_PYTHON3: True
+ FORCE_CONFIG_DRIVE: True
+ ENABLE_FILE_INJECTION: False
+ devstack_services:
+ s-account: false
+ s-container: false
+ s-object: false
+ s-proxy: false
+ # without Swift, c-bak cannot run (in the Gate at least)
+ c-bak: false
+
+- job:
name: tempest-tox-plugin-sanity-check
parent: tox
description: |
@@ -116,4 +132,15 @@
- ^playbooks/
- ^roles/
- ^.zuul.yaml$
+ - tempest-full-py3:
+ voting: false
+ irrelevant-files:
+ - ^(test-|)requirements.txt$
+ - ^.*\.rst$
+ - ^doc/.*$
+ - ^etc/.*$
+ - ^releasenotes/.*$
+ - ^setup.cfg$
+ - ^tempest/hacking/.*$
+ - ^tempest/tests/.*$
- tempest-tox-plugin-sanity-check
diff --git a/HACKING.rst b/HACKING.rst
index a3e9c26..f961884 100644
--- a/HACKING.rst
+++ b/HACKING.rst
@@ -385,7 +385,7 @@
Otherwise the bug fix won't be able to land in the project.
-Handily, `Zuul’s cross-repository dependencies
+Handily, `Zuul's cross-repository dependencies
<https://docs.openstack.org/infra/zuul/user/gating.html#cross-project-dependencies>`_.
can be leveraged to do without step 2 and to have steps 3 and 4 happen
"atomically". To do that, make the patch written in step 1 to depend (refer to
diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst
index e5f70d2..d0d7320 100644
--- a/doc/source/configuration.rst
+++ b/doc/source/configuration.rst
@@ -400,7 +400,7 @@
Examples:
* Good - ``http://example.com:1234/v2.0``
- * Wouldn’t work - ``http://example.com:1234/xyz/v2.0/``
+ * Wouldn't work - ``http://example.com:1234/xyz/v2.0/``
(adding prefix/suffix around version etc)
Service Feature Configuration
diff --git a/releasenotes/notes/add-group-type-specs-apis-to-v3-group-types-client-10390b52dedede54.yaml b/releasenotes/notes/add-group-type-specs-apis-to-v3-group-types-client-10390b52dedede54.yaml
new file mode 100644
index 0000000..404319d
--- /dev/null
+++ b/releasenotes/notes/add-group-type-specs-apis-to-v3-group-types-client-10390b52dedede54.yaml
@@ -0,0 +1,10 @@
+---
+features:
+ - |
+ Add group type specs APIs to v3 group_types_client library.
+
+ * create_or_update_group_type_specs
+ * list_group_type_specs
+ * show_group_type_specs_item
+ * update_group_type_specs_item
+ * delete_group_type_specs_item
diff --git a/releasenotes/notes/add-show-default-quotas-api-to-network-quotas-client-3a7c1159af9e56ff.yaml b/releasenotes/notes/add-show-default-quotas-api-to-network-quotas-client-3a7c1159af9e56ff.yaml
new file mode 100644
index 0000000..6efe7e6
--- /dev/null
+++ b/releasenotes/notes/add-show-default-quotas-api-to-network-quotas-client-3a7c1159af9e56ff.yaml
@@ -0,0 +1,6 @@
+---
+features:
+ - |
+ Add show default quotas API to network quotas_client library.
+ This feature enables the possibility to show default network quotas for
+ a specified project.
diff --git a/releasenotes/notes/fix-list-group-snapshots-api-969d9321002c566c.yaml b/releasenotes/notes/fix-list-group-snapshots-api-969d9321002c566c.yaml
index 775a383..a002fb8 100644
--- a/releasenotes/notes/fix-list-group-snapshots-api-969d9321002c566c.yaml
+++ b/releasenotes/notes/fix-list-group-snapshots-api-969d9321002c566c.yaml
@@ -1,6 +1,6 @@
---
fixes:
- |
- Fix list_group_snapshots API in v3 group_snapshots_client: Bug#1715786.
+ Fix list_group_snapshots API in v3 group_snapshots_client: Bug#1715786.
The url path for list group snapshots with details API is changed from
``?detail=True`` to ``/detail``.
diff --git a/releasenotes/notes/removal-deprecated-config-options-3db535b979fe3509.yaml b/releasenotes/notes/removal-deprecated-config-options-3db535b979fe3509.yaml
index 0b03e21..e15d387 100644
--- a/releasenotes/notes/removal-deprecated-config-options-3db535b979fe3509.yaml
+++ b/releasenotes/notes/removal-deprecated-config-options-3db535b979fe3509.yaml
@@ -8,3 +8,5 @@
* ``[identity-feature-enabled].forbid_global_implied_dsr``
* ``[image-feature-enabled].deactivate_image``
* ``[default].resources_prefix``
+ * config group ``orchestration``
+ * ``[service_available].heat``
diff --git a/tempest/api/compute/admin/test_live_migration.py b/tempest/api/compute/admin/test_live_migration.py
index dcd7b9b..9e897e3 100644
--- a/tempest/api/compute/admin/test_live_migration.py
+++ b/tempest/api/compute/admin/test_live_migration.py
@@ -230,8 +230,8 @@
while data not in console_output and t <= 120.0:
try:
ws.send_frame(data)
- recieved = ws.receive_frame()
- console_output += recieved
+ received = ws.receive_frame()
+ console_output += received
except Exception:
# In case we had an issue with send/receive on the
# websocket connection, we create a new one.
diff --git a/tempest/api/compute/admin/test_networks.py b/tempest/api/compute/admin/test_networks.py
index acb0d90..87ce39d 100644
--- a/tempest/api/compute/admin/test_networks.py
+++ b/tempest/api/compute/admin/test_networks.py
@@ -24,7 +24,7 @@
"""Tests Nova Networks API that usually requires admin privileges.
API docs:
- http://developer.openstack.org/api-ref-compute-v2-ext.html#ext-os-networks
+ https://developer.openstack.org/api-ref/compute/#networks-os-networks-deprecated
"""
@classmethod
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 83fabdb..9759be7 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -185,11 +185,12 @@
cls.request_microversion)
v2_37_version = api_version_request.APIVersionRequest('2.37')
+ tenant_network = cls.get_tenant_network()
# NOTE(snikitin): since microversion v2.37 'networks' field is required
- if request_version >= v2_37_version and 'networks' not in kwargs:
+ if (request_version >= v2_37_version and 'networks' not in kwargs and
+ not tenant_network):
kwargs['networks'] = 'none'
- tenant_network = cls.get_tenant_network()
body, servers = compute.create_test_server(
cls.os_primary,
validatable,
diff --git a/tempest/api/network/admin/test_quotas.py b/tempest/api/network/admin/test_quotas.py
index cf4236d..57a28bf 100644
--- a/tempest/api/network/admin/test_quotas.py
+++ b/tempest/api/network/admin/test_quotas.py
@@ -80,6 +80,10 @@
non_default_quotas = self.admin_quotas_client.list_quotas()
for q in non_default_quotas['quotas']:
self.assertNotEqual(project_id, q['tenant_id'])
+ quota_set = self.admin_quotas_client.show_quotas(project_id)['quota']
+ default_quotas = self.admin_quotas_client.show_default_quotas(
+ project_id)['quota']
+ self.assertEqual(default_quotas, quota_set)
@decorators.idempotent_id('2390f766-836d-40ef-9aeb-e810d78207fb')
def test_quotas(self):
diff --git a/tempest/api/volume/admin/test_group_type_specs.py b/tempest/api/volume/admin/test_group_type_specs.py
new file mode 100644
index 0000000..c5e6d1a
--- /dev/null
+++ b/tempest/api/volume/admin/test_group_type_specs.py
@@ -0,0 +1,80 @@
+# Copyright 2017 FiberHome Telecommunication Technologies CO.,LTD
+# 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.api.volume import base
+from tempest.lib import decorators
+from tempest.lib import exceptions as lib_exc
+
+
+class GroupTypeSpecsTest(base.BaseVolumeAdminTest):
+ _api_version = 3
+ min_microversion = '3.11'
+ max_microversion = 'latest'
+
+ @decorators.idempotent_id('bb4e30d0-de6e-4f4d-866c-dcc48d023b4e')
+ def test_group_type_specs_create_show_update_list_delete(self):
+ # Create new group type
+ group_type = self.create_group_type()
+
+ # Create new group type specs
+ create_specs = {
+ "key1": "value1",
+ "key2": "value2"
+ }
+ body = self.admin_group_types_client.create_or_update_group_type_specs(
+ group_type['id'], create_specs)['group_specs']
+ self.assertEqual(create_specs, body)
+
+ # Create a new group type spec and update an existing group type spec
+ update_specs = {
+ "key2": "value2-updated",
+ "key3": "value3"
+ }
+ body = self.admin_group_types_client.create_or_update_group_type_specs(
+ group_type['id'], update_specs)['group_specs']
+ self.assertEqual(update_specs, body)
+
+ # Show specified item of group type specs
+ spec_keys = ['key2', 'key3']
+ for key in spec_keys:
+ body = self.admin_group_types_client.show_group_type_specs_item(
+ group_type['id'], key)
+ self.assertIn(key, body)
+ self.assertEqual(update_specs[key], body[key])
+
+ # Update specified item of group type specs
+ update_key = 'key3'
+ update_spec = {update_key: "value3-updated"}
+ body = self.admin_group_types_client.update_group_type_specs_item(
+ group_type['id'], update_key, update_spec)
+ self.assertEqual(update_spec, body)
+
+ # List all group type specs that created or updated above
+ list_specs = {}
+ list_specs.update(create_specs)
+ list_specs.update(update_specs)
+ list_specs.update(update_spec)
+ body = self.admin_group_types_client.list_group_type_specs(
+ group_type['id'])['group_specs']
+ self.assertEqual(list_specs, body)
+
+ # Delete specified item of group type specs
+ delete_key = 'key1'
+ self.admin_group_types_client.delete_group_type_specs_item(
+ group_type['id'], delete_key)
+ self.assertRaises(
+ lib_exc.NotFound,
+ self.admin_group_types_client.show_group_type_specs_item,
+ group_type['id'], delete_key)
diff --git a/tempest/api/volume/admin/test_volume_quotas.py b/tempest/api/volume/admin/test_volume_quotas.py
index 42bfcd6..6f9daa8 100644
--- a/tempest/api/volume/admin/test_volume_quotas.py
+++ b/tempest/api/volume/admin/test_volume_quotas.py
@@ -38,7 +38,6 @@
def setup_credentials(cls):
super(BaseVolumeQuotasAdminTestJSON, cls).setup_credentials()
cls.demo_tenant_id = cls.os_primary.credentials.tenant_id
- cls.alt_client = cls.os_alt.volumes_client_latest
@classmethod
def setup_clients(cls):
@@ -150,7 +149,8 @@
self.demo_tenant_id, params={'usage': True})['quota_set']
alt_quota = self.admin_quotas_client.show_quota_set(
- self.alt_client.tenant_id, params={'usage': True})['quota_set']
+ self.os_alt.volumes_client_latest.tenant_id,
+ params={'usage': True})['quota_set']
# Creates a volume transfer
transfer = self.transfer_client.create_volume_transfer(
@@ -164,14 +164,15 @@
# Verify volume transferred is available
waiters.wait_for_volume_resource_status(
- self.alt_client, volume['id'], 'available')
+ self.os_alt.volumes_client_latest, volume['id'], 'available')
# List of tenants quota usage post transfer
new_primary_quota = self.admin_quotas_client.show_quota_set(
self.demo_tenant_id, params={'usage': True})['quota_set']
new_alt_quota = self.admin_quotas_client.show_quota_set(
- self.alt_client.tenant_id, params={'usage': True})['quota_set']
+ self.os_alt.volumes_client_latest.tenant_id,
+ params={'usage': True})['quota_set']
# Verify tenants quota usage was updated
self.assertEqual(primary_quota['volumes']['in_use'] -
diff --git a/tempest/api/volume/admin/test_volume_type_access.py b/tempest/api/volume/admin/test_volume_type_access.py
index e93bcb5..b64face 100644
--- a/tempest/api/volume/admin/test_volume_type_access.py
+++ b/tempest/api/volume/admin/test_volume_type_access.py
@@ -27,11 +27,6 @@
credentials = ['primary', 'alt', 'admin']
- @classmethod
- def setup_clients(cls):
- super(VolumeTypesAccessTest, cls).setup_clients()
- cls.alt_client = cls.os_alt.volumes_client_latest
-
@decorators.idempotent_id('d4dd0027-835f-4554-a6e5-50903fb79184')
def test_volume_type_access_add(self):
# Creating a NON public volume type
@@ -70,10 +65,11 @@
# Adding volume type access for alt tenant
self.admin_volume_types_client.add_type_access(
- volume_type['id'], project=self.alt_client.tenant_id)
+ volume_type['id'],
+ project=self.os_alt.volumes_client_latest.tenant_id)
self.addCleanup(self.admin_volume_types_client.remove_type_access,
volume_type['id'],
- project=self.alt_client.tenant_id)
+ project=self.os_alt.volumes_client_latest.tenant_id)
# List tenant access for the given volume type
type_access_list = self.admin_volume_types_client.list_type_access(
@@ -88,5 +84,5 @@
# Validating the permitted tenants are the expected tenants
self.assertIn(self.volumes_client.tenant_id,
map(operator.itemgetter('project_id'), type_access_list))
- self.assertIn(self.alt_client.tenant_id,
+ self.assertIn(self.os_alt.volumes_client_latest.tenant_id,
map(operator.itemgetter('project_id'), type_access_list))
diff --git a/tempest/api/volume/test_volumes_extend.py b/tempest/api/volume/test_volumes_extend.py
index b73bdf2..54052ae 100644
--- a/tempest/api/volume/test_volumes_extend.py
+++ b/tempest/api/volume/test_volumes_extend.py
@@ -80,11 +80,6 @@
# is implicit - Cinder calls Nova at that microversion, Tempest does not.
min_microversion = '3.42'
- @classmethod
- def setup_clients(cls):
- super(VolumesExtendAttachedTest, cls).setup_clients()
- cls.admin_servers_client = cls.os_admin.servers_client
-
def _find_extend_volume_instance_action(self, server_id):
actions = self.servers_client.list_instance_actions(
server_id)['instanceActions']
@@ -95,7 +90,7 @@
def _find_extend_volume_instance_action_finish_event(self, action):
# This has to be called by an admin client otherwise
# the events don't show up.
- action = self.admin_servers_client.show_instance_action(
+ action = self.os_admin.servers_client.show_instance_action(
action['instance_uuid'], action['request_id'])['instanceAction']
for event in action['events']:
if (event['event'] == 'compute_extend_volume' and
diff --git a/tempest/cmd/account_generator.py b/tempest/cmd/account_generator.py
index 92eae02..1c671ec 100755
--- a/tempest/cmd/account_generator.py
+++ b/tempest/cmd/account_generator.py
@@ -162,9 +162,7 @@
if CONF.service_available.swift:
spec.append([CONF.object_storage.operator_role])
spec.append([CONF.object_storage.reseller_admin_role])
- if CONF.service_available.heat:
- spec.append([CONF.orchestration.stack_owner_role,
- CONF.object_storage.operator_role])
+ spec.append([CONF.object_storage.operator_role])
if admin:
spec.append('admin')
resources = []
diff --git a/tempest/cmd/cleanup_service.py b/tempest/cmd/cleanup_service.py
index d1e80f1..025959a 100644
--- a/tempest/cmd/cleanup_service.py
+++ b/tempest/cmd/cleanup_service.py
@@ -37,7 +37,6 @@
IS_CINDER = None
IS_GLANCE = None
-IS_HEAT = None
IS_NEUTRON = None
IS_NOVA = None
@@ -60,7 +59,6 @@
IS_CINDER = CONF.service_available.cinder
IS_GLANCE = CONF.service_available.glance
- IS_HEAT = CONF.service_available.heat
IS_NEUTRON = CONF.service_available.neutron
IS_NOVA = CONF.service_available.nova
@@ -212,33 +210,6 @@
self.data['server_groups'] = sgs
-class StackService(BaseService):
- def __init__(self, manager, **kwargs):
- super(StackService, self).__init__(kwargs)
- params = config.service_client_config('orchestration')
- self.client = manager.orchestration.OrchestrationClient(
- manager.auth_provider, **params)
-
- def list(self):
- client = self.client
- stacks = client.list_stacks()['stacks']
- LOG.debug("List count, %s Stacks", len(stacks))
- return stacks
-
- def delete(self):
- client = self.client
- stacks = self.list()
- for stack in stacks:
- try:
- client.delete_stack(stack['id'])
- except Exception:
- LOG.exception("Delete Stack exception.")
-
- def dry_run(self):
- stacks = self.list()
- self.data['stacks'] = stacks
-
-
class KeyPairService(BaseService):
def __init__(self, manager, **kwargs):
super(KeyPairService, self).__init__(kwargs)
@@ -960,8 +931,6 @@
if not IS_NEUTRON:
project_services.append(FloatingIpService)
project_services.append(NovaQuotaService)
- if IS_HEAT:
- project_services.append(StackService)
if IS_NEUTRON:
project_services.append(NetworkFloatingIpService)
if utils.is_extension_enabled('metering', 'network'):
diff --git a/tempest/cmd/verify_tempest_config.py b/tempest/cmd/verify_tempest_config.py
index fdf28d5..15af271 100644
--- a/tempest/cmd/verify_tempest_config.py
+++ b/tempest/cmd/verify_tempest_config.py
@@ -349,7 +349,6 @@
'image': 'glance',
'object_storage': 'swift',
'compute': 'nova',
- 'orchestration': 'heat',
'baremetal': 'ironic',
'identity': 'keystone',
}
diff --git a/tempest/config.py b/tempest/config.py
index bc585cb..231d005 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -65,9 +65,7 @@
deprecated_opts=[cfg.DeprecatedOpt('allow_tenant_isolation',
group='auth'),
cfg.DeprecatedOpt('allow_tenant_isolation',
- group='compute'),
- cfg.DeprecatedOpt('allow_tenant_isolation',
- group='orchestration')]),
+ group='compute')]),
cfg.ListOpt('tempest_roles',
help="Roles to assign to all users created by tempest",
default=[]),
@@ -909,66 +907,6 @@
help="Execute discoverability tests"),
]
-orchestration_group = cfg.OptGroup(name='orchestration',
- title='Orchestration Service Options')
-
-OrchestrationGroup = [
- cfg.StrOpt('catalog_type',
- default='orchestration',
- help="Catalog type of the Orchestration service.",
- deprecated_for_removal=True,
- deprecated_reason='Heat support will be removed from Tempest'),
- cfg.StrOpt('region',
- default='',
- help="The orchestration region name to use. If empty, the "
- "value of identity.region is used instead. If no such "
- "region is found in the service catalog, the first found "
- "one is used.",
- deprecated_for_removal=True,
- deprecated_reason='Heat support will be removed from Tempest'),
- cfg.StrOpt('endpoint_type',
- default='publicURL',
- choices=['public', 'admin', 'internal',
- 'publicURL', 'adminURL', 'internalURL'],
- help="The endpoint type to use for the orchestration service.",
- deprecated_for_removal=True,
- deprecated_reason='Heat support will be removed from Tempest'),
- cfg.StrOpt('stack_owner_role', default='heat_stack_owner',
- help='Role required for users to be able to manage stacks',
- deprecated_for_removal=True,
- deprecated_reason='Heat support will be removed from Tempest'),
- cfg.IntOpt('build_interval',
- default=1,
- help="Time in seconds between build status checks.",
- deprecated_for_removal=True,
- deprecated_reason='Heat support will be removed from Tempest'),
- cfg.IntOpt('build_timeout',
- default=1200,
- help="Timeout in seconds to wait for a stack to build.",
- deprecated_for_removal=True,
- deprecated_reason='Heat support will be removed from Tempest'),
- cfg.StrOpt('instance_type',
- default='m1.micro',
- help="Instance type for tests. Needs to be big enough for a "
- "full OS plus the test workload",
- deprecated_for_removal=True,
- deprecated_reason='Heat support will be removed from Tempest'),
- cfg.StrOpt('keypair_name',
- help="Name of existing keypair to launch servers with.",
- deprecated_for_removal=True,
- deprecated_reason='Heat support will be removed from Tempest'),
- cfg.IntOpt('max_template_size',
- default=524288,
- help="Value must match heat configuration of the same name.",
- deprecated_for_removal=True,
- deprecated_reason='Heat support will be removed from Tempest'),
- cfg.IntOpt('max_resources_per_stack',
- default=1000,
- help="Value must match heat configuration of the same name.",
- deprecated_for_removal=True,
- deprecated_reason='Heat support will be removed from Tempest'),
-]
-
scenario_group = cfg.OptGroup(name='scenario', title='Scenario Test Options')
@@ -1030,11 +968,6 @@
cfg.BoolOpt('nova',
default=True,
help="Whether or not nova is expected to be available"),
- cfg.BoolOpt('heat',
- default=False,
- help="Whether or not Heat is expected to be available",
- deprecated_for_removal=True,
- deprecated_reason='Heat support will be removed from Tempest'),
]
debug_group = cfg.OptGroup(name="debug",
@@ -1091,7 +1024,6 @@
(volume_feature_group, VolumeFeaturesGroup),
(object_storage_group, ObjectStoreGroup),
(object_storage_feature_group, ObjectStoreFeaturesGroup),
- (orchestration_group, OrchestrationGroup),
(scenario_group, ScenarioGroup),
(service_available_group, ServiceAvailableGroup),
(debug_group, DebugGroup),
@@ -1158,7 +1090,6 @@
self.object_storage = _CONF['object-storage']
self.object_storage_feature_enabled = _CONF[
'object-storage-feature-enabled']
- self.orchestration = _CONF.orchestration
self.scenario = _CONF.scenario
self.service_available = _CONF.service_available
self.debug = _CONF.debug
diff --git a/tempest/lib/common/utils/test_utils.py b/tempest/lib/common/utils/test_utils.py
index c2e93ee..2a9f3a9 100644
--- a/tempest/lib/common/utils/test_utils.py
+++ b/tempest/lib/common/utils/test_utils.py
@@ -102,13 +102,13 @@
now = time.time()
begin_time = now
timeout = now + duration
+ func_name = getattr(func, '__name__', getattr(func.__class__, '__name__'))
while now < timeout:
if func(*args, **kwargs):
LOG.debug("Call %s returns true in %f seconds",
- getattr(func, '__name__'), time.time() - begin_time)
+ func_name, time.time() - begin_time)
return True
time.sleep(sleep_for)
now = time.time()
- LOG.debug("Call %s returns false in %f seconds",
- getattr(func, '__name__'), duration)
+ LOG.debug("Call %s returns false in %f seconds", func_name, duration)
return False
diff --git a/tempest/lib/services/compute/quota_classes_client.py b/tempest/lib/services/compute/quota_classes_client.py
index 0fe9868..64e06f4 100644
--- a/tempest/lib/services/compute/quota_classes_client.py
+++ b/tempest/lib/services/compute/quota_classes_client.py
@@ -35,8 +35,9 @@
def update_quota_class_set(self, quota_class_id, **kwargs):
"""Update the quota class's limits for one or more resources.
- # NOTE: Current api-site doesn't contain this API description.
- # LP: https://bugs.launchpad.net/nova/+bug/1602400
+ For a full list of available parameters, please refer to the official
+ API reference:
+ https://developer.openstack.org/api-ref/compute/#create-or-update-quotas-for-quota-class
"""
post_body = json.dumps({'quota_class_set': kwargs})
diff --git a/tempest/lib/services/compute/quotas_client.py b/tempest/lib/services/compute/quotas_client.py
index daf4bc0..12df895 100644
--- a/tempest/lib/services/compute/quotas_client.py
+++ b/tempest/lib/services/compute/quotas_client.py
@@ -28,8 +28,8 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref-compute-v2.1.html/#show-a-quota
- http://developer.openstack.org/api-ref-compute-v2.1.html/#show-the-detail-of-quota
+ https://developer.openstack.org/api-ref/compute/#show-a-quota
+ https://developer.openstack.org/api-ref/compute/#show-the-detail-of-quota
"""
params = {}
@@ -49,7 +49,10 @@
return rest_client.ResponseBody(resp, body)
def show_default_quota_set(self, tenant_id):
- """List the default quota set for a tenant."""
+ """List the default quota set for a tenant.
+
+ https://developer.openstack.org/api-ref/compute/#list-default-quotas-for-tenant
+ """
url = 'os-quota-sets/%s/defaults' % tenant_id
resp, body = self.get(url)
@@ -79,7 +82,10 @@
return rest_client.ResponseBody(resp, body)
def delete_quota_set(self, tenant_id):
- """Delete the tenant's quota set."""
+ """Delete the tenant's quota set.
+
+ https://developer.openstack.org/api-ref/compute/#revert-quotas-to-defaults
+ """
resp, body = self.delete('os-quota-sets/%s' % tenant_id)
self.validate_response(schema.delete_quota, resp, body)
return rest_client.ResponseBody(resp, body)
diff --git a/tempest/lib/services/network/quotas_client.py b/tempest/lib/services/network/quotas_client.py
index fdd3d6b..f23af88 100644
--- a/tempest/lib/services/network/quotas_client.py
+++ b/tempest/lib/services/network/quotas_client.py
@@ -41,3 +41,8 @@
def list_quotas(self, **filters):
uri = '/quotas'
return self.list_resources(uri, **filters)
+
+ def show_default_quotas(self, tenant_id):
+ """List default quotas for a project."""
+ uri = '/quotas/%s/default' % tenant_id
+ return self.show_resource(uri)
diff --git a/tempest/lib/services/volume/v2/quota_classes_client.py b/tempest/lib/services/volume/v2/quota_classes_client.py
index d40d2d9..733b1ac 100644
--- a/tempest/lib/services/volume/v2/quota_classes_client.py
+++ b/tempest/lib/services/volume/v2/quota_classes_client.py
@@ -26,8 +26,9 @@
def show_quota_class_set(self, quota_class_id):
"""List quotas for a quota class.
- TODO: Current api-site doesn't contain this API description.
- LP: https://bugs.launchpad.net/nova/+bug/1602400
+ For a full list of available parameters, please refer to the official
+ API reference:
+ https://developer.openstack.org/api-ref/block-storage/v2/index.html#show-quota-classes
"""
url = 'os-quota-class-sets/%s' % quota_class_id
resp, body = self.get(url)
@@ -38,8 +39,9 @@
def update_quota_class_set(self, quota_class_id, **kwargs):
"""Update quotas for a quota class.
- TODO: Current api-site doesn't contain this API description.
- LP: https://bugs.launchpad.net/nova/+bug/1602400
+ For a full list of available parameters, please refer to the official
+ API reference:
+ https://developer.openstack.org/api-ref/block-storage/v2/index.html#update-quota-classes
"""
url = 'os-quota-class-sets/%s' % quota_class_id
put_body = json.dumps({'quota_class_set': kwargs})
diff --git a/tempest/lib/services/volume/v3/group_types_client.py b/tempest/lib/services/volume/v3/group_types_client.py
index 6181472..1b47201 100644
--- a/tempest/lib/services/volume/v3/group_types_client.py
+++ b/tempest/lib/services/volume/v3/group_types_client.py
@@ -88,3 +88,54 @@
self.expected_success(200, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
+
+ def create_or_update_group_type_specs(self, group_type_id, group_specs):
+ """Creates new group specs or updates existing group specs.
+
+ For a full list of available parameters, please refer to the official
+ API reference:
+ https://developer.openstack.org/api-ref/block-storage/v3/#create-group-specs-for-a-group-type
+ """
+ url = "group_types/%s/group_specs" % group_type_id
+ post_body = json.dumps({'group_specs': group_specs})
+ resp, body = self.post(url, post_body)
+ body = json.loads(body)
+ self.expected_success(202, resp.status)
+ return rest_client.ResponseBody(resp, body)
+
+ def list_group_type_specs(self, group_type_id):
+ """Lists all group specs for a given group type."""
+ url = 'group_types/%s/group_specs' % group_type_id
+ resp, body = self.get(url)
+ body = json.loads(body)
+ self.expected_success(200, resp.status)
+ return rest_client.ResponseBody(resp, body)
+
+ def show_group_type_specs_item(self, group_type_id, spec_id):
+ """Shows specified item of group specs for a given group type."""
+ url = "group_types/%s/group_specs/%s" % (group_type_id, spec_id)
+ resp, body = self.get(url)
+ body = json.loads(body)
+ self.expected_success(200, resp.status)
+ return rest_client.ResponseBody(resp, body)
+
+ def update_group_type_specs_item(self, group_type_id, spec_id, spec):
+ """Updates specified item of group specs for a given group type.
+
+ For a full list of available parameters, please refer to the official
+ API reference:
+ https://developer.openstack.org/api-ref/block-storage/v3/#update-one-specific-group-spec-for-a-group-type
+ """
+ url = "group_types/%s/group_specs/%s" % (group_type_id, spec_id)
+ put_body = json.dumps(spec)
+ resp, body = self.put(url, put_body)
+ body = json.loads(body)
+ self.expected_success(200, resp.status)
+ return rest_client.ResponseBody(resp, body)
+
+ def delete_group_type_specs_item(self, group_type_id, spec_id):
+ """Deletes specified item of group specs for a given group type."""
+ resp, body = self.delete("group_types/%s/group_specs/%s" % (
+ group_type_id, spec_id))
+ self.expected_success(202, resp.status)
+ return rest_client.ResponseBody(resp, body)
diff --git a/tempest/tests/cmd/test_account_generator.py b/tempest/tests/cmd/test_account_generator.py
index 8bf4c5b..fd9af08 100644
--- a/tempest/tests/cmd/test_account_generator.py
+++ b/tempest/tests/cmd/test_account_generator.py
@@ -153,17 +153,14 @@
def test_generate_resources_no_admin(self):
cfg.CONF.set_default('swift', False, group='service_available')
- cfg.CONF.set_default('heat', False, group='service_available')
cfg.CONF.set_default('operator_role', 'fake_operator',
group='object-storage')
cfg.CONF.set_default('reseller_admin_role', 'fake_reseller',
group='object-storage')
- cfg.CONF.set_default('stack_owner_role', 'fake_owner',
- group='orchestration')
resources = account_generator.generate_resources(
self.cred_provider, admin=False)
resource_types = [k for k, _ in resources]
- # No admin, no heat, no swift, expect two credentials only
+ # No admin, no swift, expect two credentials only
self.assertEqual(2, len(resources))
# Ensure create_user was invoked twice (two distinct users)
self.assertEqual(2, self.user_create_fixture.mock.call_count)
@@ -180,17 +177,14 @@
def test_generate_resources_admin(self):
cfg.CONF.set_default('swift', False, group='service_available')
- cfg.CONF.set_default('heat', False, group='service_available')
cfg.CONF.set_default('operator_role', 'fake_operator',
group='object-storage')
cfg.CONF.set_default('reseller_admin_role', 'fake_reseller',
group='object-storage')
- cfg.CONF.set_default('stack_owner_role', 'fake_owner',
- group='orchestration')
resources = account_generator.generate_resources(
self.cred_provider, admin=True)
resource_types = [k for k, _ in resources]
- # Admin, no heat, no swift, expect three credentials only
+ # Admin, no swift, expect three credentials only
self.assertEqual(3, len(resources))
# Ensure create_user was invoked 3 times (3 distinct users)
self.assertEqual(3, self.user_create_fixture.mock.call_count)
@@ -205,28 +199,24 @@
self.assertIsNotNone(resource[1].router)
self.assertIsNotNone(resource[1].subnet)
- def test_generate_resources_swift_heat_admin(self):
+ def test_generate_resources_swift_admin(self):
cfg.CONF.set_default('swift', True, group='service_available')
- cfg.CONF.set_default('heat', True, group='service_available')
cfg.CONF.set_default('operator_role', 'fake_operator',
group='object-storage')
cfg.CONF.set_default('reseller_admin_role', 'fake_reseller',
group='object-storage')
- cfg.CONF.set_default('stack_owner_role', 'fake_owner',
- group='orchestration')
resources = account_generator.generate_resources(
self.cred_provider, admin=True)
resource_types = [k for k, _ in resources]
# all options on, expect six credentials
self.assertEqual(6, len(resources))
# Ensure create_user was invoked 6 times (6 distinct users)
- self.assertEqual(6, self.user_create_fixture.mock.call_count)
+ self.assertEqual(5, self.user_create_fixture.mock.call_count)
self.assertIn('primary', resource_types)
self.assertIn('alt', resource_types)
self.assertIn('admin', resource_types)
self.assertIn(['fake_operator'], resource_types)
self.assertIn(['fake_reseller'], resource_types)
- self.assertIn(['fake_owner', 'fake_operator'], resource_types)
for resource in resources:
self.assertIsNotNone(resource[1].network)
self.assertIsNotNone(resource[1].router)
@@ -258,7 +248,6 @@
self.opts)
self.mock_resource_creation()
cfg.CONF.set_default('swift', True, group='service_available')
- cfg.CONF.set_default('heat', True, group='service_available')
self.resources = account_generator.generate_resources(
self.cred_provider, admin=True)
diff --git a/tempest/tests/fake_config.py b/tempest/tests/fake_config.py
index f1d3bba..4a2fff4 100644
--- a/tempest/tests/fake_config.py
+++ b/tempest/tests/fake_config.py
@@ -39,7 +39,6 @@
self.conf.set_default('uri_v3', 'http://fake_uri_v3.com/auth',
group='identity')
self.conf.set_default('neutron', True, group='service_available')
- self.conf.set_default('heat', True, group='service_available')
lock_path = str(os.environ.get('OS_TEST_LOCK_PATH',
os.environ.get('TMPDIR', '/tmp')))
if not os.path.exists(lock_path):
diff --git a/tempest/tests/lib/services/network/test_quotas_client.py b/tempest/tests/lib/services/network/test_quotas_client.py
index e76bc9c..5a09911 100644
--- a/tempest/tests/lib/services/network/test_quotas_client.py
+++ b/tempest/tests/lib/services/network/test_quotas_client.py
@@ -38,6 +38,20 @@
]
}
+ FAKE_PROJECT_QUOTAS = {
+ "quota": {
+ "floatingip": 50,
+ "network": 10,
+ "port": 50,
+ "rbac_policy": -1,
+ "router": 10,
+ "security_group": 10,
+ "security_group_rule": 100,
+ "subnet": 10,
+ "subnetpool": -1
+ }
+ }
+
FAKE_QUOTA_TENANT_ID = "bab7d5c60cd041a0a36f7c4b6e1dd978"
def setUp(self):
@@ -58,7 +72,16 @@
self.check_service_client_function(
self.quotas_client.show_quotas,
"tempest.lib.common.rest_client.RestClient.get",
- {"quota": self.FAKE_QUOTAS["quotas"][0]},
+ self.FAKE_PROJECT_QUOTAS,
+ bytes_body,
+ 200,
+ tenant_id=self.FAKE_QUOTA_TENANT_ID)
+
+ def _test_show_default_quotas(self, bytes_body=False):
+ self.check_service_client_function(
+ self.quotas_client.show_default_quotas,
+ "tempest.lib.common.rest_client.RestClient.get",
+ self.FAKE_PROJECT_QUOTAS,
bytes_body,
200,
tenant_id=self.FAKE_QUOTA_TENANT_ID)
@@ -67,7 +90,7 @@
self.check_service_client_function(
self.quotas_client.update_quotas,
"tempest.lib.common.rest_client.RestClient.put",
- {"quota": self.FAKE_QUOTAS["quotas"][0]},
+ self.FAKE_PROJECT_QUOTAS,
bytes_body,
200,
tenant_id=self.FAKE_QUOTA_TENANT_ID)
@@ -92,6 +115,12 @@
def test_show_quotas_with_bytes_body(self):
self._test_show_quotas(bytes_body=True)
+ def test_show_default_quotas_with_str_body(self):
+ self._test_show_default_quotas()
+
+ def test_show_default_quotas_with_bytes_body(self):
+ self._test_show_default_quotas(bytes_body=True)
+
def test_update_quotas_with_str_body(self):
self._test_update_quotas()
diff --git a/tempest/tests/lib/services/volume/v3/test_group_types_client.py b/tempest/tests/lib/services/volume/v3/test_group_types_client.py
index e86594e..c60cc36 100644
--- a/tempest/tests/lib/services/volume/v3/test_group_types_client.py
+++ b/tempest/tests/lib/services/volume/v3/test_group_types_client.py
@@ -69,6 +69,28 @@
]
}
+ FAKE_CREATE_GROUP_TYPE_SPECS = {
+ "group_specs": {
+ "key1": "value1",
+ "key2": "value2"
+ }
+ }
+
+ FAKE_LIST_GROUP_TYPE_SPECS = {
+ "group_specs": {
+ "key1": "value1",
+ "key2": "value2"
+ }
+ }
+
+ FAKE_SHOW_GROUP_TYPE_SPECS_ITEM = {
+ "key1": "value1"
+ }
+
+ FAKE_UPDATE_GROUP_TYPE_SPECS_ITEM = {
+ "key2": "value2-updated"
+ }
+
def setUp(self):
super(TestGroupTypesClient, self).setUp()
fake_auth = fake_auth_provider.FakeAuthProvider()
@@ -111,6 +133,45 @@
group_type_id="3fbbcccf-d058-4502-8844-6feeffdf4cb5",
name='updated-group-type-name')
+ def _test_create_or_update_group_type_specs(self, bytes_body=False):
+ group_specs = self.FAKE_CREATE_GROUP_TYPE_SPECS['group_specs']
+ self.check_service_client_function(
+ self.client.create_or_update_group_type_specs,
+ 'tempest.lib.common.rest_client.RestClient.post',
+ self.FAKE_CREATE_GROUP_TYPE_SPECS,
+ bytes_body,
+ group_type_id="3fbbcccf-d058-4502-8844-6feeffdf4cb5",
+ group_specs=group_specs,
+ status=202)
+
+ def _test_list_group_type_specs(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.list_group_type_specs,
+ 'tempest.lib.common.rest_client.RestClient.get',
+ self.FAKE_LIST_GROUP_TYPE_SPECS,
+ bytes_body,
+ group_type_id="3fbbcccf-d058-4502-8844-6feeffdf4cb5")
+
+ def _test_show_group_type_specs_item(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.show_group_type_specs_item,
+ 'tempest.lib.common.rest_client.RestClient.get',
+ self.FAKE_SHOW_GROUP_TYPE_SPECS_ITEM,
+ bytes_body,
+ group_type_id="3fbbcccf-d058-4502-8844-6feeffdf4cb5",
+ spec_id="key1")
+
+ def _test_update_group_type_specs_item(self, bytes_body=False):
+ spec = self.FAKE_UPDATE_GROUP_TYPE_SPECS_ITEM
+ self.check_service_client_function(
+ self.client.update_group_type_specs_item,
+ 'tempest.lib.common.rest_client.RestClient.put',
+ self.FAKE_UPDATE_GROUP_TYPE_SPECS_ITEM,
+ bytes_body,
+ group_type_id="3fbbcccf-d058-4502-8844-6feeffdf4cb5",
+ spec_id="key2",
+ spec=spec)
+
def test_create_group_type_with_str_body(self):
self._test_create_group_type()
@@ -142,3 +203,36 @@
def test_update_group_types_with_bytes_body(self):
self._test_update_group_types(bytes_body=True)
+
+ def test_create_or_update_group_type_specs_with_str_body(self):
+ self._test_create_or_update_group_type_specs()
+
+ def test_create_or_update_group_type_specs_with_bytes_body(self):
+ self._test_create_or_update_group_type_specs(bytes_body=True)
+
+ def test_list_group_type_specs_with_str_body(self):
+ self._test_list_group_type_specs()
+
+ def test_list_group_type_specs_with_bytes_body(self):
+ self._test_list_group_type_specs(bytes_body=True)
+
+ def test_show_group_type_specs_item_with_str_body(self):
+ self._test_show_group_type_specs_item()
+
+ def test_show_group_type_specs_item_with_bytes_body(self):
+ self._test_show_group_type_specs_item(bytes_body=True)
+
+ def test_update_group_type_specs_item_with_str_body(self):
+ self._test_update_group_type_specs_item()
+
+ def test_update_group_type_specs_item_with_bytes_body(self):
+ self._test_update_group_type_specs_item(bytes_body=True)
+
+ def test_delete_group_type_specs_item(self):
+ self.check_service_client_function(
+ self.client.delete_group_type_specs_item,
+ 'tempest.lib.common.rest_client.RestClient.delete',
+ {},
+ group_type_id='0e58433f-d108-4bf3-a22c-34e6b71ef86b',
+ spec_id='key1',
+ status=202)
diff --git a/tox.ini b/tox.ini
index c0df8a6..892b6f4 100644
--- a/tox.ini
+++ b/tox.ini
@@ -123,6 +123,10 @@
tempest run --serial --regex '\[.*\bsmoke\b.*\]' {posargs}
[testenv:venv]
+deps =
+ -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt}
+ -r{toxinidir}/requirements.txt
+ -r{toxinidir}/doc/requirements.txt
commands = {posargs}
[testenv:venv-tempest]