Merge "Preparation for support scenario tests on CephFS Native"

This commit is contained in:
Zuul 2020-06-02 01:57:21 +00:00 committed by Gerrit Code Review
commit 3a71fb7e86
4 changed files with 221 additions and 36 deletions

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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