Merge "Make v1 list_images use **kwargs & doc string update"
diff --git a/setup.cfg b/setup.cfg
index b94a4f4..cc3a365 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -33,10 +33,12 @@
tempest-account-generator = tempest.cmd.account_generator:main
tempest = tempest.cmd.main:main
tempest.cm =
+ account-generator = tempest.cmd.account_generator:TempestAccountGenerator
init = tempest.cmd.init:TempestInit
cleanup = tempest.cmd.cleanup:TempestCleanup
run-stress = tempest.cmd.run_stress:TempestRunStress
list-plugins = tempest.cmd.list_plugins:TempestListPlugins
+ verify-config = tempest.cmd.verify_tempest_config:TempestVerifyConfig
oslo.config.opts =
tempest.config = tempest.config:list_opts
diff --git a/tempest/api/compute/admin/test_live_migration.py b/tempest/api/compute/admin/test_live_migration.py
index 7c4c30c..653a3cd 100644
--- a/tempest/api/compute/admin/test_live_migration.py
+++ b/tempest/api/compute/admin/test_live_migration.py
@@ -79,11 +79,6 @@
def _get_server_status(self, server_id):
return self._get_server_details(server_id)['status']
- def _create_server(self, volume_backed=False):
- server = self.create_test_server(wait_until="ACTIVE",
- volume_backed=volume_backed)
- return server['id']
-
def _volume_clean_up(self, server_id, volume_id):
body = self.volumes_client.show_volume(volume_id)['volume']
if body['status'] == 'in-use':
@@ -103,7 +98,8 @@
volume_backed, *block* migration is not used.
"""
# Live migrate an instance to another host
- server_id = self._create_server(volume_backed=volume_backed)
+ server_id = self.create_test_server(wait_until="ACTIVE",
+ volume_backed=volume_backed)['id']
actual_host = self._get_host_for_server(server_id)
target_host = self._get_host_other_than(actual_host)
@@ -153,7 +149,7 @@
block_migrate_cinder_iscsi,
'Block Live migration not configured for iSCSI')
def test_iscsi_volume(self):
- server_id = self._create_server()
+ server_id = self.create_test_server(wait_until="ACTIVE")['id']
actual_host = self._get_host_for_server(server_id)
target_host = self._get_host_other_than(actual_host)
diff --git a/tempest/api/compute/admin/test_servers.py b/tempest/api/compute/admin/test_servers.py
index fd6f105..49c7318 100644
--- a/tempest/api/compute/admin/test_servers.py
+++ b/tempest/api/compute/admin/test_servers.py
@@ -15,6 +15,7 @@
from tempest_lib import decorators
from tempest.api.compute import base
+from tempest.common import compute
from tempest.common import fixed_network
from tempest.common.utils import data_utils
from tempest.common import waiters
@@ -104,16 +105,14 @@
def test_list_servers_filter_by_exist_host(self):
# Filter the list of servers by existent host
name = data_utils.rand_name('server')
- flavor = self.flavor_ref
- image_id = self.image_ref
network = self.get_tenant_network()
network_kwargs = fixed_network.set_networks_kwarg(network)
- test_server = self.client.create_server(name=name, imageRef=image_id,
- flavorRef=flavor,
- **network_kwargs)['server']
+ # We need to create the server as an admin, so we can't use
+ # self.create_test_server() here as this method creates the server
+ # in the "primary" (i.e non-admin) tenant.
+ test_server, _ = compute.create_test_server(
+ self.os_adm, wait_until="ACTIVE", name=name, **network_kwargs)
self.addCleanup(self.client.delete_server, test_server['id'])
- waiters.wait_for_server_status(self.client,
- test_server['id'], 'ACTIVE')
server = self.client.show_server(test_server['id'])['server']
self.assertEqual(server['status'], 'ACTIVE')
hostname = server[self._host_key]
diff --git a/tempest/api/compute/admin/test_servers_on_multinodes.py b/tempest/api/compute/admin/test_servers_on_multinodes.py
new file mode 100644
index 0000000..814a876
--- /dev/null
+++ b/tempest/api/compute/admin/test_servers_on_multinodes.py
@@ -0,0 +1,68 @@
+# 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.api.compute import base
+from tempest import config
+from tempest import test
+
+CONF = config.CONF
+
+
+class ServersOnMultiNodesTest(base.BaseV2ComputeAdminTest):
+
+ @classmethod
+ def skip_checks(cls):
+ super(ServersOnMultiNodesTest, cls).skip_checks()
+
+ if CONF.compute.min_compute_nodes < 2:
+ raise cls.skipException(
+ "Less than 2 compute nodes, skipping multi-nodes test.")
+
+ def _get_host(self, server_id):
+ return self.os_adm.servers_client.show_server(
+ server_id)['server']['OS-EXT-SRV-ATTR:host']
+
+ @test.idempotent_id('26a9d5df-6890-45f2-abc4-a659290cb130')
+ def test_create_servers_on_same_host(self):
+ server01 = self.create_test_server(wait_until='ACTIVE')['id']
+
+ hints = {'same_host': server01}
+ server02 = self.create_test_server(scheduler_hints=hints,
+ wait_until='ACTIVE')['id']
+ host01 = self._get_host(server01)
+ host02 = self._get_host(server02)
+ self.assertEqual(host01, host02)
+
+ @test.idempotent_id('cc7ca884-6e3e-42a3-a92f-c522fcf25e8e')
+ def test_create_servers_on_different_hosts(self):
+ server01 = self.create_test_server(wait_until='ACTIVE')['id']
+
+ hints = {'different_host': server01}
+ server02 = self.create_test_server(scheduler_hints=hints,
+ wait_until='ACTIVE')['id']
+ host01 = self._get_host(server01)
+ host02 = self._get_host(server02)
+ self.assertNotEqual(host01, host02)
+
+ @test.idempotent_id('7869cc84-d661-4e14-9f00-c18cdc89cf57')
+ def test_create_servers_on_different_hosts_with_list_of_servers(self):
+ server01 = self.create_test_server(wait_until='ACTIVE')['id']
+
+ # This scheduler-hint supports list of servers also.
+ hints = {'different_host': [server01]}
+ server02 = self.create_test_server(scheduler_hints=hints,
+ wait_until='ACTIVE')['id']
+ host01 = self._get_host(server01)
+ host02 = self._get_host(server02)
+ self.assertNotEqual(host01, host02)
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 8a27929..6d19ca7 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -329,11 +329,12 @@
except Exception:
LOG.exception('Failed to delete server %s' % server_id)
+ cls.password = data_utils.rand_password()
server = cls.create_test_server(
validatable,
wait_until='ACTIVE',
+ adminPass=cls.password,
**kwargs)
- cls.password = server['adminPass']
return server['id']
@classmethod
diff --git a/tempest/api/compute/images/test_list_image_filters.py b/tempest/api/compute/images/test_list_image_filters.py
index 49d9bc8..af840cc 100644
--- a/tempest/api/compute/images/test_list_image_filters.py
+++ b/tempest/api/compute/images/test_list_image_filters.py
@@ -15,7 +15,6 @@
import time
-from oslo_log import log as logging
import six
import testtools
@@ -27,8 +26,6 @@
CONF = config.CONF
-LOG = logging.getLogger(__name__)
-
class ListImageFiltersTestJSON(base.BaseV2ComputeTest):
diff --git a/tempest/api/compute/keypairs/base.py b/tempest/api/compute/keypairs/base.py
index 15f231b..ebfb724 100644
--- a/tempest/api/compute/keypairs/base.py
+++ b/tempest/api/compute/keypairs/base.py
@@ -27,10 +27,12 @@
def _delete_keypair(self, keypair_name):
self.client.delete_keypair(keypair_name)
- def _create_keypair(self, keypair_name, pub_key=None):
+ def _create_keypair(self, keypair_name, pub_key=None, keypair_type=None):
kwargs = {'name': keypair_name}
if pub_key:
kwargs.update({'public_key': pub_key})
+ if keypair_type:
+ kwargs.update({'type': keypair_type})
body = self.client.create_keypair(**kwargs)['keypair']
self.addCleanup(self._delete_keypair, keypair_name)
return body
diff --git a/tempest/api/compute/keypairs/test_keypairs.py b/tempest/api/compute/keypairs/test_keypairs.py
index d10bf14..be6f615 100644
--- a/tempest/api/compute/keypairs/test_keypairs.py
+++ b/tempest/api/compute/keypairs/test_keypairs.py
@@ -19,6 +19,8 @@
class KeyPairsV2TestJSON(base.BaseKeypairTest):
+ max_microversion = '2.1'
+
@test.idempotent_id('1d1dbedb-d7a0-432a-9d09-83f543c3c19b')
def test_keypairs_create_list_delete(self):
# Keypairs created should be available in the response list
diff --git a/tempest/api/compute/keypairs/test_keypairs_v22.py b/tempest/api/compute/keypairs/test_keypairs_v22.py
new file mode 100644
index 0000000..997ef9b
--- /dev/null
+++ b/tempest/api/compute/keypairs/test_keypairs_v22.py
@@ -0,0 +1,51 @@
+# 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.api.compute.keypairs import test_keypairs
+from tempest.common.utils import data_utils
+from tempest import test
+
+
+class KeyPairsV22TestJSON(test_keypairs.KeyPairsV2TestJSON):
+ min_microversion = '2.2'
+ max_microversion = 'latest'
+
+ def _check_keypair_type(self, keypair, keypair_type):
+ if keypair_type is None:
+ keypair_type = 'ssh'
+ self.assertEqual(keypair_type, keypair['type'])
+
+ def _test_keypairs_create_list_show(self, keypair_type=None):
+ k_name = data_utils.rand_name('keypair')
+ keypair = self._create_keypair(k_name, keypair_type=keypair_type)
+ # Verify whether 'type' is present in keypair create response of
+ # version 2.2 and it is with default value 'ssh'.
+ self._check_keypair_type(keypair, keypair_type)
+ keypair_detail = self.client.show_keypair(k_name)['keypair']
+ self._check_keypair_type(keypair_detail, keypair_type)
+ fetched_list = self.client.list_keypairs()['keypairs']
+ for keypair in fetched_list:
+ # Verify whether 'type' is present in keypair list response of
+ # version 2.2 and it is with default value 'ssh'.
+ if keypair['keypair']['name'] == k_name:
+ self._check_keypair_type(keypair['keypair'], keypair_type)
+
+ @test.idempotent_id('8726fa85-7f98-4b20-af9e-f710a4f3391c')
+ def test_keypairsv22_create_list_show(self):
+ self._test_keypairs_create_list_show()
+
+ @test.idempotent_id('89d59d43-f735-441a-abcf-0601727f47b6')
+ def test_keypairsv22_create_list_show_with_type(self):
+ keypair_type = 'x509'
+ self._test_keypairs_create_list_show(keypair_type=keypair_type)
diff --git a/tempest/api/compute/servers/test_create_server.py b/tempest/api/compute/servers/test_create_server.py
index e1c22e5..f719bfc 100644
--- a/tempest/api/compute/servers/test_create_server.py
+++ b/tempest/api/compute/servers/test_create_server.py
@@ -50,6 +50,7 @@
cls.accessIPv4 = '1.1.1.1'
cls.accessIPv6 = '0000:0000:0000:0000:0000:babe:220.12.22.2'
cls.name = data_utils.rand_name('server')
+ cls.password = data_utils.rand_password()
disk_config = cls.disk_config
cls.server_initial = cls.create_test_server(
validatable=True,
@@ -58,8 +59,8 @@
metadata=cls.meta,
accessIPv4=cls.accessIPv4,
accessIPv6=cls.accessIPv6,
- disk_config=disk_config)
- cls.password = cls.server_initial['adminPass']
+ disk_config=disk_config,
+ adminPass=cls.password)
cls.server = (cls.client.show_server(cls.server_initial['id'])
['server'])
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index d7f0d75..66e85a6 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -172,11 +172,16 @@
self.assertEqual(new_name, server['name'])
if CONF.validation.run_validation:
- # TODO(jlanoux) add authentication with the provided password
+ # Authentication is attempted in the following order of priority:
+ # 1.The key passed in, if one was passed in.
+ # 2.Any key we can find through an SSH agent (if allowed).
+ # 3.Any "id_rsa", "id_dsa" or "id_ecdsa" key discoverable in
+ # ~/.ssh/ (if allowed).
+ # 4.Plain username/password auth, if a password was given.
linux_client = remote_client.RemoteClient(
self.get_server_ip(rebuilt_server),
self.ssh_user,
- self.password,
+ password,
self.validation_resources['keypair']['private_key'])
linux_client.validate_authentication()
diff --git a/tempest/api/compute/servers/test_server_personality.py b/tempest/api/compute/servers/test_server_personality.py
index c948f8c..dad8e90 100644
--- a/tempest/api/compute/servers/test_server_personality.py
+++ b/tempest/api/compute/servers/test_server_personality.py
@@ -14,6 +14,7 @@
# under the License.
import base64
+from tempest_lib.common.utils import data_utils
from tempest_lib import exceptions as lib_exc
from tempest.api.compute import base
@@ -55,14 +56,16 @@
file_path = '/test.txt'
personality = [{'path': file_path,
'contents': base64.b64encode(file_contents)}]
+ password = data_utils.rand_password()
created_server = self.create_test_server(personality=personality,
+ adminPass=password,
wait_until='ACTIVE',
validatable=True)
server = self.client.show_server(created_server['id'])['server']
if CONF.validation.run_validation:
linux_client = remote_client.RemoteClient(
self.get_server_ip(server),
- self.ssh_user, created_server['adminPass'],
+ self.ssh_user, password,
self.validation_resources['keypair']['private_key'])
self.assertEqual(file_contents,
linux_client.exec_command(
@@ -117,14 +120,16 @@
'path': path,
'contents': base64.b64encode(file_contents),
})
+ password = data_utils.rand_password()
created_server = self.create_test_server(personality=person,
+ adminPass=password,
wait_until='ACTIVE',
validatable=True)
server = self.client.show_server(created_server['id'])['server']
if CONF.validation.run_validation:
linux_client = remote_client.RemoteClient(
self.get_server_ip(server),
- self.ssh_user, created_server['adminPass'],
+ self.ssh_user, password,
self.validation_resources['keypair']['private_key'])
for i in person:
self.assertEqual(base64.b64decode(i['contents']),
diff --git a/tempest/api/compute/servers/test_server_rescue.py b/tempest/api/compute/servers/test_server_rescue.py
index 2296980..12b824f 100644
--- a/tempest/api/compute/servers/test_server_rescue.py
+++ b/tempest/api/compute/servers/test_server_rescue.py
@@ -52,10 +52,11 @@
name=cls.sg_name, description=cls.sg_desc)['security_group']
cls.sg_id = cls.sg['id']
+ cls.password = data_utils.rand_password()
# Server for positive tests
- server = cls.create_test_server(wait_until='BUILD')
+ server = cls.create_test_server(adminPass=cls.password,
+ wait_until='BUILD')
cls.server_id = server['id']
- cls.password = server['adminPass']
waiters.wait_for_server_status(cls.servers_client, cls.server_id,
'ACTIVE')
diff --git a/tempest/api/compute/servers/test_server_rescue_negative.py b/tempest/api/compute/servers/test_server_rescue_negative.py
index 65ad2f5..5afb4d1 100644
--- a/tempest/api/compute/servers/test_server_rescue_negative.py
+++ b/tempest/api/compute/servers/test_server_rescue_negative.py
@@ -43,14 +43,15 @@
def resource_setup(cls):
super(ServerRescueNegativeTestJSON, cls).resource_setup()
cls.device = CONF.compute.volume_device_name
-
+ cls.password = data_utils.rand_password()
+ rescue_password = data_utils.rand_password()
# Server for negative tests
- server = cls.create_test_server(wait_until='BUILD')
- resc_server = cls.create_test_server(wait_until='ACTIVE')
+ server = cls.create_test_server(adminPass=cls.password,
+ wait_until='BUILD')
+ resc_server = cls.create_test_server(adminPass=rescue_password,
+ wait_until='ACTIVE')
cls.server_id = server['id']
- cls.password = server['adminPass']
cls.rescue_id = resc_server['id']
- rescue_password = resc_server['adminPass']
cls.servers_client.rescue_server(
cls.rescue_id, adminPass=rescue_password)
diff --git a/tempest/api/compute/servers/test_servers.py b/tempest/api/compute/servers/test_servers.py
index 8e2fbf1..2f79d47 100644
--- a/tempest/api/compute/servers/test_servers.py
+++ b/tempest/api/compute/servers/test_servers.py
@@ -13,11 +13,16 @@
# License for the specific language governing permissions and limitations
# under the License.
+import testtools
+
from tempest.api.compute import base
from tempest.common.utils import data_utils
from tempest.common import waiters
+from tempest import config
from tempest import test
+CONF = config.CONF
+
class ServersTestJSON(base.BaseV2ComputeTest):
@@ -31,6 +36,9 @@
super(ServersTestJSON, self).tearDown()
@test.idempotent_id('b92d5ec7-b1dd-44a2-87e4-45e888c46ef0')
+ @testtools.skipUnless(CONF.compute_feature_enabled.
+ enable_instance_password,
+ 'Instance password not available.')
def test_create_server_with_admin_password(self):
# If an admin password is provided on server creation, the server's
# root password should be set to that password.
diff --git a/tempest/api/compute/volumes/test_attach_volume.py b/tempest/api/compute/volumes/test_attach_volume.py
index 468c79a..01a8e58 100644
--- a/tempest/api/compute/volumes/test_attach_volume.py
+++ b/tempest/api/compute/volumes/test_attach_volume.py
@@ -63,11 +63,11 @@
def _create_and_attach(self):
# Start a server and wait for it to become ready
- admin_pass = self.image_ssh_password
+ self.admin_pass = self.image_ssh_password
self.server = self.create_test_server(
validatable=True,
wait_until='ACTIVE',
- adminPass=admin_pass)
+ adminPass=self.admin_pass)
# Record addresses so that we can ssh later
self.server['addresses'] = self.servers_client.list_addresses(
@@ -108,7 +108,7 @@
linux_client = remote_client.RemoteClient(
self.get_server_ip(self.server),
self.image_ssh_user,
- self.server['adminPass'],
+ self.admin_pass,
self.validation_resources['keypair']['private_key'])
partitions = linux_client.get_partitions()
@@ -127,7 +127,7 @@
linux_client = remote_client.RemoteClient(
self.get_server_ip(self.server),
self.image_ssh_user,
- self.server['adminPass'],
+ self.admin_pass,
self.validation_resources['keypair']['private_key'])
partitions = linux_client.get_partitions()
diff --git a/tempest/api/compute/volumes/test_volume_snapshots.py b/tempest/api/compute/volumes/test_volume_snapshots.py
index a00c0ba..f42d153 100644
--- a/tempest/api/compute/volumes/test_volume_snapshots.py
+++ b/tempest/api/compute/volumes/test_volume_snapshots.py
@@ -50,7 +50,7 @@
s_name = data_utils.rand_name('Snapshot')
# Create snapshot
snapshot = self.snapshots_client.create_snapshot(
- volume['id'],
+ volume_id=volume['id'],
display_name=s_name)['snapshot']
def delete_snapshot(snapshot_id):
diff --git a/tempest/api/data_processing/base.py b/tempest/api/data_processing/base.py
index 4e88f65..b6d0c48 100644
--- a/tempest/api/data_processing/base.py
+++ b/tempest/api/data_processing/base.py
@@ -13,6 +13,7 @@
# under the License.
from collections import OrderedDict
+import copy
import six
from tempest_lib import exceptions as lib_exc
@@ -27,42 +28,93 @@
"""Default templates.
There should always be at least a master1 and a worker1 node
group template."""
-DEFAULT_TEMPLATES = {
- 'vanilla': OrderedDict([
- ('2.6.0', {
- 'NODES': {
- 'master1': {
- 'count': 1,
- 'node_processes': ['namenode', 'resourcemanager',
- 'hiveserver']
+BASE_VANILLA_DESC = {
+ 'NODES': {
+ 'master1': {
+ 'count': 1,
+ 'node_processes': ['namenode', 'resourcemanager',
+ 'hiveserver']
+ },
+ 'master2': {
+ 'count': 1,
+ 'node_processes': ['oozie', 'historyserver',
+ 'secondarynamenode']
+ },
+ 'worker1': {
+ 'count': 1,
+ 'node_processes': ['datanode', 'nodemanager'],
+ 'node_configs': {
+ 'MapReduce': {
+ 'yarn.app.mapreduce.am.resource.mb': 256,
+ 'yarn.app.mapreduce.am.command-opts': '-Xmx256m'
},
- 'master2': {
- 'count': 1,
- 'node_processes': ['oozie', 'historyserver',
- 'secondarynamenode']
- },
- 'worker1': {
- 'count': 1,
- 'node_processes': ['datanode', 'nodemanager'],
- 'node_configs': {
- 'MapReduce': {
- 'yarn.app.mapreduce.am.resource.mb': 256,
- 'yarn.app.mapreduce.am.command-opts': '-Xmx256m'
- },
- 'YARN': {
- 'yarn.scheduler.minimum-allocation-mb': 256,
- 'yarn.scheduler.maximum-allocation-mb': 1024,
- 'yarn.nodemanager.vmem-check-enabled': False
- }
- }
- }
- },
- 'cluster_configs': {
- 'HDFS': {
- 'dfs.replication': 1
+ 'YARN': {
+ 'yarn.scheduler.minimum-allocation-mb': 256,
+ 'yarn.scheduler.maximum-allocation-mb': 1024,
+ 'yarn.nodemanager.vmem-check-enabled': False
}
}
- }),
+ }
+ },
+ 'cluster_configs': {
+ 'HDFS': {
+ 'dfs.replication': 1
+ }
+ }
+}
+
+BASE_SPARK_DESC = {
+ 'NODES': {
+ 'master1': {
+ 'count': 1,
+ 'node_processes': ['namenode', 'master']
+ },
+ 'worker1': {
+ 'count': 1,
+ 'node_processes': ['datanode', 'slave']
+ }
+ },
+ 'cluster_configs': {
+ 'HDFS': {
+ 'dfs.replication': 1
+ }
+ }
+}
+
+BASE_CDH_DESC = {
+ 'NODES': {
+ 'master1': {
+ 'count': 1,
+ 'node_processes': ['CLOUDERA_MANAGER']
+ },
+ 'master2': {
+ 'count': 1,
+ 'node_processes': ['HDFS_NAMENODE',
+ 'YARN_RESOURCEMANAGER']
+ },
+ 'master3': {
+ 'count': 1,
+ 'node_processes': ['OOZIE_SERVER', 'YARN_JOBHISTORY',
+ 'HDFS_SECONDARYNAMENODE',
+ 'HIVE_METASTORE', 'HIVE_SERVER2']
+ },
+ 'worker1': {
+ 'count': 1,
+ 'node_processes': ['YARN_NODEMANAGER', 'HDFS_DATANODE']
+ }
+ },
+ 'cluster_configs': {
+ 'HDFS': {
+ 'dfs_replication': 1
+ }
+ }
+}
+
+
+DEFAULT_TEMPLATES = {
+ 'vanilla': OrderedDict([
+ ('2.6.0', copy.deepcopy(BASE_VANILLA_DESC)),
+ ('2.7.1', copy.deepcopy(BASE_VANILLA_DESC)),
('1.2.1', {
'NODES': {
'master1': {
@@ -123,81 +175,13 @@
})
]),
'spark': OrderedDict([
- ('1.0.0', {
- 'NODES': {
- 'master1': {
- 'count': 1,
- 'node_processes': ['namenode', 'master']
- },
- 'worker1': {
- 'count': 1,
- 'node_processes': ['datanode', 'slave']
- }
- },
- 'cluster_configs': {
- 'HDFS': {
- 'dfs.replication': 1
- }
- }
- })
+ ('1.0.0', copy.deepcopy(BASE_SPARK_DESC)),
+ ('1.3.1', copy.deepcopy(BASE_SPARK_DESC))
]),
'cdh': OrderedDict([
- ('5.3.0', {
- 'NODES': {
- 'master1': {
- 'count': 1,
- 'node_processes': ['CLOUDERA_MANAGER']
- },
- 'master2': {
- 'count': 1,
- 'node_processes': ['HDFS_NAMENODE',
- 'YARN_RESOURCEMANAGER']
- },
- 'master3': {
- 'count': 1,
- 'node_processes': ['OOZIE_SERVER', 'YARN_JOBHISTORY',
- 'HDFS_SECONDARYNAMENODE',
- 'HIVE_METASTORE', 'HIVE_SERVER2']
- },
- 'worker1': {
- 'count': 1,
- 'node_processes': ['YARN_NODEMANAGER', 'HDFS_DATANODE']
- }
- },
- 'cluster_configs': {
- 'HDFS': {
- 'dfs_replication': 1
- }
- }
- }),
- ('5', {
- 'NODES': {
- 'master1': {
- 'count': 1,
- 'node_processes': ['CLOUDERA_MANAGER']
- },
- 'master2': {
- 'count': 1,
- 'node_processes': ['HDFS_NAMENODE',
- 'YARN_RESOURCEMANAGER']
- },
- 'master3': {
- 'count': 1,
- 'node_processes': ['OOZIE_SERVER', 'YARN_JOBHISTORY',
- 'HDFS_SECONDARYNAMENODE',
- 'HIVE_METASTORE', 'HIVE_SERVER2']
- },
- 'worker1': {
- 'count': 1,
- 'node_processes': ['YARN_NODEMANAGER', 'HDFS_DATANODE']
- }
- },
- 'cluster_configs': {
- 'HDFS': {
- 'dfs_replication': 1
- }
- }
- })
+ ('5.4.0', copy.deepcopy(BASE_CDH_DESC)),
+ ('5.3.0', copy.deepcopy(BASE_CDH_DESC)),
+ ('5', copy.deepcopy(BASE_CDH_DESC))
]),
'mapr': OrderedDict([
('4.0.1.mrv2', {
diff --git a/tempest/api/database/base.py b/tempest/api/database/base.py
index f4c1881..01e05db 100644
--- a/tempest/api/database/base.py
+++ b/tempest/api/database/base.py
@@ -13,13 +13,10 @@
# License for the specific language governing permissions and limitations
# under the License.
-from oslo_log import log as logging
-
from tempest import config
import tempest.test
CONF = config.CONF
-LOG = logging.getLogger(__name__)
class BaseDatabaseTest(tempest.test.BaseTestCase):
diff --git a/tempest/api/identity/admin/v2/test_tokens.py b/tempest/api/identity/admin/v2/test_tokens.py
index fdb5a5a..ee04420 100644
--- a/tempest/api/identity/admin/v2/test_tokens.py
+++ b/tempest/api/identity/admin/v2/test_tokens.py
@@ -30,8 +30,8 @@
tenant = self.tenants_client.create_tenant(tenant_name)['tenant']
self.data.tenants.append(tenant)
# second:create a user
- user = self.client.create_user(user_name, user_password,
- tenant['id'], '')['user']
+ user = self.users_client.create_user(user_name, user_password,
+ tenant['id'], '')['user']
self.data.users.append(user)
# then get a token for the user
body = self.token_client.auth(user_name,
@@ -62,8 +62,8 @@
user_password = data_utils.rand_password()
tenant_id = None # No default tenant so will get unscoped token.
email = ''
- user = self.client.create_user(user_name, user_password,
- tenant_id, email)['user']
+ user = self.users_client.create_user(user_name, user_password,
+ tenant_id, email)['user']
self.data.users.append(user)
# Create a couple tenants.
diff --git a/tempest/api/identity/admin/v2/test_users.py b/tempest/api/identity/admin/v2/test_users.py
index d886524..4497575 100644
--- a/tempest/api/identity/admin/v2/test_users.py
+++ b/tempest/api/identity/admin/v2/test_users.py
@@ -34,9 +34,9 @@
def test_create_user(self):
# Create a user
self.data.setup_test_tenant()
- user = self.client.create_user(self.alt_user, self.alt_password,
- self.data.tenant['id'],
- self.alt_email)['user']
+ user = self.users_client.create_user(self.alt_user, self.alt_password,
+ self.data.tenant['id'],
+ self.alt_email)['user']
self.data.users.append(user)
self.assertEqual(self.alt_user, user['name'])
@@ -45,9 +45,10 @@
# Create a user with enabled : False
self.data.setup_test_tenant()
name = data_utils.rand_name('test_user')
- user = self.client.create_user(name, self.alt_password,
- self.data.tenant['id'],
- self.alt_email, enabled=False)['user']
+ user = self.users_client.create_user(name, self.alt_password,
+ self.data.tenant['id'],
+ self.alt_email,
+ enabled=False)['user']
self.data.users.append(user)
self.assertEqual(name, user['name'])
self.assertEqual(False, user['enabled'])
@@ -58,22 +59,22 @@
# Test case to check if updating of user attributes is successful.
test_user = data_utils.rand_name('test_user')
self.data.setup_test_tenant()
- user = self.client.create_user(test_user, self.alt_password,
- self.data.tenant['id'],
- self.alt_email)['user']
+ user = self.users_client.create_user(test_user, self.alt_password,
+ self.data.tenant['id'],
+ self.alt_email)['user']
# Delete the User at the end of this method
- self.addCleanup(self.client.delete_user, user['id'])
+ self.addCleanup(self.users_client.delete_user, user['id'])
# Updating user details with new values
u_name2 = data_utils.rand_name('user2')
u_email2 = u_name2 + '@testmail.tm'
- update_user = self.client.update_user(user['id'], name=u_name2,
- email=u_email2,
- enabled=False)['user']
+ update_user = self.users_client.update_user(user['id'], name=u_name2,
+ email=u_email2,
+ enabled=False)['user']
self.assertEqual(u_name2, update_user['name'])
self.assertEqual(u_email2, update_user['email'])
self.assertEqual(False, update_user['enabled'])
# GET by id after updating
- updated_user = self.client.show_user(user['id'])['user']
+ updated_user = self.users_client.show_user(user['id'])['user']
# Assert response body of GET after updating
self.assertEqual(u_name2, updated_user['name'])
self.assertEqual(u_email2, updated_user['email'])
@@ -84,10 +85,10 @@
# Delete a user
test_user = data_utils.rand_name('test_user')
self.data.setup_test_tenant()
- user = self.client.create_user(test_user, self.alt_password,
- self.data.tenant['id'],
- self.alt_email)['user']
- self.client.delete_user(user['id'])
+ user = self.users_client.create_user(test_user, self.alt_password,
+ self.data.tenant['id'],
+ self.alt_email)['user']
+ self.users_client.delete_user(user['id'])
@test.idempotent_id('aca696c3-d645-4f45-b728-63646045beb1')
def test_user_authentication(self):
@@ -121,7 +122,7 @@
def test_get_users(self):
# Get a list of users and find the test user
self.data.setup_test_user()
- users = self.client.list_users()['users']
+ users = self.users_client.list_users()['users']
self.assertThat([u['name'] for u in users],
matchers.Contains(self.data.test_user),
"Could not find %s" % self.data.test_user)
@@ -134,16 +135,16 @@
fetched_user_ids = list()
password1 = data_utils.rand_password()
alt_tenant_user1 = data_utils.rand_name('tenant_user1')
- user1 = self.client.create_user(alt_tenant_user1, password1,
- self.data.tenant['id'],
- 'user1@123')['user']
+ user1 = self.users_client.create_user(alt_tenant_user1, password1,
+ self.data.tenant['id'],
+ 'user1@123')['user']
user_ids.append(user1['id'])
self.data.users.append(user1)
password2 = data_utils.rand_password()
alt_tenant_user2 = data_utils.rand_name('tenant_user2')
- user2 = self.client.create_user(alt_tenant_user2, password2,
- self.data.tenant['id'],
- 'user2@123')['user']
+ user2 = self.users_client.create_user(alt_tenant_user2, password2,
+ self.data.tenant['id'],
+ 'user2@123')['user']
user_ids.append(user2['id'])
self.data.users.append(user2)
# List of users for the respective tenant ID
@@ -175,9 +176,9 @@
alt_user2 = data_utils.rand_name('second_user')
alt_password2 = data_utils.rand_password()
- second_user = self.client.create_user(alt_user2, alt_password2,
- self.data.tenant['id'],
- 'user2@123')['user']
+ second_user = self.users_client.create_user(alt_user2, alt_password2,
+ self.data.tenant['id'],
+ 'user2@123')['user']
user_ids.append(second_user['id'])
self.data.users.append(second_user)
role = self.roles_client.assign_user_role(tenant['id'],
@@ -201,7 +202,7 @@
self.data.setup_test_user()
# Updating the user with new password
new_pass = data_utils.rand_password()
- update_user = self.client.update_user_password(
+ update_user = self.users_client.update_user_password(
self.data.user['id'], password=new_pass)['user']
self.assertEqual(update_user['id'], self.data.user['id'])
diff --git a/tempest/api/identity/admin/v2/test_users_negative.py b/tempest/api/identity/admin/v2/test_users_negative.py
index 8fa5a36..c5248fd 100644
--- a/tempest/api/identity/admin/v2/test_users_negative.py
+++ b/tempest/api/identity/admin/v2/test_users_negative.py
@@ -37,8 +37,9 @@
# Non-administrator should not be authorized to create a user
self.data.setup_test_tenant()
self.assertRaises(lib_exc.Forbidden,
- self.non_admin_client.create_user, self.alt_user,
- self.alt_password, self.data.tenant['id'],
+ self.non_admin_users_client.create_user,
+ self.alt_user, self.alt_password,
+ self.data.tenant['id'],
self.alt_email)
@test.attr(type=['negative'])
@@ -46,8 +47,8 @@
def test_create_user_with_empty_name(self):
# User with an empty name should not be created
self.data.setup_test_tenant()
- self.assertRaises(lib_exc.BadRequest, self.client.create_user, '',
- self.alt_password, self.data.tenant['id'],
+ self.assertRaises(lib_exc.BadRequest, self.users_client.create_user,
+ '', self.alt_password, self.data.tenant['id'],
self.alt_email)
@test.attr(type=['negative'])
@@ -55,7 +56,7 @@
def test_create_user_with_name_length_over_255(self):
# Length of user name filed should be restricted to 255 characters
self.data.setup_test_tenant()
- self.assertRaises(lib_exc.BadRequest, self.client.create_user,
+ self.assertRaises(lib_exc.BadRequest, self.users_client.create_user,
'a' * 256, self.alt_password,
self.data.tenant['id'], self.alt_email)
@@ -64,7 +65,7 @@
def test_create_user_with_duplicate_name(self):
# Duplicate user should not be created
self.data.setup_test_user()
- self.assertRaises(lib_exc.Conflict, self.client.create_user,
+ self.assertRaises(lib_exc.Conflict, self.users_client.create_user,
self.data.test_user, self.data.test_password,
self.data.tenant['id'], self.data.test_email)
@@ -72,7 +73,7 @@
@test.idempotent_id('0132cc22-7c4f-42e1-9e50-ac6aad31d59a')
def test_create_user_for_non_existent_tenant(self):
# Attempt to create a user in a non-existent tenant should fail
- self.assertRaises(lib_exc.NotFound, self.client.create_user,
+ self.assertRaises(lib_exc.NotFound, self.users_client.create_user,
self.alt_user, self.alt_password, '49ffgg99999',
self.alt_email)
@@ -85,7 +86,7 @@
token = self.client.auth_provider.get_token()
# Delete the token from database
self.client.delete_token(token)
- self.assertRaises(lib_exc.Unauthorized, self.client.create_user,
+ self.assertRaises(lib_exc.Unauthorized, self.users_client.create_user,
self.alt_user, self.alt_password,
self.data.tenant['id'], self.alt_email)
@@ -98,7 +99,7 @@
# Attempt to create a user with valid enabled para should fail
self.data.setup_test_tenant()
name = data_utils.rand_name('test_user')
- self.assertRaises(lib_exc.BadRequest, self.client.create_user,
+ self.assertRaises(lib_exc.BadRequest, self.users_client.create_user,
name, self.alt_password,
self.data.tenant['id'],
self.alt_email, enabled=3)
@@ -109,7 +110,7 @@
# Attempt to update a user non-existent user should fail
user_name = data_utils.rand_name('user')
non_existent_id = str(uuid.uuid4())
- self.assertRaises(lib_exc.NotFound, self.client.update_user,
+ self.assertRaises(lib_exc.NotFound, self.users_client.update_user,
non_existent_id, name=user_name)
@test.attr(type=['negative'])
@@ -121,7 +122,7 @@
token = self.client.auth_provider.get_token()
# Delete the token from database
self.client.delete_token(token)
- self.assertRaises(lib_exc.Unauthorized, self.client.update_user,
+ self.assertRaises(lib_exc.Unauthorized, self.users_client.update_user,
self.alt_user)
# Unset the token to allow further tests to generate a new token
@@ -133,7 +134,8 @@
# Non-administrator should not be authorized to update user
self.data.setup_test_tenant()
self.assertRaises(lib_exc.Forbidden,
- self.non_admin_client.update_user, self.alt_user)
+ self.non_admin_users_client.update_user,
+ self.alt_user)
@test.attr(type=['negative'])
@test.idempotent_id('d45195d5-33ed-41b9-a452-7d0d6a00f6e9')
@@ -141,14 +143,14 @@
# Non-administrator user should not be authorized to delete a user
self.data.setup_test_user()
self.assertRaises(lib_exc.Forbidden,
- self.non_admin_client.delete_user,
+ self.non_admin_users_client.delete_user,
self.data.user['id'])
@test.attr(type=['negative'])
@test.idempotent_id('7cc82f7e-9998-4f89-abae-23df36495867')
def test_delete_non_existent_user(self):
# Attempt to delete a non-existent user should fail
- self.assertRaises(lib_exc.NotFound, self.client.delete_user,
+ self.assertRaises(lib_exc.NotFound, self.users_client.delete_user,
'junk12345123')
@test.attr(type=['negative'])
@@ -160,7 +162,7 @@
token = self.client.auth_provider.get_token()
# Delete the token from database
self.client.delete_token(token)
- self.assertRaises(lib_exc.Unauthorized, self.client.delete_user,
+ self.assertRaises(lib_exc.Unauthorized, self.users_client.delete_user,
self.alt_user)
# Unset the token to allow further tests to generate a new token
@@ -222,7 +224,7 @@
# Non-administrator user should not be authorized to get user list
self.data.setup_test_user()
self.assertRaises(lib_exc.Forbidden,
- self.non_admin_client.list_users)
+ self.non_admin_users_client.list_users)
@test.attr(type=['negative'])
@test.idempotent_id('a73591ec-1903-4ffe-be42-282b39fefc9d')
@@ -230,7 +232,7 @@
# Request to get list of users without a valid token should fail
token = self.client.auth_provider.get_token()
self.client.delete_token(token)
- self.assertRaises(lib_exc.Unauthorized, self.client.list_users)
+ self.assertRaises(lib_exc.Unauthorized, self.users_client.list_users)
self.client.auth_provider.clear_auth()
@test.attr(type=['negative'])
diff --git a/tempest/api/identity/base.py b/tempest/api/identity/base.py
index d68a204..1ad8b92 100644
--- a/tempest/api/identity/base.py
+++ b/tempest/api/identity/base.py
@@ -30,7 +30,7 @@
@classmethod
def disable_user(cls, user_name):
user = cls.get_user_by_name(user_name)
- cls.client.enable_disable_user(user['id'], enabled=False)
+ cls.users_client.enable_disable_user(user['id'], enabled=False)
@classmethod
def disable_tenant(cls, tenant_name):
@@ -39,7 +39,7 @@
@classmethod
def get_user_by_name(cls, name):
- users = cls.client.list_users()['users']
+ users = cls.users_client.list_users()['users']
user = [u for u in users if u['name'] == name]
if len(user) > 0:
return user[0]
@@ -77,6 +77,7 @@
cls.non_admin_token_client = cls.os.token_client
cls.non_admin_tenants_client = cls.os.tenants_public_client
cls.non_admin_roles_client = cls.os.roles_public_client
+ cls.non_admin_users_client = cls.os.users_public_client
@classmethod
def resource_setup(cls):
@@ -101,12 +102,14 @@
cls.non_admin_tenants_client = cls.os.tenants_client
cls.roles_client = cls.os_adm.roles_client
cls.non_admin_roles_client = cls.os.roles_client
+ cls.users_client = cls.os_adm.users_client
+ cls.non_admin_users_client = cls.os.users_client
@classmethod
def resource_setup(cls):
super(BaseIdentityV2AdminTest, cls).resource_setup()
cls.data = DataGenerator(cls.client, cls.tenants_client,
- cls.roles_client)
+ cls.roles_client, cls.users_client)
@classmethod
def resource_cleanup(cls):
@@ -191,11 +194,13 @@
class DataGenerator(object):
- def __init__(self, client, tenants_client=None, roles_client=None):
+ def __init__(self, client, tenants_client=None, roles_client=None,
+ users_client=None):
self.client = client
# TODO(dmellado) split Datagenerator for v2 and v3
self.tenants_client = tenants_client
self.roles_client = roles_client
+ self.users_client = users_client
self.users = []
self.tenants = []
self.roles = []
@@ -219,10 +224,10 @@
self.test_user = data_utils.rand_name('test_user')
self.test_password = data_utils.rand_password()
self.test_email = self.test_user + '@testmail.tm'
- self.user = self.client.create_user(self.test_user,
- self.test_password,
- self.tenant['id'],
- self.test_email)['user']
+ self.user = self.users_client.create_user(self.test_user,
+ self.test_password,
+ self.tenant['id'],
+ self.test_email)['user']
self.users.append(self.user)
def setup_test_tenant(self):
@@ -296,7 +301,7 @@
# (e.g. delete_tenant) So we need to check resources existence
# before using client methods.
for user in self.users:
- self._try_wrapper(self.client.delete_user, user)
+ self._try_wrapper(self.users_client.delete_user, user)
for tenant in self.tenants:
self._try_wrapper(self.tenants_client.delete_tenant, tenant)
for role in self.roles:
diff --git a/tempest/api/identity/v2/test_ec2_credentials.py b/tempest/api/identity/v2/test_ec2_credentials.py
index 88161a3..bd49326 100644
--- a/tempest/api/identity/v2/test_ec2_credentials.py
+++ b/tempest/api/identity/v2/test_ec2_credentials.py
@@ -36,12 +36,12 @@
@test.idempotent_id('b580fab9-7ae9-46e8-8138-417260cb6f9f')
def test_create_ec2_credentials(self):
"""Create user ec2 credentials."""
- resp = self.non_admin_client.create_user_ec2_credentials(
+ resp = self.non_admin_users_client.create_user_ec2_credentials(
self.creds.credentials.user_id,
tenant_id=self.creds.credentials.tenant_id)["credential"]
access = resp['access']
self.addCleanup(
- self.non_admin_client.delete_user_ec2_credentials,
+ self.non_admin_users_client.delete_user_ec2_credentials,
self.creds.credentials.user_id, access)
self.assertNotEmpty(resp['access'])
self.assertNotEmpty(resp['secret'])
@@ -54,24 +54,24 @@
created_creds = []
fetched_creds = []
# create first ec2 credentials
- creds1 = self.non_admin_client.create_user_ec2_credentials(
+ creds1 = self.non_admin_users_client.create_user_ec2_credentials(
self.creds.credentials.user_id,
tenant_id=self.creds.credentials.tenant_id)["credential"]
created_creds.append(creds1['access'])
# create second ec2 credentials
- creds2 = self.non_admin_client.create_user_ec2_credentials(
+ creds2 = self.non_admin_users_client.create_user_ec2_credentials(
self.creds.credentials.user_id,
tenant_id=self.creds.credentials.tenant_id)["credential"]
created_creds.append(creds2['access'])
# add credentials to be cleaned up
self.addCleanup(
- self.non_admin_client.delete_user_ec2_credentials,
+ self.non_admin_users_client.delete_user_ec2_credentials,
self.creds.credentials.user_id, creds1['access'])
self.addCleanup(
- self.non_admin_client.delete_user_ec2_credentials,
+ self.non_admin_users_client.delete_user_ec2_credentials,
self.creds.credentials.user_id, creds2['access'])
# get the list of user ec2 credentials
- resp = self.non_admin_client.list_user_ec2_credentials(
+ resp = self.non_admin_users_client.list_user_ec2_credentials(
self.creds.credentials.user_id)["credentials"]
fetched_creds = [cred['access'] for cred in resp]
# created credentials should be in a fetched list
@@ -84,14 +84,14 @@
@test.idempotent_id('cb284075-b613-440d-83ca-fe0b33b3c2b8')
def test_show_ec2_credentials(self):
"""Get the definite user ec2 credentials."""
- resp = self.non_admin_client.create_user_ec2_credentials(
+ resp = self.non_admin_users_client.create_user_ec2_credentials(
self.creds.credentials.user_id,
tenant_id=self.creds.credentials.tenant_id)["credential"]
self.addCleanup(
- self.non_admin_client.delete_user_ec2_credentials,
+ self.non_admin_users_client.delete_user_ec2_credentials,
self.creds.credentials.user_id, resp['access'])
- ec2_creds = self.non_admin_client.show_user_ec2_credentials(
+ ec2_creds = self.non_admin_users_client.show_user_ec2_credentials(
self.creds.credentials.user_id, resp['access']
)["credential"]
for key in ['access', 'secret', 'user_id', 'tenant_id']:
@@ -100,14 +100,14 @@
@test.idempotent_id('6aba0d4c-b76b-4e46-aa42-add79bc1551d')
def test_delete_ec2_credentials(self):
"""Delete user ec2 credentials."""
- resp = self.non_admin_client.create_user_ec2_credentials(
+ resp = self.non_admin_users_client.create_user_ec2_credentials(
self.creds.credentials.user_id,
tenant_id=self.creds.credentials.tenant_id)["credential"]
access = resp['access']
- self.non_admin_client.delete_user_ec2_credentials(
+ self.non_admin_users_client.delete_user_ec2_credentials(
self.creds.credentials.user_id, access)
self.assertRaises(
lib_exc.NotFound,
- self.non_admin_client.show_user_ec2_credentials,
+ self.non_admin_users_client.show_user_ec2_credentials,
self.creds.credentials.user_id,
access)
diff --git a/tempest/api/identity/v2/test_users.py b/tempest/api/identity/v2/test_users.py
index 98a2e68..a59a1a0 100644
--- a/tempest/api/identity/v2/test_users.py
+++ b/tempest/api/identity/v2/test_users.py
@@ -41,8 +41,9 @@
# we need new non-admin Identity Client with new credentials, since
# current non_admin_client token will be revoked after updating
# password
- self.non_admin_client_for_cleanup = copy.copy(self.non_admin_client)
- self.non_admin_client_for_cleanup.auth_provider = (
+ self.non_admin_users_client_for_cleanup = copy.copy(
+ self.non_admin_users_client)
+ self.non_admin_users_client_for_cleanup.auth_provider = (
manager.get_auth_provider(self.new_creds))
user_id = self.creds.credentials.user_id
old_pass = self.creds.credentials.password
@@ -50,10 +51,10 @@
# to change password back. important for allow_tenant_isolation = false
self.addCleanup(
- self.non_admin_client_for_cleanup.update_user_own_password,
+ self.non_admin_users_client_for_cleanup.update_user_own_password,
user_id, original_password=new_pass, password=old_pass)
# user updates own password
- self.non_admin_client.update_user_own_password(
+ self.non_admin_users_client.update_user_own_password(
user_id, password=new_pass, original_password=old_pass)
# TODO(lbragstad): Sleeping after the response status has been checked
# and the body loaded as JSON allows requests to fail-fast. The sleep
@@ -72,7 +73,7 @@
# authorize with old token should lead to Unauthorized
self.assertRaises(exceptions.Unauthorized,
self.non_admin_token_client.auth_token,
- self.non_admin_client.token)
+ self.non_admin_users_client.token)
# authorize with old password should lead to Unauthorized
self.assertRaises(exceptions.Unauthorized,
diff --git a/tempest/api/image/base.py b/tempest/api/image/base.py
index 18d0446..ade7b67 100644
--- a/tempest/api/image/base.py
+++ b/tempest/api/image/base.py
@@ -12,7 +12,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-from oslo_log import log as logging
from six import moves
from tempest_lib import exceptions as lib_exc
@@ -22,8 +21,6 @@
CONF = config.CONF
-LOG = logging.getLogger(__name__)
-
class BaseImageTest(tempest.test.BaseTestCase):
"""Base test class for Image API tests."""
diff --git a/tempest/api/image/v1/test_images.py b/tempest/api/image/v1/test_images.py
index 64f3174..1a84d06 100644
--- a/tempest/api/image/v1/test_images.py
+++ b/tempest/api/image/v1/test_images.py
@@ -18,11 +18,27 @@
from tempest.api.image import base
from tempest.common.utils import data_utils
from tempest import config
+from tempest import exceptions
from tempest import test
CONF = config.CONF
+def get_container_and_disk_format():
+ a_formats = ['ami', 'ari', 'aki']
+
+ container_format = CONF.image.container_formats[0]
+ disk_format = CONF.image.disk_formats[0]
+
+ if container_format in a_formats and container_format != disk_format:
+ msg = ("The container format and the disk format don't match. "
+ "Contaiter format: %(container)s, Disk format: %(disk)s." %
+ {'container': container_format, 'disk': disk_format})
+ raise exceptions.InvalidConfiguration(message=msg)
+
+ return container_format, disk_format
+
+
class CreateRegisterImagesTest(base.BaseV1ImageTest):
"""Here we test the registration and creation of images."""
@@ -30,9 +46,10 @@
def test_register_then_upload(self):
# Register, then upload an image
properties = {'prop1': 'val1'}
+ container_format, disk_format = get_container_and_disk_format()
body = self.create_image(name='New Name',
- container_format='bare',
- disk_format='raw',
+ container_format=container_format,
+ disk_format=disk_format,
is_public=False,
properties=properties)
self.assertIn('id', body)
@@ -52,9 +69,10 @@
@test.idempotent_id('69da74d9-68a9-404b-9664-ff7164ccb0f5')
def test_register_remote_image(self):
# Register a new remote image
+ container_format, disk_format = get_container_and_disk_format()
body = self.create_image(name='New Remote Image',
- container_format='bare',
- disk_format='raw', is_public=False,
+ container_format=container_format,
+ disk_format=disk_format, is_public=False,
location=CONF.image.http_image,
properties={'key1': 'value1',
'key2': 'value2'})
@@ -68,9 +86,10 @@
@test.idempotent_id('6d0e13a7-515b-460c-b91f-9f4793f09816')
def test_register_http_image(self):
+ container_format, disk_format = get_container_and_disk_format()
body = self.create_image(name='New Http Image',
- container_format='bare',
- disk_format='raw', is_public=False,
+ container_format=container_format,
+ disk_format=disk_format, is_public=False,
copy_from=CONF.image.http_image)
self.assertIn('id', body)
image_id = body.get('id')
@@ -82,10 +101,11 @@
@test.idempotent_id('05b19d55-140c-40d0-b36b-fafd774d421b')
def test_register_image_with_min_ram(self):
# Register an image with min ram
+ container_format, disk_format = get_container_and_disk_format()
properties = {'prop1': 'val1'}
body = self.create_image(name='New_image_with_min_ram',
- container_format='bare',
- disk_format='raw',
+ container_format=container_format,
+ disk_format=disk_format,
is_public=False,
min_ram=40,
properties=properties)
@@ -103,22 +123,51 @@
"""Here we test the listing of image information"""
@classmethod
+ def skip_checks(cls):
+ super(ListImagesTest, cls).skip_checks()
+ if (len(CONF.image.container_formats) < 2
+ or len(CONF.image.disk_formats) < 2):
+ skip_msg = ("%s skipped as multiple container formats "
+ "or disk formats are not available." % cls.__name__)
+ raise cls.skipException(skip_msg)
+
+ @classmethod
def resource_setup(cls):
super(ListImagesTest, cls).resource_setup()
# We add a few images here to test the listing functionality of
# the images API
- img1 = cls._create_remote_image('one', 'bare', 'raw')
- img2 = cls._create_remote_image('two', 'ami', 'ami')
- img3 = cls._create_remote_image('dup', 'bare', 'raw')
- img4 = cls._create_remote_image('dup', 'bare', 'raw')
- img5 = cls._create_standard_image('1', 'ami', 'ami', 42)
- img6 = cls._create_standard_image('2', 'ami', 'ami', 142)
- img7 = cls._create_standard_image('33', 'bare', 'raw', 142)
- img8 = cls._create_standard_image('33', 'bare', 'raw', 142)
+ a_formats = ['ami', 'ari', 'aki']
+
+ (cls.container_format,
+ cls.container_format_alt) = CONF.image.container_formats[:2]
+ cls.disk_format, cls.disk_format_alt = CONF.image.disk_formats[:2]
+ if cls.container_format in a_formats:
+ cls.disk_format = cls.container_format
+ if cls.container_format_alt in a_formats:
+ cls.disk_format_alt = cls.container_format_alt
+
+ img1 = cls._create_remote_image('one', cls.container_format,
+ cls.disk_format)
+ img2 = cls._create_remote_image('two', cls.container_format_alt,
+ cls.disk_format_alt)
+ img3 = cls._create_remote_image('dup', cls.container_format,
+ cls.disk_format)
+ img4 = cls._create_remote_image('dup', cls.container_format,
+ cls.disk_format)
+ img5 = cls._create_standard_image('1', cls.container_format_alt,
+ cls.disk_format_alt, 42)
+ img6 = cls._create_standard_image('2', cls.container_format_alt,
+ cls.disk_format_alt, 142)
+ img7 = cls._create_standard_image('33', cls.container_format,
+ cls.disk_format, 142)
+ img8 = cls._create_standard_image('33', cls.container_format,
+ cls.disk_format, 142)
cls.created_set = set(cls.created_images)
- # 5x bare, 3x ami
- cls.bare_set = set((img1, img3, img4, img7, img8))
- cls.ami_set = set((img2, img5, img6))
+ # same container format
+ cls.same_container_format_set = set((img1, img3, img4, img7, img8))
+ # same disk format
+ cls.same_disk_format_set = set((img2, img5, img6))
+
# 1x with size 42
cls.size42_set = set((img5,))
# 3x with size 142
@@ -167,22 +216,25 @@
@test.idempotent_id('f1755589-63d6-4468-b098-589820eb4031')
def test_index_disk_format(self):
- images_list = self.client.list_images(disk_format='ami')['images']
+ images_list = self.client.list_images(
+ disk_format=self.disk_format_alt)['images']
for image in images_list:
- self.assertEqual(image['disk_format'], 'ami')
+ self.assertEqual(image['disk_format'], self.disk_format_alt)
result_set = set(map(lambda x: x['id'], images_list))
- self.assertTrue(self.ami_set <= result_set)
- self.assertFalse(self.created_set - self.ami_set <= result_set)
+ self.assertTrue(self.same_disk_format_set <= result_set)
+ self.assertFalse(self.created_set - self.same_disk_format_set
+ <= result_set)
@test.idempotent_id('2143655d-96d9-4bec-9188-8674206b4b3b')
def test_index_container_format(self):
- images_list = (self.client.list_images(container_format='bare')
- ['images'])
+ images_list = self.client.list_images(
+ container_format=self.container_format)['images']
for image in images_list:
- self.assertEqual(image['container_format'], 'bare')
+ self.assertEqual(image['container_format'], self.container_format)
result_set = set(map(lambda x: x['id'], images_list))
- self.assertTrue(self.bare_set <= result_set)
- self.assertFalse(self.created_set - self.bare_set <= result_set)
+ self.assertTrue(self.same_container_format_set <= result_set)
+ self.assertFalse(self.created_set - self.same_container_format_set
+ <= result_set)
@test.idempotent_id('feb32ac6-22bb-4a16-afd8-9454bb714b14')
def test_index_max_size(self):
@@ -231,7 +283,9 @@
@classmethod
def resource_setup(cls):
super(UpdateImageMetaTest, cls).resource_setup()
- cls.image_id = cls._create_standard_image('1', 'ami', 'ami', 42)
+ container_format, disk_format = get_container_and_disk_format()
+ cls.image_id = cls._create_standard_image('1', container_format,
+ disk_format, 42)
@classmethod
def _create_standard_image(cls, name, container_format,
diff --git a/tempest/api/messaging/base.py b/tempest/api/messaging/base.py
index 528fbea..a324c37 100644
--- a/tempest/api/messaging/base.py
+++ b/tempest/api/messaging/base.py
@@ -13,16 +13,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from oslo_log import log as logging
-
from tempest.common.utils import data_utils
from tempest import config
from tempest import test
CONF = config.CONF
-LOG = logging.getLogger(__name__)
-
class BaseMessagingTest(test.BaseTestCase):
diff --git a/tempest/api/messaging/test_claims.py b/tempest/api/messaging/test_claims.py
index 57b8c7f..99edde1 100644
--- a/tempest/api/messaging/test_claims.py
+++ b/tempest/api/messaging/test_claims.py
@@ -13,8 +13,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-import logging
-
from six.moves.urllib import parse as urlparse
from tempest_lib import decorators
@@ -24,7 +22,6 @@
from tempest import test
-LOG = logging.getLogger(__name__)
CONF = config.CONF
diff --git a/tempest/api/messaging/test_messages.py b/tempest/api/messaging/test_messages.py
index efbbf56..7f4182a 100644
--- a/tempest/api/messaging/test_messages.py
+++ b/tempest/api/messaging/test_messages.py
@@ -13,7 +13,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-import logging
from tempest.api.messaging import base
from tempest.common.utils import data_utils
@@ -21,7 +20,6 @@
from tempest import test
-LOG = logging.getLogger(__name__)
CONF = config.CONF
diff --git a/tempest/api/messaging/test_queues.py b/tempest/api/messaging/test_queues.py
index df49663..dcb5450 100644
--- a/tempest/api/messaging/test_queues.py
+++ b/tempest/api/messaging/test_queues.py
@@ -13,7 +13,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-import logging
from six import moves
from tempest_lib import exceptions as lib_exc
@@ -24,9 +23,6 @@
from tempest import test
-LOG = logging.getLogger(__name__)
-
-
class TestQueues(base.BaseMessagingTest):
@test.attr(type='smoke')
diff --git a/tempest/api/network/base.py b/tempest/api/network/base.py
index 2a1776a..81337f3 100644
--- a/tempest/api/network/base.py
+++ b/tempest/api/network/base.py
@@ -14,7 +14,6 @@
# under the License.
import netaddr
-from oslo_log import log as logging
from tempest_lib import exceptions as lib_exc
from tempest.common.utils import data_utils
@@ -24,8 +23,6 @@
CONF = config.CONF
-LOG = logging.getLogger(__name__)
-
class BaseNetworkTest(tempest.test.BaseTestCase):
"""Base class for the Neutron tests
diff --git a/tempest/api/network/test_metering_extensions.py b/tempest/api/network/test_metering_extensions.py
index 007ba3b..299700f 100644
--- a/tempest/api/network/test_metering_extensions.py
+++ b/tempest/api/network/test_metering_extensions.py
@@ -12,16 +12,11 @@
# License for the specific language governing permissions and limitations
# under the License.
-from oslo_log import log as logging
-
from tempest.api.network import base
from tempest.common.utils import data_utils
from tempest import test
-LOG = logging.getLogger(__name__)
-
-
class MeteringTestJSON(base.BaseAdminNetworkTest):
"""Tests the following operations in the Neutron API:
diff --git a/tempest/api/orchestration/base.py b/tempest/api/orchestration/base.py
index 4968835..c93b5ed 100644
--- a/tempest/api/orchestration/base.py
+++ b/tempest/api/orchestration/base.py
@@ -12,7 +12,6 @@
import os.path
-from oslo_log import log as logging
from tempest_lib import exceptions as lib_exc
import yaml
@@ -22,8 +21,6 @@
CONF = config.CONF
-LOG = logging.getLogger(__name__)
-
class BaseOrchestrationTest(tempest.test.BaseTestCase):
"""Base test case class for all Orchestration API tests."""
diff --git a/tempest/api/orchestration/stacks/test_environment.py b/tempest/api/orchestration/stacks/test_environment.py
index 0416bc7..9d2b425 100644
--- a/tempest/api/orchestration/stacks/test_environment.py
+++ b/tempest/api/orchestration/stacks/test_environment.py
@@ -10,8 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-import logging
-
from tempest.api.orchestration import base
from tempest.common.utils import data_utils
from tempest import config
@@ -19,7 +17,6 @@
CONF = config.CONF
-LOG = logging.getLogger(__name__)
class StackEnvironmentTest(base.BaseOrchestrationTest):
diff --git a/tempest/api/orchestration/stacks/test_limits.py b/tempest/api/orchestration/stacks/test_limits.py
index bb5b89d..2acf97b 100644
--- a/tempest/api/orchestration/stacks/test_limits.py
+++ b/tempest/api/orchestration/stacks/test_limits.py
@@ -10,8 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-import logging
-
from tempest_lib import exceptions as lib_exc
from tempest.api.orchestration import base
@@ -21,8 +19,6 @@
CONF = config.CONF
-LOG = logging.getLogger(__name__)
-
class TestServerStackLimits(base.BaseOrchestrationTest):
diff --git a/tempest/api/orchestration/stacks/test_non_empty_stack.py b/tempest/api/orchestration/stacks/test_non_empty_stack.py
index 4bc2c17..3be5bb6 100644
--- a/tempest/api/orchestration/stacks/test_non_empty_stack.py
+++ b/tempest/api/orchestration/stacks/test_non_empty_stack.py
@@ -10,8 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-import logging
-
from tempest.api.orchestration import base
from tempest.common.utils import data_utils
from tempest import config
@@ -19,8 +17,6 @@
CONF = config.CONF
-LOG = logging.getLogger(__name__)
-
class StacksTestJSON(base.BaseOrchestrationTest):
diff --git a/tempest/api/orchestration/stacks/test_nova_keypair_resources.py b/tempest/api/orchestration/stacks/test_nova_keypair_resources.py
index b4d7fa0..0400e76 100644
--- a/tempest/api/orchestration/stacks/test_nova_keypair_resources.py
+++ b/tempest/api/orchestration/stacks/test_nova_keypair_resources.py
@@ -10,17 +10,11 @@
# License for the specific language governing permissions and limitations
# under the License.
-
-import logging
-
from tempest.api.orchestration import base
from tempest.common.utils import data_utils
from tempest import test
-LOG = logging.getLogger(__name__)
-
-
class NovaKeyPairResourcesYAMLTest(base.BaseOrchestrationTest):
_tpl_type = 'yaml'
_resource = 'resources'
diff --git a/tempest/api/orchestration/stacks/test_soft_conf.py b/tempest/api/orchestration/stacks/test_soft_conf.py
index 34d93e4..ab45929 100644
--- a/tempest/api/orchestration/stacks/test_soft_conf.py
+++ b/tempest/api/orchestration/stacks/test_soft_conf.py
@@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-from oslo_log import log as logging
from tempest_lib import exceptions as lib_exc
from tempest.api.orchestration import base
@@ -18,7 +17,6 @@
from tempest import config
from tempest import test
-LOG = logging.getLogger(__name__)
CONF = config.CONF
diff --git a/tempest/api/orchestration/stacks/test_stacks.py b/tempest/api/orchestration/stacks/test_stacks.py
index f766b00..28463ab 100644
--- a/tempest/api/orchestration/stacks/test_stacks.py
+++ b/tempest/api/orchestration/stacks/test_stacks.py
@@ -10,16 +10,11 @@
# License for the specific language governing permissions and limitations
# under the License.
-from oslo_log import log as logging
-
from tempest.api.orchestration import base
from tempest.common.utils import data_utils
from tempest import test
-LOG = logging.getLogger(__name__)
-
-
class StacksTestJSON(base.BaseOrchestrationTest):
empty_template = "HeatTemplateFormatVersion: '2012-12-12'\n"
diff --git a/tempest/api/orchestration/stacks/test_volumes.py b/tempest/api/orchestration/stacks/test_volumes.py
index ae9a411..e51551b 100644
--- a/tempest/api/orchestration/stacks/test_volumes.py
+++ b/tempest/api/orchestration/stacks/test_volumes.py
@@ -10,8 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-import logging
-
from tempest_lib import exceptions as lib_exc
from tempest.api.orchestration import base
@@ -21,7 +19,6 @@
CONF = config.CONF
-LOG = logging.getLogger(__name__)
class CinderResourcesTest(base.BaseOrchestrationTest):
diff --git a/tempest/api/volume/admin/test_multi_backend.py b/tempest/api/volume/admin/test_multi_backend.py
index 8e43b00..60e6e6c 100644
--- a/tempest/api/volume/admin/test_multi_backend.py
+++ b/tempest/api/volume/admin/test_multi_backend.py
@@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-from oslo_log import log as logging
import six
from tempest.api.volume import base
from tempest.common.utils import data_utils
@@ -19,8 +18,6 @@
CONF = config.CONF
-LOG = logging.getLogger(__name__)
-
class VolumeMultiBackendV2Test(base.BaseVolumeAdminTest):
diff --git a/tempest/api/volume/admin/test_snapshots_actions.py b/tempest/api/volume/admin/test_snapshots_actions.py
index aa6bfdf..f2bf613 100644
--- a/tempest/api/volume/admin/test_snapshots_actions.py
+++ b/tempest/api/volume/admin/test_snapshots_actions.py
@@ -50,7 +50,7 @@
snap_name = data_utils.rand_name(cls.__name__ + '-Snapshot')
params = {cls.name_field: snap_name}
cls.snapshot = cls.client.create_snapshot(
- cls.volume['id'], **params)['snapshot']
+ volume_id=cls.volume['id'], **params)['snapshot']
cls.client.wait_for_snapshot_status(cls.snapshot['id'],
'available')
@@ -77,7 +77,7 @@
def _create_reset_and_force_delete_temp_snapshot(self, status=None):
# Create snapshot, reset snapshot status,
# and force delete temp snapshot
- temp_snapshot = self.create_snapshot(self.volume['id'])
+ temp_snapshot = self.create_snapshot(volume_id=self.volume['id'])
if status:
self.admin_snapshots_client.\
reset_snapshot_status(temp_snapshot['id'], status)
@@ -110,7 +110,7 @@
status = 'error'
progress_alias = self._get_progress_alias()
self.client.update_snapshot_status(self.snapshot['id'],
- status, progress)
+ status=status, progress=progress)
snapshot_get = self.admin_snapshots_client.show_snapshot(
self.snapshot['id'])['snapshot']
self.assertEqual(status, snapshot_get['status'])
diff --git a/tempest/api/volume/admin/test_volume_snapshot_quotas_negative.py b/tempest/api/volume/admin/test_volume_snapshot_quotas_negative.py
index ce0b618..c66207f 100644
--- a/tempest/api/volume/admin/test_volume_snapshot_quotas_negative.py
+++ b/tempest/api/volume/admin/test_volume_snapshot_quotas_negative.py
@@ -52,14 +52,14 @@
# NOTE(gfidente): no need to delete in tearDown as
# they are created using utility wrapper methods.
cls.volume = cls.create_volume()
- cls.snapshot = cls.create_snapshot(cls.volume['id'])
+ cls.snapshot = cls.create_snapshot(volume_id=cls.volume['id'])
@test.attr(type='negative')
@test.idempotent_id('02bbf63f-6c05-4357-9d98-2926a94064ff')
def test_quota_volume_snapshots(self):
self.assertRaises(lib_exc.OverLimit,
self.snapshots_client.create_snapshot,
- self.volume['id'])
+ volume_id=self.volume['id'])
@test.attr(type='negative')
@test.idempotent_id('c99a1ca9-6cdf-498d-9fdf-25832babef27')
@@ -74,7 +74,7 @@
**new_quota_set)
self.assertRaises(lib_exc.OverLimit,
self.snapshots_client.create_snapshot,
- self.volume['id'])
+ volume_id=self.volume['id'])
class VolumeSnapshotNegativeV1TestJSON(VolumeSnapshotQuotasNegativeV2TestJSON):
diff --git a/tempest/api/volume/admin/test_volumes_backup.py b/tempest/api/volume/admin/test_volumes_backup.py
index ed34a9b..4b2d3f3 100644
--- a/tempest/api/volume/admin/test_volumes_backup.py
+++ b/tempest/api/volume/admin/test_volumes_backup.py
@@ -13,7 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-from oslo_log import log as logging
from tempest_lib import decorators
from tempest.api.volume import base
@@ -22,7 +21,6 @@
from tempest import test
CONF = config.CONF
-LOG = logging.getLogger(__name__)
class VolumesBackupsV2Test(base.BaseVolumeAdminTest):
diff --git a/tempest/api/volume/base.py b/tempest/api/volume/base.py
index dc53450..cc906e5 100644
--- a/tempest/api/volume/base.py
+++ b/tempest/api/volume/base.py
@@ -13,7 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-from oslo_log import log as logging
from tempest_lib import exceptions as lib_exc
from tempest.common import compute
@@ -24,8 +23,6 @@
CONF = config.CONF
-LOG = logging.getLogger(__name__)
-
class BaseVolumeTest(tempest.test.BaseTestCase):
"""Base test case class for all Cinder API tests."""
@@ -123,7 +120,7 @@
def create_snapshot(cls, volume_id=1, **kwargs):
"""Wrapper utility that returns a test snapshot."""
snapshot = cls.snapshots_client.create_snapshot(
- volume_id, **kwargs)['snapshot']
+ volume_id=volume_id, **kwargs)['snapshot']
cls.snapshots.append(snapshot)
cls.snapshots_client.wait_for_snapshot_status(snapshot['id'],
'available')
diff --git a/tempest/api/volume/test_volumes_list.py b/tempest/api/volume/test_volumes_list.py
index b776494..38a5a80 100644
--- a/tempest/api/volume/test_volumes_list.py
+++ b/tempest/api/volume/test_volumes_list.py
@@ -15,15 +15,12 @@
# under the License.
import operator
-from oslo_log import log as logging
from testtools import matchers
from tempest.api.volume import base
from tempest.common.utils import data_utils
from tempest import test
-LOG = logging.getLogger(__name__)
-
class VolumesV2ListTestJSON(base.BaseVolumeTest):
# NOTE: This test creates a number of 1G volumes. To run successfully,
diff --git a/tempest/api/volume/test_volumes_snapshots.py b/tempest/api/volume/test_volumes_snapshots.py
index 856adcc..c79235a 100644
--- a/tempest/api/volume/test_volumes_snapshots.py
+++ b/tempest/api/volume/test_volumes_snapshots.py
@@ -10,14 +10,11 @@
# License for the specific language governing permissions and limitations
# under the License.
-from oslo_log import log as logging
-
from tempest.api.volume import base
from tempest.common.utils import data_utils
from tempest import config
from tempest import test
-LOG = logging.getLogger(__name__)
CONF = config.CONF
@@ -42,15 +39,15 @@
self.volumes_client.detach_volume(volume_id)
self.volumes_client.wait_for_volume_status(volume_id, 'available')
- def _list_by_param_values_and_assert(self, params, with_detail=False):
+ def _list_by_param_values_and_assert(self, with_detail=False, **params):
"""list or list_details with given params and validates result."""
if with_detail:
fetched_snap_list = self.snapshots_client.list_snapshots(
- detail=True, params=params)['snapshots']
+ detail=True, **params)['snapshots']
else:
fetched_snap_list = self.snapshots_client.list_snapshots(
- params=params)['snapshots']
+ **params)['snapshots']
# Validating params of fetched snapshots
for snap in fetched_snap_list:
@@ -135,16 +132,16 @@
# Verify list snapshots by display_name filter
params = {self.name_field: snapshot[self.name_field]}
- self._list_by_param_values_and_assert(params)
+ self._list_by_param_values_and_assert(**params)
# Verify list snapshots by status filter
params = {'status': 'available'}
- self._list_by_param_values_and_assert(params)
+ self._list_by_param_values_and_assert(**params)
# Verify list snapshots by status and display name filter
params = {'status': 'available',
self.name_field: snapshot[self.name_field]}
- self._list_by_param_values_and_assert(params)
+ self._list_by_param_values_and_assert(**params)
@test.idempotent_id('220a1022-1fcd-4a74-a7bd-6b859156cda2')
def test_snapshots_list_details_with_params(self):
@@ -157,14 +154,14 @@
# Verify list snapshot details by display_name filter
params = {self.name_field: snapshot[self.name_field]}
- self._list_by_param_values_and_assert(params, with_detail=True)
+ self._list_by_param_values_and_assert(with_detail=True, **params)
# Verify list snapshot details by status filter
params = {'status': 'available'}
- self._list_by_param_values_and_assert(params, with_detail=True)
+ self._list_by_param_values_and_assert(with_detail=True, **params)
# Verify list snapshot details by status and display name filter
params = {'status': 'available',
self.name_field: snapshot[self.name_field]}
- self._list_by_param_values_and_assert(params, with_detail=True)
+ self._list_by_param_values_and_assert(with_detail=True, **params)
@test.idempotent_id('677863d1-3142-456d-b6ac-9924f667a7f4')
def test_volume_from_snapshot(self):
diff --git a/tempest/api/volume/test_volumes_snapshots_negative.py b/tempest/api/volume/test_volumes_snapshots_negative.py
index b604360..d46c9b5 100644
--- a/tempest/api/volume/test_volumes_snapshots_negative.py
+++ b/tempest/api/volume/test_volumes_snapshots_negative.py
@@ -37,7 +37,7 @@
s_name = data_utils.rand_name('snap')
self.assertRaises(lib_exc.NotFound,
self.snapshots_client.create_snapshot,
- str(uuid.uuid4()), display_name=s_name)
+ volume_id=str(uuid.uuid4()), display_name=s_name)
@test.attr(type=['negative'])
@test.idempotent_id('bb9da53e-d335-4309-9c15-7e76fd5e4d6d')
@@ -46,7 +46,7 @@
s_name = data_utils.rand_name('snap')
self.assertRaises(lib_exc.NotFound,
self.snapshots_client.create_snapshot,
- None, display_name=s_name)
+ volume_id=None, display_name=s_name)
class VolumesV1SnapshotNegativeTestJSON(VolumesV2SnapshotNegativeTestJSON):
diff --git a/tempest/api_schema/response/compute/v2_2/__init__.py b/tempest/api_schema/response/compute/v2_2/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/api_schema/response/compute/v2_2/__init__.py
diff --git a/tempest/api_schema/response/compute/v2_2/keypairs.py b/tempest/api_schema/response/compute/v2_2/keypairs.py
new file mode 100644
index 0000000..5d8d24d
--- /dev/null
+++ b/tempest/api_schema/response/compute/v2_2/keypairs.py
@@ -0,0 +1,41 @@
+# 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.
+
+import copy
+
+from tempest.api_schema.response.compute.v2_1 import keypairs
+
+get_keypair = copy.deepcopy(keypairs.get_keypair)
+get_keypair['response_body']['properties']['keypair'][
+ 'properties'].update({'type': {'type': 'string'}})
+get_keypair['response_body']['properties']['keypair'][
+ 'required'].append('type')
+
+create_keypair = copy.deepcopy(keypairs.create_keypair)
+create_keypair['status_code'] = [201]
+create_keypair['response_body']['properties']['keypair'][
+ 'properties'].update({'type': {'type': 'string'}})
+create_keypair['response_body']['properties']['keypair'][
+ 'required'].append('type')
+
+delete_keypair = {
+ 'status_code': [204],
+}
+
+list_keypairs = copy.deepcopy(keypairs.list_keypairs)
+list_keypairs['response_body']['properties']['keypairs'][
+ 'items']['properties']['keypair'][
+ 'properties'].update({'type': {'type': 'string'}})
+list_keypairs['response_body']['properties']['keypairs'][
+ 'items']['properties']['keypair']['required'].append('type')
diff --git a/tempest/clients.py b/tempest/clients.py
index 0507ee8..2c40d0c 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -71,6 +71,13 @@
from tempest_lib.services.identity.v2.token_client import TokenClient
from tempest_lib.services.identity.v3.token_client import V3TokenClient
from tempest_lib.services.network.floating_ips_client import FloatingIPsClient
+from tempest_lib.services.network.metering_label_rules_client import \
+ MeteringLabelRulesClient
+from tempest_lib.services.network.metering_labels_client import \
+ MeteringLabelsClient
+from tempest_lib.services.network.networks_client import NetworksClient
+from tempest_lib.services.network.ports_client import PortsClient
+from tempest_lib.services.network.subnets_client import SubnetsClient
from tempest.common import negative_rest_client
from tempest import config
@@ -93,6 +100,8 @@
RolesClient
from tempest.services.identity.v2.json.tenants_client import \
TenantsClient
+from tempest.services.identity.v2.json.users_client import \
+ UsersClient
from tempest.services.identity.v3.json.credentials_client import \
CredentialsClient as CredentialsV3Client
from tempest.services.identity.v3.json.endpoints_client import \
@@ -112,19 +121,12 @@
MessagingClient
from tempest.services.network.json.agents_client import AgentsClient \
as NetworkAgentsClient
-from tempest.services.network.json.metering_label_rules_client import \
- MeteringLabelRulesClient
-from tempest.services.network.json.metering_labels_client import \
- MeteringLabelsClient
from tempest.services.network.json.network_client import NetworkClient
-from tempest.services.network.json.networks_client import NetworksClient
-from tempest.services.network.json.ports_client import PortsClient
from tempest.services.network.json.quotas_client import QuotasClient \
as NetworkQuotasClient
from tempest.services.network.json.security_groups_client import \
SecurityGroupsClient
from tempest.services.network.json.subnetpools_client import SubnetpoolsClient
-from tempest.services.network.json.subnets_client import SubnetsClient
from tempest.services.object_storage.account_client import AccountClient
from tempest.services.object_storage.container_client import ContainerClient
from tempest.services.object_storage.object_client import ObjectClient
@@ -484,6 +486,8 @@
**params_v2_admin)
self.roles_client = RolesClient(self.auth_provider,
**params_v2_admin)
+ self.users_client = UsersClient(self.auth_provider,
+ **params_v2_admin)
params_v2_public = params.copy()
params_v2_public['endpoint_type'] = (
CONF.identity.v2_public_endpoint_type)
@@ -494,6 +498,8 @@
**params_v2_public)
self.roles_public_client = RolesClient(self.auth_provider,
**params_v2_public)
+ self.users_public_client = UsersClient(self.auth_provider,
+ **params_v2_public)
params_v3 = params.copy()
params_v3['endpoint_type'] = CONF.identity.v3_endpoint_type
# Clients below use the endpoint type of Keystone API v3
diff --git a/tempest/cmd/account_generator.py b/tempest/cmd/account_generator.py
index 5a2713b..32d6ef1 100755
--- a/tempest/cmd/account_generator.py
+++ b/tempest/cmd/account_generator.py
@@ -85,8 +85,15 @@
import argparse
import netaddr
import os
+import traceback
+from cliff import command
from oslo_log import log as logging
+import tempest_lib.auth
+from tempest_lib.common.utils import data_utils
+import tempest_lib.exceptions
+from tempest_lib.services.network import networks_client
+from tempest_lib.services.network import subnets_client
import yaml
from tempest.common import identity
@@ -95,15 +102,16 @@
from tempest.services.identity.v2.json import identity_client
from tempest.services.identity.v2.json import roles_client
from tempest.services.identity.v2.json import tenants_client
+from tempest.services.identity.v2.json import users_client
from tempest.services.network.json import network_client
-from tempest.services.network.json import networks_client
-from tempest.services.network.json import subnets_client
-import tempest_lib.auth
-from tempest_lib.common.utils import data_utils
-import tempest_lib.exceptions
LOG = None
CONF = config.CONF
+DESCRIPTION = ('Create accounts.yaml file for concurrent test runs.%s'
+ 'One primary user, one alt user, '
+ 'one swift admin, one stack owner '
+ 'and one admin (optionally) will be created '
+ 'for each concurrent thread.' % os.linesep)
def setup_logging():
@@ -154,6 +162,13 @@
endpoint_type='adminURL',
**params
)
+ users_admin = users_client.UsersClient(
+ _auth,
+ CONF.identity.catalog_type,
+ CONF.identity.region,
+ endpoint_type='adminURL',
+ **params
+ )
network_admin = None
networks_admin = None
subnets_admin = None
@@ -179,13 +194,14 @@
CONF.network.region or CONF.identity.region,
endpoint_type='adminURL',
**params)
- return (identity_admin, tenants_admin, roles_admin, neutron_iso_networks,
- network_admin, networks_admin, subnets_admin)
+ return (identity_admin, tenants_admin, roles_admin, users_admin,
+ neutron_iso_networks, network_admin, networks_admin, subnets_admin)
def create_resources(opts, resources):
- (identity_admin, tenants_admin, roles_admin, neutron_iso_networks,
- network_admin, networks_admin, subnets_admin) = get_admin_clients(opts)
+ (identity_admin, tenants_admin, roles_admin, users_admin,
+ neutron_iso_networks, network_admin, networks_admin,
+ subnets_admin) = get_admin_clients(opts)
roles = roles_admin.list_roles()['roles']
for u in resources['users']:
u['role_ids'] = []
@@ -215,7 +231,7 @@
identity.get_user_by_username(tenants_admin,
tenant['id'], u['name'])
except tempest_lib.exceptions.NotFound:
- identity_admin.create_user(
+ users_admin.create_user(
u['name'], u['pass'], tenant['id'],
"%s@%s" % (u['name'], tenant['id']),
enabled=True)
@@ -388,20 +404,7 @@
LOG.info('%s generated successfully!' % opts.accounts)
-def get_options():
- usage_string = ('tempest-account-generator [-h] <ARG> ...\n\n'
- 'To see help on specific argument, do:\n'
- 'tempest-account-generator <ARG> -h')
- parser = argparse.ArgumentParser(
- description='Create accounts.yaml file for concurrent test runs. '
- 'One primary user, one alt user, '
- 'one swift admin, one stack owner '
- 'and one admin (optionally) will be created '
- 'for each concurrent thread.',
- formatter_class=argparse.ArgumentDefaultsHelpFormatter,
- usage=usage_string
- )
-
+def _parser_add_args(parser):
parser.add_argument('-c', '--config-file',
metavar='/etc/tempest.conf',
help='path to tempest config file')
@@ -438,16 +441,50 @@
metavar='accounts_file.yaml',
help='Output accounts yaml file')
+
+def get_options():
+ usage_string = ('tempest-account-generator [-h] <ARG> ...\n\n'
+ 'To see help on specific argument, do:\n'
+ 'tempest-account-generator <ARG> -h')
+ parser = argparse.ArgumentParser(
+ description=DESCRIPTION,
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ usage=usage_string
+ )
+
+ _parser_add_args(parser)
opts = parser.parse_args()
- if opts.config_file:
- config.CONF.set_config_path(opts.config_file)
return opts
+class TempestAccountGenerator(command.Command):
+
+ def get_parser(self, prog_name):
+ parser = super(TempestAccountGenerator, self).get_parser(prog_name)
+ _parser_add_args(parser)
+ return parser
+
+ def take_action(self, parsed_args):
+ try:
+ return main(parsed_args)
+ except Exception:
+ LOG.exception("Failure generating test accounts.")
+ traceback.print_exc()
+ raise
+ return 0
+
+ def get_description(self):
+ return DESCRIPTION
+
+
def main(opts=None):
- if not opts:
- opts = get_options()
setup_logging()
+ if not opts:
+ LOG.warn("Use of: 'tempest-account-generator' is deprecated, "
+ "please use: 'tempest account-generator'")
+ opts = get_options()
+ if opts.config_file:
+ config.CONF.set_config_path(opts.config_file)
resources = generate_resources(opts)
create_resources(opts, resources)
dump_accounts(opts, resources)
diff --git a/tempest/cmd/cleanup_service.py b/tempest/cmd/cleanup_service.py
index 8538509..8a47406 100644
--- a/tempest/cmd/cleanup_service.py
+++ b/tempest/cmd/cleanup_service.py
@@ -815,11 +815,14 @@
self.client = manager.identity_client
-class UserService(IdentityService):
+class UserService(BaseService):
+
+ def __init__(self, manager, **kwargs):
+ super(UserService, self).__init__(kwargs)
+ self.client = manager.users_client
def list(self):
- client = self.client
- users = client.list_users()['users']
+ users = self.client.list_users()['users']
if not self.is_save_state:
users = [user for user in users if user['id']
@@ -837,11 +840,10 @@
return users
def delete(self):
- client = self.client
users = self.list()
for user in users:
try:
- client.delete_user(user['id'])
+ self.client.delete_user(user['id'])
except Exception:
LOG.exception("Delete User exception.")
diff --git a/tempest/cmd/javelin.py b/tempest/cmd/javelin.py
index 9d889bd..8012ad7 100755
--- a/tempest/cmd/javelin.py
+++ b/tempest/cmd/javelin.py
@@ -122,6 +122,7 @@
from tempest_lib.services.compute import security_group_rules_client
from tempest_lib.services.compute import security_groups_client
from tempest_lib.services.compute import servers_client
+from tempest_lib.services.network import subnets_client
import yaml
from tempest.common import identity
@@ -130,9 +131,9 @@
from tempest.services.identity.v2.json import identity_client
from tempest.services.identity.v2.json import roles_client
from tempest.services.identity.v2.json import tenants_client
+from tempest.services.identity.v2.json import users_client
from tempest.services.image.v2.json import images_client
from tempest.services.network.json import network_client
-from tempest.services.network.json import subnets_client
from tempest.services.object_storage import container_client
from tempest.services.object_storage import object_client
from tempest.services.telemetry.json import alarming_client
@@ -213,6 +214,12 @@
CONF.identity.region,
endpoint_type='adminURL',
**default_params_with_timeout_values)
+ self.users = users_client.UsersClient(
+ _auth,
+ CONF.identity.catalog_type,
+ CONF.identity.region,
+ endpoint_type='adminURL',
+ **default_params_with_timeout_values)
self.servers = servers_client.ServersClient(_auth,
**compute_params)
self.flavors = flavors_client.FlavorsClient(_auth,
@@ -375,12 +382,12 @@
LOG.error("Tenant: %s - not found" % u['tenant'])
continue
try:
- identity.get_user_by_username(admin.identity,
+ identity.get_user_by_username(admin.tenants,
tenant['id'], u['name'])
LOG.warning("User '%s' already exists in this environment"
% u['name'])
except lib_exc.NotFound:
- admin.identity.create_user(
+ admin.users.create_user(
u['name'], u['pass'], tenant['id'],
"%s@%s" % (u['name'], tenant['id']),
enabled=True)
@@ -391,9 +398,9 @@
for user in users:
tenant_id = identity.get_tenant_by_name(admin.tenants,
user['tenant'])['id']
- user_id = identity.get_user_by_username(admin.identity,
+ user_id = identity.get_user_by_username(admin.tenants,
tenant_id, user['name'])['id']
- admin.identity.delete_user(user_id)
+ admin.users.delete_user(user_id)
def collect_users(users):
@@ -404,7 +411,7 @@
tenant = identity.get_tenant_by_name(admin.tenants, u['tenant'])
u['tenant_id'] = tenant['id']
USERS[u['name']] = u
- body = identity.get_user_by_username(admin.identity,
+ body = identity.get_user_by_username(admin.tenants,
tenant['id'], u['name'])
USERS[u['name']]['id'] = body['id']
@@ -458,7 +465,7 @@
LOG.info("checking users")
for name, user in six.iteritems(self.users):
client = keystone_admin()
- found = client.identity.show_user(user['id'])['user']
+ found = client.users.show_user(user['id'])['user']
self.assertEqual(found['name'], user['name'])
self.assertEqual(found['tenantId'], user['tenant_id'])
@@ -1133,6 +1140,8 @@
def main():
+ print("Javelin is deprecated and will be removed from Tempest in the "
+ "future.")
global RES
get_options()
setup_logging()
diff --git a/tempest/cmd/main.py b/tempest/cmd/main.py
index 577df9b..acd97a8 100644
--- a/tempest/cmd/main.py
+++ b/tempest/cmd/main.py
@@ -28,6 +28,7 @@
description='Tempest cli application',
version=version.VersionInfo('tempest').version_string(),
command_manager=commandmanager.CommandManager('tempest.cm'),
+ deferred_help=True,
)
def initialize_app(self, argv):
diff --git a/tempest/cmd/verify_tempest_config.py b/tempest/cmd/verify_tempest_config.py
old mode 100755
new mode 100644
index 9c8e2a0..5d867df
--- a/tempest/cmd/verify_tempest_config.py
+++ b/tempest/cmd/verify_tempest_config.py
@@ -15,10 +15,13 @@
# under the License.
import argparse
+import httplib2
import os
import sys
+import traceback
-import httplib2
+from cliff import command
+from oslo_log import log as logging
from oslo_serialization import jsonutils as json
from six import moves
from six.moves.urllib import parse as urlparse
@@ -31,6 +34,8 @@
CONF = config.CONF
CONF_PARSER = None
+LOG = logging.getLogger(__name__)
+
def _get_config_file():
default_config_dir = os.path.join(os.path.abspath(
@@ -310,8 +315,7 @@
return avail_services
-def parse_args():
- parser = argparse.ArgumentParser()
+def _parser_add_args(parser):
parser.add_argument('-u', '--update', action='store_true',
help='Update the config file with results from api '
'queries. This assumes whatever is set in the '
@@ -329,13 +333,21 @@
parser.add_argument('-r', '--replace-ext', action='store_true',
help="If specified the all option will be replaced "
"with a full list of extensions")
- args = parser.parse_args()
- return args
-def main():
+def parse_args():
+ parser = argparse.ArgumentParser()
+ _parser_add_args(parser)
+ opts = parser.parse_args()
+ return opts
+
+
+def main(opts=None):
print('Running config verification...')
- opts = parse_args()
+ if opts is None:
+ print("Use of: 'verify-tempest-config' is deprecated, "
+ "please use: 'tempest verify-config'")
+ opts = parse_args()
update = opts.update
replace = opts.replace_ext
global CONF_PARSER
@@ -373,5 +385,22 @@
icreds.clear_creds()
+class TempestVerifyConfig(command.Command):
+ """Verify your current tempest configuration"""
+
+ def get_parser(self, prog_name):
+ parser = super(TempestVerifyConfig, self).get_parser(prog_name)
+ _parser_add_args(parser)
+ return parser
+
+ def take_action(self, parsed_args):
+ try:
+ return main(parsed_args)
+ except Exception:
+ LOG.exception("Failure verifying configuration.")
+ traceback.print_exc()
+ raise
+ return 0
+
if __name__ == "__main__":
main()
diff --git a/tempest/common/compute.py b/tempest/common/compute.py
index 6e6ada8..73505e6 100644
--- a/tempest/common/compute.py
+++ b/tempest/common/compute.py
@@ -29,7 +29,8 @@
def create_test_server(clients, validatable=False, validation_resources=None,
tenant_network=None, wait_until=None,
- volume_backed=False, **kwargs):
+ volume_backed=False, name=None, flavor=None,
+ image_id=None, **kwargs):
"""Common wrapper utility returning a test server.
This method is a common wrapper returning a test server that can be
@@ -48,17 +49,27 @@
# TODO(jlanoux) add support of wait_until PINGABLE/SSHABLE
- name = kwargs.pop('name', data_utils.rand_name(__name__ + "-instance"))
- flavor = kwargs.pop('flavor', CONF.compute.flavor_ref)
- image_id = kwargs.pop('image_id', CONF.compute.image_ref)
+ name = name
+ flavor = flavor
+ image_id = image_id
+
+ if name is None:
+ name = data_utils.rand_name(__name__ + "-instance")
+ if flavor is None:
+ flavor = CONF.compute.flavor_ref
+ if image_id is None:
+ image_id = CONF.compute.image_ref
kwargs = fixed_network.set_networks_kwarg(
tenant_network, kwargs) or {}
+ multiple_create_request = (max(kwargs.get('min_count', 0),
+ kwargs.get('max_count', 0)) > 1)
+
if CONF.validation.run_validation and validatable:
# As a first implementation, multiple pingable or sshable servers will
# not be supported
- if 'min_count' in kwargs or 'max_count' in kwargs:
+ if multiple_create_request:
msg = ("Multiple pingable or sshable servers not supported at "
"this stage.")
raise ValueError(msg)
@@ -112,7 +123,7 @@
# handle the case of multiple servers
servers = []
- if 'min_count' in kwargs or 'max_count' in kwargs:
+ if multiple_create_request:
# Get servers created which name match with name param.
body_servers = clients.servers_client.list_servers()
servers = \
diff --git a/tempest/common/cred_client.py b/tempest/common/cred_client.py
index 5d15988..6df7eb2 100644
--- a/tempest/common/cred_client.py
+++ b/tempest/common/cred_client.py
@@ -32,16 +32,17 @@
"""
def __init__(self, identity_client, projects_client=None,
- roles_client=None):
+ roles_client=None, users_client=None):
# The client implies version and credentials
self.identity_client = identity_client
# this is temporary until the v3 project client is
# separated, then projects_client will become mandatory
self.projects_client = projects_client or identity_client
self.roles_client = roles_client or identity_client
+ self.users_client = users_client or identity_client
def create_user(self, username, password, project, email):
- user = self.identity_client.create_user(
+ user = self.users_client.create_user(
username, password, project['id'], email)
if 'user' in user:
user = user['user']
@@ -87,7 +88,7 @@
pass
def delete_user(self, user_id):
- self.identity_client.delete_user(user_id)
+ self.users_client.delete_user(user_id)
def _list_roles(self):
roles = self.roles_client.list_roles()['roles']
@@ -96,10 +97,12 @@
class V2CredsClient(CredsClient):
- def __init__(self, identity_client, projects_client, roles_client):
+ def __init__(self, identity_client, projects_client, roles_client,
+ users_client):
super(V2CredsClient, self).__init__(identity_client,
projects_client,
- roles_client)
+ roles_client,
+ users_client)
def create_project(self, name, description):
tenant = self.projects_client.create_tenant(
@@ -165,8 +168,10 @@
def get_creds_client(identity_client,
projects_client=None,
roles_client=None,
+ users_client=None,
project_domain_name=None):
if isinstance(identity_client, v2_identity.IdentityClient):
- return V2CredsClient(identity_client, projects_client, roles_client)
+ return V2CredsClient(identity_client, projects_client, roles_client,
+ users_client)
else:
return V3CredsClient(identity_client, project_domain_name)
diff --git a/tempest/common/cred_provider.py b/tempest/common/cred_provider.py
index aa237e0..9dd89ea 100644
--- a/tempest/common/cred_provider.py
+++ b/tempest/common/cred_provider.py
@@ -14,14 +14,11 @@
import abc
-from oslo_log import log as logging
import six
from tempest_lib import auth
from tempest import exceptions
-LOG = logging.getLogger(__name__)
-
@six.add_metaclass(abc.ABCMeta)
class CredentialProvider(object):
diff --git a/tempest/common/credentials_factory.py b/tempest/common/credentials_factory.py
index 5d290d4..24c1198 100644
--- a/tempest/common/credentials_factory.py
+++ b/tempest/common/credentials_factory.py
@@ -12,7 +12,6 @@
# limitations under the License.
from oslo_concurrency import lockutils
-from oslo_log import log as logging
from tempest_lib import auth
from tempest import clients
@@ -23,7 +22,6 @@
from tempest import exceptions
CONF = config.CONF
-LOG = logging.getLogger(__name__)
"""This module provides factories of credential and credential providers
diff --git a/tempest/common/dynamic_creds.py b/tempest/common/dynamic_creds.py
index 0af07f0..95ad229 100644
--- a/tempest/common/dynamic_creds.py
+++ b/tempest/common/dynamic_creds.py
@@ -59,6 +59,7 @@
self.default_admin_creds = admin_creds
(self.identity_admin_client, self.tenants_admin_client,
self.roles_admin_client,
+ self.users_admin_client,
self.network_admin_client,
self.networks_admin_client,
self.subnets_admin_client,
@@ -75,6 +76,7 @@
self.identity_admin_client,
self.tenants_admin_client,
self.roles_admin_client,
+ self.users_admin_client,
self.creds_domain_name)
def _get_admin_clients(self):
@@ -87,10 +89,11 @@
os = clients.Manager(self.default_admin_creds)
if self.identity_version == 'v2':
return (os.identity_client, os.tenants_client, os.roles_client,
- os.network_client, os.networks_client, os.subnets_client,
- os.ports_client, os.security_groups_client)
+ os.users_client, os.network_client, os.networks_client,
+ os.subnets_client, os.ports_client,
+ os.security_groups_client)
else:
- return (os.identity_v3_client, None, None, os.network_client,
+ return (os.identity_v3_client, None, None, None, os.network_client,
os.networks_client, os.subnets_client, os.ports_client,
os.security_groups_client)
diff --git a/tempest/common/generator/base_generator.py b/tempest/common/generator/base_generator.py
index a66002f..3a51f2e 100644
--- a/tempest/common/generator/base_generator.py
+++ b/tempest/common/generator/base_generator.py
@@ -17,11 +17,8 @@
import functools
import jsonschema
-from oslo_log import log as logging
import six
-LOG = logging.getLogger(__name__)
-
def _check_for_expected_result(name, schema):
expected_result = None
diff --git a/tempest/common/generator/negative_generator.py b/tempest/common/generator/negative_generator.py
index 17997a5..67ace54 100644
--- a/tempest/common/generator/negative_generator.py
+++ b/tempest/common/generator/negative_generator.py
@@ -15,13 +15,9 @@
import copy
-from oslo_log import log as logging
-
import tempest.common.generator.base_generator as base
import tempest.common.generator.valid_generator as valid
-LOG = logging.getLogger(__name__)
-
class NegativeTestGenerator(base.BasicGeneratorSet):
@base.generator_type("string")
diff --git a/tempest/common/generator/valid_generator.py b/tempest/common/generator/valid_generator.py
index 2213b4a..3070489 100644
--- a/tempest/common/generator/valid_generator.py
+++ b/tempest/common/generator/valid_generator.py
@@ -13,15 +13,11 @@
# License for the specific language governing permissions and limitations
# under the License.
-from oslo_log import log as logging
import six
import tempest.common.generator.base_generator as base
-LOG = logging.getLogger(__name__)
-
-
class ValidTestGenerator(base.BasicGeneratorSet):
@base.generator_type("string")
@base.simple_generator
diff --git a/tempest/config.py b/tempest/config.py
index 92123b9..6942172 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -1046,7 +1046,8 @@
cfg.StrOpt('img_dir',
default='/opt/stack/new/devstack/files/images/'
'cirros-0.3.1-x86_64-uec',
- help='Directory containing image files'),
+ help='Directory containing image files',
+ deprecated_for_removal=True),
cfg.StrOpt('img_file', deprecated_name='qcow2_img_file',
default='cirros-0.3.1-x86_64-disk.img',
help='Image file name'),
@@ -1060,13 +1061,16 @@
'Use for custom images which require them'),
cfg.StrOpt('ami_img_file',
default='cirros-0.3.1-x86_64-blank.img',
- help='AMI image file name'),
+ help='AMI image file name',
+ deprecated_for_removal=True),
cfg.StrOpt('ari_img_file',
default='cirros-0.3.1-x86_64-initrd',
- help='ARI image file name'),
+ help='ARI image file name',
+ deprecated_for_removal=True),
cfg.StrOpt('aki_img_file',
default='cirros-0.3.1-x86_64-vmlinuz',
- help='AKI image file name'),
+ help='AKI image file name',
+ deprecated_for_removal=True),
cfg.IntOpt(
'large_ops_number',
default=0,
diff --git a/tempest/hacking/checks.py b/tempest/hacking/checks.py
index 1dad3ba..88598de 100644
--- a/tempest/hacking/checks.py
+++ b/tempest/hacking/checks.py
@@ -185,7 +185,8 @@
# the end of a method
return
- if 'self.get(' not in line:
+ if 'self.get(' not in line and ('self.show_resource(' not in line and
+ 'self.list_resources(' not in line):
continue
if METHOD_GET_RESOURCE.match(logical_line):
@@ -211,7 +212,7 @@
# the end of a method
return
- if 'self.delete(' not in line:
+ if 'self.delete(' not in line and 'self.delete_resource(' not in line:
continue
if METHOD_DELETE_RESOURCE.match(logical_line):
diff --git a/tempest/hacking/ignored_list_T110.txt b/tempest/hacking/ignored_list_T110.txt
index 8de3151..ce69931 100644
--- a/tempest/hacking/ignored_list_T110.txt
+++ b/tempest/hacking/ignored_list_T110.txt
@@ -6,3 +6,4 @@
./tempest/services/volume/base/base_qos_client.py
./tempest/services/volume/base/base_backups_client.py
./tempest/services/baremetal/base.py
+./tempest/services/network/json/network_client.py
diff --git a/tempest/hacking/ignored_list_T111.txt b/tempest/hacking/ignored_list_T111.txt
index 8017e76..8130c85 100644
--- a/tempest/hacking/ignored_list_T111.txt
+++ b/tempest/hacking/ignored_list_T111.txt
@@ -1 +1,3 @@
./tempest/services/baremetal/base.py
+./tempest/services/network/json/agents_client.py
+./tempest/services/network/json/quotas_client.py
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index bb4e521..37d0d10 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -160,7 +160,7 @@
self.addCleanup(client.delete_keypair, name)
return body['keypair']
- def create_server(self, name=None, image=None, flavor=None,
+ def create_server(self, name=None, image_id=None, flavor=None,
validatable=False, wait_until=None,
wait_on_delete=True, clients=None, **kwargs):
"""Wrapper utility that returns a test server.
@@ -240,7 +240,8 @@
clients,
tenant_network=tenant_network,
wait_until=wait_until,
- **kwargs)
+ name=name, flavor=flavor,
+ image_id=image_id, **kwargs)
# TODO(jlanoux) Move wait_on_delete in compute.py
if wait_on_delete:
diff --git a/tempest/scenario/test_aggregates_basic_ops.py b/tempest/scenario/test_aggregates_basic_ops.py
index 62c0262..97a755d 100644
--- a/tempest/scenario/test_aggregates_basic_ops.py
+++ b/tempest/scenario/test_aggregates_basic_ops.py
@@ -13,17 +13,12 @@
# License for the specific language governing permissions and limitations
# under the License.
-from oslo_log import log as logging
-
from tempest.common import tempest_fixtures as fixtures
from tempest.common.utils import data_utils
from tempest.scenario import manager
from tempest import test
-LOG = logging.getLogger(__name__)
-
-
class TestAggregatesBasicOps(manager.ScenarioTest):
"""Creates an aggregate within an availability zone
diff --git a/tempest/scenario/test_large_ops.py b/tempest/scenario/test_large_ops.py
index b549ecb..402077f 100644
--- a/tempest/scenario/test_large_ops.py
+++ b/tempest/scenario/test_large_ops.py
@@ -13,7 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-from oslo_log import log as logging
from tempest_lib import exceptions as lib_exc
from tempest.common import fixed_network
@@ -26,9 +25,6 @@
CONF = config.CONF
-LOG = logging.getLogger(__name__)
-
-
class TestLargeOpsScenario(manager.ScenarioTest):
"""Test large operations.
diff --git a/tempest/scenario/test_minimum_basic.py b/tempest/scenario/test_minimum_basic.py
index 2ef3cee..d9c6924 100644
--- a/tempest/scenario/test_minimum_basic.py
+++ b/tempest/scenario/test_minimum_basic.py
@@ -13,8 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-from oslo_log import log as logging
-
from tempest.common import custom_matchers
from tempest.common import waiters
from tempest import config
@@ -24,8 +22,6 @@
CONF = config.CONF
-LOG = logging.getLogger(__name__)
-
class TestMinimumBasicScenario(manager.ScenarioTest):
@@ -51,13 +47,6 @@
"""
- def _wait_for_server_status(self, server, status):
- server_id = server['id']
- # Raise on error defaults to True, which is consistent with the
- # original function from scenario tests here
- waiters.wait_for_server_status(self.servers_client,
- server_id, status)
-
def nova_list(self):
servers = self.servers_client.list_servers()
# The list servers in the compute client is inconsistent...
@@ -85,7 +74,8 @@
def nova_reboot(self, server):
self.servers_client.reboot_server(server['id'], type='SOFT')
- self._wait_for_server_status(server, 'ACTIVE')
+ waiters.wait_for_server_status(self.servers_client,
+ server['id'], 'ACTIVE')
def check_partitions(self):
# NOTE(andreaf) The device name may be different on different guest OS
diff --git a/tempest/scenario/test_network_advanced_server_ops.py b/tempest/scenario/test_network_advanced_server_ops.py
index d6dd6f3..2cbe6dc 100644
--- a/tempest/scenario/test_network_advanced_server_ops.py
+++ b/tempest/scenario/test_network_advanced_server_ops.py
@@ -13,7 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-from oslo_log import log as logging
import testtools
from tempest.common.utils import data_utils
@@ -23,7 +22,6 @@
from tempest import test
CONF = config.CONF
-LOG = logging.getLogger(__name__)
class TestNetworkAdvancedServerOps(manager.NetworkScenarioTest):
diff --git a/tempest/scenario/test_network_v6.py b/tempest/scenario/test_network_v6.py
index 40c7680..cc28873 100644
--- a/tempest/scenario/test_network_v6.py
+++ b/tempest/scenario/test_network_v6.py
@@ -14,7 +14,6 @@
# under the License.
import functools
-from oslo_log import log as logging
import six
from tempest import config
@@ -23,7 +22,6 @@
CONF = config.CONF
-LOG = logging.getLogger(__name__)
class TestGettingAddress(manager.NetworkScenarioTest):
diff --git a/tempest/scenario/test_object_storage_basic_ops.py b/tempest/scenario/test_object_storage_basic_ops.py
index 98dd705..63ffa0b 100644
--- a/tempest/scenario/test_object_storage_basic_ops.py
+++ b/tempest/scenario/test_object_storage_basic_ops.py
@@ -13,16 +13,12 @@
# License for the specific language governing permissions and limitations
# under the License.
-from oslo_log import log as logging
-
from tempest import config
from tempest.scenario import manager
from tempest import test
CONF = config.CONF
-LOG = logging.getLogger(__name__)
-
class TestObjectStorageBasicOps(manager.ObjectStorageScenarioTest):
"""Test swift basic ops.
diff --git a/tempest/scenario/test_security_groups_basic_ops.py b/tempest/scenario/test_security_groups_basic_ops.py
index 783b740..8375d05 100644
--- a/tempest/scenario/test_security_groups_basic_ops.py
+++ b/tempest/scenario/test_security_groups_basic_ops.py
@@ -13,8 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-from oslo_log import log as logging
-
from tempest import clients
from tempest.common.utils import data_utils
from tempest import config
@@ -23,8 +21,6 @@
CONF = config.CONF
-LOG = logging.getLogger(__name__)
-
class TestSecurityGroupsBasicOps(manager.NetworkScenarioTest):
@@ -137,6 +133,9 @@
msg = ('Either tenant_networks_reachable must be "true", or '
'public_network_id must be defined.')
raise cls.skipException(msg)
+ if not test.is_extension_enabled('security-group', 'network'):
+ msg = "security-group extension not enabled."
+ raise cls.skipException(msg)
@classmethod
def setup_credentials(cls):
diff --git a/tempest/scenario/test_server_multinode.py b/tempest/scenario/test_server_multinode.py
index f21ff4f..0cf72c3 100644
--- a/tempest/scenario/test_server_multinode.py
+++ b/tempest/scenario/test_server_multinode.py
@@ -14,8 +14,6 @@
# under the License.
-from oslo_log import log as logging
-
from tempest import config
from tempest import exceptions
from tempest.scenario import manager
@@ -23,8 +21,6 @@
CONF = config.CONF
-LOG = logging.getLogger(__name__)
-
class TestServerMultinode(manager.ScenarioTest):
"""This is a set of tests specific to multinode testing."""
diff --git a/tempest/scenario/test_stamp_pattern.py b/tempest/scenario/test_stamp_pattern.py
index faae800..8183ce3 100644
--- a/tempest/scenario/test_stamp_pattern.py
+++ b/tempest/scenario/test_stamp_pattern.py
@@ -67,7 +67,7 @@
def _create_volume_snapshot(self, volume):
snapshot_name = data_utils.rand_name('scenario-snapshot')
snapshot = self.snapshots_client.create_snapshot(
- volume['id'], display_name=snapshot_name)['snapshot']
+ volume_id=volume['id'], display_name=snapshot_name)['snapshot']
def cleaner():
self.snapshots_client.delete_snapshot(snapshot['id'])
diff --git a/tempest/scenario/test_volume_boot_pattern.py b/tempest/scenario/test_volume_boot_pattern.py
index 81ecda0..7b88025 100644
--- a/tempest/scenario/test_volume_boot_pattern.py
+++ b/tempest/scenario/test_volume_boot_pattern.py
@@ -70,7 +70,7 @@
create_kwargs.update(self._get_bdm(
vol_id, delete_on_termination=delete_on_termination))
return self.create_server(
- image='',
+ image_id='',
wait_until='ACTIVE',
**create_kwargs)
diff --git a/tempest/services/compute/json/keypairs_client.py b/tempest/services/compute/json/keypairs_client.py
index 2e22bc6..e956100 100644
--- a/tempest/services/compute/json/keypairs_client.py
+++ b/tempest/services/compute/json/keypairs_client.py
@@ -15,21 +15,28 @@
from oslo_serialization import jsonutils as json
-from tempest.api_schema.response.compute.v2_1 import keypairs as schema
+from tempest.api_schema.response.compute.v2_1 import keypairs as schemav21
+from tempest.api_schema.response.compute.v2_2 import keypairs as schemav22
from tempest.common import service_client
+from tempest.services.compute.json import base
-class KeyPairsClient(service_client.ServiceClient):
+class KeyPairsClient(base.BaseComputeClient):
+
+ schema_versions_info = [{'min': None, 'max': '2.1', 'schema': schemav21},
+ {'min': '2.2', 'max': None, 'schema': schemav22}]
def list_keypairs(self):
resp, body = self.get("os-keypairs")
body = json.loads(body)
+ schema = self.get_schema(self.schema_versions_info)
self.validate_response(schema.list_keypairs, resp, body)
return service_client.ResponseBody(resp, body)
def show_keypair(self, keypair_name):
resp, body = self.get("os-keypairs/%s" % keypair_name)
body = json.loads(body)
+ schema = self.get_schema(self.schema_versions_info)
self.validate_response(schema.get_keypair, resp, body)
return service_client.ResponseBody(resp, body)
@@ -37,10 +44,12 @@
post_body = json.dumps({'keypair': kwargs})
resp, body = self.post("os-keypairs", body=post_body)
body = json.loads(body)
+ schema = self.get_schema(self.schema_versions_info)
self.validate_response(schema.create_keypair, resp, body)
return service_client.ResponseBody(resp, body)
def delete_keypair(self, keypair_name):
resp, body = self.delete("os-keypairs/%s" % keypair_name)
+ schema = self.get_schema(self.schema_versions_info)
self.validate_response(schema.delete_keypair, resp, body)
return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/identity/v2/json/identity_client.py b/tempest/services/identity/v2/json/identity_client.py
index ff6c838..0ff59d5 100644
--- a/tempest/services/identity/v2/json/identity_client.py
+++ b/tempest/services/identity/v2/json/identity_client.py
@@ -26,67 +26,6 @@
body = json.loads(body)
return service_client.ResponseBody(resp, body)
- def create_user(self, name, password, tenant_id, email, **kwargs):
- """Create a user."""
- post_body = {
- 'name': name,
- 'password': password,
- 'email': email
- }
- if tenant_id is not None:
- post_body['tenantId'] = tenant_id
- if kwargs.get('enabled') is not None:
- post_body['enabled'] = kwargs.get('enabled')
- post_body = json.dumps({'user': post_body})
- resp, body = self.post('users', post_body)
- self.expected_success(200, resp.status)
- body = json.loads(body)
- return service_client.ResponseBody(resp, body)
-
- def update_user(self, user_id, **kwargs):
- """Updates a user."""
- put_body = json.dumps({'user': kwargs})
- resp, body = self.put('users/%s' % user_id, put_body)
- self.expected_success(200, resp.status)
- body = json.loads(body)
- return service_client.ResponseBody(resp, body)
-
- def show_user(self, user_id):
- """GET a user."""
- resp, body = self.get("users/%s" % user_id)
- self.expected_success(200, resp.status)
- body = json.loads(body)
- return service_client.ResponseBody(resp, body)
-
- def delete_user(self, user_id):
- """Delete a user."""
- resp, body = self.delete("users/%s" % user_id)
- self.expected_success(204, resp.status)
- return service_client.ResponseBody(resp, body)
-
- def list_users(self):
- """Get the list of users."""
- resp, body = self.get("users")
- self.expected_success(200, resp.status)
- body = json.loads(body)
- return service_client.ResponseBody(resp, body)
-
- def enable_disable_user(self, user_id, **kwargs):
- """Enables or disables a user.
-
- Available params: see 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
- # because of the fact that in keystone/contrib/admin_crud/core.py
- # both api use same action='set_user_enabled'
- put_body = json.dumps({'user': kwargs})
- resp, body = self.put('users/%s/enabled' % user_id, put_body)
- self.expected_success(200, resp.status)
- body = json.loads(body)
- return service_client.ResponseBody(resp, body)
-
def show_token(self, token_id):
"""Get token details."""
resp, body = self.get("tokens/%s" % token_id)
@@ -164,66 +103,9 @@
self.expected_success(204, resp.status)
return service_client.ResponseBody(resp, body)
- def update_user_password(self, user_id, **kwargs):
- """Update User Password."""
- # TODO(piyush): Current api-site doesn't contain this API description.
- # After fixing the api-site, we need to fix here also for putting the
- # link to api-site.
- # LP: https://bugs.launchpad.net/openstack-api-site/+bug/1524147
- put_body = json.dumps({'user': kwargs})
- resp, body = self.put('users/%s/OS-KSADM/password' % user_id, put_body)
- self.expected_success(200, resp.status)
- body = json.loads(body)
- return service_client.ResponseBody(resp, body)
-
- def update_user_own_password(self, user_id, **kwargs):
- """User updates own password"""
- # TODO(piyush): Current api-site doesn't contain this API description.
- # After fixing the api-site, we need to fix here also for putting the
- # link to api-site.
- # LP: https://bugs.launchpad.net/openstack-api-site/+bug/1524153
- # NOTE: This API is used for updating user password by itself.
- # Ref: http://lists.openstack.org/pipermail/openstack-dev/2015-December
- # /081803.html
- patch_body = json.dumps({'user': kwargs})
- resp, body = self.patch('OS-KSCRUD/users/%s' % user_id, patch_body)
- self.expected_success(200, resp.status)
- body = json.loads(body)
- return service_client.ResponseBody(resp, body)
-
def list_extensions(self):
"""List all the extensions."""
resp, body = self.get('/extensions')
self.expected_success(200, resp.status)
body = json.loads(body)
return service_client.ResponseBody(resp, body)
-
- def create_user_ec2_credentials(self, user_id, **kwargs):
- # TODO(piyush): Current api-site doesn't contain this API description.
- # After fixing the api-site, we need to fix here also for putting the
- # link to api-site.
- post_body = json.dumps(kwargs)
- resp, body = self.post('/users/%s/credentials/OS-EC2' % user_id,
- post_body)
- self.expected_success(200, resp.status)
- body = json.loads(body)
- return service_client.ResponseBody(resp, body)
-
- def delete_user_ec2_credentials(self, user_id, access):
- resp, body = self.delete('/users/%s/credentials/OS-EC2/%s' %
- (user_id, access))
- self.expected_success(204, resp.status)
- return service_client.ResponseBody(resp, body)
-
- def list_user_ec2_credentials(self, user_id):
- resp, body = self.get('/users/%s/credentials/OS-EC2' % user_id)
- self.expected_success(200, resp.status)
- body = json.loads(body)
- return service_client.ResponseBody(resp, body)
-
- def show_user_ec2_credentials(self, user_id, access):
- resp, body = self.get('/users/%s/credentials/OS-EC2/%s' %
- (user_id, access))
- self.expected_success(200, resp.status)
- body = json.loads(body)
- return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/identity/v2/json/users_client.py b/tempest/services/identity/v2/json/users_client.py
new file mode 100644
index 0000000..5327638
--- /dev/null
+++ b/tempest/services/identity/v2/json/users_client.py
@@ -0,0 +1,137 @@
+# 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.common import service_client
+
+
+class UsersClient(service_client.ServiceClient):
+ api_version = "v2.0"
+
+ def create_user(self, name, password, tenant_id, email, **kwargs):
+ """Create a user."""
+ post_body = {
+ 'name': name,
+ 'password': password,
+ 'email': email
+ }
+ if tenant_id is not None:
+ post_body['tenantId'] = tenant_id
+ if kwargs.get('enabled') is not None:
+ post_body['enabled'] = kwargs.get('enabled')
+ post_body = json.dumps({'user': post_body})
+ resp, body = self.post('users', post_body)
+ self.expected_success(200, resp.status)
+ body = json.loads(body)
+ return service_client.ResponseBody(resp, body)
+
+ def update_user(self, user_id, **kwargs):
+ """Updates a user."""
+ put_body = json.dumps({'user': kwargs})
+ resp, body = self.put('users/%s' % user_id, put_body)
+ self.expected_success(200, resp.status)
+ body = json.loads(body)
+ return service_client.ResponseBody(resp, body)
+
+ def show_user(self, user_id):
+ """GET a user."""
+ resp, body = self.get("users/%s" % user_id)
+ self.expected_success(200, resp.status)
+ body = json.loads(body)
+ return service_client.ResponseBody(resp, body)
+
+ def delete_user(self, user_id):
+ """Delete a user."""
+ resp, body = self.delete("users/%s" % user_id)
+ self.expected_success(204, resp.status)
+ return service_client.ResponseBody(resp, body)
+
+ def list_users(self):
+ """Get the list of users."""
+ resp, body = self.get("users")
+ self.expected_success(200, resp.status)
+ body = json.loads(body)
+ return service_client.ResponseBody(resp, body)
+
+ def enable_disable_user(self, user_id, **kwargs):
+ """Enables or disables a user.
+
+ Available params: see 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
+ # because of the fact that in keystone/contrib/admin_crud/core.py
+ # both api use same action='set_user_enabled'
+ put_body = json.dumps({'user': kwargs})
+ resp, body = self.put('users/%s/enabled' % user_id, put_body)
+ self.expected_success(200, resp.status)
+ body = json.loads(body)
+ return service_client.ResponseBody(resp, body)
+
+ def update_user_password(self, user_id, **kwargs):
+ """Update User Password."""
+ # TODO(piyush): Current api-site doesn't contain this API description.
+ # After fixing the api-site, we need to fix here also for putting the
+ # link to api-site.
+ # LP: https://bugs.launchpad.net/openstack-api-site/+bug/1524147
+ put_body = json.dumps({'user': kwargs})
+ resp, body = self.put('users/%s/OS-KSADM/password' % user_id, put_body)
+ self.expected_success(200, resp.status)
+ body = json.loads(body)
+ return service_client.ResponseBody(resp, body)
+
+ def update_user_own_password(self, user_id, **kwargs):
+ """User updates own password"""
+ # TODO(piyush): Current api-site doesn't contain this API description.
+ # After fixing the api-site, we need to fix here also for putting the
+ # link to api-site.
+ # LP: https://bugs.launchpad.net/openstack-api-site/+bug/1524153
+ # NOTE: This API is used for updating user password by itself.
+ # Ref: http://lists.openstack.org/pipermail/openstack-dev/2015-December
+ # /081803.html
+ patch_body = json.dumps({'user': kwargs})
+ resp, body = self.patch('OS-KSCRUD/users/%s' % user_id, patch_body)
+ self.expected_success(200, resp.status)
+ body = json.loads(body)
+ return service_client.ResponseBody(resp, body)
+
+ def create_user_ec2_credentials(self, user_id, **kwargs):
+ # TODO(piyush): Current api-site doesn't contain this API description.
+ # After fixing the api-site, we need to fix here also for putting the
+ # link to api-site.
+ post_body = json.dumps(kwargs)
+ resp, body = self.post('/users/%s/credentials/OS-EC2' % user_id,
+ post_body)
+ self.expected_success(200, resp.status)
+ body = json.loads(body)
+ return service_client.ResponseBody(resp, body)
+
+ def delete_user_ec2_credentials(self, user_id, access):
+ resp, body = self.delete('/users/%s/credentials/OS-EC2/%s' %
+ (user_id, access))
+ self.expected_success(204, resp.status)
+ return service_client.ResponseBody(resp, body)
+
+ def list_user_ec2_credentials(self, user_id):
+ resp, body = self.get('/users/%s/credentials/OS-EC2' % user_id)
+ self.expected_success(200, resp.status)
+ body = json.loads(body)
+ return service_client.ResponseBody(resp, body)
+
+ def show_user_ec2_credentials(self, user_id, access):
+ resp, body = self.get('/users/%s/credentials/OS-EC2/%s' %
+ (user_id, access))
+ self.expected_success(200, resp.status)
+ body = json.loads(body)
+ return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/network/json/metering_label_rules_client.py b/tempest/services/network/json/metering_label_rules_client.py
deleted file mode 100644
index 374a89c..0000000
--- a/tempest/services/network/json/metering_label_rules_client.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from tempest.services.network.json import base
-
-
-class MeteringLabelRulesClient(base.BaseNetworkClient):
-
- def create_metering_label_rule(self, **kwargs):
- uri = '/metering/metering-label-rules'
- post_data = {'metering_label_rule': kwargs}
- return self.create_resource(uri, post_data)
-
- def show_metering_label_rule(self, metering_label_rule_id, **fields):
- uri = '/metering/metering-label-rules/%s' % metering_label_rule_id
- return self.show_resource(uri, **fields)
-
- def delete_metering_label_rule(self, metering_label_rule_id):
- uri = '/metering/metering-label-rules/%s' % metering_label_rule_id
- return self.delete_resource(uri)
-
- def list_metering_label_rules(self, **filters):
- uri = '/metering/metering-label-rules'
- return self.list_resources(uri, **filters)
diff --git a/tempest/services/network/json/metering_labels_client.py b/tempest/services/network/json/metering_labels_client.py
deleted file mode 100644
index 2e5cdae..0000000
--- a/tempest/services/network/json/metering_labels_client.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from tempest.services.network.json import base
-
-
-class MeteringLabelsClient(base.BaseNetworkClient):
-
- def create_metering_label(self, **kwargs):
- uri = '/metering/metering-labels'
- post_data = {'metering_label': kwargs}
- return self.create_resource(uri, post_data)
-
- def show_metering_label(self, metering_label_id, **fields):
- uri = '/metering/metering-labels/%s' % metering_label_id
- return self.show_resource(uri, **fields)
-
- def delete_metering_label(self, metering_label_id):
- uri = '/metering/metering-labels/%s' % metering_label_id
- return self.delete_resource(uri)
-
- def list_metering_labels(self, **filters):
- uri = '/metering/metering-labels'
- return self.list_resources(uri, **filters)
diff --git a/tempest/services/network/json/networks_client.py b/tempest/services/network/json/networks_client.py
deleted file mode 100644
index 2907d44..0000000
--- a/tempest/services/network/json/networks_client.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from tempest.services.network.json import base
-
-
-class NetworksClient(base.BaseNetworkClient):
-
- def create_network(self, **kwargs):
- uri = '/networks'
- post_data = {'network': kwargs}
- return self.create_resource(uri, post_data)
-
- def update_network(self, network_id, **kwargs):
- uri = '/networks/%s' % network_id
- post_data = {'network': kwargs}
- return self.update_resource(uri, post_data)
-
- def show_network(self, network_id, **fields):
- uri = '/networks/%s' % network_id
- return self.show_resource(uri, **fields)
-
- def delete_network(self, network_id):
- uri = '/networks/%s' % network_id
- return self.delete_resource(uri)
-
- def list_networks(self, **filters):
- uri = '/networks'
- return self.list_resources(uri, **filters)
diff --git a/tempest/services/network/json/ports_client.py b/tempest/services/network/json/ports_client.py
deleted file mode 100644
index d52d65e..0000000
--- a/tempest/services/network/json/ports_client.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from tempest.services.network.json import base
-
-
-class PortsClient(base.BaseNetworkClient):
-
- def create_port(self, **kwargs):
- uri = '/ports'
- post_data = {'port': kwargs}
- return self.create_resource(uri, post_data)
-
- def update_port(self, port_id, **kwargs):
- uri = '/ports/%s' % port_id
- post_data = {'port': kwargs}
- return self.update_resource(uri, post_data)
-
- def show_port(self, port_id, **fields):
- uri = '/ports/%s' % port_id
- return self.show_resource(uri, **fields)
-
- def delete_port(self, port_id):
- uri = '/ports/%s' % port_id
- return self.delete_resource(uri)
-
- def list_ports(self, **filters):
- uri = '/ports'
- return self.list_resources(uri, **filters)
diff --git a/tempest/services/network/json/subnets_client.py b/tempest/services/network/json/subnets_client.py
deleted file mode 100644
index 957b606..0000000
--- a/tempest/services/network/json/subnets_client.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from tempest.services.network.json import base
-
-
-class SubnetsClient(base.BaseNetworkClient):
-
- def create_subnet(self, **kwargs):
- uri = '/subnets'
- post_data = {'subnet': kwargs}
- return self.create_resource(uri, post_data)
-
- def update_subnet(self, subnet_id, **kwargs):
- uri = '/subnets/%s' % subnet_id
- post_data = {'subnet': kwargs}
- return self.update_resource(uri, post_data)
-
- def show_subnet(self, subnet_id, **fields):
- uri = '/subnets/%s' % subnet_id
- return self.show_resource(uri, **fields)
-
- def delete_subnet(self, subnet_id):
- uri = '/subnets/%s' % subnet_id
- return self.delete_resource(uri)
-
- def list_subnets(self, **filters):
- uri = '/subnets'
- return self.list_resources(uri, **filters)
diff --git a/tempest/services/volume/base/base_snapshots_client.py b/tempest/services/volume/base/base_snapshots_client.py
index fb705e1..1388e9c 100644
--- a/tempest/services/volume/base/base_snapshots_client.py
+++ b/tempest/services/volume/base/base_snapshots_client.py
@@ -29,7 +29,7 @@
create_resp = 200
- def list_snapshots(self, detail=False, params=None):
+ def list_snapshots(self, detail=False, **params):
"""List all the snapshot."""
url = 'snapshots'
if detail:
@@ -50,17 +50,13 @@
self.expected_success(200, resp.status)
return service_client.ResponseBody(resp, body)
- def create_snapshot(self, volume_id, **kwargs):
+ def create_snapshot(self, **kwargs):
"""Creates a new snapshot.
- volume_id(Required): id of the volume.
- force: Create a snapshot even if the volume attached (Default=False)
- display_name: Optional snapshot Name.
- display_description: User friendly snapshot description.
+ Available params: see http://developer.openstack.org/
+ api-ref-blockstorage-v2.html#createSnapshot
"""
- post_body = {'volume_id': volume_id}
- post_body.update(kwargs)
- post_body = json.dumps({'snapshot': post_body})
+ post_body = json.dumps({'snapshot': kwargs})
resp, body = self.post('snapshots', post_body)
body = json.loads(body)
self.expected_success(self.create_resp, resp.status)
@@ -136,13 +132,14 @@
self.expected_success(202, resp.status)
return service_client.ResponseBody(resp, body)
- def update_snapshot_status(self, snapshot_id, status, progress):
+ def update_snapshot_status(self, snapshot_id, **kwargs):
"""Update the specified snapshot's status."""
- post_body = {
- 'status': status,
- 'progress': progress
- }
- post_body = json.dumps({'os-update_snapshot_status': post_body})
+ # TODO(gmann): api-site doesn't contain doc ref
+ # for this API. After fixing the api-site, we need to
+ # add the link here.
+ # Bug https://bugs.launchpad.net/openstack-api-site/+bug/1532645
+
+ post_body = json.dumps({'os-update_snapshot_status': kwargs})
url = 'snapshots/%s/action' % str(snapshot_id)
resp, body = self.post(url, post_body)
self.expected_success(202, resp.status)
diff --git a/tempest/stress/cleanup.py b/tempest/stress/cleanup.py
index 5c25e32..1c1fb46 100644
--- a/tempest/stress/cleanup.py
+++ b/tempest/stress/cleanup.py
@@ -69,11 +69,11 @@
except Exception:
pass
- users = admin_manager.identity_client.list_users()['users']
+ users = admin_manager.users_client.list_users()['users']
LOG.info("Cleanup::remove %s users" % len(users))
for user in users:
if user['name'].startswith("stress_user"):
- admin_manager.identity_client.delete_user(user['id'])
+ admin_manager.users_client.delete_user(user['id'])
tenants = admin_manager.tenants_client.list_tenants()['tenants']
LOG.info("Cleanup::remove %s tenants" % len(tenants))
for tenant in tenants:
@@ -84,7 +84,7 @@
# volume deletion may block
_, snaps = admin_manager.snapshots_client.list_snapshots(
- params={"all_tenants": True})['snapshots']
+ all_tenants=True)['snapshots']
LOG.info("Cleanup::remove %s snapshots" % len(snaps))
for v in snaps:
try:
diff --git a/tempest/stress/driver.py b/tempest/stress/driver.py
index a3e1ea3..6531059 100644
--- a/tempest/stress/driver.py
+++ b/tempest/stress/driver.py
@@ -148,12 +148,15 @@
identity_client = admin_manager.identity_client
projects_client = admin_manager.tenants_client
roles_client = admin_manager.roles_client
+ users_client = admin_manager.users_client
else:
identity_client = admin_manager.identity_v3_client
projects_client = None
roles_client = None
+ users_client = None
credentials_client = cred_client.get_creds_client(
- identity_client, projects_client, roles_client)
+ identity_client, projects_client, roles_client,
+ users_client)
project = credentials_client.create_project(
name=tenant_name, description=tenant_name)
user = credentials_client.create_user(username, password,
diff --git a/tempest/test.py b/tempest/test.py
index 615a6e2..dfed947 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -439,10 +439,12 @@
client = self.os_admin.identity_client
project_client = self.os_admin.tenants_client
roles_client = self.os_admin.roles_client
+ users_client = self.os_admin.users_client
else:
client = self.os_admin.identity_v3_client
project_client = None
roles_client = None
+ users_client = None
try:
domain = client.auth_provider.credentials.project_domain_name
@@ -451,6 +453,7 @@
return cred_client.get_creds_client(client, project_client,
roles_client,
+ users_client,
project_domain_name=domain)
@classmethod
diff --git a/tempest/tests/cmd/test_javelin.py b/tempest/tests/cmd/test_javelin.py
index 62409bf..ab6a7a0 100644
--- a/tempest/tests/cmd/test_javelin.py
+++ b/tempest/tests/cmd/test_javelin.py
@@ -24,7 +24,7 @@
def setUp(self):
super(JavelinUnitTest, self).setUp()
- javelin.setup_logging()
+ javelin.LOG = mock.MagicMock()
self.fake_client = mock.MagicMock()
self.fake_object = mock.MagicMock()
@@ -119,7 +119,7 @@
fake_tenant_id = self.fake_object['tenant']['id']
fake_email = "%s@%s" % (self.fake_object['user'], fake_tenant_id)
- mocked_function = self.fake_client.identity.create_user
+ mocked_function = self.fake_client.users.create_user
mocked_function.assert_called_once_with(self.fake_object['name'],
self.fake_object['password'],
fake_tenant_id,
@@ -135,7 +135,7 @@
javelin.create_users([self.fake_object])
- mocked_function = self.fake_client.identity.create_user
+ mocked_function = self.fake_client.users.create_user
self.assertFalse(mocked_function.called)
def test_create_objects(self):
@@ -310,7 +310,7 @@
fake_auth = self.fake_client
fake_auth.tenants.list_tenants.return_value = \
{'tenants': [fake_tenant]}
- fake_auth.identity.list_users.return_value = {'users': [fake_user]}
+ fake_auth.users.list_users.return_value = {'users': [fake_user]}
self.useFixture(mockpatch.Patch(
'tempest.common.identity.get_user_by_username',
@@ -320,7 +320,7 @@
javelin.destroy_users([fake_user])
- mocked_function = fake_auth.identity.delete_user
+ mocked_function = fake_auth.users.delete_user
mocked_function.assert_called_once_with(fake_user['id'])
def test_destroy_objects(self):
diff --git a/tempest/tests/common/test_dynamic_creds.py b/tempest/tests/common/test_dynamic_creds.py
index a55e556..4379756 100644
--- a/tempest/tests/common/test_dynamic_creds.py
+++ b/tempest/tests/common/test_dynamic_creds.py
@@ -28,6 +28,8 @@
json_roles_client
from tempest.services.identity.v2.json import tenants_client as \
json_tenants_client
+from tempest.services.identity.v2.json import users_client as \
+ json_users_client
from tempest.services.network.json import network_client as json_network_client
from tempest.tests import base
from tempest.tests import fake_config
@@ -70,7 +72,7 @@
def _mock_user_create(self, id, name):
user_fix = self.useFixture(mockpatch.PatchObject(
- json_iden_client.IdentityClient,
+ json_users_client.UsersClient,
'create_user',
return_value=(service_client.ResponseBody
(200, {'user': {'id': id, 'name': name}}))))
@@ -125,7 +127,7 @@
def _mock_list_ec2_credentials(self, user_id, tenant_id):
ec2_creds_fix = self.useFixture(mockpatch.PatchObject(
- json_iden_client.IdentityClient,
+ json_users_client.UsersClient,
'list_user_ec2_credentials',
return_value=(service_client.ResponseBody
(200, {'credentials': [{
@@ -241,8 +243,8 @@
self._mock_list_roles('123456', 'admin')
creds.get_admin_creds()
user_mock = self.patch(
- 'tempest.services.identity.v2.json.identity_client.'
- 'IdentityClient.delete_user')
+ 'tempest.services.identity.v2.json.users_client.'
+ 'UsersClient.delete_user')
tenant_mock = self.patch(
'tempest.services.identity.v2.json.tenants_client.'
'TenantsClient.delete_tenant')
@@ -322,7 +324,7 @@
'tempest.services.network.json.network_client.NetworkClient.'
'add_router_interface_with_subnet_id')
primary_creds = creds.get_primary_creds()
- router_interface_mock.called_once_with('1234', '1234')
+ router_interface_mock.assert_called_once_with('1234', '1234')
network = primary_creds.network
subnet = primary_creds.subnet
router = primary_creds.router
@@ -354,7 +356,7 @@
'tempest.services.network.json.network_client.NetworkClient.'
'add_router_interface_with_subnet_id')
creds.get_primary_creds()
- router_interface_mock.called_once_with('1234', '1234')
+ router_interface_mock.assert_called_once_with('1234', '1234')
router_interface_mock.reset_mock()
# Create alternate tenant and network
self._mock_user_create('12345', 'fake_alt_user')
@@ -363,7 +365,7 @@
self._mock_subnet_create(creds, '12345', 'fake_alt_subnet')
self._mock_router_create('12345', 'fake_alt_router')
creds.get_alt_creds()
- router_interface_mock.called_once_with('12345', '12345')
+ router_interface_mock.assert_called_once_with('12345', '12345')
router_interface_mock.reset_mock()
# Create admin tenant and networks
self._mock_user_create('123456', 'fake_admin_user')
@@ -373,8 +375,8 @@
self._mock_router_create('123456', 'fake_admin_router')
self._mock_list_roles('123456', 'admin')
creds.get_admin_creds()
- self.patch('tempest.services.identity.v2.json.identity_client.'
- 'IdentityClient.delete_user')
+ self.patch('tempest.services.identity.v2.json.users_client.'
+ 'UsersClient.delete_user')
self.patch('tempest.services.identity.v2.json.tenants_client.'
'TenantsClient.delete_tenant')
net = mock.patch.object(creds.networks_admin_client,
@@ -461,7 +463,7 @@
'tempest.services.network.json.network_client.NetworkClient.'
'add_router_interface_with_subnet_id')
alt_creds = creds.get_alt_creds()
- router_interface_mock.called_once_with('1234', '1234')
+ router_interface_mock.assert_called_once_with('1234', '1234')
network = alt_creds.network
subnet = alt_creds.subnet
router = alt_creds.router
@@ -486,7 +488,7 @@
'add_router_interface_with_subnet_id')
self._mock_list_roles('123456', 'admin')
admin_creds = creds.get_admin_creds()
- router_interface_mock.called_once_with('1234', '1234')
+ router_interface_mock.assert_called_once_with('1234', '1234')
network = admin_creds.network
subnet = admin_creds.subnet
router = admin_creds.router
diff --git a/tools/check_logs.py b/tools/check_logs.py
index c8d3a1a..9b707b0 100755
--- a/tools/check_logs.py
+++ b/tools/check_logs.py
@@ -19,7 +19,7 @@
import gzip
import os
import re
-import StringIO
+import six
import sys
import urllib2
@@ -71,7 +71,7 @@
req = urllib2.Request(url)
req.add_header('Accept-Encoding', 'gzip')
page = urllib2.urlopen(req)
- buf = StringIO.StringIO(page.read())
+ buf = six.StringIO(page.read())
f = gzip.GzipFile(fileobj=buf)
if scan_content(name, f.read().splitlines(), regexp, whitelist):
logs_with_errors.append(name)
diff --git a/tools/find_stack_traces.py b/tools/find_stack_traces.py
index 4862d01..49a42fe 100755
--- a/tools/find_stack_traces.py
+++ b/tools/find_stack_traces.py
@@ -18,7 +18,7 @@
import gzip
import pprint
import re
-import StringIO
+import six
import sys
import urllib2
@@ -68,7 +68,7 @@
req = urllib2.Request(url)
req.add_header('Accept-Encoding', 'gzip')
page = urllib2.urlopen(req)
- buf = StringIO.StringIO(page.read())
+ buf = six.StringIO(page.read())
f = gzip.GzipFile(fileobj=buf)
content = f.read()
diff --git a/tox.ini b/tox.ini
index fedd04c..832a7b3 100644
--- a/tox.ini
+++ b/tox.ini
@@ -34,7 +34,7 @@
sitepackages = {[tempestenv]sitepackages}
# 'all' includes slow tests
setenv = {[tempestenv]setenv}
- OS_TEST_TIMEOUT=1200
+ OS_TEST_TIMEOUT={env:OS_TEST_TIMEOUT:1200}
deps = {[tempestenv]deps}
commands =
find . -type f -name "*.pyc" -delete
@@ -44,7 +44,7 @@
sitepackages = True
# 'all' includes slow tests
setenv = {[tempestenv]setenv}
- OS_TEST_TIMEOUT=1200
+ OS_TEST_TIMEOUT={env:OS_TEST_TIMEOUT:1200}
deps = {[tempestenv]deps}
commands =
find . -type f -name "*.pyc" -delete