Merge "Preparation for support scenario tests on CephFS Native"
This commit is contained in:
commit
3a71fb7e86
|
@ -124,6 +124,9 @@ class ShareScenarioTest(manager.NetworkScenarioTest):
|
|||
def mount_share(self, location, remote_client, target_dir=None):
|
||||
raise NotImplementedError
|
||||
|
||||
def allow_access(self, **kwargs):
|
||||
raise NotImplementedError
|
||||
|
||||
def unmount_share(self, remote_client, target_dir=None):
|
||||
target_dir = target_dir or "/mnt"
|
||||
remote_client.exec_command("sudo umount %s" % target_dir)
|
||||
|
@ -347,6 +350,54 @@ class ShareScenarioTest(manager.NetworkScenarioTest):
|
|||
share['id'], instance=instance, cleanup=False,
|
||||
snapshot=snapshot, access_level=access_level, client=client)
|
||||
|
||||
def provide_access_to_client_identified_by_cephx(self, share=None,
|
||||
access_level='rw',
|
||||
access_to=None,
|
||||
remote_client=None,
|
||||
locations=None,
|
||||
client=None,
|
||||
oc_size=20971520):
|
||||
share = share or self.share
|
||||
client = client or self.shares_v2_client
|
||||
access_to = access_to or data_utils.rand_name(
|
||||
self.__class__.__name__ + '-cephx-id')
|
||||
# Check if access is already granted to the client
|
||||
access = self.shares_v2_client.list_access_rules(
|
||||
share['id'], metadata={'metadata': {'access_to': access_to}})
|
||||
access = access[0] if access else None
|
||||
|
||||
if not access:
|
||||
access = self._allow_access(
|
||||
share['id'], access_level=access_level, access_to=access_to,
|
||||
access_type="cephx", cleanup=False, client=client)
|
||||
# Set metadata to access rule to be filtered if necessary.
|
||||
# This is necessary to prevent granting access to a client who
|
||||
# already has.
|
||||
self.shares_v2_client.update_access_metadata(
|
||||
metadata={"access_to": "{}".format(access_to)},
|
||||
access_id=access['id'])
|
||||
get_access = self.shares_v2_client.get_access(access['id'])
|
||||
# Set 'access_key' and 'access_to' attributes for being use in mount
|
||||
# operation.
|
||||
setattr(self, 'access_key', get_access['access_key'])
|
||||
setattr(self, 'access_to', access_to)
|
||||
|
||||
remote_client.exec_command(
|
||||
"sudo crudini --set {access_to}.keyring client.{access_to} key "
|
||||
"{access_key}"
|
||||
.format(access_to=access_to, access_key=self.access_key))
|
||||
remote_client.exec_command(
|
||||
"sudo crudini --set ceph.conf client \"client quota\" true")
|
||||
remote_client.exec_command(
|
||||
"sudo crudini --set ceph.conf client \"client oc size\" {}"
|
||||
.format(oc_size))
|
||||
if not isinstance(locations, list):
|
||||
locations = [locations]
|
||||
remote_client.exec_command(
|
||||
"sudo crudini --set ceph.conf client \"mon host\" {}"
|
||||
.format(locations[0].split(':/')[0]))
|
||||
return access
|
||||
|
||||
def wait_for_active_instance(self, instance_id):
|
||||
waiters.wait_for_server_status(
|
||||
self.os_primary.servers_client, instance_id, "ACTIVE")
|
||||
|
@ -598,9 +649,10 @@ class ShareScenarioTest(manager.NetworkScenarioTest):
|
|||
locations = self._get_snapshot_export_locations(snapshot)
|
||||
|
||||
self.assertNotEmpty(locations)
|
||||
locations = self._get_export_locations_according_to_ip_version(
|
||||
locations, error_on_invalid_ip_version)
|
||||
self.assertNotEmpty(locations)
|
||||
if self.protocol != 'cephfs':
|
||||
locations = self._get_export_locations_according_to_ip_version(
|
||||
locations, error_on_invalid_ip_version)
|
||||
self.assertNotEmpty(locations)
|
||||
|
||||
return locations
|
||||
|
||||
|
@ -630,3 +682,39 @@ class ShareScenarioTest(manager.NetworkScenarioTest):
|
|||
message = ("Protocol %s is not supported" % self.protocol)
|
||||
raise self.skipException(message)
|
||||
return ip, version
|
||||
|
||||
|
||||
class BaseShareCEPHFSTest(ShareScenarioTest):
|
||||
|
||||
def allow_access(self, access_level='rw', **kwargs):
|
||||
return self.provide_access_to_client_identified_by_cephx(
|
||||
remote_client=kwargs['remote_client'],
|
||||
locations=kwargs['locations'], access_level=access_level)
|
||||
|
||||
def _fuse_client(self, mountpoint, remote_client, target_dir, access_to):
|
||||
remote_client.exec_command(
|
||||
"sudo ceph-fuse {target_dir} --id={access_to} --conf=ceph.conf "
|
||||
"--keyring={access_to}.keyring --client-mountpoint={mountpoint}"
|
||||
.format(target_dir=target_dir, access_to=access_to,
|
||||
mountpoint=mountpoint))
|
||||
|
||||
def mount_share(self, location, remote_client, target_dir=None,
|
||||
access_to=None):
|
||||
target_dir = target_dir or "/mnt"
|
||||
access_to = access_to or self.access_to
|
||||
mountpoint = location.split(':')[-1]
|
||||
if getattr(self, 'mount_client', None):
|
||||
return self._fuse_client(mountpoint, remote_client, target_dir,
|
||||
access_to=access_to)
|
||||
remote_client.exec_command(
|
||||
"sudo mount -t ceph {location} {target_dir} -o name={access_to},"
|
||||
"secret={access_key}"
|
||||
.format(location=location, target_dir=target_dir,
|
||||
access_to=access_to, access_key=self.access_key))
|
||||
|
||||
def unmount_share(self, remote_client, target_dir=None):
|
||||
target_dir = target_dir or "/mnt"
|
||||
if getattr(self, 'mount_client', None):
|
||||
return remote_client.exec_command(
|
||||
"sudo fusermount -uz %s" % target_dir)
|
||||
super(BaseShareCEPHFSTest, self).unmount_share(remote_client)
|
||||
|
|
|
@ -44,14 +44,6 @@ class ShareBasicOpsBase(manager.ShareScenarioTest):
|
|||
* Terminate the instance
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def skip_checks(cls):
|
||||
super(ShareBasicOpsBase, cls).skip_checks()
|
||||
if cls.protocol not in CONF.share.enable_ip_rules_for_protocols:
|
||||
message = ("%s tests for access rules other than IP are disabled" %
|
||||
cls.protocol)
|
||||
raise cls.skipException(message)
|
||||
|
||||
def _ping_host_from_export_location(self, export, remote_client):
|
||||
ip, version = self.get_ip_and_version_from_export_location(export)
|
||||
if version == 6:
|
||||
|
@ -66,7 +58,8 @@ class ShareBasicOpsBase(manager.ShareScenarioTest):
|
|||
locations = self.get_user_export_locations(self.share)
|
||||
instance = self.wait_for_active_instance(instance["id"])
|
||||
remote_client = self.init_remote_client(instance)
|
||||
self.provide_access_to_auxiliary_instance(instance)
|
||||
self.allow_access(instance=instance, remote_client=remote_client,
|
||||
locations=locations)
|
||||
|
||||
for location in locations:
|
||||
self.mount_share(location, remote_client)
|
||||
|
@ -85,12 +78,17 @@ class ShareBasicOpsBase(manager.ShareScenarioTest):
|
|||
remote_client_inst = self.init_remote_client(instance)
|
||||
|
||||
# First, check if write works RW access.
|
||||
acc_rule_id = self.provide_access_to_auxiliary_instance(instance)['id']
|
||||
acc_rule_id = self.allow_access(
|
||||
instance=instance, remote_client=remote_client_inst,
|
||||
locations=location)['id']
|
||||
|
||||
self.mount_share(location, remote_client_inst)
|
||||
self.write_data_to_mounted_share(test_data, remote_client_inst)
|
||||
self.deny_access(self.share['id'], acc_rule_id)
|
||||
|
||||
self.provide_access_to_auxiliary_instance(instance, access_level='ro')
|
||||
self.allow_access(instance=instance, remote_client=remote_client_inst,
|
||||
locations=location, access_level='ro')
|
||||
|
||||
self.addCleanup(self.unmount_share, remote_client_inst)
|
||||
|
||||
# Test if write with RO access fails.
|
||||
|
@ -113,7 +111,9 @@ class ShareBasicOpsBase(manager.ShareScenarioTest):
|
|||
|
||||
# Write data to first VM
|
||||
remote_client_inst1 = self.init_remote_client(instance1)
|
||||
self.provide_access_to_auxiliary_instance(instance1)
|
||||
self.allow_access(instance=instance1,
|
||||
remote_client=remote_client_inst1,
|
||||
locations=location)
|
||||
|
||||
self.mount_share(location, remote_client_inst1)
|
||||
self.addCleanup(self.unmount_share,
|
||||
|
@ -123,7 +123,9 @@ class ShareBasicOpsBase(manager.ShareScenarioTest):
|
|||
# Read from second VM
|
||||
remote_client_inst2 = self.init_remote_client(instance2)
|
||||
if not CONF.share.override_ip_for_nfs_access or self.ipv6_enabled:
|
||||
self.provide_access_to_auxiliary_instance(instance2)
|
||||
self.allow_access(instance=instance2,
|
||||
remote_client=remote_client_inst2,
|
||||
locations=location)
|
||||
|
||||
self.mount_share(location, remote_client_inst2)
|
||||
self.addCleanup(self.unmount_share,
|
||||
|
@ -387,6 +389,18 @@ class ShareBasicOpsBase(manager.ShareScenarioTest):
|
|||
class TestShareBasicOpsNFS(ShareBasicOpsBase):
|
||||
protocol = "nfs"
|
||||
|
||||
@classmethod
|
||||
def skip_checks(cls):
|
||||
super(TestShareBasicOpsNFS, cls).skip_checks()
|
||||
if cls.protocol not in CONF.share.enable_ip_rules_for_protocols:
|
||||
message = ("%s tests for access rules other than IP are disabled" %
|
||||
cls.protocol)
|
||||
raise cls.skipException(message)
|
||||
|
||||
def allow_access(self, access_level='rw', **kwargs):
|
||||
return self.provide_access_to_auxiliary_instance(
|
||||
instance=kwargs['instance'], access_level=access_level)
|
||||
|
||||
def mount_share(self, location, remote_client, target_dir=None):
|
||||
|
||||
self._ping_host_from_export_location(location, remote_client)
|
||||
|
@ -399,6 +413,18 @@ class TestShareBasicOpsNFS(ShareBasicOpsBase):
|
|||
class TestShareBasicOpsCIFS(ShareBasicOpsBase):
|
||||
protocol = "cifs"
|
||||
|
||||
@classmethod
|
||||
def skip_checks(cls):
|
||||
super(TestShareBasicOpsCIFS, cls).skip_checks()
|
||||
if cls.protocol not in CONF.share.enable_ip_rules_for_protocols:
|
||||
message = ("%s tests for access rules other than IP are disabled" %
|
||||
cls.protocol)
|
||||
raise cls.skipException(message)
|
||||
|
||||
def allow_access(self, access_level='rw', **kwargs):
|
||||
return self.provide_access_to_auxiliary_instance(
|
||||
instance=kwargs['instance'], access_level=access_level)
|
||||
|
||||
def mount_share(self, location, remote_client, target_dir=None):
|
||||
|
||||
self._ping_host_from_export_location(location, remote_client)
|
||||
|
@ -426,6 +452,25 @@ class TestShareBasicOpsCIFS(ShareBasicOpsBase):
|
|||
raise self.skipException(msg)
|
||||
|
||||
|
||||
class TestShareBasicOpsCEPHFS(ShareBasicOpsBase, manager.BaseShareCEPHFSTest):
|
||||
protocol = "cephfs"
|
||||
|
||||
@tc.attr(base.TAG_POSITIVE, base.TAG_BACKEND)
|
||||
def test_mount_share_one_vm_with_ceph_fuse_client(self):
|
||||
self.mount_client = 'fuse'
|
||||
super(TestShareBasicOpsCEPHFS, self).test_mount_share_one_vm()
|
||||
|
||||
@tc.attr(base.TAG_POSITIVE, base.TAG_BACKEND)
|
||||
def test_write_with_ro_access_with_ceph_fuse_client(self):
|
||||
self.mount_client = 'fuse'
|
||||
super(TestShareBasicOpsCEPHFS, self).test_write_with_ro_access()
|
||||
|
||||
@tc.attr(base.TAG_POSITIVE, base.TAG_BACKEND)
|
||||
def test_read_write_two_vms_with_ceph_fuse_client(self):
|
||||
self.mount_client = 'fuse'
|
||||
super(TestShareBasicOpsCEPHFS, self).test_read_write_two_vms()
|
||||
|
||||
|
||||
class TestShareBasicOpsNFSIPv6(TestShareBasicOpsNFS):
|
||||
ip_version = 6
|
||||
|
||||
|
|
|
@ -45,14 +45,6 @@ class ShareExtendBase(manager.ShareScenarioTest):
|
|||
* Terminate the instance
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def skip_checks(cls):
|
||||
super(ShareExtendBase, cls).skip_checks()
|
||||
if cls.protocol not in CONF.share.enable_ip_rules_for_protocols:
|
||||
message = ("%s tests for access rules other than IP are disabled" %
|
||||
cls.protocol)
|
||||
raise cls.skipException(message)
|
||||
|
||||
@tc.attr(base.TAG_POSITIVE, base.TAG_BACKEND)
|
||||
def test_create_extend_and_write(self):
|
||||
default_share_size = CONF.share.share_size
|
||||
|
@ -69,10 +61,11 @@ class ShareExtendBase(manager.ShareScenarioTest):
|
|||
remote_client = self.init_remote_client(instance)
|
||||
|
||||
LOG.debug('Step 4 - grant access')
|
||||
self.provide_access_to_auxiliary_instance(instance, share=share)
|
||||
location = self.get_share_export_location_for_mount(share)
|
||||
self.allow_access(instance=instance, remote_client=remote_client,
|
||||
locations=location)
|
||||
|
||||
LOG.debug('Step 5 - mount')
|
||||
location = self.get_share_export_location_for_mount(share)
|
||||
self.mount_share(location, remote_client)
|
||||
|
||||
total_blocks = (units.Ki * default_share_size) / 64
|
||||
|
@ -153,6 +146,18 @@ class ShareExtendBase(manager.ShareScenarioTest):
|
|||
class TestShareExtendNFS(ShareExtendBase):
|
||||
protocol = "nfs"
|
||||
|
||||
@classmethod
|
||||
def skip_checks(cls):
|
||||
super(ShareExtendBase, cls).skip_checks()
|
||||
if cls.protocol not in CONF.share.enable_ip_rules_for_protocols:
|
||||
message = ("%s tests for access rules other than IP are disabled" %
|
||||
cls.protocol)
|
||||
raise cls.skipException(message)
|
||||
|
||||
def allow_access(self, access_level='rw', **kwargs):
|
||||
return self.provide_access_to_auxiliary_instance(
|
||||
instance=kwargs['instance'], access_level=access_level)
|
||||
|
||||
def mount_share(self, location, remote_client, target_dir=None):
|
||||
target_dir = target_dir or "/mnt"
|
||||
remote_client.exec_command(
|
||||
|
@ -163,6 +168,18 @@ class TestShareExtendNFS(ShareExtendBase):
|
|||
class TestShareExtendCIFS(ShareExtendBase):
|
||||
protocol = "cifs"
|
||||
|
||||
@classmethod
|
||||
def skip_checks(cls):
|
||||
super(ShareExtendBase, cls).skip_checks()
|
||||
if cls.protocol not in CONF.share.enable_ip_rules_for_protocols:
|
||||
message = ("%s tests for access rules other than IP are disabled" %
|
||||
cls.protocol)
|
||||
raise cls.skipException(message)
|
||||
|
||||
def allow_access(self, access_level='rw', **kwargs):
|
||||
return self.provide_access_to_auxiliary_instance(
|
||||
instance=kwargs['instance'], access_level=access_level)
|
||||
|
||||
def mount_share(self, location, remote_client, target_dir=None):
|
||||
location = location.replace("\\", "/")
|
||||
target_dir = target_dir or "/mnt"
|
||||
|
@ -171,6 +188,15 @@ class TestShareExtendCIFS(ShareExtendBase):
|
|||
)
|
||||
|
||||
|
||||
class TestShareExtendCEPHFS(ShareExtendBase, manager.BaseShareCEPHFSTest):
|
||||
protocol = "cephfs"
|
||||
|
||||
@tc.attr(base.TAG_POSITIVE, base.TAG_BACKEND)
|
||||
def test_create_extend_and_write_with_ceph_fuse_client(self):
|
||||
self.mount_client = 'fuse'
|
||||
super(TestShareExtendCEPHFS, self).test_create_extend_and_write()
|
||||
|
||||
|
||||
# NOTE(u_glide): this function is required to exclude ShareExtendBase
|
||||
# from executed test cases.
|
||||
# See: https://docs.python.org/3/library/unittest.html#load-tests-protocol
|
||||
|
|
|
@ -46,14 +46,6 @@ class ShareShrinkBase(manager.ShareScenarioTest):
|
|||
* Terminate the instance
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def skip_checks(cls):
|
||||
super(ShareShrinkBase, cls).skip_checks()
|
||||
if cls.protocol not in CONF.share.enable_ip_rules_for_protocols:
|
||||
message = ("%s tests for access rules other than IP are disabled" %
|
||||
cls.protocol)
|
||||
raise cls.skipException(message)
|
||||
|
||||
@tc.attr(base.TAG_POSITIVE, base.TAG_BACKEND)
|
||||
@testtools.skipUnless(
|
||||
CONF.share.run_shrink_tests, 'Shrink share tests are disabled.')
|
||||
|
@ -72,10 +64,11 @@ class ShareShrinkBase(manager.ShareScenarioTest):
|
|||
remote_client = self.init_remote_client(instance)
|
||||
|
||||
LOG.debug('Step 4 - grant access')
|
||||
self.provide_access_to_auxiliary_instance(instance)
|
||||
location = self.get_share_export_location_for_mount(share)
|
||||
self.allow_access(instance=instance, remote_client=remote_client,
|
||||
locations=location)
|
||||
|
||||
LOG.debug('Step 5 - mount')
|
||||
location = self.get_share_export_location_for_mount(share)
|
||||
self.mount_share(location, remote_client)
|
||||
|
||||
total_blocks = (1024 * default_share_size) / 64
|
||||
|
@ -167,6 +160,18 @@ class ShareShrinkBase(manager.ShareScenarioTest):
|
|||
class TestShareShrinkNFS(ShareShrinkBase):
|
||||
protocol = "nfs"
|
||||
|
||||
@classmethod
|
||||
def skip_checks(cls):
|
||||
super(ShareShrinkBase, cls).skip_checks()
|
||||
if cls.protocol not in CONF.share.enable_ip_rules_for_protocols:
|
||||
message = ("%s tests for access rules other than IP are disabled" %
|
||||
cls.protocol)
|
||||
raise cls.skipException(message)
|
||||
|
||||
def allow_access(self, access_level='rw', **kwargs):
|
||||
return self.provide_access_to_auxiliary_instance(
|
||||
instance=kwargs['instance'], access_level=access_level)
|
||||
|
||||
def mount_share(self, location, ssh_client, target_dir=None):
|
||||
target_dir = target_dir or "/mnt"
|
||||
ssh_client.exec_command(
|
||||
|
@ -177,6 +182,18 @@ class TestShareShrinkNFS(ShareShrinkBase):
|
|||
class TestShareShrinkCIFS(ShareShrinkBase):
|
||||
protocol = "cifs"
|
||||
|
||||
@classmethod
|
||||
def skip_checks(cls):
|
||||
super(ShareShrinkBase, cls).skip_checks()
|
||||
if cls.protocol not in CONF.share.enable_ip_rules_for_protocols:
|
||||
message = ("%s tests for access rules other than IP are disabled" %
|
||||
cls.protocol)
|
||||
raise cls.skipException(message)
|
||||
|
||||
def allow_access(self, access_level='rw', **kwargs):
|
||||
return self.provide_access_to_auxiliary_instance(
|
||||
instance=kwargs['instance'], access_level=access_level)
|
||||
|
||||
def mount_share(self, location, ssh_client, target_dir=None):
|
||||
location = location.replace("\\", "/")
|
||||
target_dir = target_dir or "/mnt"
|
||||
|
@ -185,6 +202,15 @@ class TestShareShrinkCIFS(ShareShrinkBase):
|
|||
)
|
||||
|
||||
|
||||
class TestShareShrinkCEPHFS(ShareShrinkBase, manager.BaseShareCEPHFSTest):
|
||||
protocol = "cephfs"
|
||||
|
||||
@tc.attr(base.TAG_POSITIVE, base.TAG_BACKEND)
|
||||
def test_create_shrink_and_write_with_ceph_fuse_client(self):
|
||||
self.mount_client = 'fuse'
|
||||
super(TestShareShrinkCEPHFS, self).test_create_shrink_and_write()
|
||||
|
||||
|
||||
# NOTE(u_glide): this function is required to exclude ShareShrinkBase from
|
||||
# executed test cases.
|
||||
# See: https://docs.python.org/3/library/unittest.html#load-tests-protocol
|
||||
|
|
Loading…
Reference in New Issue