Merge "Add cleanup for endpoint tests"
diff --git a/.coveragerc b/.coveragerc
index c9b6467..51482d3 100644
--- a/.coveragerc
+++ b/.coveragerc
@@ -1,4 +1,4 @@
[run]
branch = True
source = tempest
-omit = tempest/tests/*,tempest/openstack/*
+omit = tempest/tests/*,tempest/scenario/test_*.py,tempest/api_schema/*,tempest/api/*
diff --git a/.gitignore b/.gitignore
index efba45e..d58b162 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,6 +16,9 @@
dist
build
.testrepository
+.idea
+.project
+.pydevproject
.coverage*
!.coveragerc
cover/
diff --git a/.mailmap b/.mailmap
index 5c37a5e..a43c0b9 100644
--- a/.mailmap
+++ b/.mailmap
@@ -1,9 +1,25 @@
-Ravikumar Venkatesan <ravikumar.venkatesan@hp.com> ravikumar-venkatesan <ravikumar.venkatesan@hp.com>
-Ravikumar Venkatesan <ravikumar.venkatesan@hp.com> ravikumar venkatesan <ravikumar.venkatesan@hp.com>
-Rohit Karajgi <rohit.karajgi@nttdata.com> Rohit Karajgi <rohit.karajgi@vertex.co.in>
-Jay Pipes <jaypipes@gmail.com> Jay Pipes <jpipes@librebox.gateway.2wire.net>
-Joe Gordon <joe.gordon0@gmail.com> <jogo@cloudscaling.com>
<brian.waldon@rackspace.com> <bcwaldon@gmail.com>
-Daryl Walleck <daryl.walleck@rackspace.com> dwalleck <daryl.walleck@rackspace.com>
<jeblair@hp.com> <corvus@inaugust.com>
<jeblair@hp.com> <james.blair@rackspace.com>
+Adam Gandelman <adamg@ubuntu.com> Adam Gandelman <adamg@canonical.com>
+Andrea Frittoli (andreaf) <andrea.frittoli@hpe.com> Andrea Frittoli (andreaf) <andrea.frittoli@hp.com>
+Andrea Frittoli (andreaf) <andrea.frittoli@hpe.com> Andrea Frittoli <andrea.frittoli@hp.com>
+Daryl Walleck <daryl.walleck@rackspace.com> dwalleck <daryl.walleck@rackspace.com>
+David Kranz <dkranz@redhat.com> David Kranz <david.kranz@qrclab.com>
+Ghanshyam <ghanshyam.mann@nectechnologies.in> Ghanshyam Mann <ghanshyam.mann@nectechnologies.in>
+Ghanshyam <ghanshyam.mann@nectechnologies.in> ghanshyam <ghanshyam.mann@nectechnologies.in>
+Jay Pipes <jaypipes@gmail.com> Jay Pipes <jpipes@librebox.gateway.2wire.net>
+Joe Gordon <joe.gordon0@gmail.com> <jogo@cloudscaling.com>
+Ken'ichi Ohmichi <ken-oomichi@wx.jp.nec.com> Ken'ichi Ohmichi <oomichi@mxs.nes.nec.co.jp>
+Marc Koderer <marc@koderer.com> Marc Koderer <m.koderer@telekom.de>
+Masayuki Igawa <masayuki.igawa@gmail.com> Masayuki Igawa <igawa@mxs.nes.nec.co.jp>
+Masayuki Igawa <masayuki.igawa@gmail.com> Masayuki Igawa <mas-igawa@ut.jp.nec.com>
+Matthew Treinish <mtreinish@kortar.org> Matthew Treinish <treinish@linux.vnet.ibm.com>
+Nayna Patel <nayna.patel@hp.com> nayna-patel <nayna.patel@hp.com>
+ravikumar-venkatesan <ravikumar.venkatesan@hp.com> Ravikumar Venkatesan <ravikumar.venkatesan@hp.com>
+ravikumar-venkatesan <ravikumar.venkatesan@hp.com> ravikumar venkatesan <ravikumar.venkatesan@hp.com>
+Rohit Karajgi <rohit.karajgi@nttdata.com> Rohit Karajgi <rohit.karajgi@vertex.co.in>
+Sean Dague <sean@dague.net> Sean Dague <sdague@linux.vnet.ibm.com>
+Sean Dague <sean@dague.net> Sean Dague <sean.dague@samsung.com>
+Yuiko Takada <takada-yuiko@mxn.nes.nec.co.jp> YuikoTakada <takada-yuiko@mxn.nes.nec.co.jp>
+Zhi Kun Liu <zhikunli@cn.ibm.com> Liu, Zhi Kun <zhikunli@cn.ibm.com>
diff --git a/requirements.txt b/requirements.txt
index aa304a4..66e5696 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,27 +1,27 @@
# The order of packages is significant, because pip processes them in the order
# of appearance. Changing the order has an impact on the overall integration
# process, which may cause wedges in the gate later.
-pbr>=1.6
-cliff>=1.15.0 # Apache-2.0
-anyjson>=0.3.3
-httplib2>=0.7.5
-jsonschema!=2.5.0,<3.0.0,>=2.0.0
-testtools>=1.4.0
-paramiko>=1.13.0
-netaddr!=0.7.16,>=0.7.12
-testrepository>=0.0.18
-pyOpenSSL>=0.14
+pbr>=1.6 # Apache-2.0
+cliff!=1.16.0,>=1.15.0 # Apache-2.0
+anyjson>=0.3.3 # BSD
+httplib2>=0.7.5 # MIT
+jsonschema!=2.5.0,<3.0.0,>=2.0.0 # MIT
+testtools>=1.4.0 # MIT
+paramiko>=1.16.0 # LGPL
+netaddr!=0.7.16,>=0.7.12 # BSD
+testrepository>=0.0.18 # Apache-2.0/BSD
+pyOpenSSL>=0.14 # Apache-2.0
oslo.concurrency>=2.3.0 # Apache-2.0
-oslo.config>=3.2.0 # Apache-2.0
-oslo.i18n>=1.5.0 # Apache-2.0
+oslo.config>=3.4.0 # Apache-2.0
+oslo.i18n>=2.1.0 # Apache-2.0
oslo.log>=1.14.0 # Apache-2.0
oslo.serialization>=1.10.0 # Apache-2.0
-oslo.utils>=3.2.0 # Apache-2.0
-six>=1.9.0
-iso8601>=0.1.9
-fixtures>=1.3.1
-testscenarios>=0.4
-tempest-lib>=0.13.0
-PyYAML>=3.1.0
+oslo.utils>=3.4.0 # Apache-2.0
+six>=1.9.0 # MIT
+iso8601>=0.1.9 # MIT
+fixtures>=1.3.1 # Apache-2.0/BSD
+testscenarios>=0.4 # Apache-2.0/BSD
+tempest-lib>=0.14.0 # Apache-2.0
+PyYAML>=3.1.0 # MIT
stevedore>=1.5.0 # Apache-2.0
-PrettyTable<0.8,>=0.7
+PrettyTable<0.8,>=0.7 # BSD
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/base.py b/tempest/api/compute/base.py
index 6d19ca7..0856983 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -23,6 +23,7 @@
from tempest.common.utils import data_utils
from tempest.common import waiters
from tempest import config
+from tempest import exceptions
import tempest.test
CONF = config.CONF
@@ -356,16 +357,19 @@
def get_server_ip(cls, server):
"""Get the server fixed or floating IP.
- For the floating IP, the address created by the validation resources
- is returned.
- For the fixed IP, the server is returned and the current mechanism of
- address extraction in the remote_client is followed.
+ Based on the configuration we're in, return a correct ip
+ address for validating that a guest is up.
"""
if CONF.validation.connect_method == 'floating':
- ip_or_server = cls.validation_resources['floating_ip']['ip']
+ return cls.validation_resources['floating_ip']['ip']
elif CONF.validation.connect_method == 'fixed':
- ip_or_server = server
- return ip_or_server
+ addresses = server['addresses'][CONF.validation.network_for_ssh]
+ for address in addresses:
+ if address['version'] == CONF.validation.ip_version_for_ssh:
+ return address['addr']
+ raise exceptions.ServerUnreachable()
+ else:
+ raise exceptions.InvalidConfiguration()
class BaseV2ComputeAdminTest(BaseV2ComputeTest):
diff --git a/tempest/api/compute/images/test_images_negative.py b/tempest/api/compute/images/test_images_negative.py
index 8f6ede9..8706566 100644
--- a/tempest/api/compute/images/test_images_negative.py
+++ b/tempest/api/compute/images/test_images_negative.py
@@ -68,7 +68,7 @@
resp = {}
resp['status'] = None
self.assertRaises(lib_exc.NotFound, self.create_image_from_server,
- '!@#$%^&*()', name=name, meta=meta)
+ '!@$%^&*()', name=name, meta=meta)
@test.attr(type=['negative'])
@test.idempotent_id('ec176029-73dc-4037-8d72-2e4ff60cf538')
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/security_groups/test_security_group_rules.py b/tempest/api/compute/security_groups/test_security_group_rules.py
index 9aa59f7..38c294b 100644
--- a/tempest/api/compute/security_groups/test_security_group_rules.py
+++ b/tempest/api/compute/security_groups/test_security_group_rules.py
@@ -158,7 +158,9 @@
to_port=to_port2)['security_group_rule']
rule2_id = rule['id']
# Delete the Security Group rule2 at the end of this method
- self.addCleanup(self.client.delete_security_group_rule, rule2_id)
+ self.addCleanup(
+ self.security_group_rules_client.delete_security_group_rule,
+ rule2_id)
# Get rules of the created Security Group
rules = self.security_groups_client.show_security_group(
diff --git a/tempest/api/compute/servers/test_list_server_filters.py b/tempest/api/compute/servers/test_list_server_filters.py
index d1ec064..37f322f 100644
--- a/tempest/api/compute/servers/test_list_server_filters.py
+++ b/tempest/api/compute/servers/test_list_server_filters.py
@@ -13,6 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
+from tempest_lib import decorators
from tempest_lib import exceptions as lib_exc
from tempest.api.compute import base
@@ -290,6 +291,7 @@
self.assertNotIn(self.s2_name, map(lambda x: x['name'], servers))
self.assertNotIn(self.s3_name, map(lambda x: x['name'], servers))
+ @decorators.skip_because(bug="1540645")
@test.idempotent_id('a905e287-c35e-42f2-b132-d02b09f3654a')
def test_list_servers_filtered_by_ip_regex(self):
# Filter servers by regex ip
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/identity/admin/v2/test_endpoints.py b/tempest/api/identity/admin/v2/test_endpoints.py
index bff4f91..df75d0a 100644
--- a/tempest/api/identity/admin/v2/test_endpoints.py
+++ b/tempest/api/identity/admin/v2/test_endpoints.py
@@ -27,7 +27,7 @@
s_name = data_utils.rand_name('service')
s_type = data_utils.rand_name('type')
s_description = data_utils.rand_name('description')
- cls.service_data = cls.client.create_service(
+ cls.service_data = cls.services_client.create_service(
s_name, s_type, description=s_description)['OS-KSADM:service']
cls.service_id = cls.service_data['id']
cls.service_ids.append(cls.service_id)
@@ -36,11 +36,12 @@
for i in range(2):
region = data_utils.rand_name('region')
url = data_utils.rand_url()
- endpoint = cls.client.create_endpoint(cls.service_id,
- region,
- publicurl=url,
- adminurl=url,
- internalurl=url)['endpoint']
+ endpoint = cls.endpoints_client.create_endpoint(
+ cls.service_id,
+ region,
+ publicurl=url,
+ adminurl=url,
+ internalurl=url)['endpoint']
# list_endpoints() will return 'enabled' field
endpoint['enabled'] = True
cls.setup_endpoints.append(endpoint)
@@ -48,15 +49,15 @@
@classmethod
def resource_cleanup(cls):
for e in cls.setup_endpoints:
- cls.client.delete_endpoint(e['id'])
+ cls.endpoints_client.delete_endpoint(e['id'])
for s in cls.service_ids:
- cls.client.delete_service(s)
+ cls.services_client.delete_service(s)
super(EndPointsTestJSON, cls).resource_cleanup()
@test.idempotent_id('11f590eb-59d8-4067-8b2b-980c7f387f51')
def test_list_endpoints(self):
# Get a list of endpoints
- fetched_endpoints = self.client.list_endpoints()['endpoints']
+ fetched_endpoints = self.endpoints_client.list_endpoints()['endpoints']
# Asserting LIST endpoints
missing_endpoints =\
[e for e in self.setup_endpoints if e not in fetched_endpoints]
@@ -68,22 +69,23 @@
def test_create_list_delete_endpoint(self):
region = data_utils.rand_name('region')
url = data_utils.rand_url()
- endpoint = self.client.create_endpoint(self.service_id,
- region,
- publicurl=url,
- adminurl=url,
- internalurl=url)['endpoint']
+ endpoint = self.endpoints_client.create_endpoint(
+ self.service_id,
+ region,
+ publicurl=url,
+ adminurl=url,
+ internalurl=url)['endpoint']
# Asserting Create Endpoint response body
self.assertIn('id', endpoint)
self.assertEqual(region, endpoint['region'])
self.assertEqual(url, endpoint['publicurl'])
# Checking if created endpoint is present in the list of endpoints
- fetched_endpoints = self.client.list_endpoints()['endpoints']
+ fetched_endpoints = self.endpoints_client.list_endpoints()['endpoints']
fetched_endpoints_id = [e['id'] for e in fetched_endpoints]
self.assertIn(endpoint['id'], fetched_endpoints_id)
# Deleting the endpoint created in this method
- self.client.delete_endpoint(endpoint['id'])
+ self.endpoints_client.delete_endpoint(endpoint['id'])
# Checking whether endpoint is deleted successfully
- fetched_endpoints = self.client.list_endpoints()['endpoints']
+ fetched_endpoints = self.endpoints_client.list_endpoints()['endpoints']
fetched_endpoints_id = [e['id'] for e in fetched_endpoints]
self.assertNotIn(endpoint['id'], fetched_endpoints_id)
diff --git a/tempest/api/identity/admin/v2/test_roles.py b/tempest/api/identity/admin/v2/test_roles.py
index 3f3d16e..5847129 100644
--- a/tempest/api/identity/admin/v2/test_roles.py
+++ b/tempest/api/identity/admin/v2/test_roles.py
@@ -33,9 +33,9 @@
def _get_role_params(self):
self.data.setup_test_user()
self.data.setup_test_role()
- user = self.get_user_by_name(self.data.test_user)
- tenant = self.get_tenant_by_name(self.data.test_tenant)
- role = self.get_role_by_name(self.data.test_role)
+ user = self.get_user_by_name(self.data.user['name'])
+ tenant = self.get_tenant_by_name(self.data.tenant['name'])
+ role = self.get_role_by_name(self.data.role['name'])
return (user, tenant, role)
def assert_role_in_role_list(self, role, roles):
diff --git a/tempest/api/identity/admin/v2/test_roles_negative.py b/tempest/api/identity/admin/v2/test_roles_negative.py
index c9af7c6..23a1958 100644
--- a/tempest/api/identity/admin/v2/test_roles_negative.py
+++ b/tempest/api/identity/admin/v2/test_roles_negative.py
@@ -27,9 +27,9 @@
def _get_role_params(self):
self.data.setup_test_user()
self.data.setup_test_role()
- user = self.get_user_by_name(self.data.test_user)
- tenant = self.get_tenant_by_name(self.data.test_tenant)
- role = self.get_role_by_name(self.data.test_role)
+ user = self.get_user_by_name(self.data.user['name'])
+ tenant = self.get_tenant_by_name(self.data.tenant['name'])
+ role = self.get_role_by_name(self.data.role['name'])
return (user, tenant, role)
@test.attr(type=['negative'])
diff --git a/tempest/api/identity/admin/v2/test_services.py b/tempest/api/identity/admin/v2/test_services.py
index 04e15d2..5685922 100644
--- a/tempest/api/identity/admin/v2/test_services.py
+++ b/tempest/api/identity/admin/v2/test_services.py
@@ -25,9 +25,9 @@
def _del_service(self, service_id):
# Deleting the service created in this method
- self.client.delete_service(service_id)
+ self.services_client.delete_service(service_id)
# Checking whether service is deleted successfully
- self.assertRaises(lib_exc.NotFound, self.client.show_service,
+ self.assertRaises(lib_exc.NotFound, self.services_client.show_service,
service_id)
@test.idempotent_id('84521085-c6e6-491c-9a08-ec9f70f90110')
@@ -37,7 +37,7 @@
name = data_utils.rand_name('service')
type = data_utils.rand_name('type')
description = data_utils.rand_name('description')
- service_data = self.client.create_service(
+ service_data = self.services_client.create_service(
name, type, description=description)['OS-KSADM:service']
self.assertFalse(service_data['id'] is None)
self.addCleanup(self._del_service, service_data['id'])
@@ -50,8 +50,9 @@
self.assertIn('description', service_data)
self.assertEqual(description, service_data['description'])
# Get service
- fetched_service = (self.client.show_service(service_data['id'])
- ['OS-KSADM:service'])
+ fetched_service = (
+ self.services_client.show_service(service_data['id'])
+ ['OS-KSADM:service'])
# verifying the existence of service created
self.assertIn('id', fetched_service)
self.assertEqual(fetched_service['id'], service_data['id'])
@@ -68,7 +69,8 @@
# Create a service only with name and type
name = data_utils.rand_name('service')
type = data_utils.rand_name('type')
- service = self.client.create_service(name, type)['OS-KSADM:service']
+ service = self.services_client.create_service(name,
+ type)['OS-KSADM:service']
self.assertIn('id', service)
self.addCleanup(self._del_service, service['id'])
self.assertIn('name', service)
@@ -85,17 +87,17 @@
name = data_utils.rand_name('service')
type = data_utils.rand_name('type')
description = data_utils.rand_name('description')
- service = self.client.create_service(
+ service = self.services_client.create_service(
name, type, description=description)['OS-KSADM:service']
services.append(service)
service_ids = map(lambda x: x['id'], services)
def delete_services():
for service_id in service_ids:
- self.client.delete_service(service_id)
+ self.services_client.delete_service(service_id)
self.addCleanup(delete_services)
# List and Verify Services
- body = self.client.list_services()['OS-KSADM:services']
+ body = self.services_client.list_services()['OS-KSADM:services']
found = [serv for serv in body if serv['id'] in service_ids]
self.assertEqual(len(found), len(services), 'Services not found')
diff --git a/tempest/api/identity/admin/v2/test_users.py b/tempest/api/identity/admin/v2/test_users.py
index 4497575..60c4e97 100644
--- a/tempest/api/identity/admin/v2/test_users.py
+++ b/tempest/api/identity/admin/v2/test_users.py
@@ -95,27 +95,29 @@
# Valid user's token is authenticated
self.data.setup_test_user()
# Get a token
- self.token_client.auth(self.data.test_user, self.data.test_password,
- self.data.test_tenant)
+ self.token_client.auth(self.data.user['name'],
+ self.data.user_password,
+ self.data.tenant['name'])
# Re-auth
- self.token_client.auth(self.data.test_user,
- self.data.test_password,
- self.data.test_tenant)
+ self.token_client.auth(self.data.user['name'],
+ self.data.user_password,
+ self.data.tenant['name'])
@test.idempotent_id('5d1fa498-4c2d-4732-a8fe-2b054598cfdd')
def test_authentication_request_without_token(self):
# Request for token authentication with a valid token in header
self.data.setup_test_user()
- self.token_client.auth(self.data.test_user, self.data.test_password,
- self.data.test_tenant)
+ self.token_client.auth(self.data.user['name'],
+ self.data.user_password,
+ self.data.tenant['name'])
# Get the token of the current client
token = self.client.auth_provider.get_token()
# Delete the token from database
self.client.delete_token(token)
# Re-auth
- self.token_client.auth(self.data.test_user,
- self.data.test_password,
- self.data.test_tenant)
+ self.token_client.auth(self.data.user['name'],
+ self.data.user_password,
+ self.data.tenant['name'])
self.client.auth_provider.clear_auth()
@test.idempotent_id('a149c02e-e5e0-4b89-809e-7e8faf33ccda')
@@ -124,8 +126,8 @@
self.data.setup_test_user()
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)
+ matchers.Contains(self.data.user['name']),
+ "Could not find %s" % self.data.user['name'])
@test.idempotent_id('6e317209-383a-4bed-9f10-075b7c82c79a')
def test_list_users_for_tenant(self):
@@ -164,9 +166,9 @@
# Return list of users on tenant when roles are assigned to users
self.data.setup_test_user()
self.data.setup_test_role()
- user = self.get_user_by_name(self.data.test_user)
- tenant = self.get_tenant_by_name(self.data.test_tenant)
- role = self.get_role_by_name(self.data.test_role)
+ user = self.get_user_by_name(self.data.user['name'])
+ tenant = self.get_tenant_by_name(self.data.tenant['name'])
+ role = self.get_role_by_name(self.data.role['name'])
# Assigning roles to two users
user_ids = list()
fetched_user_ids = list()
@@ -208,6 +210,6 @@
# Validate the updated password
# Get a token
- body = self.token_client.auth(self.data.test_user, new_pass,
- self.data.test_tenant)
+ body = self.token_client.auth(self.data.user['name'], new_pass,
+ self.data.tenant['name'])
self.assertTrue('id' in body['token'])
diff --git a/tempest/api/identity/admin/v2/test_users_negative.py b/tempest/api/identity/admin/v2/test_users_negative.py
index c5248fd..0a5d0c9 100644
--- a/tempest/api/identity/admin/v2/test_users_negative.py
+++ b/tempest/api/identity/admin/v2/test_users_negative.py
@@ -66,8 +66,8 @@
# Duplicate user should not be created
self.data.setup_test_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)
+ self.data.user['name'], self.data.user_password,
+ self.data.tenant['id'], self.data.user['email'])
@test.attr(type=['negative'])
@test.idempotent_id('0132cc22-7c4f-42e1-9e50-ac6aad31d59a')
@@ -173,22 +173,22 @@
def test_authentication_for_disabled_user(self):
# Disabled user's token should not get authenticated
self.data.setup_test_user()
- self.disable_user(self.data.test_user)
+ self.disable_user(self.data.user['name'])
self.assertRaises(lib_exc.Unauthorized, self.token_client.auth,
- self.data.test_user,
- self.data.test_password,
- self.data.test_tenant)
+ self.data.user['name'],
+ self.data.user_password,
+ self.data.tenant['name'])
@test.attr(type=['negative'])
@test.idempotent_id('440a7a8d-9328-4b7b-83e0-d717010495e4')
def test_authentication_when_tenant_is_disabled(self):
# User's token for a disabled tenant should not be authenticated
self.data.setup_test_user()
- self.disable_tenant(self.data.test_tenant)
+ self.disable_tenant(self.data.tenant['name'])
self.assertRaises(lib_exc.Unauthorized, self.token_client.auth,
- self.data.test_user,
- self.data.test_password,
- self.data.test_tenant)
+ self.data.user['name'],
+ self.data.user_password,
+ self.data.tenant['name'])
@test.attr(type=['negative'])
@test.idempotent_id('921f1ad6-7907-40b8-853f-637e7ee52178')
@@ -196,8 +196,8 @@
# User's token for an invalid tenant should not be authenticated
self.data.setup_test_user()
self.assertRaises(lib_exc.Unauthorized, self.token_client.auth,
- self.data.test_user,
- self.data.test_password,
+ self.data.user['name'],
+ self.data.user_password,
'junktenant1234')
@test.attr(type=['negative'])
@@ -206,8 +206,8 @@
# Non-existent user's token should not get authenticated
self.data.setup_test_user()
self.assertRaises(lib_exc.Unauthorized, self.token_client.auth,
- 'junkuser123', self.data.test_password,
- self.data.test_tenant)
+ 'junkuser123', self.data.user_password,
+ self.data.tenant['name'])
@test.attr(type=['negative'])
@test.idempotent_id('d5308b33-3574-43c3-8d87-1c090c5e1eca')
@@ -215,8 +215,8 @@
# User's token with invalid password should not be authenticated
self.data.setup_test_user()
self.assertRaises(lib_exc.Unauthorized, self.token_client.auth,
- self.data.test_user, 'junkpass1234',
- self.data.test_tenant)
+ self.data.user['name'], 'junkpass1234',
+ self.data.tenant['name'])
@test.attr(type=['negative'])
@test.idempotent_id('284192ce-fb7c-4909-a63b-9a502e0ddd11')
diff --git a/tempest/api/identity/admin/v3/test_domains.py b/tempest/api/identity/admin/v3/test_domains.py
index 15bea28..1729dc9 100644
--- a/tempest/api/identity/admin/v3/test_domains.py
+++ b/tempest/api/identity/admin/v3/test_domains.py
@@ -85,7 +85,7 @@
self.assertEqual(new_desc, updated_domain['description'])
self.assertEqual(True, updated_domain['enabled'])
- fetched_domain = self.client.get_domain(domain['id'])['domain']
+ fetched_domain = self.client.show_domain(domain['id'])['domain']
self.assertEqual(new_name, fetched_domain['name'])
self.assertEqual(new_desc, fetched_domain['description'])
self.assertEqual(True, fetched_domain['enabled'])
@@ -124,6 +124,6 @@
@test.attr(type='smoke')
@test.idempotent_id('17a5de24-e6a0-4e4a-a9ee-d85b6e5612b5')
def test_default_domain_exists(self):
- domain = self.client.get_domain(self.domain_id)['domain']
+ domain = self.client.show_domain(self.domain_id)['domain']
self.assertTrue(domain['enabled'])
diff --git a/tempest/api/identity/admin/v3/test_groups.py b/tempest/api/identity/admin/v3/test_groups.py
index 21fc62a..03b8b29 100644
--- a/tempest/api/identity/admin/v3/test_groups.py
+++ b/tempest/api/identity/admin/v3/test_groups.py
@@ -76,8 +76,10 @@
# list users in group
group_users = self.groups_client.list_group_users(group['id'])['users']
self.assertEqual(sorted(users), sorted(group_users))
- # delete user in group
+ # check and delete user in group
for user in users:
+ self.groups_client.check_group_user_existence(
+ group['id'], user['id'])
self.groups_client.delete_group_user(group['id'], user['id'])
group_users = self.groups_client.list_group_users(group['id'])['users']
self.assertEqual(len(group_users), 0)
diff --git a/tempest/api/identity/admin/v3/test_list_projects.py b/tempest/api/identity/admin/v3/test_list_projects.py
index 5185fea..aaed467 100644
--- a/tempest/api/identity/admin/v3/test_list_projects.py
+++ b/tempest/api/identity/admin/v3/test_list_projects.py
@@ -44,8 +44,8 @@
list_projects = self.client.list_projects()['projects']
for p in self.project_ids:
- get_project = self.client.get_project(p)['project']
- self.assertIn(get_project, list_projects)
+ show_project = self.client.show_project(p)['project']
+ self.assertIn(show_project, list_projects)
@test.idempotent_id('fab13f3c-f6a6-4b9f-829b-d32fd44fdf10')
def test_list_projects_with_domains(self):
diff --git a/tempest/api/identity/admin/v3/test_list_users.py b/tempest/api/identity/admin/v3/test_list_users.py
index ca91ce5..4921c00 100644
--- a/tempest/api/identity/admin/v3/test_list_users.py
+++ b/tempest/api/identity/admin/v3/test_list_users.py
@@ -42,13 +42,13 @@
cls.domain_enabled_user = cls.client.create_user(
u1_name, password=alt_password,
email=cls.alt_email, domain_id=cls.data.domain['id'])['user']
- cls.data.v3_users.append(cls.domain_enabled_user)
+ cls.data.users.append(cls.domain_enabled_user)
# Create default not enabled user
u2_name = data_utils.rand_name('test_user')
cls.non_domain_enabled_user = cls.client.create_user(
u2_name, password=alt_password,
email=cls.alt_email, enabled=False)['user']
- cls.data.v3_users.append(cls.non_domain_enabled_user)
+ cls.data.users.append(cls.non_domain_enabled_user)
@test.idempotent_id('08f9aabb-dcfe-41d0-8172-82b5fa0bd73d')
def test_list_user_domains(self):
@@ -79,7 +79,7 @@
# List users
body = self.client.list_users()['users']
fetched_ids = [u['id'] for u in body]
- missing_users = [u['id'] for u in self.data.v3_users
+ missing_users = [u['id'] for u in self.data.users
if u['id'] not in fetched_ids]
self.assertEqual(0, len(missing_users),
"Failed to find user %s in fetched list" %
@@ -88,8 +88,8 @@
@test.idempotent_id('b4baa3ae-ac00-4b4e-9e27-80deaad7771f')
def test_get_user(self):
# Get a user detail
- user = self.client.show_user(self.data.v3_users[0]['id'])['user']
- self.assertEqual(self.data.v3_users[0]['id'], user['id'])
- self.assertEqual(self.data.v3_users[0]['name'], user['name'])
+ user = self.client.show_user(self.data.users[0]['id'])['user']
+ self.assertEqual(self.data.users[0]['id'], user['id'])
+ self.assertEqual(self.data.users[0]['name'], user['name'])
self.assertEqual(self.alt_email, user['email'])
self.assertEqual(self.data.domain['id'], user['domain_id'])
diff --git a/tempest/api/identity/admin/v3/test_projects.py b/tempest/api/identity/admin/v3/test_projects.py
index af9497c..2f4cc51 100644
--- a/tempest/api/identity/admin/v3/test_projects.py
+++ b/tempest/api/identity/admin/v3/test_projects.py
@@ -32,7 +32,7 @@
desc1 = project['description']
self.assertEqual(desc1, project_desc, 'Description should have '
'been sent in response for create')
- body = self.client.get_project(project_id)['project']
+ body = self.client.show_project(project_id)['project']
desc2 = body['description']
self.assertEqual(desc2, project_desc, 'Description does not appear'
'to be set')
@@ -48,7 +48,7 @@
project_id = project['id']
self.assertEqual(project_name, project['name'])
self.assertEqual(self.data.domain['id'], project['domain_id'])
- body = self.client.get_project(project_id)['project']
+ body = self.client.show_project(project_id)['project']
self.assertEqual(project_name, body['name'])
self.assertEqual(self.data.domain['id'], body['domain_id'])
@@ -62,7 +62,7 @@
project_id = project['id']
en1 = project['enabled']
self.assertTrue(en1, 'Enable should be True in response')
- body = self.client.get_project(project_id)['project']
+ body = self.client.show_project(project_id)['project']
en2 = body['enabled']
self.assertTrue(en2, 'Enable should be True in lookup')
@@ -76,7 +76,7 @@
en1 = project['enabled']
self.assertEqual('false', str(en1).lower(),
'Enable should be False in response')
- body = self.client.get_project(project['id'])['project']
+ body = self.client.show_project(project['id'])['project']
en2 = body['enabled']
self.assertEqual('false', str(en2).lower(),
'Enable should be False in lookup')
@@ -96,7 +96,7 @@
resp2_name = body['name']
self.assertNotEqual(resp1_name, resp2_name)
- body = self.client.get_project(project['id'])['project']
+ body = self.client.show_project(project['id'])['project']
resp3_name = body['name']
self.assertNotEqual(resp1_name, resp3_name)
@@ -119,7 +119,7 @@
resp2_desc = body['description']
self.assertNotEqual(resp1_desc, resp2_desc)
- body = self.client.get_project(project['id'])['project']
+ body = self.client.show_project(project['id'])['project']
resp3_desc = body['description']
self.assertNotEqual(resp1_desc, resp3_desc)
@@ -142,7 +142,7 @@
resp2_en = body['enabled']
self.assertNotEqual(resp1_en, resp2_en)
- body = self.client.get_project(project['id'])['project']
+ body = self.client.show_project(project['id'])['project']
resp3_en = body['enabled']
self.assertNotEqual(resp1_en, resp3_en)
diff --git a/tempest/api/identity/admin/v3/test_roles.py b/tempest/api/identity/admin/v3/test_roles.py
index ae714aa..f1f06ee 100644
--- a/tempest/api/identity/admin/v3/test_roles.py
+++ b/tempest/api/identity/admin/v3/test_roles.py
@@ -26,7 +26,7 @@
for _ in range(3):
role_name = data_utils.rand_name(name='role')
role = cls.client.create_role(name=role_name)['role']
- cls.data.v3_roles.append(role)
+ cls.data.roles.append(role)
cls.fetched_role_ids = list()
u_name = data_utils.rand_name('user')
u_desc = '%s description' % u_name
@@ -103,6 +103,9 @@
self._list_assertions(roles, self.fetched_role_ids,
self.role['id'])
+ self.client.check_user_role_existence_on_project(
+ self.project['id'], self.user_body['id'], self.role['id'])
+
self.client.delete_role_from_user_on_project(
self.project['id'], self.user_body['id'], self.role['id'])
@@ -120,6 +123,9 @@
self._list_assertions(roles, self.fetched_role_ids,
self.role['id'])
+ self.client.check_user_role_existence_on_domain(
+ self.domain['id'], self.user_body['id'], self.role['id'])
+
self.client.delete_role_from_user_on_domain(
self.domain['id'], self.user_body['id'], self.role['id'])
@@ -150,6 +156,10 @@
roles = body['token']['roles']
self.assertEqual(len(roles), 1)
self.assertEqual(roles[0]['id'], self.role['id'])
+
+ self.client.check_role_from_group_on_project_existence(
+ self.project['id'], self.group_body['id'], self.role['id'])
+
# Revoke role to group on project
self.client.delete_role_from_group_on_project(
self.project['id'], self.group_body['id'], self.role['id'])
@@ -168,6 +178,9 @@
self._list_assertions(roles, self.fetched_role_ids,
self.role['id'])
+ self.client.check_role_from_group_on_domain_existence(
+ self.domain['id'], self.group_body['id'], self.role['id'])
+
self.client.delete_role_from_group_on_domain(
self.domain['id'], self.group_body['id'], self.role['id'])
@@ -175,5 +188,5 @@
def test_list_roles(self):
# Return a list of all roles
body = self.client.list_roles()['roles']
- found = [role for role in body if role in self.data.v3_roles]
- self.assertEqual(len(found), len(self.data.v3_roles))
+ found = [role for role in body if role in self.data.roles]
+ self.assertEqual(len(found), len(self.data.roles))
diff --git a/tempest/api/identity/admin/v3/test_trusts.py b/tempest/api/identity/admin/v3/test_trusts.py
index 85961b4..2ffc596 100644
--- a/tempest/api/identity/admin/v3/test_trusts.py
+++ b/tempest/api/identity/admin/v3/test_trusts.py
@@ -139,8 +139,8 @@
self.assertEqual(self.delegated_role, trust['roles'][0]['name'])
self.assertEqual(1, len(trust['roles']))
- def get_trust(self):
- trust_get = self.trustor_client.get_trust(self.trust_id)['trust']
+ def show_trust(self):
+ trust_get = self.trustor_client.show_trust(self.trust_id)['trust']
return trust_get
def validate_role(self, role):
@@ -155,12 +155,12 @@
def check_trust_roles(self):
# Check we find the delegated role
- roles_get = self.trustor_client.get_trust_roles(
+ roles_get = self.trustor_client.list_trust_roles(
self.trust_id)['roles']
self.assertEqual(1, len(roles_get))
self.validate_role(roles_get[0])
- role_get = self.trustor_client.get_trust_role(
+ role_get = self.trustor_client.show_trust_role(
self.trust_id, self.delegated_role_id)['role']
self.validate_role(role_get)
@@ -169,7 +169,7 @@
# And that we don't find not_delegated_role
self.assertRaises(lib_exc.NotFound,
- self.trustor_client.get_trust_role,
+ self.trustor_client.show_trust_role,
self.trust_id,
self.not_delegated_role_id)
@@ -181,7 +181,7 @@
def delete_trust(self):
self.trustor_client.delete_trust(self.trust_id)
self.assertRaises(lib_exc.NotFound,
- self.trustor_client.get_trust,
+ self.trustor_client.show_trust,
self.trust_id)
self.trust_id = None
@@ -200,7 +200,7 @@
trust = self.create_trust()
self.validate_trust(trust)
- trust_get = self.get_trust()
+ trust_get = self.show_trust()
self.validate_trust(trust_get)
self.check_trust_roles()
@@ -212,7 +212,7 @@
trust = self.create_trust(impersonate=False)
self.validate_trust(trust, impersonate=False)
- trust_get = self.get_trust()
+ trust_get = self.show_trust()
self.validate_trust(trust_get, impersonate=False)
self.check_trust_roles()
@@ -236,7 +236,7 @@
trust = self.create_trust(expires=expires_str)
self.validate_trust(trust, expires=expires_str)
- trust_get = self.get_trust()
+ trust_get = self.show_trust()
self.validate_trust(trust_get, expires=expires_str)
@@ -255,7 +255,7 @@
@test.idempotent_id('6268b345-87ca-47c0-9ce3-37792b43403a')
def test_get_trusts_query(self):
self.create_trust()
- trusts_get = self.trustor_client.get_trusts(
+ trusts_get = self.trustor_client.list_trusts(
trustor_user_id=self.trustor_user_id)['trusts']
self.assertEqual(1, len(trusts_get))
self.validate_trust(trusts_get[0], summary=True)
@@ -264,7 +264,7 @@
@test.idempotent_id('4773ebd5-ecbf-4255-b8d8-b63e6f72b65d')
def test_get_trusts_all(self):
self.create_trust()
- trusts_get = self.client.get_trusts()['trusts']
+ trusts_get = self.client.list_trusts()['trusts']
trusts = [t for t in trusts_get
if t['id'] == self.trust_id]
self.assertEqual(1, len(trusts))
diff --git a/tempest/api/identity/admin/v3/test_users.py b/tempest/api/identity/admin/v3/test_users.py
index a402b3f..7c0c223 100644
--- a/tempest/api/identity/admin/v3/test_users.py
+++ b/tempest/api/identity/admin/v3/test_users.py
@@ -128,7 +128,7 @@
project_body = self.client.create_project(
data_utils.rand_name('project'),
description=data_utils.rand_name('project-desc'))['project']
- project = self.client.get_project(project_body['id'])['project']
+ project = self.client.show_project(project_body['id'])['project']
# Delete the Project at the end of this method
self.addCleanup(self.client.delete_project, project_body['id'])
# Assigning roles to user on project
@@ -151,6 +151,6 @@
@test.idempotent_id('c10dcd90-461d-4b16-8e23-4eb836c00644')
def test_get_user(self):
# Get a user detail
- self.data.setup_test_v3_user()
- user = self.client.show_user(self.data.v3_user['id'])['user']
- self.assertEqual(self.data.v3_user['id'], user['id'])
+ self.data.setup_test_user()
+ user = self.client.show_user(self.data.user['id'])['user']
+ self.assertEqual(self.data.user['id'], user['id'])
diff --git a/tempest/api/identity/admin/v3/test_users_negative.py b/tempest/api/identity/admin/v3/test_users_negative.py
index 4c80bda..39c89a5 100644
--- a/tempest/api/identity/admin/v3/test_users_negative.py
+++ b/tempest/api/identity/admin/v3/test_users_negative.py
@@ -38,9 +38,9 @@
@test.idempotent_id('b3c9fccc-4134-46f5-b600-1da6fb0a3b1f')
def test_authentication_for_disabled_user(self):
# Attempt to authenticate for disabled user should fail
- self.data.setup_test_v3_user()
- self.disable_user(self.data.test_user)
+ self.data.setup_test_user()
+ self.disable_user(self.data.user['name'])
self.assertRaises(lib_exc.Unauthorized, self.token.auth,
- username=self.data.test_user,
- password=self.data.test_password,
+ username=self.data.user['name'],
+ password=self.data.user_password,
user_domain_id='default')
diff --git a/tempest/api/identity/base.py b/tempest/api/identity/base.py
index 1ad8b92..d31569b 100644
--- a/tempest/api/identity/base.py
+++ b/tempest/api/identity/base.py
@@ -16,7 +16,6 @@
from oslo_log import log as logging
from tempest_lib import exceptions as lib_exc
-from tempest.common import credentials_factory as common_creds
from tempest.common.utils import data_utils
from tempest import config
import tempest.test
@@ -76,7 +75,6 @@
cls.non_admin_client = cls.os.identity_public_client
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
@@ -104,12 +102,14 @@
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
+ cls.services_client = cls.os_adm.services_v2_client
+ cls.endpoints_client = cls.os_adm.endpoints_v2_client
@classmethod
def resource_setup(cls):
super(BaseIdentityV2AdminTest, cls).resource_setup()
- cls.data = DataGenerator(cls.client, cls.tenants_client,
- cls.roles_client, cls.users_client)
+ cls.data = DataGeneratorV2(cls.client, cls.tenants_client,
+ cls.users_client, cls.roles_client)
@classmethod
def resource_cleanup(cls):
@@ -152,7 +152,10 @@
cls.creds_client = cls.os_adm.credentials_client
cls.groups_client = cls.os_adm.groups_client
- cls.data = DataGenerator(cls.client)
+ @classmethod
+ def resource_setup(cls):
+ super(BaseIdentityV3AdminTest, cls).resource_setup()
+ cls.data = DataGeneratorV3(cls.client)
@classmethod
def resource_cleanup(cls):
@@ -192,127 +195,98 @@
self.client.delete_domain(domain_id)
-class DataGenerator(object):
+class BaseDataGenerator(object):
- 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 = []
- self.role_name = None
- self.v3_users = []
- self.projects = []
- self.v3_roles = []
- self.domains = []
+ def __init__(self, client, projects_client=None,
+ users_client=None, roles_client=None):
+ self.client = client
+ self.projects_client = projects_client or client
+ self.users_client = users_client or client
+ self.roles_client = roles_client or client
- @property
- def test_credentials(self):
- return common_creds.get_credentials(username=self.test_user,
- user_id=self.user['id'],
- password=self.test_password,
- tenant_name=self.test_tenant,
- tenant_id=self.tenant['id'])
+ self.user_password = None
+ self.user = None
+ self.tenant = None
+ self.project = None
+ self.role = None
+ self.domain = None
- def setup_test_user(self):
- """Set up a test user."""
- self.setup_test_tenant()
- 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.users_client.create_user(self.test_user,
- self.test_password,
- self.tenant['id'],
- self.test_email)['user']
- self.users.append(self.user)
+ self.users = []
+ self.tenants = []
+ self.projects = []
+ self.roles = []
+ self.domains = []
- def setup_test_tenant(self):
- """Set up a test tenant."""
- self.test_tenant = data_utils.rand_name('test_tenant')
- self.test_description = data_utils.rand_name('desc')
- self.tenant = self.tenants_client.create_tenant(
- name=self.test_tenant,
- description=self.test_description)['tenant']
- self.tenants.append(self.tenant)
+ def _create_test_user(self, **kwargs):
+ username = data_utils.rand_name('test_user')
+ self.user_password = data_utils.rand_password()
+ self.user = self.users_client.create_user(
+ username, password=self.user_password,
+ email=username + '@testmail.tm', **kwargs)['user']
+ self.users.append(self.user)
- def setup_test_role(self):
- """Set up a test role."""
- self.test_role = data_utils.rand_name('role')
- self.role = self.roles_client.create_role(
- name=self.test_role)['role']
- self.roles.append(self.role)
+ def setup_test_role(self):
+ """Set up a test role."""
+ self.role = self.roles_client.create_role(
+ name=data_utils.rand_name('test_role'))['role']
+ self.roles.append(self.role)
- def setup_test_v3_user(self):
- """Set up a test v3 user."""
- self.setup_test_project()
- 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.v3_user = self.client.create_user(
- self.test_user,
- password=self.test_password,
- project_id=self.project['id'],
- email=self.test_email)['user']
- self.v3_users.append(self.v3_user)
+ @staticmethod
+ def _try_wrapper(func, item, **kwargs):
+ try:
+ func(item['id'], **kwargs)
+ except lib_exc.NotFound:
+ pass
+ except Exception:
+ LOG.exception("Unexpected exception occurred in %s deletion. "
+ "But ignored here." % item['id'])
- def setup_test_project(self):
- """Set up a test project."""
- self.test_project = data_utils.rand_name('test_project')
- self.test_description = data_utils.rand_name('desc')
- self.project = self.client.create_project(
- name=self.test_project,
- description=self.test_description)['project']
- self.projects.append(self.project)
+ def teardown_all(self):
+ for user in self.users:
+ self._try_wrapper(self.users_client.delete_user, user)
+ for tenant in self.tenants:
+ self._try_wrapper(self.projects_client.delete_tenant, tenant)
+ for project in self.projects:
+ self._try_wrapper(self.projects_client.delete_project, project)
+ for role in self.roles:
+ self._try_wrapper(self.roles_client.delete_role, role)
+ for domain in self.domains:
+ self._try_wrapper(self.client.update_domain, domain, enabled=False)
+ self._try_wrapper(self.client.delete_domain, domain)
- def setup_test_v3_role(self):
- """Set up a test v3 role."""
- self.test_role = data_utils.rand_name('role')
- self.v3_role = self.client.create_role(name=self.test_role)['role']
- self.v3_roles.append(self.v3_role)
- def setup_test_domain(self):
- """Set up a test domain."""
- self.test_domain = data_utils.rand_name('test_domain')
- self.test_description = data_utils.rand_name('desc')
- self.domain = self.client.create_domain(
- name=self.test_domain,
- description=self.test_description)['domain']
- self.domains.append(self.domain)
+class DataGeneratorV2(BaseDataGenerator):
- @staticmethod
- def _try_wrapper(func, item, **kwargs):
- try:
- if kwargs:
- func(item['id'], **kwargs)
- else:
- func(item['id'])
- except lib_exc.NotFound:
- pass
- except Exception:
- LOG.exception("Unexpected exception occurred in %s deletion."
- " But ignored here." % item['id'])
+ def setup_test_user(self):
+ """Set up a test user."""
+ self.setup_test_tenant()
+ self._create_test_user(tenant_id=self.tenant['id'])
- def teardown_all(self):
- # NOTE(masayukig): v3 client doesn't have v2 method.
- # (e.g. delete_tenant) So we need to check resources existence
- # before using client methods.
- for user in self.users:
- 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:
- self._try_wrapper(self.roles_client.delete_role, role)
- for v3_user in self.v3_users:
- self._try_wrapper(self.client.delete_user, v3_user)
- for v3_project in self.projects:
- self._try_wrapper(self.client.delete_project, v3_project)
- for v3_role in self.v3_roles:
- self._try_wrapper(self.client.delete_role, v3_role)
- for domain in self.domains:
- self._try_wrapper(self.client.update_domain, domain,
- enabled=False)
- self._try_wrapper(self.client.delete_domain, domain)
+ def setup_test_tenant(self):
+ """Set up a test tenant."""
+ self.tenant = self.projects_client.create_tenant(
+ name=data_utils.rand_name('test_tenant'),
+ description=data_utils.rand_name('desc'))['tenant']
+ self.tenants.append(self.tenant)
+
+
+class DataGeneratorV3(BaseDataGenerator):
+
+ def setup_test_user(self):
+ """Set up a test user."""
+ self.setup_test_project()
+ self._create_test_user(project_id=self.project['id'])
+
+ def setup_test_project(self):
+ """Set up a test project."""
+ self.project = self.projects_client.create_project(
+ name=data_utils.rand_name('test_project'),
+ description=data_utils.rand_name('desc'))['project']
+ self.projects.append(self.project)
+
+ def setup_test_domain(self):
+ """Set up a test domain."""
+ self.domain = self.client.create_domain(
+ name=data_utils.rand_name('test_domain'),
+ description=data_utils.rand_name('desc'))['domain']
+ self.domains.append(self.domain)
diff --git a/tempest/api/network/admin/test_dhcp_agent_scheduler.py b/tempest/api/network/admin/test_dhcp_agent_scheduler.py
index 5ff465b..fcb6fce 100644
--- a/tempest/api/network/admin/test_dhcp_agent_scheduler.py
+++ b/tempest/api/network/admin/test_dhcp_agent_scheduler.py
@@ -84,7 +84,7 @@
self._remove_network_from_dhcp_agent(network_id, agent)
def _remove_network_from_dhcp_agent(self, network_id, agent):
- self.admin_agents_client.remove_network_from_dhcp_agent(
+ self.admin_agents_client.delete_network_from_dhcp_agent(
agent_id=agent['id'],
network_id=network_id)
self.assertFalse(self._check_network_in_dhcp_agent(
diff --git a/tempest/api/network/admin/test_l3_agent_scheduler.py b/tempest/api/network/admin/test_l3_agent_scheduler.py
index c64cf77..78d6aea 100644
--- a/tempest/api/network/admin/test_l3_agent_scheduler.py
+++ b/tempest/api/network/admin/test_l3_agent_scheduler.py
@@ -80,8 +80,8 @@
cls.network = cls.create_network()
cls.subnet = cls.create_subnet(cls.network)
cls.port = cls.create_port(cls.network)
- cls.client.add_router_interface_with_port_id(
- cls.router['id'], cls.port['id'])
+ cls.client.add_router_interface(cls.router['id'],
+ port_id=cls.port['id'])
# NOTE: Sometimes we have seen this test fail with dvr in,
# multinode tests, since the dhcp port is not created before
# the test gets executed and so the router is not scheduled
@@ -99,8 +99,8 @@
@classmethod
def resource_cleanup(cls):
if cls.is_dvr_router:
- cls.client.remove_router_interface_with_port_id(
- cls.router['id'], cls.port['id'])
+ cls.client.remove_router_interface(cls.router['id'],
+ port_id=cls.port['id'])
super(L3AgentSchedulerTestJSON, cls).resource_cleanup()
@test.idempotent_id('b7ce6e89-e837-4ded-9b78-9ed3c9c6a45a')
@@ -110,7 +110,7 @@
@test.idempotent_id('9464e5e7-8625-49c3-8fd1-89c52be59d66')
def test_add_list_remove_router_on_l3_agent(self):
l3_agent_ids = list()
- self.admin_agents_client.add_router_to_l3_agent(
+ self.admin_agents_client.create_router_on_l3_agent(
self.agent['id'],
router_id=self.router['id'])
body = (
@@ -120,7 +120,7 @@
self.assertIn('agent_type', agent)
self.assertEqual('L3 agent', agent['agent_type'])
self.assertIn(self.agent['id'], l3_agent_ids)
- body = self.admin_agents_client.remove_router_from_l3_agent(
+ body = self.admin_agents_client.delete_router_from_l3_agent(
self.agent['id'],
self.router['id'])
# NOTE(afazekas): The deletion not asserted, because neutron
diff --git a/tempest/api/network/admin/test_quotas.py b/tempest/api/network/admin/test_quotas.py
index 45d35cf..8b32a94 100644
--- a/tempest/api/network/admin/test_quotas.py
+++ b/tempest/api/network/admin/test_quotas.py
@@ -18,6 +18,7 @@
from tempest.api.network import base
from tempest.common.utils import data_utils
from tempest import test
+from tempest_lib import exceptions as lib_exc
class QuotasTest(base.BaseAdminNetworkTest):
@@ -59,7 +60,7 @@
# Change quotas for tenant
quota_set = self.admin_quotas_client.update_quotas(
project_id, **new_quotas)['quota']
- self.addCleanup(self.admin_quotas_client.reset_quotas, project_id)
+ self.addCleanup(self._cleanup_quotas, project_id)
for key, value in six.iteritems(new_quotas):
self.assertEqual(value, quota_set[key])
@@ -87,3 +88,12 @@
def test_quotas(self):
new_quotas = {'network': 0, 'security_group': 0}
self._check_quotas(new_quotas)
+
+ def _cleanup_quotas(self, project_id):
+ # try to clean up the resources.If it fails, then
+ # assume that everything was already deleted, so
+ # it is OK to continue.
+ try:
+ self.admin_quotas_client.reset_quotas(project_id)
+ except lib_exc.NotFound:
+ pass
diff --git a/tempest/api/network/base.py b/tempest/api/network/base.py
index 81337f3..f209f89 100644
--- a/tempest/api/network/base.py
+++ b/tempest/api/network/base.py
@@ -69,6 +69,7 @@
super(BaseNetworkTest, cls).setup_clients()
cls.client = cls.os.network_client
cls.agents_client = cls.os.network_agents_client
+ cls.network_extensions_client = cls.os.network_extensions_client
cls.networks_client = cls.os.networks_client
cls.subnetpools_client = cls.os.subnetpools_client
cls.subnets_client = cls.os.subnets_client
@@ -76,6 +77,8 @@
cls.quotas_client = cls.os.network_quotas_client
cls.floating_ips_client = cls.os.floating_ips_client
cls.security_groups_client = cls.os.security_groups_client
+ cls.security_group_rules_client = (
+ cls.os.security_group_rules_client)
@classmethod
def resource_setup(cls):
@@ -247,8 +250,8 @@
@classmethod
def create_router_interface(cls, router_id, subnet_id):
"""Wrapper utility that returns a router interface."""
- interface = cls.client.add_router_interface_with_subnet_id(
- router_id, subnet_id)
+ interface = cls.client.add_router_interface(router_id,
+ subnet_id=subnet_id)
return interface
@classmethod
@@ -257,8 +260,9 @@
interfaces = body['ports']
for i in interfaces:
try:
- cls.client.remove_router_interface_with_subnet_id(
- router['id'], i['fixed_ips'][0]['subnet_id'])
+ cls.client.remove_router_interface(
+ router['id'],
+ subnet_id=i['fixed_ips'][0]['subnet_id'])
except lib_exc.NotFound:
pass
cls.client.delete_router(router['id'])
diff --git a/tempest/api/network/base_routers.py b/tempest/api/network/base_routers.py
index 739e6f9..3495b76f 100644
--- a/tempest/api/network/base_routers.py
+++ b/tempest/api/network/base_routers.py
@@ -45,19 +45,19 @@
self.assertNotIn(router_id, routers_list)
def _add_router_interface_with_subnet_id(self, router_id, subnet_id):
- interface = self.client.add_router_interface_with_subnet_id(
- router_id, subnet_id)
+ interface = self.client.add_router_interface(router_id,
+ subnet_id=subnet_id)
self.addCleanup(self._remove_router_interface_with_subnet_id,
router_id, subnet_id)
self.assertEqual(subnet_id, interface['subnet_id'])
return interface
def _remove_router_interface_with_subnet_id(self, router_id, subnet_id):
- body = self.client.remove_router_interface_with_subnet_id(
- router_id, subnet_id)
+ body = self.client.remove_router_interface(router_id,
+ subnet_id=subnet_id)
self.assertEqual(subnet_id, body['subnet_id'])
def _remove_router_interface_with_port_id(self, router_id, port_id):
- body = self.client.remove_router_interface_with_port_id(router_id,
- port_id)
+ body = self.client.remove_router_interface(router_id,
+ port_id=port_id)
self.assertEqual(port_id, body['port_id'])
diff --git a/tempest/api/network/base_security_groups.py b/tempest/api/network/base_security_groups.py
index 1525e19..3ea3aea 100644
--- a/tempest/api/network/base_security_groups.py
+++ b/tempest/api/network/base_security_groups.py
@@ -40,10 +40,11 @@
self.assertNotIn(secgroup_id, secgroup_list)
def _delete_security_group_rule(self, rule_id):
- self.client.delete_security_group_rule(rule_id)
+ self.security_group_rules_client.delete_security_group_rule(rule_id)
# Asserting that the security group is not found in the list
# after deletion
- list_body = self.client.list_security_group_rules()
+ list_body = (
+ self.security_group_rules_client.list_security_group_rules())
rules_list = list()
for rule in list_body['security_group_rules']:
rules_list.append(rule['id'])
diff --git a/tempest/api/network/test_dhcp_ipv6.py b/tempest/api/network/test_dhcp_ipv6.py
index 74c1d51..dbb0d14 100644
--- a/tempest/api/network/test_dhcp_ipv6.py
+++ b/tempest/api/network/test_dhcp_ipv6.py
@@ -68,9 +68,8 @@
for port in ports:
if (port['device_owner'].startswith('network:router_interface')
and port['device_id'] in [r['id'] for r in self.routers]):
- self.client.remove_router_interface_with_port_id(
- port['device_id'], port['id']
- )
+ self.client.remove_router_interface(port['device_id'],
+ port_id=port['id'])
else:
if port['id'] in [p['id'] for p in self.ports]:
self.ports_client.delete_port(port['id'])
diff --git a/tempest/api/network/test_extensions.py b/tempest/api/network/test_extensions.py
index b83d2b0..d71d600 100644
--- a/tempest/api/network/test_extensions.py
+++ b/tempest/api/network/test_extensions.py
@@ -41,14 +41,15 @@
expected_alias = [ext for ext in expected_alias if
test.is_extension_enabled(ext, 'network')]
actual_alias = list()
- extensions = self.client.list_extensions()
+ extensions = self.network_extensions_client.list_extensions()
list_extensions = extensions['extensions']
# Show and verify the details of the available extensions
for ext in list_extensions:
ext_name = ext['name']
ext_alias = ext['alias']
actual_alias.append(ext['alias'])
- ext_details = self.client.show_extension(ext_alias)
+ ext_details = self.network_extensions_client.show_extension(
+ ext_alias)
ext_details = ext_details['extension']
self.assertIsNotNone(ext_details)
diff --git a/tempest/api/network/test_ports.py b/tempest/api/network/test_ports.py
index 67f2c83..d7b220b 100644
--- a/tempest/api/network/test_ports.py
+++ b/tempest/api/network/test_ports.py
@@ -22,6 +22,7 @@
from tempest.common import custom_matchers
from tempest.common.utils import data_utils
from tempest import config
+from tempest import exceptions
from tempest import test
CONF = config.CONF
@@ -87,14 +88,16 @@
@classmethod
def _get_ipaddress_from_tempest_conf(cls):
- """Return first subnet gateway for configured CIDR """
+ """Return subnet with mask bits for configured CIDR """
if cls._ip_version == 4:
cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
+ cidr.prefixlen = CONF.network.tenant_network_mask_bits
elif cls._ip_version == 6:
cidr = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
+ cidr.prefixlen = CONF.network.tenant_network_v6_mask_bits
- return netaddr.IPAddress(cidr)
+ return cidr
@test.attr(type='smoke')
@test.idempotent_id('0435f278-40ae-48cb-a404-b8a087bc09b1')
@@ -102,9 +105,15 @@
network = self.create_network()
net_id = network['id']
address = self._get_ipaddress_from_tempest_conf()
- allocation_pools = {'allocation_pools': [{'start': str(address + 4),
- 'end': str(address + 6)}]}
- subnet = self.create_subnet(network, **allocation_pools)
+ if ((address.version == 4 and address.prefixlen >= 30) or
+ (address.version == 6 and address.prefixlen >= 126)):
+ msg = ("Subnet %s isn't large enough for the test" % address.cidr)
+ raise exceptions.InvalidConfiguration(message=msg)
+ allocation_pools = {'allocation_pools': [{'start': str(address[2]),
+ 'end': str(address[-2])}]}
+ subnet = self.create_subnet(network, cidr=address,
+ mask_bits=address.prefixlen,
+ **allocation_pools)
self.addCleanup(self.subnets_client.delete_subnet, subnet['id'])
body = self.ports_client.create_port(network_id=net_id)
self.addCleanup(self.ports_client.delete_port, body['port']['id'])
@@ -191,10 +200,10 @@
self.addCleanup(self.client.delete_router, router['id'])
port = self.ports_client.create_port(network_id=network['id'])
# Add router interface to port created above
- self.client.add_router_interface_with_port_id(
- router['id'], port['port']['id'])
- self.addCleanup(self.client.remove_router_interface_with_port_id,
- router['id'], port['port']['id'])
+ self.client.add_router_interface(router['id'],
+ port_id=port['port']['id'])
+ self.addCleanup(self.client.remove_router_interface, router['id'],
+ port_id=port['port']['id'])
# List ports filtered by router_id
port_list = self.ports_client.list_ports(device_id=router['id'])
ports = port_list['ports']
diff --git a/tempest/api/network/test_routers.py b/tempest/api/network/test_routers.py
index 406ad44..0b64be4 100644
--- a/tempest/api/network/test_routers.py
+++ b/tempest/api/network/test_routers.py
@@ -137,8 +137,8 @@
subnet = self.create_subnet(network)
router = self._create_router(data_utils.rand_name('router-'))
# Add router interface with subnet id
- interface = self.client.add_router_interface_with_subnet_id(
- router['id'], subnet['id'])
+ interface = self.client.add_router_interface(router['id'],
+ subnet_id=subnet['id'])
self.addCleanup(self._remove_router_interface_with_subnet_id,
router['id'], subnet['id'])
self.assertIn('subnet_id', interface.keys())
@@ -158,8 +158,9 @@
port_body = self.ports_client.create_port(
network_id=network['id'])
# add router interface to port created above
- interface = self.client.add_router_interface_with_port_id(
- router['id'], port_body['port']['id'])
+ interface = self.client.add_router_interface(
+ router['id'],
+ port_id=port_body['port']['id'])
self.addCleanup(self._remove_router_interface_with_port_id,
router['id'], port_body['port']['id'])
self.assertIn('subnet_id', interface.keys())
diff --git a/tempest/api/network/test_routers_negative.py b/tempest/api/network/test_routers_negative.py
index 90da6fd..7b07d42 100644
--- a/tempest/api/network/test_routers_negative.py
+++ b/tempest/api/network/test_routers_negative.py
@@ -84,8 +84,8 @@
@test.attr(type=['negative'])
@test.idempotent_id('04df80f9-224d-47f5-837a-bf23e33d1c20')
def test_router_remove_interface_in_use_returns_409(self):
- self.client.add_router_interface_with_subnet_id(
- self.router['id'], self.subnet['id'])
+ self.client.add_router_interface(self.router['id'],
+ subnet_id=self.subnet['id'])
self.assertRaises(lib_exc.Conflict,
self.client.delete_router,
self.router['id'])
diff --git a/tempest/api/network/test_security_groups.py b/tempest/api/network/test_security_groups.py
index cf45328..7d0765e 100644
--- a/tempest/api/network/test_security_groups.py
+++ b/tempest/api/network/test_security_groups.py
@@ -41,7 +41,8 @@
remote_ip_prefix=None):
# Create Security Group rule with the input params and validate
# that SG rule is created with the same parameters.
- rule_create_body = self.client.create_security_group_rule(
+ sec_group_rules_client = self.security_group_rules_client
+ rule_create_body = sec_group_rules_client.create_security_group_rule(
security_group_id=sg_id,
direction=direction,
ethertype=ethertype,
@@ -116,8 +117,9 @@
# Create rules for each protocol
protocols = ['tcp', 'udp', 'icmp']
+ client = self.security_group_rules_client
for protocol in protocols:
- rule_create_body = self.client.create_security_group_rule(
+ rule_create_body = client.create_security_group_rule(
security_group_id=group_create_body['security_group']['id'],
protocol=protocol,
direction='ingress',
@@ -125,7 +127,7 @@
)
# Show details of the created security rule
- show_rule_body = self.client.show_security_group_rule(
+ show_rule_body = client.show_security_group_rule(
rule_create_body['security_group_rule']['id']
)
create_dict = rule_create_body['security_group_rule']
@@ -135,7 +137,8 @@
"%s does not match." % key)
# List rules and verify created rule is in response
- rule_list_body = self.client.list_security_group_rules()
+ rule_list_body = (
+ self.security_group_rules_client.list_security_group_rules())
rule_list = [rule['id']
for rule in rule_list_body['security_group_rules']]
self.assertIn(rule_create_body['security_group_rule']['id'],
@@ -223,7 +226,8 @@
direction = 'ingress'
protocol = 17
security_group_id = group_create_body['security_group']['id']
- rule_create_body = self.client.create_security_group_rule(
+ client = self.security_group_rules_client
+ rule_create_body = client.create_security_group_rule(
security_group_id=security_group_id,
direction=direction,
protocol=protocol
diff --git a/tempest/api/network/test_security_groups_negative.py b/tempest/api/network/test_security_groups_negative.py
index 58e39e9..ff38e9e 100644
--- a/tempest/api/network/test_security_groups_negative.py
+++ b/tempest/api/network/test_security_groups_negative.py
@@ -46,9 +46,10 @@
@test.idempotent_id('4c094c09-000b-4e41-8100-9617600c02a6')
def test_show_non_existent_security_group_rule(self):
non_exist_id = str(uuid.uuid4())
- self.assertRaises(lib_exc.NotFound,
- self.client.show_security_group_rule,
- non_exist_id)
+ self.assertRaises(
+ lib_exc.NotFound,
+ self.security_group_rules_client.show_security_group_rule,
+ non_exist_id)
@test.attr(type=['negative'])
@test.idempotent_id('1f1bb89d-5664-4956-9fcd-83ee0fa603df')
@@ -67,7 +68,8 @@
# Create rule with bad protocol name
pname = 'bad_protocol_name'
self.assertRaises(
- lib_exc.BadRequest, self.client.create_security_group_rule,
+ lib_exc.BadRequest,
+ self.security_group_rules_client.create_security_group_rule,
security_group_id=group_create_body['security_group']['id'],
protocol=pname, direction='ingress', ethertype=self.ethertype)
@@ -80,7 +82,8 @@
prefix = ['192.168.1./24', '192.168.1.1/33', 'bad_prefix', '256']
for remote_ip_prefix in prefix:
self.assertRaises(
- lib_exc.BadRequest, self.client.create_security_group_rule,
+ lib_exc.BadRequest,
+ self.security_group_rules_client.create_security_group_rule,
security_group_id=group_create_body['security_group']['id'],
protocol='tcp', direction='ingress', ethertype=self.ethertype,
remote_ip_prefix=remote_ip_prefix)
@@ -95,7 +98,8 @@
group_ids = ['bad_group_id', non_exist_id]
for remote_group_id in group_ids:
self.assertRaises(
- lib_exc.NotFound, self.client.create_security_group_rule,
+ lib_exc.NotFound,
+ self.security_group_rules_client.create_security_group_rule,
security_group_id=group_create_body['security_group']['id'],
protocol='tcp', direction='ingress', ethertype=self.ethertype,
remote_group_id=remote_group_id)
@@ -109,7 +113,8 @@
# Create rule specifying both remote_ip_prefix and remote_group_id
prefix = self._tenant_network_cidr
self.assertRaises(
- lib_exc.BadRequest, self.client.create_security_group_rule,
+ lib_exc.BadRequest,
+ self.security_group_rules_client.create_security_group_rule,
security_group_id=sg1_body['security_group']['id'],
protocol='tcp', direction='ingress',
ethertype=self.ethertype, remote_ip_prefix=prefix,
@@ -123,7 +128,8 @@
# Create rule with bad ethertype
ethertype = 'bad_ethertype'
self.assertRaises(
- lib_exc.BadRequest, self.client.create_security_group_rule,
+ lib_exc.BadRequest,
+ self.security_group_rules_client.create_security_group_rule,
security_group_id=group_create_body['security_group']['id'],
protocol='udp', direction='ingress', ethertype=ethertype)
@@ -140,7 +146,8 @@
(-16, 65536, 'Invalid value for port')]
for pmin, pmax, msg in states:
ex = self.assertRaises(
- lib_exc.BadRequest, self.client.create_security_group_rule,
+ lib_exc.BadRequest,
+ self.security_group_rules_client.create_security_group_rule,
security_group_id=group_create_body['security_group']['id'],
protocol='tcp', port_range_min=pmin, port_range_max=pmax,
direction='ingress', ethertype=self.ethertype)
@@ -152,7 +159,8 @@
(300, 1, 'Invalid value for ICMP type')]
for pmin, pmax, msg in states:
ex = self.assertRaises(
- lib_exc.BadRequest, self.client.create_security_group_rule,
+ lib_exc.BadRequest,
+ self.security_group_rules_client.create_security_group_rule,
security_group_id=group_create_body['security_group']['id'],
protocol='icmp', port_range_min=pmin, port_range_max=pmax,
direction='ingress', ethertype=self.ethertype)
@@ -176,7 +184,7 @@
min_port = 66
max_port = 67
# Create a rule with valid params
- self.client.create_security_group_rule(
+ self.security_group_rules_client.create_security_group_rule(
security_group_id=body['security_group']['id'],
direction='ingress',
ethertype=self.ethertype,
@@ -187,7 +195,8 @@
# Try creating the same security group rule, it should fail
self.assertRaises(
- lib_exc.Conflict, self.client.create_security_group_rule,
+ lib_exc.Conflict,
+ self.security_group_rules_client.create_security_group_rule,
security_group_id=body['security_group']['id'],
protocol='tcp', direction='ingress', ethertype=self.ethertype,
port_range_min=min_port, port_range_max=max_port)
@@ -197,10 +206,11 @@
def test_create_security_group_rule_with_non_existent_security_group(self):
# Create security group rules with not existing security group.
non_existent_sg = str(uuid.uuid4())
- self.assertRaises(lib_exc.NotFound,
- self.client.create_security_group_rule,
- security_group_id=non_existent_sg,
- direction='ingress', ethertype=self.ethertype)
+ self.assertRaises(
+ lib_exc.NotFound,
+ self.security_group_rules_client.create_security_group_rule,
+ security_group_id=non_existent_sg,
+ direction='ingress', ethertype=self.ethertype)
class NegativeSecGroupIPv6Test(NegativeSecGroupTest):
@@ -221,7 +231,7 @@
self.assertRaisesRegexp(
lib_exc.BadRequest,
"Conflicting value ethertype",
- self.client.create_security_group_rule,
+ self.security_group_rules_client.create_security_group_rule,
security_group_id=group_create_body['security_group']['id'],
protocol='tcp', direction='ingress',
ethertype=pair['ethertype'],
diff --git a/tempest/api/orchestration/stacks/test_neutron_resources.py b/tempest/api/orchestration/stacks/test_neutron_resources.py
index 8466e11..09e863e 100644
--- a/tempest/api/orchestration/stacks/test_neutron_resources.py
+++ b/tempest/api/orchestration/stacks/test_neutron_resources.py
@@ -16,7 +16,6 @@
import netaddr
from tempest.api.orchestration import base
-from tempest.common import credentials_factory as credentials
from tempest.common.utils import data_utils
from tempest import config
from tempest import exceptions
@@ -37,8 +36,8 @@
@classmethod
def setup_credentials(cls):
+ cls.set_network_resources()
super(NeutronResourcesTestJSON, cls).setup_credentials()
- cls.os = credentials.ConfiguredUserManager()
@classmethod
def setup_clients(cls):
diff --git a/tempest/api/telemetry/base.py b/tempest/api/telemetry/base.py
index bbf6db2..ff06810 100644
--- a/tempest/api/telemetry/base.py
+++ b/tempest/api/telemetry/base.py
@@ -17,6 +17,7 @@
from tempest.common import compute
from tempest.common.utils import data_utils
+from tempest.common import waiters
from tempest import config
from tempest import exceptions
import tempest.test
@@ -97,8 +98,14 @@
pass
@classmethod
+ def wait_for_server_termination(cls, server_id):
+ waiters.wait_for_server_termination(cls.servers_client,
+ server_id)
+
+ @classmethod
def resource_cleanup(cls):
cls.cleanup_resources(cls.servers_client.delete_server, cls.server_ids)
+ cls.cleanup_resources(cls.wait_for_server_termination, cls.server_ids)
cls.cleanup_resources(cls.image_client.delete_image, cls.image_ids)
super(BaseTelemetryTest, cls).resource_cleanup()
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 2c40d0c..d617b0f 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -70,6 +70,10 @@
VolumesClient as ComputeVolumesClient
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.agents_client import AgentsClient \
+ as NetworkAgentsClient
+from tempest_lib.services.network.extensions_client import \
+ ExtensionsClient as NetworkExtensionsClient
from tempest_lib.services.network.floating_ips_client import FloatingIPsClient
from tempest_lib.services.network.metering_label_rules_client import \
MeteringLabelRulesClient
@@ -94,10 +98,14 @@
DatabaseLimitsClient
from tempest.services.database.json.versions_client import \
DatabaseVersionsClient
+from tempest.services.identity.v2.json.endpoints_client import \
+ EndpointsClient as EndpointsV2Client
from tempest.services.identity.v2.json.identity_client import \
IdentityClient
from tempest.services.identity.v2.json.roles_client import \
RolesClient
+from tempest.services.identity.v2.json.services_client import \
+ ServicesClient as ServicesV2Client
from tempest.services.identity.v2.json.tenants_client import \
TenantsClient
from tempest.services.identity.v2.json.users_client import \
@@ -119,11 +127,11 @@
from tempest.services.image.v2.json.images_client import ImagesClientV2
from tempest.services.messaging.json.messaging_client import \
MessagingClient
-from tempest.services.network.json.agents_client import AgentsClient \
- as NetworkAgentsClient
from tempest.services.network.json.network_client import NetworkClient
from tempest.services.network.json.quotas_client import QuotasClient \
as NetworkQuotasClient
+from tempest.services.network.json.security_group_rules_client import \
+ SecurityGroupRulesClient
from tempest.services.network.json.security_groups_client import \
SecurityGroupsClient
from tempest.services.network.json.subnetpools_client import SubnetpoolsClient
@@ -238,6 +246,14 @@
build_interval=CONF.network.build_interval,
build_timeout=CONF.network.build_timeout,
**self.default_params)
+ self.network_extensions_client = NetworkExtensionsClient(
+ self.auth_provider,
+ CONF.network.catalog_type,
+ CONF.network.region or CONF.identity.region,
+ endpoint_type=CONF.network.endpoint_type,
+ build_interval=CONF.network.build_interval,
+ build_timeout=CONF.network.build_timeout,
+ **self.default_params)
self.network_client = NetworkClient(
self.auth_provider,
CONF.network.catalog_type,
@@ -310,6 +326,14 @@
build_interval=CONF.network.build_interval,
build_timeout=CONF.network.build_timeout,
**self.default_params)
+ self.security_group_rules_client = SecurityGroupRulesClient(
+ self.auth_provider,
+ CONF.network.catalog_type,
+ CONF.network.region or CONF.identity.region,
+ endpoint_type=CONF.network.endpoint_type,
+ build_interval=CONF.network.build_interval,
+ build_timeout=CONF.network.build_timeout,
+ **self.default_params)
self.security_groups_client = SecurityGroupsClient(
self.auth_provider,
CONF.network.catalog_type,
@@ -477,9 +501,12 @@
'region': CONF.identity.region
}
params.update(self.default_params_with_timeout_values)
+
+ # Clients below use the admin endpoint type of Keystone API v2
params_v2_admin = params.copy()
params_v2_admin['endpoint_type'] = CONF.identity.v2_admin_endpoint_type
- # Client uses admin endpoint type of Keystone API v2
+ self.endpoints_v2_client = EndpointsV2Client(self.auth_provider,
+ **params_v2_admin)
self.identity_client = IdentityClient(self.auth_provider,
**params_v2_admin)
self.tenants_client = TenantsClient(self.auth_provider,
@@ -488,21 +515,23 @@
**params_v2_admin)
self.users_client = UsersClient(self.auth_provider,
**params_v2_admin)
+ self.services_v2_client = ServicesV2Client(self.auth_provider,
+ **params_v2_admin)
+
+ # Clients below use the public endpoint type of Keystone API v2
params_v2_public = params.copy()
params_v2_public['endpoint_type'] = (
CONF.identity.v2_public_endpoint_type)
- # Client uses public endpoint type of Keystone API v2
self.identity_public_client = IdentityClient(self.auth_provider,
**params_v2_public)
self.tenants_public_client = TenantsClient(self.auth_provider,
**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)
+
+ # Clients below use the endpoint type of Keystone API v3
params_v3 = params.copy()
params_v3['endpoint_type'] = CONF.identity.v3_endpoint_type
- # Clients below use the endpoint type of Keystone API v3
self.identity_v3_client = IdentityV3Client(self.auth_provider,
**params_v3)
self.endpoints_client = EndPointV3Client(self.auth_provider,
@@ -515,6 +544,7 @@
self.credentials_client = CredentialsV3Client(self.auth_provider,
**params_v3)
self.groups_client = GroupsV3Client(self.auth_provider, **params_v3)
+
# Token clients do not use the catalog. They only need default_params.
# They read auth_url, so they should only be set if the corresponding
# API version is marked as enabled
diff --git a/tempest/cmd/account_generator.py b/tempest/cmd/account_generator.py
index 32d6ef1..9e98d90 100755
--- a/tempest/cmd/account_generator.py
+++ b/tempest/cmd/account_generator.py
@@ -312,8 +312,8 @@
return resp_body['router']
def _add_router_interface(router_id, subnet_id):
- network_admin_client.add_router_interface_with_subnet_id(
- router_id, subnet_id)
+ network_admin_client.add_router_interface(router_id,
+ subnet_id=subnet_id)
network_name = name + "-network"
network = _create_network(network_name)
@@ -390,7 +390,7 @@
'password': user['pass'],
'roles': user['roles']
}
- if 'network' or 'router' in user:
+ if 'network' in user or 'router' in user:
account['resources'] = {}
if 'network' in user:
account['resources']['network'] = user['network']
diff --git a/tempest/cmd/cleanup_service.py b/tempest/cmd/cleanup_service.py
index 8a47406..33f19b1 100644
--- a/tempest/cmd/cleanup_service.py
+++ b/tempest/cmd/cleanup_service.py
@@ -469,8 +469,7 @@
in client.list_router_interfaces(rid)['ports']
if port["device_owner"] == "network:router_interface"]
for port in ports:
- client.remove_router_interface_with_port_id(rid,
- port['id'])
+ client.remove_router_interface(rid, port_id=port['id'])
client.delete_router(rid)
except Exception:
LOG.exception("Delete Router exception.")
diff --git a/tempest/cmd/javelin.py b/tempest/cmd/javelin.py
index 8012ad7..e26a014 100755
--- a/tempest/cmd/javelin.py
+++ b/tempest/cmd/javelin.py
@@ -841,8 +841,8 @@
for subnet in router['subnet']:
subnet_id = _get_resource_by_name(client.networks,
'subnets', subnet)['id']
- client.networks.remove_router_interface_with_subnet_id(router_id,
- subnet_id)
+ client.networks.remove_router_interface(router_id,
+ subnet_id=subnet_id)
client.networks.delete_router(router_id)
@@ -856,8 +856,8 @@
subnet_id = _get_resource_by_name(client.networks,
'subnets', subnet)['id']
# connect routers to their subnets
- client.networks.add_router_interface_with_subnet_id(router_id,
- subnet_id)
+ client.networks.add_router_interface(router_id,
+ subnet_id=subnet_id)
# connect routers to external network if set to "gateway"
if router['gateway']:
if CONF.network.public_network_id:
diff --git a/tempest/cmd/verify_tempest_config.py b/tempest/cmd/verify_tempest_config.py
index 5d867df..92aa19e 100644
--- a/tempest/cmd/verify_tempest_config.py
+++ b/tempest/cmd/verify_tempest_config.py
@@ -146,7 +146,7 @@
extensions_client = {
'nova': os.extensions_client,
'cinder': os.volumes_extension_client,
- 'neutron': os.network_client,
+ 'neutron': os.network_extensions_client,
'swift': os.account_client,
}
# NOTE (e0ne): Use Cinder API v2 by default because v1 is deprecated
@@ -157,7 +157,7 @@
if service not in extensions_client:
print('No tempest extensions client for %s' % service)
- exit(1)
+ sys.exit(1)
return extensions_client[service]
@@ -170,7 +170,7 @@
}
if service not in extensions_options:
print('No supported extensions list option for %s' % service)
- exit(1)
+ sys.exit(1)
return extensions_options[service]
diff --git a/tempest/common/api_version_utils.py b/tempest/common/api_version_utils.py
index ac3322e..c3d977f 100644
--- a/tempest/common/api_version_utils.py
+++ b/tempest/common/api_version_utils.py
@@ -38,13 +38,13 @@
config_max_version = api_version_request.APIVersionRequest(cfg_max_version)
if ((min_version > max_version) or
(config_min_version > config_max_version)):
- msg = ("Min version is greater than Max version. Test Class versions "
- "[%s - %s]. configuration versions [%s - %s]."
+ msg = ("Test Class versions [%s - %s]. "
+ "Configuration versions [%s - %s]."
% (min_version.get_string(),
max_version.get_string(),
config_min_version.get_string(),
config_max_version.get_string()))
- raise exceptions.InvalidConfiguration(msg)
+ raise exceptions.InvalidAPIVersionRange(msg)
# NOTE: Select tests which are in range of configuration like
# config min config max
@@ -69,3 +69,27 @@
cfg_version = api_version_request.APIVersionRequest(cfg_min_version)
max_version = cfg_version if cfg_version >= test_version else test_version
return max_version.get_string()
+
+
+def assert_version_header_matches_request(api_microversion_header_name,
+ api_microversion,
+ response_header):
+ """Checks API microversion in resposne header
+
+ Verify whether microversion is present in response header
+ and with specified 'api_microversion' value.
+
+ @param: api_microversion_header_name: Microversion header name
+ Example- "X-OpenStack-Nova-API-Version"
+ @param: api_microversion: Microversion number like "2.10"
+ @param: response_header: Response header where microversion is
+ expected to be present.
+ """
+ api_microversion_header_name = api_microversion_header_name.lower()
+ if (api_microversion_header_name not in response_header or
+ api_microversion != response_header[api_microversion_header_name]):
+ msg = ("Microversion header '%s' with value '%s' does not match in "
+ "response - %s. " % (api_microversion_header_name,
+ api_microversion,
+ response_header))
+ raise exceptions.InvalidHTTPResponseHeader(msg)
diff --git a/tempest/common/compute.py b/tempest/common/compute.py
index d57bae3..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,9 +49,16 @@
# 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 {}
diff --git a/tempest/common/dynamic_creds.py b/tempest/common/dynamic_creds.py
index 95ad229..8d3a24d 100644
--- a/tempest/common/dynamic_creds.py
+++ b/tempest/common/dynamic_creds.py
@@ -233,8 +233,8 @@
return resp_body['router']
def _add_router_interface(self, router_id, subnet_id):
- self.network_admin_client.add_router_interface_with_subnet_id(
- router_id, subnet_id)
+ self.network_admin_client.add_router_interface(router_id,
+ subnet_id=subnet_id)
def get_credentials(self, credential_type):
if self._creds.get(str(credential_type)):
@@ -333,8 +333,9 @@
if (not self.network_resources or
(self.network_resources.get('router') and creds.subnet)):
try:
- net_client.remove_router_interface_with_subnet_id(
- creds.router['id'], creds.subnet['id'])
+ net_client.remove_router_interface(
+ creds.router['id'],
+ subnet_id=creds.subnet['id'])
except lib_exc.NotFound:
LOG.warning('router with name: %s not found for delete' %
creds.router['name'])
diff --git a/tempest/common/utils/__init__.py b/tempest/common/utils/__init__.py
index 81b8110..aad6373 100644
--- a/tempest/common/utils/__init__.py
+++ b/tempest/common/utils/__init__.py
@@ -27,8 +27,6 @@
class DataUtils(object):
def __getattr__(self, attr):
- if attr in self.__dict__:
- return self.__dict__[attr]
if attr == 'rand_name':
# NOTE(flwang): This is a proxy to generate a random name that
diff --git a/tempest/common/utils/linux/remote_client.py b/tempest/common/utils/linux/remote_client.py
index b76c356..8f5faef 100644
--- a/tempest/common/utils/linux/remote_client.py
+++ b/tempest/common/utils/linux/remote_client.py
@@ -15,8 +15,8 @@
import time
from oslo_log import log as logging
-import six
from tempest_lib.common import ssh
+import tempest_lib.exceptions
from tempest import config
from tempest import exceptions
@@ -28,22 +28,10 @@
class RemoteClient(object):
- # NOTE(afazekas): It should always get an address instead of server
- def __init__(self, server, username, password=None, pkey=None):
+ def __init__(self, ip_address, username, password=None, pkey=None):
ssh_timeout = CONF.validation.ssh_timeout
- network = CONF.validation.network_for_ssh
- ip_version = CONF.validation.ip_version_for_ssh
connect_timeout = CONF.validation.connect_timeout
- if isinstance(server, six.string_types):
- ip_address = server
- else:
- addresses = server['addresses'][network]
- for address in addresses:
- if address['version'] == ip_version:
- ip_address = address['addr']
- break
- else:
- raise exceptions.ServerUnreachable()
+
self.ssh_client = ssh.Client(ip_address, username, password,
ssh_timeout, pkey=pkey,
channel_timeout=connect_timeout)
@@ -191,4 +179,10 @@
def make_fs(self, dev_name, fs='ext4'):
cmd_mkfs = 'sudo /usr/sbin/mke2fs -t %s /dev/%s' % (fs, dev_name)
- self.exec_command(cmd_mkfs)
+ try:
+ self.exec_command(cmd_mkfs)
+ except tempest_lib.exceptions.SSHExecCommandFailed:
+ LOG.error("Couldn't mke2fs")
+ cmd_why = 'sudo ls -lR /dev'
+ LOG.info("Contents of /dev: %s" % self.exec_command(cmd_why))
+ raise
diff --git a/tempest/config.py b/tempest/config.py
index 6942172..14a6ad2 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -1189,6 +1189,11 @@
'live_migration, pause, rescue, resize '
'shelve, snapshot, and suspend')
+
+# NOTE(deva): Ironic tests have been ported to tempest-lib. New config options
+# should be added to ironic/ironic_tempest_plugin/config.py.
+# However, these options need to remain here for testing stable
+# branches until Liberty release reaches EOL.
BaremetalGroup = [
cfg.StrOpt('catalog_type',
default='baremetal',
diff --git a/tempest/exceptions.py b/tempest/exceptions.py
index 931737d..86e8460 100644
--- a/tempest/exceptions.py
+++ b/tempest/exceptions.py
@@ -186,6 +186,10 @@
" %(schema_versions_info)s")
+class InvalidAPIVersionRange(TempestException):
+ message = ("API Min Version is greater than Max version")
+
+
class CommandFailed(Exception):
def __init__(self, returncode, cmd, output, stderr):
super(CommandFailed, self).__init__()
diff --git a/tempest/hacking/ignored_list_T110.txt b/tempest/hacking/ignored_list_T110.txt
index ce69931..f1f21d1 100644
--- a/tempest/hacking/ignored_list_T110.txt
+++ b/tempest/hacking/ignored_list_T110.txt
@@ -1,4 +1,3 @@
-./tempest/services/identity/v3/json/identity_client.py
./tempest/services/messaging/json/messaging_client.py
./tempest/services/object_storage/object_client.py
./tempest/services/telemetry/json/alarming_client.py
diff --git a/tempest/hacking/ignored_list_T111.txt b/tempest/hacking/ignored_list_T111.txt
index 8130c85..20d58d2 100644
--- a/tempest/hacking/ignored_list_T111.txt
+++ b/tempest/hacking/ignored_list_T111.txt
@@ -1,3 +1,2 @@
./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..1962286 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -69,6 +69,8 @@
cls.subnets_client = cls.manager.subnets_client
cls.floating_ips_client = cls.manager.floating_ips_client
cls.security_groups_client = cls.manager.security_groups_client
+ cls.security_group_rules_client = (
+ cls.manager.security_group_rules_client)
# Heat client
cls.orchestration_client = cls.manager.orchestration_client
@@ -160,7 +162,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 +242,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:
@@ -325,9 +328,6 @@
for ruleset in rulesets:
sg_rule = _client_rules.create_security_group_rule(
parent_group_id=secgroup_id, **ruleset)['security_group_rule']
- self.addCleanup(self.delete_wrapper,
- _client_rules.delete_security_group_rule,
- sg_rule['id'])
rules.append(sg_rule)
return rules
@@ -349,25 +349,15 @@
return secgroup
- def get_remote_client(self, server_or_ip, username=None, private_key=None):
+ def get_remote_client(self, ip_address, username=None, private_key=None):
"""Get a SSH client to a remote server
- @param server_or_ip a server object as returned by Tempest compute
- client or an IP address to connect to
+ @param ip_address the server floating or fixed IP address to use
+ for ssh validation
@param username name of the Linux account on the remote server
@param private_key the SSH private key to use
@return a RemoteClient object
"""
- if isinstance(server_or_ip, six.string_types):
- ip = server_or_ip
- else:
- addrs = server_or_ip['addresses'][CONF.validation.network_for_ssh]
- try:
- ip = (addr['addr'] for addr in addrs if
- netaddr.valid_ipv4(addr['addr'])).next()
- except StopIteration:
- raise lib_exc.NotFound("No IPv4 addresses to use for SSH to "
- "remote server.")
if username is None:
username = CONF.validation.image_ssh_user
@@ -380,14 +370,15 @@
else:
password = CONF.validation.image_ssh_password
private_key = None
- linux_client = remote_client.RemoteClient(ip, username,
+ linux_client = remote_client.RemoteClient(ip_address, username,
pkey=private_key,
password=password)
try:
linux_client.validate_authentication()
except Exception as e:
message = ('Initializing SSH connection to %(ip)s failed. '
- 'Error: %(error)s' % {'ip': ip, 'error': e})
+ 'Error: %(error)s' % {'ip': ip_address,
+ 'error': e})
caller = misc_utils.find_test_caller()
if caller:
message = '(%s) %s' % (caller, message)
@@ -625,9 +616,9 @@
floating_ip['ip'], thing['id'])
return floating_ip
- def create_timestamp(self, server_or_ip, dev_name=None, mount_path='/mnt',
+ def create_timestamp(self, ip_address, dev_name=None, mount_path='/mnt',
private_key=None):
- ssh_client = self.get_remote_client(server_or_ip,
+ ssh_client = self.get_remote_client(ip_address,
private_key=private_key)
if dev_name is not None:
ssh_client.make_fs(dev_name)
@@ -640,9 +631,9 @@
ssh_client.umount(mount_path)
return timestamp
- def get_timestamp(self, server_or_ip, dev_name=None, mount_path='/mnt',
+ def get_timestamp(self, ip_address, dev_name=None, mount_path='/mnt',
private_key=None):
- ssh_client = self.get_remote_client(server_or_ip,
+ ssh_client = self.get_remote_client(ip_address,
private_key=private_key)
if dev_name is not None:
ssh_client.mount(dev_name, mount_path)
@@ -652,12 +643,25 @@
ssh_client.umount(mount_path)
return timestamp
- def get_server_or_ip(self, server):
+ def get_server_ip(self, server):
+ """Get the server fixed or floating IP.
+
+ Based on the configuration we're in, return a correct ip
+ address for validating that a guest is up.
+ """
if CONF.validation.connect_method == 'floating':
- ip = self.create_floating_ip(server)['ip']
+ # The tests calling this method don't have a floating IP
+ # and can't make use of the validattion resources. So the
+ # method is creating the floating IP there.
+ return self.create_floating_ip(server)['ip']
+ elif CONF.validation.connect_method == 'fixed':
+ addresses = server['addresses'][CONF.validation.network_for_ssh]
+ for address in addresses:
+ if address['version'] == CONF.validation.ip_version_for_ssh:
+ return address['addr']
+ raise exceptions.ServerUnreachable()
else:
- ip = server
- return ip
+ raise exceptions.InvalidConfiguration()
class NetworkScenarioTest(ScenarioTest):
@@ -939,11 +943,12 @@
CONF.validation.ping_timeout,
1)
- def _create_security_group(self, client=None, tenant_id=None,
+ def _create_security_group(self, security_group_rules_client=None,
+ tenant_id=None,
namestart='secgroup-smoke',
security_groups_client=None):
- if client is None:
- client = self.network_client
+ if security_group_rules_client is None:
+ security_group_rules_client = self.security_group_rules_client
if security_groups_client is None:
security_groups_client = self.security_groups_client
if tenant_id is None:
@@ -954,7 +959,8 @@
# Add rules to the security group
rules = self._create_loginable_secgroup_rule(
- client=client, secgroup=secgroup,
+ security_group_rules_client=security_group_rules_client,
+ secgroup=secgroup,
security_groups_client=security_groups_client)
for rule in rules:
self.assertEqual(tenant_id, rule.tenant_id)
@@ -1010,7 +1016,8 @@
return net_resources.DeletableSecurityGroup(client=client,
**sgs[0])
- def _create_security_group_rule(self, secgroup=None, client=None,
+ def _create_security_group_rule(self, secgroup=None,
+ sec_group_rules_client=None,
tenant_id=None,
security_groups_client=None, **kwargs):
"""Create a rule from a dictionary of rule parameters.
@@ -1030,8 +1037,8 @@
port_range_max: 22
}
"""
- if client is None:
- client = self.network_client
+ if sec_group_rules_client is None:
+ sec_group_rules_client = self.security_group_rules_client
if security_groups_client is None:
security_groups_client = self.security_groups_client
if not tenant_id:
@@ -1044,18 +1051,18 @@
tenant_id=secgroup.tenant_id)
ruleset.update(kwargs)
- sg_rule = client.create_security_group_rule(**ruleset)
+ sg_rule = sec_group_rules_client.create_security_group_rule(**ruleset)
sg_rule = net_resources.DeletableSecurityGroupRule(
- client=client,
+ client=sec_group_rules_client,
**sg_rule['security_group_rule']
)
- self.addCleanup(self.delete_wrapper, sg_rule.delete)
self.assertEqual(secgroup.tenant_id, sg_rule.tenant_id)
self.assertEqual(secgroup.id, sg_rule.security_group_id)
return sg_rule
- def _create_loginable_secgroup_rule(self, client=None, secgroup=None,
+ def _create_loginable_secgroup_rule(self, security_group_rules_client=None,
+ secgroup=None,
security_groups_client=None):
"""Create loginable security group rule
@@ -1065,8 +1072,8 @@
belonging to the same security group.
"""
- if client is None:
- client = self.network_client
+ if security_group_rules_client is None:
+ security_group_rules_client = self.security_group_rules_client
if security_groups_client is None:
security_groups_client = self.security_groups_client
rules = []
@@ -1087,12 +1094,14 @@
ethertype='IPv6',
)
]
+ sec_group_rules_client = security_group_rules_client
for ruleset in rulesets:
for r_direction in ['ingress', 'egress']:
ruleset['direction'] = r_direction
try:
sg_rule = self._create_security_group_rule(
- client=client, secgroup=secgroup,
+ sec_group_rules_client=sec_group_rules_client,
+ secgroup=secgroup,
security_groups_client=security_groups_client,
**ruleset)
except lib_exc.Conflict as ex:
@@ -1106,12 +1115,6 @@
return rules
- def _ssh_to_server(self, server, private_key):
- ssh_login = CONF.validation.image_ssh_user
- return self.get_remote_client(server,
- username=ssh_login,
- private_key=private_key)
-
def _get_router(self, client=None, tenant_id=None):
"""Retrieve a router for the given tenant id.
@@ -1313,13 +1316,6 @@
def add_keypair(self):
self.keypair = self.create_keypair()
- def verify_connectivity(self, ip=None):
- if ip:
- dest = self.get_remote_client(ip)
- else:
- dest = self.get_remote_client(self.instance)
- dest.validate_authentication()
-
def boot_instance(self):
self.instance = self.create_server(
key_name=self.keypair['name'])
diff --git a/tempest/scenario/test_aggregates_basic_ops.py b/tempest/scenario/test_aggregates_basic_ops.py
index 97a755d..cace90b 100644
--- a/tempest/scenario/test_aggregates_basic_ops.py
+++ b/tempest/scenario/test_aggregates_basic_ops.py
@@ -43,16 +43,14 @@
def _create_aggregate(self, **kwargs):
aggregate = (self.aggregates_client.create_aggregate(**kwargs)
['aggregate'])
- self.addCleanup(self._delete_aggregate, aggregate)
+ self.addCleanup(self.aggregates_client.delete_aggregate,
+ aggregate['id'])
aggregate_name = kwargs['name']
availability_zone = kwargs['availability_zone']
self.assertEqual(aggregate['name'], aggregate_name)
self.assertEqual(aggregate['availability_zone'], availability_zone)
return aggregate
- def _delete_aggregate(self, aggregate):
- self.aggregates_client.delete_aggregate(aggregate['id'])
-
def _get_host_name(self):
hosts = self.hosts_client.list_hosts()['hosts']
self.assertTrue(len(hosts) >= 1)
diff --git a/tempest/scenario/test_baremetal_basic_ops.py b/tempest/scenario/test_baremetal_basic_ops.py
index 93b32f7..15d9b66 100644
--- a/tempest/scenario/test_baremetal_basic_ops.py
+++ b/tempest/scenario/test_baremetal_basic_ops.py
@@ -112,12 +112,9 @@
self.add_keypair()
self.boot_instance()
self.validate_ports()
- self.verify_connectivity()
- if CONF.validation.connect_method == 'floating':
- floating_ip = self.create_floating_ip(self.instance)['ip']
- self.verify_connectivity(ip=floating_ip)
-
- vm_client = self.get_remote_client(self.instance)
+ ip_address = self.get_server_ip(self.instance)
+ self.get_remote_client(ip_address).validate_authentication()
+ vm_client = self.get_remote_client(ip_address)
# We expect the ephemeral partition to be mounted on /mnt and to have
# the same size as our flavor definition.
@@ -126,6 +123,6 @@
self.verify_partition(vm_client, 'ephemeral0', '/mnt', eph_size)
# Create the test file
self.create_timestamp(
- floating_ip, private_key=self.keypair['private_key'])
+ ip_address, private_key=self.keypair['private_key'])
self.terminate_instance()
diff --git a/tempest/scenario/test_dashboard_basic_ops.py b/tempest/scenario/test_dashboard_basic_ops.py
index cb6b968..5d4f7b3 100644
--- a/tempest/scenario/test_dashboard_basic_ops.py
+++ b/tempest/scenario/test_dashboard_basic_ops.py
@@ -97,9 +97,13 @@
req = request.Request(login_url)
req.add_header('Content-type', 'application/x-www-form-urlencoded')
req.add_header('Referer', CONF.dashboard.dashboard_url)
+
+ # Pass the default domain name regardless of the auth version in order
+ # to test the scenario of when horizon is running with keystone v3
params = {'username': username,
'password': password,
'region': parser.region,
+ 'domain': CONF.auth.default_credentials_domain_name,
'csrfmiddlewaretoken': parser.csrf_token}
self.opener.open(req, parse.urlencode(params))
diff --git a/tempest/scenario/test_minimum_basic.py b/tempest/scenario/test_minimum_basic.py
index d9c6924..f7c7434 100644
--- a/tempest/scenario/test_minimum_basic.py
+++ b/tempest/scenario/test_minimum_basic.py
@@ -62,12 +62,6 @@
server, custom_matchers.MatchesDictExceptForKeys(
got_server, excluded_keys=excluded_keys))
- def cinder_create(self):
- return self.create_volume()
-
- def cinder_list(self):
- return self.volumes_client.list_volumes()['volumes']
-
def cinder_show(self, volume):
got_volume = self.volumes_client.show_volume(volume['id'])['volume']
self.assertEqual(volume, got_volume)
@@ -115,8 +109,8 @@
self.nova_show(server)
- volume = self.cinder_create()
- volumes = self.cinder_list()
+ volume = self.create_volume()
+ volumes = self.volumes_client.list_volumes()['volumes']
self.assertIn(volume['id'], [x['id'] for x in volumes])
self.cinder_show(volume)
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index b8bec16..79a5099 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -240,8 +240,8 @@
old_floating_ip, server = self.floating_ip_tuple
ip_address = old_floating_ip.floating_ip_address
private_key = self._get_server_key(server)
- ssh_client = self.get_remote_client(ip_address,
- private_key=private_key)
+ ssh_client = self.get_remote_client(
+ ip_address, private_key=private_key)
old_nic_list = self._get_server_nics(ssh_client)
# get a port from a list of one item
port_list = self._list_ports(device_id=server['id'])
@@ -336,7 +336,8 @@
should_connect=True):
ip_address = floating_ip.floating_ip_address
private_key = self._get_server_key(self.floating_ip_tuple.server)
- ssh_source = self._ssh_to_server(ip_address, private_key)
+ ssh_source = self.get_remote_client(
+ ip_address, private_key=private_key)
for remote_ip in address_list:
if should_connect:
@@ -553,7 +554,8 @@
floating_ip, server = self.floating_ip_tuple
ip_address = floating_ip.floating_ip_address
private_key = self._get_server_key(server)
- ssh_client = self._ssh_to_server(ip_address, private_key)
+ ssh_client = self.get_remote_client(
+ ip_address, private_key=private_key)
dns_servers = [initial_dns_server]
servers = ssh_client.get_dns_servers()
@@ -684,9 +686,9 @@
list_hosts = (self.admin_manager.network_client.
list_l3_agents_hosting_router)
schedule_router = (self.admin_manager.network_agents_client.
- add_router_to_l3_agent)
+ create_router_on_l3_agent)
unschedule_router = (self.admin_manager.network_agents_client.
- remove_router_from_l3_agent)
+ delete_router_from_l3_agent)
agent_list = set(a["id"] for a in
self._list_agents(agent_type="L3 agent"))
diff --git a/tempest/scenario/test_network_v6.py b/tempest/scenario/test_network_v6.py
index cc28873..fc33dd9 100644
--- a/tempest/scenario/test_network_v6.py
+++ b/tempest/scenario/test_network_v6.py
@@ -124,7 +124,7 @@
fip = self.create_floating_ip(thing=srv)
ips = self.define_server_ips(srv=srv)
ssh = self.get_remote_client(
- server_or_ip=fip.floating_ip_address,
+ ip_address=fip.floating_ip_address,
username=username)
return ssh, ips, srv["id"]
@@ -203,31 +203,37 @@
(dest, source.ssh_client.host)
)
+ @test.attr(type='slow')
@test.idempotent_id('2c92df61-29f0-4eaa-bee3-7c65bef62a43')
@test.services('compute', 'network')
def test_slaac_from_os(self):
self._prepare_and_test(address6_mode='slaac')
+ @test.attr(type='slow')
@test.idempotent_id('d7e1f858-187c-45a6-89c9-bdafde619a9f')
@test.services('compute', 'network')
def test_dhcp6_stateless_from_os(self):
self._prepare_and_test(address6_mode='dhcpv6-stateless')
+ @test.attr(type='slow')
@test.idempotent_id('7ab23f41-833b-4a16-a7c9-5b42fe6d4123')
@test.services('compute', 'network')
def test_multi_prefix_dhcpv6_stateless(self):
self._prepare_and_test(address6_mode='dhcpv6-stateless', n_subnets6=2)
+ @test.attr(type='slow')
@test.idempotent_id('dec222b1-180c-4098-b8c5-cc1b8342d611')
@test.services('compute', 'network')
def test_multi_prefix_slaac(self):
self._prepare_and_test(address6_mode='slaac', n_subnets6=2)
+ @test.attr(type='slow')
@test.idempotent_id('b6399d76-4438-4658-bcf5-0d6c8584fde2')
@test.services('compute', 'network')
def test_dualnet_slaac_from_os(self):
self._prepare_and_test(address6_mode='slaac', dualnet=True)
+ @test.attr(type='slow')
@test.idempotent_id('76f26acd-9688-42b4-bc3e-cd134c4cb09e')
@test.services('compute', 'network')
def test_dualnet_dhcp6_stateless_from_os(self):
diff --git a/tempest/scenario/test_security_groups_basic_ops.py b/tempest/scenario/test_security_groups_basic_ops.py
index 8375d05..18bd764 100644
--- a/tempest/scenario/test_security_groups_basic_ops.py
+++ b/tempest/scenario/test_security_groups_basic_ops.py
@@ -191,9 +191,11 @@
port_range_max=22,
direction='ingress',
)
- self._create_security_group_rule(secgroup=access_sg,
- client=tenant.manager.network_client,
- **ssh_rule)
+ sec_group_rules_client = tenant.manager.security_group_rules_client
+ self._create_security_group_rule(
+ secgroup=access_sg,
+ sec_group_rules_client=sec_group_rules_client,
+ **ssh_rule)
def _verify_network_details(self, tenant):
# Checks that we see the newly created network/subnet/router via
@@ -319,8 +321,8 @@
access_point_ssh = \
self.floating_ips[tenant.access_point['id']].floating_ip_address
private_key = tenant.keypair['private_key']
- access_point_ssh = self._ssh_to_server(access_point_ssh,
- private_key=private_key)
+ access_point_ssh = self.get_remote_client(
+ access_point_ssh, private_key=private_key)
return access_point_ssh
def _check_connectivity(self, access_point, ip, should_succeed=True):
@@ -371,9 +373,11 @@
protocol='icmp',
direction='ingress'
)
+ sec_group_rules_client = (
+ dest_tenant.manager.security_group_rules_client)
self._create_security_group_rule(
secgroup=dest_tenant.security_groups['default'],
- client=dest_tenant.manager.network_client,
+ sec_group_rules_client=sec_group_rules_client,
**ruleset
)
access_point_ssh = self._connect_to_access_point(source_tenant)
@@ -385,9 +389,11 @@
self._test_cross_tenant_block(dest_tenant, source_tenant)
# allow reverse traffic and check
+ sec_group_rules_client = (
+ source_tenant.manager.security_group_rules_client)
self._create_security_group_rule(
secgroup=source_tenant.security_groups['default'],
- client=source_tenant.manager.network_client,
+ sec_group_rules_client=sec_group_rules_client,
**ruleset
)
@@ -468,9 +474,10 @@
protocol='icmp',
direction='ingress',
)
+ sec_group_rules_client = new_tenant.manager.security_group_rules_client
self._create_security_group_rule(
secgroup=new_sg,
- client=new_tenant.manager.network_client,
+ sec_group_rules_client=sec_group_rules_client,
**icmp_rule)
new_tenant.security_groups.update(new_sg=new_sg)
diff --git a/tempest/scenario/test_server_basic_ops.py b/tempest/scenario/test_server_basic_ops.py
index 239e120..dcb095b 100644
--- a/tempest/scenario/test_server_basic_ops.py
+++ b/tempest/scenario/test_server_basic_ops.py
@@ -69,18 +69,15 @@
image=self.image_ref, flavor=self.flavor_ref,
ssh=self.run_ssh, ssh_user=self.ssh_user))
- def add_keypair(self):
- self.keypair = self.create_keypair()
-
- def verify_ssh(self):
+ def verify_ssh(self, keypair):
if self.run_ssh:
# Obtain a floating IP
self.fip = self.create_floating_ip(self.instance)['ip']
# Check ssh
self.ssh_client = self.get_remote_client(
- server_or_ip=self.fip,
+ ip_address=self.fip,
username=self.image_utils.ssh_user(self.image_ref),
- private_key=self.keypair['private_key'])
+ private_key=keypair['private_key'])
def verify_metadata(self):
if self.run_ssh and CONF.compute_feature_enabled.metadata_service:
@@ -123,19 +120,19 @@
@test.attr(type='smoke')
@test.services('compute', 'network')
def test_server_basicops(self):
- self.add_keypair()
+ keypair = self.create_keypair()
self.security_group = self._create_security_group()
security_groups = [{'name': self.security_group['name']}]
self.md = {'meta1': 'data1', 'meta2': 'data2', 'metaN': 'dataN'}
self.instance = self.create_server(
image_id=self.image_ref,
flavor=self.flavor_ref,
- key_name=self.keypair['name'],
+ key_name=keypair['name'],
security_groups=security_groups,
config_drive=CONF.compute_feature_enabled.config_drive,
metadata=self.md,
wait_until='ACTIVE')
- self.verify_ssh()
+ self.verify_ssh(keypair)
self.verify_metadata()
self.verify_metadata_on_config_drive()
self.servers_client.delete_server(self.instance['id'])
diff --git a/tempest/scenario/test_shelve_instance.py b/tempest/scenario/test_shelve_instance.py
index 378ae9d..77de47e 100644
--- a/tempest/scenario/test_shelve_instance.py
+++ b/tempest/scenario/test_shelve_instance.py
@@ -13,7 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-from oslo_log import log
import testtools
from tempest.common import waiters
@@ -23,8 +22,6 @@
CONF = config.CONF
-LOG = log.getLogger(__name__)
-
class TestShelveInstance(manager.ScenarioTest):
"""This test shelves then unshelves a Nova instance
@@ -80,7 +77,7 @@
security_groups=security_groups,
wait_until='ACTIVE')
- instance_ip = self.get_server_or_ip(server)
+ instance_ip = self.get_server_ip(server)
timestamp = self.create_timestamp(instance_ip,
private_key=keypair['private_key'])
diff --git a/tempest/scenario/test_snapshot_pattern.py b/tempest/scenario/test_snapshot_pattern.py
index f3b6558..d6528a3 100644
--- a/tempest/scenario/test_snapshot_pattern.py
+++ b/tempest/scenario/test_snapshot_pattern.py
@@ -13,7 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-from oslo_log import log
import testtools
from tempest import config
@@ -22,8 +21,6 @@
CONF = config.CONF
-LOG = log.getLogger(__name__)
-
class TestSnapshotPattern(manager.ScenarioTest):
"""This test is for snapshotting an instance and booting with it.
@@ -52,7 +49,7 @@
security_groups=[{'name': security_group['name']}],
wait_until='ACTIVE')
- instance_ip = self.get_server_or_ip(server)
+ instance_ip = self.get_server_ip(server)
timestamp = self.create_timestamp(instance_ip,
private_key=keypair['private_key'])
@@ -67,7 +64,7 @@
wait_until='ACTIVE')
# check the existence of the timestamp file in the second instance
- server_from_snapshot_ip = self.get_server_or_ip(server_from_snapshot)
+ server_from_snapshot_ip = self.get_server_ip(server_from_snapshot)
timestamp2 = self.get_timestamp(server_from_snapshot_ip,
private_key=keypair['private_key'])
self.assertEqual(timestamp, timestamp2)
diff --git a/tempest/scenario/test_stamp_pattern.py b/tempest/scenario/test_stamp_pattern.py
index 8183ce3..1d09fe7 100644
--- a/tempest/scenario/test_stamp_pattern.py
+++ b/tempest/scenario/test_stamp_pattern.py
@@ -25,10 +25,8 @@
from tempest import exceptions
from tempest.scenario import manager
from tempest import test
-import tempest.test
CONF = config.CONF
-
LOG = logging.getLogger(__name__)
@@ -60,10 +58,6 @@
if not CONF.volume_feature_enabled.snapshot:
raise cls.skipException("Cinder volume snapshots are disabled")
- def _wait_for_volume_snapshot_status(self, volume_snapshot, status):
- self.snapshots_client.wait_for_snapshot_status(volume_snapshot['id'],
- status)
-
def _create_volume_snapshot(self, volume):
snapshot_name = data_utils.rand_name('scenario-snapshot')
snapshot = self.snapshots_client.create_snapshot(
@@ -78,55 +72,38 @@
except lib_exc.NotFound:
pass
self.addCleanup(cleaner)
- self._wait_for_volume_status(volume, 'available')
+ self.volumes_client.wait_for_volume_status(volume['id'], 'available')
self.snapshots_client.wait_for_snapshot_status(snapshot['id'],
'available')
self.assertEqual(snapshot_name, snapshot['display_name'])
return snapshot
- def _wait_for_volume_status(self, volume, status):
- self.volumes_client.wait_for_volume_status(volume['id'], status)
-
- def _create_volume(self, snapshot_id=None):
- return self.create_volume(snapshot_id=snapshot_id)
-
- def _attach_volume(self, server, volume):
- attached_volume = self.servers_client.attach_volume(
- server['id'], volumeId=volume['id'], device='/dev/%s'
- % CONF.compute.volume_device_name)['volumeAttachment']
- self.assertEqual(volume['id'], attached_volume['id'])
- self._wait_for_volume_status(attached_volume, 'in-use')
-
- def _detach_volume(self, server, volume):
- self.servers_client.detach_volume(server['id'], volume['id'])
- self._wait_for_volume_status(volume, 'available')
-
- def _wait_for_volume_available_on_the_system(self, server_or_ip,
+ def _wait_for_volume_available_on_the_system(self, ip_address,
private_key):
- ssh = self.get_remote_client(server_or_ip, private_key=private_key)
+ ssh = self.get_remote_client(ip_address, private_key=private_key)
def _func():
part = ssh.get_partitions()
LOG.debug("Partitions:%s" % part)
return CONF.compute.volume_device_name in part
- if not tempest.test.call_until_true(_func,
- CONF.compute.build_timeout,
- CONF.compute.build_interval):
+ if not test.call_until_true(_func,
+ CONF.compute.build_timeout,
+ CONF.compute.build_interval):
raise exceptions.TimeoutException
@decorators.skip_because(bug="1205344")
@test.idempotent_id('10fd234a-515c-41e5-b092-8323060598c5')
@testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
'Snapshotting is not available.')
- @tempest.test.services('compute', 'network', 'volume', 'image')
+ @test.services('compute', 'network', 'volume', 'image')
def test_stamp_pattern(self):
# prepare for booting an instance
keypair = self.create_keypair()
security_group = self._create_security_group()
# boot an instance and create a timestamp file in it
- volume = self._create_volume()
+ volume = self.create_volume()
server = self.create_server(
image_id=CONF.compute.image_ref,
key_name=keypair['name'],
@@ -134,15 +111,15 @@
wait_until='ACTIVE')
# create and add floating IP to server1
- ip_for_server = self.get_server_or_ip(server)
+ ip_for_server = self.get_server_ip(server)
- self._attach_volume(server, volume)
+ self.nova_volume_attach(server, volume)
self._wait_for_volume_available_on_the_system(ip_for_server,
keypair['private_key'])
timestamp = self.create_timestamp(ip_for_server,
CONF.compute.volume_device_name,
private_key=keypair['private_key'])
- self._detach_volume(server, volume)
+ self.nova_volume_detach(server, volume)
# snapshot the volume
volume_snapshot = self._create_volume_snapshot(volume)
@@ -151,7 +128,7 @@
snapshot_image = self.create_server_snapshot(server=server)
# create second volume from the snapshot(volume2)
- volume_from_snapshot = self._create_volume(
+ volume_from_snapshot = self.create_volume(
snapshot_id=volume_snapshot['id'])
# boot second instance from the snapshot(instance2)
@@ -161,10 +138,10 @@
security_groups=security_group)
# create and add floating IP to server_from_snapshot
- ip_for_snapshot = self.get_server_or_ip(server_from_snapshot)
+ ip_for_snapshot = self.get_server_ip(server_from_snapshot)
# attach volume2 to instance2
- self._attach_volume(server_from_snapshot, volume_from_snapshot)
+ self.nova_volume_attach(server_from_snapshot, volume_from_snapshot)
self._wait_for_volume_available_on_the_system(ip_for_snapshot,
keypair['private_key'])
diff --git a/tempest/scenario/test_volume_boot_pattern.py b/tempest/scenario/test_volume_boot_pattern.py
index 81ecda0..4ce57db 100644
--- a/tempest/scenario/test_volume_boot_pattern.py
+++ b/tempest/scenario/test_volume_boot_pattern.py
@@ -10,8 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-from oslo_log import log
-
from tempest.common.utils import data_utils
from tempest.common import waiters
from tempest import config
@@ -20,8 +18,6 @@
CONF = config.CONF
-LOG = log.getLogger(__name__)
-
class TestVolumeBootPattern(manager.ScenarioTest):
@@ -70,7 +66,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)
@@ -114,7 +110,7 @@
keypair, security_group)
# write content to volume on instance
- ip_instance_1st = self.get_server_or_ip(instance_1st)
+ ip_instance_1st = self.get_server_ip(instance_1st)
timestamp = self.create_timestamp(ip_instance_1st,
private_key=keypair['private_key'])
@@ -126,7 +122,7 @@
keypair, security_group)
# check the content of written file
- ip_instance_2nd = self.get_server_or_ip(instance_2nd)
+ ip_instance_2nd = self.get_server_ip(instance_2nd)
timestamp2 = self.get_timestamp(ip_instance_2nd,
private_key=keypair['private_key'])
self.assertEqual(timestamp, timestamp2)
@@ -141,7 +137,7 @@
keypair, security_group))
# check the content of written file
- server_from_snapshot_ip = self.get_server_or_ip(server_from_snapshot)
+ server_from_snapshot_ip = self.get_server_ip(server_from_snapshot)
timestamp3 = self.get_timestamp(server_from_snapshot_ip,
private_key=keypair['private_key'])
self.assertEqual(timestamp, timestamp3)
diff --git a/tempest/services/base_microversion_client.py b/tempest/services/base_microversion_client.py
new file mode 100644
index 0000000..4c750f5
--- /dev/null
+++ b/tempest/services/base_microversion_client.py
@@ -0,0 +1,54 @@
+# Copyright 2016 NEC Corporation. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from tempest_lib.common import rest_client
+
+
+class BaseMicroversionClient(rest_client.RestClient):
+ """Base class to support microversion in service clients
+
+ This class is used to support microversion in service clients.
+ This provides feature to make API request with microversion.
+ Service clients derived from this class will be able to send API
+ request to server with or without microversion.
+ If api_microversion is not set on service client then API request will be
+ normal request without microversion.
+
+ """
+ def __init__(self, auth_provider, service, region,
+ api_microversion_header_name, **kwargs):
+ """Base Microversion Client __init__
+
+ :param auth_provider: an auth provider object used to wrap requests in
+ auth
+ :param str service: The service name to use for the catalog lookup
+ :param str region: The region to use for the catalog lookup
+ :param str api_microversion_header_name: The microversion header name
+ to use for sending API
+ request with microversion
+ :param kwargs: kwargs required by rest_client.RestClient
+ """
+ super(BaseMicroversionClient, self).__init__(
+ auth_provider, service, region, **kwargs)
+ self.api_microversion_header_name = api_microversion_header_name
+ self.api_microversion = None
+
+ def get_headers(self):
+ headers = super(BaseMicroversionClient, self).get_headers()
+ if self.api_microversion:
+ headers[self.api_microversion_header_name] = self.api_microversion
+ return headers
+
+ def set_api_microversion(self, microversion):
+ self.api_microversion = microversion
diff --git a/tempest/services/compute/json/base.py b/tempest/services/compute/json/base_compute_client.py
similarity index 69%
rename from tempest/services/compute/json/base.py
rename to tempest/services/compute/json/base_compute_client.py
index 40d3056..5349af6 100644
--- a/tempest/services/compute/json/base.py
+++ b/tempest/services/compute/json/base_compute_client.py
@@ -12,23 +12,31 @@
# License for the specific language governing permissions and limitations
# under the License.
-from tempest_lib.common import rest_client
-
from tempest.common import api_version_request
+from tempest.common import api_version_utils
from tempest import exceptions
+from tempest.services import base_microversion_client
-class BaseComputeClient(rest_client.RestClient):
- api_microversion = None
+class BaseComputeClient(base_microversion_client.BaseMicroversionClient):
- def get_headers(self):
- headers = super(BaseComputeClient, self).get_headers()
- if self.api_microversion:
- headers['X-OpenStack-Nova-API-Version'] = self.api_microversion
- return headers
+ def __init__(self, auth_provider, service, region,
+ api_microversion_header_name='X-OpenStack-Nova-API-Version',
+ **kwargs):
+ super(BaseComputeClient, self).__init__(
+ auth_provider, service, region,
+ api_microversion_header_name, **kwargs)
- def set_api_microversion(self, microversion):
- self.api_microversion = microversion
+ def request(self, method, url, extra_headers=False, headers=None,
+ body=None):
+ resp, resp_body = super(BaseComputeClient, self).request(
+ method, url, extra_headers, headers, body)
+ if self.api_microversion and self.api_microversion != 'latest':
+ api_version_utils.assert_version_header_matches_request(
+ self.api_microversion_header_name,
+ self.api_microversion,
+ resp)
+ return resp, resp_body
def get_schema(self, schema_versions_info):
"""Get JSON schema
diff --git a/tempest/services/compute/json/keypairs_client.py b/tempest/services/compute/json/keypairs_client.py
index 2e22bc6..ec9b1e0 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_compute_client
-class KeyPairsClient(service_client.ServiceClient):
+class KeyPairsClient(base_compute_client.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/endpoints_client.py b/tempest/services/identity/v2/json/endpoints_client.py
new file mode 100644
index 0000000..ff9907d
--- /dev/null
+++ b/tempest/services/identity/v2/json/endpoints_client.py
@@ -0,0 +1,50 @@
+# Copyright 2016 Red Hat, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from oslo_serialization import jsonutils as json
+
+from tempest.common import service_client
+
+
+class EndpointsClient(service_client.ServiceClient):
+ api_version = "v2.0"
+
+ def create_endpoint(self, service_id, region_id, **kwargs):
+ """Create an endpoint for service."""
+ post_body = {
+ 'service_id': service_id,
+ 'region': region_id,
+ 'publicurl': kwargs.get('publicurl'),
+ 'adminurl': kwargs.get('adminurl'),
+ 'internalurl': kwargs.get('internalurl')
+ }
+ post_body = json.dumps({'endpoint': post_body})
+ resp, body = self.post('/endpoints', post_body)
+ self.expected_success(200, resp.status)
+ body = json.loads(body)
+ return service_client.ResponseBody(resp, body)
+
+ def list_endpoints(self):
+ """List Endpoints - Returns Endpoints."""
+ resp, body = self.get('/endpoints')
+ self.expected_success(200, resp.status)
+ body = json.loads(body)
+ return service_client.ResponseBody(resp, body)
+
+ def delete_endpoint(self, endpoint_id):
+ """Delete an endpoint."""
+ url = '/endpoints/%s' % endpoint_id
+ resp, body = self.delete(url)
+ self.expected_success(204, resp.status)
+ 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 0ff59d5..f045bb7 100644
--- a/tempest/services/identity/v2/json/identity_client.py
+++ b/tempest/services/identity/v2/json/identity_client.py
@@ -39,70 +39,6 @@
self.expected_success(204, resp.status)
return service_client.ResponseBody(resp, body)
- def create_service(self, name, type, **kwargs):
- """Create a service."""
- post_body = {
- 'name': name,
- 'type': type,
- 'description': kwargs.get('description')
- }
- post_body = json.dumps({'OS-KSADM:service': post_body})
- resp, body = self.post('/OS-KSADM/services', post_body)
- self.expected_success(200, resp.status)
- body = json.loads(body)
- return service_client.ResponseBody(resp, body)
-
- def show_service(self, service_id):
- """Get Service."""
- url = '/OS-KSADM/services/%s' % service_id
- resp, body = self.get(url)
- self.expected_success(200, resp.status)
- body = json.loads(body)
- return service_client.ResponseBody(resp, body)
-
- def list_services(self):
- """List Service - Returns Services."""
- resp, body = self.get('/OS-KSADM/services')
- self.expected_success(200, resp.status)
- body = json.loads(body)
- return service_client.ResponseBody(resp, body)
-
- def delete_service(self, service_id):
- """Delete Service."""
- url = '/OS-KSADM/services/%s' % service_id
- resp, body = self.delete(url)
- self.expected_success(204, resp.status)
- return service_client.ResponseBody(resp, body)
-
- def create_endpoint(self, service_id, region_id, **kwargs):
- """Create an endpoint for service."""
- post_body = {
- 'service_id': service_id,
- 'region': region_id,
- 'publicurl': kwargs.get('publicurl'),
- 'adminurl': kwargs.get('adminurl'),
- 'internalurl': kwargs.get('internalurl')
- }
- post_body = json.dumps({'endpoint': post_body})
- resp, body = self.post('/endpoints', post_body)
- self.expected_success(200, resp.status)
- body = json.loads(body)
- return service_client.ResponseBody(resp, body)
-
- def list_endpoints(self):
- """List Endpoints - Returns Endpoints."""
- resp, body = self.get('/endpoints')
- self.expected_success(200, resp.status)
- body = json.loads(body)
- return service_client.ResponseBody(resp, body)
-
- def delete_endpoint(self, endpoint_id):
- """Delete an endpoint."""
- url = '/endpoints/%s' % endpoint_id
- resp, body = self.delete(url)
- self.expected_success(204, resp.status)
- return service_client.ResponseBody(resp, body)
-
def list_extensions(self):
"""List all the extensions."""
resp, body = self.get('/extensions')
diff --git a/tempest/services/identity/v2/json/services_client.py b/tempest/services/identity/v2/json/services_client.py
new file mode 100644
index 0000000..436d00d
--- /dev/null
+++ b/tempest/services/identity/v2/json/services_client.py
@@ -0,0 +1,56 @@
+# Copyright 2015 Red Hat, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from oslo_serialization import jsonutils as json
+
+from tempest.common import service_client
+
+
+class ServicesClient(service_client.ServiceClient):
+ api_version = "v2.0"
+
+ def create_service(self, name, type, **kwargs):
+ """Create a service."""
+ post_body = {
+ 'name': name,
+ 'type': type,
+ 'description': kwargs.get('description')
+ }
+ post_body = json.dumps({'OS-KSADM:service': post_body})
+ resp, body = self.post('/OS-KSADM/services', post_body)
+ self.expected_success(200, resp.status)
+ body = json.loads(body)
+ return service_client.ResponseBody(resp, body)
+
+ def show_service(self, service_id):
+ """Get Service."""
+ url = '/OS-KSADM/services/%s' % service_id
+ resp, body = self.get(url)
+ self.expected_success(200, resp.status)
+ body = json.loads(body)
+ return service_client.ResponseBody(resp, body)
+
+ def list_services(self):
+ """List Service - Returns Services."""
+ resp, body = self.get('/OS-KSADM/services')
+ self.expected_success(200, resp.status)
+ body = json.loads(body)
+ return service_client.ResponseBody(resp, body)
+
+ def delete_service(self, service_id):
+ """Delete Service."""
+ url = '/OS-KSADM/services/%s' % service_id
+ resp, body = self.delete(url)
+ self.expected_success(204, resp.status)
+ return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/identity/v3/json/groups_client.py b/tempest/services/identity/v3/json/groups_client.py
index 70edd23..6ed85cf 100644
--- a/tempest/services/identity/v3/json/groups_client.py
+++ b/tempest/services/identity/v3/json/groups_client.py
@@ -88,3 +88,9 @@
resp, body = self.delete('groups/%s/users/%s' % (group_id, user_id))
self.expected_success(204, resp.status)
return service_client.ResponseBody(resp, body)
+
+ def check_group_user_existence(self, group_id, user_id):
+ """Check user in group."""
+ resp, body = self.head('groups/%s/users/%s' % (group_id, user_id))
+ self.expected_success(204, resp.status)
+ return service_client.ResponseBody(resp)
diff --git a/tempest/services/identity/v3/json/identity_client.py b/tempest/services/identity/v3/json/identity_client.py
index ab8ba2a..15f0577 100644
--- a/tempest/services/identity/v3/json/identity_client.py
+++ b/tempest/services/identity/v3/json/identity_client.py
@@ -149,7 +149,7 @@
return service_client.ResponseBody(resp, body)
def update_project(self, project_id, **kwargs):
- body = self.get_project(project_id)['project']
+ body = self.show_project(project_id)['project']
name = kwargs.get('name', body['name'])
desc = kwargs.get('description', body['description'])
en = kwargs.get('enabled', body['enabled'])
@@ -167,7 +167,7 @@
body = json.loads(body)
return service_client.ResponseBody(resp, body)
- def get_project(self, project_id):
+ def show_project(self, project_id):
"""GET a Project."""
resp, body = self.get("projects/%s" % project_id)
self.expected_success(200, resp.status)
@@ -264,7 +264,7 @@
def update_domain(self, domain_id, **kwargs):
"""Updates a domain."""
- body = self.get_domain(domain_id)['domain']
+ body = self.show_domain(domain_id)['domain']
description = kwargs.get('description', body['description'])
en = kwargs.get('enabled', body['enabled'])
name = kwargs.get('name', body['name'])
@@ -279,7 +279,7 @@
body = json.loads(body)
return service_client.ResponseBody(resp, body)
- def get_domain(self, domain_id):
+ def show_domain(self, domain_id):
"""Get Domain details."""
resp, body = self.get('domains/%s' % domain_id)
self.expected_success(200, resp.status)
@@ -352,6 +352,22 @@
self.expected_success(204, resp.status)
return service_client.ResponseBody(resp, body)
+ def check_user_role_existence_on_project(self, project_id,
+ user_id, role_id):
+ """Check role of a user on a project."""
+ resp, body = self.head('projects/%s/users/%s/roles/%s' %
+ (project_id, user_id, role_id))
+ self.expected_success(204, resp.status)
+ return service_client.ResponseBody(resp)
+
+ def check_user_role_existence_on_domain(self, domain_id,
+ user_id, role_id):
+ """Check role of a user on a domain."""
+ resp, body = self.head('domains/%s/users/%s/roles/%s' %
+ (domain_id, user_id, role_id))
+ self.expected_success(204, resp.status)
+ return service_client.ResponseBody(resp)
+
def assign_group_role_on_project(self, project_id, group_id, role_id):
"""Add roles to a user on a project."""
resp, body = self.put('projects/%s/groups/%s/roles/%s' %
@@ -396,6 +412,22 @@
self.expected_success(204, resp.status)
return service_client.ResponseBody(resp, body)
+ def check_role_from_group_on_project_existence(self, project_id,
+ group_id, role_id):
+ """Check role of a user on a project."""
+ resp, body = self.head('projects/%s/groups/%s/roles/%s' %
+ (project_id, group_id, role_id))
+ self.expected_success(204, resp.status)
+ return service_client.ResponseBody(resp)
+
+ def check_role_from_group_on_domain_existence(self, domain_id,
+ group_id, role_id):
+ """Check role of a user on a domain."""
+ resp, body = self.head('domains/%s/groups/%s/roles/%s' %
+ (domain_id, group_id, role_id))
+ self.expected_success(204, resp.status)
+ return service_client.ResponseBody(resp)
+
def create_trust(self, **kwargs):
"""Creates a trust.
@@ -414,7 +446,7 @@
self.expected_success(204, resp.status)
return service_client.ResponseBody(resp, body)
- def get_trusts(self, trustor_user_id=None, trustee_user_id=None):
+ def list_trusts(self, trustor_user_id=None, trustee_user_id=None):
"""GET trusts."""
if trustor_user_id:
resp, body = self.get("OS-TRUST/trusts?trustor_user_id=%s"
@@ -428,21 +460,21 @@
body = json.loads(body)
return service_client.ResponseBody(resp, body)
- def get_trust(self, trust_id):
+ def show_trust(self, trust_id):
"""GET trust."""
resp, body = self.get("OS-TRUST/trusts/%s" % trust_id)
self.expected_success(200, resp.status)
body = json.loads(body)
return service_client.ResponseBody(resp, body)
- def get_trust_roles(self, trust_id):
+ def list_trust_roles(self, trust_id):
"""GET roles delegated by a trust."""
resp, body = self.get("OS-TRUST/trusts/%s/roles" % trust_id)
self.expected_success(200, resp.status)
body = json.loads(body)
return service_client.ResponseBody(resp, body)
- def get_trust_role(self, trust_id, role_id):
+ def show_trust_role(self, trust_id, role_id):
"""GET role delegated by a trust."""
resp, body = self.get("OS-TRUST/trusts/%s/roles/%s"
% (trust_id, role_id))
diff --git a/tempest/services/image/v1/json/images_client.py b/tempest/services/image/v1/json/images_client.py
index 5b6a394..af2e68c 100644
--- a/tempest/services/image/v1/json/images_client.py
+++ b/tempest/services/image/v1/json/images_client.py
@@ -180,21 +180,27 @@
self.expected_success(200, resp.status)
return service_client.ResponseBody(resp, body)
- def list_images(self, detail=False, properties=dict(),
- changes_since=None, **kwargs):
+ def list_images(self, detail=False, **kwargs):
+ """Return a list of all images filtered by input parameters.
+
+ Available params: see http://developer.openstack.org/
+ api-ref-image-v1.html#listImage-v1
+
+ Most parameters except the following are passed to the API without
+ any changes.
+ :param changes_since: The name is changed to changes-since
+ """
url = 'v1/images'
if detail:
url += '/detail'
- params = {}
- for key, value in properties.items():
- params['property-%s' % key] = value
+ properties = kwargs.pop('properties', {})
+ for key, value in six.iteritems(properties):
+ kwargs['property-%s' % key] = value
- kwargs.update(params)
-
- if changes_since is not None:
- kwargs['changes-since'] = changes_since
+ if kwargs.get('changes_since'):
+ kwargs['changes-since'] = kwargs.pop('changes_since')
if len(kwargs) > 0:
url += '?%s' % urllib.urlencode(kwargs)
diff --git a/tempest/services/network/json/agents_client.py b/tempest/services/network/json/agents_client.py
deleted file mode 100644
index 07f93b2..0000000
--- a/tempest/services/network/json/agents_client.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# Copyright 2015 NEC Corporation. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from tempest.services.network.json import base
-
-
-class AgentsClient(base.BaseNetworkClient):
-
- def update_agent(self, agent_id, **kwargs):
- """Update agent."""
- # 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/1526673
- uri = '/agents/%s' % agent_id
- return self.update_resource(uri, kwargs)
-
- def show_agent(self, agent_id, **fields):
- uri = '/agents/%s' % agent_id
- return self.show_resource(uri, **fields)
-
- def list_agents(self, **filters):
- uri = '/agents'
- return self.list_resources(uri, **filters)
-
- def list_routers_on_l3_agent(self, agent_id):
- uri = '/agents/%s/l3-routers' % agent_id
- return self.list_resources(uri)
-
- def add_router_to_l3_agent(self, agent_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.
- # LP: https://bugs.launchpad.net/openstack-api-site/+bug/1526670
- uri = '/agents/%s/l3-routers' % agent_id
- return self.create_resource(uri, kwargs)
-
- def remove_router_from_l3_agent(self, agent_id, router_id):
- uri = '/agents/%s/l3-routers/%s' % (agent_id, router_id)
- return self.delete_resource(uri)
-
- def list_networks_hosted_by_one_dhcp_agent(self, agent_id):
- uri = '/agents/%s/dhcp-networks' % agent_id
- return self.list_resources(uri)
-
- def remove_network_from_dhcp_agent(self, agent_id, network_id):
- uri = '/agents/%s/dhcp-networks/%s' % (agent_id,
- network_id)
- return self.delete_resource(uri)
-
- def add_dhcp_agent_to_network(self, agent_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.
- # LP: https://bugs.launchpad.net/openstack-api-site/+bug/1526212
- uri = '/agents/%s/dhcp-networks' % agent_id
- return self.create_resource(uri, kwargs)
diff --git a/tempest/services/network/json/network_client.py b/tempest/services/network/json/network_client.py
index e8e21d2..c6b22df 100644
--- a/tempest/services/network/json/network_client.py
+++ b/tempest/services/network/json/network_client.py
@@ -35,31 +35,6 @@
quotas
"""
- def create_security_group_rule(self, **kwargs):
- uri = '/security-group-rules'
- post_data = {'security_group_rule': kwargs}
- return self.create_resource(uri, post_data)
-
- def show_security_group_rule(self, security_group_rule_id, **fields):
- uri = '/security-group-rules/%s' % security_group_rule_id
- return self.show_resource(uri, **fields)
-
- def delete_security_group_rule(self, security_group_rule_id):
- uri = '/security-group-rules/%s' % security_group_rule_id
- return self.delete_resource(uri)
-
- def list_security_group_rules(self, **filters):
- uri = '/security-group-rules'
- return self.list_resources(uri, **filters)
-
- def show_extension(self, ext_alias, **fields):
- uri = '/extensions/%s' % ext_alias
- return self.show_resource(uri, **fields)
-
- def list_extensions(self, **filters):
- uri = '/extensions'
- return self.list_resources(uri, **filters)
-
def create_bulk_network(self, **kwargs):
"""create bulk network
@@ -205,25 +180,23 @@
"""
return self._update_router(router_id, set_enable_snat=True, **kwargs)
- def add_router_interface_with_subnet_id(self, router_id, subnet_id):
+ def add_router_interface(self, router_id, **kwargs):
+ """Add router interface.
+
+ Available params: see http://developer.openstack.org/
+ api-ref-networking-v2-ext.html#addRouterInterface
+ """
uri = '/routers/%s/add_router_interface' % router_id
- update_body = {"subnet_id": subnet_id}
- return self.update_resource(uri, update_body)
+ return self.update_resource(uri, kwargs)
- def add_router_interface_with_port_id(self, router_id, port_id):
- uri = '/routers/%s/add_router_interface' % router_id
- update_body = {"port_id": port_id}
- return self.update_resource(uri, update_body)
+ def remove_router_interface(self, router_id, **kwargs):
+ """Remove router interface.
- def remove_router_interface_with_subnet_id(self, router_id, subnet_id):
+ Available params: see http://developer.openstack.org/
+ api-ref-networking-v2-ext.html#removeRouterInterface
+ """
uri = '/routers/%s/remove_router_interface' % router_id
- update_body = {"subnet_id": subnet_id}
- return self.update_resource(uri, update_body)
-
- def remove_router_interface_with_port_id(self, router_id, port_id):
- uri = '/routers/%s/remove_router_interface' % router_id
- update_body = {"port_id": port_id}
- return self.update_resource(uri, update_body)
+ return self.update_resource(uri, kwargs)
def list_router_interfaces(self, uuid):
uri = '/ports?device_id=%s' % uuid
diff --git a/tempest/services/network/json/security_group_rules_client.py b/tempest/services/network/json/security_group_rules_client.py
new file mode 100644
index 0000000..b2ba5b2
--- /dev/null
+++ b/tempest/services/network/json/security_group_rules_client.py
@@ -0,0 +1,33 @@
+# 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 SecurityGroupRulesClient(base.BaseNetworkClient):
+
+ def create_security_group_rule(self, **kwargs):
+ uri = '/security-group-rules'
+ post_data = {'security_group_rule': kwargs}
+ return self.create_resource(uri, post_data)
+
+ def show_security_group_rule(self, security_group_rule_id, **fields):
+ uri = '/security-group-rules/%s' % security_group_rule_id
+ return self.show_resource(uri, **fields)
+
+ def delete_security_group_rule(self, security_group_rule_id):
+ uri = '/security-group-rules/%s' % security_group_rule_id
+ return self.delete_resource(uri)
+
+ def list_security_group_rules(self, **filters):
+ uri = '/security-group-rules'
+ return self.list_resources(uri, **filters)
diff --git a/tempest/services/network/resources.py b/tempest/services/network/resources.py
index 10911f7..0a7da92 100644
--- a/tempest/services/network/resources.py
+++ b/tempest/services/network/resources.py
@@ -89,14 +89,13 @@
def add_to_router(self, router_id):
self._router_ids.add(router_id)
- self.network_client.add_router_interface_with_subnet_id(
- router_id, subnet_id=self.id)
+ self.network_client.add_router_interface(router_id,
+ subnet_id=self.id)
def delete(self):
for router_id in self._router_ids.copy():
- self.network_client.remove_router_interface_with_subnet_id(
- router_id,
- subnet_id=self.id)
+ self.network_client.remove_router_interface(router_id,
+ subnet_id=self.id)
self._router_ids.remove(router_id)
self.subnets_client.delete_subnet(self.id)
diff --git a/tempest/stress/driver.py b/tempest/stress/driver.py
index 6531059..02cb901 100644
--- a/tempest/stress/driver.py
+++ b/tempest/stress/driver.py
@@ -154,9 +154,11 @@
projects_client = None
roles_client = None
users_client = None
+ domain = (identity_client.auth_provider.credentials.
+ get('project_domain_name', 'Default'))
credentials_client = cred_client.get_creds_client(
identity_client, projects_client, roles_client,
- users_client)
+ users_client, project_domain_name=domain)
project = credentials_client.create_project(
name=tenant_name, description=tenant_name)
user = credentials_client.create_user(username, password,
diff --git a/tempest/stress/etc/sample-unit-test.json b/tempest/stress/etc/sample-unit-test.json
index b388bfe..54433d5 100644
--- a/tempest/stress/etc/sample-unit-test.json
+++ b/tempest/stress/etc/sample-unit-test.json
@@ -1,7 +1,7 @@
[{"action": "tempest.stress.actions.unit_test.UnitTest",
"threads": 8,
- "use_admin": false,
- "use_isolated_tenants": false,
+ "use_admin": true,
+ "use_isolated_tenants": true,
"kwargs": {"test_method": "tempest.cli.simple_read_only.test_glance.SimpleReadOnlyGlanceClientTest.test_glance_fake_action",
"class_setup_per": "process"}
}
diff --git a/tempest/stress/etc/server-create-destroy-test.json b/tempest/stress/etc/server-create-destroy-test.json
index 17d5e1a..bbb5352 100644
--- a/tempest/stress/etc/server-create-destroy-test.json
+++ b/tempest/stress/etc/server-create-destroy-test.json
@@ -1,7 +1,7 @@
[{"action": "tempest.stress.actions.server_create_destroy.ServerCreateDestroyTest",
"threads": 8,
- "use_admin": false,
- "use_isolated_tenants": false,
+ "use_admin": true,
+ "use_isolated_tenants": true,
"kwargs": {}
}
]
diff --git a/tempest/stress/etc/ssh_floating.json b/tempest/stress/etc/ssh_floating.json
index e03fd4f..c502e96 100644
--- a/tempest/stress/etc/ssh_floating.json
+++ b/tempest/stress/etc/ssh_floating.json
@@ -1,7 +1,7 @@
[{"action": "tempest.stress.actions.ssh_floating.FloatingStress",
"threads": 8,
- "use_admin": false,
- "use_isolated_tenants": false,
+ "use_admin": true,
+ "use_isolated_tenants": true,
"kwargs": {"vm_extra_args": {},
"new_vm": true,
"new_sec_group": true,
diff --git a/tempest/stress/etc/stress-tox-job.json b/tempest/stress/etc/stress-tox-job.json
index 9cee316..bfa448d 100644
--- a/tempest/stress/etc/stress-tox-job.json
+++ b/tempest/stress/etc/stress-tox-job.json
@@ -1,25 +1,25 @@
[{"action": "tempest.stress.actions.server_create_destroy.ServerCreateDestroyTest",
"threads": 8,
- "use_admin": false,
- "use_isolated_tenants": false,
+ "use_admin": true,
+ "use_isolated_tenants": true,
"kwargs": {}
},
{"action": "tempest.stress.actions.volume_create_delete.VolumeCreateDeleteTest",
"threads": 4,
- "use_admin": false,
- "use_isolated_tenants": false,
+ "use_admin": true,
+ "use_isolated_tenants": true,
"kwargs": {}
},
{"action": "tempest.stress.actions.volume_attach_delete.VolumeAttachDeleteTest",
"threads": 2,
- "use_admin": false,
- "use_isolated_tenants": false,
+ "use_admin": true,
+ "use_isolated_tenants": true,
"kwargs": {}
},
{"action": "tempest.stress.actions.unit_test.UnitTest",
"threads": 4,
- "use_admin": false,
- "use_isolated_tenants": false,
+ "use_admin": true,
+ "use_isolated_tenants": true,
"required_services": ["neutron"],
"kwargs": {"test_method": "tempest.scenario.test_network_advanced_server_ops.TestNetworkAdvancedServerOps.test_server_connectivity_stop_start",
"class_setup_per": "process"}
diff --git a/tempest/stress/etc/volume-attach-delete-test.json b/tempest/stress/etc/volume-attach-delete-test.json
index 4553ff8..d468967 100644
--- a/tempest/stress/etc/volume-attach-delete-test.json
+++ b/tempest/stress/etc/volume-attach-delete-test.json
@@ -1,7 +1,7 @@
[{"action": "tempest.stress.actions.volume_attach_delete.VolumeAttachDeleteTest",
"threads": 4,
- "use_admin": false,
- "use_isolated_tenants": false,
+ "use_admin": true,
+ "use_isolated_tenants": true,
"kwargs": {}
}
]
diff --git a/tempest/stress/etc/volume-attach-verify.json b/tempest/stress/etc/volume-attach-verify.json
index 731f5ed..d8c96fd 100644
--- a/tempest/stress/etc/volume-attach-verify.json
+++ b/tempest/stress/etc/volume-attach-verify.json
@@ -1,7 +1,7 @@
[{"action": "tempest.stress.actions.volume_attach_verify.VolumeVerifyStress",
"threads": 1,
- "use_admin": false,
- "use_isolated_tenants": false,
+ "use_admin": true,
+ "use_isolated_tenants": true,
"kwargs": {"vm_extra_args": {},
"new_volume": true,
"new_server": false,
diff --git a/tempest/stress/etc/volume-create-delete-test.json b/tempest/stress/etc/volume-create-delete-test.json
index e8a58f7..a60cde6 100644
--- a/tempest/stress/etc/volume-create-delete-test.json
+++ b/tempest/stress/etc/volume-create-delete-test.json
@@ -1,7 +1,7 @@
[{"action": "tempest.stress.actions.volume_create_delete.VolumeCreateDeleteTest",
"threads": 4,
- "use_admin": false,
- "use_isolated_tenants": false,
+ "use_admin": true,
+ "use_isolated_tenants": true,
"kwargs": {}
}
]
diff --git a/tempest/test.py b/tempest/test.py
index dfed947..9c04ea1 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -293,7 +293,7 @@
LOG.exception("teardown of %s failed: %s" % (name, te))
if not etype:
etype, value, trace = sys_exec_info
- # If exceptions were raised during teardown, an not before, re-raise
+ # If exceptions were raised during teardown, and not before, re-raise
# the first one
if re_raise and etype is not None:
try:
@@ -600,7 +600,7 @@
networks_client = cls.get_client_manager().compute_networks_client
cred_provider = cls._get_credentials_provider()
# In case of nova network, isolated tenants are not able to list the
- # network configured in fixed_network_name, even if the can use it
+ # network configured in fixed_network_name, even if they can use it
# for their servers, so using an admin network client to validate
# the network name
if (not CONF.service_available.neutron and
@@ -790,9 +790,9 @@
@classmethod
def set_resource(cls, name, resource):
- """Register a resoruce for a test
+ """Register a resource for a test
- This function can be used in setUpClass context to register a resoruce
+ This function can be used in setUpClass context to register a resource
for a test.
:param name: The name of the kind of resource such as "flavor", "role",
diff --git a/tempest/tests/cmd/test_verify_tempest_config.py b/tempest/tests/cmd/test_verify_tempest_config.py
index a5dea54..193abc7 100644
--- a/tempest/tests/cmd/test_verify_tempest_config.py
+++ b/tempest/tests/cmd/test_verify_tempest_config.py
@@ -201,7 +201,8 @@
{'alias': 'fake2'},
{'alias': 'not_fake'}]}
fake_os = mock.MagicMock()
- fake_os.network_client.list_extensions = fake_list_extensions
+ fake_os.network_extensions_client.list_extensions = (
+ fake_list_extensions)
self.useFixture(mockpatch.PatchObject(
verify_tempest_config, 'get_enabled_extensions',
return_value=(['fake1', 'fake2', 'fake3'])))
@@ -223,7 +224,8 @@
{'alias': 'fake2'},
{'alias': 'not_fake'}]}
fake_os = mock.MagicMock()
- fake_os.network_client.list_extensions = fake_list_extensions
+ fake_os.network_extensions_client.list_extensions = (
+ fake_list_extensions)
self.useFixture(mockpatch.PatchObject(
verify_tempest_config, 'get_enabled_extensions',
return_value=(['all'])))
diff --git a/tempest/tests/common/test_api_version_utils.py b/tempest/tests/common/test_api_version_utils.py
index 9f399a2..501f954 100644
--- a/tempest/tests/common/test_api_version_utils.py
+++ b/tempest/tests/common/test_api_version_utils.py
@@ -12,146 +12,11 @@
# License for the specific language governing permissions and limitations
# under the License.
-from oslo_config import cfg
import testtools
-from tempest.api.compute import base as compute_base
from tempest.common import api_version_utils
-from tempest import config
from tempest import exceptions
from tempest.tests import base
-from tempest.tests import fake_config
-
-
-class VersionTestNoneTolatest(compute_base.BaseV2ComputeTest):
- min_microversion = None
- max_microversion = 'latest'
-
-
-class VersionTestNoneTo2_2(compute_base.BaseV2ComputeTest):
- min_microversion = None
- max_microversion = '2.2'
-
-
-class VersionTest2_3ToLatest(compute_base.BaseV2ComputeTest):
- min_microversion = '2.3'
- max_microversion = 'latest'
-
-
-class VersionTest2_5To2_10(compute_base.BaseV2ComputeTest):
- min_microversion = '2.5'
- max_microversion = '2.10'
-
-
-class VersionTest2_10To2_10(compute_base.BaseV2ComputeTest):
- min_microversion = '2.10'
- max_microversion = '2.10'
-
-
-class InvalidVersionTest(compute_base.BaseV2ComputeTest):
- min_microversion = '2.11'
- max_microversion = '2.1'
-
-
-class TestMicroversionsTestsClass(base.TestCase):
-
- def setUp(self):
- super(TestMicroversionsTestsClass, self).setUp()
- self.useFixture(fake_config.ConfigFixture())
- self.stubs.Set(config, 'TempestConfigPrivate',
- fake_config.FakePrivate)
-
- def _test_version(self, cfg_min, cfg_max,
- expected_pass_tests,
- expected_skip_tests):
- cfg.CONF.set_default('min_microversion',
- cfg_min, group='compute-feature-enabled')
- cfg.CONF.set_default('max_microversion',
- cfg_max, group='compute-feature-enabled')
- try:
- for test_class in expected_pass_tests:
- test_class.skip_checks()
- for test_class in expected_skip_tests:
- self.assertRaises(testtools.TestCase.skipException,
- test_class.skip_checks)
- except testtools.TestCase.skipException as e:
- raise testtools.TestCase.failureException(e.message)
-
- def test_config_version_none_none(self):
- expected_pass_tests = [VersionTestNoneTolatest, VersionTestNoneTo2_2]
- expected_skip_tests = [VersionTest2_3ToLatest, VersionTest2_5To2_10,
- VersionTest2_10To2_10]
- self._test_version(None, None,
- expected_pass_tests,
- expected_skip_tests)
-
- def test_config_version_none_23(self):
- expected_pass_tests = [VersionTestNoneTolatest, VersionTestNoneTo2_2,
- VersionTest2_3ToLatest]
- expected_skip_tests = [VersionTest2_5To2_10, VersionTest2_10To2_10]
- self._test_version(None, '2.3',
- expected_pass_tests,
- expected_skip_tests)
-
- def test_config_version_22_latest(self):
- expected_pass_tests = [VersionTestNoneTolatest, VersionTestNoneTo2_2,
- VersionTest2_3ToLatest, VersionTest2_5To2_10,
- VersionTest2_10To2_10]
- expected_skip_tests = []
- self._test_version('2.2', 'latest',
- expected_pass_tests,
- expected_skip_tests)
-
- def test_config_version_22_23(self):
- expected_pass_tests = [VersionTestNoneTolatest, VersionTestNoneTo2_2,
- VersionTest2_3ToLatest]
- expected_skip_tests = [VersionTest2_5To2_10, VersionTest2_10To2_10]
- self._test_version('2.2', '2.3',
- expected_pass_tests,
- expected_skip_tests)
-
- def test_config_version_210_210(self):
- expected_pass_tests = [VersionTestNoneTolatest,
- VersionTest2_3ToLatest,
- VersionTest2_5To2_10,
- VersionTest2_10To2_10]
- expected_skip_tests = [VersionTestNoneTo2_2]
- self._test_version('2.10', '2.10',
- expected_pass_tests,
- expected_skip_tests)
-
- def test_config_version_none_latest(self):
- expected_pass_tests = [VersionTestNoneTolatest, VersionTestNoneTo2_2,
- VersionTest2_3ToLatest, VersionTest2_5To2_10,
- VersionTest2_10To2_10]
- expected_skip_tests = []
- self._test_version(None, 'latest',
- expected_pass_tests,
- expected_skip_tests)
-
- def test_config_version_latest_latest(self):
- expected_pass_tests = [VersionTestNoneTolatest, VersionTest2_3ToLatest]
- expected_skip_tests = [VersionTestNoneTo2_2, VersionTest2_5To2_10,
- VersionTest2_10To2_10]
- self._test_version('latest', 'latest',
- expected_pass_tests,
- expected_skip_tests)
-
- def test_config_invalid_version(self):
- cfg.CONF.set_default('min_microversion',
- '2.5', group='compute-feature-enabled')
- cfg.CONF.set_default('max_microversion',
- '2.1', group='compute-feature-enabled')
- self.assertRaises(exceptions.InvalidConfiguration,
- VersionTestNoneTolatest.skip_checks)
-
- def test_config_version_invalid_test_version(self):
- cfg.CONF.set_default('min_microversion',
- None, group='compute-feature-enabled')
- cfg.CONF.set_default('max_microversion',
- '2.13', group='compute-feature-enabled')
- self.assertRaises(exceptions.InvalidConfiguration,
- InvalidVersionTest.skip_checks)
class TestVersionSkipLogic(base.TestCase):
@@ -186,11 +51,11 @@
self._test_version('2.8', '2.9', '2.3', '2.7', expected_skip=True)
def test_version_min_greater_than_max(self):
- self.assertRaises(exceptions.InvalidConfiguration,
+ self.assertRaises(exceptions.InvalidAPIVersionRange,
self._test_version, '2.8', '2.7', '2.3', '2.7')
def test_cfg_version_min_greater_than_max(self):
- self.assertRaises(exceptions.InvalidConfiguration,
+ self.assertRaises(exceptions.InvalidAPIVersionRange,
self._test_version, '2.2', '2.7', '2.9', '2.7')
@@ -219,3 +84,31 @@
def test_both_min_version_equal(self):
self._test_request_version('2.3', '2.3', expected_version='2.3')
+
+
+class TestMicroversionHeaderMatches(base.TestCase):
+
+ def test_header_matches(self):
+ microversion_header_name = 'x-openstack-xyz-api-version'
+ request_microversion = '2.1'
+ test_respose = {microversion_header_name: request_microversion}
+ api_version_utils.assert_version_header_matches_request(
+ microversion_header_name, request_microversion, test_respose)
+
+ def test_header_does_not_match(self):
+ microversion_header_name = 'x-openstack-xyz-api-version'
+ request_microversion = '2.1'
+ test_respose = {microversion_header_name: '2.2'}
+ self.assertRaises(
+ exceptions.InvalidHTTPResponseHeader,
+ api_version_utils.assert_version_header_matches_request,
+ microversion_header_name, request_microversion, test_respose)
+
+ def test_header_not_present(self):
+ microversion_header_name = 'x-openstack-xyz-api-version'
+ request_microversion = '2.1'
+ test_respose = {}
+ self.assertRaises(
+ exceptions.InvalidHTTPResponseHeader,
+ api_version_utils.assert_version_header_matches_request,
+ microversion_header_name, request_microversion, test_respose)
diff --git a/tempest/tests/common/test_dynamic_creds.py b/tempest/tests/common/test_dynamic_creds.py
index 4379756..de2000d 100644
--- a/tempest/tests/common/test_dynamic_creds.py
+++ b/tempest/tests/common/test_dynamic_creds.py
@@ -322,9 +322,9 @@
self._mock_router_create('1234', 'fake_router')
router_interface_mock = self.patch(
'tempest.services.network.json.network_client.NetworkClient.'
- 'add_router_interface_with_subnet_id')
+ 'add_router_interface')
primary_creds = creds.get_primary_creds()
- router_interface_mock.assert_called_once_with('1234', '1234')
+ router_interface_mock.assert_called_once_with('1234', subnet_id='1234')
network = primary_creds.network
subnet = primary_creds.subnet
router = primary_creds.router
@@ -354,9 +354,9 @@
self._mock_router_create('1234', 'fake_router')
router_interface_mock = self.patch(
'tempest.services.network.json.network_client.NetworkClient.'
- 'add_router_interface_with_subnet_id')
+ 'add_router_interface')
creds.get_primary_creds()
- router_interface_mock.assert_called_once_with('1234', '1234')
+ router_interface_mock.assert_called_once_with('1234', subnet_id='1234')
router_interface_mock.reset_mock()
# Create alternate tenant and network
self._mock_user_create('12345', 'fake_alt_user')
@@ -365,7 +365,8 @@
self._mock_subnet_create(creds, '12345', 'fake_alt_subnet')
self._mock_router_create('12345', 'fake_alt_router')
creds.get_alt_creds()
- router_interface_mock.assert_called_once_with('12345', '12345')
+ router_interface_mock.assert_called_once_with('12345',
+ subnet_id='12345')
router_interface_mock.reset_mock()
# Create admin tenant and networks
self._mock_user_create('123456', 'fake_admin_user')
@@ -390,7 +391,7 @@
router_mock = router.start()
remove_router_interface_mock = self.patch(
'tempest.services.network.json.network_client.NetworkClient.'
- 'remove_router_interface_with_subnet_id')
+ 'remove_router_interface')
return_values = ({'status': 200}, {'ports': []})
port_list_mock = mock.patch.object(creds.ports_admin_client,
'list_ports',
@@ -419,11 +420,11 @@
# Verify remove router interface calls
calls = remove_router_interface_mock.mock_calls
self.assertEqual(len(calls), 3)
- args = map(lambda x: x[1], calls)
+ args = map(lambda x: (x[1][0], x[2]), calls)
args = list(args)
- self.assertIn(('1234', '1234'), args)
- self.assertIn(('12345', '12345'), args)
- self.assertIn(('123456', '123456'), args)
+ self.assertIn(('1234', {'subnet_id': '1234'}), args)
+ self.assertIn(('12345', {'subnet_id': '12345'}), args)
+ self.assertIn(('123456', {'subnet_id': '123456'}), args)
# Verify network delete calls
calls = net_mock.mock_calls
self.assertEqual(len(calls), 3)
@@ -461,9 +462,9 @@
self._mock_router_create('1234', 'fake_alt_router')
router_interface_mock = self.patch(
'tempest.services.network.json.network_client.NetworkClient.'
- 'add_router_interface_with_subnet_id')
+ 'add_router_interface')
alt_creds = creds.get_alt_creds()
- router_interface_mock.assert_called_once_with('1234', '1234')
+ router_interface_mock.assert_called_once_with('1234', subnet_id='1234')
network = alt_creds.network
subnet = alt_creds.subnet
router = alt_creds.router
@@ -485,10 +486,10 @@
self._mock_router_create('1234', 'fake_admin_router')
router_interface_mock = self.patch(
'tempest.services.network.json.network_client.NetworkClient.'
- 'add_router_interface_with_subnet_id')
+ 'add_router_interface')
self._mock_list_roles('123456', 'admin')
admin_creds = creds.get_admin_creds()
- router_interface_mock.assert_called_once_with('1234', '1234')
+ router_interface_mock.assert_called_once_with('1234', subnet_id='1234')
network = admin_creds.network
subnet = admin_creds.subnet
router = admin_creds.router
diff --git a/tempest/tests/services/compute/test_base_compute_client.py b/tempest/tests/services/compute/test_base_compute_client.py
index 134fe39..7a55cdb 100644
--- a/tempest/tests/services/compute/test_base_compute_client.py
+++ b/tempest/tests/services/compute/test_base_compute_client.py
@@ -13,64 +13,48 @@
# under the License.
import httplib2
-import mock
+from oslotest import mockpatch
from tempest_lib.common import rest_client
from tempest import exceptions
-from tempest.services.compute.json import base as base_compute_client
+from tempest.services.compute.json import base_compute_client
from tempest.tests import fake_auth_provider
from tempest.tests.services.compute import base
-class TestClientWithoutMicroversionHeader(base.BaseComputeServiceTest):
+class TestMicroversionHeaderCheck(base.BaseComputeServiceTest):
def setUp(self):
- super(TestClientWithoutMicroversionHeader, self).setUp()
+ super(TestMicroversionHeaderCheck, self).setUp()
fake_auth = fake_auth_provider.FakeAuthProvider()
self.client = base_compute_client.BaseComputeClient(
fake_auth, 'compute', 'regionOne')
+ self.client.set_api_microversion('2.2')
- def test_no_microverion_header(self):
- header = self.client.get_headers()
- self.assertNotIn('X-OpenStack-Nova-API-Version', header)
+ def _check_microverion_header_in_response(self, fake_response):
+ def request(*args, **kwargs):
+ return (httplib2.Response(fake_response), {})
- def test_no_microverion_header_in_raw_request(self):
- def raw_request(*args, **kwargs):
- self.assertNotIn('X-OpenStack-Nova-API-Version', kwargs['headers'])
- return (httplib2.Response({'status': 200}), {})
+ self.useFixture(mockpatch.PatchObject(
+ rest_client.RestClient,
+ 'request',
+ side_effect=request))
- with mock.patch.object(rest_client.RestClient,
- 'raw_request') as mock_get:
- mock_get.side_effect = raw_request
- self.client.get('fake_url')
+ def test_correct_microverion_in_response(self):
+ fake_response = {self.client.api_microversion_header_name: '2.2'}
+ self._check_microverion_header_in_response(fake_response)
+ self.client.get('fake_url')
+ def test_incorrect_microverion_in_response(self):
+ fake_response = {self.client.api_microversion_header_name: '2.3'}
+ self._check_microverion_header_in_response(fake_response)
+ self.assertRaises(exceptions.InvalidHTTPResponseHeader,
+ self.client.get, 'fake_url')
-class TestClientWithMicroversionHeader(base.BaseComputeServiceTest):
-
- def setUp(self):
- super(TestClientWithMicroversionHeader, self).setUp()
- fake_auth = fake_auth_provider.FakeAuthProvider()
- self.client = base_compute_client.BaseComputeClient(
- fake_auth, 'compute', 'regionOne')
- self.client.api_microversion = '2.2'
-
- def test_microverion_header(self):
- header = self.client.get_headers()
- self.assertIn('X-OpenStack-Nova-API-Version', header)
- self.assertEqual(self.client.api_microversion,
- header['X-OpenStack-Nova-API-Version'])
-
- def test_microverion_header_in_raw_request(self):
- def raw_request(*args, **kwargs):
- self.assertIn('X-OpenStack-Nova-API-Version', kwargs['headers'])
- self.assertEqual(self.client.api_microversion,
- kwargs['headers']['X-OpenStack-Nova-API-Version'])
- return (httplib2.Response({'status': 200}), {})
-
- with mock.patch.object(rest_client.RestClient,
- 'raw_request') as mock_get:
- mock_get.side_effect = raw_request
- self.client.get('fake_url')
+ def test_no_microverion_header_in_response(self):
+ self._check_microverion_header_in_response({})
+ self.assertRaises(exceptions.InvalidHTTPResponseHeader,
+ self.client.get, 'fake_url')
class DummyServiceClient1(base_compute_client.BaseComputeClient):
diff --git a/tempest/tests/services/test_base_microversion_client.py b/tempest/tests/services/test_base_microversion_client.py
new file mode 100644
index 0000000..11b8170
--- /dev/null
+++ b/tempest/tests/services/test_base_microversion_client.py
@@ -0,0 +1,75 @@
+# 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 httplib2
+import mock
+from tempest_lib.common import rest_client
+
+from tempest.services import base_microversion_client
+from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
+
+
+class TestClientWithoutMicroversionHeader(base.BaseComputeServiceTest):
+
+ def setUp(self):
+ super(TestClientWithoutMicroversionHeader, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.client = base_microversion_client.BaseMicroversionClient(
+ fake_auth, 'compute', 'regionOne', 'X-OpenStack-Nova-API-Version')
+
+ def test_no_microverion_header(self):
+ header = self.client.get_headers()
+ self.assertNotIn(self.client.api_microversion_header_name, header)
+
+ def test_no_microverion_header_in_raw_request(self):
+ def raw_request(*args, **kwargs):
+ self.assertNotIn(self.client.api_microversion_header_name,
+ kwargs['headers'])
+ return (httplib2.Response({'status': 200}), {})
+
+ with mock.patch.object(rest_client.RestClient,
+ 'raw_request') as mock_get:
+ mock_get.side_effect = raw_request
+ self.client.get('fake_url')
+
+
+class TestClientWithMicroversionHeader(base.BaseComputeServiceTest):
+
+ def setUp(self):
+ super(TestClientWithMicroversionHeader, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.client = base_microversion_client.BaseMicroversionClient(
+ fake_auth, 'compute', 'regionOne', 'X-OpenStack-Nova-API-Version')
+ self.client.set_api_microversion('2.2')
+
+ def test_microverion_header(self):
+ header = self.client.get_headers()
+ self.assertIn(self.client.api_microversion_header_name, header)
+ self.assertEqual(self.client.api_microversion,
+ header[self.client.api_microversion_header_name])
+
+ def test_microverion_header_in_raw_request(self):
+ def raw_request(*args, **kwargs):
+ self.assertIn(self.client.api_microversion_header_name,
+ kwargs['headers'])
+ self.assertEqual(
+ self.client.api_microversion,
+ kwargs['headers'][self.client.api_microversion_header_name])
+ return (httplib2.Response({'status': 200}), {})
+
+ with mock.patch.object(rest_client.RestClient,
+ 'raw_request') as mock_get:
+ mock_get.side_effect = raw_request
+ self.client.get('fake_url')
diff --git a/tempest/tests/test_microversions.py b/tempest/tests/test_microversions.py
new file mode 100644
index 0000000..6738641
--- /dev/null
+++ b/tempest/tests/test_microversions.py
@@ -0,0 +1,153 @@
+# Copyright 2015 NEC Corporation. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from oslo_config import cfg
+import testtools
+
+from tempest.api.compute import base as compute_base
+from tempest import config
+from tempest import exceptions
+from tempest.tests import base
+from tempest.tests import fake_config
+
+
+class VersionTestNoneTolatest(compute_base.BaseV2ComputeTest):
+ min_microversion = None
+ max_microversion = 'latest'
+
+
+class VersionTestNoneTo2_2(compute_base.BaseV2ComputeTest):
+ min_microversion = None
+ max_microversion = '2.2'
+
+
+class VersionTest2_3ToLatest(compute_base.BaseV2ComputeTest):
+ min_microversion = '2.3'
+ max_microversion = 'latest'
+
+
+class VersionTest2_5To2_10(compute_base.BaseV2ComputeTest):
+ min_microversion = '2.5'
+ max_microversion = '2.10'
+
+
+class VersionTest2_10To2_10(compute_base.BaseV2ComputeTest):
+ min_microversion = '2.10'
+ max_microversion = '2.10'
+
+
+class InvalidVersionTest(compute_base.BaseV2ComputeTest):
+ min_microversion = '2.11'
+ max_microversion = '2.1'
+
+
+class TestMicroversionsTestsClass(base.TestCase):
+
+ def setUp(self):
+ super(TestMicroversionsTestsClass, self).setUp()
+ self.useFixture(fake_config.ConfigFixture())
+ self.stubs.Set(config, 'TempestConfigPrivate',
+ fake_config.FakePrivate)
+
+ def _test_version(self, cfg_min, cfg_max,
+ expected_pass_tests,
+ expected_skip_tests):
+ cfg.CONF.set_default('min_microversion',
+ cfg_min, group='compute-feature-enabled')
+ cfg.CONF.set_default('max_microversion',
+ cfg_max, group='compute-feature-enabled')
+ try:
+ for test_class in expected_pass_tests:
+ test_class.skip_checks()
+ for test_class in expected_skip_tests:
+ self.assertRaises(testtools.TestCase.skipException,
+ test_class.skip_checks)
+ except testtools.TestCase.skipException as e:
+ raise testtools.TestCase.failureException(e.message)
+
+ def test_config_version_none_none(self):
+ expected_pass_tests = [VersionTestNoneTolatest, VersionTestNoneTo2_2]
+ expected_skip_tests = [VersionTest2_3ToLatest, VersionTest2_5To2_10,
+ VersionTest2_10To2_10]
+ self._test_version(None, None,
+ expected_pass_tests,
+ expected_skip_tests)
+
+ def test_config_version_none_23(self):
+ expected_pass_tests = [VersionTestNoneTolatest, VersionTestNoneTo2_2,
+ VersionTest2_3ToLatest]
+ expected_skip_tests = [VersionTest2_5To2_10, VersionTest2_10To2_10]
+ self._test_version(None, '2.3',
+ expected_pass_tests,
+ expected_skip_tests)
+
+ def test_config_version_22_latest(self):
+ expected_pass_tests = [VersionTestNoneTolatest, VersionTestNoneTo2_2,
+ VersionTest2_3ToLatest, VersionTest2_5To2_10,
+ VersionTest2_10To2_10]
+ expected_skip_tests = []
+ self._test_version('2.2', 'latest',
+ expected_pass_tests,
+ expected_skip_tests)
+
+ def test_config_version_22_23(self):
+ expected_pass_tests = [VersionTestNoneTolatest, VersionTestNoneTo2_2,
+ VersionTest2_3ToLatest]
+ expected_skip_tests = [VersionTest2_5To2_10, VersionTest2_10To2_10]
+ self._test_version('2.2', '2.3',
+ expected_pass_tests,
+ expected_skip_tests)
+
+ def test_config_version_210_210(self):
+ expected_pass_tests = [VersionTestNoneTolatest,
+ VersionTest2_3ToLatest,
+ VersionTest2_5To2_10,
+ VersionTest2_10To2_10]
+ expected_skip_tests = [VersionTestNoneTo2_2]
+ self._test_version('2.10', '2.10',
+ expected_pass_tests,
+ expected_skip_tests)
+
+ def test_config_version_none_latest(self):
+ expected_pass_tests = [VersionTestNoneTolatest, VersionTestNoneTo2_2,
+ VersionTest2_3ToLatest, VersionTest2_5To2_10,
+ VersionTest2_10To2_10]
+ expected_skip_tests = []
+ self._test_version(None, 'latest',
+ expected_pass_tests,
+ expected_skip_tests)
+
+ def test_config_version_latest_latest(self):
+ expected_pass_tests = [VersionTestNoneTolatest, VersionTest2_3ToLatest]
+ expected_skip_tests = [VersionTestNoneTo2_2, VersionTest2_5To2_10,
+ VersionTest2_10To2_10]
+ self._test_version('latest', 'latest',
+ expected_pass_tests,
+ expected_skip_tests)
+
+ def test_config_invalid_version(self):
+ cfg.CONF.set_default('min_microversion',
+ '2.5', group='compute-feature-enabled')
+ cfg.CONF.set_default('max_microversion',
+ '2.1', group='compute-feature-enabled')
+ self.assertRaises(exceptions.InvalidAPIVersionRange,
+ VersionTestNoneTolatest.skip_checks)
+
+ def test_config_version_invalid_test_version(self):
+ cfg.CONF.set_default('min_microversion',
+ None, group='compute-feature-enabled')
+ cfg.CONF.set_default('max_microversion',
+ '2.13', group='compute-feature-enabled')
+ self.assertRaises(exceptions.InvalidAPIVersionRange,
+ InvalidVersionTest.skip_checks)
diff --git a/test-requirements.txt b/test-requirements.txt
index 5b01ea9..eb43f31 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -3,10 +3,10 @@
# process, which may cause wedges in the gate later.
hacking<0.11,>=0.10.0
# needed for doc build
-sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2
-python-subunit>=0.0.18
+sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2 # BSD
+python-subunit>=0.0.18 # Apache-2.0/BSD
oslosphinx!=3.4.0,>=2.5.0 # Apache-2.0
-mox>=0.5.3
-mock>=1.2
-coverage>=3.6
+mox>=0.5.3 # Apache-2.0
+mock>=1.2 # BSD
+coverage>=3.6 # Apache-2.0
oslotest>=1.10.0 # Apache-2.0
diff --git a/tools/check_logs.py b/tools/check_logs.py
index 9b707b0..fa7129d 100755
--- a/tools/check_logs.py
+++ b/tools/check_logs.py
@@ -105,7 +105,7 @@
def main(opts):
if opts.directory and opts.url or not (opts.directory or opts.url):
print("Must provide exactly one of -d or -u")
- exit(1)
+ return 1
print("Checking logs...")
WHITELIST_FILE = os.path.join(
os.path.abspath(os.path.dirname(os.path.dirname(__file__))),
diff --git a/tox.ini b/tox.ini
index 832a7b3..95f2cf1 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,6 +1,6 @@
[tox]
envlist = pep8,py34,py27
-minversion = 1.6
+minversion = 2.3.1
skipsdist = True
[tempestenv]