Merge "Fix update_host API response schema"
diff --git a/tempest/api/object_storage/test_container_acl.py b/tempest/api/object_storage/test_container_acl.py
index ffdd1de..e555fd9 100644
--- a/tempest/api/object_storage/test_container_acl.py
+++ b/tempest/api/object_storage/test_container_acl.py
@@ -26,17 +26,6 @@
credentials = [['operator', CONF.object_storage.operator_role],
['operator_alt', CONF.object_storage.operator_role]]
- @classmethod
- def setup_credentials(cls):
- super(ObjectTestACLs, cls).setup_credentials()
- cls.os = cls.os_roles_operator
- cls.os_operator = cls.os_roles_operator_alt
-
- @classmethod
- def resource_setup(cls):
- super(ObjectTestACLs, cls).resource_setup()
- cls.test_auth_data = cls.os_operator.auth_provider.auth_data
-
def setUp(self):
super(ObjectTestACLs, self).setUp()
self.container_name = self.create_container()
@@ -49,24 +38,26 @@
def test_read_object_with_rights(self):
# attempt to read object using authorized user
# update X-Container-Read metadata ACL
- tenant_name = self.os_operator.credentials.tenant_name
- username = self.os_operator.credentials.username
+ tenant_name = self.os_roles_operator_alt.credentials.tenant_name
+ username = self.os_roles_operator_alt.credentials.username
cont_headers = {'X-Container-Read': tenant_name + ':' + username}
- resp_meta, body = self.container_client.update_container_metadata(
- self.container_name, metadata=cont_headers,
- metadata_prefix='')
+ resp_meta, body = self.os_roles_operator.container_client.\
+ update_container_metadata(
+ self.container_name, metadata=cont_headers,
+ metadata_prefix='')
self.assertHeaders(resp_meta, 'Container', 'POST')
# create object
object_name = data_utils.rand_name(name='Object')
- resp, _ = self.object_client.create_object(self.container_name,
- object_name, 'data')
+ resp, _ = self.os_roles_operator.object_client.create_object(
+ self.container_name, object_name, 'data')
self.assertHeaders(resp, 'Object', 'PUT')
- # Trying to read the object with rights
- self.object_client.auth_provider.set_alt_auth_data(
+ # set alternative authentication data; cannot simply use the
+ # other object client.
+ self.os_roles_operator.object_client.auth_provider.set_alt_auth_data(
request_part='headers',
- auth_data=self.test_auth_data
- )
- resp, _ = self.object_client.get_object(
+ auth_data=self.os_roles_operator_alt.object_client.auth_provider.
+ auth_data)
+ resp, _ = self.os_roles_operator.object_client.get_object(
self.container_name, object_name)
self.assertHeaders(resp, 'Object', 'GET')
@@ -74,20 +65,23 @@
def test_write_object_with_rights(self):
# attempt to write object using authorized user
# update X-Container-Write metadata ACL
- tenant_name = self.os_operator.credentials.tenant_name
- username = self.os_operator.credentials.username
+ tenant_name = self.os_roles_operator_alt.credentials.tenant_name
+ username = self.os_roles_operator_alt.credentials.username
cont_headers = {'X-Container-Write': tenant_name + ':' + username}
- resp_meta, body = self.container_client.update_container_metadata(
- self.container_name, metadata=cont_headers,
- metadata_prefix='')
+ resp_meta, body = self.os_roles_operator.container_client.\
+ update_container_metadata(self.container_name,
+ metadata=cont_headers,
+ metadata_prefix='')
self.assertHeaders(resp_meta, 'Container', 'POST')
- # Trying to write the object with rights
- self.object_client.auth_provider.set_alt_auth_data(
+ # set alternative authentication data; cannot simply use the
+ # other object client.
+ self.os_roles_operator.object_client.auth_provider.set_alt_auth_data(
request_part='headers',
- auth_data=self.test_auth_data
- )
+ auth_data=self.os_roles_operator_alt.object_client.auth_provider.
+ auth_data)
+ # Trying to write the object with rights
object_name = data_utils.rand_name(name='Object')
- resp, _ = self.object_client.create_object(
+ resp, _ = self.os_roles_operator.object_client.create_object(
self.container_name,
object_name, 'data', headers={})
self.assertHeaders(resp, 'Object', 'PUT')
diff --git a/tempest/api/volume/admin/test_volume_retype_with_migration.py b/tempest/api/volume/admin/test_volume_retype_with_migration.py
new file mode 100644
index 0000000..8a69ea3
--- /dev/null
+++ b/tempest/api/volume/admin/test_volume_retype_with_migration.py
@@ -0,0 +1,109 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+
+from oslo_log import log as logging
+
+from tempest.api.volume import base
+from tempest.common import waiters
+from tempest import config
+from tempest import test
+
+CONF = config.CONF
+
+LOG = logging.getLogger(__name__)
+
+
+class VolumeRetypeWithMigrationV2Test(base.BaseVolumeAdminTest):
+
+ @classmethod
+ def skip_checks(cls):
+ super(VolumeRetypeWithMigrationV2Test, cls).skip_checks()
+
+ if not CONF.volume_feature_enabled.multi_backend:
+ raise cls.skipException("Cinder multi-backend feature disabled.")
+
+ if len(set(CONF.volume.backend_names)) < 2:
+ raise cls.skipException("Requires at least two different "
+ "backend names")
+
+ @classmethod
+ def resource_setup(cls):
+ super(VolumeRetypeWithMigrationV2Test, cls).resource_setup()
+ # read backend name from a list.
+ cls.backend_src = CONF.volume.backend_names[0]
+ cls.backend_dst = CONF.volume.backend_names[1]
+
+ extra_specs_src = {"volume_backend_name": cls.backend_src}
+ extra_specs_dst = {"volume_backend_name": cls.backend_dst}
+
+ cls.src_vol_type = cls.create_volume_type(extra_specs=extra_specs_src)
+ cls.dst_vol_type = cls.create_volume_type(extra_specs=extra_specs_dst)
+
+ cls.src_vol = cls.create_volume(volume_type=cls.src_vol_type['name'])
+
+ @classmethod
+ def resource_cleanup(cls):
+ # When retyping a volume, Cinder creates an internal volume in the
+ # target backend. The volume in the source backend is deleted after
+ # the migration, so we need to wait for Cinder delete this volume
+ # before deleting the types we've created.
+
+ # This list should return 2 volumes until the copy and cleanup
+ # process is finished.
+ fetched_list = cls.admin_volume_client.list_volumes(
+ params={'all_tenants': True,
+ 'display_name': cls.src_vol['name']})['volumes']
+
+ for fetched_vol in fetched_list:
+ if fetched_vol['id'] != cls.src_vol['id']:
+ # This is the Cinder internal volume
+ LOG.debug('Waiting for internal volume %s deletion',
+ fetched_vol['id'])
+ cls.admin_volume_client.wait_for_resource_deletion(
+ fetched_vol['id'])
+ break
+
+ super(VolumeRetypeWithMigrationV2Test, cls).resource_cleanup()
+
+ @test.idempotent_id('a1a41f3f-9dad-493e-9f09-3ff197d477cd')
+ def test_available_volume_retype_with_migration(self):
+
+ keys_with_no_change = ('id', 'size', 'description', 'name', 'user_id',
+ 'os-vol-tenant-attr:tenant_id')
+ keys_with_change = ('volume_type', 'os-vol-host-attr:host')
+
+ volume_source = self.admin_volume_client.show_volume(
+ self.src_vol['id'])['volume']
+
+ # TODO(erlon): change this to volumes_client client after Bug
+ # #1657806 is fixed
+ self.admin_volume_client.retype_volume(
+ self.src_vol['id'],
+ new_type=self.dst_vol_type['name'],
+ migration_policy='on-demand')
+
+ waiters.wait_for_volume_retype(self.volumes_client, self.src_vol['id'],
+ self.dst_vol_type['name'])
+ volume_dest = self.admin_volume_client.show_volume(
+ self.src_vol['id'])['volume']
+
+ # Check the volume information after the migration.
+ self.assertEqual('success',
+ volume_dest['os-vol-mig-status-attr:migstat'])
+ self.assertEqual('success', volume_dest['migration_status'])
+
+ for key in keys_with_no_change:
+ self.assertEqual(volume_source[key], volume_dest[key])
+
+ for key in keys_with_change:
+ self.assertNotEqual(volume_source[key], volume_dest[key])
diff --git a/tempest/api/volume/admin/test_volume_types.py b/tempest/api/volume/admin/test_volume_types.py
index 6b2acc6..3d44bbe 100644
--- a/tempest/api/volume/admin/test_volume_types.py
+++ b/tempest/api/volume/admin/test_volume_types.py
@@ -42,7 +42,7 @@
extra_specs = {"storage_protocol": proto,
"vendor_name": vendor}
# Create two volume_types
- for i in range(2):
+ for _ in range(2):
vol_type = self.create_volume_type(
extra_specs=extra_specs)
volume_types.append(vol_type)
diff --git a/tempest/api/volume/admin/v2/test_volumes_list.py b/tempest/api/volume/admin/v2/test_volumes_list.py
index cdd9df9..fd36d0a 100644
--- a/tempest/api/volume/admin/v2/test_volumes_list.py
+++ b/tempest/api/volume/admin/v2/test_volumes_list.py
@@ -32,7 +32,7 @@
# NOTE(zhufl): When using pre-provisioned credentials, the project
# may have volumes other than those created below.
cls.volume_list = cls.volumes_client.list_volumes()['volumes']
- for i in range(3):
+ for _ in range(3):
volume = cls.create_volume()
# Fetch volume details
volume_details = cls.volumes_client.show_volume(
diff --git a/tempest/api/volume/test_volumes_list.py b/tempest/api/volume/test_volumes_list.py
index 030ea6c..5e3f49f 100644
--- a/tempest/api/volume/test_volumes_list.py
+++ b/tempest/api/volume/test_volumes_list.py
@@ -61,7 +61,7 @@
# Create 3 test volumes
cls.volume_list = []
cls.metadata = {'Type': 'work'}
- for i in range(3):
+ for _ in range(3):
volume = cls.create_volume(metadata=cls.metadata)
volume = cls.volumes_client.show_volume(volume['id'])['volume']
cls.volume_list.append(volume)
diff --git a/tempest/api/volume/test_volumes_snapshots_list.py b/tempest/api/volume/test_volumes_snapshots_list.py
index 4416bef..b831252 100644
--- a/tempest/api/volume/test_volumes_snapshots_list.py
+++ b/tempest/api/volume/test_volumes_snapshots_list.py
@@ -105,12 +105,6 @@
# List returns zero elements
self._list_snapshots_by_param_limit(limit=0, expected_elements=0)
- def cleanup_snapshot(self, snapshot):
- # Delete the snapshot
- self.snapshots_client.delete_snapshot(snapshot['id'])
- self.snapshots_client.wait_for_resource_deletion(snapshot['id'])
- self.snapshots.remove(snapshot)
-
class VolumesV1SnapshotLimitTestJSON(VolumesV2SnapshotListTestJSON):
_api_version = 1
diff --git a/tempest/api/volume/v2/test_volumes_list.py b/tempest/api/volume/v2/test_volumes_list.py
index fb8c65d..28ba941 100644
--- a/tempest/api/volume/v2/test_volumes_list.py
+++ b/tempest/api/volume/v2/test_volumes_list.py
@@ -42,7 +42,7 @@
# may have volumes other than those created below.
existing_volumes = cls.volumes_client.list_volumes()['volumes']
cls.volume_id_list = [vol['id'] for vol in existing_volumes]
- for i in range(3):
+ for _ in range(3):
volume = cls.create_volume(metadata=cls.metadata)
cls.volume_id_list.append(volume['id'])
diff --git a/tempest/lib/cmd/skip_tracker.py b/tempest/lib/cmd/skip_tracker.py
index d95aa46..07b811d 100755
--- a/tempest/lib/cmd/skip_tracker.py
+++ b/tempest/lib/cmd/skip_tracker.py
@@ -21,16 +21,18 @@
"""
import argparse
-import logging
import os
import re
+from oslo_log import log as logging
+
try:
from launchpadlib import launchpad
except ImportError:
launchpad = None
LPCACHEDIR = os.path.expanduser('~/.launchpadlib/cache')
+LOG = logging.getLogger(__name__)
def parse_args():
@@ -40,11 +42,11 @@
def info(msg, *args, **kwargs):
- logging.info(msg, *args, **kwargs)
+ LOG.info(msg, *args, **kwargs)
def debug(msg, *args, **kwargs):
- logging.debug(msg, *args, **kwargs)
+ LOG.debug(msg, *args, **kwargs)
def find_skips(start):
@@ -110,8 +112,6 @@
def main():
- logging.basicConfig(format='%(levelname)s: %(message)s',
- level=logging.INFO)
parser = parse_args()
results = find_skips(parser.test_path)
unique_bugs = sorted(set([bug for (method, bug) in get_results(results)]))
diff --git a/tools/skip_tracker.py b/tools/skip_tracker.py
index 55f41a6..9735f77 100755
--- a/tools/skip_tracker.py
+++ b/tools/skip_tracker.py
@@ -20,23 +20,25 @@
is fixed but a skip is still in the Tempest test code
"""
-import logging
import os
import re
from launchpadlib import launchpad
+from oslo_log import log as logging
BASEDIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
TESTDIR = os.path.join(BASEDIR, 'tempest')
LPCACHEDIR = os.path.expanduser('~/.launchpadlib/cache')
+LOG = logging.getLogger(__name__)
+
def info(msg, *args, **kwargs):
- logging.info(msg, *args, **kwargs)
+ LOG.info(msg, *args, **kwargs)
def debug(msg, *args, **kwargs):
- logging.debug(msg, *args, **kwargs)
+ LOG.debug(msg, *args, **kwargs)
def find_skips(start=TESTDIR):
@@ -102,8 +104,6 @@
if __name__ == '__main__':
- logging.basicConfig(format='%(levelname)s: %(message)s',
- level=logging.INFO)
results = find_skips()
unique_bugs = sorted(set([bug for (method, bug) in get_results(results)]))
unskips = []