Merge "Add support to chose ssh key type"
diff --git a/manila_tempest_tests/common/remote_client.py b/manila_tempest_tests/common/remote_client.py
index 440bee2..a6eee45 100644
--- a/manila_tempest_tests/common/remote_client.py
+++ b/manila_tempest_tests/common/remote_client.py
@@ -13,7 +13,6 @@
import sys
from oslo_log import log
-import six
from tempest import config
from tempest.lib.common import ssh
from tempest.lib.common.utils import test_utils
@@ -47,7 +46,7 @@
msg = 'Could not get console_log for server %s'
LOG.debug(msg, self.server['id'])
# re-raise the original ssh timeout exception
- six.reraise(*original_exception)
+ raise original_exception
finally:
# Delete the traceback to avoid circular references
_, _, trace = original_exception
diff --git a/manila_tempest_tests/common/waiters.py b/manila_tempest_tests/common/waiters.py
index 5d8d344..24b30de 100644
--- a/manila_tempest_tests/common/waiters.py
+++ b/manila_tempest_tests/common/waiters.py
@@ -15,7 +15,6 @@
import time
-import six
from tempest import config
from tempest.lib import exceptions
@@ -137,7 +136,7 @@
'dest': dest_host,
'share_id': share['id'],
'timeout': client.build_timeout,
- 'status': six.text_type(statuses),
+ 'status': str(statuses),
})
raise exceptions.TimeoutException(message)
return share
@@ -180,3 +179,41 @@
' the required time (%s s).' %
(resource_id, client.build_timeout))
raise exceptions.TimeoutException(message)
+
+
+def wait_for_soft_delete(client, share_id, version=LATEST_MICROVERSION):
+ """Wait for a share soft delete to recycle bin."""
+ share = client.get_share(share_id, version=version)['share']
+ start = int(time.time())
+ while not share['is_soft_deleted']:
+ time.sleep(client.build_interval)
+ share = client.get_share(share_id, version=version)['share']
+ if share['is_soft_deleted']:
+ break
+ elif int(time.time()) - start >= client.build_timeout:
+ message = ('Share %(share_id)s failed to be soft deleted to '
+ 'recycle bin within the required time '
+ '%(timeout)s.' % {
+ 'share_id': share['id'],
+ 'timeout': client.build_timeout,
+ })
+ raise exceptions.TimeoutException(message)
+
+
+def wait_for_restore(client, share_id, version=LATEST_MICROVERSION):
+ """Wait for a share restore from recycle bin."""
+ share = client.get_share(share_id, version=version)['share']
+ start = int(time.time())
+ while share['is_soft_deleted']:
+ time.sleep(client.build_interval)
+ share = client.get_share(share_id, version=version)['share']
+ if not share['is_soft_deleted']:
+ break
+ elif int(time.time()) - start >= client.build_timeout:
+ message = ('Share %(share_id)s failed to restore from '
+ 'recycle bin within the required time '
+ '%(timeout)s.' % {
+ 'share_id': share['id'],
+ 'timeout': client.build_timeout,
+ })
+ raise exceptions.TimeoutException(message)
diff --git a/manila_tempest_tests/config.py b/manila_tempest_tests/config.py
index 6f9813c..f5022af 100644
--- a/manila_tempest_tests/config.py
+++ b/manila_tempest_tests/config.py
@@ -21,6 +21,15 @@
help="Whether or not manila is expected to be "
"available")
+manila_scope_enforcement = cfg.BoolOpt('manila',
+ default=False,
+ help="Does the Share service API "
+ "policies enforce scope? "
+ "This configuration value should "
+ "be same as manila.conf: "
+ "[oslo_policy].enforce_scope "
+ "option.")
+
share_group = cfg.OptGroup(name="share", title="Share Service Options")
ShareGroup = [
@@ -31,7 +40,7 @@
"This value is only used to validate the versions "
"response from Manila."),
cfg.StrOpt("max_api_microversion",
- default="2.65",
+ default="2.69",
help="The maximum api microversion is configured to be the "
"value of the latest microversion supported by Manila."),
cfg.StrOpt("region",
diff --git a/manila_tempest_tests/plugin.py b/manila_tempest_tests/plugin.py
index 0c32ce1..148a368 100644
--- a/manila_tempest_tests/plugin.py
+++ b/manila_tempest_tests/plugin.py
@@ -33,6 +33,8 @@
def register_opts(self, conf):
conf.register_opt(config_share.service_option,
group='service_available')
+ conf.register_opt(config_share.manila_scope_enforcement,
+ group='enforce_scope')
conf.register_group(config_share.share_group)
conf.register_opts(config_share.ShareGroup, group='share')
@@ -54,7 +56,8 @@
def get_opt_lists(self):
return [(config_share.share_group.name, config_share.ShareGroup),
- ('service_available', [config_share.service_option])]
+ ('service_available', [config_share.service_option]),
+ ('enforce_scope', [config_share.manila_scope_enforcement])]
def get_service_clients(self):
shares_config = config.service_client_config('share')
diff --git a/manila_tempest_tests/services/share/json/shares_client.py b/manila_tempest_tests/services/share/json/shares_client.py
index 770bbb9..3413387 100644
--- a/manila_tempest_tests/services/share/json/shares_client.py
+++ b/manila_tempest_tests/services/share/json/shares_client.py
@@ -15,9 +15,8 @@
import json
import time
+from urllib import parse as urlparse
-import six
-from six.moves.urllib import parse as urlparse
from tempest import config
from tempest.lib.common import rest_client
from tempest.lib.common.utils import data_utils
@@ -322,7 +321,7 @@
self.show_share_server, kwargs.get("server_id"))
else:
raise share_exceptions.InvalidResource(
- message=six.text_type(kwargs))
+ message=str(kwargs))
def _is_resource_deleted(self, func, res_id, **kwargs):
try:
diff --git a/manila_tempest_tests/services/share/v2/json/shares_client.py b/manila_tempest_tests/services/share/v2/json/shares_client.py
index 01028cd..6db5393 100644
--- a/manila_tempest_tests/services/share/v2/json/shares_client.py
+++ b/manila_tempest_tests/services/share/v2/json/shares_client.py
@@ -16,8 +16,8 @@
import json
import re
import time
+from urllib import parse
-from six.moves.urllib import parse
from tempest import config
from tempest.lib.common import rest_client
from tempest.lib.common.utils import data_utils
@@ -299,6 +299,20 @@
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
+ def list_shares_in_recycle_bin(self, detailed=False,
+ params=None, version=LATEST_MICROVERSION,
+ experimental=False):
+ """Get list of shares in recycle bin with w/o filters."""
+ headers = EXPERIMENTAL if experimental else None
+ uri = 'shares/detail' if detailed else 'shares'
+ uri += '?is_soft_deleted=true'
+ uri += '&%s' % parse.urlencode(params) if params else ''
+ resp, body = self.get(uri, headers=headers, extra_headers=experimental,
+ version=version)
+ self.expected_success(200, resp.status)
+ body = json.loads(body)
+ return rest_client.ResponseBody(resp, body)
+
def list_shares_with_detail(self, params=None,
version=LATEST_MICROVERSION,
experimental=False):
@@ -342,6 +356,22 @@
self.expected_success(202, resp.status)
return rest_client.ResponseBody(resp, body)
+ def soft_delete_share(self, share_id, version=LATEST_MICROVERSION):
+ post_body = {"soft_delete": None}
+ body = json.dumps(post_body)
+ resp, body = self.post(
+ "shares/%s/action" % share_id, body, version=version)
+ self.expected_success(202, resp.status)
+ return rest_client.ResponseBody(resp, body)
+
+ def restore_share(self, share_id, version=LATEST_MICROVERSION):
+ post_body = {"restore": None}
+ body = json.dumps(post_body)
+ resp, body = self.post(
+ "shares/%s/action" % share_id, body, version=version)
+ self.expected_success(202, resp.status)
+ return rest_client.ResponseBody(resp, body)
+
###############
def get_instances_of_share(self, share_id, version=LATEST_MICROVERSION):
@@ -390,17 +420,22 @@
###############
def extend_share(self, share_id, new_size, version=LATEST_MICROVERSION,
- action_name=None):
+ action_name=None, force=False):
if action_name is None:
if utils.is_microversion_gt(version, "2.6"):
action_name = 'extend'
else:
action_name = 'os-extend'
+
post_body = {
action_name: {
"new_size": new_size,
}
}
+
+ if utils.is_microversion_gt(version, "2.63"):
+ post_body[action_name]["force"] = force
+
body = json.dumps(post_body)
resp, body = self.post(
"shares/%s/action" % share_id, body, version=version)
@@ -1523,16 +1558,18 @@
version=version)
return rest_client.ResponseBody(resp, body)
-################
-
def create_share_replica(self, share_id, availability_zone=None,
- version=LATEST_MICROVERSION):
+ version=LATEST_MICROVERSION,
+ scheduler_hints=None):
"""Add a share replica of an existing share."""
uri = "share-replicas"
post_body = {
'share_id': share_id,
'availability_zone': availability_zone,
}
+
+ if scheduler_hints:
+ post_body["scheduler_hints"] = scheduler_hints
headers, extra_headers = utils.get_extra_headers(
version, constants.SHARE_REPLICA_GRADUATION_VERSION)
body = json.dumps({'share_replica': post_body})
diff --git a/manila_tempest_tests/tests/api/admin/test_admin_actions.py b/manila_tempest_tests/tests/api/admin/test_admin_actions.py
index e958ac9..1a5ecc7 100644
--- a/manila_tempest_tests/tests/api/admin/test_admin_actions.py
+++ b/manila_tempest_tests/tests/api/admin/test_admin_actions.py
@@ -181,3 +181,29 @@
self.assertNotEmpty(share_server)
else:
self.assertEmpty(share_server)
+
+ @decorators.idempotent_id('83d94560-e9b4-47c1-b21e-400531528e27')
+ @tc.attr(base.TAG_POSITIVE, base.TAG_BACKEND)
+ @utils.skip_if_microversion_not_supported("2.64")
+ @testtools.skipUnless(
+ CONF.share.run_extend_tests,
+ "Share extend tests are disabled.")
+ @ddt.data(True, False)
+ def test_extend_share_force(self, force_flag):
+ # Force extend were supported from v2.64
+ # If a admin tries to do force extend, it should be success
+ share = self.create_share(share_type_id=self.share_type_id,
+ cleanup_in_class=False)
+ new_size = int(share['size']) + 1
+
+ # force extend share and wait for active status
+ self.admin_shares_v2_client.extend_share(share['id'], new_size,
+ force=force_flag)
+ waiters.wait_for_resource_status(
+ self.shares_client, share['id'], 'available')
+
+ # check new size
+ share_get = self.shares_v2_client.get_share(share['id'])['share']
+ msg = ("Share could not be extended. Expected %s, got %s." % (
+ new_size, share_get['size']))
+ self.assertEqual(new_size, share_get['size'], msg)
diff --git a/manila_tempest_tests/tests/api/admin/test_export_locations.py b/manila_tempest_tests/tests/api/admin/test_export_locations.py
index 7d09f69..db382f2 100644
--- a/manila_tempest_tests/tests/api/admin/test_export_locations.py
+++ b/manila_tempest_tests/tests/api/admin/test_export_locations.py
@@ -16,7 +16,6 @@
import ddt
from oslo_utils import timeutils
from oslo_utils import uuidutils
-import six
from tempest import config
from tempest.lib import decorators
from testtools import testcase as tc
@@ -91,7 +90,7 @@
# Check the format of ever-present summary keys
self.assertTrue(uuidutils.is_uuid_like(export_location['id']))
self.assertIsInstance(export_location['path'],
- six.string_types)
+ str)
if utils.is_microversion_ge(version, '2.14'):
self.assertIn(export_location['preferred'], (True, False))
diff --git a/manila_tempest_tests/tests/api/admin/test_quotas_negative.py b/manila_tempest_tests/tests/api/admin/test_quotas_negative.py
index 7dd12e1..20e359a 100644
--- a/manila_tempest_tests/tests/api/admin/test_quotas_negative.py
+++ b/manila_tempest_tests/tests/api/admin/test_quotas_negative.py
@@ -426,6 +426,25 @@
self.create_share,
share_type_id=self.share_type_id)
+ @decorators.idempotent_id('a2267f4d-63ef-4631-a01d-3723707e5516')
+ @testtools.skipUnless(
+ CONF.share.run_snapshot_tests, 'Snapshot tests are disabled.')
+ @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
+ def test_create_snapshot_over_quota_limit(self):
+ extra_specs = {'snapshot_support': True}
+ share_type = self.create_share_type(extra_specs=extra_specs)
+ share = self.create_share(share_type_id=share_type['id'])
+
+ # Update snapshot quota
+ self.update_quotas(self.tenant_id, snapshots=1)
+
+ # Create share from updated snapshot, wait for status 'available'
+ self.create_snapshot_wait_for_active(share['id'])
+
+ self.assertRaises(lib_exc.OverLimit,
+ self.create_snapshot_wait_for_active,
+ share['id'])
+
@ddt.ddt
class ReplicaQuotasNegativeTest(rep_neg_test.ReplicationNegativeBase):
diff --git a/manila_tempest_tests/tests/api/admin/test_replication.py b/manila_tempest_tests/tests/api/admin/test_replication.py
index b5b340c..242e786 100644
--- a/manila_tempest_tests/tests/api/admin/test_replication.py
+++ b/manila_tempest_tests/tests/api/admin/test_replication.py
@@ -45,7 +45,6 @@
def resource_setup(cls):
super(ReplicationAdminTest, cls).resource_setup()
cls.admin_client = cls.admin_shares_v2_client
- cls.member_client = cls.shares_v2_client
cls.replication_type = CONF.share.backend_replication_type
cls.multitenancy_enabled = (
utils.replication_with_multitenancy_support())
@@ -83,6 +82,7 @@
return [replica['id'] for replica in replica_list
if replica['replica_state'] == r_state]
+ @decorators.unstable_test(bug='1631314')
@decorators.idempotent_id('0213cdfd-6a0f-4f24-a154-69796888a64a')
@tc.attr(base.TAG_POSITIVE, base.TAG_BACKEND)
@ddt.data(
@@ -137,7 +137,8 @@
version=version)
# Original replica will need to be cleaned up before the promoted
# replica can be deleted.
- self.addCleanup(self.delete_share_replica, original_replica['id'])
+ self.addCleanup(self.delete_share_replica, original_replica['id'],
+ client=self.admin_client)
# Check if there is still only 1 'active' replica after promotion.
replica_list = self.admin_client.list_share_replicas(
@@ -211,6 +212,7 @@
self.admin_client, replica['id'], constants.STATUS_ERROR,
resource_name='share_replica', status_attr='replica_state')
+ @decorators.unstable_test(bug='1631314')
@decorators.idempotent_id('2969565a-85e8-4c61-9dfb-cc7f7ca9f6dd')
@tc.attr(base.TAG_POSITIVE, base.TAG_BACKEND)
@ddt.data(
diff --git a/manila_tempest_tests/tests/api/admin/test_scheduler_hints.py b/manila_tempest_tests/tests/api/admin/test_scheduler_hints.py
new file mode 100644
index 0000000..55c9ca7
--- /dev/null
+++ b/manila_tempest_tests/tests/api/admin/test_scheduler_hints.py
@@ -0,0 +1,113 @@
+# Copyright 2022 Cloudification GmbH
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from tempest import config
+from tempest.lib.common.utils import data_utils
+from tempest.lib import decorators
+from testtools import testcase as tc
+
+from manila_tempest_tests.common import constants
+from manila_tempest_tests import share_exceptions
+from manila_tempest_tests.tests.api import base
+from manila_tempest_tests import utils
+
+CONF = config.CONF
+LATEST_MICROVERSION = CONF.share.max_api_microversion
+
+
+class SharesSchedulerHintsAdminTest(base.BaseSharesAdminTest):
+
+ @classmethod
+ def skip_checks(cls):
+ super(SharesSchedulerHintsAdminTest, cls).skip_checks()
+ if not CONF.share.multi_backend:
+ raise cls.skipException("Manila multi-backend tests are disabled.")
+ elif len(CONF.share.backend_names) < 2:
+ raise cls.skipException("For running multi-backend tests, two or "
+ "more backend names must be configured.")
+ elif any(not name for name in CONF.share.backend_names):
+ raise cls.skipException("Share backend names can not be empty.")
+ utils.check_skip_if_microversion_not_supported('2.67')
+
+ @classmethod
+ def resource_setup(cls):
+ super(SharesSchedulerHintsAdminTest, cls).resource_setup()
+ # Need for requesting pools
+ cls.admin_client = cls.admin_shares_v2_client
+ # create share type
+ share_type = cls.create_share_type()
+ cls.share_type_id = share_type['id']
+
+ @decorators.idempotent_id('54f4dea7-890e-443b-aea5-f6108da893f0')
+ @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
+ def test_only_host_scheduler_hint_in_share_creation(self):
+ share_a = self.create_share(share_type_id=self.share_type_id)
+ share_a = self.admin_shares_v2_client.get_share(share_a['id'])['share']
+ backend_a = share_a['host']
+ scheduler_hint = {"only_host": "%s" % backend_a}
+
+ # create share with hint
+ share_b = self.create_share(share_type_id=self.share_type_id,
+ scheduler_hints=scheduler_hint,
+ cleanup_in_class=False)
+ share_b = self.admin_shares_v2_client.get_share(share_b['id'])['share']
+ backend_b = share_b['host']
+
+ # verify same backends
+ self.assertEqual(backend_a, backend_b)
+
+ @decorators.idempotent_id('1dec3306-61f4-41b9-ba4a-572a9e6f5f57')
+ @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
+ @tc.skipUnless(CONF.share.run_replication_tests,
+ 'Replication tests are disabled.')
+ def test_only_host_scheduler_hint_in_share_replica_creation(self):
+ replication_type = CONF.share.backend_replication_type
+ if replication_type not in constants.REPLICATION_TYPE_CHOICES:
+ raise share_exceptions.ShareReplicationTypeException(
+ replication_type=replication_type
+ )
+ extra_specs = self.add_extra_specs_to_dict({
+ "replication_type": replication_type
+ })
+ replicated_share_type = self.create_share_type(
+ data_utils.rand_name("replicated-shares"),
+ extra_specs=extra_specs)
+ share = self.create_share(
+ share_type_id=replicated_share_type['id'],
+ cleanup_in_class=False)
+ share = self.admin_shares_v2_client.get_share(share['id'])['share']
+ share_host = share['host']
+ rep_domain, pools = self.get_pools_for_replication_domain(share=share)
+ if len(pools) < 2:
+ msg = ("Can not create valid hint due to insufficient pools.")
+ raise self.skipException(msg)
+
+ for p in pools:
+ if p['name'] != share_host:
+ expected_replica_host = p['name']
+ scheduler_hint = {"only_host": "%s" % expected_replica_host}
+ break
+
+ # create share replica with hint
+ replica = self.create_share_replica(share['id'],
+ cleanup_in_class=False,
+ version=LATEST_MICROVERSION,
+ scheduler_hints=scheduler_hint)
+ replica = self.admin_shares_v2_client.get_share_replica(
+ replica['id'])['share_replica']
+ replica_host = replica['host']
+
+ # verify same backends
+ self.assertEqual(expected_replica_host, replica_host)
diff --git a/manila_tempest_tests/tests/api/admin/test_share_servers.py b/manila_tempest_tests/tests/api/admin/test_share_servers.py
index fd553ff..b406a92 100644
--- a/manila_tempest_tests/tests/api/admin/test_share_servers.py
+++ b/manila_tempest_tests/tests/api/admin/test_share_servers.py
@@ -16,7 +16,6 @@
import re
import ddt
-import six
from tempest import config
from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
@@ -120,7 +119,7 @@
else:
msg = ("Appropriate server was not found. Its share_network_data"
": '%s'. List of servers: '%s'.") % (self.sn_name_and_id,
- six.text_type(servers))
+ str(servers))
raise lib_exc.NotFound(message=msg)
search_opts = {"host": host}
servers = self.shares_v2_client.list_share_servers(
@@ -226,8 +225,8 @@
# If details are present they and their values should be only strings
for k, v in details.items():
- self.assertIsInstance(k, six.string_types)
- self.assertIsInstance(v, six.string_types)
+ self.assertIsInstance(k, str)
+ self.assertIsInstance(v, str)
@decorators.idempotent_id('2fdf8d29-3ab8-4424-b684-6253f45b9666')
@tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
diff --git a/manila_tempest_tests/tests/api/admin/test_snapshot_export_locations.py b/manila_tempest_tests/tests/api/admin/test_snapshot_export_locations.py
index fca92c7..1c6a9b7 100644
--- a/manila_tempest_tests/tests/api/admin/test_snapshot_export_locations.py
+++ b/manila_tempest_tests/tests/api/admin/test_snapshot_export_locations.py
@@ -15,7 +15,6 @@
import ddt
from oslo_utils import uuidutils
-import six
from tempest import config
from tempest.lib import decorators
from testtools import testcase as tc
@@ -94,7 +93,7 @@
# Check the format of ever-present summary keys
self.assertTrue(uuidutils.is_uuid_like(export_location['id']))
self.assertIsInstance(export_location['path'],
- six.string_types)
+ str)
if role == 'admin':
self.assertIn(export_location['is_admin_only'], (True, False))
diff --git a/manila_tempest_tests/tests/api/admin/test_snapshot_manage_negative.py b/manila_tempest_tests/tests/api/admin/test_snapshot_manage_negative.py
index f2fb48f..36ddf7e 100644
--- a/manila_tempest_tests/tests/api/admin/test_snapshot_manage_negative.py
+++ b/manila_tempest_tests/tests/api/admin/test_snapshot_manage_negative.py
@@ -13,7 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import six
+
from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
@@ -51,7 +51,7 @@
cls.extra_specs = {
'storage_protocol': CONF.share.capability_storage_protocol,
'driver_handles_share_servers': CONF.share.multitenancy_enabled,
- 'snapshot_support': six.text_type(
+ 'snapshot_support': str(
CONF.share.capability_snapshot_support),
}
diff --git a/manila_tempest_tests/tests/api/admin/test_user_messages_negative.py b/manila_tempest_tests/tests/api/admin/test_user_messages_negative.py
index 197b883..e675387 100644
--- a/manila_tempest_tests/tests/api/admin/test_user_messages_negative.py
+++ b/manila_tempest_tests/tests/api/admin/test_user_messages_negative.py
@@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from oslo_utils import uuidutils
-import six
from tempest import config
from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
@@ -47,7 +46,7 @@
def test_show_nonexistent_message(self):
self.assertRaises(lib_exc.NotFound,
self.shares_v2_client.get_message,
- six.text_type(uuidutils.generate_uuid()))
+ str(uuidutils.generate_uuid()))
@decorators.attr(type=[base.TAG_NEGATIVE, base.TAG_API])
@decorators.idempotent_id('2f5be1aa-974b-4f6a-ae3a-084578e64f82')
@@ -61,7 +60,7 @@
def test_delete_nonexistent_message(self):
self.assertRaises(lib_exc.NotFound,
self.shares_v2_client.delete_message,
- six.text_type(uuidutils.generate_uuid()))
+ str(uuidutils.generate_uuid()))
@decorators.attr(type=[base.TAG_NEGATIVE, base.TAG_API])
@utils.skip_if_microversion_not_supported(QUERY_BY_TIMESTAMP_MICROVERSION)
diff --git a/manila_tempest_tests/tests/api/base.py b/manila_tempest_tests/tests/api/base.py
index dd25062..d5cc439 100755
--- a/manila_tempest_tests/tests/api/base.py
+++ b/manila_tempest_tests/tests/api/base.py
@@ -18,7 +18,6 @@
import traceback
from oslo_log import log
-import six
from tempest import config
from tempest.lib.common import cred_client
from tempest.lib.common.utils import data_utils
@@ -636,8 +635,8 @@
extra_specs = {}
for k, v in share_type['extra_specs'].items():
extra_specs[k] = (
- True if six.text_type(v).lower() == 'true'
- else False if six.text_type(v).lower() == 'false' else v
+ True if str(v).lower() == 'true'
+ else False if str(v).lower() == 'false' else v
)
return [
pool for pool in pools if all(y in pool['capabilities'].items()
@@ -657,11 +656,15 @@
azs = cls.get_availability_zones(backends=backends_matching_share_type)
return azs
- def get_pools_for_replication_domain(self):
+ def get_pools_for_replication_domain(self, share=None):
# Get the list of pools for the replication domain
pools = self.admin_client.list_pools(detail=True)['pools']
- instance_host = self.admin_client.get_share(
- self.shares[0]['id'])['share']['host']
+ if share:
+ instance_host = self.admin_client.get_share(
+ share['id'])['share']['host']
+ else:
+ instance_host = self.admin_client.get_share(
+ self.shares[0]['id'])['share']['host']
host_pool = [p for p in pools if p['name'] == instance_host][0]
rep_domain = host_pool['capabilities']['replication_domain']
pools_in_rep_domain = [p for p in pools if p['capabilities'][
@@ -672,11 +675,12 @@
def create_share_replica(cls, share_id, availability_zone=None,
client=None, cleanup_in_class=False,
cleanup=True,
- version=CONF.share.max_api_microversion):
+ version=CONF.share.max_api_microversion,
+ scheduler_hints=None):
client = client or cls.shares_v2_client
replica = client.create_share_replica(
share_id, availability_zone=availability_zone,
- version=version)['share_replica']
+ version=version, scheduler_hints=scheduler_hints)['share_replica']
resource = {
"type": "share_replica",
"id": replica["id"],
@@ -1077,7 +1081,7 @@
@staticmethod
def add_extra_specs_to_dict(extra_specs=None):
"""Add any required extra-specs to share type dictionary"""
- dhss = six.text_type(CONF.share.multitenancy_enabled)
+ dhss = str(CONF.share.multitenancy_enabled)
extra_specs_dict = {"driver_handles_share_servers": dhss}
if extra_specs:
extra_specs_dict.update(extra_specs)
diff --git a/manila_tempest_tests/tests/api/test_metadata.py b/manila_tempest_tests/tests/api/test_metadata.py
index 5ca4e83..c8529a3 100644
--- a/manila_tempest_tests/tests/api/test_metadata.py
+++ b/manila_tempest_tests/tests/api/test_metadata.py
@@ -31,6 +31,19 @@
# create share
cls.share = cls.create_share(share_type_id=cls.share_type_id)
+ def _verify_share_metadata(self, share, md):
+
+ # get metadata of share
+ metadata = self.shares_client.get_metadata(share["id"])['metadata']
+
+ # verify metadata
+ self.assertEqual(md, metadata)
+
+ # verify metadata items
+ for key in md:
+ get_value = self.shares_client.get_metadata_item(share["id"], key)
+ self.assertEqual(md[key], get_value[key])
+
@decorators.idempotent_id('9070249f-6e94-4a38-a036-08debee547c3')
@tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
def test_set_metadata_in_share_creation(self):
@@ -42,11 +55,8 @@
metadata=md,
cleanup_in_class=False)
- # get metadata of share
- metadata = self.shares_client.get_metadata(share["id"])['metadata']
-
# verify metadata
- self.assertEqual(md, metadata)
+ self._verify_share_metadata(share, md)
@decorators.idempotent_id('2725ab8e-cc04-4032-9393-74726ba43eb7')
@tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
@@ -61,16 +71,8 @@
# set metadata
self.shares_client.set_metadata(share["id"], md)
- # read metadata
- get_md = self.shares_client.get_metadata(share["id"])['metadata']
-
# verify metadata
- self.assertEqual(md, get_md)
-
- # verify metadata items
- for key in md:
- get_value = self.shares_client.get_metadata_item(share["id"], key)
- self.assertEqual(md[key], get_value[key])
+ self._verify_share_metadata(share, md)
# delete metadata
for key in md.keys():
@@ -78,7 +80,73 @@
# verify deletion of metadata
get_metadata = self.shares_client.get_metadata(share["id"])['metadata']
- self.assertEqual({}, get_metadata)
+ self.assertEmpty(get_metadata)
+
+ @decorators.idempotent_id('4e5f8159-62b6-4d5c-f729-d8b1f029d7de')
+ @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
+ def test_set_metadata_not_delete_pre_metadata(self):
+ md1 = {u"key9": u"value9", u"key10": u"value10", }
+ md2 = {u"key11": u"value11", u"key12": u"value12", }
+
+ # create share
+ share = self.create_share(share_type_id=self.share_type_id,
+ cleanup_in_class=False)
+
+ # set metadata
+ self.shares_client.set_metadata(share["id"], md1)
+
+ # verify metadata
+ self._verify_share_metadata(share, md1)
+
+ # set metadata again
+ self.shares_client.set_metadata(share["id"], md2)
+
+ # verify metadata
+ md1.update(md2)
+ md = md1
+
+ # verify metadata
+ self._verify_share_metadata(share, md)
+
+ # delete metadata
+ for key in md.keys():
+ self.shares_client.delete_metadata(share["id"], key)
+
+ # verify deletion of metadata
+ get_metadata = self.shares_client.get_metadata(share["id"])['metadata']
+ self.assertEmpty(get_metadata)
+
+ @decorators.idempotent_id('2ec70ba5-050b-3b17-c862-c149e53543c0')
+ @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
+ def test_set_metadata_key_already_exist(self):
+ md1 = {u"key9": u"value9", u"key10": u"value10", }
+ md2 = {u"key9": u"value13", u"key11": u"value11", }
+
+ # create share
+ share = self.create_share(share_type_id=self.share_type_id,
+ cleanup_in_class=False)
+
+ # set metadata
+ self.shares_client.set_metadata(share["id"], md1)
+
+ # verify metadata
+ self._verify_share_metadata(share, md1)
+
+ # set metadata again
+ self.shares_client.set_metadata(share["id"], md2)
+
+ # verify metadata
+ md = {u"key9": u"value13", u"key10": u"value10",
+ u"key11": u"value11"}
+ self._verify_share_metadata(share, md)
+
+ # delete metadata
+ for key in md.keys():
+ self.shares_client.delete_metadata(share["id"], key)
+
+ # verify deletion of metadata
+ get_metadata = self.shares_client.get_metadata(share["id"])['metadata']
+ self.assertEmpty(get_metadata)
@decorators.idempotent_id('c94851f4-2559-4712-9297-9912db1da7ff')
@tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
@@ -97,11 +165,8 @@
# update metadata
self.shares_client.update_all_metadata(share["id"], md2)
- # get metadata
- get_md = self.shares_client.get_metadata(share["id"])['metadata']
-
# verify metadata
- self.assertEqual(md2, get_md)
+ self._verify_share_metadata(share, md2)
@decorators.idempotent_id('698ba406-493f-4c69-a093-273676fed438')
@tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
diff --git a/manila_tempest_tests/tests/api/test_metadata_negative.py b/manila_tempest_tests/tests/api/test_metadata_negative.py
index a34d1a6..93a3628 100644
--- a/manila_tempest_tests/tests/api/test_metadata_negative.py
+++ b/manila_tempest_tests/tests/api/test_metadata_negative.py
@@ -113,20 +113,3 @@
self.assertRaises(lib_exc.NotFound,
self.shares_client.delete_metadata,
self.share["id"], "wrong_key")
-
- @decorators.idempotent_id('c6c70d55-7ed0-439f-ae34-f19af55361f6')
- @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
- @ddt.data(("foo.xml", False), ("foo.json", False),
- ("foo.xml", True), ("foo.json", True))
- @ddt.unpack
- def test_try_delete_metadata_with_unsupport_format_key(
- self, key, is_v2_client):
- md = {key: u"value.test"}
-
- client = self.shares_v2_client if is_v2_client else self.shares_client
- # set metadata
- client.set_metadata(self.share["id"], md)
-
- self.assertRaises(lib_exc.NotFound,
- client.delete_metadata,
- self.share["id"], key)
diff --git a/manila_tempest_tests/tests/api/test_replication_negative.py b/manila_tempest_tests/tests/api/test_replication_negative.py
index 90c52c7..e7d0e7d 100644
--- a/manila_tempest_tests/tests/api/test_replication_negative.py
+++ b/manila_tempest_tests/tests/api/test_replication_negative.py
@@ -137,6 +137,7 @@
self.shares_v2_client.delete_share,
self.share1["id"])
+ @decorators.unstable_test(bug='1631314')
@decorators.idempotent_id('b9c2e57b-f1ae-475c-9d0b-df75dbe93b61')
@tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
def test_promote_out_of_sync_share_replica(self):
diff --git a/manila_tempest_tests/tests/api/test_security_services.py b/manila_tempest_tests/tests/api/test_security_services.py
index 5bfbc2e..24d8bad 100644
--- a/manila_tempest_tests/tests/api/test_security_services.py
+++ b/manila_tempest_tests/tests/api/test_security_services.py
@@ -15,7 +15,6 @@
import ddt
from oslo_log import log
-import six
from tempest import config
from tempest.lib import decorators
import testtools
@@ -252,7 +251,7 @@
LOG.warning("Caught exception. It is expected in case backend "
"fails having security-service with improper data "
"that leads to share-server creation error. "
- "%s", six.text_type(e))
+ "%s", str(e))
update_data = {
"name": "name",
diff --git a/manila_tempest_tests/tests/api/test_security_services_mapping_negative.py b/manila_tempest_tests/tests/api/test_security_services_mapping_negative.py
index 9aaf20b..d0bb321 100644
--- a/manila_tempest_tests/tests/api/test_security_services_mapping_negative.py
+++ b/manila_tempest_tests/tests/api/test_security_services_mapping_negative.py
@@ -14,7 +14,6 @@
# under the License.
from oslo_log import log
-import six
from tempest import config
from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
@@ -136,7 +135,7 @@
LOG.warning("Caught exception. It is expected in case backend "
"fails having security-service with improper data "
"that leads to share-server creation error. "
- "%s", six.text_type(e))
+ "%s", str(e))
self.assertRaises(lib_exc.Forbidden,
self.cl.remove_sec_service_from_share_network,
diff --git a/manila_tempest_tests/tests/api/test_security_services_negative.py b/manila_tempest_tests/tests/api/test_security_services_negative.py
index 3895fa9..08e3c7b 100644
--- a/manila_tempest_tests/tests/api/test_security_services_negative.py
+++ b/manila_tempest_tests/tests/api/test_security_services_negative.py
@@ -14,7 +14,6 @@
# under the License.
from oslo_log import log
-import six
from tempest import config
from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
@@ -120,7 +119,7 @@
LOG.warning("Caught exception. It is expected in case backend "
"fails having security-service with improper data "
"that leads to share-server creation error. "
- "%s", six.text_type(e))
+ "%s", str(e))
self.assertRaises(lib_exc.Forbidden,
self.shares_client.update_security_service,
diff --git a/manila_tempest_tests/tests/api/test_share_networks.py b/manila_tempest_tests/tests/api/test_share_networks.py
index bd45ed1..e3d5a78 100644
--- a/manila_tempest_tests/tests/api/test_share_networks.py
+++ b/manila_tempest_tests/tests/api/test_share_networks.py
@@ -298,41 +298,14 @@
sn2 = self.create_share_network(**data)
self.assertDictContainsSubset(data, sn2)
- @decorators.idempotent_id('50bac743-7ca9-409b-827f-f277da67e32e')
- @testtools.skipUnless(CONF.share.create_networks_when_multitenancy_enabled,
- "Only for setups with network creation.")
- @testtools.skipUnless(CONF.share.multitenancy_enabled,
- "Only for multitenancy.")
- @testtools.skipUnless(CONF.service_available.neutron, "Only with neutron.")
- @utils.skip_if_microversion_not_supported("2.18")
- @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
- def test_gateway_with_neutron(self):
- subnet_client = self.subnets_client
-
- self.create_share(share_type_id=self.share_type_id,
- cleanup_in_class=False)
- share_net_details = self.shares_v2_client.get_share_network(
- self.shares_v2_client.share_network_id)['share_network']
- share_net_info = (
- utils.share_network_get_default_subnet(share_net_details)
- if utils.share_network_subnets_are_supported()
- else share_net_details)
- subnet_details = subnet_client.show_subnet(
- share_net_info['neutron_subnet_id'])
- self.assertEqual(subnet_details['subnet']['gateway_ip'],
- share_net_info['gateway'])
-
@decorators.idempotent_id('2dbf91da-04ae-4f9f-a7b9-0299c6b2e02c')
@testtools.skipUnless(CONF.share.create_networks_when_multitenancy_enabled,
"Only for setups with network creation.")
@testtools.skipUnless(CONF.share.multitenancy_enabled,
"Only for multitenancy.")
@testtools.skipUnless(CONF.service_available.neutron, "Only with neutron.")
- @utils.skip_if_microversion_not_supported("2.20")
@tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
- def test_mtu_with_neutron(self):
- network_client = self.networks_client
-
+ def test_gateway_mtu_neutron_net_id_with_neutron(self):
self.create_share(share_type_id=self.share_type_id,
cleanup_in_class=False)
share_net_details = self.shares_v2_client.get_share_network(
@@ -341,8 +314,17 @@
utils.share_network_get_default_subnet(share_net_details)
if utils.share_network_subnets_are_supported()
else share_net_details)
- network_details = network_client.show_network(
- share_net_info['neutron_net_id'])
- self.assertEqual(network_details['network']['mtu'],
- share_net_info['mtu'])
+ if utils.is_microversion_supported('2.18'):
+ subnet_details = self.subnets_client.show_subnet(
+ share_net_info['neutron_subnet_id'])
+ self.assertEqual(subnet_details['subnet']['gateway_ip'],
+ share_net_info['gateway'])
+
+ if utils.is_microversion_supported('2.20'):
+ network_details = self.networks_client.show_network(
+ share_net_info['neutron_net_id'])
+ self.assertEqual(network_details['network']['mtu'],
+ share_net_info['mtu'])
+ self.assertEqual(network_details['network']['id'],
+ share_net_info['neutron_net_id'])
diff --git a/manila_tempest_tests/tests/api/test_shares_actions.py b/manila_tempest_tests/tests/api/test_shares_actions.py
index 4cdc70d..779bfb6 100644
--- a/manila_tempest_tests/tests/api/test_shares_actions.py
+++ b/manila_tempest_tests/tests/api/test_shares_actions.py
@@ -14,7 +14,6 @@
# under the License.
import ddt
-import six
from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
@@ -93,7 +92,7 @@
# get share
share = self.shares_v2_client.get_share(
- self.shares[0]['id'], version=six.text_type(version))['share']
+ self.shares[0]['id'], version=str(version))['share']
# verify keys
expected_keys = [
@@ -125,13 +124,13 @@
# verify values
msg = "Expected name: '%s', actual name: '%s'" % (self.share_name,
share["name"])
- self.assertEqual(self.share_name, six.text_type(share["name"]), msg)
+ self.assertEqual(self.share_name, str(share["name"]), msg)
msg = ("Expected description: '%s', "
"actual description: '%s'" % (self.share_desc,
share["description"]))
self.assertEqual(
- self.share_desc, six.text_type(share["description"]), msg)
+ self.share_desc, str(share["description"]), msg)
msg = "Expected size: '%s', actual size: '%s'" % (
CONF.share.share_size, share["size"])
@@ -211,7 +210,7 @@
# list shares
shares = self.shares_v2_client.list_shares_with_detail(
- version=six.text_type(version))['shares']
+ version=str(version))['shares']
# verify keys
keys = [
@@ -688,6 +687,51 @@
)
self.assertEqual(new_size, share_get['size'], msg)
+ @utils.skip_if_microversion_not_supported("2.69")
+ @decorators.idempotent_id('7a19fb58-b645-44cc-a6d7-b3508ff8754d')
+ @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
+ def test_soft_delete_and_restore_share(self):
+ share = self.create_share(share_type_id=self.share_type_id)
+
+ # list shares
+ shares = self.shares_v2_client.list_shares()['shares']
+
+ # check the share in share list
+ share_ids = [sh['id'] for sh in shares]
+ self.assertIn(share['id'], share_ids)
+
+ # soft delete the share
+ self.shares_v2_client.soft_delete_share(share['id'])
+ waiters.wait_for_soft_delete(self.shares_v2_client, share['id'])
+
+ # list shares again
+ shares1 = self.shares_v2_client.list_shares()['shares']
+ share_ids1 = [sh['id'] for sh in shares1]
+
+ # list shares in recycle bin
+ shares2 = self.shares_v2_client.list_shares_in_recycle_bin()['shares']
+ share_ids2 = [sh['id'] for sh in shares2]
+
+ # check share has been soft delete to recycle bin
+ self.assertNotIn(share['id'], share_ids1)
+ self.assertIn(share['id'], share_ids2)
+
+ # restore share from recycle bin
+ self.shares_v2_client.restore_share(share['id'])
+ waiters.wait_for_restore(self.shares_v2_client, share['id'])
+
+ # list shares again
+ shares3 = self.shares_v2_client.list_shares()['shares']
+ share_ids3 = [sh['id'] for sh in shares3]
+
+ # list shares in recycle bin again
+ shares4 = self.shares_v2_client.list_shares_in_recycle_bin()['shares']
+ share_ids4 = [sh['id'] for sh in shares4]
+
+ # check share has restored from recycle bin
+ self.assertNotIn(share['id'], share_ids4)
+ self.assertIn(share['id'], share_ids3)
+
class SharesRenameTest(base.BaseSharesMixedTest):
diff --git a/manila_tempest_tests/tests/api/test_shares_actions_negative.py b/manila_tempest_tests/tests/api/test_shares_actions_negative.py
index dfd92a8..a600b8e 100644
--- a/manila_tempest_tests/tests/api/test_shares_actions_negative.py
+++ b/manila_tempest_tests/tests/api/test_shares_actions_negative.py
@@ -21,6 +21,7 @@
import testtools
from testtools import testcase as tc
+from manila_tempest_tests.common import waiters
from manila_tempest_tests.tests.api import base
from manila_tempest_tests import utils
@@ -121,6 +122,20 @@
share['id'],
new_size)
+ @decorators.idempotent_id('f9d2ba94-4032-d17a-b4ab-a2b67f650a39')
+ @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
+ @utils.skip_if_microversion_not_supported("2.64")
+ @testtools.skipUnless(
+ CONF.share.run_extend_tests,
+ "Share extend tests are disabled.")
+ def test_share_force_extend_non_admin_user(self):
+ # only admin cloud force extend share with micversion >= 2.64
+ # non-admin will get unauthorized error.
+ new_size = int(self.share['size']) + 1
+ self.assertRaises(lib_exc.Forbidden,
+ self.shares_v2_client.extend_share, self.share['id'],
+ new_size, force=True)
+
@decorators.idempotent_id('99d42f94-8da1-4c04-ad5b-9738d6acc139')
@tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
@testtools.skipUnless(
@@ -280,3 +295,68 @@
self.assertRaises(lib_exc.NotFound,
self.alt_shares_v2_client.get_share,
self.share['id'])
+
+ @utils.skip_if_microversion_not_supported("2.69")
+ @decorators.idempotent_id('36cbe23b-08d2-49d9-bb42-f9eb2a804cb1')
+ @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
+ def test_soft_delete_share_has_been_soft_deleted(self):
+ share = self.create_share(share_type_id=self.share_type_id,
+ cleanup_in_class=False)
+
+ # soft delete the share
+ self.shares_v2_client.soft_delete_share(share['id'])
+
+ # try soft delete the share again
+ self.assertRaises(lib_exc.Forbidden,
+ self.shares_v2_client.soft_delete_share,
+ share['id'])
+
+ # restore the share for resource_cleanup
+ self.shares_v2_client.restore_share(share['id'])
+ waiters.wait_for_restore(self.shares_v2_client, share['id'])
+
+ @utils.skip_if_microversion_not_supported("2.69")
+ @decorators.idempotent_id('cf675ac9-0970-49fc-a051-8a94555c73b5')
+ @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
+ def test_soft_delete_share_with_invalid_share_state(self):
+ share = self.create_share(share_type_id=self.share_type_id,
+ cleanup_in_class=False)
+
+ # set "error_deleting" state
+ self.admin_client.reset_state(share['id'], status="error_deleting")
+
+ # try soft delete the share
+ self.assertRaises(lib_exc.Forbidden,
+ self.shares_v2_client.soft_delete_share,
+ share['id'])
+
+ # rollback to available status
+ self.admin_client.reset_state(share['id'], status="available")
+
+ @utils.skip_if_microversion_not_supported("2.69")
+ @decorators.idempotent_id('f6106ee4-1a01-444f-b623-912a5e751d49')
+ @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
+ def test_soft_delete_share_from_other_project(self):
+ share = self.create_share(share_type_id=self.share_type_id,
+ cleanup_in_class=False)
+
+ # try soft delete the share
+ self.assertRaises(lib_exc.Forbidden,
+ self.alt_shares_v2_client.soft_delete_share,
+ share['id'])
+
+ @utils.skip_if_microversion_not_supported("2.69")
+ @decorators.idempotent_id('0ccd44dd-2fda-403e-bc23-7ce428550f36')
+ @tc.attr(base.TAG_NEGATIVE, base.TAG_API)
+ def test_soft_delete_share_with_wrong_id(self):
+ self.assertRaises(lib_exc.NotFound,
+ self.shares_v2_client.soft_delete_share,
+ "wrong_share_id")
+
+ @utils.skip_if_microversion_not_supported("2.69")
+ @decorators.idempotent_id('87345725-f187-4d7d-86b1-62284e8c75ae')
+ @tc.attr(base.TAG_NEGATIVE, base.TAG_API)
+ def test_restore_share_with_wrong_id(self):
+ self.assertRaises(lib_exc.NotFound,
+ self.shares_v2_client.restore_share,
+ "wrong_share_id")
diff --git a/manila_tempest_tests/tests/api/test_snapshot_rules.py b/manila_tempest_tests/tests/api/test_snapshot_rules.py
index 541e861..74d5221 100644
--- a/manila_tempest_tests/tests/api/test_snapshot_rules.py
+++ b/manila_tempest_tests/tests/api/test_snapshot_rules.py
@@ -14,7 +14,6 @@
# under the License.
import ddt
-import six
from tempest import config
from tempest.lib import decorators
from testtools import testcase as tc
@@ -54,7 +53,7 @@
access_to)['snapshot_access']
for key in ('deleted', 'deleted_at', 'instance_mappings'):
- self.assertNotIn(key, list(six.iterkeys(rule)))
+ self.assertNotIn(key, list(rule.keys()))
waiters.wait_for_resource_status(
self.shares_v2_client, self.snapshot['id'], 'active',
diff --git a/manila_tempest_tests/tests/scenario/manager.py b/manila_tempest_tests/tests/scenario/manager.py
index 1fa03f4..947d0e6 100644
--- a/manila_tempest_tests/tests/scenario/manager.py
+++ b/manila_tempest_tests/tests/scenario/manager.py
@@ -20,7 +20,6 @@
from oslo_log import log
from oslo_utils import netutils
from oslo_utils import uuidutils
-import six
from tempest.common import compute
from tempest.common import image as common_image
from tempest.common.utils.linux import remote_client
@@ -630,7 +629,7 @@
try:
return subnets_client.create_subnet(**subnet)
except lib_exc.Conflict as e:
- if 'overlaps with another subnet' not in six.text_type(e):
+ if 'overlaps with another subnet' not in str(e):
raise
result = None
diff --git a/manila_tempest_tests/tests/scenario/manager_share.py b/manila_tempest_tests/tests/scenario/manager_share.py
index d68ab04..657b1f1 100644
--- a/manila_tempest_tests/tests/scenario/manager_share.py
+++ b/manila_tempest_tests/tests/scenario/manager_share.py
@@ -14,10 +14,9 @@
# under the License.
from tempfile import mkstemp
+from urllib.request import urlopen
from oslo_log import log
-import six
-from six.moves.urllib.request import urlopen
from tempest.common import waiters
from tempest import config
from tempest.lib.common.utils import data_utils
@@ -288,7 +287,7 @@
# original implementation depends on CONF.compute.ssh_auth_method
# option.
server_or_ip = kwargs['server_or_ip']
- if isinstance(server_or_ip, six.string_types):
+ if isinstance(server_or_ip, str):
ip = server_or_ip
else:
addr = server_or_ip['addresses'][
diff --git a/manila_tempest_tests/tests/scenario/test_share_extend.py b/manila_tempest_tests/tests/scenario/test_share_extend.py
index f4dce61..595ddd4 100644
--- a/manila_tempest_tests/tests/scenario/test_share_extend.py
+++ b/manila_tempest_tests/tests/scenario/test_share_extend.py
@@ -13,7 +13,6 @@
import ddt
from oslo_log import log as logging
from oslo_utils import units
-import six
from tempest import config
from tempest.lib import decorators
from tempest.lib import exceptions
@@ -133,7 +132,7 @@
block_count,
'/dev/urandom')
except exceptions.SSHExecCommandFailed as e:
- if 'stale file handle' in six.text_type(e).lower():
+ if 'stale file handle' in str(e).lower():
LOG.warning("Client was disconnected during extend process")
self.unmount_share(remote_client)
self.mount_share(mount_location, remote_client)
@@ -151,7 +150,12 @@
class TestShareExtendCIFS(manager.BaseShareScenarioCIFSTest, ShareExtendBase):
- pass
+
+ @decorators.idempotent_id('4a9f5cf9-990d-4a35-9ac7-87ef593a09e3')
+ @decorators.unstable_test(bug='1903922')
+ @tc.attr(base.TAG_POSITIVE, base.TAG_BACKEND)
+ def test_create_extend_and_write(self):
+ super(TestShareExtendCIFS, self).test_create_extend_and_write()
class TestBaseShareExtendScenarioCEPHFS(manager.BaseShareScenarioCEPHFSTest,
diff --git a/manila_tempest_tests/tests/scenario/test_share_shrink.py b/manila_tempest_tests/tests/scenario/test_share_shrink.py
index b4bfcd5..a4e59e8 100644
--- a/manila_tempest_tests/tests/scenario/test_share_shrink.py
+++ b/manila_tempest_tests/tests/scenario/test_share_shrink.py
@@ -13,7 +13,6 @@
import time
from oslo_log import log as logging
-import six
from tempest import config
from tempest.lib import decorators
from tempest.lib import exceptions
@@ -146,7 +145,7 @@
new_size=new_size)
except exceptions.BadRequest as e:
if ('New size for shrink must be less than current size'
- in six.text_type(e)):
+ in str(e)):
break
time.sleep(check_interval)
diff --git a/manila_tempest_tests/utils.py b/manila_tempest_tests/utils.py
index 7625460..d0860f0 100644
--- a/manila_tempest_tests/utils.py
+++ b/manila_tempest_tests/utils.py
@@ -18,7 +18,6 @@
import re
from netaddr import ip
-import six
from tempest import config
import testtools
@@ -110,12 +109,12 @@
conflicts in real-world testing.
"""
test_net_3 = '203.0.113.'
- address = test_net_3 + six.text_type(random.randint(0, 255))
+ address = test_net_3 + str(random.randint(0, 255))
if network:
- mask_length = six.text_type(random.randint(24, 32))
+ mask_length = str(random.randint(24, 32))
address = '/'.join((address, mask_length))
ip_network = ip.IPNetwork(address)
- return '/'.join((six.text_type(ip_network.network), mask_length))
+ return '/'.join((str(ip_network.network), mask_length))
return address
@@ -124,10 +123,10 @@
ran_add = ["%x" % random.randrange(0, 16 ** 4) for i in range(6)]
address = "2001:0DB8:" + ":".join(ran_add)
if network:
- mask_length = six.text_type(random.randint(32, 128))
+ mask_length = str(random.randint(32, 128))
address = '/'.join((address, mask_length))
ip_network = ip.IPNetwork(address)
- return '/'.join((six.text_type(ip_network.network), mask_length))
+ return '/'.join((str(ip_network.network), mask_length))
return address
@@ -135,8 +134,8 @@
extra_specs = {}
# fix extra specs with string values instead of boolean
for k, v in share_type['extra_specs'].items():
- extra_specs[k] = (True if six.text_type(v).lower() == 'true'
- else False if six.text_type(v).lower() == 'false'
+ extra_specs[k] = (True if str(v).lower() == 'true'
+ else False if str(v).lower() == 'false'
else v)
selected_pool = next(
(x for x in pools if (x['name'] != share['host'] and all(
diff --git a/releasenotes/notes/bug-1631314-1509db08c75ff645.yaml b/releasenotes/notes/bug-1631314-1509db08c75ff645.yaml
new file mode 100644
index 0000000..601ff57
--- /dev/null
+++ b/releasenotes/notes/bug-1631314-1509db08c75ff645.yaml
@@ -0,0 +1,5 @@
+---
+fixes:
+ - |
+ `Bug #1631314 <https://bugs.launchpad.net/manila/+bug/1631314>`_:
+ Fixed an issue on unstable replication tests.
diff --git a/zuul.d/manila-tempest-jobs.yaml b/zuul.d/manila-tempest-jobs.yaml
index f31ff11..494b285 100644
--- a/zuul.d/manila-tempest-jobs.yaml
+++ b/zuul.d/manila-tempest-jobs.yaml
@@ -60,6 +60,8 @@
required-projects: *manila-tempest-required-projects
vars:
<<: *manila-tempest-base-vars
+ # NOTE(gouthamr): Disabled until https://launchpad.net/bugs/1940324 is
+ # fixed.
tempest_exclude_regex: "(^manila_tempest_tests.tests.scenario.*IPv6.*)"
- job:
diff --git a/zuul.d/manila-tempest-stable-jobs.yaml b/zuul.d/manila-tempest-stable-jobs.yaml
index ff74f5d..3d2447e 100644
--- a/zuul.d/manila-tempest-stable-jobs.yaml
+++ b/zuul.d/manila-tempest-stable-jobs.yaml
@@ -1,6 +1,16 @@
# Stable branch jobs to test the trunk version of manila-tempest-plugin against
# released stable branches of manila
- job:
+ name: manila-tempest-plugin-lvm-xena
+ parent: manila-tempest-plugin-lvm
+ override-checkout: stable/xena
+ nodeset: openstack-single-node-focal
+ vars:
+ # NOTE(gouthamr): Disabled until https://launchpad.net/bugs/1940324 is
+ # fixed.
+ tempest_exclude_regex: "(^manila_tempest_tests.tests.scenario.*IPv6.*)"
+
+- job:
name: manila-tempest-plugin-lvm-wallaby
parent: manila-tempest-plugin-lvm
override-checkout: stable/wallaby
@@ -15,11 +25,3 @@
nodeset: openstack-single-node-focal
vars:
tempest_exclude_regex: ''
-
-- job:
- name: manila-tempest-plugin-lvm-ussuri
- parent: manila-tempest-plugin-lvm
- override-checkout: stable/ussuri
- nodeset: openstack-single-node-bionic
- vars:
- tempest_exclude_regex: ''
diff --git a/zuul.d/project.yaml b/zuul.d/project.yaml
index bfeaa7b..ce21547 100644
--- a/zuul.d/project.yaml
+++ b/zuul.d/project.yaml
@@ -7,9 +7,9 @@
- manila-tempest-plugin-dummy-no-dhss
- manila-tempest-plugin-dummy-dhss
- manila-tempest-plugin-lvm
+ - manila-tempest-plugin-lvm-xena
- manila-tempest-plugin-lvm-wallaby
- manila-tempest-plugin-lvm-victoria
- - manila-tempest-plugin-lvm-ussuri
- manila-tempest-plugin-zfsonlinux:
voting: false
- manila-tempest-plugin-cephfs-native: