Merge "Add compare header version function to tempest.lib"
diff --git a/doc/source/microversion_testing.rst b/doc/source/microversion_testing.rst
index 573b7d4..307eb07 100644
--- a/doc/source/microversion_testing.rst
+++ b/doc/source/microversion_testing.rst
@@ -338,4 +338,4 @@
* `3.3`_
- .. _3.3: https://docs.openstack.org/cinder/ocata/devref/api_microversion_history.html#id4
+ .. _3.3: https://docs.openstack.org/cinder/latest/contributor/api_microversion_history.html#id4
diff --git a/releasenotes/notes/identity-tests-domain-drivers-76235f6672221e45.yaml b/releasenotes/notes/identity-tests-domain-drivers-76235f6672221e45.yaml
new file mode 100644
index 0000000..7ed3081
--- /dev/null
+++ b/releasenotes/notes/identity-tests-domain-drivers-76235f6672221e45.yaml
@@ -0,0 +1,7 @@
+---
+features:
+ - |
+ A new boolean config option ``domain_specific_drivers``
+ is added to the section ``identity-feature-enabled``.
+ This option must be enabled when testing an environment that
+ is configured to use domain-specific identity drivers.
diff --git a/releasenotes/source/index.rst b/releasenotes/source/index.rst
index db01da0..df1de46 100644
--- a/releasenotes/source/index.rst
+++ b/releasenotes/source/index.rst
@@ -6,6 +6,7 @@
:maxdepth: 1
unreleased
+ v17.0.0
v16.1.0
v16.0.0
v15.0.0
diff --git a/releasenotes/source/v17.0.0.rst b/releasenotes/source/v17.0.0.rst
new file mode 100644
index 0000000..3f50f11
--- /dev/null
+++ b/releasenotes/source/v17.0.0.rst
@@ -0,0 +1,6 @@
+=====================
+v17.0.0 Release Notes
+=====================
+
+.. release-notes:: 17.0.0 Release Notes
+ :version: 17.0.0
diff --git a/tempest/api/identity/admin/v3/test_groups.py b/tempest/api/identity/admin/v3/test_groups.py
index 4bc987f..17db3ea 100644
--- a/tempest/api/identity/admin/v3/test_groups.py
+++ b/tempest/api/identity/admin/v3/test_groups.py
@@ -14,9 +14,12 @@
# under the License.
from tempest.api.identity import base
+from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
+CONF = config.CONF
+
class GroupsV3TestJSON(base.BaseIdentityV3AdminTest):
@@ -130,7 +133,14 @@
self.addCleanup(self.groups_client.delete_group, group['id'])
group_ids.append(group['id'])
# List and Verify Groups
- body = self.groups_client.list_groups()['groups']
+ # When domain specific drivers are enabled the operations
+ # of listing all users and listing all groups are not supported,
+ # they need a domain filter to be specified
+ if CONF.identity_feature_enabled.domain_specific_drivers:
+ body = self.groups_client.list_groups(
+ domain_id=self.domain['id'])['groups']
+ else:
+ body = self.groups_client.list_groups()['groups']
for g in body:
fetched_ids.append(g['id'])
missing_groups = [g for g in group_ids if g not in fetched_ids]
diff --git a/tempest/api/identity/admin/v3/test_list_users.py b/tempest/api/identity/admin/v3/test_list_users.py
index 47a3580..506c729 100644
--- a/tempest/api/identity/admin/v3/test_list_users.py
+++ b/tempest/api/identity/admin/v3/test_list_users.py
@@ -14,9 +14,12 @@
# under the License.
from tempest.api.identity import base
+from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
+CONF = config.CONF
+
class UsersV3TestJSON(base.BaseIdentityV3AdminTest):
@@ -82,6 +85,11 @@
def test_list_users_with_name(self):
# List users with name
params = {'name': self.domain_enabled_user['name']}
+ # When domain specific drivers are enabled the operations
+ # of listing all users and listing all groups are not supported,
+ # they need a domain filter to be specified
+ if CONF.identity_feature_enabled.domain_specific_drivers:
+ params['domain_id'] = self.domain_enabled_user['domain_id']
self._list_users_with_params(params, 'name',
self.domain_enabled_user,
self.non_domain_enabled_user)
@@ -89,7 +97,18 @@
@decorators.idempotent_id('b30d4651-a2ea-4666-8551-0c0e49692635')
def test_list_users(self):
# List users
- body = self.users_client.list_users()['users']
+ # When domain specific drivers are enabled the operations
+ # of listing all users and listing all groups are not supported,
+ # they need a domain filter to be specified
+ if CONF.identity_feature_enabled.domain_specific_drivers:
+ body_enabled_user = self.users_client.list_users(
+ domain_id=self.domain_enabled_user['domain_id'])['users']
+ body_non_enabled_user = self.users_client.list_users(
+ domain_id=self.non_domain_enabled_user['domain_id'])['users']
+ body = (body_enabled_user + body_non_enabled_user)
+ else:
+ body = self.users_client.list_users()['users']
+
fetched_ids = [u['id'] for u in body]
missing_users = [u['id'] for u in self.users
if u['id'] not in fetched_ids]
diff --git a/tempest/api/volume/admin/test_snapshots_actions.py b/tempest/api/volume/admin/test_snapshots_actions.py
index 471f39a..41849bc 100644
--- a/tempest/api/volume/admin/test_snapshots_actions.py
+++ b/tempest/api/volume/admin/test_snapshots_actions.py
@@ -14,6 +14,7 @@
# under the License.
from tempest.api.volume import base
+from tempest.common import waiters
from tempest import config
from tempest.lib import decorators
@@ -43,6 +44,8 @@
snapshot_id = self.snapshot['id']
self.admin_snapshots_client.reset_snapshot_status(snapshot_id,
status)
+ waiters.wait_for_volume_resource_status(self.snapshots_client,
+ snapshot_id, status)
super(SnapshotsActionsTest, self).tearDown()
def _create_reset_and_force_delete_temp_snapshot(self, status=None):
@@ -50,10 +53,11 @@
# and force delete temp snapshot
temp_snapshot = self.create_snapshot(volume_id=self.volume['id'])
if status:
- self.admin_snapshots_client.\
- reset_snapshot_status(temp_snapshot['id'], status)
- self.admin_snapshots_client.\
- force_delete_snapshot(temp_snapshot['id'])
+ self.admin_snapshots_client.reset_snapshot_status(
+ temp_snapshot['id'], status)
+ waiters.wait_for_volume_resource_status(
+ self.snapshots_client, temp_snapshot['id'], status)
+ self.admin_snapshots_client.force_delete_snapshot(temp_snapshot['id'])
self.snapshots_client.wait_for_resource_deletion(temp_snapshot['id'])
def _get_progress_alias(self):
@@ -63,18 +67,19 @@
def test_reset_snapshot_status(self):
# Reset snapshot status to creating
status = 'creating'
- self.admin_snapshots_client.\
- reset_snapshot_status(self.snapshot['id'], status)
- snapshot_get = self.admin_snapshots_client.show_snapshot(
- self.snapshot['id'])['snapshot']
- self.assertEqual(status, snapshot_get['status'])
+ self.admin_snapshots_client.reset_snapshot_status(
+ self.snapshot['id'], status)
+ waiters.wait_for_volume_resource_status(self.snapshots_client,
+ self.snapshot['id'], status)
@decorators.idempotent_id('41288afd-d463-485e-8f6e-4eea159413eb')
def test_update_snapshot_status(self):
# Reset snapshot status to creating
status = 'creating'
- self.admin_snapshots_client.\
- reset_snapshot_status(self.snapshot['id'], status)
+ self.admin_snapshots_client.reset_snapshot_status(
+ self.snapshot['id'], status)
+ waiters.wait_for_volume_resource_status(self.snapshots_client,
+ self.snapshot['id'], status)
# Update snapshot status to error
progress = '80%'
diff --git a/tempest/api/volume/admin/test_volume_hosts.py b/tempest/api/volume/admin/test_volume_hosts.py
index e4ec442..ce0cbd2 100644
--- a/tempest/api/volume/admin/test_volume_hosts.py
+++ b/tempest/api/volume/admin/test_volume_hosts.py
@@ -13,8 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-import random
-
from tempest.api.volume import base
from tempest.lib import decorators
@@ -42,20 +40,25 @@
"The count of volume hosts is < 2, "
"response of list hosts is: %s" % hosts)
- # Note(jeremyZ): Host in volume is always presented in two formats:
- # <host-name> or <host-name>@<driver-name>. Since Mitaka is EOL,
- # both formats can be chosen for test.
- host_names = [host['host_name'] for host in hosts]
- self.assertNotEmpty(host_names, "No available volume host is found, "
- "all hosts that found are: %s" % hosts)
+ # Note(jeremyZ): The show host API is to show volume usage info on the
+ # specified cinder-volume host. If the host does not run cinder-volume
+ # service, or the cinder-volume service is disabled on the host, the
+ # show host API should fail (return code: 404). The cinder-volume host
+ # is presented in format: <host-name>@driver-name.
+ c_vol_hosts = [host['host_name'] for host in hosts
+ if (host['service'] == 'cinder-volume'
+ and host['service-state'] == 'enabled')]
+ self.assertNotEmpty(c_vol_hosts,
+ "No available cinder-volume host is found, "
+ "all hosts that found are: %s" % hosts)
- # Choose a random host to get and check its elements
- host_details = self.admin_hosts_client.show_host(
- random.choice(host_names))['host']
- self.assertNotEmpty(host_details)
+ # Check each cinder-volume host.
host_detail_keys = ['project', 'volume_count', 'snapshot_count',
'host', 'total_volume_gb', 'total_snapshot_gb']
- for detail in host_details:
- self.assertIn('resource', detail)
- for key in host_detail_keys:
- self.assertIn(key, detail['resource'])
+ for host in c_vol_hosts:
+ host_details = self.admin_hosts_client.show_host(host)['host']
+ self.assertNotEmpty(host_details)
+ for detail in host_details:
+ self.assertIn('resource', detail)
+ for key in host_detail_keys:
+ self.assertIn(key, detail['resource'])
diff --git a/tempest/api/volume/base.py b/tempest/api/volume/base.py
index 9142dc3..63ef85b 100644
--- a/tempest/api/volume/base.py
+++ b/tempest/api/volume/base.py
@@ -72,6 +72,11 @@
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
@@ -82,10 +87,6 @@
cls.availability_zone_client = (
cls.os_primary.volume_v2_availability_zone_client)
cls.volume_limits_client = cls.os_primary.volume_v2_limits_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
def setUp(self):
super(BaseVolumeTest, self).setUp()
@@ -259,6 +260,11 @@
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.admin_snapshot_manage_client = \
cls.os_admin.snapshot_manage_v2_client
@@ -274,11 +280,6 @@
cls.os_admin.volume_capabilities_v2_client
cls.admin_scheduler_stats_client = \
cls.os_admin.volume_scheduler_stats_v2_client
- cls.admin_messages_client = cls.os_admin.volume_v3_messages_client
- cls.admin_groups_client = cls.os_admin.groups_v3_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
@classmethod
def resource_setup(cls):
diff --git a/tempest/config.py b/tempest/config.py
index af9eefc..e78a07f 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -234,6 +234,12 @@
deprecated_reason="This feature flag was introduced to "
"support testing of old OpenStack versions, "
"which are not supported anymore"),
+ cfg.BoolOpt('domain_specific_drivers',
+ default=False,
+ help='Are domain specific drivers enabled? '
+ 'This configuration value should be same as '
+ '[identity]->domain_specific_drivers_enabled '
+ 'in keystone.conf.'),
cfg.BoolOpt('security_compliance',
default=False,
help='Does the environment have the security compliance '