Merge "Delete snapshot in test_image_defined_boot_from_volume"
diff --git a/.gitignore b/.gitignore
index 7cb052f..06a2281 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,9 +3,8 @@
*.pyc
__pycache__/
etc/accounts.yaml
-etc/tempest.conf
+etc/*.conf
etc/tempest.conf.sample
-etc/logging.conf
include/swift_objects/swift_small
include/swift_objects/swift_medium
include/swift_objects/swift_large
diff --git a/README.rst b/README.rst
index 2243536..c93e19f 100644
--- a/README.rst
+++ b/README.rst
@@ -95,10 +95,12 @@
command. Tempest is expecting a ``tempest.conf`` file in etc/ so if only a
sample exists you must rename or copy it to tempest.conf before making
any changes to it otherwise Tempest will not know how to load it. For
- details on configuring Tempest refer to the :ref:`tempest-configuration`.
+ details on configuring Tempest refer to the
+ `Tempest Configuration <https://docs.openstack.org/tempest/latest/configuration.html#tempest-configuration>`_
#. Once the configuration is done you're now ready to run Tempest. This can
- be done using the :ref:`tempest_run` command. This can be done by either
+ be done using the `Tempest Run <https://docs.openstack.org/tempest/latest/run.html#tempest-run>`_
+ command. This can be done by either
running::
$ tempest run
@@ -129,7 +131,8 @@
stable interface and there are no guarantees on the Python API unless otherwise
stated.
-For more details refer to the library documentation here: :ref:`library`
+For more details refer to the `library documentation
+<https://docs.openstack.org/tempest/latest/library.html#library>`_
Release Versioning
------------------
@@ -165,8 +168,10 @@
-------------
Detailed configuration of Tempest is beyond the scope of this
-document see :ref:`tempest-configuration` for more details on configuring
-Tempest. The ``etc/tempest.conf.sample`` attempts to be a self-documenting
+document, see `Tempest Configuration Documentation
+<https://docs.openstack.org/tempest/latest/configuration.html#tempest-configuration>`_
+for more details on configuring Tempest.
+The ``etc/tempest.conf.sample`` attempts to be a self-documenting
version of the configuration.
You can generate a new sample tempest.conf file, run the following
diff --git a/doc/source/data/tempest-plugins-registry.header b/doc/source/data/tempest-plugins-registry.header
index 9821e8e..0de12b7 100644
--- a/doc/source/data/tempest-plugins-registry.header
+++ b/doc/source/data/tempest-plugins-registry.header
@@ -17,7 +17,3 @@
The following are plugins that a script has found in the openstack/
namespace, which includes but is not limited to official OpenStack
projects.
-
-+----------------------------+-------------------------------------------------------------------------+
-|Plugin Name |URL |
-+----------------------------+-------------------------------------------------------------------------+
diff --git a/doc/source/microversion_testing.rst b/doc/source/microversion_testing.rst
index ce9bbb5..983fa24 100644
--- a/doc/source/microversion_testing.rst
+++ b/doc/source/microversion_testing.rst
@@ -306,6 +306,10 @@
.. _2.6: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#id5
+ * `2.8`_
+
+ .. _2.8: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#id7
+
* `2.9`_
.. _2.9: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#id8
@@ -334,6 +338,10 @@
.. _2.26: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#id23
+* `2.28`_
+
+ .. _2.28: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#id25
+
* `2.32`_
.. _2.32: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#id29
@@ -350,6 +358,10 @@
.. _2.39: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#id35
+ * `2.41`_
+
+ .. _2.41: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#id37
+
* `2.42`_
.. _2.42: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#maximum-in-ocata
diff --git a/releasenotes/notes/deprecate-volume-api-selection-config-options-b95c5c0ccbf38916.yaml b/releasenotes/notes/deprecate-volume-api-selection-config-options-b95c5c0ccbf38916.yaml
new file mode 100644
index 0000000..1bea6d0
--- /dev/null
+++ b/releasenotes/notes/deprecate-volume-api-selection-config-options-b95c5c0ccbf38916.yaml
@@ -0,0 +1,19 @@
+---
+deprecations:
+ - |
+ The v2 volume API has been deprecated since Pike release.
+ Volume v3 API is current and Tempest volume tests can
+ be run against v2 or v3 API based on config option
+ ``CONF.volume.catalog_type``. If catalog_type is ``volumev2``, then
+ all the volume tests will run against v2 API. If catalog_type is
+ ``volumev3`` which is default in Tempest, then all the volume
+ tests will run against v3 API.
+ That makes below config options unusable in Tempest which used to
+ select the target volume API for volume tests.
+
+ * ``CONF.volume-feature-enabled.api_v2``
+ * ``CONF.volume-feature-enabled.api_v3``
+
+ Tempest deprecate the above two config options in Rocky release
+ and will be removed in future. Alternatively ``CONF.volume.catalog_type``
+ can be used to run the Tempest against volume v2 or v3 API.
diff --git a/releasenotes/notes/tempest-rocky-release-0fc3312053923380.yaml b/releasenotes/notes/tempest-rocky-release-0fc3312053923380.yaml
new file mode 100644
index 0000000..e9c77a6
--- /dev/null
+++ b/releasenotes/notes/tempest-rocky-release-0fc3312053923380.yaml
@@ -0,0 +1,16 @@
+---
+prelude: >
+ This release is to tag the Tempest for OpenStack Rocky release.
+ After this release, Tempest will support below OpenStack Releases:
+
+ * Rocky
+ * Queens
+ * Pike
+ * Ocata
+
+ Current development of Tempest is for OpenStack Stein development
+ cycle. Every Tempest commit is also tested against master during
+ the Stein cycle. However, this does not necessarily mean that using
+ Tempest as of this tag will work against a Stein (or future release)
+ cloud.
+ To be on safe side, use this tag to test the OpenStack Rocky release.
\ No newline at end of file
diff --git a/releasenotes/notes/vnc-hardcoded-server-name-removed-6f8d1e90a175dc08.yaml b/releasenotes/notes/vnc-hardcoded-server-name-removed-6f8d1e90a175dc08.yaml
index 0da2ddc..d3a6851 100644
--- a/releasenotes/notes/vnc-hardcoded-server-name-removed-6f8d1e90a175dc08.yaml
+++ b/releasenotes/notes/vnc-hardcoded-server-name-removed-6f8d1e90a175dc08.yaml
@@ -2,9 +2,9 @@
features:
- |
New string configuration option ``vnc_server_header`` is added
- to ``compute-feature-enabled`` section. It offers to provide VNC server
- name that is to be expected in the responce header. For example, obvious
- at hand names is 'WebSockify', 'nginx'.
+ to ``compute-feature-enabled`` section. It allows the expected
+ VNC server name in the response header to be specified. For example,
+ obvious at hand names are 'WebSockify', 'nginx'.
fixes:
- |
Fix VNC server response header issue when it is behind reverse proxy
diff --git a/releasenotes/source/index.rst b/releasenotes/source/index.rst
index 2518703..3be014f 100644
--- a/releasenotes/source/index.rst
+++ b/releasenotes/source/index.rst
@@ -6,6 +6,7 @@
:maxdepth: 1
unreleased
+ v19.0.0
v18.0.0
v17.2.0
v17.1.0
diff --git a/releasenotes/source/v19.0.0.rst b/releasenotes/source/v19.0.0.rst
new file mode 100644
index 0000000..bcffe5d
--- /dev/null
+++ b/releasenotes/source/v19.0.0.rst
@@ -0,0 +1,6 @@
+=====================
+v19.0.0 Release Notes
+=====================
+
+.. release-notes:: 19.0.0 Release Notes
+ :version: 19.0.0
diff --git a/roles/run-tempest/README.rst b/roles/run-tempest/README.rst
index 384ca38..71b8e4f 100644
--- a/roles/run-tempest/README.rst
+++ b/roles/run-tempest/README.rst
@@ -39,3 +39,20 @@
:default: smoke
The Tempest tox environment to run.
+
+.. zuul:rolevar:: tempest_black_regex
+ :default: ''
+
+ A regular expression used to skip the tests.
+
+ It works only when used with some specific tox environments
+ ('all', 'all-plugin'.)
+
+ Multi-line and commented regexs can be achieved by doing this:
+
+ ::
+ vars:
+ tempest_black_regex: |
+ (?x) # Ignore comments and whitespaces
+ # Line with only a comment.
+ (tempest.api.identity).*$
diff --git a/roles/run-tempest/defaults/main.yaml b/roles/run-tempest/defaults/main.yaml
index 85e94f2..c89eb93 100644
--- a/roles/run-tempest/defaults/main.yaml
+++ b/roles/run-tempest/defaults/main.yaml
@@ -1,3 +1,4 @@
devstack_base_dir: /opt/stack
tempest_test_regex: ''
tox_envlist: smoke
+tempest_black_regex: ''
diff --git a/roles/run-tempest/tasks/main.yaml b/roles/run-tempest/tasks/main.yaml
index b68507a..54ddc71 100644
--- a/roles/run-tempest/tasks/main.yaml
+++ b/roles/run-tempest/tasks/main.yaml
@@ -35,7 +35,9 @@
when: blacklist_stat.stat.exists
- name: Run Tempest
- command: tox -e {{tox_envlist}} -- {{tempest_test_regex|quote}} {{blacklist_option|default('')}} --concurrency={{tempest_concurrency|default(default_concurrency)}}
+ command: tox -e {{tox_envlist}} -- {{tempest_test_regex|quote}} {{blacklist_option|default('')}} \
+ --concurrency={{tempest_concurrency|default(default_concurrency)}} \
+ --black-regex={{tempest_black_regex|quote}}
args:
chdir: "{{devstack_base_dir}}/tempest"
become: true
diff --git a/tempest/api/compute/admin/test_aggregates.py b/tempest/api/compute/admin/test_aggregates.py
index d8faa33..c9d5733 100644
--- a/tempest/api/compute/admin/test_aggregates.py
+++ b/tempest/api/compute/admin/test_aggregates.py
@@ -25,17 +25,17 @@
CONF = config.CONF
-class AggregatesAdminTestJSON(base.BaseV2ComputeAdminTest):
+class AggregatesAdminTestBase(base.BaseV2ComputeAdminTest):
"""Tests Aggregates API that require admin privileges"""
@classmethod
def setup_clients(cls):
- super(AggregatesAdminTestJSON, cls).setup_clients()
+ super(AggregatesAdminTestBase, cls).setup_clients()
cls.client = cls.os_admin.aggregates_client
@classmethod
def resource_setup(cls):
- super(AggregatesAdminTestJSON, cls).resource_setup()
+ super(AggregatesAdminTestBase, cls).resource_setup()
cls.aggregate_name_prefix = 'test_aggregate'
cls.az_name_prefix = 'test_az'
@@ -69,6 +69,9 @@
return aggregate
+
+class AggregatesAdminTestJSON(AggregatesAdminTestBase):
+
@decorators.idempotent_id('0d148aa3-d54c-4317-aa8d-42040a475e20')
def test_aggregate_create_delete(self):
# Create and delete an aggregate.
@@ -226,3 +229,28 @@
wait_until='ACTIVE')
body = admin_servers_client.show_server(server['id'])['server']
self.assertEqual(host, body['OS-EXT-SRV-ATTR:host'])
+
+
+class AggregatesAdminTestV241(AggregatesAdminTestBase):
+ min_microversion = '2.41'
+
+ # NOTE(gmann): This test tests the Aggregate APIs response schema
+ # for 2.41 microversion. No specific assert or behaviour verification
+ # is needed.
+
+ @decorators.idempotent_id('fdf24d9e-8afa-4700-b6aa-9c498351504f')
+ def test_create_update_show_aggregate_add_remove_host(self):
+ # Update and add a host to the given aggregate and get details.
+ self.useFixture(fixtures.LockFixture('availability_zone'))
+ # Checking create aggregate API response schema
+ aggregate = self._create_test_aggregate()
+
+ new_aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
+ # Checking update aggregate API response schema
+ self.client.update_aggregate(aggregate['id'], name=new_aggregate_name)
+ # Checking show aggregate API response schema
+ self.client.show_aggregate(aggregate['id'])['aggregate']
+ # Checking add host to aggregate API response schema
+ self.client.add_host(aggregate['id'], host=self.host)
+ # Checking rempve host from aggregate API response schema
+ self.client.remove_host(aggregate['id'], host=self.host)
diff --git a/tempest/api/compute/admin/test_hypervisor.py b/tempest/api/compute/admin/test_hypervisor.py
index b23c59f..14f51e9 100644
--- a/tempest/api/compute/admin/test_hypervisor.py
+++ b/tempest/api/compute/admin/test_hypervisor.py
@@ -104,6 +104,19 @@
"None of the hypervisors had a valid uptime: %s" % hypers)
+class HypervisorAdminV228Test(HypervisorAdminTestBase):
+ min_microversion = '2.28'
+
+ @decorators.idempotent_id('d46bab64-0fbe-4eb8-9133-e6ee56188cc5')
+ def test_get_list_hypervisor_details(self):
+ # NOTE(zhufl): This test tests the hypervisor APIs response schema
+ # for 2.28 microversion. No specific assert or behaviour verification
+ # is needed.
+ hypers = self._list_hypervisors()
+ self.assertNotEmpty(hypers, "No hypervisors found.")
+ self.client.show_hypervisor(hypers[0]['id'])
+
+
class HypervisorAdminUnderV252Test(HypervisorAdminTestBase):
max_microversion = '2.52'
diff --git a/tempest/api/compute/admin/test_quotas.py b/tempest/api/compute/admin/test_quotas.py
index df534bc..12c7255 100644
--- a/tempest/api/compute/admin/test_quotas.py
+++ b/tempest/api/compute/admin/test_quotas.py
@@ -25,22 +25,57 @@
LOG = logging.getLogger(__name__)
-class QuotasAdminTestJSON(base.BaseV2ComputeAdminTest):
+class QuotasAdminTestBase(base.BaseV2ComputeAdminTest):
force_tenant_isolation = True
def setUp(self):
# NOTE(mriedem): Avoid conflicts with os-quota-class-sets tests.
self.useFixture(fixtures.LockFixture('compute_quotas'))
- super(QuotasAdminTestJSON, self).setUp()
+ super(QuotasAdminTestBase, self).setUp()
@classmethod
def setup_clients(cls):
- super(QuotasAdminTestJSON, cls).setup_clients()
+ super(QuotasAdminTestBase, cls).setup_clients()
cls.adm_client = cls.os_admin.quotas_client
+ def _get_updated_quotas(self):
+ # Verify that GET shows the updated quota set of project
+ project_name = data_utils.rand_name('cpu_quota_project')
+ project_desc = project_name + '-desc'
+ project = identity.identity_utils(self.os_admin).create_project(
+ name=project_name, description=project_desc)
+ project_id = project['id']
+ self.addCleanup(identity.identity_utils(self.os_admin).delete_project,
+ project_id)
+
+ self.adm_client.update_quota_set(project_id, ram='5120')
+ # Call show_quota_set with detail=true to cover the
+ # get_quota_set_details response schema for microversion tests
+ quota_set = self.adm_client.show_quota_set(
+ project_id, detail=True)['quota_set']
+ self.assertEqual(5120, quota_set['ram']['limit'])
+
+ # Verify that GET shows the updated quota set of user
+ user_name = data_utils.rand_name('cpu_quota_user')
+ password = data_utils.rand_password()
+ email = user_name + '@testmail.tm'
+ user = identity.identity_utils(self.os_admin).create_user(
+ username=user_name, password=password, project=project,
+ email=email)
+ user_id = user['id']
+ self.addCleanup(identity.identity_utils(self.os_admin).delete_user,
+ user_id)
+
+ self.adm_client.update_quota_set(project_id,
+ user_id=user_id,
+ ram='2048')
+ quota_set = self.adm_client.show_quota_set(
+ project_id, user_id=user_id)['quota_set']
+ self.assertEqual(2048, quota_set['ram'])
+
@classmethod
def resource_setup(cls):
- super(QuotasAdminTestJSON, cls).resource_setup()
+ super(QuotasAdminTestBase, cls).resource_setup()
# NOTE(afazekas): these test cases should always create and use a new
# tenant most of them should be skipped if we can't do that
@@ -60,6 +95,8 @@
'injected_file_path_bytes',
'injected_files'])
+
+class QuotasAdminTestJSON(QuotasAdminTestBase):
@decorators.idempotent_id('3b0a7c8f-cf58-46b8-a60c-715a32a8ba7d')
def test_get_default_quotas(self):
# Admin can get the default resource quota set for a tenant
@@ -103,36 +140,7 @@
# TODO(afazekas): merge these test cases
@decorators.idempotent_id('ce9e0815-8091-4abd-8345-7fe5b85faa1d')
def test_get_updated_quotas(self):
- # Verify that GET shows the updated quota set of project
- project_name = data_utils.rand_name('cpu_quota_project')
- project_desc = project_name + '-desc'
- project = identity.identity_utils(self.os_admin).create_project(
- name=project_name, description=project_desc)
- project_id = project['id']
- self.addCleanup(identity.identity_utils(self.os_admin).delete_project,
- project_id)
-
- self.adm_client.update_quota_set(project_id, ram='5120')
- quota_set = self.adm_client.show_quota_set(project_id)['quota_set']
- self.assertEqual(5120, quota_set['ram'])
-
- # Verify that GET shows the updated quota set of user
- user_name = data_utils.rand_name('cpu_quota_user')
- password = data_utils.rand_password()
- email = user_name + '@testmail.tm'
- user = identity.identity_utils(self.os_admin).create_user(
- username=user_name, password=password, project=project,
- email=email)
- user_id = user['id']
- self.addCleanup(identity.identity_utils(self.os_admin).delete_user,
- user_id)
-
- self.adm_client.update_quota_set(project_id,
- user_id=user_id,
- ram='2048')
- quota_set = self.adm_client.show_quota_set(
- project_id, user_id=user_id)['quota_set']
- self.assertEqual(2048, quota_set['ram'])
+ self._get_updated_quotas()
@decorators.idempotent_id('389d04f0-3a41-405f-9317-e5f86e3c44f0')
def test_delete_quota(self):
@@ -156,6 +164,30 @@
self.assertEqual(ram_default, quota_set_new['ram'])
+class QuotasAdminTestV236(QuotasAdminTestBase):
+ min_microversion = '2.36'
+ # NOTE(gmann): This test tests the Quota APIs response schema
+ # for 2.36 microversion. No specific assert or behaviour verification
+ # is needed.
+
+ @decorators.idempotent_id('4268b5c9-92e5-4adc-acf1-3a2798f3d803')
+ def test_get_updated_quotas(self):
+ # Checking Quota update, get, get details APIs response schema
+ self._get_updated_quotas()
+
+
+class QuotasAdminTestV257(QuotasAdminTestBase):
+ min_microversion = '2.57'
+ # NOTE(gmann): This test tests the Quota APIs response schema
+ # for 2.57 microversion. No specific assert or behaviour verification
+ # is needed.
+
+ @decorators.idempotent_id('e641e6c6-e86c-41a4-9e5c-9493c0ae47ad')
+ def test_get_updated_quotas(self):
+ # Checking Quota update, get, get details APIs response schema
+ self._get_updated_quotas()
+
+
class QuotaClassesAdminTestJSON(base.BaseV2ComputeAdminTest):
"""Tests the os-quota-class-sets API to update default quotas."""
diff --git a/tempest/api/compute/servers/test_attach_interfaces.py b/tempest/api/compute/servers/test_attach_interfaces.py
index 7509ac6..0636ee4 100644
--- a/tempest/api/compute/servers/test_attach_interfaces.py
+++ b/tempest/api/compute/servers/test_attach_interfaces.py
@@ -29,11 +29,11 @@
CONF = config.CONF
-class AttachInterfacesTestJSON(base.BaseV2ComputeTest):
+class AttachInterfacesTestBase(base.BaseV2ComputeTest):
@classmethod
def skip_checks(cls):
- super(AttachInterfacesTestJSON, cls).skip_checks()
+ super(AttachInterfacesTestBase, cls).skip_checks()
if not CONF.service_available.neutron:
raise cls.skipException("Neutron is required")
if not CONF.compute_feature_enabled.interface_attach:
@@ -43,14 +43,26 @@
def setup_credentials(cls):
# This test class requires network and subnet
cls.set_network_resources(network=True, subnet=True)
- super(AttachInterfacesTestJSON, cls).setup_credentials()
+ super(AttachInterfacesTestBase, cls).setup_credentials()
@classmethod
def setup_clients(cls):
- super(AttachInterfacesTestJSON, cls).setup_clients()
+ super(AttachInterfacesTestBase, cls).setup_clients()
cls.subnets_client = cls.os_primary.subnets_client
cls.ports_client = cls.os_primary.ports_client
+ def _create_server_get_interfaces(self):
+ server = self.create_test_server(wait_until='ACTIVE')
+ ifs = (self.interfaces_client.list_interfaces(server['id'])
+ ['interfaceAttachments'])
+ body = waiters.wait_for_interface_status(
+ self.interfaces_client, server['id'], ifs[0]['port_id'], 'ACTIVE')
+ ifs[0]['port_state'] = body['port_state']
+ return server, ifs
+
+
+class AttachInterfacesTestJSON(AttachInterfacesTestBase):
+
def wait_for_port_detach(self, port_id):
"""Waits for the port's device_id to be unset.
@@ -92,15 +104,6 @@
if mac_addr:
self.assertEqual(iface['mac_addr'], mac_addr)
- def _create_server_get_interfaces(self):
- server = self.create_test_server(wait_until='ACTIVE')
- ifs = (self.interfaces_client.list_interfaces(server['id'])
- ['interfaceAttachments'])
- body = waiters.wait_for_interface_status(
- self.interfaces_client, server['id'], ifs[0]['port_id'], 'ACTIVE')
- ifs[0]['port_state'] = body['port_state']
- return server, ifs
-
def _test_create_interface(self, server):
iface = (self.interfaces_client.create_interface(server['id'])
['interfaceAttachment'])
@@ -254,30 +257,6 @@
_ifs = self._test_delete_interface(server, ifs)
self.assertEqual(len(ifs) - 1, len(_ifs))
- @decorators.attr(type='smoke')
- @decorators.idempotent_id('c7e0e60b-ee45-43d0-abeb-8596fd42a2f9')
- @utils.services('network')
- def test_add_remove_fixed_ip(self):
- # Add and Remove the fixed IP to server.
- server, ifs = self._create_server_get_interfaces()
- interface_count = len(ifs)
- self.assertGreater(interface_count, 0)
- network_id = ifs[0]['net_id']
- self.servers_client.add_fixed_ip(server['id'], networkId=network_id)
- # Remove the fixed IP from server.
- server_detail = self.os_primary.servers_client.show_server(
- server['id'])['server']
- # Get the Fixed IP from server.
- fixed_ip = None
- for ip_set in server_detail['addresses']:
- for ip in server_detail['addresses'][ip_set]:
- if ip['OS-EXT-IPS:type'] == 'fixed':
- fixed_ip = ip['addr']
- break
- if fixed_ip is not None:
- break
- self.servers_client.remove_fixed_ip(server['id'], address=fixed_ip)
-
@decorators.idempotent_id('2f3a0127-95c7-4977-92d2-bc5aec602fb4')
def test_reassign_port_between_servers(self):
"""Tests the following:
@@ -314,3 +293,31 @@
# API so we have to poll the port until the device_id is unset.
self.interfaces_client.delete_interface(server['id'], port_id)
self.wait_for_port_detach(port_id)
+
+
+class AttachInterfacesUnderV243Test(AttachInterfacesTestBase):
+ max_microversion = '2.43'
+
+ @decorators.attr(type='smoke')
+ @decorators.idempotent_id('c7e0e60b-ee45-43d0-abeb-8596fd42a2f9')
+ @utils.services('network')
+ def test_add_remove_fixed_ip(self):
+ # Add and Remove the fixed IP to server.
+ server, ifs = self._create_server_get_interfaces()
+ interface_count = len(ifs)
+ self.assertGreater(interface_count, 0)
+ network_id = ifs[0]['net_id']
+ self.servers_client.add_fixed_ip(server['id'], networkId=network_id)
+ # Remove the fixed IP from server.
+ server_detail = self.os_primary.servers_client.show_server(
+ server['id'])['server']
+ # Get the Fixed IP from server.
+ fixed_ip = None
+ for ip_set in server_detail['addresses']:
+ for ip in server_detail['addresses'][ip_set]:
+ if ip['OS-EXT-IPS:type'] == 'fixed':
+ fixed_ip = ip['addr']
+ break
+ if fixed_ip is not None:
+ break
+ self.servers_client.remove_fixed_ip(server['id'], address=fixed_ip)
diff --git a/tempest/api/volume/admin/test_volume_quotas.py b/tempest/api/volume/admin/test_volume_quotas.py
index e546bff..61a6df4 100644
--- a/tempest/api/volume/admin/test_volume_quotas.py
+++ b/tempest/api/volume/admin/test_volume_quotas.py
@@ -38,8 +38,8 @@
@classmethod
def setup_clients(cls):
super(BaseVolumeQuotasAdminTestJSON, cls).setup_clients()
- cls.transfer_client = cls.os_primary.volume_transfers_v2_client
- cls.alt_transfer_client = cls.os_alt.volume_transfers_v2_client
+ cls.transfer_client = cls.os_primary.volume_transfers_client_latest
+ cls.alt_transfer_client = cls.os_alt.volume_transfers_client_latest
@classmethod
def resource_setup(cls):
diff --git a/tempest/api/volume/base.py b/tempest/api/volume/base.py
index 81fd6e6..64fe29a 100644
--- a/tempest/api/volume/base.py
+++ b/tempest/api/volume/base.py
@@ -74,24 +74,19 @@
if CONF.service_available.glance:
cls.images_client = cls.os_primary.image_client_v2
- if cls._api_version == 3:
- cls.backups_client = cls.os_primary.backups_v3_client
- cls.volumes_client = cls.os_primary.volumes_v3_client
- cls.messages_client = cls.os_primary.volume_v3_messages_client
- cls.versions_client = cls.os_primary.volume_v3_versions_client
- cls.groups_client = cls.os_primary.groups_v3_client
- cls.group_snapshots_client = (
- cls.os_primary.group_snapshots_v3_client)
- else:
- cls.backups_client = cls.os_primary.backups_v2_client
- cls.volumes_client = cls.os_primary.volumes_v2_client
-
- cls.snapshots_client = cls.os_primary.snapshots_v2_client
+ cls.backups_client = cls.os_primary.backups_client_latest
+ cls.volumes_client = cls.os_primary.volumes_client_latest
+ cls.messages_client = cls.os_primary.volume_messages_client_latest
+ cls.versions_client = cls.os_primary.volume_versions_client_latest
+ cls.groups_client = cls.os_primary.groups_client_latest
+ cls.group_snapshots_client = (
+ cls.os_primary.group_snapshots_client_latest)
+ cls.snapshots_client = cls.os_primary.snapshots_client_latest
cls.volumes_extension_client =\
- cls.os_primary.volumes_v2_extension_client
+ cls.os_primary.volumes_extension_client_latest
cls.availability_zone_client = (
- cls.os_primary.volume_v2_availability_zone_client)
- cls.volume_limits_client = cls.os_primary.volume_v2_limits_client
+ cls.os_primary.volume_availability_zone_client_latest)
+ cls.volume_limits_client = cls.os_primary.volume_limits_client_latest
def setUp(self):
super(BaseVolumeTest, self).setUp()
@@ -247,34 +242,34 @@
def setup_clients(cls):
super(BaseVolumeAdminTest, cls).setup_clients()
- cls.admin_volume_qos_client = cls.os_admin.volume_qos_v2_client
+ cls.admin_volume_qos_client = cls.os_admin.volume_qos_client_latest
cls.admin_volume_services_client = \
- cls.os_admin.volume_services_v2_client
- cls.admin_volume_types_client = cls.os_admin.volume_types_v2_client
- cls.admin_volume_manage_client = cls.os_admin.volume_manage_v2_client
- cls.admin_volume_client = cls.os_admin.volumes_v2_client
- if cls._api_version == 3:
- cls.admin_volume_client = cls.os_admin.volumes_v3_client
- cls.admin_groups_client = cls.os_admin.groups_v3_client
- cls.admin_messages_client = cls.os_admin.volume_v3_messages_client
- cls.admin_group_snapshots_client = \
- cls.os_admin.group_snapshots_v3_client
- cls.admin_group_types_client = cls.os_admin.group_types_v3_client
- cls.admin_hosts_client = cls.os_admin.volume_hosts_v2_client
+ cls.os_admin.volume_services_client_latest
+ cls.admin_volume_types_client = cls.os_admin.volume_types_client_latest
+ cls.admin_volume_manage_client = (
+ cls.os_admin.volume_manage_client_latest)
+ cls.admin_volume_client = cls.os_admin.volumes_client_latest
+ cls.admin_groups_client = cls.os_admin.groups_client_latest
+ cls.admin_messages_client = cls.os_admin.volume_messages_client_latest
+ cls.admin_group_snapshots_client = \
+ cls.os_admin.group_snapshots_client_latest
+ cls.admin_group_types_client = cls.os_admin.group_types_client_latest
+ cls.admin_hosts_client = cls.os_admin.volume_hosts_client_latest
cls.admin_snapshot_manage_client = \
- cls.os_admin.snapshot_manage_v2_client
- cls.admin_snapshots_client = cls.os_admin.snapshots_v2_client
- cls.admin_backups_client = cls.os_admin.backups_v2_client
+ cls.os_admin.snapshot_manage_client_latest
+ cls.admin_snapshots_client = cls.os_admin.snapshots_client_latest
+ cls.admin_backups_client = cls.os_admin.backups_client_latest
cls.admin_encryption_types_client = \
- cls.os_admin.encryption_types_v2_client
+ cls.os_admin.encryption_types_client_latest
cls.admin_quota_classes_client = \
- cls.os_admin.volume_quota_classes_v2_client
- cls.admin_quotas_client = cls.os_admin.volume_quotas_v2_client
- cls.admin_volume_limits_client = cls.os_admin.volume_v2_limits_client
+ cls.os_admin.volume_quota_classes_client_latest
+ cls.admin_quotas_client = cls.os_admin.volume_quotas_client_latest
+ cls.admin_volume_limits_client = (
+ cls.os_admin.volume_limits_client_latest)
cls.admin_capabilities_client = \
- cls.os_admin.volume_capabilities_v2_client
+ cls.os_admin.volume_capabilities_client_latest
cls.admin_scheduler_stats_client = \
- cls.os_admin.volume_scheduler_stats_v2_client
+ cls.os_admin.volume_scheduler_stats_client_latest
@classmethod
def create_test_qos_specs(cls, name=None, consumer=None, **kwargs):
diff --git a/tempest/api/volume/test_volume_transfers.py b/tempest/api/volume/test_volume_transfers.py
index 75e81b7..c85e0bc 100644
--- a/tempest/api/volume/test_volume_transfers.py
+++ b/tempest/api/volume/test_volume_transfers.py
@@ -27,10 +27,10 @@
def setup_clients(cls):
super(VolumesTransfersTest, cls).setup_clients()
- cls.client = cls.os_primary.volume_transfers_v2_client
- cls.alt_client = cls.os_alt.volume_transfers_v2_client
- cls.alt_volumes_client = cls.os_alt.volumes_v2_client
- cls.adm_volumes_client = cls.os_admin.volumes_v2_client
+ cls.client = cls.os_primary.volume_transfers_client_latest
+ cls.alt_client = cls.os_alt.volume_transfers_client_latest
+ cls.alt_volumes_client = cls.os_alt.volumes_client_latest
+ cls.adm_volumes_client = cls.os_admin.volumes_client_latest
@decorators.idempotent_id('4d75b645-a478-48b1-97c8-503f64242f1a')
def test_create_get_list_accept_volume_transfer(self):
diff --git a/tempest/clients.py b/tempest/clients.py
index 2a07be9..4f2846e 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -241,6 +241,47 @@
# if only api_v3 is enabled, all these clients should be available
if (CONF.volume_feature_enabled.api_v2 or
CONF.volume_feature_enabled.api_v3):
+ self.backups_client_latest = self.volume_v3.BackupsClient()
+ self.encryption_types_client_latest = \
+ self.volume_v3.EncryptionTypesClient()
+ self.snapshot_manage_client_latest = \
+ self.volume_v3.SnapshotManageClient()
+ self.snapshots_client_latest = self.volume_v3.SnapshotsClient()
+ self.volume_capabilities_client_latest = \
+ self.volume_v3.CapabilitiesClient()
+ self.volume_manage_client_latest = (
+ self.volume_v3.VolumeManageClient())
+ self.volume_qos_client_latest = self.volume_v3.QosSpecsClient()
+ self.volume_services_client_latest = (
+ self.volume_v3.ServicesClient())
+ self.volume_types_client_latest = self.volume_v3.TypesClient()
+ self.volume_hosts_client_latest = self.volume_v3.HostsClient()
+ self.volume_quotas_client_latest = self.volume_v3.QuotasClient()
+ self.volume_quota_classes_client_latest = \
+ self.volume_v3.QuotaClassesClient()
+ self.volume_scheduler_stats_client_latest = \
+ self.volume_v3.SchedulerStatsClient()
+ self.volume_transfers_client_latest = \
+ self.volume_v3.TransfersClient()
+ self.volume_availability_zone_client_latest = \
+ self.volume_v3.AvailabilityZoneClient()
+ self.volume_limits_client_latest = self.volume_v3.LimitsClient()
+ self.volumes_client_latest = self.volume_v3.VolumesClient()
+ self.volumes_extension_client_latest = \
+ self.volume_v3.ExtensionsClient()
+ self.group_types_client_latest = self.volume_v3.GroupTypesClient()
+ self.groups_client_latest = self.volume_v3.GroupsClient()
+ self.group_snapshots_client_latest = \
+ self.volume_v3.GroupSnapshotsClient()
+ self.volume_messages_client_latest = (
+ self.volume_v3.MessagesClient())
+ self.volume_versions_client_latest = (
+ self.volume_v3.VersionsClient())
+
+ # TODO(gmann): Below alias for service clients have been
+ # deprecated and will be removed in future. Start using the alias
+ # defined above with suffix _latest.
+ # ****************Deprecated alias start from here***************
self.backups_v2_client = self.volume_v3.BackupsClient()
self.encryption_types_v2_client = \
self.volume_v3.EncryptionTypesClient()
@@ -268,11 +309,6 @@
self.volumes_v2_extension_client = \
self.volume_v3.ExtensionsClient()
- # Set default client for users that don't need explicit version
- self.volumes_client_latest = self.volumes_v2_client
- self.snapshots_client_latest = self.snapshots_v2_client
- self.backups_client_latest = self.backups_v2_client
-
if CONF.volume_feature_enabled.api_v3:
self.backups_v3_client = self.volume_v3.BackupsClient()
self.group_types_v3_client = self.volume_v3.GroupTypesClient()
@@ -283,11 +319,7 @@
self.volume_v3_messages_client = self.volume_v3.MessagesClient()
self.volume_v3_versions_client = self.volume_v3.VersionsClient()
self.volumes_v3_client = self.volume_v3.VolumesClient()
-
- # Set default client for users that don't need explicit version
- self.volumes_client_latest = self.volumes_v3_client
- self.snapshots_client_latest = self.snapshots_v3_client
- self.backups_client_latest = self.backups_v3_client
+ # ****************Deprecated alias end here***********************
def _set_object_storage_clients(self):
self.account_client = self.object_storage.AccountClient()
diff --git a/tempest/cmd/cleanup_service.py b/tempest/cmd/cleanup_service.py
index 27e1bc1..83cf42c 100644
--- a/tempest/cmd/cleanup_service.py
+++ b/tempest/cmd/cleanup_service.py
@@ -315,7 +315,7 @@
class VolumeQuotaService(BaseService):
def __init__(self, manager, **kwargs):
super(VolumeQuotaService, self).__init__(kwargs)
- self.client = manager.volume_quotas_v2_client
+ self.client = manager.volume_quotas_client_latest
def delete(self):
client = self.client
diff --git a/tempest/common/compute.py b/tempest/common/compute.py
index 68c4a10..f2730b3 100644
--- a/tempest/common/compute.py
+++ b/tempest/common/compute.py
@@ -165,7 +165,7 @@
if volume_backed:
volume_name = data_utils.rand_name(__name__ + '-volume')
- volumes_client = clients.volumes_v2_client
+ volumes_client = clients.volumes_client_latest
params = {'name': volume_name,
'imageRef': image_id,
'size': CONF.volume.volume_size}
diff --git a/tempest/config.py b/tempest/config.py
index cc0ba34..0f3fa54 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -845,10 +845,29 @@
"removed."),
cfg.BoolOpt('api_v2',
default=True,
- help="Is the v2 volume API enabled"),
+ help="Is the v2 volume API enabled",
+ deprecated_for_removal=True,
+ deprecated_reason="The v2 volume API has been deprecated "
+ "since Pike release. Now Tempest run all "
+ "the volume tests against v2 or v3 API "
+ "based on CONF.volume.catalog_type which "
+ "makes this config option unusable. If "
+ "catalog_type is volumev2, then all the "
+ "volume tests will run against v2 API. "
+ "Use ``CONF.volume.catalog_type`` to run "
+ "the Tempest against volume v2 or v3 API"),
cfg.BoolOpt('api_v3',
default=True,
- help="Is the v3 volume API enabled"),
+ help="Is the v3 volume API enabled",
+ deprecated_for_removal=True,
+ deprecated_reason="Tempest run all the volume tests against "
+ "v2 or v3 API based on "
+ "CONF.volume.catalog_type which makes this "
+ "config option unusable. If catalog_type is "
+ "volumev3 which is default, then all the "
+ "volume tests will run against v3 API. "
+ "Use ``CONF.volume.catalog_type`` to run "
+ "the Tempest against volume v2 or v3 API"),
cfg.BoolOpt('extend_attached_volume',
default=False,
help='Does the cloud support extending the size of a volume '
diff --git a/tempest/hacking/checks.py b/tempest/hacking/checks.py
index a72675e..2c40cb1 100644
--- a/tempest/hacking/checks.py
+++ b/tempest/hacking/checks.py
@@ -15,7 +15,7 @@
import os
import re
-import pep8
+import pycodestyle
PYTHON_CLIENTS = ['cinder', 'glance', 'keystone', 'nova', 'swift', 'neutron',
@@ -69,7 +69,7 @@
def no_setup_teardown_class_for_tests(physical_line, filename):
- if pep8.noqa(physical_line):
+ if pycodestyle.noqa(physical_line):
return
if 'tempest/test.py' in filename or 'tempest/lib/' in filename:
@@ -164,7 +164,7 @@
if not METHOD.match(physical_line):
return False
- if pep8.noqa(physical_line):
+ if pycodestyle.noqa(physical_line):
return False
return True
@@ -287,7 +287,7 @@
if 'tempest/api/' not in filename:
return
- if pep8.noqa(physical_line):
+ if pycodestyle.noqa(physical_line):
return
if not re.match(r'class .*Test.*\(.*Admin.*\):', logical_line):
diff --git a/tempest/lib/api_schema/response/compute/v2_1/flavors.py b/tempest/lib/api_schema/response/compute/v2_1/flavors.py
index 43e80cc..bd5e3d6 100644
--- a/tempest/lib/api_schema/response/compute/v2_1/flavors.py
+++ b/tempest/lib/api_schema/response/compute/v2_1/flavors.py
@@ -60,7 +60,7 @@
},
'additionalProperties': False,
# 'OS-FLV-DISABLED', 'os-flavor-access', 'rxtx_factor' and
- # 'OS-FLV-EXT-DATA' are API extensions. So they are not 'required'.
+ # 'OS-FLV-EXT-DATA' are API extensions, so they are not 'required'.
'required': ['name', 'links', 'ram', 'vcpus', 'swap', 'disk', 'id']
}
@@ -74,7 +74,7 @@
'items': common_flavor_info
},
# NOTE(gmann): flavors_links attribute is not necessary
- # to be present always So it is not 'required'.
+ # to be present always so it is not 'required'.
'flavors_links': parameter_types.links
},
'additionalProperties': False,
diff --git a/tempest/lib/api_schema/response/compute/v2_13/server_groups.py b/tempest/lib/api_schema/response/compute/v2_13/server_groups.py
index 2b59e38..5cb4241 100644
--- a/tempest/lib/api_schema/response/compute/v2_13/server_groups.py
+++ b/tempest/lib/api_schema/response/compute/v2_13/server_groups.py
@@ -16,7 +16,9 @@
from tempest.lib.api_schema.response.compute.v2_1 import server_groups
-
+# Compute microversion 2.13:
+# 1. New attributes in 'server_group' dict.
+# 'project_id', 'user_id'
common_server_group = copy.deepcopy(server_groups.common_server_group)
common_server_group['properties']['project_id'] = {'type': 'string'}
common_server_group['properties']['user_id'] = {'type': 'string'}
diff --git a/tempest/lib/api_schema/response/compute/v2_16/servers.py b/tempest/lib/api_schema/response/compute/v2_16/servers.py
index fb1a2fc..72b84f5 100644
--- a/tempest/lib/api_schema/response/compute/v2_16/servers.py
+++ b/tempest/lib/api_schema/response/compute/v2_16/servers.py
@@ -122,7 +122,7 @@
'^[a-zA-Z0-9-_.]+$']['items']['properties'].update({
'OS-EXT-IPS:type': {'type': 'string'},
'OS-EXT-IPS-MAC:mac_addr': parameter_types.mac_address})
-# NOTE(gmann)dd: Update OS-EXT-IPS:type and OS-EXT-IPS-MAC:mac_addr
+# NOTE(gmann): Update OS-EXT-IPS:type and OS-EXT-IPS-MAC:mac_addr
# attributes in server address. Those are API extension,
# and some environments return a response without
# these attributes. So they are not 'required'.
diff --git a/tempest/lib/api_schema/response/compute/v2_19/servers.py b/tempest/lib/api_schema/response/compute/v2_19/servers.py
index 136e3e1..e3e8ad1 100644
--- a/tempest/lib/api_schema/response/compute/v2_19/servers.py
+++ b/tempest/lib/api_schema/response/compute/v2_19/servers.py
@@ -17,6 +17,9 @@
from tempest.lib.api_schema.response.compute.v2_16 import servers \
as serversv216
+# Compute microversion 2.19:
+# 1. New attributes in 'server' dict.
+# 'description'
get_server = copy.deepcopy(serversv216.get_server)
get_server['response_body']['properties']['server'][
'properties'].update({'description': {'type': ['string', 'null']}})
diff --git a/tempest/lib/api_schema/response/compute/v2_28/__init__.py b/tempest/lib/api_schema/response/compute/v2_28/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/lib/api_schema/response/compute/v2_28/__init__.py
diff --git a/tempest/lib/api_schema/response/compute/v2_28/hypervisors.py b/tempest/lib/api_schema/response/compute/v2_28/hypervisors.py
new file mode 100644
index 0000000..8ea9ff8
--- /dev/null
+++ b/tempest/lib/api_schema/response/compute/v2_28/hypervisors.py
@@ -0,0 +1,40 @@
+# Copyright 2018 ZTE 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.lib.api_schema.response.compute.v2_1 \
+ import hypervisors as hypervisorsv21
+
+# hypervisor.cpu_info change from string to JSON object.
+hypervisor_detail = copy.deepcopy(hypervisorsv21.hypervisor_detail)
+hypervisor_detail['properties'].update({'cpu_info': {'type': 'object'}})
+
+list_hypervisors_detail = copy.deepcopy(hypervisorsv21.list_hypervisors_detail)
+list_hypervisors_detail['response_body']['properties']['hypervisors'].update(
+ {'items': hypervisor_detail})
+
+get_hypervisor = copy.deepcopy(hypervisorsv21.get_hypervisor)
+get_hypervisor['response_body']['properties'].update(
+ {'hypervisor': hypervisor_detail})
+
+# NOTE(zhufl): Below are the unchanged schema in this microversion. We need
+# to keep this schema in this file to have the generic way to select the
+# right schema based on self.schema_versions_info mapping in service client.
+# ****** Schemas unchanged since microversion 2.1 ***
+get_hypervisor_statistics = \
+ copy.deepcopy(hypervisorsv21.get_hypervisor_statistics)
+list_search_hypervisors = copy.deepcopy(hypervisorsv21.list_search_hypervisors)
+get_hypervisor_uptime = copy.deepcopy(hypervisorsv21.get_hypervisor_uptime)
+get_hypervisors_servers = copy.deepcopy(hypervisorsv21.get_hypervisors_servers)
diff --git a/tempest/lib/api_schema/response/compute/v2_3/servers.py b/tempest/lib/api_schema/response/compute/v2_3/servers.py
index 969df3b..18fb352 100644
--- a/tempest/lib/api_schema/response/compute/v2_3/servers.py
+++ b/tempest/lib/api_schema/response/compute/v2_3/servers.py
@@ -128,7 +128,7 @@
'^[a-zA-Z0-9-_.]+$']['items']['properties'].update({
'OS-EXT-IPS:type': {'type': 'string'},
'OS-EXT-IPS-MAC:mac_addr': parameter_types.mac_address})
-# NOTE(gmann)dd: Update OS-EXT-IPS:type and OS-EXT-IPS-MAC:mac_addr
+# NOTE(gmann): Update OS-EXT-IPS:type and OS-EXT-IPS-MAC:mac_addr
# attributes in server address. Those are API extension,
# and some environments return a response without
# these attributes. So they are not 'required'.
diff --git a/tempest/lib/api_schema/response/compute/v2_36/quotas.py b/tempest/lib/api_schema/response/compute/v2_36/quotas.py
new file mode 100644
index 0000000..f191ed1
--- /dev/null
+++ b/tempest/lib/api_schema/response/compute/v2_36/quotas.py
@@ -0,0 +1,54 @@
+# Copyright 2018 ZTE 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.lib.api_schema.response.compute.v2_1 import quotas as quotasv21
+
+# Compute microversion 2.36:
+# remove attributes in quota_set:
+# 'fixed_ips',
+# 'floating_ips',
+# 'security_group_rules',
+# 'security_groups'
+
+remove_item_list = ['fixed_ips', 'floating_ips',
+ 'security_group_rules', 'security_groups']
+
+update_quota_set = copy.deepcopy(quotasv21.update_quota_set)
+for item in remove_item_list:
+ update_quota_set['response_body']['properties']['quota_set'][
+ 'properties'].pop(item)
+ update_quota_set['response_body']['properties']['quota_set'][
+ 'required'].remove(item)
+
+get_quota_set = copy.deepcopy(quotasv21.get_quota_set)
+for item in remove_item_list:
+ get_quota_set['response_body']['properties']['quota_set'][
+ 'properties'].pop(item)
+ get_quota_set['response_body']['properties']['quota_set'][
+ 'required'].remove(item)
+
+get_quota_set_details = copy.deepcopy(quotasv21.get_quota_set_details)
+for item in remove_item_list:
+ get_quota_set_details['response_body']['properties']['quota_set'][
+ 'properties'].pop(item)
+ get_quota_set_details['response_body']['properties']['quota_set'][
+ 'required'].remove(item)
+
+# NOTE(zhufl): Below are the unchanged schema in this microversion. We need
+# to keep this schema in this file to have the generic way to select the
+# right schema based on self.schema_versions_info mapping in service client.
+# ****** Schemas unchanged since microversion 2.1 ***
+delete_quota = copy.deepcopy(quotasv21.delete_quota)
diff --git a/tempest/lib/api_schema/response/compute/v2_41/__init__.py b/tempest/lib/api_schema/response/compute/v2_41/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/lib/api_schema/response/compute/v2_41/__init__.py
diff --git a/tempest/lib/api_schema/response/compute/v2_41/aggregates.py b/tempest/lib/api_schema/response/compute/v2_41/aggregates.py
new file mode 100644
index 0000000..036bd83
--- /dev/null
+++ b/tempest/lib/api_schema/response/compute/v2_41/aggregates.py
@@ -0,0 +1,54 @@
+# Copyright 2018 ZTE 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.lib.api_schema.response.compute.v2_1 import aggregates
+
+# 'uuid' of an aggregate is returned in microversion 2.41
+aggregate_for_create = copy.deepcopy(aggregates.aggregate_for_create)
+aggregate_for_create['properties'].update({'uuid': {'type': 'string',
+ 'format': 'uuid'}})
+aggregate_for_create['required'].append('uuid')
+
+common_aggregate_info = copy.deepcopy(aggregates.common_aggregate_info)
+common_aggregate_info['properties'].update({'uuid': {'type': 'string',
+ 'format': 'uuid'}})
+common_aggregate_info['required'].append('uuid')
+
+list_aggregates = copy.deepcopy(aggregates.list_aggregates)
+list_aggregates['response_body']['properties']['aggregates'].update(
+ {'items': common_aggregate_info})
+
+get_aggregate = copy.deepcopy(aggregates.get_aggregate)
+get_aggregate['response_body']['properties'].update(
+ {'aggregate': common_aggregate_info})
+
+aggregate_set_metadata = get_aggregate
+
+update_aggregate = copy.deepcopy(aggregates.update_aggregate)
+update_aggregate['response_body']['properties'].update(
+ {'aggregate': common_aggregate_info})
+
+create_aggregate = copy.deepcopy(aggregates.create_aggregate)
+create_aggregate['response_body']['properties'].update(
+ {'aggregate': aggregate_for_create})
+
+aggregate_add_remove_host = get_aggregate
+
+# NOTE(zhufl): Below are the unchanged schema in this microversion. We need
+# to keep this schema in this file to have the generic way to select the
+# right schema based on self.schema_versions_info mapping in service client.
+# ****** Schemas unchanged since microversion 2.1 ***
+delete_aggregate = copy.deepcopy(aggregates.delete_aggregate)
diff --git a/tempest/lib/api_schema/response/compute/v2_47/servers.py b/tempest/lib/api_schema/response/compute/v2_47/servers.py
index 5922f76..0fbacd3 100644
--- a/tempest/lib/api_schema/response/compute/v2_47/servers.py
+++ b/tempest/lib/api_schema/response/compute/v2_47/servers.py
@@ -57,10 +57,12 @@
# NOTE(zhufl): Below are the unchanged schema in this microversion. We need
# to keep this schema in this file to have the generic way to select the
# right schema based on self.schema_versions_info mapping in service client.
-# ****** Schemas unchanged since microversion 2.26 ***
+show_server_diagnostics = copy.deepcopy(servers226.show_server_diagnostics)
+get_remote_consoles = copy.deepcopy(servers226.get_remote_consoles)
list_tags = copy.deepcopy(servers226.list_tags)
update_all_tags = copy.deepcopy(servers226.update_all_tags)
delete_all_tags = copy.deepcopy(servers226.delete_all_tags)
check_tag_existence = copy.deepcopy(servers226.check_tag_existence)
update_tag = copy.deepcopy(servers226.update_tag)
delete_tag = copy.deepcopy(servers226.delete_tag)
+list_servers = copy.deepcopy(servers226.list_servers)
diff --git a/tempest/lib/api_schema/response/compute/v2_48/servers.py b/tempest/lib/api_schema/response/compute/v2_48/servers.py
index 02b00d6..84b5a2a 100644
--- a/tempest/lib/api_schema/response/compute/v2_48/servers.py
+++ b/tempest/lib/api_schema/response/compute/v2_48/servers.py
@@ -112,15 +112,20 @@
}
}
-get_server = copy.deepcopy(servers247.get_server)
-
# NOTE(zhufl): Below are the unchanged schema in this microversion. We need
# to keep this schema in this file to have the generic way to select the
# right schema based on self.schema_versions_info mapping in service client.
-# ****** Schemas unchanged since microversion 2.26 ***
+list_servers = copy.deepcopy(servers247.list_servers)
+get_remote_consoles = copy.deepcopy(servers247.get_remote_consoles)
list_tags = copy.deepcopy(servers247.list_tags)
update_all_tags = copy.deepcopy(servers247.update_all_tags)
delete_all_tags = copy.deepcopy(servers247.delete_all_tags)
check_tag_existence = copy.deepcopy(servers247.check_tag_existence)
update_tag = copy.deepcopy(servers247.update_tag)
delete_tag = copy.deepcopy(servers247.delete_tag)
+get_server = copy.deepcopy(servers247.get_server)
+list_servers_detail = copy.deepcopy(servers247.list_servers_detail)
+update_server = copy.deepcopy(servers247.update_server)
+rebuild_server = copy.deepcopy(servers247.rebuild_server)
+rebuild_server_with_admin_pass = copy.deepcopy(
+ servers247.rebuild_server_with_admin_pass)
diff --git a/tempest/lib/api_schema/response/compute/v2_53/services.py b/tempest/lib/api_schema/response/compute/v2_53/services.py
index aa132a9..97b0c72 100644
--- a/tempest/lib/api_schema/response/compute/v2_53/services.py
+++ b/tempest/lib/api_schema/response/compute/v2_53/services.py
@@ -42,7 +42,8 @@
'properties': {
'id': {'type': 'string', 'format': 'uuid'},
'binary': {'type': 'string'},
- 'disabled_reason': {'type': 'string'},
+ # disabled_reason can be null when status is enabled.
+ 'disabled_reason': {'type': ['string', 'null']},
'host': {'type': 'string'},
'state': {'type': 'string'},
'status': {'type': 'string'},
diff --git a/tempest/lib/api_schema/response/compute/v2_54/servers.py b/tempest/lib/api_schema/response/compute/v2_54/servers.py
index e264186..099e1b8 100644
--- a/tempest/lib/api_schema/response/compute/v2_54/servers.py
+++ b/tempest/lib/api_schema/response/compute/v2_54/servers.py
@@ -12,7 +12,7 @@
import copy
-from tempest.lib.api_schema.response.compute.v2_47 import servers as servers247
+from tempest.lib.api_schema.response.compute.v2_48 import servers as servers248
# ****** Schemas changed in microversion 2.54 *****************
# Note(gmann): This is schema for microversion 2.54 which includes the
@@ -26,14 +26,14 @@
]
}
-rebuild_server = copy.deepcopy(servers247.rebuild_server)
+rebuild_server = copy.deepcopy(servers248.rebuild_server)
rebuild_server['response_body']['properties']['server'][
'properties'].update({'key_name': key_name})
rebuild_server['response_body']['properties']['server'][
'required'].append('key_name')
rebuild_server_with_admin_pass = copy.deepcopy(
- servers247.rebuild_server_with_admin_pass)
+ servers248.rebuild_server_with_admin_pass)
rebuild_server_with_admin_pass['response_body']['properties']['server'][
'properties'].update({'key_name': key_name})
rebuild_server_with_admin_pass['response_body']['properties']['server'][
@@ -42,15 +42,16 @@
# NOTE(gmann): Below are the unchanged schema in this microversion. We need
# to keep this schema in this file to have the generic way to select the
# right schema based on self.schema_versions_info mapping in service client.
-# ****** Schemas unchanged in microversion 2.54 since microversion 2.47 ***
-get_server = copy.deepcopy(servers247.get_server)
-list_servers_detail = copy.deepcopy(servers247.list_servers_detail)
-update_server = copy.deepcopy(servers247.update_server)
-
-# ****** Schemas unchanged since microversion 2.26 ***
-list_tags = copy.deepcopy(servers247.list_tags)
-update_all_tags = copy.deepcopy(servers247.update_all_tags)
-delete_all_tags = copy.deepcopy(servers247.delete_all_tags)
-check_tag_existence = copy.deepcopy(servers247.check_tag_existence)
-update_tag = copy.deepcopy(servers247.update_tag)
-delete_tag = copy.deepcopy(servers247.delete_tag)
+# ****** Schemas unchanged in microversion 2.54 since microversion 2.48 ***
+get_server = copy.deepcopy(servers248.get_server)
+list_servers_detail = copy.deepcopy(servers248.list_servers_detail)
+update_server = copy.deepcopy(servers248.update_server)
+list_servers = copy.deepcopy(servers248.list_servers)
+show_server_diagnostics = copy.deepcopy(servers248.show_server_diagnostics)
+get_remote_consoles = copy.deepcopy(servers248.get_remote_consoles)
+list_tags = copy.deepcopy(servers248.list_tags)
+update_all_tags = copy.deepcopy(servers248.update_all_tags)
+delete_all_tags = copy.deepcopy(servers248.delete_all_tags)
+check_tag_existence = copy.deepcopy(servers248.check_tag_existence)
+update_tag = copy.deepcopy(servers248.update_tag)
+delete_tag = copy.deepcopy(servers248.delete_tag)
diff --git a/tempest/lib/api_schema/response/compute/v2_55/flavors.py b/tempest/lib/api_schema/response/compute/v2_55/flavors.py
index 823190a..554f43b 100644
--- a/tempest/lib/api_schema/response/compute/v2_55/flavors.py
+++ b/tempest/lib/api_schema/response/compute/v2_55/flavors.py
@@ -11,7 +11,9 @@
# 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.lib.api_schema.response.compute.v2_1 import flavors as flavorsv21
from tempest.lib.api_schema.response.compute.v2_1 import parameter_types
# Note(gmann): This is schema for microversion 2.55 which includes the
@@ -110,3 +112,9 @@
'required': ['flavor']
}
}
+
+# Note(zhufl): Below are the unchanged schema in this microversion. We need
+# to keep this schema in this file to have the generic way to select the
+# right schema based on self.schema_versions_info mapping in service client.
+# ****** Schemas unchanged since microversion 2.1 ***
+delete_flavor = copy.deepcopy(flavorsv21.delete_flavor)
diff --git a/tempest/lib/api_schema/response/compute/v2_57/quotas.py b/tempest/lib/api_schema/response/compute/v2_57/quotas.py
new file mode 100644
index 0000000..4664a1a
--- /dev/null
+++ b/tempest/lib/api_schema/response/compute/v2_57/quotas.py
@@ -0,0 +1,53 @@
+# Copyright 2018 ZTE 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.lib.api_schema.response.compute.v2_36 import quotas as quotasv236
+
+# Compute microversion 2.57:
+# remove attributes in quota_set:
+# 'injected_file_content_bytes',
+# 'injected_file_path_bytes',
+# 'injected_files'
+
+remove_item_list = ['injected_file_content_bytes', 'injected_file_path_bytes',
+ 'injected_files']
+
+update_quota_set = copy.deepcopy(quotasv236.update_quota_set)
+for item in remove_item_list:
+ update_quota_set['response_body']['properties']['quota_set'][
+ 'properties'].pop(item)
+ update_quota_set['response_body']['properties']['quota_set'][
+ 'required'].remove(item)
+
+get_quota_set = copy.deepcopy(quotasv236.get_quota_set)
+for item in remove_item_list:
+ get_quota_set['response_body']['properties']['quota_set'][
+ 'properties'].pop(item)
+ get_quota_set['response_body']['properties']['quota_set'][
+ 'required'].remove(item)
+
+get_quota_set_details = copy.deepcopy(quotasv236.get_quota_set_details)
+for item in remove_item_list:
+ get_quota_set_details['response_body']['properties']['quota_set'][
+ 'properties'].pop(item)
+ get_quota_set_details['response_body']['properties']['quota_set'][
+ 'required'].remove(item)
+
+# NOTE(zhufl): Below are the unchanged schema in this microversion. We need
+# to keep this schema in this file to have the generic way to select the
+# right schema based on self.schema_versions_info mapping in service client.
+# ****** Schemas unchanged since microversion 2.1 ***
+delete_quota = copy.deepcopy(quotasv236.delete_quota)
diff --git a/tempest/lib/api_schema/response/compute/v2_57/servers.py b/tempest/lib/api_schema/response/compute/v2_57/servers.py
index d7de5fd..0099a2b 100644
--- a/tempest/lib/api_schema/response/compute/v2_57/servers.py
+++ b/tempest/lib/api_schema/response/compute/v2_57/servers.py
@@ -50,8 +50,9 @@
get_server = copy.deepcopy(servers254.get_server)
list_servers_detail = copy.deepcopy(servers254.list_servers_detail)
update_server = copy.deepcopy(servers254.update_server)
-
-# ****** Schemas unchanged since microversion 2.26 ***
+list_servers = copy.deepcopy(servers254.list_servers)
+show_server_diagnostics = copy.deepcopy(servers254.show_server_diagnostics)
+get_remote_consoles = copy.deepcopy(servers254.get_remote_consoles)
list_tags = copy.deepcopy(servers254.list_tags)
update_all_tags = copy.deepcopy(servers254.update_all_tags)
delete_all_tags = copy.deepcopy(servers254.delete_all_tags)
diff --git a/tempest/lib/api_schema/response/compute/v2_61/flavors.py b/tempest/lib/api_schema/response/compute/v2_61/flavors.py
index 381fb64..5119466 100644
--- a/tempest/lib/api_schema/response/compute/v2_61/flavors.py
+++ b/tempest/lib/api_schema/response/compute/v2_61/flavors.py
@@ -99,4 +99,8 @@
# Note(gmann): Below are the unchanged schema in this microversion. We need
# to keep this schema in this file to have the generic way to select the
# right schema based on self.schema_versions_info mapping in service client.
+# ****** Schemas unchanged since microversion 2.55 ***
list_flavors = copy.deepcopy(flavorsv255.list_flavors)
+
+# ****** Schemas unchanged since microversion 2.1 ***
+delete_flavor = copy.deepcopy(flavorsv255.delete_flavor)
diff --git a/tempest/lib/api_schema/response/compute/v2_63/servers.py b/tempest/lib/api_schema/response/compute/v2_63/servers.py
index 6a20890..3c3d41c 100644
--- a/tempest/lib/api_schema/response/compute/v2_63/servers.py
+++ b/tempest/lib/api_schema/response/compute/v2_63/servers.py
@@ -12,8 +12,6 @@
import copy
-from tempest.lib.api_schema.response.compute.v2_26 import servers as servers226
-from tempest.lib.api_schema.response.compute.v2_54 import servers as servers254
from tempest.lib.api_schema.response.compute.v2_57 import servers as servers257
# Nova microversion 2.63 adds 'trusted_image_certificates' (a list of
@@ -30,10 +28,8 @@
'minLength': 1
}
}
-# list response schema wasn't changed for v2.63 so use v2.26
-list_servers = copy.deepcopy(servers226.list_servers)
-list_servers_detail = copy.deepcopy(servers254.list_servers_detail)
+list_servers_detail = copy.deepcopy(servers257.list_servers_detail)
list_servers_detail['response_body']['properties']['servers']['items'][
'properties'].update({'trusted_image_certificates': trusted_certs})
list_servers_detail['response_body']['properties']['servers']['items'][
@@ -52,13 +48,13 @@
rebuild_server_with_admin_pass['response_body']['properties']['server'][
'required'].append('trusted_image_certificates')
-update_server = copy.deepcopy(servers254.update_server)
+update_server = copy.deepcopy(servers257.update_server)
update_server['response_body']['properties']['server'][
'properties'].update({'trusted_image_certificates': trusted_certs})
update_server['response_body']['properties']['server'][
'required'].append('trusted_image_certificates')
-get_server = copy.deepcopy(servers254.get_server)
+get_server = copy.deepcopy(servers257.get_server)
get_server['response_body']['properties']['server'][
'properties'].update({'trusted_image_certificates': trusted_certs})
get_server['response_body']['properties']['server'][
@@ -67,7 +63,10 @@
# NOTE(zhufl): Below are the unchanged schema in this microversion. We need
# to keep this schema in this file to have the generic way to select the
# right schema based on self.schema_versions_info mapping in service client.
-# ****** Schemas unchanged since microversion 2.26 ***
+# ****** Schemas unchanged since microversion 2.57 ***
+list_servers = copy.deepcopy(servers257.list_servers)
+show_server_diagnostics = copy.deepcopy(servers257.show_server_diagnostics)
+get_remote_consoles = copy.deepcopy(servers257.get_remote_consoles)
list_tags = copy.deepcopy(servers257.list_tags)
update_all_tags = copy.deepcopy(servers257.update_all_tags)
delete_all_tags = copy.deepcopy(servers257.delete_all_tags)
diff --git a/tempest/lib/api_schema/response/compute/v2_8/__init__.py b/tempest/lib/api_schema/response/compute/v2_8/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/lib/api_schema/response/compute/v2_8/__init__.py
diff --git a/tempest/lib/api_schema/response/compute/v2_8/servers.py b/tempest/lib/api_schema/response/compute/v2_8/servers.py
new file mode 100644
index 0000000..df7847f
--- /dev/null
+++ b/tempest/lib/api_schema/response/compute/v2_8/servers.py
@@ -0,0 +1,37 @@
+# Copyright 2018 AT&T 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.lib.api_schema.response.compute.v2_6 import servers
+
+# 2.8: Add 'mks' protocol and 'webmks' type for remote consoles.
+get_remote_consoles = copy.deepcopy(servers.get_remote_consoles)
+get_remote_consoles['response_body']['properties']['remote_console'][
+ 'properties']['protocol']['enum'].append('mks')
+get_remote_consoles['response_body']['properties']['remote_console'][
+ 'properties']['type']['enum'].append('webmks')
+
+# NOTE: Below are the unchanged schema in this microversion. We need
+# to keep this schema in this file to have the generic way to select the
+# right schema based on self.schema_versions_info mapping in service client.
+# ****** Schemas unchanged since microversion 2.6 ******
+list_servers = copy.deepcopy(servers.list_servers)
+get_server = copy.deepcopy(servers.get_server)
+list_servers_detail = copy.deepcopy(servers.list_servers_detail)
+update_server = copy.deepcopy(servers.update_server)
+rebuild_server = copy.deepcopy(servers.rebuild_server)
+rebuild_server_with_admin_pass = copy.deepcopy(
+ servers.rebuild_server_with_admin_pass)
+show_server_diagnostics = copy.deepcopy(servers.show_server_diagnostics)
diff --git a/tempest/lib/api_schema/response/compute/v2_9/servers.py b/tempest/lib/api_schema/response/compute/v2_9/servers.py
index f412839..55f8e75 100644
--- a/tempest/lib/api_schema/response/compute/v2_9/servers.py
+++ b/tempest/lib/api_schema/response/compute/v2_9/servers.py
@@ -14,16 +14,7 @@
import copy
-from tempest.lib.api_schema.response.compute.v2_1 import servers as servers_21
-from tempest.lib.api_schema.response.compute.v2_6 import servers
-
-# NOTE: Below are the unchanged schema in this microversion. We need
-# to keep this schema in this file to have the generic way to select the
-# right schema based on self.schema_versions_info mapping in service client.
-# ****** Schemas unchanged since microversion 2.6 ******
-list_servers = copy.deepcopy(servers.list_servers)
-show_server_diagnostics = copy.deepcopy(servers.show_server_diagnostics)
-get_remote_consoles = copy.deepcopy(servers.get_remote_consoles)
+from tempest.lib.api_schema.response.compute.v2_8 import servers
get_server = copy.deepcopy(servers.get_server)
get_server['response_body']['properties']['server'][
@@ -37,21 +28,29 @@
list_servers_detail['response_body']['properties']['servers']['items'][
'required'].append('locked')
-update_server = copy.deepcopy(servers_21.update_server)
+update_server = copy.deepcopy(servers.update_server)
update_server['response_body']['properties']['server'][
'properties'].update({'locked': {'type': 'boolean'}})
update_server['response_body']['properties']['server'][
'required'].append('locked')
-rebuild_server = copy.deepcopy(servers_21.rebuild_server)
+rebuild_server = copy.deepcopy(servers.rebuild_server)
rebuild_server['response_body']['properties']['server'][
'properties'].update({'locked': {'type': 'boolean'}})
rebuild_server['response_body']['properties']['server'][
'required'].append('locked')
rebuild_server_with_admin_pass = copy.deepcopy(
- servers_21.rebuild_server_with_admin_pass)
+ servers.rebuild_server_with_admin_pass)
rebuild_server_with_admin_pass['response_body']['properties']['server'][
'properties'].update({'locked': {'type': 'boolean'}})
rebuild_server_with_admin_pass['response_body']['properties']['server'][
'required'].append('locked')
+
+# NOTE: Below are the unchanged schema in this microversion. We need
+# to keep this schema in this file to have the generic way to select the
+# right schema based on self.schema_versions_info mapping in service client.
+# ****** Schemas unchanged since microversion 2.8 ******
+list_servers = copy.deepcopy(servers.list_servers)
+show_server_diagnostics = copy.deepcopy(servers.show_server_diagnostics)
+get_remote_consoles = copy.deepcopy(servers.get_remote_consoles)
diff --git a/tempest/lib/services/compute/aggregates_client.py b/tempest/lib/services/compute/aggregates_client.py
index 713d7a3..57f5e4e 100644
--- a/tempest/lib/services/compute/aggregates_client.py
+++ b/tempest/lib/services/compute/aggregates_client.py
@@ -15,7 +15,10 @@
from oslo_serialization import jsonutils as json
-from tempest.lib.api_schema.response.compute.v2_1 import aggregates as schema
+from tempest.lib.api_schema.response.compute.v2_1 \
+ import aggregates as schema
+from tempest.lib.api_schema.response.compute.v2_41 \
+ import aggregates as schemav241
from tempest.lib.common import rest_client
from tempest.lib import exceptions as lib_exc
from tempest.lib.services.compute import base_compute_client
@@ -23,10 +26,15 @@
class AggregatesClient(base_compute_client.BaseComputeClient):
+ schema_versions_info = [
+ {'min': None, 'max': '2.40', 'schema': schema},
+ {'min': '2.41', 'max': None, 'schema': schemav241}]
+
def list_aggregates(self):
"""Get aggregate list."""
resp, body = self.get("os-aggregates")
body = json.loads(body)
+ schema = self.get_schema(self.schema_versions_info)
self.validate_response(schema.list_aggregates, resp, body)
return rest_client.ResponseBody(resp, body)
@@ -34,6 +42,7 @@
"""Get details of the given aggregate."""
resp, body = self.get("os-aggregates/%s" % aggregate_id)
body = json.loads(body)
+ schema = self.get_schema(self.schema_versions_info)
self.validate_response(schema.get_aggregate, resp, body)
return rest_client.ResponseBody(resp, body)
@@ -48,6 +57,7 @@
resp, body = self.post('os-aggregates', post_body)
body = json.loads(body)
+ schema = self.get_schema(self.schema_versions_info)
self.validate_response(schema.create_aggregate, resp, body)
return rest_client.ResponseBody(resp, body)
@@ -62,12 +72,14 @@
resp, body = self.put('os-aggregates/%s' % aggregate_id, put_body)
body = json.loads(body)
+ schema = self.get_schema(self.schema_versions_info)
self.validate_response(schema.update_aggregate, resp, body)
return rest_client.ResponseBody(resp, body)
def delete_aggregate(self, aggregate_id):
"""Delete the given aggregate."""
resp, body = self.delete("os-aggregates/%s" % aggregate_id)
+ schema = self.get_schema(self.schema_versions_info)
self.validate_response(schema.delete_aggregate, resp, body)
return rest_client.ResponseBody(resp, body)
@@ -94,6 +106,7 @@
resp, body = self.post('os-aggregates/%s/action' % aggregate_id,
post_body)
body = json.loads(body)
+ schema = self.get_schema(self.schema_versions_info)
self.validate_response(schema.aggregate_add_remove_host, resp, body)
return rest_client.ResponseBody(resp, body)
@@ -108,6 +121,7 @@
resp, body = self.post('os-aggregates/%s/action' % aggregate_id,
post_body)
body = json.loads(body)
+ schema = self.get_schema(self.schema_versions_info)
self.validate_response(schema.aggregate_add_remove_host, resp, body)
return rest_client.ResponseBody(resp, body)
@@ -122,5 +136,6 @@
resp, body = self.post('os-aggregates/%s/action' % aggregate_id,
post_body)
body = json.loads(body)
+ schema = self.get_schema(self.schema_versions_info)
self.validate_response(schema.aggregate_set_metadata, resp, body)
return rest_client.ResponseBody(resp, body)
diff --git a/tempest/lib/services/compute/hypervisor_client.py b/tempest/lib/services/compute/hypervisor_client.py
index 23c304e..1cbfcc3 100644
--- a/tempest/lib/services/compute/hypervisor_client.py
+++ b/tempest/lib/services/compute/hypervisor_client.py
@@ -15,16 +15,24 @@
from oslo_serialization import jsonutils as json
-from tempest.lib.api_schema.response.compute.v2_1 import hypervisors as schema
+from tempest.lib.api_schema.response.compute.v2_1 \
+ import hypervisors as schemav21
+from tempest.lib.api_schema.response.compute.v2_28 \
+ import hypervisors as schemav228
from tempest.lib.common import rest_client
from tempest.lib.services.compute import base_compute_client
class HypervisorClient(base_compute_client.BaseComputeClient):
+ schema_versions_info = [
+ {'min': None, 'max': '2.27', 'schema': schemav21},
+ {'min': '2.28', 'max': None, 'schema': schemav228}]
+
def list_hypervisors(self, detail=False):
"""List hypervisors information."""
url = 'os-hypervisors'
+ schema = self.get_schema(self.schema_versions_info)
_schema = schema.list_search_hypervisors
if detail:
url += '/detail'
@@ -39,6 +47,7 @@
"""Display the details of the specified hypervisor."""
resp, body = self.get('os-hypervisors/%s' % hypervisor_id)
body = json.loads(body)
+ schema = self.get_schema(self.schema_versions_info)
self.validate_response(schema.get_hypervisor, resp, body)
return rest_client.ResponseBody(resp, body)
@@ -46,6 +55,7 @@
"""List instances belonging to the specified hypervisor."""
resp, body = self.get('os-hypervisors/%s/servers' % hypervisor_name)
body = json.loads(body)
+ schema = self.get_schema(self.schema_versions_info)
self.validate_response(schema.get_hypervisors_servers, resp, body)
return rest_client.ResponseBody(resp, body)
@@ -53,6 +63,7 @@
"""Get hypervisor statistics over all compute nodes."""
resp, body = self.get('os-hypervisors/statistics')
body = json.loads(body)
+ schema = self.get_schema(self.schema_versions_info)
self.validate_response(schema.get_hypervisor_statistics, resp, body)
return rest_client.ResponseBody(resp, body)
@@ -60,6 +71,7 @@
"""Display the uptime of the specified hypervisor."""
resp, body = self.get('os-hypervisors/%s/uptime' % hypervisor_id)
body = json.loads(body)
+ schema = self.get_schema(self.schema_versions_info)
self.validate_response(schema.get_hypervisor_uptime, resp, body)
return rest_client.ResponseBody(resp, body)
@@ -69,5 +81,6 @@
"""Search specified hypervisor."""
resp, body = self.get('os-hypervisors/%s/search' % hypervisor_name)
body = json.loads(body)
+ schema = self.get_schema(self.schema_versions_info)
self.validate_response(schema.list_search_hypervisors, resp, body)
return rest_client.ResponseBody(resp, body)
diff --git a/tempest/lib/services/compute/quotas_client.py b/tempest/lib/services/compute/quotas_client.py
index 12df895..99c8d0f 100644
--- a/tempest/lib/services/compute/quotas_client.py
+++ b/tempest/lib/services/compute/quotas_client.py
@@ -17,12 +17,19 @@
from six.moves.urllib import parse as urllib
from tempest.lib.api_schema.response.compute.v2_1 import quotas as schema
+from tempest.lib.api_schema.response.compute.v2_36 import quotas as schemav236
+from tempest.lib.api_schema.response.compute.v2_57 import quotas as schemav257
from tempest.lib.common import rest_client
from tempest.lib.services.compute import base_compute_client
class QuotasClient(base_compute_client.BaseComputeClient):
+ schema_versions_info = [
+ {'min': None, 'max': '2.35', 'schema': schema},
+ {'min': '2.36', 'max': '2.56', 'schema': schemav236},
+ {'min': '2.57', 'max': None, 'schema': schemav257}]
+
def show_quota_set(self, tenant_id, user_id=None, detail=False):
"""List the quota set for a tenant.
@@ -42,6 +49,7 @@
url += '?%s' % urllib.urlencode(params)
resp, body = self.get(url)
body = json.loads(body)
+ schema = self.get_schema(self.schema_versions_info)
if detail:
self.validate_response(schema.get_quota_set_details, resp, body)
else:
@@ -57,6 +65,7 @@
url = 'os-quota-sets/%s/defaults' % tenant_id
resp, body = self.get(url)
body = json.loads(body)
+ schema = self.get_schema(self.schema_versions_info)
self.validate_response(schema.get_quota_set, resp, body)
return rest_client.ResponseBody(resp, body)
@@ -78,6 +87,7 @@
post_body)
body = json.loads(body)
+ schema = self.get_schema(self.schema_versions_info)
self.validate_response(schema.update_quota_set, resp, body)
return rest_client.ResponseBody(resp, body)
@@ -87,5 +97,6 @@
https://developer.openstack.org/api-ref/compute/#revert-quotas-to-defaults
"""
resp, body = self.delete('os-quota-sets/%s' % tenant_id)
+ schema = self.get_schema(self.schema_versions_info)
self.validate_response(schema.delete_quota, resp, body)
return rest_client.ResponseBody(resp, body)
diff --git a/tempest/lib/services/compute/servers_client.py b/tempest/lib/services/compute/servers_client.py
index 0314356..9eed4b3 100644
--- a/tempest/lib/services/compute/servers_client.py
+++ b/tempest/lib/services/compute/servers_client.py
@@ -33,6 +33,7 @@
from tempest.lib.api_schema.response.compute.v2_57 import servers as schemav257
from tempest.lib.api_schema.response.compute.v2_6 import servers as schemav26
from tempest.lib.api_schema.response.compute.v2_63 import servers as schemav263
+from tempest.lib.api_schema.response.compute.v2_8 import servers as schemav28
from tempest.lib.api_schema.response.compute.v2_9 import servers as schemav29
from tempest.lib.common import rest_client
from tempest.lib.services.compute import base_compute_client
@@ -44,7 +45,8 @@
schema_versions_info = [
{'min': None, 'max': '2.2', 'schema': schema},
{'min': '2.3', 'max': '2.5', 'schema': schemav23},
- {'min': '2.6', 'max': '2.8', 'schema': schemav26},
+ {'min': '2.6', 'max': '2.7', 'schema': schemav26},
+ {'min': '2.8', 'max': '2.8', 'schema': schemav28},
{'min': '2.9', 'max': '2.15', 'schema': schemav29},
{'min': '2.16', 'max': '2.18', 'schema': schemav216},
{'min': '2.19', 'max': '2.25', 'schema': schemav219},
diff --git a/tempest/lib/services/volume/v3/backups_client.py b/tempest/lib/services/volume/v3/backups_client.py
index 10538b0..f2d2d21 100644
--- a/tempest/lib/services/volume/v3/backups_client.py
+++ b/tempest/lib/services/volume/v3/backups_client.py
@@ -23,7 +23,6 @@
class BackupsClient(base_client.BaseClient):
"""Volume V3 Backups client"""
- api_version = "v3"
def create_backup(self, **kwargs):
"""Creates a backup of volume.
diff --git a/tempest/lib/services/volume/v3/base_client.py b/tempest/lib/services/volume/v3/base_client.py
index e78380b..617da2e 100644
--- a/tempest/lib/services/volume/v3/base_client.py
+++ b/tempest/lib/services/volume/v3/base_client.py
@@ -20,4 +20,3 @@
BaseClient = moves.moved_class(base_client.BaseClient, 'BaseClient', __name__,
version="Pike", removal_version='?')
-BaseClient.api_version = 'v3'
diff --git a/tempest/lib/services/volume/v3/group_snapshots_client.py b/tempest/lib/services/volume/v3/group_snapshots_client.py
index 6e53e3e..16412d3 100644
--- a/tempest/lib/services/volume/v3/group_snapshots_client.py
+++ b/tempest/lib/services/volume/v3/group_snapshots_client.py
@@ -23,7 +23,6 @@
class GroupSnapshotsClient(base_client.BaseClient):
"""Client class to send CRUD Volume Group Snapshot API requests"""
- api_version = 'v3'
def create_group_snapshot(self, **kwargs):
"""Creates a group snapshot.
diff --git a/tempest/lib/services/volume/v3/group_types_client.py b/tempest/lib/services/volume/v3/group_types_client.py
index ecbcba1..1ccb9f8 100644
--- a/tempest/lib/services/volume/v3/group_types_client.py
+++ b/tempest/lib/services/volume/v3/group_types_client.py
@@ -22,7 +22,6 @@
class GroupTypesClient(base_client.BaseClient):
"""Client class to send CRUD Volume V3 Group Types API requests"""
- api_version = 'v3'
@property
def resource_type(self):
diff --git a/tempest/lib/services/volume/v3/groups_client.py b/tempest/lib/services/volume/v3/groups_client.py
index e2e477d..3cf1e6a 100644
--- a/tempest/lib/services/volume/v3/groups_client.py
+++ b/tempest/lib/services/volume/v3/groups_client.py
@@ -23,7 +23,6 @@
class GroupsClient(base_client.BaseClient):
"""Client class to send CRUD Volume Group API requests"""
- api_version = 'v3'
def create_group(self, **kwargs):
"""Creates a group.
diff --git a/tempest/lib/services/volume/v3/messages_client.py b/tempest/lib/services/volume/v3/messages_client.py
index 0127271..47538cd 100644
--- a/tempest/lib/services/volume/v3/messages_client.py
+++ b/tempest/lib/services/volume/v3/messages_client.py
@@ -22,7 +22,6 @@
class MessagesClient(base_client.BaseClient):
"""Client class to send user messages API requests."""
- api_version = 'v3'
def show_message(self, message_id):
"""Show details for a single message."""
diff --git a/tempest/lib/services/volume/v3/snapshots_client.py b/tempest/lib/services/volume/v3/snapshots_client.py
index 08e6c94..0cb5e54 100644
--- a/tempest/lib/services/volume/v3/snapshots_client.py
+++ b/tempest/lib/services/volume/v3/snapshots_client.py
@@ -22,7 +22,6 @@
class SnapshotsClient(rest_client.RestClient):
"""Client class to send CRUD Volume Snapshot V3 API requests."""
- api_version = "v3"
create_resp = 202
def list_snapshots(self, detail=False, **params):
diff --git a/tempest/lib/services/volume/v3/versions_client.py b/tempest/lib/services/volume/v3/versions_client.py
index 5702f95..57629bd 100644
--- a/tempest/lib/services/volume/v3/versions_client.py
+++ b/tempest/lib/services/volume/v3/versions_client.py
@@ -22,7 +22,6 @@
class VersionsClient(base_client.BaseClient):
- api_version = 'v3'
def list_versions(self):
"""List API versions
diff --git a/tempest/lib/services/volume/v3/volumes_client.py b/tempest/lib/services/volume/v3/volumes_client.py
index a1185c4..11c5767 100644
--- a/tempest/lib/services/volume/v3/volumes_client.py
+++ b/tempest/lib/services/volume/v3/volumes_client.py
@@ -24,7 +24,6 @@
class VolumesClient(base_client.BaseClient):
"""Client class to send CRUD Volume V3 API requests"""
- api_version = "v3"
def _prepare_params(self, params):
"""Prepares params for use in get or _ext_get methods.
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index be52eef..cdc30b9 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -301,7 +301,7 @@
def create_volume_type(self, client=None, name=None, backend_name=None):
if not client:
- client = self.os_admin.volume_types_v2_client
+ client = self.os_admin.volume_types_client_latest
randomized_name = name or data_utils.rand_name(
'volume-type-' + self.__class__.__name__)
@@ -1208,9 +1208,9 @@
@classmethod
def setup_clients(cls):
super(EncryptionScenarioTest, cls).setup_clients()
- cls.admin_volume_types_client = cls.os_admin.volume_types_v2_client
+ cls.admin_volume_types_client = cls.os_admin.volume_types_client_latest
cls.admin_encryption_types_client =\
- cls.os_admin.encryption_types_v2_client
+ cls.os_admin.encryption_types_client_latest
def create_encryption_type(self, client=None, type_id=None, provider=None,
key_size=None, cipher=None,
diff --git a/tempest/scenario/test_volume_migrate_attached.py b/tempest/scenario/test_volume_migrate_attached.py
index 4624249..c54bb38 100644
--- a/tempest/scenario/test_volume_migrate_attached.py
+++ b/tempest/scenario/test_volume_migrate_attached.py
@@ -40,7 +40,7 @@
@classmethod
def setup_clients(cls):
super(TestVolumeMigrateRetypeAttached, cls).setup_clients()
- cls.admin_volumes_client = cls.os_admin.volumes_v2_client
+ cls.admin_volumes_client = cls.os_admin.volumes_client_latest
@classmethod
def skip_checks(cls):
diff --git a/tempest/tests/cmd/test_run.py b/tempest/tests/cmd/test_run.py
index 6cc356e..f55df30 100644
--- a/tempest/tests/cmd/test_run.py
+++ b/tempest/tests/cmd/test_run.py
@@ -40,24 +40,18 @@
args = mock.Mock(spec=argparse.Namespace)
setattr(args, 'smoke', False)
setattr(args, 'regex', '')
- setattr(args, 'whitelist_file', None)
- setattr(args, 'blacklist_file', None)
self.assertIsNone(None, self.run_cmd._build_regex(args))
def test__build_regex_smoke(self):
args = mock.Mock(spec=argparse.Namespace)
setattr(args, "smoke", True)
setattr(args, 'regex', '')
- setattr(args, 'whitelist_file', None)
- setattr(args, 'blacklist_file', None)
self.assertEqual(['smoke'], self.run_cmd._build_regex(args))
def test__build_regex_regex(self):
args = mock.Mock(spec=argparse.Namespace)
setattr(args, 'smoke', False)
setattr(args, "regex", 'i_am_a_fun_little_regex')
- setattr(args, 'whitelist_file', None)
- setattr(args, 'blacklist_file', None)
self.assertEqual(['i_am_a_fun_little_regex'],
self.run_cmd._build_regex(args))
diff --git a/tempest/tests/cmd/test_verify_tempest_config.py b/tempest/tests/cmd/test_verify_tempest_config.py
index 8641b63..32d6224 100644
--- a/tempest/tests/cmd/test_verify_tempest_config.py
+++ b/tempest/tests/cmd/test_verify_tempest_config.py
@@ -225,7 +225,7 @@
# This test verifies that wrong config api_v2 = True is detected
class FakeClient(object):
def get_versions(self):
- return (None, ['v1.0'])
+ return (None, ['v1.1'])
fake_os = mock.MagicMock()
fake_module = mock.MagicMock()
diff --git a/test-requirements.txt b/test-requirements.txt
index e33f207..196387c 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -1,7 +1,7 @@
# The order of packages is significant, because pip processes them in the order
# of appearance. Changing the order has an impact on the overall integration
# process, which may cause wedges in the gate later.
-hacking!=0.13.0,<0.14,>=0.12.0 # Apache-2.0
+hacking>=1.1.0,<1.2.0 # Apache-2.0
mock>=2.0.0 # BSD
coverage!=4.4,>=4.0 # Apache-2.0
oslotest>=3.2.0 # Apache-2.0
diff --git a/tools/generate-tempest-plugins-list.sh b/tools/generate-tempest-plugins-list.sh
index 20c99b2..b27b23a 100755
--- a/tools/generate-tempest-plugins-list.sh
+++ b/tools/generate-tempest-plugins-list.sh
@@ -49,13 +49,37 @@
sorted_plugins=$(python tools/generate-tempest-plugins-list.py)
-for k in ${sorted_plugins}; do
- project=${k:0:28}
- giturl="git://git.openstack.org/openstack/${k:0:26}"
- printf "|%-28s|%-73s|\n" "${project}" "${giturl}"
- printf "+----------------------------+-------------------------------------------------------------------------+\n"
+name_col_len=$(echo "${sorted_plugins}" | wc -L)
+name_col_len=$(( name_col_len + 20 ))
+
+# Print the title underline for a RST table.
+function title_underline {
+ printf "== "
+ local len=$1
+ while [[ $len -gt 0 ]]; do
+ printf "="
+ len=$(( len - 1))
+ done
+ printf " ===\n"
+}
+
+printf "\n\n"
+title_underline ${name_col_len}
+printf "%-3s %-${name_col_len}s %s\n" "SR" "Plugin Name" "URL"
+title_underline ${name_col_len}
+
+i=0
+for plugin in ${sorted_plugins}; do
+ i=$((i+1))
+ giturl="git://git.openstack.org/openstack/${plugin}"
+ gitlink="https://git.openstack.org/cgit/openstack/${plugin}"
+ printf "%-3s %-${name_col_len}s %s\n" "$i" "${plugin}" "\`${giturl} <${gitlink}>\`__"
done
+title_underline ${name_col_len}
+
+printf "\n\n"
+
if [[ -r doc/source/data/tempest-plugins-registry.footer ]]; then
cat doc/source/data/tempest-plugins-registry.footer
fi
diff --git a/tox.ini b/tox.ini
index befa991..d61a7fe 100644
--- a/tox.ini
+++ b/tox.ini
@@ -186,7 +186,8 @@
# E125 is a won't fix until https://github.com/jcrocholl/pep8/issues/126 is resolved. For further detail see https://review.openstack.org/#/c/36788/
# E123 skipped because it is ignored by default in the default pep8
# E129 skipped because it is too limiting when combined with other rules
-ignore = E125,E123,E129
+# W504 skipped because it is overeager and unnecessary
+ignore = E125,E123,E129,W504
show-source = True
exclude = .git,.venv,.tox,dist,doc,*egg,build
enable-extensions = H106,H203,H904