Merge "Validate floating IP in server['addresses'] scenario"
diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst
index 6c55015..fd9ad05 100644
--- a/doc/source/configuration.rst
+++ b/doc/source/configuration.rst
@@ -61,10 +61,9 @@
Credential Provider Mechanisms
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-Tempest currently also has three different internal methods for providing
-authentication to tests: dynamic credentials, locking test accounts, and
-non-locking test accounts. Depending on which one is in use the configuration
-of Tempest is slightly different.
+Tempest currently has two different internal methods for providing authentication
+to tests: dynamic credentials and pre-provisioned credentials.
+Depending on which one is in use the configuration of Tempest is slightly different.
Dynamic Credentials
"""""""""""""""""""
diff --git a/releasenotes/notes/12.3.0-volume-clients-as-library-660811011be29d1a.yaml b/releasenotes/notes/12.3.0-volume-clients-as-library-660811011be29d1a.yaml
new file mode 100644
index 0000000..9e9eff6
--- /dev/null
+++ b/releasenotes/notes/12.3.0-volume-clients-as-library-660811011be29d1a.yaml
@@ -0,0 +1,6 @@
+---
+features:
+ - |
+ Define the v1 and v2 types_client clients for the volume service as
+ library interfaces, allowing other projects to use these modules as
+ stable libraries without maintenance changes.
diff --git a/releasenotes/notes/add-new-identity-clients-as-library-5f7ndha733nwdsn9.yaml b/releasenotes/notes/add-new-identity-clients-as-library-5f7ndha733nwdsn9.yaml
index d1635e3..9e828f6 100644
--- a/releasenotes/notes/add-new-identity-clients-as-library-5f7ndha733nwdsn9.yaml
+++ b/releasenotes/notes/add-new-identity-clients-as-library-5f7ndha733nwdsn9.yaml
@@ -1,11 +1,15 @@
---
features:
- |
- Define identity service clients as libraries
+ Define identity service clients as libraries.
Add new service clients to the library interface so the other projects can use these modules as stable libraries without
any maintenance changes.
* identity_client(v2)
* groups_client(v3)
+ * trusts_client(v3)
* users_client(v3)
* identity_client(v3)
+ * roles_client(v3)
+ * inherited_roles_client(v3)
+ * credentials_client(v3)
diff --git a/tempest/api/compute/admin/test_aggregates.py b/tempest/api/compute/admin/test_aggregates.py
index fbcc1d1..667d30b 100644
--- a/tempest/api/compute/admin/test_aggregates.py
+++ b/tempest/api/compute/admin/test_aggregates.py
@@ -215,10 +215,8 @@
self.client.add_host(aggregate['id'], host=self.host)
self.addCleanup(self.client.remove_host, aggregate['id'],
host=self.host)
- server_name = data_utils.rand_name('test_server')
admin_servers_client = self.os_adm.servers_client
- server = self.create_test_server(name=server_name,
- availability_zone=az_name,
+ server = self.create_test_server(availability_zone=az_name,
wait_until='ACTIVE')
body = admin_servers_client.show_server(server['id'])['server']
self.assertEqual(self.host, body['OS-EXT-SRV-ATTR:host'])
diff --git a/tempest/api/compute/admin/test_servers_negative.py b/tempest/api/compute/admin/test_servers_negative.py
index db6e682..23b16e7 100755
--- a/tempest/api/compute/admin/test_servers_negative.py
+++ b/tempest/api/compute/admin/test_servers_negative.py
@@ -69,7 +69,7 @@
self.tenant_id)['quota_set']
ram = int(quota_set['ram'])
if ram == -1:
- raise self.skipException("default ram quota set is -1,"
+ raise self.skipException("ram quota set is -1,"
" cannot test overlimit")
ram += 1
vcpus = 8
@@ -98,7 +98,7 @@
self.tenant_id)['quota_set']
vcpus = int(quota_set['cores'])
if vcpus == -1:
- raise self.skipException("default cores quota set is -1,"
+ raise self.skipException("cores quota set is -1,"
" cannot test overlimit")
vcpus += 1
disk = 10
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 5e75493..27afff3 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -219,6 +219,8 @@
:param validatable: Whether the server will be pingable or sshable.
:param volume_backed: Whether the instance is volume backed or not.
"""
+ if 'name' not in kwargs:
+ kwargs['name'] = data_utils.rand_name(cls.__name__ + "-server")
tenant_network = cls.get_tenant_network()
body, servers = compute.create_test_server(
cls.os,
diff --git a/tempest/api/compute/images/test_image_metadata.py b/tempest/api/compute/images/test_image_metadata.py
index 6f80730..999233d 100644
--- a/tempest/api/compute/images/test_image_metadata.py
+++ b/tempest/api/compute/images/test_image_metadata.py
@@ -71,7 +71,7 @@
body = body['image'] if 'image' in body else body
cls.image_id = body['id']
cls.images.append(cls.image_id)
- image_file = six.StringIO(('*' * 1024))
+ image_file = six.BytesIO((b'*' * 1024))
if CONF.image_feature_enabled.api_v1:
cls.glance_client.update_image(cls.image_id, data=image_file)
else:
diff --git a/tempest/api/compute/images/test_list_image_filters.py b/tempest/api/compute/images/test_list_image_filters.py
index c0caa52..f340658 100755
--- a/tempest/api/compute/images/test_list_image_filters.py
+++ b/tempest/api/compute/images/test_list_image_filters.py
@@ -78,7 +78,7 @@
# Wait 1 second between creation and upload to ensure a delta
# between created_at and updated_at.
time.sleep(1)
- image_file = six.StringIO(('*' * 1024))
+ image_file = six.BytesIO((b'*' * 1024))
if CONF.image_feature_enabled.api_v1:
cls.glance_client.update_image(image_id, data=image_file)
else:
diff --git a/tempest/api/compute/security_groups/test_security_group_rules_negative.py b/tempest/api/compute/security_groups/test_security_group_rules_negative.py
index 853ef31..4f53663 100644
--- a/tempest/api/compute/security_groups/test_security_group_rules_negative.py
+++ b/tempest/api/compute/security_groups/test_security_group_rules_negative.py
@@ -23,7 +23,8 @@
def not_existing_id():
- if CONF.service_available.neutron:
+ if (CONF.service_available.neutron and
+ test.is_extension_enabled('security-group', 'network')):
return data_utils.rand_uuid()
else:
return data_utils.rand_int_id(start=999)
diff --git a/tempest/api/compute/security_groups/test_security_groups.py b/tempest/api/compute/security_groups/test_security_groups.py
index f6353c8..755336f 100644
--- a/tempest/api/compute/security_groups/test_security_groups.py
+++ b/tempest/api/compute/security_groups/test_security_groups.py
@@ -94,8 +94,7 @@
# Create server and add the security group created
# above to the server we just created
- server_name = data_utils.rand_name('server')
- server = self.create_test_server(name=server_name)
+ server = self.create_test_server()
server_id = server['id']
waiters.wait_for_server_status(self.servers_client, server_id,
'ACTIVE')
diff --git a/tempest/api/compute/servers/test_list_servers_negative.py b/tempest/api/compute/servers/test_list_servers_negative.py
index 357c907..fcd5a24 100644
--- a/tempest/api/compute/servers/test_list_servers_negative.py
+++ b/tempest/api/compute/servers/test_list_servers_negative.py
@@ -13,8 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-from six import moves
-
from tempest.api.compute import base
from tempest.common import waiters
from tempest.lib import exceptions as lib_exc
@@ -38,7 +36,7 @@
# tearDownClass method of the super-class.
cls.existing_fixtures = []
cls.deleted_fixtures = []
- for x in moves.xrange(2):
+ for x in range(2):
srv = cls.create_test_server(wait_until='ACTIVE')
cls.existing_fixtures.append(srv)
diff --git a/tempest/api/compute/servers/test_server_personality.py b/tempest/api/compute/servers/test_server_personality.py
index baa4f9a..cd90473 100644
--- a/tempest/api/compute/servers/test_server_personality.py
+++ b/tempest/api/compute/servers/test_server_personality.py
@@ -13,7 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import base64
+from oslo_serialization import base64
from tempest.api.compute import base
from tempest.common.utils.linux import remote_client
@@ -55,7 +55,7 @@
file_contents = 'This is a test file.'
file_path = '/test.txt'
personality = [{'path': file_path,
- 'contents': base64.b64encode(file_contents)}]
+ 'contents': base64.encode_as_text(file_contents)}]
password = data_utils.rand_password()
created_server = self.create_test_server(personality=personality,
adminPass=password,
@@ -79,7 +79,7 @@
server_id = server['id']
file_contents = 'Test server rebuild.'
personality = [{'path': 'rebuild.txt',
- 'contents': base64.b64encode(file_contents)}]
+ 'contents': base64.encode_as_text(file_contents)}]
rebuilt_server = self.client.rebuild_server(server_id,
self.image_ref_alt,
personality=personality)
@@ -100,7 +100,8 @@
for i in range(0, int(max_file_limit) + 1):
path = 'etc/test' + str(i) + '.txt'
personality.append({'path': path,
- 'contents': base64.b64encode(file_contents)})
+ 'contents': base64.encode_as_text(
+ file_contents)})
# A 403 Forbidden or 413 Overlimit (old behaviour) exception
# will be raised when out of quota
self.assertRaises((lib_exc.Forbidden, lib_exc.OverLimit),
@@ -120,7 +121,7 @@
path = '/etc/test' + str(i) + '.txt'
person.append({
'path': path,
- 'contents': base64.b64encode(file_contents),
+ 'contents': base64.encode_as_text(file_contents),
})
password = data_utils.rand_password()
created_server = self.create_test_server(personality=person,
diff --git a/tempest/api/compute/servers/test_servers_negative.py b/tempest/api/compute/servers/test_servers_negative.py
index 2304cb7..89be3f3 100755
--- a/tempest/api/compute/servers/test_servers_negative.py
+++ b/tempest/api/compute/servers/test_servers_negative.py
@@ -302,7 +302,7 @@
# Pass a server ID that exceeds length limit to delete server
self.assertRaises(lib_exc.NotFound, self.client.delete_server,
- sys.maxint + 1)
+ sys.maxsize + 1)
@test.attr(type=['negative'])
@test.idempotent_id('c5fa6041-80cd-483b-aa6d-4e45f19d093c')
diff --git a/tempest/api/compute/volumes/test_attach_volume.py b/tempest/api/compute/volumes/test_attach_volume.py
index 7c13ef0..ff5dc49 100644
--- a/tempest/api/compute/volumes/test_attach_volume.py
+++ b/tempest/api/compute/volumes/test_attach_volume.py
@@ -57,13 +57,6 @@
waiters.wait_for_volume_status(self.volumes_client,
volume_id, 'available')
- def _delete_volume(self):
- # Delete the created Volumes
- if self.volume:
- self.volumes_client.delete_volume(self.volume['id'])
- self.volumes_client.wait_for_resource_deletion(self.volume['id'])
- self.volume = None
-
def _create_server(self):
# Start a server and wait for it to become ready
server = self.create_test_server(
@@ -78,28 +71,29 @@
def _create_and_attach_volume(self, server):
# Create a volume and wait for it to become ready
- self.volume = self.volumes_client.create_volume(
+ volume = self.volumes_client.create_volume(
size=CONF.volume.volume_size, display_name='test')['volume']
- self.addCleanup(self._delete_volume)
+ self.addCleanup(self.delete_volume, volume['id'])
waiters.wait_for_volume_status(self.volumes_client,
- self.volume['id'], 'available')
+ volume['id'], 'available')
# Attach the volume to the server
self.attachment = self.servers_client.attach_volume(
server['id'],
- volumeId=self.volume['id'],
+ volumeId=volume['id'],
device='/dev/%s' % self.device)['volumeAttachment']
waiters.wait_for_volume_status(self.volumes_client,
- self.volume['id'], 'in-use')
+ volume['id'], 'in-use')
- self.addCleanup(self._detach, server['id'], self.volume['id'])
+ self.addCleanup(self._detach, server['id'], volume['id'])
+ return volume
@test.idempotent_id('52e9045a-e90d-4c0d-9087-79d657faffff')
def test_attach_detach_volume(self):
# Stop and Start a server with an attached volume, ensuring that
# the volume remains attached.
server = self._create_server()
- self._create_and_attach_volume(server)
+ volume = self._create_and_attach_volume(server)
self.servers_client.stop_server(server['id'])
waiters.wait_for_server_status(self.servers_client, server['id'],
@@ -122,7 +116,7 @@
device_name_to_match = ' ' + self.device + '\n'
self.assertIn(device_name_to_match, partitions)
- self._detach(server['id'], self.volume['id'])
+ self._detach(server['id'], volume['id'])
self.attachment = None
self.servers_client.stop_server(server['id'])
waiters.wait_for_server_status(self.servers_client, server['id'],
@@ -148,7 +142,7 @@
def test_list_get_volume_attachments(self):
# Create Server, Volume and attach that Volume to Server
server = self._create_server()
- self._create_and_attach_volume(server)
+ volume = self._create_and_attach_volume(server)
# List Volume attachment of the server
body = self.servers_client.list_volume_attachments(
@@ -161,7 +155,7 @@
server['id'],
self.attachment['id'])['volumeAttachment']
self.assertEqual(server['id'], body['serverId'])
- self.assertEqual(self.volume['id'], body['volumeId'])
+ self.assertEqual(volume['id'], body['volumeId'])
self.assertEqual(self.attachment['id'], body['id'])
@@ -254,10 +248,10 @@
server = self._create_server()
num_vol = self._count_volumes(server)
self._shelve_server(server)
- self._create_and_attach_volume(server)
+ volume = self._create_and_attach_volume(server)
# Detach the volume
- self._detach(server['id'], self.volume['id'])
+ self._detach(server['id'], volume['id'])
self.attachment = None
# Unshelve the instance and check that we have the expected number of
diff --git a/tempest/api/identity/admin/v2/test_roles.py b/tempest/api/identity/admin/v2/test_roles.py
index 380920f..d284aac 100644
--- a/tempest/api/identity/admin/v2/test_roles.py
+++ b/tempest/api/identity/admin/v2/test_roles.py
@@ -13,8 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-from six import moves
-
from tempest.api.identity import base
from tempest.common.utils import data_utils
from tempest.lib.common.utils import test_utils
@@ -27,7 +25,7 @@
def resource_setup(cls):
super(RolesTestJSON, cls).resource_setup()
cls.roles = list()
- for _ in moves.xrange(5):
+ for _ in range(5):
role_name = data_utils.rand_name(name='role')
role = cls.roles_client.create_role(name=role_name)['role']
cls.roles.append(role)
diff --git a/tempest/api/identity/admin/v2/test_services.py b/tempest/api/identity/admin/v2/test_services.py
index 94291f8..3ed51f0 100644
--- a/tempest/api/identity/admin/v2/test_services.py
+++ b/tempest/api/identity/admin/v2/test_services.py
@@ -13,8 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-from six import moves
-
from tempest.api.identity import base
from tempest.common.utils import data_utils
from tempest.lib import exceptions as lib_exc
@@ -84,7 +82,7 @@
def test_list_services(self):
# Create, List, Verify and Delete Services
services = []
- for _ in moves.xrange(3):
+ for _ in range(3):
name = data_utils.rand_name('service')
s_type = data_utils.rand_name('type')
description = data_utils.rand_name('description')
diff --git a/tempest/api/identity/admin/v2/test_tenants.py b/tempest/api/identity/admin/v2/test_tenants.py
index 4faf184..f4fad53 100644
--- a/tempest/api/identity/admin/v2/test_tenants.py
+++ b/tempest/api/identity/admin/v2/test_tenants.py
@@ -13,8 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-from six import moves
-
from tempest.api.identity import base
from tempest.common.utils import data_utils
from tempest.lib.common.utils import test_utils
@@ -27,7 +25,7 @@
def test_tenant_list_delete(self):
# Create several tenants and delete them
tenants = []
- for _ in moves.xrange(3):
+ for _ in range(3):
tenant_name = data_utils.rand_name(name='tenant-new')
tenant = self.tenants_client.create_tenant(
name=tenant_name)['tenant']
diff --git a/tempest/api/identity/admin/v2/test_users.py b/tempest/api/identity/admin/v2/test_users.py
index 8e63498..4a4b51a 100644
--- a/tempest/api/identity/admin/v2/test_users.py
+++ b/tempest/api/identity/admin/v2/test_users.py
@@ -234,4 +234,4 @@
# Validate the updated password through getting a token.
body = self.token_client.auth(user['name'], new_pass,
tenant['name'])
- self.assertTrue('id' in body['token'])
+ self.assertIn('id', body['token'])
diff --git a/tempest/api/identity/admin/v3/test_credentials.py b/tempest/api/identity/admin/v3/test_credentials.py
index 12b236f..a0d8748 100644
--- a/tempest/api/identity/admin/v3/test_credentials.py
+++ b/tempest/api/identity/admin/v3/test_credentials.py
@@ -12,6 +12,7 @@
# 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 oslo_serialization import jsonutils as json
from tempest.api.identity import base
from tempest.common.utils import data_utils
@@ -70,6 +71,7 @@
update_body = self.creds_client.update_credential(
cred['id'], blob=blob, project_id=self.projects[1],
type='ec2')['credential']
+ update_body['blob'] = json.loads(update_body['blob'])
self.assertEqual(cred['id'], update_body['id'])
self.assertEqual(self.projects[1], update_body['project_id'])
self.assertEqual(self.user_body['id'], update_body['user_id'])
@@ -77,6 +79,7 @@
self.assertEqual(update_body['blob']['secret'], new_keys[1])
get_body = self.creds_client.show_credential(cred['id'])['credential']
+ get_body['blob'] = json.loads(get_body['blob'])
for value1 in self.creds_list[0]:
self.assertEqual(update_body[value1],
get_body[value1])
diff --git a/tempest/api/identity/admin/v3/test_groups.py b/tempest/api/identity/admin/v3/test_groups.py
index 48e5f02..3cbcc1f 100644
--- a/tempest/api/identity/admin/v3/test_groups.py
+++ b/tempest/api/identity/admin/v3/test_groups.py
@@ -91,7 +91,8 @@
# list users in group
group_users = self.groups_client.list_group_users(group['id'])['users']
- self.assertEqual(sorted(users), sorted(group_users))
+ self.assertEqual(sorted(users, key=lambda k: k['name']),
+ sorted(group_users, key=lambda k: k['name']))
# check and delete user in group
for user in users:
self.groups_client.check_group_user_existence(
@@ -118,7 +119,8 @@
self.groups_client.add_group_user(group['id'], user['id'])
# list groups which user belongs to
user_groups = self.users_client.list_user_groups(user['id'])['groups']
- self.assertEqual(sorted(groups), sorted(user_groups))
+ self.assertEqual(sorted(groups, key=lambda k: k['name']),
+ sorted(user_groups, key=lambda k: k['name']))
self.assertEqual(2, len(user_groups))
@test.idempotent_id('cc9a57a5-a9ed-4f2d-a29f-4f979a06ec71')
diff --git a/tempest/api/identity/admin/v3/test_inherits.py b/tempest/api/identity/admin/v3/test_inherits.py
index 76771bb..373d44b 100644
--- a/tempest/api/identity/admin/v3/test_inherits.py
+++ b/tempest/api/identity/admin/v3/test_inherits.py
@@ -68,10 +68,10 @@
name=data_utils.rand_name('Role'))['role']
self.addCleanup(self.roles_client.delete_role, src_role['id'])
# Assign role on domains user
- self.roles_client.assign_inherited_role_on_domains_user(
+ self.inherited_roles_client.create_inherited_role_on_domains_user(
self.domain['id'], self.user['id'], src_role['id'])
# list role on domains user
- roles = self.roles_client.\
+ roles = self.inherited_roles_client.\
list_inherited_project_role_for_user_on_domain(
self.domain['id'], self.user['id'])['roles']
@@ -80,10 +80,11 @@
src_role['id'])
# Check role on domains user
- self.roles_client.check_user_inherited_project_role_on_domain(
- self.domain['id'], self.user['id'], src_role['id'])
+ (self.inherited_roles_client.
+ check_user_inherited_project_role_on_domain(
+ self.domain['id'], self.user['id'], src_role['id']))
# Revoke role from domains user.
- self.roles_client.revoke_inherited_role_from_user_on_domain(
+ self.inherited_roles_client.delete_inherited_role_from_user_on_domain(
self.domain['id'], self.user['id'], src_role['id'])
@test.idempotent_id('c7a8dda2-be50-4fb4-9a9c-e830771078b1')
@@ -93,10 +94,10 @@
name=data_utils.rand_name('Role'))['role']
self.addCleanup(self.roles_client.delete_role, src_role['id'])
# Assign role on domains group
- self.roles_client.assign_inherited_role_on_domains_group(
+ self.inherited_roles_client.create_inherited_role_on_domains_group(
self.domain['id'], self.group['id'], src_role['id'])
# List role on domains group
- roles = self.roles_client.\
+ roles = self.inherited_roles_client.\
list_inherited_project_role_for_group_on_domain(
self.domain['id'], self.group['id'])['roles']
@@ -105,10 +106,11 @@
src_role['id'])
# Check role on domains group
- self.roles_client.check_group_inherited_project_role_on_domain(
- self.domain['id'], self.group['id'], src_role['id'])
+ (self.inherited_roles_client.
+ check_group_inherited_project_role_on_domain(
+ self.domain['id'], self.group['id'], src_role['id']))
# Revoke role from domains group
- self.roles_client.revoke_inherited_role_from_group_on_domain(
+ self.inherited_roles_client.delete_inherited_role_from_group_on_domain(
self.domain['id'], self.group['id'], src_role['id'])
@test.idempotent_id('18b70e45-7687-4b72-8277-b8f1a47d7591')
@@ -118,13 +120,14 @@
name=data_utils.rand_name('Role'))['role']
self.addCleanup(self.roles_client.delete_role, src_role['id'])
# Assign role on projects user
- self.roles_client.assign_inherited_role_on_projects_user(
+ self.inherited_roles_client.create_inherited_role_on_projects_user(
self.project['id'], self.user['id'], src_role['id'])
# Check role on projects user
- self.roles_client.check_user_has_flag_on_inherited_to_project(
- self.project['id'], self.user['id'], src_role['id'])
+ (self.inherited_roles_client.
+ check_user_has_flag_on_inherited_to_project(
+ self.project['id'], self.user['id'], src_role['id']))
# Revoke role from projects user
- self.roles_client.revoke_inherited_role_from_user_on_project(
+ self.inherited_roles_client.delete_inherited_role_from_user_on_project(
self.project['id'], self.user['id'], src_role['id'])
@test.idempotent_id('26021436-d5a4-4256-943c-ded01e0d4b45')
@@ -134,11 +137,13 @@
name=data_utils.rand_name('Role'))['role']
self.addCleanup(self.roles_client.delete_role, src_role['id'])
# Assign role on projects group
- self.roles_client.assign_inherited_role_on_projects_group(
+ self.inherited_roles_client.create_inherited_role_on_projects_group(
self.project['id'], self.group['id'], src_role['id'])
# Check role on projects group
- self.roles_client.check_group_has_flag_on_inherited_to_project(
- self.project['id'], self.group['id'], src_role['id'])
+ (self.inherited_roles_client.
+ check_group_has_flag_on_inherited_to_project(
+ self.project['id'], self.group['id'], src_role['id']))
# Revoke role from projects group
- self.roles_client.revoke_inherited_role_from_group_on_project(
- self.project['id'], self.group['id'], src_role['id'])
+ (self.inherited_roles_client.
+ delete_inherited_role_from_group_on_project(
+ self.project['id'], self.group['id'], src_role['id']))
diff --git a/tempest/api/identity/base.py b/tempest/api/identity/base.py
index 9e40c42..f5e4943 100644
--- a/tempest/api/identity/base.py
+++ b/tempest/api/identity/base.py
@@ -173,6 +173,7 @@
cls.users_client = cls.os_adm.users_v3_client
cls.trusts_client = cls.os_adm.trusts_client
cls.roles_client = cls.os_adm.roles_v3_client
+ cls.inherited_roles_client = cls.os_adm.inherited_roles_client
cls.token = cls.os_adm.token_v3_client
cls.endpoints_client = cls.os_adm.endpoints_v3_client
cls.regions_client = cls.os_adm.regions_client
diff --git a/tempest/api/image/admin/v2/test_images.py b/tempest/api/image/admin/v2/test_images.py
index 80da7a1..c719b7a 100644
--- a/tempest/api/image/admin/v2/test_images.py
+++ b/tempest/api/image/admin/v2/test_images.py
@@ -13,7 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-from six import moves
+import six
import testtools
from tempest.api.image import base
@@ -42,7 +42,7 @@
self.addCleanup(self.client.delete_image, image_id)
# upload an image file
content = data_utils.random_bytes()
- image_file = moves.cStringIO(content)
+ image_file = six.BytesIO(content)
self.client.store_image_file(image_id, image_file)
# deactivate image
self.admin_client.deactivate_image(image_id)
diff --git a/tempest/api/image/base.py b/tempest/api/image/base.py
index e7a46b0..f74f97b 100755
--- a/tempest/api/image/base.py
+++ b/tempest/api/image/base.py
@@ -12,7 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-from six import moves
+import six
from tempest.common import image as common_image
from tempest.common.utils import data_utils
@@ -118,7 +118,7 @@
cls.alt_tenant_id = cls.alt_image_member_client.tenant_id
def _create_image(self):
- image_file = moves.cStringIO(data_utils.random_bytes())
+ image_file = six.BytesIO(data_utils.random_bytes())
image = self.create_image(container_format='bare',
disk_format='raw',
is_public=False,
diff --git a/tempest/api/image/v1/test_images.py b/tempest/api/image/v1/test_images.py
index 694408d..712b34b 100644
--- a/tempest/api/image/v1/test_images.py
+++ b/tempest/api/image/v1/test_images.py
@@ -13,7 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-from six import moves
+import six
from tempest.api.image import base
from tempest.common import image as common_image
@@ -63,7 +63,7 @@
self.assertEqual(val, body.get('properties')[key])
# Now try uploading an image file
- image_file = moves.cStringIO(data_utils.random_bytes())
+ image_file = six.BytesIO(data_utils.random_bytes())
body = self.client.update_image(image_id, data=image_file)['image']
self.assertIn('size', body)
self.assertEqual(1024, body.get('size'))
@@ -199,7 +199,7 @@
Note that the size of the new image is a random number between
1024 and 4096
"""
- image_file = moves.cStringIO(data_utils.random_bytes(size))
+ image_file = six.BytesIO(data_utils.random_bytes(size))
name = 'New Standard Image %s' % name
image = cls.create_image(name=name,
container_format=container_format,
@@ -294,7 +294,7 @@
disk_format, size):
"""Create a new standard image and return newly-registered image-id"""
- image_file = moves.cStringIO(data_utils.random_bytes(size))
+ image_file = six.BytesIO(data_utils.random_bytes(size))
name = 'New Standard Image %s' % name
image = cls.create_image(name=name,
container_format=container_format,
diff --git a/tempest/api/image/v2/test_images.py b/tempest/api/image/v2/test_images.py
index 42a4352..443e332 100644
--- a/tempest/api/image/v2/test_images.py
+++ b/tempest/api/image/v2/test_images.py
@@ -16,7 +16,7 @@
import random
-from six import moves
+import six
from oslo_log import log as logging
from tempest.api.image import base
@@ -60,7 +60,7 @@
# Now try uploading an image file
file_content = data_utils.random_bytes()
- image_file = moves.cStringIO(file_content)
+ image_file = six.BytesIO(file_content)
self.client.store_image_file(image_id, image_file)
# Now try to get image details
@@ -117,7 +117,7 @@
image_id = body['id']
# Now try uploading an image file
- image_file = moves.cStringIO(data_utils.random_bytes())
+ image_file = six.BytesIO(data_utils.random_bytes())
self.client.store_image_file(image_id, image_file)
# Update Image
@@ -160,7 +160,7 @@
1024 and 4096
"""
size = random.randint(1024, 4096)
- image_file = moves.cStringIO(data_utils.random_bytes(size))
+ image_file = six.BytesIO(data_utils.random_bytes(size))
name = data_utils.rand_name('image')
body = cls.create_image(name=name,
container_format=container_format,
diff --git a/tempest/api/network/admin/test_quotas.py b/tempest/api/network/admin/test_quotas.py
index 2ff31e0..3a264ff 100644
--- a/tempest/api/network/admin/test_quotas.py
+++ b/tempest/api/network/admin/test_quotas.py
@@ -87,5 +87,5 @@
@test.idempotent_id('2390f766-836d-40ef-9aeb-e810d78207fb')
def test_quotas(self):
- new_quotas = {'network': 0, 'security_group': 0}
+ new_quotas = {'network': 0, 'port': 0}
self._check_quotas(new_quotas)
diff --git a/tempest/api/object_storage/base.py b/tempest/api/object_storage/base.py
index 85026af..fd973c6 100644
--- a/tempest/api/object_storage/base.py
+++ b/tempest/api/object_storage/base.py
@@ -58,6 +58,16 @@
cls.container_client.auth_provider.clear_auth()
cls.account_client.auth_provider.clear_auth()
+ # make sure that discoverability is enabled and that the sections
+ # have not been disallowed by Swift
+ cls.policies = None
+
+ if CONF.object_storage_feature_enabled.discoverability:
+ _, body = cls.account_client.list_extensions()
+
+ if 'swift' in body and 'policies' in body['swift']:
+ cls.policies = body['swift']['policies']
+
cls.containers = []
@classmethod
@@ -117,5 +127,5 @@
"""Check the existence and the format of response headers"""
self.assertThat(resp, custom_matchers.ExistsAllResponseHeaders(
- target, method))
+ target, method, self.policies))
self.assertThat(resp, custom_matchers.AreAllWellFormatted())
diff --git a/tempest/api/object_storage/test_account_services.py b/tempest/api/object_storage/test_account_services.py
index 9e9f08b..a0c0a5f 100644
--- a/tempest/api/object_storage/test_account_services.py
+++ b/tempest/api/object_storage/test_account_services.py
@@ -15,7 +15,6 @@
import random
-from six import moves
import testtools
from tempest.api.object_storage import base
@@ -42,7 +41,7 @@
@classmethod
def resource_setup(cls):
super(AccountTest, cls).resource_setup()
- for i in moves.xrange(ord('a'), ord('f') + 1):
+ for i in range(ord('a'), ord('f') + 1):
name = data_utils.rand_name(name='%s-' % chr(i))
cls.container_client.create_container(name)
cls.containers.append(name)
@@ -140,7 +139,8 @@
@test.idempotent_id('5cfa4ab2-4373-48dd-a41f-a532b12b08b2')
def test_list_containers_with_limit(self):
# list containers one of them, half of them then all of them
- for limit in (1, self.containers_count / 2, self.containers_count):
+ for limit in (1, self.containers_count // 2,
+ self.containers_count):
params = {'limit': limit}
resp, container_list = \
self.account_client.list_account_containers(params=params)
@@ -161,12 +161,13 @@
self.assertEqual(len(container_list), 0)
- params = {'marker': self.containers[self.containers_count / 2]}
+ params = {'marker': self.containers[self.containers_count // 2]}
resp, container_list = \
self.account_client.list_account_containers(params=params)
self.assertHeaders(resp, 'Account', 'GET')
- self.assertEqual(len(container_list), self.containers_count / 2 - 1)
+ self.assertEqual(len(container_list),
+ self.containers_count // 2 - 1)
@test.idempotent_id('5ca164e4-7bde-43fa-bafb-913b53b9e786')
def test_list_containers_with_end_marker(self):
@@ -180,11 +181,11 @@
self.assertHeaders(resp, 'Account', 'GET')
self.assertEqual(len(container_list), 0)
- params = {'end_marker': self.containers[self.containers_count / 2]}
+ params = {'end_marker': self.containers[self.containers_count // 2]}
resp, container_list = \
self.account_client.list_account_containers(params=params)
self.assertHeaders(resp, 'Account', 'GET')
- self.assertEqual(len(container_list), self.containers_count / 2)
+ self.assertEqual(len(container_list), self.containers_count // 2)
@test.idempotent_id('ac8502c2-d4e4-4f68-85a6-40befea2ef5e')
def test_list_containers_with_marker_and_end_marker(self):
@@ -215,12 +216,12 @@
# list containers combining limit and end_marker param
limit = random.randint(1, self.containers_count)
params = {'limit': limit,
- 'end_marker': self.containers[self.containers_count / 2]}
+ 'end_marker': self.containers[self.containers_count // 2]}
resp, container_list = self.account_client.list_account_containers(
params=params)
self.assertHeaders(resp, 'Account', 'GET')
self.assertEqual(len(container_list),
- min(limit, self.containers_count / 2))
+ min(limit, self.containers_count // 2))
@test.idempotent_id('8cf98d9c-e3a0-4e44-971b-c87656fdddbd')
def test_list_containers_with_limit_and_marker_and_end_marker(self):
diff --git a/tempest/api/object_storage/test_object_services.py b/tempest/api/object_storage/test_object_services.py
index a707ebb..919f695 100644
--- a/tempest/api/object_storage/test_object_services.py
+++ b/tempest/api/object_storage/test_object_services.py
@@ -47,9 +47,9 @@
object_name = data_utils.rand_name(name='LObject')
data = data_utils.arbitrary_string()
segments = 10
- data_segments = [data + str(i) for i in six.moves.xrange(segments)]
+ data_segments = [data + str(i) for i in range(segments)]
# uploading segments
- for i in six.moves.xrange(segments):
+ for i in range(segments):
resp, _ = self.object_client.create_object_segments(
self.container_name, object_name, i, data_segments[i])
@@ -901,9 +901,9 @@
object_name = data_utils.rand_name(name='LObject')
data = data_utils.arbitrary_string()
segments = 10
- data_segments = [data + str(i) for i in six.moves.xrange(segments)]
+ data_segments = [data + str(i) for i in range(segments)]
# uploading segments
- for i in six.moves.xrange(segments):
+ for i in range(segments):
resp, _ = self.object_client.create_object_segments(
self.container_name, object_name, i, data_segments[i])
# creating a manifest file
diff --git a/tempest/api/orchestration/stacks/test_nova_keypair_resources.py b/tempest/api/orchestration/stacks/test_nova_keypair_resources.py
index 0400e76..8d12e75 100644
--- a/tempest/api/orchestration/stacks/test_nova_keypair_resources.py
+++ b/tempest/api/orchestration/stacks/test_nova_keypair_resources.py
@@ -72,10 +72,10 @@
for outputs in stack['outputs']:
output_map[outputs['output_key']] = outputs['output_value']
# Test that first key generated public and private keys
- self.assertTrue('KeyPair_PublicKey' in output_map)
- self.assertTrue("Generated" in output_map['KeyPair_PublicKey'])
- self.assertTrue('KeyPair_PrivateKey' in output_map)
- self.assertTrue('-----BEGIN' in output_map['KeyPair_PrivateKey'])
+ self.assertIn('KeyPair_PublicKey', output_map)
+ self.assertIn("Generated", output_map['KeyPair_PublicKey'])
+ self.assertIn('KeyPair_PrivateKey', output_map)
+ self.assertIn('-----BEGIN', output_map['KeyPair_PrivateKey'])
# Test that second key generated public key, and private key is not
# in the output due to save_private_key = false
self.assertTrue('KeyPairDontSavePrivate_PublicKey' in output_map)
diff --git a/tempest/api/volume/admin/test_volumes_backup.py b/tempest/api/volume/admin/test_volumes_backup.py
index f7013d8..a26052c 100755
--- a/tempest/api/volume/admin/test_volumes_backup.py
+++ b/tempest/api/volume/admin/test_volumes_backup.py
@@ -13,9 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import base64
-import six
-
+from oslo_serialization import base64
from oslo_serialization import jsonutils as json
from tempest.api.volume import base
@@ -46,13 +44,11 @@
self.admin_backups_client.wait_for_resource_deletion(backup_id)
def _decode_url(self, backup_url):
- return json.loads(base64.decodestring(backup_url))
+ return json.loads(base64.decode_as_text(backup_url))
def _encode_backup(self, backup):
retval = json.dumps(backup)
- if six.PY3:
- retval = retval.encode('utf-8')
- return base64.encodestring(retval)
+ return base64.encode_as_text(retval)
def _modify_backup_url(self, backup_url, changes):
backup = self._decode_url(backup_url)
diff --git a/tempest/api/volume/base.py b/tempest/api/volume/base.py
index 183452c..ada55f7 100644
--- a/tempest/api/volume/base.py
+++ b/tempest/api/volume/base.py
@@ -175,14 +175,19 @@
except Exception:
pass
- @classmethod
- def create_server(cls, name, **kwargs):
- tenant_network = cls.get_tenant_network()
+ def create_server(self, name, **kwargs):
+ tenant_network = self.get_tenant_network()
body, _ = compute.create_test_server(
- cls.os,
+ self.os,
tenant_network=tenant_network,
name=name,
**kwargs)
+
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ waiters.wait_for_server_termination,
+ self.servers_client, body['id'])
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.servers_client.delete_server, body['id'])
return body
diff --git a/tempest/api/volume/test_volumes_actions.py b/tempest/api/volume/test_volumes_actions.py
index 7783c18..b80a4a4 100755
--- a/tempest/api/volume/test_volumes_actions.py
+++ b/tempest/api/volume/test_volumes_actions.py
@@ -45,34 +45,25 @@
@classmethod
def resource_setup(cls):
super(VolumesV2ActionsTest, cls).resource_setup()
- # Create a test shared instance
- srv_name = data_utils.rand_name(cls.__name__ + '-Instance')
- cls.server = cls.create_server(
- name=srv_name,
- wait_until='ACTIVE')
# Create a test shared volume for attach/detach tests
cls.volume = cls.create_volume()
waiters.wait_for_volume_status(cls.client,
cls.volume['id'], 'available')
- @classmethod
- def resource_cleanup(cls):
- # Delete the test instance
- cls.servers_client.delete_server(cls.server['id'])
- waiters.wait_for_server_termination(cls.servers_client,
- cls.server['id'])
-
- super(VolumesV2ActionsTest, cls).resource_cleanup()
-
@test.idempotent_id('fff42874-7db5-4487-a8e1-ddda5fb5288d')
@test.stresstest(class_setup_per='process')
@test.attr(type='smoke')
@test.services('compute')
def test_attach_detach_volume_to_instance(self):
+ # Create a server
+ srv_name = data_utils.rand_name(self.__class__.__name__ + '-Instance')
+ server = self.create_server(
+ name=srv_name,
+ wait_until='ACTIVE')
# Volume is attached and detached successfully from an instance
self.client.attach_volume(self.volume['id'],
- instance_uuid=self.server['id'],
+ instance_uuid=server['id'],
mountpoint='/dev/%s' %
CONF.compute.volume_device_name)
waiters.wait_for_volume_status(self.client,
@@ -99,9 +90,14 @@
@test.stresstest(class_setup_per='process')
@test.services('compute')
def test_get_volume_attachment(self):
+ # Create a server
+ srv_name = data_utils.rand_name(self.__class__.__name__ + '-Instance')
+ server = self.create_server(
+ name=srv_name,
+ wait_until='ACTIVE')
# Verify that a volume's attachment information is retrieved
self.client.attach_volume(self.volume['id'],
- instance_uuid=self.server['id'],
+ instance_uuid=server['id'],
mountpoint='/dev/%s' %
CONF.compute.volume_device_name)
waiters.wait_for_volume_status(self.client,
@@ -119,7 +115,7 @@
self.assertEqual('/dev/%s' %
CONF.compute.volume_device_name,
attachment['device'])
- self.assertEqual(self.server['id'], attachment['server_id'])
+ self.assertEqual(server['id'], attachment['server_id'])
self.assertEqual(self.volume['id'], attachment['id'])
self.assertEqual(self.volume['id'], attachment['volume_id'])
diff --git a/tempest/api/volume/test_volumes_backup.py b/tempest/api/volume/test_volumes_backup.py
index 50a1360..86076b7 100755
--- a/tempest/api/volume/test_volumes_backup.py
+++ b/tempest/api/volume/test_volumes_backup.py
@@ -30,10 +30,6 @@
if not CONF.volume_feature_enabled.backup:
raise cls.skipException("Cinder backup feature disabled")
- @classmethod
- def resource_setup(cls):
- super(VolumesBackupsV2Test, cls).resource_setup()
-
@test.idempotent_id('a66eb488-8ee1-47d4-8e9f-575a095728c6')
def test_volume_backup_create_get_detailed_list_restore_delete(self):
# Create backup
@@ -91,7 +87,6 @@
server_name = data_utils.rand_name(
self.__class__.__name__ + '-instance')
server = self.create_server(name=server_name, wait_until='ACTIVE')
- self.addCleanup(self.servers_client.delete_server, server['id'])
# Attach volume to instance
self.servers_client.attach_volume(server['id'],
volumeId=volume['id'])
diff --git a/tempest/api/volume/test_volumes_negative.py b/tempest/api/volume/test_volumes_negative.py
index 16c8571..e8ead5b 100755
--- a/tempest/api/volume/test_volumes_negative.py
+++ b/tempest/api/volume/test_volumes_negative.py
@@ -15,7 +15,6 @@
from tempest.api.volume import base
from tempest.common.utils import data_utils
-from tempest.common import waiters
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -181,9 +180,6 @@
server = self.create_server(
name=srv_name,
wait_until='ACTIVE')
- self.addCleanup(waiters.wait_for_server_termination,
- self.servers_client, server['id'])
- self.addCleanup(self.servers_client.delete_server, server['id'])
self.assertRaises(lib_exc.NotFound,
self.client.attach_volume,
diff --git a/tempest/api/volume/test_volumes_snapshots.py b/tempest/api/volume/test_volumes_snapshots.py
index 20c647a..8f7996a 100755
--- a/tempest/api/volume/test_volumes_snapshots.py
+++ b/tempest/api/volume/test_volumes_snapshots.py
@@ -36,7 +36,7 @@
cls.name_field = cls.special_fields['name_field']
cls.descrip_field = cls.special_fields['descrip_field']
# Create 2 snapshots
- for _ in xrange(2):
+ for _ in range(2):
cls.create_snapshot(cls.volume_origin['id'])
def _detach(self, volume_id):
@@ -80,7 +80,6 @@
server = self.create_server(
name=server_name,
wait_until='ACTIVE')
- self.addCleanup(self.servers_client.delete_server, server['id'])
self.servers_client.attach_volume(
server['id'], volumeId=self.volume_origin['id'],
device='/dev/%s' % CONF.compute.volume_device_name)
diff --git a/tempest/clients.py b/tempest/clients.py
index f8c276a..4c677f0 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -246,6 +246,8 @@
self.auth_provider, **params_v3)
self.roles_v3_client = identity.v3.RolesClient(self.auth_provider,
**params_v3)
+ self.inherited_roles_client = identity.v3.InheritedRolesClient(
+ self.auth_provider, **params_v3)
self.identity_services_v3_client = identity.v3.ServicesClient(
self.auth_provider, **params_v3)
self.policies_client = identity.v3.PoliciesClient(self.auth_provider,
diff --git a/tempest/cmd/init.py b/tempest/cmd/init.py
index eeca063..ba1f1fa 100644
--- a/tempest/cmd/init.py
+++ b/tempest/cmd/init.py
@@ -69,7 +69,10 @@
def get_parser(self, prog_name):
parser = super(TempestInit, self).get_parser(prog_name)
- parser.add_argument('dir', nargs='?', default=os.getcwd())
+ parser.add_argument('dir', nargs='?', default=os.getcwd(),
+ help="The path to the workspace directory. If you "
+ "omit this argument, the workspace directory is "
+ "your current directory")
parser.add_argument('--config-dir', '-c', default=None)
parser.add_argument('--show-global-config-dir', '-s',
action='store_true', dest='show_global_dir',
@@ -78,7 +81,7 @@
parser.add_argument('--name', help="The workspace name", default=None)
parser.add_argument('--workspace-path', default=None,
help="The path to the workspace file, the default "
- "is ~/.tempest/workspace")
+ "is ~/.tempest/workspace.yaml")
return parser
def generate_testr_conf(self, local_path):
diff --git a/tempest/cmd/verify_tempest_config.py b/tempest/cmd/verify_tempest_config.py
index 9947f2a..630532c 100644
--- a/tempest/cmd/verify_tempest_config.py
+++ b/tempest/cmd/verify_tempest_config.py
@@ -46,7 +46,7 @@
conf_dir = os.environ.get('TEMPEST_CONFIG_DIR', default_config_dir)
conf_file = os.environ.get('TEMPEST_CONFIG', default_config_file)
path = os.path.join(conf_dir, conf_file)
- fd = open(path, 'rw')
+ fd = open(path, 'r+')
return fd
@@ -69,7 +69,7 @@
def verify_glance_api_versions(os, update):
# Check glance api versions
- _, versions = os.image_client.get_versions()
+ versions = _get_api_versions(os, 'glance')
if CONF.image_feature_enabled.api_v1 != contains_version('v1.', versions):
print_and_or_update('api_v1', 'image-feature-enabled',
not CONF.image_feature_enabled.api_v1, update)
@@ -96,6 +96,7 @@
'nova': os.servers_client,
'keystone': os.identity_client,
'cinder': os.volumes_client,
+ 'glance': os.image_client,
}
if service != 'keystone':
# Since keystone may be listening on a path, do not remove the path.
diff --git a/tempest/common/custom_matchers.py b/tempest/common/custom_matchers.py
index 998612b..b6ff241 100644
--- a/tempest/common/custom_matchers.py
+++ b/tempest/common/custom_matchers.py
@@ -28,7 +28,7 @@
checked in each test code.
"""
- def __init__(self, target, method):
+ def __init__(self, target, method, policies=None):
"""Initialization of ExistsAllResponseHeaders
param: target Account/Container/Object
@@ -36,6 +36,7 @@
"""
self.target = target
self.method = method
+ self.policies = policies or []
def _content_length_required(self, resp):
# Verify whether given HTTP response must contain content-length.
@@ -84,11 +85,63 @@
return NonExistentHeader('x-account-container-count')
if 'x-account-object-count' not in actual:
return NonExistentHeader('x-account-object-count')
+ if actual['x-account-container-count'] > 0:
+ acct_header = "x-account-storage-policy-"
+ matched_policy_count = 0
+
+ # Loop through the policies and look for account
+ # usage data. There should be at least 1 set
+ for policy in self.policies:
+ front_header = acct_header + policy['name'].lower()
+
+ usage_policies = [
+ front_header + '-bytes-used',
+ front_header + '-object-count',
+ front_header + '-container-count'
+ ]
+
+ # There should be 3 usage values for a give storage
+ # policy in an account bytes, object count, and
+ # container count
+ policy_hdrs = sum(1 for use_hdr in usage_policies
+ if use_hdr in actual)
+
+ # If there are less than 3 headers here then 1 is
+ # missing, let's figure out which one and report
+ if policy_hdrs == 3:
+ matched_policy_count = matched_policy_count + 1
+ else:
+ if policy_hdrs > 0 and policy_hdrs < 3:
+ for use_hdr in usage_policies:
+ if use_hdr not in actual:
+ return NonExistentHeader(use_hdr)
+
+ # Only flag an error if actual policies have been read and
+ # no usage has been found
+ if self.policies and matched_policy_count == 0:
+ return GenericError("No storage policy usage headers")
+
elif self.target == 'Container':
if 'x-container-bytes-used' not in actual:
return NonExistentHeader('x-container-bytes-used')
if 'x-container-object-count' not in actual:
return NonExistentHeader('x-container-object-count')
+ if 'x-storage-policy' not in actual:
+ return NonExistentHeader('x-storage-policy')
+ else:
+ policy_name = actual['x-storage-policy']
+
+ # loop through the policies and ensure that
+ # the value in the container header matches
+ # one of the storage policies
+ for policy in self.policies:
+ if policy['name'] == policy_name:
+ break
+ else:
+ # Ensure that there are actual policies stored
+ if self.policies:
+ return InvalidHeaderValue('x-storage-policy',
+ policy_name)
elif self.target == 'Object':
if 'etag' not in actual:
return NonExistentHeader('etag')
@@ -114,6 +167,19 @@
return None
+class GenericError(object):
+ """Informs an error message of a generic error during header evaluation"""
+
+ def __init__(self, body):
+ self.body = body
+
+ def describe(self):
+ return "%s" % self.body
+
+ def get_details(self):
+ return {}
+
+
class NonExistentHeader(object):
"""Informs an error message in the case of missing a certain header"""
@@ -127,6 +193,20 @@
return {}
+class InvalidHeaderValue(object):
+ """Informs an error message when a header contains a bad value"""
+
+ def __init__(self, header, value):
+ self.header = header
+ self.value = value
+
+ def describe(self):
+ return "InvalidValue (%s, %s)" % (self.header, self.value)
+
+ def get_details(self):
+ return {}
+
+
class AreAllWellFormatted(object):
"""Specific matcher to check the correctness of formats of values
diff --git a/tempest/config.py b/tempest/config.py
index 3fd20ab..f6c89ae 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -304,6 +304,12 @@
title="Enabled Compute Service Features")
ComputeFeaturesGroup = [
+ # NOTE(mriedem): This is a feature toggle for bug 1175464 which is fixed in
+ # mitaka and newton. This option can be removed after liberty-eol.
+ cfg.BoolOpt('allow_port_security_disabled',
+ default=False,
+ help='Does the test environment support creating ports in a '
+ 'network where port security is disabled?'),
cfg.BoolOpt('disk_config',
default=True,
help="If false, skip disk config tests"),
@@ -370,7 +376,8 @@
default=True,
help='Enables returning of the instance password by the '
'relevant server API calls such as create, rebuild '
- 'or rescue.'),
+ 'or rescue. This configuration value should be same as '
+ 'nova.conf: DEFAULT.enable_instance_password'),
cfg.BoolOpt('interface_attach',
default=True,
help='Does the test environment support dynamic network '
@@ -564,6 +571,9 @@
default=True,
help="Does the test environment support changing"
" port admin state"),
+ cfg.BoolOpt('port_security',
+ default=False,
+ help="Does the test environment support port security?"),
]
validation_group = cfg.OptGroup(name='validation',
diff --git a/tempest/lib/common/utils/data_utils.py b/tempest/lib/common/utils/data_utils.py
index 6b6548e..70be40c 100644
--- a/tempest/lib/common/utils/data_utils.py
+++ b/tempest/lib/common/utils/data_utils.py
@@ -171,7 +171,7 @@
:return: size randomly bytes
:rtype: string
"""
- return ''.join([chr(random.randint(0, 255))
+ return b''.join([six.int2byte(random.randint(0, 255))
for i in range(size)])
@@ -204,5 +204,5 @@
# Courtesy of http://stackoverflow.com/a/312464
def chunkify(sequence, chunksize):
"""Yield successive chunks from `sequence`."""
- for i in six.moves.xrange(0, len(sequence), chunksize):
+ for i in range(0, len(sequence), chunksize):
yield sequence[i:i + chunksize]
diff --git a/tempest/lib/services/compute/hosts_client.py b/tempest/lib/services/compute/hosts_client.py
index 16b5edd..1b93b00 100644
--- a/tempest/lib/services/compute/hosts_client.py
+++ b/tempest/lib/services/compute/hosts_client.py
@@ -45,8 +45,9 @@
def update_host(self, hostname, **kwargs):
"""Update a host.
- Available params: see http://developer.openstack.org/
- api-ref-compute-v2.1.html#enablehost
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref-compute-v2.1.html#enablehost
"""
request_body = {
diff --git a/tempest/lib/services/compute/images_client.py b/tempest/lib/services/compute/images_client.py
index 3dc3749..e937c13 100644
--- a/tempest/lib/services/compute/images_client.py
+++ b/tempest/lib/services/compute/images_client.py
@@ -27,8 +27,9 @@
def create_image(self, server_id, **kwargs):
"""Create an image of the original server.
- Available params: see http://developer.openstack.org/
- api-ref-compute-v2.1.html#createImage
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref-compute-v2.1.html#createImage
"""
post_body = {'createImage': kwargs}
@@ -41,8 +42,9 @@
def list_images(self, detail=False, **params):
"""Return a list of all images filtered by any parameter.
- Available params: see http://developer.openstack.org/
- api-ref-compute-v2.1.html#listImages
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref-compute-v2.1.html#listImages
"""
url = 'images'
_schema = schema.list_images
@@ -81,8 +83,9 @@
def set_image_metadata(self, image_id, meta):
"""Set the metadata for an image.
- Available params: see http://developer.openstack.org/
- api-ref-compute-v2.1.html#createImageMetadata
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref-compute-v2.1.html#createImageMetadata
"""
post_body = json.dumps({'metadata': meta})
resp, body = self.put('images/%s/metadata' % image_id, post_body)
@@ -93,8 +96,9 @@
def update_image_metadata(self, image_id, meta):
"""Update the metadata for an image.
- Available params: see http://developer.openstack.org/
- api-ref-compute-v2.1.html#updateImageMetadata
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref-compute-v2.1.html#updateImageMetadata
"""
post_body = json.dumps({'metadata': meta})
resp, body = self.post('images/%s/metadata' % image_id, post_body)
@@ -112,8 +116,9 @@
def set_image_metadata_item(self, image_id, key, meta):
"""Set the value for a specific image metadata key.
- Available params: see http://developer.openstack.org/
- api-ref-compute-v2.1.html#setImageMetadataItem
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref-compute-v2.1.html#setImageMetadataItem
"""
post_body = json.dumps({'meta': meta})
resp, body = self.put('images/%s/metadata/%s' % (image_id, key),
diff --git a/tempest/lib/services/compute/interfaces_client.py b/tempest/lib/services/compute/interfaces_client.py
index 80192a1..37157a4 100644
--- a/tempest/lib/services/compute/interfaces_client.py
+++ b/tempest/lib/services/compute/interfaces_client.py
@@ -31,8 +31,9 @@
def create_interface(self, server_id, **kwargs):
"""Create an interface.
- Available params: see http://developer.openstack.org/
- api-ref-compute-v2.1.html#createAttachInterface
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref-compute-v2.1.html#createAttachInterface
"""
post_body = {'interfaceAttachment': kwargs}
post_body = json.dumps(post_body)
diff --git a/tempest/lib/services/compute/keypairs_client.py b/tempest/lib/services/compute/keypairs_client.py
index 2246739..c3f1781 100755
--- a/tempest/lib/services/compute/keypairs_client.py
+++ b/tempest/lib/services/compute/keypairs_client.py
@@ -30,8 +30,9 @@
def list_keypairs(self, **params):
"""Lists keypairs that are associated with the account.
- Available params: see http://developer.openstack.org/
- api-ref-compute-v2.1.html#listKeypairs
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref-compute-v2.1.html#listKeypairs
"""
url = 'os-keypairs'
if params:
@@ -45,8 +46,9 @@
def show_keypair(self, keypair_name, **params):
"""Shows details for a keypair that is associated with the account.
- Available params: see http://developer.openstack.org/
- api-ref-compute-v2.1.html#showKeypair
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref-compute-v2.1.html#showKeypair
"""
url = "os-keypairs/%s" % keypair_name
if params:
@@ -60,8 +62,9 @@
def create_keypair(self, **kwargs):
"""Create a keypair.
- Available params: see http://developer.openstack.org/
- api-ref-compute-v2.1.html#createKeypair
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref-compute-v2.1.html#createKeypair
"""
post_body = json.dumps({'keypair': kwargs})
resp, body = self.post("os-keypairs", body=post_body)
@@ -73,8 +76,9 @@
def delete_keypair(self, keypair_name, **params):
"""Deletes a keypair.
- Available params: see http://developer.openstack.org/
- api-ref-compute-v2.1.html#deleteKeypair
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref-compute-v2.1.html#deleteKeypair
"""
url = "os-keypairs/%s" % keypair_name
if params:
diff --git a/tempest/lib/services/compute/migrations_client.py b/tempest/lib/services/compute/migrations_client.py
index c3bdba7..375cbda 100644
--- a/tempest/lib/services/compute/migrations_client.py
+++ b/tempest/lib/services/compute/migrations_client.py
@@ -30,8 +30,9 @@
def list_migrations(self, **params):
"""List all migrations.
- Available params: see http://developer.openstack.org/
- api-ref-compute-v2.1.html#listMigrations
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref-compute-v2.1.html#listMigrations
"""
url = 'os-migrations'
diff --git a/tempest/lib/services/compute/quota_classes_client.py b/tempest/lib/services/compute/quota_classes_client.py
index 9dc04ad..523a306 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.
- Available params: see http://developer.openstack.org/
- api-ref-compute-v2.1.html#updatequota
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref-compute-v2.1.html#updatequota
"""
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 6d41f4b..a2b0397 100644
--- a/tempest/lib/services/compute/quotas_client.py
+++ b/tempest/lib/services/compute/quotas_client.py
@@ -45,8 +45,9 @@
def update_quota_set(self, tenant_id, user_id=None, **kwargs):
"""Updates the tenant's quota limits for one or more resources.
- Available params: see http://developer.openstack.org/
- api-ref-compute-v2.1.html#updateQuota
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref-compute-v2.1.html#updateQuota
"""
post_body = json.dumps({'quota_set': kwargs})
diff --git a/tempest/lib/services/compute/servers_client.py b/tempest/lib/services/compute/servers_client.py
index 8b22be0..d5902e1 100755
--- a/tempest/lib/services/compute/servers_client.py
+++ b/tempest/lib/services/compute/servers_client.py
@@ -47,8 +47,13 @@
def create_server(self, **kwargs):
"""Create server.
- Available params: see http://developer.openstack.org/
- api-ref-compute-v2.1.html#createServer
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/compute/#create-server
+
+ :param name: Server name
+ :param imageRef: Image reference (UUID)
+ :param flavorRef: Flavor reference (UUID or full URL)
Most parameters except the following are passed to the API without
any changes.
diff --git a/tempest/lib/services/identity/v2/__init__.py b/tempest/lib/services/identity/v2/__init__.py
index e69de29..b7d3c74 100644
--- a/tempest/lib/services/identity/v2/__init__.py
+++ b/tempest/lib/services/identity/v2/__init__.py
@@ -0,0 +1,24 @@
+# Copyright (c) 2016 Hewlett-Packard Enterprise Development Company, L.P.
+#
+# 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.lib.services.identity.v2.endpoints_client import EndpointsClient
+from tempest.lib.services.identity.v2.identity_client import IdentityClient
+from tempest.lib.services.identity.v2.roles_client import RolesClient
+from tempest.lib.services.identity.v2.services_client import ServicesClient
+from tempest.lib.services.identity.v2.tenants_client import TenantsClient
+from tempest.lib.services.identity.v2.token_client import TokenClient
+from tempest.lib.services.identity.v2.users_client import UsersClient
+
+__all__ = ['EndpointsClient', 'IdentityClient', 'RolesClient',
+ 'ServicesClient', 'TenantsClient', 'TokenClient', 'UsersClient']
diff --git a/tempest/lib/services/identity/v2/endpoints_client.py b/tempest/lib/services/identity/v2/endpoints_client.py
index f7b265d..770e8ae 100644
--- a/tempest/lib/services/identity/v2/endpoints_client.py
+++ b/tempest/lib/services/identity/v2/endpoints_client.py
@@ -23,8 +23,9 @@
def create_endpoint(self, **kwargs):
"""Create an endpoint for service.
- Available params: http://developer.openstack.org/
- api-ref-identity-v2-ext.html#createEndpoint
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref-identity-v2-ext.html#createEndpoint
"""
post_body = json.dumps({'endpoint': kwargs})
diff --git a/tempest/lib/services/identity/v2/roles_client.py b/tempest/lib/services/identity/v2/roles_client.py
index aaa75f1..635d013 100644
--- a/tempest/lib/services/identity/v2/roles_client.py
+++ b/tempest/lib/services/identity/v2/roles_client.py
@@ -22,8 +22,9 @@
def create_role(self, **kwargs):
"""Create a role.
- Available params: see http://developer.openstack.org/
- api-ref-identity-v2-ext.html#createRole
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref-identity-v2-ext.html#createRole
"""
post_body = json.dumps({'role': kwargs})
resp, body = self.post('OS-KSADM/roles', post_body)
@@ -34,12 +35,11 @@
def show_role(self, role_id_or_name):
"""Get a role by its id or name.
- Available params: see
- http://developer.openstack.org/
- api-ref-identity-v2-ext.html#showRoleByID
- OR
- http://developer.openstack.org/
- api-ref-identity-v2-ext.html#showRoleByName
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref-identity-v2-ext.html#showRoleByID
+ OR
+ http://developer.openstack.org/api-ref-identity-v2-ext.html#showRoleByName
"""
resp, body = self.get('OS-KSADM/roles/%s' % role_id_or_name)
self.expected_success(200, resp.status)
@@ -49,8 +49,9 @@
def list_roles(self, **params):
"""Returns roles.
- Available params: see http://developer.openstack.org/
- api-ref-identity-v2-ext.html#listRoles
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref-identity-v2-ext.html#listRoles
"""
url = 'OS-KSADM/roles'
if params:
@@ -63,8 +64,9 @@
def delete_role(self, role_id):
"""Delete a role.
- Available params: see http://developer.openstack.org/
- api-ref-identity-v2-ext.html#deleteRole
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref-identity-v2-ext.html#deleteRole
"""
resp, body = self.delete('OS-KSADM/roles/%s' % role_id)
self.expected_success(204, resp.status)
@@ -73,9 +75,9 @@
def create_user_role_on_project(self, tenant_id, user_id, role_id):
"""Add roles to a user on a tenant.
- Available params: see
- http://developer.openstack.org/
- api-ref-identity-v2-ext.html#grantRoleToUserOnTenant
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref-identity-v2-ext.html#grantRoleToUserOnTenant
"""
resp, body = self.put('/tenants/%s/users/%s/roles/OS-KSADM/%s' %
(tenant_id, user_id, role_id), "")
@@ -97,9 +99,9 @@
def delete_role_from_user_on_project(self, tenant_id, user_id, role_id):
"""Removes a role assignment for a user on a tenant.
- Available params: see
- http://developer.openstack.org/
- api-ref-identity-v2-ext.html#revokeRoleFromUserOnTenant
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref-identity-v2-ext.html#revokeRoleFromUserOnTenant
"""
resp, body = self.delete('/tenants/%s/users/%s/roles/OS-KSADM/%s' %
(tenant_id, user_id, role_id))
diff --git a/tempest/lib/services/identity/v2/services_client.py b/tempest/lib/services/identity/v2/services_client.py
index c26d419..b3f94aa 100755
--- a/tempest/lib/services/identity/v2/services_client.py
+++ b/tempest/lib/services/identity/v2/services_client.py
@@ -24,8 +24,9 @@
def create_service(self, **kwargs):
"""Create a service.
- Available params: see http://developer.openstack.org/api-ref/identity/
- v2-ext/?expanded=#create-service-admin-extension
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/identity/v2-ext/?expanded=#create-service-admin-extension
"""
post_body = json.dumps({'OS-KSADM:service': kwargs})
resp, body = self.post('/OS-KSADM/services', post_body)
@@ -44,8 +45,9 @@
def list_services(self, **params):
"""List Service - Returns Services.
- Available params: see http://developer.openstack.org/api-ref/identity/
- v2-ext/?expanded=#list-services-admin-extension
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/identity/v2-ext/?expanded=#list-services-admin-extension
"""
url = '/OS-KSADM/services'
if params:
diff --git a/tempest/lib/services/identity/v2/tenants_client.py b/tempest/lib/services/identity/v2/tenants_client.py
index f92c703..b687332 100644
--- a/tempest/lib/services/identity/v2/tenants_client.py
+++ b/tempest/lib/services/identity/v2/tenants_client.py
@@ -24,9 +24,9 @@
def create_tenant(self, **kwargs):
"""Create a tenant
- Available params: see http://developer.openstack.org/
- api-ref/identity/v2-admin/index.html#
- create-tenant
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/identity/v2-admin/index.html#create-tenant
"""
post_body = json.dumps({'tenant': kwargs})
resp, body = self.post('tenants', post_body)
@@ -37,8 +37,9 @@
def delete_tenant(self, tenant_id):
"""Delete a tenant.
- Available params: see http://developer.openstack.org/
- api-ref-identity-v2-ext.html#deleteTenant
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref-identity-v2-ext.html#deleteTenant
"""
resp, body = self.delete('tenants/%s' % str(tenant_id))
self.expected_success(204, resp.status)
@@ -47,9 +48,9 @@
def show_tenant(self, tenant_id):
"""Get tenant details.
- Available params: see
- http://developer.openstack.org/
- api-ref-identity-v2-ext.html#admin-showTenantById
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref-identity-v2-ext.html#admin-showTenantById
"""
resp, body = self.get('tenants/%s' % str(tenant_id))
self.expected_success(200, resp.status)
@@ -59,9 +60,9 @@
def list_tenants(self, **params):
"""Returns tenants.
- Available params: see http://developer.openstack.org/
- api-ref/identity/v2-admin/index.html#
- list-tenants-admin-endpoint
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/identity/v2-admin/index.html#list-tenants-admin-endpoint
"""
url = 'tenants'
if params:
@@ -74,9 +75,9 @@
def update_tenant(self, tenant_id, **kwargs):
"""Updates a tenant.
- Available params: see http://developer.openstack.org/
- api-ref/identity/v2-admin/index.html#
- update-tenant
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/identity/v2-admin/index.html#update-tenant
"""
if 'id' not in kwargs:
kwargs['id'] = tenant_id
@@ -89,9 +90,9 @@
def list_tenant_users(self, tenant_id, **params):
"""List users for a Tenant.
- Available params: see http://developer.openstack.org/
- api-ref/identity/v2-admin/index.html#
- list-users-on-a-tenant
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/identity/v2-admin/index.html#list-users-on-a-tenant
"""
url = '/tenants/%s/users' % tenant_id
if params:
diff --git a/tempest/lib/services/identity/v2/users_client.py b/tempest/lib/services/identity/v2/users_client.py
index 2a266d9..f20fdc4 100644
--- a/tempest/lib/services/identity/v2/users_client.py
+++ b/tempest/lib/services/identity/v2/users_client.py
@@ -22,9 +22,9 @@
def create_user(self, **kwargs):
"""Create a user.
- Available params: see http://developer.openstack.org/
- api-ref/identity/v2-admin/index.html#
- create-user-admin-endpoint
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/identity/v2-admin/index.html#create-user-admin-endpoint
"""
post_body = json.dumps({'user': kwargs})
resp, body = self.post('users', post_body)
@@ -35,9 +35,9 @@
def update_user(self, user_id, **kwargs):
"""Updates a user.
- Available params: see http://developer.openstack.org/
- api-ref/identity/v2-admin/index.html#
- update-user-admin-endpoint
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/identity/v2-admin/index.html#update-user-admin-endpoint
"""
put_body = json.dumps({'user': kwargs})
resp, body = self.put('users/%s' % user_id, put_body)
@@ -48,8 +48,9 @@
def show_user(self, user_id):
"""GET a user.
- Available params: see http://developer.openstack.org/
- api-ref-identity-admin-v2.html#admin-showUser
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref-identity-admin-v2.html#admin-showUser
"""
resp, body = self.get("users/%s" % user_id)
self.expected_success(200, resp.status)
@@ -59,8 +60,9 @@
def delete_user(self, user_id):
"""Delete a user.
- Available params: see http://developer.openstack.org/
- api-ref-identity-admin-v2.html#admin-deleteUser
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref-identity-admin-v2.html#admin-deleteUser
"""
resp, body = self.delete("users/%s" % user_id)
self.expected_success(204, resp.status)
@@ -69,9 +71,9 @@
def list_users(self, **params):
"""Get the list of users.
- Available params: see http://developer.openstack.org/
- api-ref/identity/v2-admin/index.html#
- list-users-admin-endpoint
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/identity/v2-admin/index.html#list-users-admin-endpoint
"""
url = "users"
if params:
@@ -84,8 +86,9 @@
def update_user_enabled(self, user_id, **kwargs):
"""Enables or disables a user.
- Available params: see http://developer.openstack.org/
- api-ref-identity-v2-ext.html#enableUser
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref-identity-v2-ext.html#enableUser
"""
# NOTE: The URL (users/<id>/enabled) is different from the api-site
# one (users/<id>/OS-KSADM/enabled) , but they are the same API
diff --git a/tempest/services/identity/v3/json/credentials_client.py b/tempest/lib/services/identity/v3/credentials_client.py
similarity index 71%
rename from tempest/services/identity/v3/json/credentials_client.py
rename to tempest/lib/services/identity/v3/credentials_client.py
index 55eeee4..6e5fd31 100644
--- a/tempest/services/identity/v3/json/credentials_client.py
+++ b/tempest/lib/services/identity/v3/credentials_client.py
@@ -14,7 +14,7 @@
# under the License.
"""
-http://developer.openstack.org/api-ref-identity-v3.html#credentials
+http://developer.openstack.org/api-ref/identity/v3/index.html#credentials
"""
from oslo_serialization import jsonutils as json
@@ -29,46 +29,47 @@
def create_credential(self, **kwargs):
"""Creates a credential.
- Available params: see http://developer.openstack.org/
- api-ref-identity-v3.html#create-credential
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/identity/v3/index.html#create-credential
"""
post_body = json.dumps({'credential': kwargs})
resp, body = self.post('credentials', post_body)
self.expected_success(201, resp.status)
body = json.loads(body)
- body['credential']['blob'] = json.loads(body['credential']['blob'])
return rest_client.ResponseBody(resp, body)
def update_credential(self, credential_id, **kwargs):
"""Updates a credential.
- Available params: see http://developer.openstack.org/
- api-ref-identity-v3.html#update-credential
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/identity/v3/index.html#update-credential
"""
post_body = json.dumps({'credential': kwargs})
resp, body = self.patch('credentials/%s' % credential_id, post_body)
self.expected_success(200, resp.status)
body = json.loads(body)
- body['credential']['blob'] = json.loads(body['credential']['blob'])
return rest_client.ResponseBody(resp, body)
def show_credential(self, credential_id):
"""To GET Details of a credential.
- For API details, see http://developer.openstack.org/
- api-ref-identity-v3.html#show-credential-details
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/identity/v3/index.html#show-credential-details
"""
resp, body = self.get('credentials/%s' % credential_id)
self.expected_success(200, resp.status)
body = json.loads(body)
- body['credential']['blob'] = json.loads(body['credential']['blob'])
return rest_client.ResponseBody(resp, body)
def list_credentials(self, **params):
"""Lists out all the available credentials.
- Available params: see http://developer.openstack.org/
- api-ref/identity/v3/#list-credentials
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/identity/v3/#list-credentials
"""
url = 'credentials'
if params:
@@ -81,8 +82,9 @@
def delete_credential(self, credential_id):
"""Deletes a credential.
- For API details, see http://developer.openstack.org/
- api-ref/identity/v3/#delete-credential
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/identity/v3/#delete-credential
"""
resp, body = self.delete('credentials/%s' % credential_id)
self.expected_success(204, resp.status)
diff --git a/tempest/lib/services/identity/v3/endpoints_client.py b/tempest/lib/services/identity/v3/endpoints_client.py
index db30508..c4c0d8d 100644
--- a/tempest/lib/services/identity/v3/endpoints_client.py
+++ b/tempest/lib/services/identity/v3/endpoints_client.py
@@ -35,8 +35,9 @@
def create_endpoint(self, **kwargs):
"""Create endpoint.
- Available params: see http://developer.openstack.org/
- api-ref-identity-v3.html#createEndpoint
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/identity/v3/index.html#create-endpoint
"""
post_body = json.dumps({'endpoint': kwargs})
resp, body = self.post('endpoints', post_body)
@@ -47,8 +48,9 @@
def update_endpoint(self, endpoint_id, **kwargs):
"""Updates an endpoint with given parameters.
- Available params: see http://developer.openstack.org/
- api-ref-identity-v3.html#updateEndpoint
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/identity/v3/index.html#update-endpoint
"""
post_body = json.dumps({'endpoint': kwargs})
resp, body = self.patch('endpoints/%s' % endpoint_id, post_body)
diff --git a/tempest/lib/services/identity/v3/groups_client.py b/tempest/lib/services/identity/v3/groups_client.py
index 3674496..5e68939 100644
--- a/tempest/lib/services/identity/v3/groups_client.py
+++ b/tempest/lib/services/identity/v3/groups_client.py
@@ -29,8 +29,9 @@
def create_group(self, **kwargs):
"""Creates a group.
- Available params: see http://developer.openstack.org/
- api-ref-identity-v3.html#createGroup
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/identity/v3/index.html#create-group
"""
post_body = json.dumps({'group': kwargs})
resp, body = self.post('groups', post_body)
@@ -48,8 +49,9 @@
def list_groups(self, **params):
"""Lists the groups.
- Available params: see http://developer.openstack.org/
- api-ref/identity/v3/#list-groups
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/identity/v3/#list-groups
"""
url = 'groups'
if params:
@@ -62,8 +64,9 @@
def update_group(self, group_id, **kwargs):
"""Updates a group.
- Available params: see http://developer.openstack.org/
- api-ref-identity-v3.html#updateGroup
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/identity/v3/index.html#update-group
"""
post_body = json.dumps({'group': kwargs})
resp, body = self.patch('groups/%s' % group_id, post_body)
@@ -87,8 +90,9 @@
def list_group_users(self, group_id, **params):
"""List users in group.
- Available params: see http://developer.openstack.org/
- api-ref/identity/v3/#list-users-in-group
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/identity/v3/#list-users-in-group
"""
url = 'groups/%s/users' % group_id
if params:
diff --git a/tempest/lib/services/identity/v3/inherited_roles_client.py b/tempest/lib/services/identity/v3/inherited_roles_client.py
new file mode 100644
index 0000000..691c7fd
--- /dev/null
+++ b/tempest/lib/services/identity/v3/inherited_roles_client.py
@@ -0,0 +1,151 @@
+# Copyright 2016 Red Hat, Inc.
+#
+# 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 oslo_serialization import jsonutils as json
+
+from tempest.lib.common import rest_client
+
+
+class InheritedRolesClient(rest_client.RestClient):
+ api_version = "v3"
+
+ def create_inherited_role_on_domains_user(
+ self, domain_id, user_id, role_id):
+ """Assigns a role to a user on projects owned by a domain."""
+ resp, body = self.put(
+ "OS-INHERIT/domains/%s/users/%s/roles/%s/inherited_to_projects"
+ % (domain_id, user_id, role_id), None)
+ self.expected_success(204, resp.status)
+ return rest_client.ResponseBody(resp, body)
+
+ def delete_inherited_role_from_user_on_domain(
+ self, domain_id, user_id, role_id):
+ """Revokes an inherited project role from a user on a domain."""
+ resp, body = self.delete(
+ "OS-INHERIT/domains/%s/users/%s/roles/%s/inherited_to_projects"
+ % (domain_id, user_id, role_id))
+ self.expected_success(204, resp.status)
+ return rest_client.ResponseBody(resp, body)
+
+ def list_inherited_project_role_for_user_on_domain(
+ self, domain_id, user_id):
+ """Lists the inherited project roles on a domain for a user."""
+ resp, body = self.get(
+ "OS-INHERIT/domains/%s/users/%s/roles/inherited_to_projects"
+ % (domain_id, user_id))
+ self.expected_success(200, resp.status)
+ body = json.loads(body)
+ return rest_client.ResponseBody(resp, body)
+
+ def check_user_inherited_project_role_on_domain(
+ self, domain_id, user_id, role_id):
+ """Checks whether a user has an inherited project role on a domain."""
+ resp, body = self.head(
+ "OS-INHERIT/domains/%s/users/%s/roles/%s/inherited_to_projects"
+ % (domain_id, user_id, role_id))
+ self.expected_success(204, resp.status)
+ return rest_client.ResponseBody(resp)
+
+ def create_inherited_role_on_domains_group(
+ self, domain_id, group_id, role_id):
+ """Assigns a role to a group on projects owned by a domain."""
+ resp, body = self.put(
+ "OS-INHERIT/domains/%s/groups/%s/roles/%s/inherited_to_projects"
+ % (domain_id, group_id, role_id), None)
+ self.expected_success(204, resp.status)
+ return rest_client.ResponseBody(resp, body)
+
+ def delete_inherited_role_from_group_on_domain(
+ self, domain_id, group_id, role_id):
+ """Revokes an inherited project role from a group on a domain."""
+ resp, body = self.delete(
+ "OS-INHERIT/domains/%s/groups/%s/roles/%s/inherited_to_projects"
+ % (domain_id, group_id, role_id))
+ self.expected_success(204, resp.status)
+ return rest_client.ResponseBody(resp, body)
+
+ def list_inherited_project_role_for_group_on_domain(
+ self, domain_id, group_id):
+ """Lists the inherited project roles on a domain for a group."""
+ resp, body = self.get(
+ "OS-INHERIT/domains/%s/groups/%s/roles/inherited_to_projects"
+ % (domain_id, group_id))
+ self.expected_success(200, resp.status)
+ body = json.loads(body)
+ return rest_client.ResponseBody(resp, body)
+
+ def check_group_inherited_project_role_on_domain(
+ self, domain_id, group_id, role_id):
+ """Checks whether a group has an inherited project role on a domain."""
+ resp, body = self.head(
+ "OS-INHERIT/domains/%s/groups/%s/roles/%s/inherited_to_projects"
+ % (domain_id, group_id, role_id))
+ self.expected_success(204, resp.status)
+ return rest_client.ResponseBody(resp)
+
+ def create_inherited_role_on_projects_user(
+ self, project_id, user_id, role_id):
+ """Assigns a role to a user on projects in a subtree."""
+ resp, body = self.put(
+ "OS-INHERIT/projects/%s/users/%s/roles/%s/inherited_to_projects"
+ % (project_id, user_id, role_id), None)
+ self.expected_success(204, resp.status)
+ return rest_client.ResponseBody(resp, body)
+
+ def delete_inherited_role_from_user_on_project(
+ self, project_id, user_id, role_id):
+ """Revokes an inherited role from a user on a project."""
+ resp, body = self.delete(
+ "OS-INHERIT/projects/%s/users/%s/roles/%s/inherited_to_projects"
+ % (project_id, user_id, role_id))
+ self.expected_success(204, resp.status)
+ return rest_client.ResponseBody(resp, body)
+
+ def check_user_has_flag_on_inherited_to_project(
+ self, project_id, user_id, role_id):
+ """Checks whether a user has a role assignment"""
+ """with the inherited_to_projects flag on a project."""
+ resp, body = self.head(
+ "OS-INHERIT/projects/%s/users/%s/roles/%s/inherited_to_projects"
+ % (project_id, user_id, role_id))
+ self.expected_success(204, resp.status)
+ return rest_client.ResponseBody(resp)
+
+ def create_inherited_role_on_projects_group(
+ self, project_id, group_id, role_id):
+ """Assigns a role to a group on projects in a subtree."""
+ resp, body = self.put(
+ "OS-INHERIT/projects/%s/groups/%s/roles/%s/inherited_to_projects"
+ % (project_id, group_id, role_id), None)
+ self.expected_success(204, resp.status)
+ return rest_client.ResponseBody(resp, body)
+
+ def delete_inherited_role_from_group_on_project(
+ self, project_id, group_id, role_id):
+ """Revokes an inherited role from a group on a project."""
+ resp, body = self.delete(
+ "OS-INHERIT/projects/%s/groups/%s/roles/%s/inherited_to_projects"
+ % (project_id, group_id, role_id))
+ self.expected_success(204, resp.status)
+ return rest_client.ResponseBody(resp, body)
+
+ def check_group_has_flag_on_inherited_to_project(
+ self, project_id, group_id, role_id):
+ """Checks whether a group has a role assignment"""
+ """with the inherited_to_projects flag on a project."""
+ resp, body = self.head(
+ "OS-INHERIT/projects/%s/groups/%s/roles/%s/inherited_to_projects"
+ % (project_id, group_id, role_id))
+ self.expected_success(204, resp.status)
+ return rest_client.ResponseBody(resp)
diff --git a/tempest/lib/services/identity/v3/policies_client.py b/tempest/lib/services/identity/v3/policies_client.py
index f28db9a..0282745 100644
--- a/tempest/lib/services/identity/v3/policies_client.py
+++ b/tempest/lib/services/identity/v3/policies_client.py
@@ -28,8 +28,9 @@
def create_policy(self, **kwargs):
"""Creates a Policy.
- Available params: see http://developer.openstack.org/
- api-ref-identity-v3.html#createPolicy
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/identity/v3/index.html#create-policy
"""
post_body = json.dumps({'policy': kwargs})
resp, body = self.post('policies', post_body)
@@ -55,8 +56,9 @@
def update_policy(self, policy_id, **kwargs):
"""Updates a policy.
- Available params: see http://developer.openstack.org/
- api-ref-identity-v3.html#updatePolicy
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/identity/v3/index.html#update-policy
"""
post_body = json.dumps({'policy': kwargs})
url = 'policies/%s' % policy_id
diff --git a/tempest/lib/services/identity/v3/projects_client.py b/tempest/lib/services/identity/v3/projects_client.py
index ce2f38d..20787da 100644
--- a/tempest/lib/services/identity/v3/projects_client.py
+++ b/tempest/lib/services/identity/v3/projects_client.py
@@ -25,8 +25,9 @@
def create_project(self, name, **kwargs):
"""Create a Project.
- Available params: see http://developer.openstack.org/
- api-ref-identity-v3.html#createProject
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/identity/v3/index.html#create-project
"""
# Include the project name to the kwargs parameters
@@ -49,8 +50,9 @@
def update_project(self, project_id, **kwargs):
"""Update a Project.
- Available params: see http://developer.openstack.org/
- api-ref-identity-v3.html#updateProject
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/identity/v3/index.html#update-project
"""
post_body = json.dumps({'project': kwargs})
diff --git a/tempest/lib/services/identity/v3/regions_client.py b/tempest/lib/services/identity/v3/regions_client.py
index 90dd9d7..33c754a 100644
--- a/tempest/lib/services/identity/v3/regions_client.py
+++ b/tempest/lib/services/identity/v3/regions_client.py
@@ -29,11 +29,9 @@
def create_region(self, region_id=None, **kwargs):
"""Create region.
- Available params: see http://developer.openstack.org/
- api-ref-identity-v3.html#createRegion
-
- see http://developer.openstack.org/
- api-ref-identity-v3.html#createRegionWithID
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/identity/v3/index.html#create-region
"""
if region_id is not None:
method = self.put
@@ -50,8 +48,9 @@
def update_region(self, region_id, **kwargs):
"""Updates a region.
- Available params: see http://developer.openstack.org/
- api-ref-identity-v3.html#updateRegion
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/identity/v3/index.html#update-region
"""
post_body = json.dumps({'region': kwargs})
resp, body = self.patch('regions/%s' % region_id, post_body)
diff --git a/tempest/lib/services/identity/v3/roles_client.py b/tempest/lib/services/identity/v3/roles_client.py
new file mode 100644
index 0000000..f1339dd
--- /dev/null
+++ b/tempest/lib/services/identity/v3/roles_client.py
@@ -0,0 +1,192 @@
+# Copyright 2016 Red Hat, Inc.
+#
+# 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 oslo_serialization import jsonutils as json
+from six.moves.urllib import parse as urllib
+
+from tempest.lib.common import rest_client
+
+
+class RolesClient(rest_client.RestClient):
+ api_version = "v3"
+
+ def create_role(self, **kwargs):
+ """Create a Role.
+
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/identity/v3/index.html#create-role
+ """
+ post_body = json.dumps({'role': kwargs})
+ resp, body = self.post('roles', post_body)
+ self.expected_success(201, resp.status)
+ body = json.loads(body)
+ return rest_client.ResponseBody(resp, body)
+
+ def show_role(self, role_id):
+ """GET a Role."""
+ resp, body = self.get('roles/%s' % role_id)
+ self.expected_success(200, resp.status)
+ body = json.loads(body)
+ return rest_client.ResponseBody(resp, body)
+
+ def list_roles(self, **params):
+ """Get the list of Roles."""
+
+ url = 'roles'
+ if params:
+ url += '?%s' % urllib.urlencode(params)
+ resp, body = self.get(url)
+ self.expected_success(200, resp.status)
+ body = json.loads(body)
+ return rest_client.ResponseBody(resp, body)
+
+ def update_role(self, role_id, **kwargs):
+ """Update a Role.
+
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/identity/v3/index.html#update-role
+ """
+ post_body = json.dumps({'role': kwargs})
+ resp, body = self.patch('roles/%s' % role_id, post_body)
+ self.expected_success(200, resp.status)
+ body = json.loads(body)
+ return rest_client.ResponseBody(resp, body)
+
+ def delete_role(self, role_id):
+ """Delete a role."""
+ resp, body = self.delete('roles/%s' % role_id)
+ self.expected_success(204, resp.status)
+ return rest_client.ResponseBody(resp, body)
+
+ def create_user_role_on_project(self, project_id, user_id, role_id):
+ """Add roles to a user on a project."""
+ resp, body = self.put('projects/%s/users/%s/roles/%s' %
+ (project_id, user_id, role_id), None)
+ self.expected_success(204, resp.status)
+ return rest_client.ResponseBody(resp, body)
+
+ def create_user_role_on_domain(self, domain_id, user_id, role_id):
+ """Add roles to a user on a domain."""
+ resp, body = self.put('domains/%s/users/%s/roles/%s' %
+ (domain_id, user_id, role_id), None)
+ self.expected_success(204, resp.status)
+ return rest_client.ResponseBody(resp, body)
+
+ def list_user_roles_on_project(self, project_id, user_id):
+ """list roles of a user on a project."""
+ resp, body = self.get('projects/%s/users/%s/roles' %
+ (project_id, user_id))
+ self.expected_success(200, resp.status)
+ body = json.loads(body)
+ return rest_client.ResponseBody(resp, body)
+
+ def list_user_roles_on_domain(self, domain_id, user_id):
+ """list roles of a user on a domain."""
+ resp, body = self.get('domains/%s/users/%s/roles' %
+ (domain_id, user_id))
+ self.expected_success(200, resp.status)
+ body = json.loads(body)
+ return rest_client.ResponseBody(resp, body)
+
+ def delete_role_from_user_on_project(self, project_id, user_id, role_id):
+ """Delete role of a user on a project."""
+ resp, body = self.delete('projects/%s/users/%s/roles/%s' %
+ (project_id, user_id, role_id))
+ self.expected_success(204, resp.status)
+ return rest_client.ResponseBody(resp, body)
+
+ def delete_role_from_user_on_domain(self, domain_id, user_id, role_id):
+ """Delete role of a user on a domain."""
+ resp, body = self.delete('domains/%s/users/%s/roles/%s' %
+ (domain_id, user_id, role_id))
+ self.expected_success(204, resp.status)
+ return rest_client.ResponseBody(resp, body)
+
+ def check_user_role_existence_on_project(self, project_id,
+ user_id, role_id):
+ """Check role of a user on a project."""
+ resp, body = self.head('projects/%s/users/%s/roles/%s' %
+ (project_id, user_id, role_id))
+ self.expected_success(204, resp.status)
+ return rest_client.ResponseBody(resp)
+
+ def check_user_role_existence_on_domain(self, domain_id,
+ user_id, role_id):
+ """Check role of a user on a domain."""
+ resp, body = self.head('domains/%s/users/%s/roles/%s' %
+ (domain_id, user_id, role_id))
+ self.expected_success(204, resp.status)
+ return rest_client.ResponseBody(resp)
+
+ def create_group_role_on_project(self, project_id, group_id, role_id):
+ """Add roles to a group on a project."""
+ resp, body = self.put('projects/%s/groups/%s/roles/%s' %
+ (project_id, group_id, role_id), None)
+ self.expected_success(204, resp.status)
+ return rest_client.ResponseBody(resp, body)
+
+ def create_group_role_on_domain(self, domain_id, group_id, role_id):
+ """Add roles to a group on a domain."""
+ resp, body = self.put('domains/%s/groups/%s/roles/%s' %
+ (domain_id, group_id, role_id), None)
+ self.expected_success(204, resp.status)
+ return rest_client.ResponseBody(resp, body)
+
+ def list_group_roles_on_project(self, project_id, group_id):
+ """list roles of a group on a project."""
+ resp, body = self.get('projects/%s/groups/%s/roles' %
+ (project_id, group_id))
+ self.expected_success(200, resp.status)
+ body = json.loads(body)
+ return rest_client.ResponseBody(resp, body)
+
+ def list_group_roles_on_domain(self, domain_id, group_id):
+ """list roles of a group on a domain."""
+ resp, body = self.get('domains/%s/groups/%s/roles' %
+ (domain_id, group_id))
+ self.expected_success(200, resp.status)
+ body = json.loads(body)
+ return rest_client.ResponseBody(resp, body)
+
+ def delete_role_from_group_on_project(self, project_id, group_id, role_id):
+ """Delete role of a group on a project."""
+ resp, body = self.delete('projects/%s/groups/%s/roles/%s' %
+ (project_id, group_id, role_id))
+ self.expected_success(204, resp.status)
+ return rest_client.ResponseBody(resp, body)
+
+ def delete_role_from_group_on_domain(self, domain_id, group_id, role_id):
+ """Delete role of a group on a domain."""
+ resp, body = self.delete('domains/%s/groups/%s/roles/%s' %
+ (domain_id, group_id, role_id))
+ self.expected_success(204, resp.status)
+ return rest_client.ResponseBody(resp, body)
+
+ def check_role_from_group_on_project_existence(self, project_id,
+ group_id, role_id):
+ """Check role of a group on a project."""
+ resp, body = self.head('projects/%s/groups/%s/roles/%s' %
+ (project_id, group_id, role_id))
+ self.expected_success(204, resp.status)
+ return rest_client.ResponseBody(resp)
+
+ def check_role_from_group_on_domain_existence(self, domain_id,
+ group_id, role_id):
+ """Check role of a group on a domain."""
+ resp, body = self.head('domains/%s/groups/%s/roles/%s' %
+ (domain_id, group_id, role_id))
+ self.expected_success(204, resp.status)
+ return rest_client.ResponseBody(resp)
diff --git a/tempest/lib/services/identity/v3/services_client.py b/tempest/lib/services/identity/v3/services_client.py
index 95caf7d..14c81cc 100644
--- a/tempest/lib/services/identity/v3/services_client.py
+++ b/tempest/lib/services/identity/v3/services_client.py
@@ -29,8 +29,9 @@
def update_service(self, service_id, **kwargs):
"""Updates a service.
- Available params: see http://developer.openstack.org/
- api-ref-identity-v3.html#updateService
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/identity/v3/index.html#update-service
"""
patch_body = json.dumps({'service': kwargs})
resp, body = self.patch('services/%s' % service_id, patch_body)
@@ -49,8 +50,9 @@
def create_service(self, **kwargs):
"""Creates a service.
- Available params: see http://developer.openstack.org/
- api-ref-identity-v3.html#createService
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/identity/v3/index.html#create-service
"""
body = json.dumps({'service': kwargs})
resp, body = self.post("services", body)
@@ -67,8 +69,9 @@
def list_services(self, **params):
"""List services.
- Available params: see http://developer.openstack.org/
- api-ref/identity/v3/#list-services
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/identity/v3/#list-services
"""
url = 'services'
if params:
diff --git a/tempest/services/identity/v3/json/trusts_client.py b/tempest/lib/services/identity/v3/trusts_client.py
similarity index 80%
rename from tempest/services/identity/v3/json/trusts_client.py
rename to tempest/lib/services/identity/v3/trusts_client.py
index dedee05..d113905 100644
--- a/tempest/services/identity/v3/json/trusts_client.py
+++ b/tempest/lib/services/identity/v3/trusts_client.py
@@ -13,6 +13,7 @@
# limitations under the License.
from oslo_serialization import jsonutils as json
+from six.moves.urllib import parse as urllib
from tempest.lib.common import rest_client
@@ -23,8 +24,9 @@
def create_trust(self, **kwargs):
"""Creates a trust.
- Available params: see http://developer.openstack.org/
- api-ref-identity-v3-ext.html#createTrust
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/identity/v3-ext/index.html#create-trust
"""
post_body = json.dumps({'trust': kwargs})
resp, body = self.post('OS-TRUST/trusts', post_body)
@@ -38,16 +40,17 @@
self.expected_success(204, resp.status)
return rest_client.ResponseBody(resp, body)
- def list_trusts(self, trustor_user_id=None, trustee_user_id=None):
- """GET trusts."""
- if trustor_user_id:
- resp, body = self.get("OS-TRUST/trusts?trustor_user_id=%s"
- % trustor_user_id)
- elif trustee_user_id:
- resp, body = self.get("OS-TRUST/trusts?trustee_user_id=%s"
- % trustee_user_id)
- else:
- resp, body = self.get("OS-TRUST/trusts")
+ def list_trusts(self, **params):
+ """Returns trusts
+
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/identity/v3-ext/index.html#list-trusts
+ """
+ url = "OS-TRUST/trusts/"
+ if params:
+ url += '?%s' % urllib.urlencode(params)
+ resp, body = self.get(url)
self.expected_success(200, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
diff --git a/tempest/lib/services/identity/v3/users_client.py b/tempest/lib/services/identity/v3/users_client.py
index 0dcdacd..e99a971 100644
--- a/tempest/lib/services/identity/v3/users_client.py
+++ b/tempest/lib/services/identity/v3/users_client.py
@@ -24,8 +24,9 @@
def create_user(self, **kwargs):
"""Creates a user.
- Available params: see http://developer.openstack.org/
- api-ref/identity/v3/#create-user
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/identity/v3/#create-user
"""
post_body = json.dumps({'user': kwargs})
resp, body = self.post('users', post_body)
@@ -36,8 +37,9 @@
def update_user(self, user_id, **kwargs):
"""Updates a user.
- Available params: see http://developer.openstack.org/
- api-ref-identity-v3.html#updateUser
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/identity/v3/#update-user
"""
if 'id' not in kwargs:
kwargs['id'] = user_id
@@ -50,8 +52,9 @@
def update_user_password(self, user_id, **kwargs):
"""Update a user password
- Available params: see http://developer.openstack.org/
- api-ref-identity-v3.html#changeUserPassword
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/identity/v3/index.html#change-password-for-user
"""
update_user = json.dumps({'user': kwargs})
resp, _ = self.post('users/%s/password' % user_id, update_user)
@@ -61,8 +64,9 @@
def list_user_projects(self, user_id, **params):
"""Lists the projects on which a user has roles assigned.
- Available params: see http://developer.openstack.org/
- api-ref/identity/v3/#list-projects-for-user
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/identity/v3/#list-projects-for-user
"""
url = 'users/%s/projects' % user_id
if params:
@@ -75,8 +79,9 @@
def list_users(self, **params):
"""Get the list of users.
- Available params: see http://developer.openstack.org/
- api-ref/identity/v3/#list-users
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/identity/v3/#list-users
"""
url = 'users'
if params:
@@ -102,8 +107,9 @@
def list_user_groups(self, user_id, **params):
"""Lists groups which a user belongs to.
- Available params: see http://developer.openstack.org/
- api-ref/identity/v3/#list-groups-to-which-a-user-belongs
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/identity/v3/#list-groups-to-which-a-user-belongs
"""
url = 'users/%s/groups' % user_id
if params:
diff --git a/tempest/lib/services/image/v1/image_members_client.py b/tempest/lib/services/image/v1/image_members_client.py
index e7fa0c9..2318087 100644
--- a/tempest/lib/services/image/v1/image_members_client.py
+++ b/tempest/lib/services/image/v1/image_members_client.py
@@ -29,8 +29,9 @@
def list_shared_images(self, tenant_id):
"""List image memberships for the given tenant.
- Available params: see http://developer.openstack.org/
- api-ref-image-v1.html#listSharedImages-v1
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/image/v1/#list-shared-images
"""
url = 'shared-images/%s' % tenant_id
@@ -42,8 +43,9 @@
def create_image_member(self, image_id, member_id, **kwargs):
"""Add a member to an image.
- Available params: see http://developer.openstack.org/
- api-ref-image-v1.html#addMember-v1
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/image/v1/#add-member-to-image
"""
url = 'images/%s/members/%s' % (image_id, member_id)
body = json.dumps({'member': kwargs})
@@ -54,8 +56,9 @@
def delete_image_member(self, image_id, member_id):
"""Removes a membership from the image.
- Available params: see http://developer.openstack.org/
- api-ref-image-v1.html#removeMember-v1
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/image/v1/#remove-member
"""
url = 'images/%s/members/%s' % (image_id, member_id)
resp, __ = self.delete(url)
diff --git a/tempest/lib/services/image/v1/images_client.py b/tempest/lib/services/image/v1/images_client.py
index 0db98f8..9737be3 100644
--- a/tempest/lib/services/image/v1/images_client.py
+++ b/tempest/lib/services/image/v1/images_client.py
@@ -61,8 +61,9 @@
def create_image(self, data=None, headers=None):
"""Create an image.
- Available params: http://developer.openstack.org/
- api-ref-image-v1.html#createImage-v1
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref-image-v1.html#createImage-v1
"""
if headers is None:
headers = {}
@@ -78,8 +79,9 @@
def update_image(self, image_id, data=None, headers=None):
"""Update an image.
- Available params: http://developer.openstack.org/
- api-ref-image-v1.html#updateImage-v1
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref-image-v1.html#updateImage-v1
"""
if headers is None:
headers = {}
@@ -102,8 +104,9 @@
def list_images(self, detail=False, **kwargs):
"""Return a list of all images filtered by input parameters.
- Available params: see http://developer.openstack.org/
- api-ref-image-v1.html#listImage-v1
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/image/v1/#list-images
Most parameters except the following are passed to the API without
any changes.
diff --git a/tempest/lib/services/image/v2/image_members_client.py b/tempest/lib/services/image/v2/image_members_client.py
index d0ab165..e5118a8 100644
--- a/tempest/lib/services/image/v2/image_members_client.py
+++ b/tempest/lib/services/image/v2/image_members_client.py
@@ -21,8 +21,9 @@
def list_image_members(self, image_id):
"""List image members.
- Available params: http://developer.openstack.org/
- api-ref-image-v2.html#listImageMembers-v2
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/image/v2/#list-image-members
"""
url = 'images/%s/members' % image_id
resp, body = self.get(url)
@@ -33,8 +34,9 @@
def create_image_member(self, image_id, **kwargs):
"""Create an image member.
- Available params: see http://developer.openstack.org/
- api-ref-image-v2.html#createImageMember-v2
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/image/v2/#create-image-member
"""
url = 'images/%s/members' % image_id
data = json.dumps(kwargs)
@@ -46,8 +48,9 @@
def update_image_member(self, image_id, member_id, **kwargs):
"""Update an image member.
- Available params: see http://developer.openstack.org/
- api-ref-image-v2.html#updateImageMember-v2
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/image/v2/#update-image-member
"""
url = 'images/%s/members/%s' % (image_id, member_id)
data = json.dumps(kwargs)
@@ -59,8 +62,9 @@
def show_image_member(self, image_id, member_id):
"""Show an image member.
- Available params: http://developer.openstack.org/
- api-ref-image-v2.html#showImageMember-v2
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/image/v2/#show-image-member-details
"""
url = 'images/%s/members/%s' % (image_id, member_id)
resp, body = self.get(url)
@@ -70,8 +74,9 @@
def delete_image_member(self, image_id, member_id):
"""Delete an image member.
- Available params: http://developer.openstack.org/
- api-ref-image-v2.html#deleteImageMember-v2
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/image/v2/#delete-image-member
"""
url = 'images/%s/members/%s' % (image_id, member_id)
resp, _ = self.delete(url)
diff --git a/tempest/lib/services/image/v2/images_client.py b/tempest/lib/services/image/v2/images_client.py
index 996ce94..bcdae44 100644
--- a/tempest/lib/services/image/v2/images_client.py
+++ b/tempest/lib/services/image/v2/images_client.py
@@ -30,8 +30,9 @@
def update_image(self, image_id, patch):
"""Update an image.
- Available params: see http://developer.openstack.org/
- api-ref-image-v2.html#updateImage-v2
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/image/v2/index.html#update-an-image
"""
data = json.dumps(patch)
headers = {"Content-Type": "application/openstack-images-v2.0"
@@ -44,8 +45,9 @@
def create_image(self, **kwargs):
"""Create an image.
- Available params: see http://developer.openstack.org/
- api-ref-image-v2.html#createImage-v2
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/image/v2/index.html#create-an-image
"""
data = json.dumps(kwargs)
resp, body = self.post('images', data)
@@ -56,9 +58,10 @@
def deactivate_image(self, image_id):
"""Deactivate image.
- Available params: see http://developer.openstack.org/
- api-ref-image-v2.html#deactivateImage-v2
- """
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/image/v2/#deactivate-image
+ """
url = 'images/%s/actions/deactivate' % image_id
resp, body = self.post(url, None)
self.expected_success(204, resp.status)
@@ -67,9 +70,10 @@
def reactivate_image(self, image_id):
"""Reactivate image.
- Available params: see http://developer.openstack.org/
- api-ref-image-v2.html#reactivateImage-v2
- """
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/image/v2/#reactivate-image
+ """
url = 'images/%s/actions/reactivate' % image_id
resp, body = self.post(url, None)
self.expected_success(204, resp.status)
@@ -78,8 +82,9 @@
def delete_image(self, image_id):
"""Delete image.
- Available params: see http://developer.openstack.org/
- api-ref-image-v2.html#deleteImage-v2
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/image/v2/#delete-an-image
"""
url = 'images/%s' % image_id
resp, _ = self.delete(url)
@@ -89,8 +94,9 @@
def list_images(self, params=None):
"""List images.
- Available params: see http://developer.openstack.org/
- api-ref-image-v2.html#listImages-v2
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/image/v2/#show-images
"""
url = 'images'
@@ -105,8 +111,9 @@
def show_image(self, image_id):
"""Show image details.
- Available params: http://developer.openstack.org/
- api-ref-image-v2.html#showImage-v2
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/image/v2/#show-image-details
"""
url = 'images/%s' % image_id
resp, body = self.get(url)
@@ -129,8 +136,9 @@
def store_image_file(self, image_id, data):
"""Upload binary image data.
- Available params: http://developer.openstack.org/
- api-ref-image-v2.html#storeImageFile-v2
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/image/v2/#upload-binary-image-data
"""
url = 'images/%s/file' % image_id
@@ -147,8 +155,9 @@
def show_image_file(self, image_id):
"""Download binary image data.
- Available params: http://developer.openstack.org/
- api-ref-image-v2.html#showImageFile-v2
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/image/v2/#download-binary-image-data
"""
url = 'images/%s/file' % image_id
resp, body = self.get(url)
@@ -158,8 +167,9 @@
def add_image_tag(self, image_id, tag):
"""Add an image tag.
- Available params: http://developer.openstack.org/
- api-ref-image-v2.html#addImageTag-v2
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/image/v2/#add-image-tag
"""
url = 'images/%s/tags/%s' % (image_id, tag)
resp, body = self.put(url, body=None)
@@ -169,8 +179,9 @@
def delete_image_tag(self, image_id, tag):
"""Delete an image tag.
- Available params: http://developer.openstack.org/
- api-ref-image-v2.html#deleteImageTag-v2
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/image/v2/#delete-image-tag
"""
url = 'images/%s/tags/%s' % (image_id, tag)
resp, _ = self.delete(url)
diff --git a/tempest/lib/services/image/v2/namespaces_client.py b/tempest/lib/services/image/v2/namespaces_client.py
index 5bd096d..c92ff3a 100644
--- a/tempest/lib/services/image/v2/namespaces_client.py
+++ b/tempest/lib/services/image/v2/namespaces_client.py
@@ -24,8 +24,9 @@
def create_namespace(self, **kwargs):
"""Create a namespace.
- Available params: see http://developer.openstack.org/
- api-ref-image-v2.html#createNamespace-v2
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#create-namespace
"""
data = json.dumps(kwargs)
resp, body = self.post('metadefs/namespaces', data)
@@ -34,6 +35,12 @@
return rest_client.ResponseBody(resp, body)
def show_namespace(self, namespace):
+ """Show namespace details.
+
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#get-namespace-details
+ """
url = 'metadefs/namespaces/%s' % namespace
resp, body = self.get(url)
self.expected_success(200, resp.status)
@@ -43,8 +50,9 @@
def update_namespace(self, namespace, **kwargs):
"""Update a namespace.
- Available params: see http://developer.openstack.org/
- api-ref-image-v2.html#updateNamespace-v2
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#update-namespace
"""
# NOTE: On Glance API, we need to pass namespace on both URI
# and a request body.
@@ -60,8 +68,9 @@
def delete_namespace(self, namespace):
"""Delete a namespace.
- Available params: http://developer.openstack.org/
- api-ref-image-v2.html#deleteNamespace-v2
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#delete-namespace
"""
url = 'metadefs/namespaces/%s' % namespace
resp, _ = self.delete(url)
diff --git a/tempest/lib/services/image/v2/resource_types_client.py b/tempest/lib/services/image/v2/resource_types_client.py
index 8f2a977..1b6889f 100644
--- a/tempest/lib/services/image/v2/resource_types_client.py
+++ b/tempest/lib/services/image/v2/resource_types_client.py
@@ -24,10 +24,10 @@
def list_resource_types(self):
"""Lists all resource types.
- Available params: see http://developer.openstack.org/
- api-ref/image/v2/metadefs-index.html?expanded=#
- list-resource-types
- """
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/image/v2/metadefs-index.html?expanded=#list-resource-types
+ """
url = 'metadefs/resource_types'
resp, body = self.get(url)
self.expected_success(200, resp.status)
@@ -37,10 +37,10 @@
def create_resource_type_association(self, namespace_id, **kwargs):
"""Creates a resource type association in given namespace.
- Available params: see http://developer.openstack.org/
- api-ref/image/v2/metadefs-index.html?expanded=#
- create-resource-type-association
- """
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/image/v2/metadefs-index.html?expanded=#create-resource-type-association
+ """
url = 'metadefs/namespaces/%s/resource_types' % namespace_id
data = json.dumps(kwargs)
resp, body = self.post(url, data)
@@ -51,10 +51,10 @@
def list_resource_type_association(self, namespace_id):
"""Lists resource type associations in given namespace.
- Available params: see http://developer.openstack.org/
- api-ref/image/v2/metadefs-index.html?expanded=#
- list-resource-type-associations
- """
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/image/v2/metadefs-index.html?expanded=#list-resource-type-associations
+ """
url = 'metadefs/namespaces/%s/resource_types' % namespace_id
resp, body = self.get(url)
self.expected_success(200, resp.status)
@@ -64,10 +64,10 @@
def delete_resource_type_association(self, namespace_id, resource_name):
"""Removes resource type association in given namespace.
- Available params: see http://developer.openstack.org/
- api-ref/image/v2/metadefs-index.html?expanded=#
- remove-resource-type-association
- """
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/image/v2/metadefs-index.html?expanded=#remove-resource-type-association
+ """
url = 'metadefs/namespaces/%s/resource_types/%s' % (namespace_id,
resource_name)
resp, _ = self.delete(url)
diff --git a/tempest/lib/services/network/floating_ips_client.py b/tempest/lib/services/network/floating_ips_client.py
index f6cc0ff..2bb18e0 100755
--- a/tempest/lib/services/network/floating_ips_client.py
+++ b/tempest/lib/services/network/floating_ips_client.py
@@ -21,8 +21,9 @@
If you specify port information, associates the floating IP with an
internal port.
- Available params: see http://developer.openstack.org/
- api-ref-networking-v2-ext.html#createFloatingIp
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#create-floating-ip
"""
uri = '/floatingips'
post_data = {'floatingip': kwargs}
@@ -31,8 +32,9 @@
def update_floatingip(self, floatingip_id, **kwargs):
"""Updates a floating IP and its association with an internal port.
- Available params: see http://developer.openstack.org/
- api-ref-networking-v2-ext.html#updateFloatingIp
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#update-floating-ip
"""
uri = '/floatingips/%s' % floatingip_id
post_data = {'floatingip': kwargs}
@@ -41,8 +43,9 @@
def show_floatingip(self, floatingip_id, **fields):
"""Shows details for a floating IP.
- Available params: see http://developer.openstack.org/
- api-ref-networking-v2-ext.html#showFloatingIp
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#show-floating-ip-details
"""
uri = '/floatingips/%s' % floatingip_id
return self.show_resource(uri, **fields)
@@ -54,8 +57,9 @@
def list_floatingips(self, **filters):
"""Lists floating IPs.
- Available params: see http://developer.openstack.org/
- api-ref-networking-v2-ext.html#listFloatingIps
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#list-floating-ips
"""
uri = '/floatingips'
return self.list_resources(uri, **filters)
diff --git a/tempest/lib/services/network/metering_labels_client.py b/tempest/lib/services/network/metering_labels_client.py
index 12a5834..411da1f 100755
--- a/tempest/lib/services/network/metering_labels_client.py
+++ b/tempest/lib/services/network/metering_labels_client.py
@@ -18,9 +18,9 @@
def create_metering_label(self, **kwargs):
"""Creates an L3 metering label.
- Available params: see http://developer.openstack.org/
- api-ref-networking-v2-ext.html#
- createMeteringLabel
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#create-metering-label
"""
uri = '/metering/metering-labels'
post_data = {'metering_label': kwargs}
@@ -29,8 +29,9 @@
def show_metering_label(self, metering_label_id, **fields):
"""Shows details for a metering label.
- Available params: see http://developer.openstack.org/
- api-ref-networking-v2-ext.html#showMeteringLabel
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#show-metering-label-details
"""
uri = '/metering/metering-labels/%s' % metering_label_id
return self.show_resource(uri, **fields)
@@ -38,9 +39,9 @@
def delete_metering_label(self, metering_label_id):
"""Deletes an L3 metering label.
- Available params: see http://developer.openstack.org/
- api-ref-networking-v2-ext.html#
- deleteMeteringLabel
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#delete-metering-label
"""
uri = '/metering/metering-labels/%s' % metering_label_id
return self.delete_resource(uri)
@@ -48,9 +49,9 @@
def list_metering_labels(self, **filters):
"""Lists all L3 metering labels that belong to the tenant.
- Available params: see http://developer.openstack.org/
- api-ref-networking-v2-ext.html#
- listMeteringLabels
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#list-metering-labels
"""
uri = '/metering/metering-labels'
return self.list_resources(uri, **filters)
diff --git a/tempest/lib/services/network/networks_client.py b/tempest/lib/services/network/networks_client.py
index 6b601ee..77d4823 100755
--- a/tempest/lib/services/network/networks_client.py
+++ b/tempest/lib/services/network/networks_client.py
@@ -18,8 +18,9 @@
def create_network(self, **kwargs):
"""Creates a network.
- Available params: see http://developer.openstack.org/
- api-ref/networking/v2/index.html#create-network
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#create-network
"""
uri = '/networks'
post_data = {'network': kwargs}
@@ -28,8 +29,9 @@
def update_network(self, network_id, **kwargs):
"""Updates a network.
- Available params: see http://developer.openstack.org/
- api-ref/networking/v2/index.html#update-network
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#update-network
"""
uri = '/networks/%s' % network_id
post_data = {'network': kwargs}
@@ -38,8 +40,9 @@
def show_network(self, network_id, **fields):
"""Shows details for a network.
- Available params: see http://developer.openstack.org/
- api-ref/networking/v2/index.html#show-network-details
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#show-network-details
"""
uri = '/networks/%s' % network_id
return self.show_resource(uri, **fields)
@@ -51,8 +54,9 @@
def list_networks(self, **filters):
"""Lists networks to which the tenant has access.
- Available params: see http://developer.openstack.org/
- api-ref/networking/v2/index.html#list-networks
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#list-networks
"""
uri = '/networks'
return self.list_resources(uri, **filters)
@@ -60,8 +64,9 @@
def create_bulk_networks(self, **kwargs):
"""Create multiple networks in a single request.
- Available params: see http://developer.openstack.org/
- api-ref/networking/v2/index.html#bulk-create-networks
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#bulk-create-networks
"""
uri = '/networks'
return self.create_resource(uri, kwargs)
diff --git a/tempest/lib/services/network/ports_client.py b/tempest/lib/services/network/ports_client.py
index 85f5a1d..93138b9 100755
--- a/tempest/lib/services/network/ports_client.py
+++ b/tempest/lib/services/network/ports_client.py
@@ -19,8 +19,9 @@
def create_port(self, **kwargs):
"""Creates a port on a network.
- Available params: see http://developer.openstack.org/
- api-ref/networking/v2/index.html#create-port
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#create-port
"""
uri = '/ports'
post_data = {'port': kwargs}
@@ -29,8 +30,9 @@
def update_port(self, port_id, **kwargs):
"""Updates a port.
- Available params: see http://developer.openstack.org/
- api-ref/networking/v2/index.html#update-port
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#update-port
"""
uri = '/ports/%s' % port_id
post_data = {'port': kwargs}
@@ -39,8 +41,9 @@
def show_port(self, port_id, **fields):
"""Shows details for a port.
- Available params: see http://developer.openstack.org/
- api-ref/networking/v2/index.html#show-port-details
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#show-port-details
"""
uri = '/ports/%s' % port_id
return self.show_resource(uri, **fields)
@@ -48,8 +51,9 @@
def delete_port(self, port_id):
"""Deletes a port.
- Available params: see http://developer.openstack.org/
- api-ref/networking/v2/index.html#delete-port
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#delete-port
"""
uri = '/ports/%s' % port_id
return self.delete_resource(uri)
@@ -57,8 +61,9 @@
def list_ports(self, **filters):
"""Lists ports to which the tenant has access.
- Available params: see http://developer.openstack.org/
- api-ref/networking/v2/index.html#list-ports
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#list-ports
"""
uri = '/ports'
return self.list_resources(uri, **filters)
@@ -66,8 +71,9 @@
def create_bulk_ports(self, **kwargs):
"""Create multiple ports in a single request.
- Available params: see http://developer.openstack.org/
- api-ref/networking/v2/index.html?expanded=#bulk-create-ports
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html?expanded=#bulk-create-ports
"""
uri = '/ports'
return self.create_resource(uri, kwargs)
diff --git a/tempest/lib/services/network/routers_client.py b/tempest/lib/services/network/routers_client.py
index 23e9c4e..19b7627 100755
--- a/tempest/lib/services/network/routers_client.py
+++ b/tempest/lib/services/network/routers_client.py
@@ -18,8 +18,9 @@
def create_router(self, **kwargs):
"""Create a router.
- Available params: see http://developer.openstack.org/
- api-ref-networking-v2-ext.html#createRouter
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#create-router
"""
post_body = {'router': kwargs}
uri = '/routers'
@@ -28,8 +29,9 @@
def update_router(self, router_id, **kwargs):
"""Updates a logical router.
- Available params: see http://developer.openstack.org/
- api-ref-networking-v2-ext.html#updateRouter
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#update-router
"""
uri = '/routers/%s' % router_id
update_body = {'router': kwargs}
@@ -38,8 +40,9 @@
def show_router(self, router_id, **fields):
"""Shows details for a router.
- Available params: see http://developer.openstack.org/
- api-ref-networking-v2-ext.html#showRouter
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#show-router-details
"""
uri = '/routers/%s' % router_id
return self.show_resource(uri, **fields)
@@ -51,8 +54,9 @@
def list_routers(self, **filters):
"""Lists logical routers.
- Available params: see http://developer.openstack.org/
- api-ref-networking-v2-ext.html#listRouters
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#list-routers
"""
uri = '/routers'
return self.list_resources(uri, **filters)
@@ -60,9 +64,9 @@
def add_router_interface(self, router_id, **kwargs):
"""Add router interface.
- Available params: see http://developer.openstack.org/
- api-ref-networking-v2-ext.html#
- addRouterInterface
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#add-interface-to-router
"""
uri = '/routers/%s/add_router_interface' % router_id
return self.update_resource(uri, kwargs)
@@ -70,9 +74,9 @@
def remove_router_interface(self, router_id, **kwargs):
"""Remove router interface.
- Available params: see http://developer.openstack.org/
- api-ref-networking-v2-ext.html#
- deleteRouterInterface
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#remove-interface-from-router
"""
uri = '/routers/%s/remove_router_interface' % router_id
return self.update_resource(uri, kwargs)
diff --git a/tempest/lib/services/network/security_group_rules_client.py b/tempest/lib/services/network/security_group_rules_client.py
index 6cd01e1..d2bc4a9 100755
--- a/tempest/lib/services/network/security_group_rules_client.py
+++ b/tempest/lib/services/network/security_group_rules_client.py
@@ -18,9 +18,9 @@
def create_security_group_rule(self, **kwargs):
"""Creates an OpenStack Networking security group rule.
- Available params: see http://developer.openstack.org/
- api-ref-networking-v2-ext.html#
- createSecGroupRule
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#create-security-group-rule
"""
uri = '/security-group-rules'
post_data = {'security_group_rule': kwargs}
@@ -29,8 +29,9 @@
def show_security_group_rule(self, security_group_rule_id, **fields):
"""Shows detailed information for a security group rule.
- Available params: see http://developer.openstack.org/
- api-ref-networking-v2-ext.html#showSecGroupRule
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#show-security-group-rule
"""
uri = '/security-group-rules/%s' % security_group_rule_id
return self.show_resource(uri, **fields)
@@ -42,8 +43,9 @@
def list_security_group_rules(self, **filters):
"""Lists a summary of all OpenStack Networking security group rules.
- Available params: see http://developer.openstack.org/
- api-ref-networking-v2-ext.html#listSecGroupRules
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#list-security-group-rules
"""
uri = '/security-group-rules'
return self.list_resources(uri, **filters)
diff --git a/tempest/lib/services/network/security_groups_client.py b/tempest/lib/services/network/security_groups_client.py
index 5c89a6f..1f30216 100755
--- a/tempest/lib/services/network/security_groups_client.py
+++ b/tempest/lib/services/network/security_groups_client.py
@@ -18,8 +18,9 @@
def create_security_group(self, **kwargs):
"""Creates an OpenStack Networking security group.
- Available params: see http://developer.openstack.org/
- api-ref-networking-v2-ext.html#createSecGroup
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#create-security-group
"""
uri = '/security-groups'
post_data = {'security_group': kwargs}
@@ -28,8 +29,9 @@
def update_security_group(self, security_group_id, **kwargs):
"""Updates a security group.
- Available params: see http://developer.openstack.org/
- api-ref-networking-v2-ext.html#updateSecGroup
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#update-security-group
"""
uri = '/security-groups/%s' % security_group_id
post_data = {'security_group': kwargs}
@@ -38,8 +40,9 @@
def show_security_group(self, security_group_id, **fields):
"""Shows details for a security group.
- Available params: see http://developer.openstack.org/
- api-ref-networking-v2-ext.html#showSecGroup
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#show-security-group
"""
uri = '/security-groups/%s' % security_group_id
return self.show_resource(uri, **fields)
@@ -47,8 +50,9 @@
def delete_security_group(self, security_group_id):
"""Deletes an OpenStack Networking security group.
- Available params: see http://developer.openstack.org/
- api-ref-networking-v2-ext.html#deleteSecGroup
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#delete-security-group
"""
uri = '/security-groups/%s' % security_group_id
return self.delete_resource(uri)
@@ -56,8 +60,9 @@
def list_security_groups(self, **filters):
"""Lists OpenStack Networking security groups.
- Available params: see http://developer.openstack.org/
- api-ref-networking-v2-ext.html#listSecGroups
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#list-security-groups
"""
uri = '/security-groups'
return self.list_resources(uri, **filters)
diff --git a/tempest/lib/services/network/subnetpools_client.py b/tempest/lib/services/network/subnetpools_client.py
index f0a66a0..7e77e30 100755
--- a/tempest/lib/services/network/subnetpools_client.py
+++ b/tempest/lib/services/network/subnetpools_client.py
@@ -20,8 +20,9 @@
def list_subnetpools(self, **filters):
"""Lists subnet pools to which the tenant has access.
- Available params: see http://developer.openstack.org/
- api-ref-networking-v2-ext.html#listSubnetPools
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#list-subnet-pools
"""
uri = '/subnetpools'
return self.list_resources(uri, **filters)
@@ -29,8 +30,9 @@
def create_subnetpool(self, **kwargs):
"""Creates a subnet pool.
- Available params: see http://developer.openstack.org/
- api-ref-networking-v2-ext.html#createSubnetPool
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#create-subnet-pool
"""
uri = '/subnetpools'
post_data = {'subnetpool': kwargs}
@@ -39,8 +41,9 @@
def show_subnetpool(self, subnetpool_id, **fields):
"""Shows information for a subnet pool.
- Available params: see http://developer.openstack.org/
- api-ref-networking-v2-ext.html#showSubnetPool
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#show-subnet-pool
"""
uri = '/subnetpools/%s' % subnetpool_id
return self.show_resource(uri, **fields)
@@ -48,8 +51,9 @@
def update_subnetpool(self, subnetpool_id, **kwargs):
"""Updates a subnet pool.
- Available params: see http://developer.openstack.org/
- api-ref-networking-v2-ext.html#updateSubnetPool
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#update-subnet-pool
"""
uri = '/subnetpools/%s' % subnetpool_id
post_data = {'subnetpool': kwargs}
diff --git a/tempest/lib/services/network/subnets_client.py b/tempest/lib/services/network/subnets_client.py
index 203b360..b843f84 100755
--- a/tempest/lib/services/network/subnets_client.py
+++ b/tempest/lib/services/network/subnets_client.py
@@ -18,8 +18,9 @@
def create_subnet(self, **kwargs):
"""Creates a subnet on a network.
- Available params: see http://developer.openstack.org/
- api-ref/networking/v2/index.html#create-subnet
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#create-subnet
"""
uri = '/subnets'
post_data = {'subnet': kwargs}
@@ -28,8 +29,9 @@
def update_subnet(self, subnet_id, **kwargs):
"""Updates a subnet.
- Available params: see http://developer.openstack.org/
- api-ref/networking/v2/index.html#update-subnet
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#update-subnet
"""
uri = '/subnets/%s' % subnet_id
post_data = {'subnet': kwargs}
@@ -38,8 +40,9 @@
def show_subnet(self, subnet_id, **fields):
"""Shows details for a subnet.
- Available params: see http://developer.openstack.org/
- api-ref/networking/v2/index.html#show-subnet-details
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#show-subnet-details
"""
uri = '/subnets/%s' % subnet_id
return self.show_resource(uri, **fields)
@@ -51,8 +54,9 @@
def list_subnets(self, **filters):
"""Lists subnets to which the tenant has access.
- Available params: see http://developer.openstack.org/
- api-ref/networking/v2/index.html#list-subnets
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#list-subnets
"""
uri = '/subnets'
return self.list_resources(uri, **filters)
@@ -60,8 +64,9 @@
def create_bulk_subnets(self, **kwargs):
"""Create multiple subnets in a single request.
- Available params: see http://developer.openstack.org/
- api-ref/networking/v2/index.html#bulk-create-subnet
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/networking/v2/index.html#bulk-create-subnet
"""
uri = '/subnets'
return self.create_resource(uri, kwargs)
diff --git a/tempest/lib/services/volume/v1/quotas_client.py b/tempest/lib/services/volume/v1/quotas_client.py
index 8924b42..678fd82 100644
--- a/tempest/lib/services/volume/v1/quotas_client.py
+++ b/tempest/lib/services/volume/v1/quotas_client.py
@@ -45,8 +45,9 @@
def update_quota_set(self, tenant_id, **kwargs):
"""Updates quota set
- Available params: see http://developer.openstack.org/
- api-ref-blockstorage-v1.html#updateQuota
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref-blockstorage-v1.html#updateQuota
"""
put_body = jsonutils.dumps({'quota_set': kwargs})
resp, body = self.put('os-quota-sets/%s' % tenant_id, put_body)
diff --git a/tempest/services/volume/v1/json/admin/types_client.py b/tempest/lib/services/volume/v1/types_client.py
similarity index 100%
rename from tempest/services/volume/v1/json/admin/types_client.py
rename to tempest/lib/services/volume/v1/types_client.py
diff --git a/tempest/lib/services/volume/v2/quotas_client.py b/tempest/lib/services/volume/v2/quotas_client.py
index a302045..430957d 100644
--- a/tempest/lib/services/volume/v2/quotas_client.py
+++ b/tempest/lib/services/volume/v2/quotas_client.py
@@ -47,8 +47,9 @@
def update_quota_set(self, tenant_id, **kwargs):
"""Updates quota set
- Available params: see http://developer.openstack.org/
- api-ref-blockstorage-v2.html#updateQuotas-v2
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref-blockstorage-v2.html#updateQuota
"""
put_body = jsonutils.dumps({'quota_set': kwargs})
resp, body = self.put('os-quota-sets/%s' % tenant_id, put_body)
diff --git a/tempest/services/volume/v2/json/admin/types_client.py b/tempest/lib/services/volume/v2/types_client.py
similarity index 100%
rename from tempest/services/volume/v2/json/admin/types_client.py
rename to tempest/lib/services/volume/v2/types_client.py
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 233d747..4baf420 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -658,7 +658,8 @@
def _create_network(self, networks_client=None,
routers_client=None, tenant_id=None,
- namestart='network-smoke-'):
+ namestart='network-smoke-',
+ port_security_enabled=True):
if not networks_client:
networks_client = self.networks_client
if not routers_client:
@@ -666,7 +667,12 @@
if not tenant_id:
tenant_id = networks_client.tenant_id
name = data_utils.rand_name(namestart)
- result = networks_client.create_network(name=name, tenant_id=tenant_id)
+ network_kwargs = dict(name=name, tenant_id=tenant_id)
+ # Neutron disables port security by default so we have to check the
+ # config before trying to create the network with port_security_enabled
+ if CONF.network_feature_enabled.port_security:
+ network_kwargs['port_security_enabled'] = port_security_enabled
+ result = networks_client.create_network(**network_kwargs)
network = result['network']
self.assertEqual(network['name'], name)
@@ -977,7 +983,7 @@
def _default_security_group(self, client=None, tenant_id=None):
"""Get default secgroup for given tenant_id.
- :returns: DeletableSecurityGroup -- default secgroup for given tenant
+ :returns: default secgroup for given tenant
"""
if client is None:
client = self.security_groups_client
@@ -1141,7 +1147,8 @@
def create_networks(self, networks_client=None,
routers_client=None, subnets_client=None,
- tenant_id=None, dns_nameservers=None):
+ tenant_id=None, dns_nameservers=None,
+ port_security_enabled=True):
"""Create a network with a subnet connected to a router.
The baremetal driver is a special case since all nodes are
@@ -1167,7 +1174,8 @@
else:
network = self._create_network(
networks_client=networks_client,
- tenant_id=tenant_id)
+ tenant_id=tenant_id,
+ port_security_enabled=port_security_enabled)
router = self._get_router(client=routers_client,
tenant_id=tenant_id)
subnet_kwargs = dict(network=network,
diff --git a/tempest/scenario/test_network_advanced_server_ops.py b/tempest/scenario/test_network_advanced_server_ops.py
index 8f27a5d..3390aff 100644
--- a/tempest/scenario/test_network_advanced_server_ops.py
+++ b/tempest/scenario/test_network_advanced_server_ops.py
@@ -50,14 +50,12 @@
cls.set_network_resources()
super(TestNetworkAdvancedServerOps, cls).setup_credentials()
- def _setup_network_and_servers(self):
- keypair = self.create_keypair()
+ def _setup_server(self, keypair):
security_groups = []
if test.is_extension_enabled('security-group', 'network'):
security_group = self._create_security_group()
security_groups = [{'name': security_group['name']}]
network, subnet, router = self.create_networks()
- public_network_id = CONF.network.public_network_id
server_name = data_utils.rand_name(self.__class__.__name__ + '-server')
server = self.create_server(
name=server_name,
@@ -65,13 +63,17 @@
key_name=keypair['name'],
security_groups=security_groups,
wait_until='ACTIVE')
+ return server
+
+ def _setup_network(self, server, keypair):
+ public_network_id = CONF.network.public_network_id
floating_ip = self.create_floating_ip(server, public_network_id)
# Verify that we can indeed connect to the server before we mess with
# it's state
self._wait_server_status_and_check_network_connectivity(
server, keypair, floating_ip)
- return server, keypair, floating_ip
+ return floating_ip
def _check_network_connectivity(self, server, keypair, floating_ip,
should_connect=True):
@@ -99,7 +101,9 @@
@test.stresstest(class_setup_per='process')
@test.services('compute', 'network')
def test_server_connectivity_stop_start(self):
- server, keypair, floating_ip = self._setup_network_and_servers()
+ keypair = self.create_keypair()
+ server = self._setup_server(keypair)
+ floating_ip = self._setup_network(server, keypair)
self.servers_client.stop_server(server['id'])
waiters.wait_for_server_status(self.servers_client, server['id'],
'SHUTOFF')
@@ -112,7 +116,9 @@
@test.idempotent_id('7b6860c2-afa3-4846-9522-adeb38dfbe08')
@test.services('compute', 'network')
def test_server_connectivity_reboot(self):
- server, keypair, floating_ip = self._setup_network_and_servers()
+ keypair = self.create_keypair()
+ server = self._setup_server(keypair)
+ floating_ip = self._setup_network(server, keypair)
self.servers_client.reboot_server(server['id'], type='SOFT')
self._wait_server_status_and_check_network_connectivity(
server, keypair, floating_ip)
@@ -120,7 +126,9 @@
@test.idempotent_id('88a529c2-1daa-4c85-9aec-d541ba3eb699')
@test.services('compute', 'network')
def test_server_connectivity_rebuild(self):
- server, keypair, floating_ip = self._setup_network_and_servers()
+ keypair = self.create_keypair()
+ server = self._setup_server(keypair)
+ floating_ip = self._setup_network(server, keypair)
image_ref_alt = CONF.compute.image_ref_alt
self.servers_client.rebuild_server(server['id'],
image_ref=image_ref_alt)
@@ -132,7 +140,9 @@
'Pause is not available.')
@test.services('compute', 'network')
def test_server_connectivity_pause_unpause(self):
- server, keypair, floating_ip = self._setup_network_and_servers()
+ keypair = self.create_keypair()
+ server = self._setup_server(keypair)
+ floating_ip = self._setup_network(server, keypair)
self.servers_client.pause_server(server['id'])
waiters.wait_for_server_status(self.servers_client, server['id'],
'PAUSED')
@@ -147,7 +157,9 @@
'Suspend is not available.')
@test.services('compute', 'network')
def test_server_connectivity_suspend_resume(self):
- server, keypair, floating_ip = self._setup_network_and_servers()
+ keypair = self.create_keypair()
+ server = self._setup_server(keypair)
+ floating_ip = self._setup_network(server, keypair)
self.servers_client.suspend_server(server['id'])
waiters.wait_for_server_status(self.servers_client, server['id'],
'SUSPENDED')
@@ -166,7 +178,9 @@
if resize_flavor == CONF.compute.flavor_ref:
msg = "Skipping test - flavor_ref and flavor_ref_alt are identical"
raise self.skipException(msg)
- server, keypair, floating_ip = self._setup_network_and_servers()
+ keypair = self.create_keypair()
+ server = self._setup_server(keypair)
+ floating_ip = self._setup_network(server, keypair)
self.servers_client.resize_server(server['id'],
flavor_ref=resize_flavor)
waiters.wait_for_server_status(self.servers_client, server['id'],
diff --git a/tempest/scenario/test_security_groups_basic_ops.py b/tempest/scenario/test_security_groups_basic_ops.py
index 86185c8..2c16be8 100644
--- a/tempest/scenario/test_security_groups_basic_ops.py
+++ b/tempest/scenario/test_security_groups_basic_ops.py
@@ -13,6 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
from oslo_log import log
+import testtools
from tempest import clients
from tempest.common.utils import data_utils
@@ -256,7 +257,7 @@
# and distributed routers; 'device_owner' is "" by default.
return port['device_owner'].startswith('network:router_interface')
- def _create_server(self, name, tenant, security_groups=None, **kwargs):
+ def _create_server(self, name, tenant, security_groups, **kwargs):
"""Creates a server and assigns it to security group.
If multi-host is enabled, Ensures servers are created on different
@@ -264,8 +265,6 @@
as scheduler_hints on creation.
Validates servers are created as requested, using admin client.
"""
- if security_groups is None:
- security_groups = [tenant.security_groups['default']]
security_groups_names = [{'name': s['name']} for s in security_groups]
if self.multi_node:
kwargs["scheduler_hints"] = {'different_host': self.servers}
@@ -277,9 +276,10 @@
wait_until='ACTIVE',
clients=tenant.manager,
**kwargs)
- self.assertEqual(
- sorted([s['name'] for s in security_groups]),
- sorted([s['name'] for s in server['security_groups']]))
+ if 'security_groups' in server:
+ self.assertEqual(
+ sorted([s['name'] for s in security_groups]),
+ sorted([s['name'] for s in server['security_groups']]))
# Verify servers are on different compute nodes
if self.multi_node:
@@ -303,7 +303,8 @@
num=i
)
name = data_utils.rand_name(name)
- server = self._create_server(name, tenant)
+ server = self._create_server(name, tenant,
+ [tenant.security_groups['default']])
tenant.servers.append(server)
def _set_access_point(self, tenant):
@@ -326,11 +327,12 @@
client=tenant.manager.floating_ips_client)
self.floating_ips.setdefault(server['id'], floating_ip)
- def _create_tenant_network(self, tenant):
+ def _create_tenant_network(self, tenant, port_security_enabled=True):
network, subnet, router = self.create_networks(
networks_client=tenant.manager.networks_client,
routers_client=tenant.manager.routers_client,
- subnets_client=tenant.manager.subnets_client)
+ subnets_client=tenant.manager.subnets_client,
+ port_security_enabled=port_security_enabled)
tenant.set_network(network, subnet, router)
def _deploy_tenant(self, tenant_or_id):
@@ -533,7 +535,8 @@
tenant=new_tenant.creds.tenant_name
)
name = data_utils.rand_name(name)
- server = self._create_server(name, new_tenant)
+ server = self._create_server(name, new_tenant,
+ [new_tenant.security_groups['default']])
# Check connectivity failure with default security group
try:
@@ -599,7 +602,8 @@
tenant=new_tenant.creds.tenant_name
)
name = data_utils.rand_name(name)
- server = self._create_server(name, new_tenant)
+ server = self._create_server(name, new_tenant,
+ [new_tenant.security_groups['default']])
access_point_ssh = self._connect_to_access_point(new_tenant)
server_id = server['id']
@@ -624,3 +628,32 @@
for tenant in self.tenants.values():
self._log_console_output(servers=tenant.servers)
raise
+
+ @test.requires_ext(service='network', extension='port-security')
+ @test.idempotent_id('13ccf253-e5ad-424b-9c4a-97b88a026699')
+ @testtools.skipUnless(
+ CONF.compute_feature_enabled.allow_port_security_disabled,
+ 'Port security must be enabled.')
+ # TODO(mriedem): We shouldn't actually need to check this since neutron
+ # disables the port_security extension by default, but the problem is nova
+ # assumes port_security_enabled=True if it's not set on the network
+ # resource, which will mean nova may attempt to apply a security group on
+ # a port on that network which would fail. This is really a bug in nova.
+ @testtools.skipUnless(
+ CONF.network_feature_enabled.port_security,
+ 'Port security must be enabled.')
+ @test.services('compute', 'network')
+ def test_boot_into_disabled_port_security_network_without_secgroup(self):
+ tenant = self.primary_tenant
+ self._create_tenant_network(tenant, port_security_enabled=False)
+ self.assertFalse(tenant.network['port_security_enabled'])
+ name = data_utils.rand_name('server-smoke')
+ sec_groups = []
+ server = self._create_server(name, tenant, sec_groups)
+ server_id = server['id']
+ ports = self._list_ports(device_id=server_id)
+ self.assertEqual(1, len(ports))
+ for port in ports:
+ self.assertEmpty(port['security_groups'],
+ "Neutron shouldn't even use it's default sec "
+ "group.")
diff --git a/tempest/services/identity/__init__.py b/tempest/services/identity/__init__.py
index 0e24926..53c223f 100644
--- a/tempest/services/identity/__init__.py
+++ b/tempest/services/identity/__init__.py
@@ -12,7 +12,7 @@
# License for the specific language governing permissions and limitations under
# the License.
-from tempest.services.identity import v2
+from tempest.lib.services.identity import v2
from tempest.services.identity import v3
__all__ = ['v2', 'v3']
diff --git a/tempest/services/identity/v2/__init__.py b/tempest/services/identity/v2/__init__.py
deleted file mode 100644
index b7d3c74..0000000
--- a/tempest/services/identity/v2/__init__.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (c) 2016 Hewlett-Packard Enterprise Development Company, L.P.
-#
-# 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.lib.services.identity.v2.endpoints_client import EndpointsClient
-from tempest.lib.services.identity.v2.identity_client import IdentityClient
-from tempest.lib.services.identity.v2.roles_client import RolesClient
-from tempest.lib.services.identity.v2.services_client import ServicesClient
-from tempest.lib.services.identity.v2.tenants_client import TenantsClient
-from tempest.lib.services.identity.v2.token_client import TokenClient
-from tempest.lib.services.identity.v2.users_client import UsersClient
-
-__all__ = ['EndpointsClient', 'IdentityClient', 'RolesClient',
- 'ServicesClient', 'TenantsClient', 'TokenClient', 'UsersClient']
diff --git a/tempest/services/identity/v2/json/__init__.py b/tempest/services/identity/v2/json/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/services/identity/v2/json/__init__.py
+++ /dev/null
diff --git a/tempest/services/identity/v3/__init__.py b/tempest/services/identity/v3/__init__.py
index c5ab6b3..3f5c3d5 100644
--- a/tempest/services/identity/v3/__init__.py
+++ b/tempest/services/identity/v3/__init__.py
@@ -12,24 +12,24 @@
# License for the specific language governing permissions and limitations under
# the License.
+from tempest.lib.services.identity.v3.credentials_client import \
+ CredentialsClient
from tempest.lib.services.identity.v3.endpoints_client import EndPointsClient
from tempest.lib.services.identity.v3.groups_client import GroupsClient
from tempest.lib.services.identity.v3.identity_client import IdentityClient
+from tempest.lib.services.identity.v3.inherited_roles_client import \
+ InheritedRolesClient
from tempest.lib.services.identity.v3.policies_client import PoliciesClient
from tempest.lib.services.identity.v3.projects_client import ProjectsClient
from tempest.lib.services.identity.v3.regions_client import RegionsClient
+from tempest.lib.services.identity.v3.roles_client import RolesClient
from tempest.lib.services.identity.v3.services_client import ServicesClient
from tempest.lib.services.identity.v3.token_client import V3TokenClient
+from tempest.lib.services.identity.v3.trusts_client import TrustsClient
from tempest.lib.services.identity.v3.users_client import UsersClient
-from tempest.services.identity.v3.json.credentials_client import \
- CredentialsClient
from tempest.services.identity.v3.json.domains_client import DomainsClient
-from tempest.services.identity.v3.json.roles_client import RolesClient
-from tempest.services.identity.v3.json.trusts_client import TrustsClient
-
-__all__ = ['EndPointsClient', 'GroupsClient', 'IdentityClient',
- 'PoliciesClient', 'ProjectsClient', 'RegionsClient',
- 'ServicesClient', 'V3TokenClient', 'UsersClient',
- 'CredentialsClient', 'DomainsClient', 'RolesClient',
- 'TrustsClient', ]
+__all__ = ['CredentialsClient', 'EndPointsClient', 'GroupsClient',
+ 'IdentityClient', 'InheritedRolesClient', 'PoliciesClient',
+ 'ProjectsClient', 'RegionsClient', 'RolesClient', 'ServicesClient',
+ 'V3TokenClient', 'TrustsClient', 'UsersClient', 'DomainsClient', ]
diff --git a/tempest/services/identity/v3/json/roles_client.py b/tempest/services/identity/v3/json/roles_client.py
deleted file mode 100644
index 3f165fa..0000000
--- a/tempest/services/identity/v3/json/roles_client.py
+++ /dev/null
@@ -1,320 +0,0 @@
-# Copyright 2016 Red Hat, Inc.
-#
-# 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 oslo_serialization import jsonutils as json
-from six.moves.urllib import parse as urllib
-
-from tempest.lib.common import rest_client
-
-
-class RolesClient(rest_client.RestClient):
- api_version = "v3"
-
- def create_role(self, **kwargs):
- """Create a Role.
-
- Available params: see http://developer.openstack.org/
- api-ref-identity-v3.html#createRole
- """
- post_body = json.dumps({'role': kwargs})
- resp, body = self.post('roles', post_body)
- self.expected_success(201, resp.status)
- body = json.loads(body)
- return rest_client.ResponseBody(resp, body)
-
- def show_role(self, role_id):
- """GET a Role."""
- resp, body = self.get('roles/%s' % role_id)
- self.expected_success(200, resp.status)
- body = json.loads(body)
- return rest_client.ResponseBody(resp, body)
-
- def list_roles(self, **params):
- """Get the list of Roles."""
-
- url = 'roles'
- if params:
- url += '?%s' % urllib.urlencode(params)
- resp, body = self.get(url)
- self.expected_success(200, resp.status)
- body = json.loads(body)
- return rest_client.ResponseBody(resp, body)
-
- def update_role(self, role_id, **kwargs):
- """Update a Role.
-
- Available params: see http://developer.openstack.org/
- api-ref-identity-v3.html#updateRole
- """
- post_body = json.dumps({'role': kwargs})
- resp, body = self.patch('roles/%s' % role_id, post_body)
- self.expected_success(200, resp.status)
- body = json.loads(body)
- return rest_client.ResponseBody(resp, body)
-
- def delete_role(self, role_id):
- """Delete a role."""
- resp, body = self.delete('roles/%s' % role_id)
- self.expected_success(204, resp.status)
- return rest_client.ResponseBody(resp, body)
-
- def create_user_role_on_project(self, project_id, user_id, role_id):
- """Add roles to a user on a project."""
- resp, body = self.put('projects/%s/users/%s/roles/%s' %
- (project_id, user_id, role_id), None)
- self.expected_success(204, resp.status)
- return rest_client.ResponseBody(resp, body)
-
- def create_user_role_on_domain(self, domain_id, user_id, role_id):
- """Add roles to a user on a domain."""
- resp, body = self.put('domains/%s/users/%s/roles/%s' %
- (domain_id, user_id, role_id), None)
- self.expected_success(204, resp.status)
- return rest_client.ResponseBody(resp, body)
-
- def list_user_roles_on_project(self, project_id, user_id):
- """list roles of a user on a project."""
- resp, body = self.get('projects/%s/users/%s/roles' %
- (project_id, user_id))
- self.expected_success(200, resp.status)
- body = json.loads(body)
- return rest_client.ResponseBody(resp, body)
-
- def list_user_roles_on_domain(self, domain_id, user_id):
- """list roles of a user on a domain."""
- resp, body = self.get('domains/%s/users/%s/roles' %
- (domain_id, user_id))
- self.expected_success(200, resp.status)
- body = json.loads(body)
- return rest_client.ResponseBody(resp, body)
-
- def delete_role_from_user_on_project(self, project_id, user_id, role_id):
- """Delete role of a user on a project."""
- resp, body = self.delete('projects/%s/users/%s/roles/%s' %
- (project_id, user_id, role_id))
- self.expected_success(204, resp.status)
- return rest_client.ResponseBody(resp, body)
-
- def delete_role_from_user_on_domain(self, domain_id, user_id, role_id):
- """Delete role of a user on a domain."""
- resp, body = self.delete('domains/%s/users/%s/roles/%s' %
- (domain_id, user_id, role_id))
- self.expected_success(204, resp.status)
- return rest_client.ResponseBody(resp, body)
-
- def check_user_role_existence_on_project(self, project_id,
- user_id, role_id):
- """Check role of a user on a project."""
- resp, body = self.head('projects/%s/users/%s/roles/%s' %
- (project_id, user_id, role_id))
- self.expected_success(204, resp.status)
- return rest_client.ResponseBody(resp)
-
- def check_user_role_existence_on_domain(self, domain_id,
- user_id, role_id):
- """Check role of a user on a domain."""
- resp, body = self.head('domains/%s/users/%s/roles/%s' %
- (domain_id, user_id, role_id))
- self.expected_success(204, resp.status)
- return rest_client.ResponseBody(resp)
-
- def create_group_role_on_project(self, project_id, group_id, role_id):
- """Add roles to a group on a project."""
- resp, body = self.put('projects/%s/groups/%s/roles/%s' %
- (project_id, group_id, role_id), None)
- self.expected_success(204, resp.status)
- return rest_client.ResponseBody(resp, body)
-
- def create_group_role_on_domain(self, domain_id, group_id, role_id):
- """Add roles to a group on a domain."""
- resp, body = self.put('domains/%s/groups/%s/roles/%s' %
- (domain_id, group_id, role_id), None)
- self.expected_success(204, resp.status)
- return rest_client.ResponseBody(resp, body)
-
- def list_group_roles_on_project(self, project_id, group_id):
- """list roles of a group on a project."""
- resp, body = self.get('projects/%s/groups/%s/roles' %
- (project_id, group_id))
- self.expected_success(200, resp.status)
- body = json.loads(body)
- return rest_client.ResponseBody(resp, body)
-
- def list_group_roles_on_domain(self, domain_id, group_id):
- """list roles of a group on a domain."""
- resp, body = self.get('domains/%s/groups/%s/roles' %
- (domain_id, group_id))
- self.expected_success(200, resp.status)
- body = json.loads(body)
- return rest_client.ResponseBody(resp, body)
-
- def delete_role_from_group_on_project(self, project_id, group_id, role_id):
- """Delete role of a group on a project."""
- resp, body = self.delete('projects/%s/groups/%s/roles/%s' %
- (project_id, group_id, role_id))
- self.expected_success(204, resp.status)
- return rest_client.ResponseBody(resp, body)
-
- def delete_role_from_group_on_domain(self, domain_id, group_id, role_id):
- """Delete role of a group on a domain."""
- resp, body = self.delete('domains/%s/groups/%s/roles/%s' %
- (domain_id, group_id, role_id))
- self.expected_success(204, resp.status)
- return rest_client.ResponseBody(resp, body)
-
- def check_role_from_group_on_project_existence(self, project_id,
- group_id, role_id):
- """Check role of a group on a project."""
- resp, body = self.head('projects/%s/groups/%s/roles/%s' %
- (project_id, group_id, role_id))
- self.expected_success(204, resp.status)
- return rest_client.ResponseBody(resp)
-
- def check_role_from_group_on_domain_existence(self, domain_id,
- group_id, role_id):
- """Check role of a group on a domain."""
- resp, body = self.head('domains/%s/groups/%s/roles/%s' %
- (domain_id, group_id, role_id))
- self.expected_success(204, resp.status)
- return rest_client.ResponseBody(resp)
-
- def assign_inherited_role_on_domains_user(
- self, domain_id, user_id, role_id):
- """Assigns a role to a user on projects owned by a domain."""
- resp, body = self.put(
- "OS-INHERIT/domains/%s/users/%s/roles/%s/inherited_to_projects"
- % (domain_id, user_id, role_id), None)
- self.expected_success(204, resp.status)
- return rest_client.ResponseBody(resp, body)
-
- def revoke_inherited_role_from_user_on_domain(
- self, domain_id, user_id, role_id):
- """Revokes an inherited project role from a user on a domain."""
- resp, body = self.delete(
- "OS-INHERIT/domains/%s/users/%s/roles/%s/inherited_to_projects"
- % (domain_id, user_id, role_id))
- self.expected_success(204, resp.status)
- return rest_client.ResponseBody(resp, body)
-
- def list_inherited_project_role_for_user_on_domain(
- self, domain_id, user_id):
- """Lists the inherited project roles on a domain for a user."""
- resp, body = self.get(
- "OS-INHERIT/domains/%s/users/%s/roles/inherited_to_projects"
- % (domain_id, user_id))
- self.expected_success(200, resp.status)
- body = json.loads(body)
- return rest_client.ResponseBody(resp, body)
-
- def check_user_inherited_project_role_on_domain(
- self, domain_id, user_id, role_id):
- """Checks whether a user has an inherited project role on a domain."""
- resp, body = self.head(
- "OS-INHERIT/domains/%s/users/%s/roles/%s/inherited_to_projects"
- % (domain_id, user_id, role_id))
- self.expected_success(204, resp.status)
- return rest_client.ResponseBody(resp)
-
- def assign_inherited_role_on_domains_group(
- self, domain_id, group_id, role_id):
- """Assigns a role to a group on projects owned by a domain."""
- resp, body = self.put(
- "OS-INHERIT/domains/%s/groups/%s/roles/%s/inherited_to_projects"
- % (domain_id, group_id, role_id), None)
- self.expected_success(204, resp.status)
- return rest_client.ResponseBody(resp, body)
-
- def revoke_inherited_role_from_group_on_domain(
- self, domain_id, group_id, role_id):
- """Revokes an inherited project role from a group on a domain."""
- resp, body = self.delete(
- "OS-INHERIT/domains/%s/groups/%s/roles/%s/inherited_to_projects"
- % (domain_id, group_id, role_id))
- self.expected_success(204, resp.status)
- return rest_client.ResponseBody(resp, body)
-
- def list_inherited_project_role_for_group_on_domain(
- self, domain_id, group_id):
- """Lists the inherited project roles on a domain for a group."""
- resp, body = self.get(
- "OS-INHERIT/domains/%s/groups/%s/roles/inherited_to_projects"
- % (domain_id, group_id))
- self.expected_success(200, resp.status)
- body = json.loads(body)
- return rest_client.ResponseBody(resp, body)
-
- def check_group_inherited_project_role_on_domain(
- self, domain_id, group_id, role_id):
- """Checks whether a group has an inherited project role on a domain."""
- resp, body = self.head(
- "OS-INHERIT/domains/%s/groups/%s/roles/%s/inherited_to_projects"
- % (domain_id, group_id, role_id))
- self.expected_success(204, resp.status)
- return rest_client.ResponseBody(resp)
-
- def assign_inherited_role_on_projects_user(
- self, project_id, user_id, role_id):
- """Assigns a role to a user on projects in a subtree."""
- resp, body = self.put(
- "OS-INHERIT/projects/%s/users/%s/roles/%s/inherited_to_projects"
- % (project_id, user_id, role_id), None)
- self.expected_success(204, resp.status)
- return rest_client.ResponseBody(resp, body)
-
- def revoke_inherited_role_from_user_on_project(
- self, project_id, user_id, role_id):
- """Revokes an inherited role from a user on a project."""
- resp, body = self.delete(
- "OS-INHERIT/projects/%s/users/%s/roles/%s/inherited_to_projects"
- % (project_id, user_id, role_id))
- self.expected_success(204, resp.status)
- return rest_client.ResponseBody(resp, body)
-
- def check_user_has_flag_on_inherited_to_project(
- self, project_id, user_id, role_id):
- """Checks whether a user has a role assignment"""
- """with the inherited_to_projects flag on a project."""
- resp, body = self.head(
- "OS-INHERIT/projects/%s/users/%s/roles/%s/inherited_to_projects"
- % (project_id, user_id, role_id))
- self.expected_success(204, resp.status)
- return rest_client.ResponseBody(resp)
-
- def assign_inherited_role_on_projects_group(
- self, project_id, group_id, role_id):
- """Assigns a role to a group on projects in a subtree."""
- resp, body = self.put(
- "OS-INHERIT/projects/%s/groups/%s/roles/%s/inherited_to_projects"
- % (project_id, group_id, role_id), None)
- self.expected_success(204, resp.status)
- return rest_client.ResponseBody(resp, body)
-
- def revoke_inherited_role_from_group_on_project(
- self, project_id, group_id, role_id):
- """Revokes an inherited role from a group on a project."""
- resp, body = self.delete(
- "OS-INHERIT/projects/%s/groups/%s/roles/%s/inherited_to_projects"
- % (project_id, group_id, role_id))
- self.expected_success(204, resp.status)
- return rest_client.ResponseBody(resp, body)
-
- def check_group_has_flag_on_inherited_to_project(
- self, project_id, group_id, role_id):
- """Checks whether a group has a role assignment"""
- """with the inherited_to_projects flag on a project."""
- resp, body = self.head(
- "OS-INHERIT/projects/%s/groups/%s/roles/%s/inherited_to_projects"
- % (project_id, group_id, role_id))
- self.expected_success(204, resp.status)
- return rest_client.ResponseBody(resp)
diff --git a/tempest/services/object_storage/object_client.py b/tempest/services/object_storage/object_client.py
index a7db30e..ec36fb7 100644
--- a/tempest/services/object_storage/object_client.py
+++ b/tempest/services/object_storage/object_client.py
@@ -195,7 +195,6 @@
# Read the 100 status prior to sending the data
response = conn.response_class(conn.sock,
- strict=conn.strict,
method=conn._method)
_, status, _ = response._read_status()
diff --git a/tempest/services/volume/base/base_volumes_client.py b/tempest/services/volume/base/base_volumes_client.py
index 11b6e1a..1cb1ef5 100755
--- a/tempest/services/volume/base/base_volumes_client.py
+++ b/tempest/services/volume/base/base_volumes_client.py
@@ -52,19 +52,6 @@
self.expected_success(200, resp.status)
return rest_client.ResponseBody(resp, body)
- def show_backend_capabilities(self, host):
- """Shows capabilities for a storage back end.
-
- Output params: see http://developer.openstack.org/
- api-ref-blockstorage-v2.html
- #showBackendCapabilities
- """
- url = 'capabilities/%s' % host
- resp, body = self.get(url)
- body = json.loads(body)
- self.expected_success(200, resp.status)
- return rest_client.ResponseBody(resp, body)
-
def show_volume(self, volume_id):
"""Returns the details of a single volume."""
url = "volumes/%s" % volume_id
diff --git a/tempest/services/volume/v1/__init__.py b/tempest/services/volume/v1/__init__.py
index 72868bc..b17440e 100644
--- a/tempest/services/volume/v1/__init__.py
+++ b/tempest/services/volume/v1/__init__.py
@@ -18,7 +18,7 @@
from tempest.lib.services.volume.v1.hosts_client import HostsClient
from tempest.lib.services.volume.v1.quotas_client import QuotasClient
from tempest.lib.services.volume.v1.services_client import ServicesClient
-from tempest.services.volume.v1.json.admin.types_client import TypesClient
+from tempest.lib.services.volume.v1.types_client import TypesClient
from tempest.services.volume.v1.json.backups_client import BackupsClient
from tempest.services.volume.v1.json.encryption_types_client import \
EncryptionTypesClient
@@ -26,7 +26,7 @@
from tempest.services.volume.v1.json.snapshots_client import SnapshotsClient
from tempest.services.volume.v1.json.volumes_client import VolumesClient
-__all__ = ['HostsClient', 'QuotasClient', 'ServicesClient', 'TypesClient',
- 'AvailabilityZoneClient', 'BackupsClient', 'ExtensionsClient',
- 'QosSpecsClient', 'SnapshotsClient', 'VolumesClient',
- 'EncryptionTypesClient']
+__all__ = ['AvailabilityZoneClient', 'ExtensionsClient', 'HostsClient',
+ 'QuotasClient', 'ServicesClient', 'TypesClient', 'BackupsClient',
+ 'EncryptionTypesClient', 'QosSpecsClient', 'SnapshotsClient',
+ 'VolumesClient', ]
diff --git a/tempest/services/volume/v2/__init__.py b/tempest/services/volume/v2/__init__.py
index 4afcc29..c99a81a 100644
--- a/tempest/services/volume/v2/__init__.py
+++ b/tempest/services/volume/v2/__init__.py
@@ -18,7 +18,7 @@
from tempest.lib.services.volume.v2.hosts_client import HostsClient
from tempest.lib.services.volume.v2.quotas_client import QuotasClient
from tempest.lib.services.volume.v2.services_client import ServicesClient
-from tempest.services.volume.v2.json.admin.types_client import TypesClient
+from tempest.lib.services.volume.v2.types_client import TypesClient
from tempest.services.volume.v2.json.backups_client import BackupsClient
from tempest.services.volume.v2.json.encryption_types_client import \
EncryptionTypesClient
@@ -26,7 +26,7 @@
from tempest.services.volume.v2.json.snapshots_client import SnapshotsClient
from tempest.services.volume.v2.json.volumes_client import VolumesClient
-__all__ = ['HostsClient', 'QuotasClient', 'ServicesClient', 'TypesClient',
- 'AvailabilityZoneClient', 'BackupsClient', 'ExtensionsClient',
- 'QosSpecsClient', 'SnapshotsClient', 'VolumesClient',
- 'EncryptionTypesClient']
+__all__ = ['AvailabilityZoneClient', 'ExtensionsClient', 'HostsClient',
+ 'QuotasClient', 'ServicesClient', 'TypesClient', 'BackupsClient',
+ 'EncryptionTypesClient', 'QosSpecsClient', 'SnapshotsClient',
+ 'VolumesClient', ]
diff --git a/tempest/services/volume/v2/json/volumes_client.py b/tempest/services/volume/v2/json/volumes_client.py
index 2a435e7..f21a1a3 100644
--- a/tempest/services/volume/v2/json/volumes_client.py
+++ b/tempest/services/volume/v2/json/volumes_client.py
@@ -56,3 +56,16 @@
body = json.loads(body)
self.expected_success(200, resp.status)
return rest_client.ResponseBody(resp, body)
+
+ def show_backend_capabilities(self, host):
+ """Shows capabilities for a storage back end.
+
+ Output params: see http://developer.openstack.org/
+ api-ref-blockstorage-v2.html
+ #showBackendCapabilities
+ """
+ url = 'capabilities/%s' % host
+ resp, body = self.get(url)
+ body = json.loads(body)
+ self.expected_success(200, resp.status)
+ return rest_client.ResponseBody(resp, body)
diff --git a/tempest/stress/driver.py b/tempest/stress/driver.py
index 925d765..1e33e88 100644
--- a/tempest/stress/driver.py
+++ b/tempest/stress/driver.py
@@ -20,8 +20,6 @@
from oslo_log import log as logging
from oslo_utils import importutils
import six
-from six import moves
-
from tempest import clients
from tempest.common import cred_client
@@ -142,7 +140,7 @@
manager = admin_manager
else:
raise NotImplemented('Non admin tests are not supported')
- for p_number in moves.xrange(test.get('threads', default_thread_num)):
+ for p_number in range(test.get('threads', default_thread_num)):
if test.get('use_isolated_tenants', False):
username = data_utils.rand_name("stress_user")
tenant_name = data_utils.rand_name("stress_tenant")
diff --git a/tempest/tests/cmd/test_verify_tempest_config.py b/tempest/tests/cmd/test_verify_tempest_config.py
index 00b4542..68588be 100644
--- a/tempest/tests/cmd/test_verify_tempest_config.py
+++ b/tempest/tests/cmd/test_verify_tempest_config.py
@@ -237,33 +237,45 @@
True, True)
self.assertEqual(2, print_mock.call_count)
- def test_verify_glance_version_no_v2_with_v1_1(self):
- def fake_get_versions():
- return (None, ['v1.1'])
+ @mock.patch('tempest.lib.common.http.ClosingHttp.request')
+ def test_verify_glance_version_no_v2_with_v1_1(self, mock_request):
+ self.useFixture(mockpatch.PatchObject(
+ verify_tempest_config, '_get_unversioned_endpoint',
+ return_value='http://fake_endpoint:5000'))
+ fake_resp = {'versions': [{'id': 'v1.1'}]}
+ fake_resp = json.dumps(fake_resp)
+ mock_request.return_value = (None, fake_resp)
fake_os = mock.MagicMock()
- fake_os.image_client.get_versions = fake_get_versions
with mock.patch.object(verify_tempest_config,
'print_and_or_update') as print_mock:
verify_tempest_config.verify_glance_api_versions(fake_os, True)
print_mock.assert_called_once_with('api_v2', 'image-feature-enabled',
False, True)
- def test_verify_glance_version_no_v2_with_v1_0(self):
- def fake_get_versions():
- return (None, ['v1.0'])
+ @mock.patch('tempest.lib.common.http.ClosingHttp.request')
+ def test_verify_glance_version_no_v2_with_v1_0(self, mock_request):
+ self.useFixture(mockpatch.PatchObject(
+ verify_tempest_config, '_get_unversioned_endpoint',
+ return_value='http://fake_endpoint:5000'))
+ fake_resp = {'versions': [{'id': 'v1.0'}]}
+ fake_resp = json.dumps(fake_resp)
+ mock_request.return_value = (None, fake_resp)
fake_os = mock.MagicMock()
- fake_os.image_client.get_versions = fake_get_versions
with mock.patch.object(verify_tempest_config,
'print_and_or_update') as print_mock:
verify_tempest_config.verify_glance_api_versions(fake_os, True)
print_mock.assert_called_once_with('api_v2', 'image-feature-enabled',
False, True)
- def test_verify_glance_version_no_v1(self):
- def fake_get_versions():
- return (None, ['v2.0'])
+ @mock.patch('tempest.lib.common.http.ClosingHttp.request')
+ def test_verify_glance_version_no_v1(self, mock_request):
+ self.useFixture(mockpatch.PatchObject(
+ verify_tempest_config, '_get_unversioned_endpoint',
+ return_value='http://fake_endpoint:5000'))
+ fake_resp = {'versions': [{'id': 'v2.0'}]}
+ fake_resp = json.dumps(fake_resp)
+ mock_request.return_value = (None, fake_resp)
fake_os = mock.MagicMock()
- fake_os.image_client.get_versions = fake_get_versions
with mock.patch.object(verify_tempest_config,
'print_and_or_update') as print_mock:
verify_tempest_config.verify_glance_api_versions(fake_os, True)
diff --git a/tempest/tests/common/test_dynamic_creds.py b/tempest/tests/common/test_dynamic_creds.py
index 613bc63..0033d4e 100644
--- a/tempest/tests/common/test_dynamic_creds.py
+++ b/tempest/tests/common/test_dynamic_creds.py
@@ -31,12 +31,12 @@
from tempest.lib.services.identity.v3 import identity_client as v3_iden_client
from tempest.lib.services.identity.v3 import projects_client as \
v3_projects_client
+from tempest.lib.services.identity.v3 import roles_client as v3_roles_client
from tempest.lib.services.identity.v3 import token_client as v3_token_client
from tempest.lib.services.identity.v3 import users_client as \
v3_users_client
from tempest.lib.services.network import routers_client
from tempest.services.identity.v3.json import domains_client
-from tempest.services.identity.v3.json import roles_client as v3_roles_client
from tempest.tests import base
from tempest.tests import fake_config
from tempest.tests.lib import fake_http
diff --git a/tempest/tests/fake_auth_provider.py b/tempest/tests/fake_auth_provider.py
deleted file mode 100644
index 769f6a6..0000000
--- a/tempest/tests/fake_auth_provider.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright 2014 Hewlett-Packard Development Company, L.P.
-# 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.
-
-
-class FakeAuthProvider(object):
-
- def auth_request(self, method, url, headers=None, body=None, filters=None):
- return url, headers, body
-
- def get_token(self):
- return "faketoken"
-
- def base_url(self, filters, auth_data=None):
- return "https://example.com"
diff --git a/tempest/tests/lib/common/utils/test_data_utils.py b/tempest/tests/lib/common/utils/test_data_utils.py
index 94a4847..4446e5c 100644
--- a/tempest/tests/lib/common/utils/test_data_utils.py
+++ b/tempest/tests/lib/common/utils/test_data_utils.py
@@ -125,13 +125,13 @@
def test_random_bytes(self):
actual = data_utils.random_bytes() # default size=1024
- self.assertIsInstance(actual, str)
- self.assertRegex(actual, "^[\x00-\xFF]{1024}")
+ self.assertIsInstance(actual, bytes)
+ self.assertEqual(1024, len(actual))
actual2 = data_utils.random_bytes()
self.assertNotEqual(actual, actual2)
actual = data_utils.random_bytes(size=2048)
- self.assertRegex(actual, "^[\x00-\xFF]{2048}")
+ self.assertEqual(2048, len(actual))
def test_get_ipv6_addr_by_EUI64(self):
actual = data_utils.get_ipv6_addr_by_EUI64('2001:db8::',
diff --git a/tempest/tests/lib/fake_auth_provider.py b/tempest/tests/lib/fake_auth_provider.py
index fa8ab47..e4582f8 100644
--- a/tempest/tests/lib/fake_auth_provider.py
+++ b/tempest/tests/lib/fake_auth_provider.py
@@ -27,6 +27,9 @@
def base_url(self, filters, auth_data=None):
return self.fake_base_url or "https://example.com"
+ def get_token(self):
+ return "faketoken"
+
class FakeCredentials(object):
diff --git a/tempest/tests/lib/services/identity/v3/test_credentials_client.py b/tempest/tests/lib/services/identity/v3/test_credentials_client.py
new file mode 100644
index 0000000..29d7496
--- /dev/null
+++ b/tempest/tests/lib/services/identity/v3/test_credentials_client.py
@@ -0,0 +1,179 @@
+# Copyright 2016 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.lib.services.identity.v3 import credentials_client
+from tempest.tests.lib import fake_auth_provider
+from tempest.tests.lib.services import base
+
+
+class TestCredentialsClient(base.BaseServiceTest):
+ FAKE_CREATE_CREDENTIAL = {
+ "credential": {
+ "blob": "{\"access\":\"181920\",\"secret\":\"secretKey\"}",
+ "project_id": "731fc6f265cd486d900f16e84c5cb594",
+ "type": "ec2",
+ "user_id": "bb5476fd12884539b41d5a88f838d773"
+ }
+ }
+
+ FAKE_INFO_CREDENTIAL = {
+ "credential": {
+ "user_id": "bb5476fd12884539b41d5a88f838d773",
+ "links": {
+ "self": "http://example.com/identity/v3/credentials/" +
+ "207e9b76935efc03804d3dd6ab52d22e9b22a0711e4" +
+ "ada4ff8b76165a07311d7"
+ },
+ "blob": "{\"access\": \"a42a27755ce6442596b049bd7dd8a563\"," +
+ " \"secret\": \"71faf1d40bb24c82b479b1c6fbbd9f0c\"}",
+ "project_id": "6e01855f345f4c59812999b5e459137d",
+ "type": "ec2",
+ "id": "207e9b76935efc03804d3dd6ab52d22e9b22a0711e4ada4f"
+ }
+ }
+
+ FAKE_LIST_CREDENTIALS = {
+ "credentials": [
+ {
+ "user_id": "bb5476fd12884539b41d5a88f838d773",
+ "links": {
+ "self": "http://example.com/identity/v3/credentials/" +
+ "207e9b76935efc03804d3dd6ab52d22e9b22a0711e4" +
+ "ada4ff8b76165a07311d7"
+ },
+ "blob": "{\"access\": \"a42a27755ce6442596b049bd7dd8a563\"," +
+ " \"secret\": \"71faf1d40bb24c82b479b1c6fbbd9f0c\"," +
+ " \"trust_id\": null}",
+ "project_id": "6e01855f345f4c59812999b5e459137d",
+ "type": "ec2",
+ "id": "207e9b76935efc03804d3dd6ab52d22e9b22a0711e4ada4f"
+ },
+ {
+ "user_id": "6f556708d04b4ea6bc72d7df2296b71a",
+ "links": {
+ "self": "http://example.com/identity/v3/credentials/" +
+ "2441494e52ab6d594a34d74586075cb299489bdd1e9" +
+ "389e3ab06467a4f460609"
+ },
+ "blob": "{\"access\": \"7da79ff0aa364e1396f067e352b9b79a\"," +
+ " \"secret\": \"7a18d68ba8834b799d396f3ff6f1e98c\"," +
+ " \"trust_id\": null}",
+ "project_id": "1a1d14690f3c4ec5bf5f321c5fde3c16",
+ "type": "ec2",
+ "id": "2441494e52ab6d594a34d74586075cb299489bdd1e9389e3"
+ },
+ {
+ "user_id": "c14107e65d5c4a7f8894fc4b3fc209ff",
+ "links": {
+ "self": "http://example.com/identity/v3/credentials/" +
+ "3397b204b5f04c495bcdc8f34c8a39996f280f91726" +
+ "58241873e15f070ec79d7"
+ },
+ "blob": "{\"access\": \"db9c58a558534a10a070110de4f9f20c\"," +
+ " \"secret\": \"973e790b88db447ba6f93bca02bc745b\"," +
+ " \"trust_id\": null}",
+ "project_id": "7396e43183db40dcbf40dd727637b548",
+ "type": "ec2",
+ "id": "3397b204b5f04c495bcdc8f34c8a39996f280f9172658241"
+ },
+ {
+ "user_id": "bb5476fd12884539b41d5a88f838d773",
+ "links": {
+ "self": "http://example.com/identity/v3/credentials/" +
+ "7ef4faa904ae7b8b4ddc7bad15b05ee359dad7d7a9b" +
+ "82861d4ad92fdbbb2eb4e"
+ },
+ "blob": "{\"access\": \"7d7559359b57419eb5f5f5dcd65ab57d\"," +
+ " \"secret\": \"570652bcf8c2483c86eb29e9734eed3c\"," +
+ " \"trust_id\": null}",
+ "project_id": "731fc6f265cd486d900f16e84c5cb594",
+ "type": "ec2",
+ "id": "7ef4faa904ae7b8b4ddc7bad15b05ee359dad7d7a9b82861"
+ },
+ ],
+ "links": {
+ "self": "http://example.com/identity/v3/credentials",
+ "previous": None,
+ "next": None
+ }
+ }
+
+ def setUp(self):
+ super(TestCredentialsClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.client = credentials_client.CredentialsClient(fake_auth,
+ 'identity',
+ 'regionOne')
+
+ def _test_create_credential(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.create_credential,
+ 'tempest.lib.common.rest_client.RestClient.post',
+ self.FAKE_CREATE_CREDENTIAL,
+ bytes_body, status=201)
+
+ def _test_show_credential(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.show_credential,
+ 'tempest.lib.common.rest_client.RestClient.get',
+ self.FAKE_INFO_CREDENTIAL,
+ bytes_body,
+ credential_id="207e9b76935efc03804d3dd6ab52d22e9b22a0711e4ada4f")
+
+ def _test_update_credential(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.update_credential,
+ 'tempest.lib.common.rest_client.RestClient.patch',
+ self.FAKE_INFO_CREDENTIAL,
+ bytes_body,
+ credential_id="207e9b76935efc03804d3dd6ab52d22e9b22a0711e4ada4f")
+
+ def _test_list_credentials(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.list_credentials,
+ 'tempest.lib.common.rest_client.RestClient.get',
+ self.FAKE_LIST_CREDENTIALS,
+ bytes_body)
+
+ def test_create_credential_with_str_body(self):
+ self._test_create_credential()
+
+ def test_create_credential_with_bytes_body(self):
+ self._test_create_credential(bytes_body=True)
+
+ def test_show_credential_with_str_body(self):
+ self._test_show_credential()
+
+ def test_show_credential_with_bytes_body(self):
+ self._test_show_credential(bytes_body=True)
+
+ def test_update_credential_with_str_body(self):
+ self._test_update_credential()
+
+ def test_update_credential_with_bytes_body(self):
+ self._test_update_credential(bytes_body=True)
+
+ def test_list_credentials_with_str_body(self):
+ self._test_list_credentials()
+
+ def test_list_credentials_with_bytes_body(self):
+ self._test_list_credentials(bytes_body=True)
+
+ def test_delete_credential(self):
+ self.check_service_client_function(
+ self.client.delete_credential,
+ 'tempest.lib.common.rest_client.RestClient.delete',
+ {},
+ credential_id="207e9b76935efc03804d3dd6ab52d22e9b22a0711e4ada4f",
+ status=204)
diff --git a/tempest/tests/lib/services/identity/v3/test_inherited_roles_client.py b/tempest/tests/lib/services/identity/v3/test_inherited_roles_client.py
new file mode 100644
index 0000000..9da3cce
--- /dev/null
+++ b/tempest/tests/lib/services/identity/v3/test_inherited_roles_client.py
@@ -0,0 +1,220 @@
+# Copyright 2016 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.lib.services.identity.v3 import inherited_roles_client
+from tempest.tests.lib import fake_auth_provider
+from tempest.tests.lib.services import base
+
+
+class TestInheritedRolesClient(base.BaseServiceTest):
+ FAKE_LIST_INHERITED_ROLES = {
+ "roles": [
+ {
+ "id": "1",
+ "name": "test",
+ "links": "example.com"
+ },
+ {
+ "id": "2",
+ "name": "test2",
+ "links": "example.com"
+ }
+ ]
+ }
+
+ def setUp(self):
+ super(TestInheritedRolesClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.client = inherited_roles_client.InheritedRolesClient(
+ fake_auth, 'identity', 'regionOne')
+
+ def _test_create_inherited_role_on_domains_user(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.create_inherited_role_on_domains_user,
+ 'tempest.lib.common.rest_client.RestClient.put',
+ {},
+ bytes_body,
+ domain_id="b344506af7644f6794d9cb316600b020",
+ user_id="123",
+ role_id="1234",
+ status=204)
+
+ def _test_list_inherited_project_role_for_user_on_domain(
+ self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.list_inherited_project_role_for_user_on_domain,
+ 'tempest.lib.common.rest_client.RestClient.get',
+ self.FAKE_LIST_INHERITED_ROLES,
+ bytes_body,
+ domain_id="b344506af7644f6794d9cb316600b020",
+ user_id="123")
+
+ def _test_create_inherited_role_on_domains_group(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.create_inherited_role_on_domains_group,
+ 'tempest.lib.common.rest_client.RestClient.put',
+ {},
+ bytes_body,
+ domain_id="b344506af7644f6794d9cb316600b020",
+ group_id="123",
+ role_id="1234",
+ status=204)
+
+ def _test_list_inherited_project_role_for_group_on_domain(
+ self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.list_inherited_project_role_for_group_on_domain,
+ 'tempest.lib.common.rest_client.RestClient.get',
+ self.FAKE_LIST_INHERITED_ROLES,
+ bytes_body,
+ domain_id="b344506af7644f6794d9cb316600b020",
+ group_id="123")
+
+ def _test_create_inherited_role_on_projects_user(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.create_inherited_role_on_projects_user,
+ 'tempest.lib.common.rest_client.RestClient.put',
+ {},
+ bytes_body,
+ project_id="b344506af7644f6794d9cb316600b020",
+ user_id="123",
+ role_id="1234",
+ status=204)
+
+ def _test_create_inherited_role_on_projects_group(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.create_inherited_role_on_projects_group,
+ 'tempest.lib.common.rest_client.RestClient.put',
+ {},
+ bytes_body,
+ project_id="b344506af7644f6794d9cb316600b020",
+ group_id="123",
+ role_id="1234",
+ status=204)
+
+ def test_create_inherited_role_on_domains_user_with_str_body(self):
+ self._test_create_inherited_role_on_domains_user()
+
+ def test_create_inherited_role_on_domains_user_with_bytes_body(self):
+ self._test_create_inherited_role_on_domains_user(bytes_body=True)
+
+ def test_create_inherited_role_on_domains_group_with_str_body(self):
+ self._test_create_inherited_role_on_domains_group()
+
+ def test_create_inherited_role_on_domains_group_with_bytes_body(self):
+ self._test_create_inherited_role_on_domains_group(bytes_body=True)
+
+ def test_create_inherited_role_on_projects_user_with_str_body(self):
+ self._test_create_inherited_role_on_projects_user()
+
+ def test_create_inherited_role_on_projects_group_with_bytes_body(self):
+ self._test_create_inherited_role_on_projects_group(bytes_body=True)
+
+ def test_list_inherited_project_role_for_user_on_domain_with_str_body(
+ self):
+ self._test_list_inherited_project_role_for_user_on_domain()
+
+ def test_list_inherited_project_role_for_user_on_domain_with_bytes_body(
+ self):
+ self._test_list_inherited_project_role_for_user_on_domain(
+ bytes_body=True)
+
+ def test_list_inherited_project_role_for_group_on_domain_with_str_body(
+ self):
+ self._test_list_inherited_project_role_for_group_on_domain()
+
+ def test_list_inherited_project_role_for_group_on_domain_with_bytes_body(
+ self):
+ self._test_list_inherited_project_role_for_group_on_domain(
+ bytes_body=True)
+
+ def test_delete_inherited_role_from_user_on_domain(self):
+ self.check_service_client_function(
+ self.client.delete_inherited_role_from_user_on_domain,
+ 'tempest.lib.common.rest_client.RestClient.delete',
+ {},
+ domain_id="b344506af7644f6794d9cb316600b020",
+ user_id="123",
+ role_id="1234",
+ status=204)
+
+ def test_check_user_inherited_project_role_on_domain(self):
+ self.check_service_client_function(
+ self.client.check_user_inherited_project_role_on_domain,
+ 'tempest.lib.common.rest_client.RestClient.head',
+ {},
+ domain_id="b344506af7644f6794d9cb316600b020",
+ user_id="123",
+ role_id="1234",
+ status=204)
+
+ def test_delete_inherited_role_from_group_on_domain(self):
+ self.check_service_client_function(
+ self.client.delete_inherited_role_from_group_on_domain,
+ 'tempest.lib.common.rest_client.RestClient.delete',
+ {},
+ domain_id="b344506af7644f6794d9cb316600b020",
+ group_id="123",
+ role_id="1234",
+ status=204)
+
+ def test_check_group_inherited_project_role_on_domain(self):
+ self.check_service_client_function(
+ self.client.check_group_inherited_project_role_on_domain,
+ 'tempest.lib.common.rest_client.RestClient.head',
+ {},
+ domain_id="b344506af7644f6794d9cb316600b020",
+ group_id="123",
+ role_id="1234",
+ status=204)
+
+ def test_delete_inherited_role_from_user_on_project(self):
+ self.check_service_client_function(
+ self.client.delete_inherited_role_from_user_on_project,
+ 'tempest.lib.common.rest_client.RestClient.delete',
+ {},
+ project_id="b344506af7644f6794d9cb316600b020",
+ user_id="123",
+ role_id="1234",
+ status=204)
+
+ def test_check_user_has_flag_on_inherited_to_project(self):
+ self.check_service_client_function(
+ self.client.check_user_has_flag_on_inherited_to_project,
+ 'tempest.lib.common.rest_client.RestClient.head',
+ {},
+ project_id="b344506af7644f6794d9cb316600b020",
+ user_id="123",
+ role_id="1234",
+ status=204)
+
+ def test_delete_inherited_role_from_group_on_project(self):
+ self.check_service_client_function(
+ self.client.delete_inherited_role_from_group_on_project,
+ 'tempest.lib.common.rest_client.RestClient.delete',
+ {},
+ project_id="b344506af7644f6794d9cb316600b020",
+ group_id="123",
+ role_id="1234",
+ status=204)
+
+ def test_check_group_has_flag_on_inherited_to_project(self):
+ self.check_service_client_function(
+ self.client.check_group_has_flag_on_inherited_to_project,
+ 'tempest.lib.common.rest_client.RestClient.head',
+ {},
+ project_id="b344506af7644f6794d9cb316600b020",
+ group_id="123",
+ role_id="1234",
+ status=204)
diff --git a/tempest/tests/lib/services/identity/v3/test_roles_client.py b/tempest/tests/lib/services/identity/v3/test_roles_client.py
new file mode 100644
index 0000000..bad1ef9
--- /dev/null
+++ b/tempest/tests/lib/services/identity/v3/test_roles_client.py
@@ -0,0 +1,313 @@
+# Copyright 2016 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.lib.services.identity.v3 import roles_client
+from tempest.tests.lib import fake_auth_provider
+from tempest.tests.lib.services import base
+
+
+class TestRolesClient(base.BaseServiceTest):
+ FAKE_ROLE_INFO = {
+ "role": {
+ "domain_id": "1",
+ "id": "1",
+ "name": "test",
+ "links": "example.com"
+ }
+ }
+
+ FAKE_LIST_ROLES = {
+ "roles": [
+ {
+ "domain_id": "1",
+ "id": "1",
+ "name": "test",
+ "links": "example.com"
+ },
+ {
+ "domain_id": "2",
+ "id": "2",
+ "name": "test2",
+ "links": "example.com"
+ }
+ ]
+ }
+
+ def setUp(self):
+ super(TestRolesClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.client = roles_client.RolesClient(fake_auth,
+ 'identity', 'regionOne')
+
+ def _test_create_role(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.create_role,
+ 'tempest.lib.common.rest_client.RestClient.post',
+ self.FAKE_ROLE_INFO,
+ bytes_body,
+ domain_id="1",
+ name="test",
+ status=201)
+
+ def _test_show_role(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.show_role,
+ 'tempest.lib.common.rest_client.RestClient.get',
+ self.FAKE_ROLE_INFO,
+ bytes_body,
+ role_id="1")
+
+ def _test_list_roles(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.list_roles,
+ 'tempest.lib.common.rest_client.RestClient.get',
+ self.FAKE_LIST_ROLES,
+ bytes_body)
+
+ def _test_update_role(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.update_role,
+ 'tempest.lib.common.rest_client.RestClient.patch',
+ self.FAKE_ROLE_INFO,
+ bytes_body,
+ role_id="1",
+ name="test")
+
+ def _test_create_user_role_on_project(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.create_user_role_on_project,
+ 'tempest.lib.common.rest_client.RestClient.put',
+ {},
+ bytes_body,
+ project_id="b344506af7644f6794d9cb316600b020",
+ user_id="123",
+ role_id="1234",
+ status=204)
+
+ def _test_create_user_role_on_domain(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.create_user_role_on_domain,
+ 'tempest.lib.common.rest_client.RestClient.put',
+ {},
+ bytes_body,
+ domain_id="b344506af7644f6794d9cb316600b020",
+ user_id="123",
+ role_id="1234",
+ status=204)
+
+ def _test_list_user_roles_on_project(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.list_user_roles_on_project,
+ 'tempest.lib.common.rest_client.RestClient.get',
+ self.FAKE_LIST_ROLES,
+ bytes_body,
+ project_id="b344506af7644f6794d9cb316600b020",
+ user_id="123")
+
+ def _test_list_user_roles_on_domain(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.list_user_roles_on_domain,
+ 'tempest.lib.common.rest_client.RestClient.get',
+ self.FAKE_LIST_ROLES,
+ bytes_body,
+ domain_id="b344506af7644f6794d9cb316600b020",
+ user_id="123")
+
+ def _test_create_group_role_on_project(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.create_group_role_on_project,
+ 'tempest.lib.common.rest_client.RestClient.put',
+ {},
+ bytes_body,
+ project_id="b344506af7644f6794d9cb316600b020",
+ group_id="123",
+ role_id="1234",
+ status=204)
+
+ def _test_create_group_role_on_domain(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.create_group_role_on_domain,
+ 'tempest.lib.common.rest_client.RestClient.put',
+ {},
+ bytes_body,
+ domain_id="b344506af7644f6794d9cb316600b020",
+ group_id="123",
+ role_id="1234",
+ status=204)
+
+ def _test_list_group_roles_on_project(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.list_group_roles_on_project,
+ 'tempest.lib.common.rest_client.RestClient.get',
+ self.FAKE_LIST_ROLES,
+ bytes_body,
+ project_id="b344506af7644f6794d9cb316600b020",
+ group_id="123")
+
+ def _test_list_group_roles_on_domain(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.list_group_roles_on_domain,
+ 'tempest.lib.common.rest_client.RestClient.get',
+ self.FAKE_LIST_ROLES,
+ bytes_body,
+ domain_id="b344506af7644f6794d9cb316600b020",
+ group_id="123")
+
+ def test_create_role_with_str_body(self):
+ self._test_create_role()
+
+ def test_create_role_with_bytes_body(self):
+ self._test_create_role(bytes_body=True)
+
+ def test_show_role_with_str_body(self):
+ self._test_show_role()
+
+ def test_show_role_with_bytes_body(self):
+ self._test_show_role(bytes_body=True)
+
+ def test_list_roles_with_str_body(self):
+ self._test_list_roles()
+
+ def test_list_roles_with_bytes_body(self):
+ self._test_list_roles(bytes_body=True)
+
+ def test_update_role_with_str_body(self):
+ self._test_update_role()
+
+ def test_update_role_with_bytes_body(self):
+ self._test_update_role(bytes_body=True)
+
+ def test_delete_role(self):
+ self.check_service_client_function(
+ self.client.delete_role,
+ 'tempest.lib.common.rest_client.RestClient.delete',
+ {},
+ role_id="1",
+ status=204)
+
+ def test_create_user_role_on_project_with_str_body(self):
+ self._test_create_user_role_on_project()
+
+ def test_create_user_role_on_project_with_bytes_body(self):
+ self._test_create_user_role_on_project(bytes_body=True)
+
+ def test_create_user_role_on_domain_with_str_body(self):
+ self._test_create_user_role_on_domain()
+
+ def test_create_user_role_on_domain_with_bytes_body(self):
+ self._test_create_user_role_on_domain(bytes_body=True)
+
+ def test_create_group_role_on_domain_with_str_body(self):
+ self._test_create_group_role_on_domain()
+
+ def test_create_group_role_on_domain_with_bytes_body(self):
+ self._test_create_group_role_on_domain(bytes_body=True)
+
+ def test_list_user_roles_on_project_with_str_body(self):
+ self._test_list_user_roles_on_project()
+
+ def test_list_user_roles_on_project_with_bytes_body(self):
+ self._test_list_user_roles_on_project(bytes_body=True)
+
+ def test_list_user_roles_on_domain_with_str_body(self):
+ self._test_list_user_roles_on_domain()
+
+ def test_list_user_roles_on_domain_with_bytes_body(self):
+ self._test_list_user_roles_on_domain(bytes_body=True)
+
+ def test_list_group_roles_on_domain_with_str_body(self):
+ self._test_list_group_roles_on_domain()
+
+ def test_list_group_roles_on_domain_with_bytes_body(self):
+ self._test_list_group_roles_on_domain(bytes_body=True)
+
+ def test_delete_role_from_user_on_project(self):
+ self.check_service_client_function(
+ self.client.delete_role_from_user_on_project,
+ 'tempest.lib.common.rest_client.RestClient.delete',
+ {},
+ project_id="b344506af7644f6794d9cb316600b020",
+ user_id="123",
+ role_id="1234",
+ status=204)
+
+ def test_delete_role_from_user_on_domain(self):
+ self.check_service_client_function(
+ self.client.delete_role_from_user_on_domain,
+ 'tempest.lib.common.rest_client.RestClient.delete',
+ {},
+ domain_id="b344506af7644f6794d9cb316600b020",
+ user_id="123",
+ role_id="1234",
+ status=204)
+
+ def test_delete_role_from_group_on_project(self):
+ self.check_service_client_function(
+ self.client.delete_role_from_group_on_project,
+ 'tempest.lib.common.rest_client.RestClient.delete',
+ {},
+ project_id="b344506af7644f6794d9cb316600b020",
+ group_id="123",
+ role_id="1234",
+ status=204)
+
+ def test_delete_role_from_group_on_domain(self):
+ self.check_service_client_function(
+ self.client.delete_role_from_group_on_domain,
+ 'tempest.lib.common.rest_client.RestClient.delete',
+ {},
+ domain_id="b344506af7644f6794d9cb316600b020",
+ group_id="123",
+ role_id="1234",
+ status=204)
+
+ def test_check_user_role_existence_on_project(self):
+ self.check_service_client_function(
+ self.client.check_user_role_existence_on_project,
+ 'tempest.lib.common.rest_client.RestClient.head',
+ {},
+ project_id="b344506af7644f6794d9cb316600b020",
+ user_id="123",
+ role_id="1234",
+ status=204)
+
+ def test_check_user_role_existence_on_domain(self):
+ self.check_service_client_function(
+ self.client.check_user_role_existence_on_domain,
+ 'tempest.lib.common.rest_client.RestClient.head',
+ {},
+ domain_id="b344506af7644f6794d9cb316600b020",
+ user_id="123",
+ role_id="1234",
+ status=204)
+
+ def test_check_role_from_group_on_project_existence(self):
+ self.check_service_client_function(
+ self.client.check_role_from_group_on_project_existence,
+ 'tempest.lib.common.rest_client.RestClient.head',
+ {},
+ project_id="b344506af7644f6794d9cb316600b020",
+ group_id="123",
+ role_id="1234",
+ status=204)
+
+ def test_check_role_from_group_on_domain_existence(self):
+ self.check_service_client_function(
+ self.client.check_role_from_group_on_domain_existence,
+ 'tempest.lib.common.rest_client.RestClient.head',
+ {},
+ domain_id="b344506af7644f6794d9cb316600b020",
+ group_id="123",
+ role_id="1234",
+ status=204)
diff --git a/tempest/tests/lib/services/identity/v3/test_trusts_client.py b/tempest/tests/lib/services/identity/v3/test_trusts_client.py
new file mode 100644
index 0000000..a1ca020
--- /dev/null
+++ b/tempest/tests/lib/services/identity/v3/test_trusts_client.py
@@ -0,0 +1,150 @@
+# Copyright 2016 Red Hat, Inc.
+#
+# 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.lib.services.identity.v3 import trusts_client
+from tempest.tests.lib import fake_auth_provider
+from tempest.tests.lib.services import base
+
+
+class TestTrustsClient(base.BaseServiceTest):
+ FAKE_CREATE_TRUST = {
+ "trust": {
+ "expires_at": "2013-02-27T18:30:59.999999Z",
+ "impersonation": True,
+ "allow_redelegation": True,
+ "project_id": "ddef321",
+ "roles": [
+ {
+ "name": "member"
+ }
+ ],
+ "trustee_user_id": "86c0d5",
+ "trustor_user_id": "a0fdfd"
+ }
+ }
+
+ FAKE_LIST_TRUSTS = {
+ "trusts": [
+ {
+ "id": "1ff900",
+ "expires_at":
+ "2013-02-27T18:30:59.999999Z",
+ "impersonation": True,
+ "links": {
+ "self":
+ "http://example.com/identity/v3/OS-TRUST/trusts/1ff900"
+ },
+ "project_id": "0f1233",
+ "trustee_user_id": "86c0d5",
+ "trustor_user_id": "a0fdfd"
+ },
+ {
+ "id": "f4513a",
+ "impersonation": False,
+ "links": {
+ "self":
+ "http://example.com/identity/v3/OS-TRUST/trusts/f45513a"
+ },
+ "project_id": "0f1233",
+ "trustee_user_id": "86c0d5",
+ "trustor_user_id": "3cd2ce"
+ }
+ ]
+ }
+
+ FAKE_TRUST_INFO = {
+ "trust": {
+ "id": "987fe8",
+ "expires_at": "2013-02-27T18:30:59.999999Z",
+ "impersonation": True,
+ "links": {
+ "self":
+ "http://example.com/identity/v3/OS-TRUST/trusts/987fe8"
+ },
+ "roles": [
+ {
+ "id": "ed7b78",
+ "links": {
+ "self":
+ "http://example.com/identity/v3/roles/ed7b78"
+ },
+ "name": "member"
+ }
+ ],
+ "roles_links": {
+ "next": None,
+ "previous": None,
+ "self":
+ "http://example.com/identity/v3/OS-TRUST/trusts/1ff900/roles"
+ },
+ "project_id": "0f1233",
+ "trustee_user_id": "be34d1",
+ "trustor_user_id": "56ae32"
+ }
+ }
+
+ def setUp(self):
+ super(TestTrustsClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.client = trusts_client.TrustsClient(fake_auth, 'identity',
+ 'regionOne')
+
+ def _test_create_trust(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.create_trust,
+ 'tempest.lib.common.rest_client.RestClient.post',
+ self.FAKE_CREATE_TRUST,
+ bytes_body,
+ status=201)
+
+ def _test_show_trust(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.show_trust,
+ 'tempest.lib.common.rest_client.RestClient.get',
+ self.FAKE_TRUST_INFO,
+ bytes_body,
+ trust_id="1ff900")
+
+ def _test_list_trusts(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.list_trusts,
+ 'tempest.lib.common.rest_client.RestClient.get',
+ self.FAKE_LIST_TRUSTS,
+ bytes_body)
+
+ def test_create_trust_with_str_body(self):
+ self._test_create_trust()
+
+ def test_create_trust_with_bytes_body(self):
+ self._test_create_trust(bytes_body=True)
+
+ def test_show_trust_with_str_body(self):
+ self._test_show_trust()
+
+ def test_show_trust_with_bytes_body(self):
+ self._test_show_trust(bytes_body=True)
+
+ def test_list_trusts_with_str_body(self):
+ self._test_list_trusts()
+
+ def test_list_trusts_with_bytes_body(self):
+ self._test_list_trusts(bytes_body=True)
+
+ def test_delete_trust(self):
+ self.check_service_client_function(
+ self.client.delete_trust,
+ 'tempest.lib.common.rest_client.RestClient.delete',
+ {},
+ trust_id="1ff900",
+ status=204)
diff --git a/tempest/tests/negative/test_negative_generators.py b/tempest/tests/negative/test_negative_generators.py
index 2e45ef7..7e1ee2c 100644
--- a/tempest/tests/negative/test_negative_generators.py
+++ b/tempest/tests/negative/test_negative_generators.py
@@ -107,7 +107,7 @@
def _validate_result(self, valid_schema, invalid_schema):
for k, v in six.iteritems(valid_schema):
- self.assertTrue(k in invalid_schema)
+ self.assertIn(k, invalid_schema)
def test_generator_mandatory_functions(self):
for data_type in self.types:
diff --git a/tempest/tests/services/object_storage/test_object_client.py b/tempest/tests/services/object_storage/test_object_client.py
index cd8c8f1..cc1dc1a 100644
--- a/tempest/tests/services/object_storage/test_object_client.py
+++ b/tempest/tests/services/object_storage/test_object_client.py
@@ -20,7 +20,7 @@
from tempest.lib import exceptions
from tempest.services.object_storage import object_client
from tempest.tests import base
-from tempest.tests import fake_auth_provider
+from tempest.tests.lib import fake_auth_provider
class TestObjectClient(base.TestCase):
diff --git a/tempest/tests/test_negative_rest_client.py b/tempest/tests/test_negative_rest_client.py
index 9d9c20f..05f9f3e 100644
--- a/tempest/tests/test_negative_rest_client.py
+++ b/tempest/tests/test_negative_rest_client.py
@@ -21,8 +21,8 @@
from tempest.common import negative_rest_client
from tempest import config
from tempest.tests import base
-from tempest.tests import fake_auth_provider
from tempest.tests import fake_config
+from tempest.tests.lib import fake_auth_provider
class TestNegativeRestClient(base.TestCase):
diff --git a/tools/generate-tempest-plugins-list.py b/tools/generate-tempest-plugins-list.py
index 03dbd9b..03e838e 100644
--- a/tools/generate-tempest-plugins-list.py
+++ b/tools/generate-tempest-plugins-list.py
@@ -48,6 +48,8 @@
def has_tempest_plugin(proj):
+ if proj.startswith('openstack/deb-'):
+ return False
r = requests.get(
"https://git.openstack.org/cgit/%s/plain/setup.cfg" % proj)
p = re.compile('^tempest\.test_plugins', re.M)