Move shared logic to base scenario test class
The ShareBasicOpsBase class contained setup logic which should be
reused in other tests. This code is moved up to ShareScenarioTest.
Additionally setup checks are moved up to avoid unnecessarily creating
resources, and some naming changes have been made for clarity.
Change-Id: Ia7db48ae0ecab7a11b1d724b6ca71015ee675aea
diff --git a/manila_tempest_tests/tests/scenario/manager_share.py b/manila_tempest_tests/tests/scenario/manager_share.py
index 5c8cbbf..556123f 100644
--- a/manila_tempest_tests/tests/scenario/manager_share.py
+++ b/manila_tempest_tests/tests/scenario/manager_share.py
@@ -16,13 +16,20 @@
from oslo_log import log
import six
-from tempest import config
-from tempest.lib.common.utils import data_utils
-
from manila_tempest_tests.common import constants
from manila_tempest_tests.common import remote_client
+from manila_tempest_tests.tests.api import base
from manila_tempest_tests.tests.scenario import manager
+from tempest.common import waiters
+from tempest import config
+from tempest.lib.common.utils import data_utils
+from tempest.lib.common.utils import test_utils
+from tempest.lib import exceptions
+
+from tempfile import mkstemp
+from urllib2 import urlopen
+
CONF = config.CONF
LOG = log.getLogger(__name__)
@@ -31,6 +38,12 @@
"""Provide harness to do Manila scenario tests."""
credentials = ('admin', 'primary')
+ protocol = None
+ ip_version = 4
+
+ @property
+ def ipv6_enabled(self):
+ return self.ip_version == 6
@classmethod
def resource_setup(cls):
@@ -48,6 +61,266 @@
if not CONF.service_available.manila:
raise cls.skipException("Manila support is required")
+ def setUp(self):
+ base.verify_test_has_appropriate_tags(self)
+ if self.ipv6_enabled and not CONF.share.run_ipv6_tests:
+ raise self.skipException("IPv6 tests are disabled")
+ if self.protocol not in CONF.share.enable_protocols:
+ message = "%s tests are disabled" % self.protocol
+ raise self.skipException(message)
+ if self.protocol not in CONF.share.enable_ip_rules_for_protocols:
+ message = ("%s tests for access rules other than IP are disabled" %
+ self.protocol)
+ raise self.skipException(message)
+ super(ShareScenarioTest, self).setUp()
+
+ self.image_id = None
+ # Setup image and flavor the test instance
+ # Support both configured and injected values
+ self.floating_ips = {}
+
+ if not hasattr(self, 'flavor_ref'):
+ self.flavor_ref = CONF.share.client_vm_flavor_ref
+
+ if CONF.share.image_with_share_tools == 'centos':
+ self.image_ref = self._create_centos_based_glance_image()
+ elif CONF.share.image_with_share_tools:
+ images = self.compute_images_client.list_images()["images"]
+ for img in images:
+ if img["name"] == CONF.share.image_with_share_tools:
+ self.image_id = img['id']
+ break
+ if not self.image_id:
+ msg = ("Image %s not found. Expecting an image including "
+ "required share tools." %
+ CONF.share.image_with_share_tools)
+ raise exceptions.InvalidConfiguration(message=msg)
+ self.ssh_user = CONF.share.image_username
+ LOG.debug('Starting test for i:{image_id}, f:{flavor}. '
+ 'user: {ssh_user}'.format(image_id=self.image_id,
+ flavor=self.flavor_ref,
+ ssh_user=self.ssh_user))
+
+ self.security_group = self._create_security_group()
+ self.share_network = self.create_share_network()
+
+ def mount_share(self, location, remote_client, target_dir=None):
+ raise NotImplementedError
+
+ def umount_share(self, remote_client, target_dir=None):
+ target_dir = target_dir or "/mnt"
+ remote_client.exec_command("sudo umount %s" % target_dir)
+
+ def create_share_network(self):
+ self.net = self._create_network(namestart="manila-share")
+ self.subnet = self._create_subnet(
+ network=self.net,
+ namestart="manila-share-sub",
+ ip_version=self.ip_version,
+ use_default_subnetpool=self.ipv6_enabled)
+ router = self._get_router()
+ self._create_router_interface(subnet_id=self.subnet['id'],
+ router_id=router['id'])
+ share_network = self._create_share_network(
+ neutron_net_id=self.net['id'],
+ neutron_subnet_id=self.subnet['id'],
+ name=data_utils.rand_name("sn-name"))
+ return share_network
+
+ def boot_instance(self, wait_until="ACTIVE"):
+ self.keypair = self.create_keypair()
+ security_groups = [{'name': self.security_group['name']}]
+ create_kwargs = {
+ 'key_name': self.keypair['name'],
+ 'security_groups': security_groups,
+ 'wait_until': wait_until,
+ 'networks': [{'uuid': self.net['id']}, ],
+ }
+ instance = self.create_server(
+ image_id=self.image_id, flavor=self.flavor_ref, **create_kwargs)
+ return instance
+
+ def init_remote_client(self, instance):
+ if self.ipv6_enabled:
+ server_ip = self._get_ipv6_server_ip(instance)
+ else:
+ # Obtain a floating IP
+ floating_ip = (
+ self.compute_floating_ips_client.create_floating_ip()
+ ['floating_ip'])
+ self.floating_ips[instance['id']] = floating_ip
+ self.addCleanup(
+ test_utils.call_and_ignore_notfound_exc,
+ self.compute_floating_ips_client.delete_floating_ip,
+ floating_ip['id'])
+ # Attach a floating IP
+ self.compute_floating_ips_client.associate_floating_ip_to_server(
+ floating_ip['ip'], instance['id'])
+ server_ip = floating_ip['ip']
+ self.assertIsNotNone(server_ip)
+ # Check ssh
+ remote_client = self.get_remote_client(
+ server_or_ip=server_ip,
+ username=self.ssh_user,
+ private_key=self.keypair['private_key'])
+
+ # NOTE(u_glide): Workaround for bug #1465682
+ remote_client = remote_client.ssh_client
+
+ self.share = self.shares_client.get_share(self.share['id'])
+ return remote_client
+
+ def write_data_to_mounted_share(self, escaped_string, remote_client,
+ mount_point='/mnt/t1'):
+ remote_client.exec_command("echo \"{escaped_string}\" "
+ "| sudo tee {mount_point} && sudo sync"
+ .format(escaped_string=escaped_string,
+ mount_point=mount_point))
+
+ def read_data_from_mounted_share(self,
+ remote_client,
+ mount_point='/mnt/t1'):
+ data = remote_client.exec_command("sudo cat {mount_point}"
+ .format(mount_point=mount_point))
+ return data.rstrip()
+
+ def migrate_share(self, share_id, dest_host, status,
+ force_host_assisted=False):
+ share = self._migrate_share(
+ share_id, dest_host, status, force_host_assisted,
+ self.shares_admin_v2_client)
+ return share
+
+ def migration_complete(self, share_id, dest_host):
+ return self._migration_complete(share_id, dest_host)
+
+ def create_share(self, **kwargs):
+ kwargs.update({
+ 'share_protocol': self.protocol,
+ })
+ if not ('share_type_id' in kwargs or 'snapshot_id' in kwargs):
+ default_share_type_id = self._get_share_type()['id']
+ kwargs.update({'share_type_id': default_share_type_id})
+ if CONF.share.multitenancy_enabled:
+ kwargs.update({'share_network_id': self.share_net['id']})
+ self.share = self._create_share(**kwargs)
+ return self.share
+
+ def get_remote_client(self, *args, **kwargs):
+ if not CONF.share.image_with_share_tools:
+ return super(ShareScenarioTest,
+ self).get_remote_client(*args, **kwargs)
+ # NOTE(u_glide): We need custom implementation of this method until
+ # 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):
+ ip = server_or_ip
+ else:
+ addr = server_or_ip['addresses'][
+ CONF.validation.network_for_ssh][0]
+ ip = addr['addr']
+
+ # NOTE(u_glide): Both options (pkey and password) are required here to
+ # support service images without Nova metadata support
+ client_params = {
+ 'username': kwargs['username'],
+ 'password': CONF.share.image_password,
+ 'pkey': kwargs.get('private_key'),
+ }
+
+ linux_client = remote_client.RemoteClient(ip, **client_params)
+ try:
+ linux_client.validate_authentication()
+ except Exception:
+ LOG.exception('Initializing SSH connection to %s failed', ip)
+ self._log_console_output()
+ raise
+
+ return linux_client
+
+ def allow_access_ip(self, share_id, ip=None, instance=None,
+ access_level="rw", cleanup=True, snapshot=None):
+ if instance and not ip:
+ try:
+ net_addresses = instance['addresses']
+ first_address = net_addresses.values()[0][0]
+ ip = first_address['addr']
+ except Exception:
+ LOG.debug("Instance has no valid IP address: %s", instance)
+ # In case on an error ip will be still none
+ LOG.exception("Instance has no valid IP address. "
+ "Falling back to default")
+ if not ip:
+ ip = '0.0.0.0/0'
+
+ if snapshot:
+ self._allow_access_snapshot(snapshot['id'], access_type='ip',
+ access_to=ip, cleanup=cleanup)
+ else:
+ return self._allow_access(share_id, access_type='ip',
+ access_level=access_level, access_to=ip,
+ cleanup=cleanup,
+ client=self.shares_v2_client)
+
+ def deny_access(self, share_id, access_rule_id, client=None):
+ """Deny share access
+
+ :param share_id: id of the share
+ :param access_rule_id: id of the rule that will be deleted
+ """
+ client = client or self.shares_client
+ client.delete_access_rule(share_id, access_rule_id)
+ self.shares_v2_client.wait_for_share_status(
+ share_id, "active", status_attr='access_rules_status')
+
+ def provide_access_to_auxiliary_instance(self, instance, share=None,
+ snapshot=None, access_level='rw'):
+ share = share or self.share
+ if self.protocol.lower() == 'cifs':
+ self.allow_access_ip(
+ share['id'], instance=instance, cleanup=False,
+ snapshot=snapshot, access_level=access_level)
+ elif not CONF.share.multitenancy_enabled:
+ if self.ipv6_enabled:
+ server_ip = self._get_ipv6_server_ip(instance)
+ else:
+ server_ip = (CONF.share.override_ip_for_nfs_access or
+ self.floating_ips[instance['id']]['ip'])
+ self.assertIsNotNone(server_ip)
+ return self.allow_access_ip(
+ share['id'], ip=server_ip,
+ instance=instance, cleanup=False, snapshot=snapshot,
+ access_level=access_level)
+ elif (CONF.share.multitenancy_enabled and
+ self.protocol.lower() == 'nfs'):
+ return self.allow_access_ip(
+ share['id'], instance=instance, cleanup=False,
+ snapshot=snapshot, access_level=access_level)
+
+ def wait_for_active_instance(self, instance_id):
+ waiters.wait_for_server_status(
+ self.os_primary.servers_client, instance_id, "ACTIVE")
+ return self.os_primary.servers_client.show_server(
+ instance_id)["server"]
+
+ def _get_share_type(self):
+ if CONF.share.default_share_type_name:
+ return self.shares_client.get_share_type(
+ CONF.share.default_share_type_name)['share_type']
+ return self._create_share_type(
+ data_utils.rand_name("share_type"),
+ extra_specs={
+ 'snapshot_support': CONF.share.capability_snapshot_support,
+ 'driver_handles_share_servers': CONF.share.multitenancy_enabled
+ },)['share_type']
+
+ def _get_ipv6_server_ip(self, instance):
+ for net_list in instance['addresses'].values():
+ for net_data in net_list:
+ if net_data['version'] == 6:
+ return net_data['addr']
+
def _create_share(self, share_protocol=None, size=None, name=None,
snapshot_id=None, description=None, metadata=None,
share_network_id=None, share_type_id=None,
@@ -160,17 +433,6 @@
self.addCleanup(client.delete_access_rule, share_id, access['id'])
return access
- def _deny_access(self, share_id, rule_id, client=None):
- """Deny share access
-
- :param share_id: id of the share
- :param rule_id: id of the rule that will be deleted
- """
- client = client or self.shares_client
- client.delete_access_rule(share_id, rule_id)
- self.shares_v2_client.wait_for_share_status(
- share_id, "active", status_attr='access_rules_status')
-
def _allow_access_snapshot(self, snapshot_id, access_type="ip",
access_to="0.0.0.0/0", cleanup=True):
"""Allow snapshot access
@@ -206,39 +468,6 @@
self.addCleanup(
client.remove_router_interface, router_id, subnet_id=subnet_id)
- def get_remote_client(self, *args, **kwargs):
- if not CONF.share.image_with_share_tools:
- return super(ShareScenarioTest,
- self).get_remote_client(*args, **kwargs)
- # NOTE(u_glide): We need custom implementation of this method until
- # 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):
- ip = server_or_ip
- else:
- addr = server_or_ip['addresses'][
- CONF.validation.network_for_ssh][0]
- ip = addr['addr']
-
- # NOTE(u_glide): Both options (pkey and password) are required here to
- # support service images without Nova metadata support
- client_params = {
- 'username': kwargs['username'],
- 'password': CONF.share.image_password,
- 'pkey': kwargs.get('private_key'),
- }
-
- linux_client = remote_client.RemoteClient(ip, **client_params)
- try:
- linux_client.validate_authentication()
- except Exception:
- LOG.exception('Initializing SSH connection to %s failed', ip)
- self._log_console_output()
- raise
-
- return linux_client
-
def _migrate_share(self, share_id, dest_host, status, force_host_assisted,
client=None):
client = client or self.shares_admin_v2_client
@@ -264,3 +493,21 @@
self.addCleanup(self.shares_admin_v2_client.delete_share_type,
share_type['share_type']['id'])
return share_type
+
+ def _create_centos_based_glance_image(self):
+ imagepath = mkstemp(suffix='.qcow2')[1]
+ imagefile = open(imagepath, 'wb+')
+ image_response = urlopen('http://cloud.centos.org/centos/7/images/' +
+ 'CentOS-7-x86_64-GenericCloud.qcow2')
+
+ LOG.info('Downloading CentOS7 image')
+ while True:
+ imagecopy = image_response.read(100 * 1024 * 1024)
+ if imagecopy == '':
+ break
+ imagefile.write(imagecopy)
+
+ imagefile.close()
+
+ LOG.info('Creating Glance image using the downloaded image file')
+ return self._image_create('centos', 'bare', imagepath, 'qcow2')
diff --git a/manila_tempest_tests/tests/scenario/test_share_basic_ops.py b/manila_tempest_tests/tests/scenario/test_share_basic_ops.py
index a72d538..32fd735 100644
--- a/manila_tempest_tests/tests/scenario/test_share_basic_ops.py
+++ b/manila_tempest_tests/tests/scenario/test_share_basic_ops.py
@@ -16,10 +16,7 @@
import ddt
from oslo_log import log as logging
-from tempest.common import waiters
from tempest import config
-from tempest.lib.common.utils import data_utils
-from tempest.lib.common.utils import test_utils
from tempest.lib import exceptions
import testtools
from testtools import testcase as tc
@@ -29,11 +26,7 @@
from manila_tempest_tests.tests.scenario import manager_share as manager
from manila_tempest_tests import utils
-from tempfile import mkstemp
-from urllib2 import urlopen
-
CONF = config.CONF
-
LOG = logging.getLogger(__name__)
@@ -50,225 +43,6 @@
* Mount share
* Terminate the instance
"""
- protocol = None
- ip_version = 4
-
- @property
- def use_ipv6(self):
- return self.ip_version == 6
-
- def setUp(self):
- super(ShareBasicOpsBase, self).setUp()
- if self.use_ipv6 and not CONF.share.run_ipv6_tests:
- raise self.skipException("IPv6 tests are disabled")
- base.verify_test_has_appropriate_tags(self)
- self.image_ref = None
- # Setup image and flavor the test instance
- # Support both configured and injected values
- self.floatings = {}
- if self.protocol not in CONF.share.enable_protocols:
- message = "%s tests are disabled" % self.protocol
- raise self.skipException(message)
- if self.protocol not in CONF.share.enable_ip_rules_for_protocols:
- message = ("%s tests for access rules other than IP are disabled" %
- self.protocol)
- raise self.skipException(message)
- if not hasattr(self, 'flavor_ref'):
- self.flavor_ref = CONF.share.client_vm_flavor_ref
-
- if CONF.share.image_with_share_tools == 'centos':
- self.image_ref = self._create_centos_based_glance_image()
- elif CONF.share.image_with_share_tools:
- images = self.compute_images_client.list_images()["images"]
- for img in images:
- if img["name"] == CONF.share.image_with_share_tools:
- self.image_ref = img['id']
- break
- if not self.image_ref:
- msg = ("Image %s not found" %
- CONF.share.image_with_share_tools)
- raise exceptions.InvalidConfiguration(message=msg)
- self.ssh_user = CONF.share.image_username
- LOG.debug('Starting test for i:{image}, f:{flavor}. '
- 'user: {ssh_user}'.format(
- image=self.image_ref, flavor=self.flavor_ref,
- ssh_user=self.ssh_user))
- self.security_group = self._create_security_group()
- self.create_share_network()
-
- def boot_instance(self, wait_until="ACTIVE"):
- self.keypair = self.create_keypair()
- security_groups = [{'name': self.security_group['name']}]
- create_kwargs = {
- 'key_name': self.keypair['name'],
- 'security_groups': security_groups,
- 'wait_until': wait_until,
- 'networks': [{'uuid': self.net['id']}, ],
- }
- instance = self.create_server(
- image_id=self.image_ref, flavor=self.flavor_ref, **create_kwargs)
- return instance
-
- def init_ssh(self, instance):
- if self.use_ipv6:
- server_ip = self._get_ipv6_server_ip(instance)
- else:
- # Obtain a floating IP
- floating_ip = (
- self.compute_floating_ips_client.create_floating_ip()
- ['floating_ip'])
- self.floatings[instance['id']] = floating_ip
- self.addCleanup(
- test_utils.call_and_ignore_notfound_exc,
- self.compute_floating_ips_client.delete_floating_ip,
- floating_ip['id'])
- # Attach a floating IP
- self.compute_floating_ips_client.associate_floating_ip_to_server(
- floating_ip['ip'], instance['id'])
- server_ip = floating_ip['ip']
- self.assertIsNotNone(server_ip)
- # Check ssh
- ssh_client = self.get_remote_client(
- server_or_ip=server_ip,
- username=self.ssh_user,
- private_key=self.keypair['private_key'])
-
- # NOTE(u_glide): Workaround for bug #1465682
- ssh_client = ssh_client.ssh_client
-
- self.share = self.shares_client.get_share(self.share['id'])
- return ssh_client
-
- def mount_share(self, location, ssh_client, target_dir=None):
- raise NotImplementedError
-
- def umount_share(self, ssh_client, target_dir=None):
- target_dir = target_dir or "/mnt"
- ssh_client.exec_command("sudo umount %s" % target_dir)
-
- def write_data(self, data, ssh_client):
- ssh_client.exec_command("echo \"%s\" | sudo tee /mnt/t1 && sudo sync" %
- data)
-
- def read_data(self, ssh_client):
- data = ssh_client.exec_command("sudo cat /mnt/t1")
- return data.rstrip()
-
- def migrate_share(self, share_id, dest_host, status, force_host_assisted):
- share = self._migrate_share(
- share_id, dest_host, status, force_host_assisted,
- self.shares_admin_v2_client)
- return share
-
- def migration_complete(self, share_id, dest_host):
- return self._migration_complete(share_id, dest_host)
-
- def create_share_network(self):
- self.net = self._create_network(namestart="manila-share")
- self.subnet = self._create_subnet(
- network=self.net,
- namestart="manila-share-sub",
- ip_version=self.ip_version,
- use_default_subnetpool=self.use_ipv6)
- router = self._get_router()
- self._create_router_interface(subnet_id=self.subnet['id'],
- router_id=router['id'])
- self.share_net = self._create_share_network(
- neutron_net_id=self.net['id'],
- neutron_subnet_id=self.subnet['id'],
- name=data_utils.rand_name("sn-name"))
-
- def _get_ipv6_server_ip(self, instance):
- for net_list in instance['addresses'].values():
- for net_data in net_list:
- if net_data['version'] == 6:
- return net_data['addr']
-
- def _get_share_type(self):
- if CONF.share.default_share_type_name:
- return self.shares_client.get_share_type(
- CONF.share.default_share_type_name)['share_type']
- return self._create_share_type(
- data_utils.rand_name("share_type"),
- extra_specs={
- 'snapshot_support': CONF.share.capability_snapshot_support,
- 'driver_handles_share_servers': CONF.share.multitenancy_enabled
- },)['share_type']
-
- def create_share(self, **kwargs):
- kwargs.update({
- 'share_protocol': self.protocol,
- })
- if not ('share_type_id' in kwargs or 'snapshot_id' in kwargs):
- kwargs.update({'share_type_id': self._get_share_type()['id']})
- if CONF.share.multitenancy_enabled:
- kwargs.update({'share_network_id': self.share_net['id']})
- self.share = self._create_share(**kwargs)
- return self.share
-
- def allow_access_ip(self, share_id, ip=None, instance=None,
- access_level="rw", cleanup=True, snapshot=None):
- if instance and not ip:
- try:
- net_addresses = instance['addresses']
- first_address = net_addresses.values()[0][0]
- ip = first_address['addr']
- except Exception:
- LOG.debug("Instance: %s", instance)
- # In case on an error ip will be still none
- LOG.exception("Instance does not have a valid IP address."
- "Falling back to default")
- if not ip:
- ip = '0.0.0.0/0'
-
- if snapshot:
- self._allow_access_snapshot(snapshot['id'], access_type='ip',
- access_to=ip, cleanup=cleanup)
- else:
- return self._allow_access(share_id, access_type='ip',
- access_level=access_level, access_to=ip,
- cleanup=cleanup,
- client=self.shares_v2_client)
-
- def deny_access(self, share_id, access_rule_id):
- self._deny_access(share_id, access_rule_id)
-
- def provide_access_to_auxiliary_instance(self, instance, share=None,
- snapshot=None, access_level='rw'):
- share = share or self.share
- if self.protocol.lower() == 'cifs':
- return self.allow_access_ip(
- share['id'], instance=instance, cleanup=False,
- snapshot=snapshot, access_level=access_level)
- elif not CONF.share.multitenancy_enabled:
- if self.use_ipv6:
- server_ip = self._get_ipv6_server_ip(instance)
- else:
- server_ip = (CONF.share.override_ip_for_nfs_access or
- self.floatings[instance['id']]['ip'])
- self.assertIsNotNone(server_ip)
- return self.allow_access_ip(
- share['id'], ip=server_ip,
- instance=instance, cleanup=False, snapshot=snapshot,
- access_level=access_level)
- elif (CONF.share.multitenancy_enabled and
- self.protocol.lower() == 'nfs'):
- return self.allow_access_ip(
- share['id'], instance=instance, cleanup=False,
- snapshot=snapshot, access_level=access_level)
-
- def wait_for_active_instance(self, instance_id):
- waiters.wait_for_server_status(
- self.os_primary.servers_client, instance_id, "ACTIVE")
- return self.os_primary.servers_client.show_server(
- instance_id)["server"]
-
- def _ping_export_location(self, export, ssh_client):
- ip, version = self.get_ip_and_version_from_export_location(export)
- if version == 6:
- ssh_client.exec_command("ping6 -c 1 %s" % ip)
- else:
- ssh_client.exec_command("ping -c 1 %s" % ip)
def get_ip_and_version_from_export_location(self, export):
export = export.replace('[', '').replace(']', '')
@@ -284,6 +58,13 @@
raise self.skipException(message)
return ip, version
+ def _ping_host_from_export_location(self, export, remote_client):
+ ip, version = self.get_ip_and_version_from_export_location(export)
+ if version == 6:
+ remote_client.exec_command("ping6 -c 1 %s" % ip)
+ else:
+ remote_client.exec_command("ping -c 1 %s" % ip)
+
def _get_export_locations_according_to_ip_version(
self, all_locations, error_on_invalid_ip_version):
locations = [
@@ -297,6 +78,21 @@
raise self.skipException(message)
return locations
+ def _get_user_export_locations(self, share=None, snapshot=None,
+ error_on_invalid_ip_version=False):
+ locations = None
+ if share:
+ locations = self._get_share_export_locations(share)
+ elif snapshot:
+ 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)
+
+ return locations
+
def _get_share_export_locations(self, share):
if utils.is_microversion_lt(CONF.share.max_api_microversion, "2.9"):
@@ -308,23 +104,12 @@
return locations
- def _create_centos_based_glance_image(self):
- imagepath = mkstemp(suffix='.qcow2')[1]
- imagefile = open(imagepath, 'wb+')
- image_response = urlopen('http://cloud.centos.org/centos/7/images/' +
- 'CentOS-7-x86_64-GenericCloud.qcow2')
+ def _get_snapshot_export_locations(self, snapshot):
+ exports = (self.shares_v2_client.
+ list_snapshot_export_locations(snapshot['id']))
+ locations = [x['path'] for x in exports]
- LOG.info('Downloading CentOS7 image')
- while True:
- imagecopy = image_response.read(100 * 1024 * 1024)
- if imagecopy == '':
- break
- imagefile.write(imagecopy)
-
- imagefile.close()
-
- LOG.info('Creating Glance image using the downloaded image file')
- return self._image_create('centos', 'bare', imagepath, 'qcow2')
+ return locations
@tc.attr(base.TAG_POSITIVE, base.TAG_BACKEND)
def test_mount_share_one_vm(self):
@@ -332,19 +117,12 @@
self.create_share()
locations = self._get_user_export_locations(self.share)
instance = self.wait_for_active_instance(instance["id"])
- ssh_client = self.init_ssh(instance)
+ remote_client = self.init_remote_client(instance)
self.provide_access_to_auxiliary_instance(instance)
for location in locations:
- self.mount_share(location, ssh_client)
- self.umount_share(ssh_client)
-
- def _get_snapshot_export_locations(self, snapshot):
- exports = (self.shares_v2_client.
- list_snapshot_export_locations(snapshot['id']))
- locations = [x['path'] for x in exports]
-
- return locations
+ self.mount_share(location, remote_client)
+ self.umount_share(remote_client)
@tc.attr(base.TAG_NEGATIVE, base.TAG_BACKEND)
def test_write_with_ro_access(self):
@@ -356,20 +134,21 @@
location = self._get_user_export_locations(self.share)[0]
instance = self.wait_for_active_instance(instance["id"])
- ssh_client_inst = self.init_ssh(instance)
+ 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']
- self.mount_share(location, ssh_client_inst)
- self.write_data(test_data, ssh_client_inst)
+ 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.addCleanup(self.umount_share, ssh_client_inst)
+ self.addCleanup(self.umount_share, remote_client_inst)
# Test if write with RO access fails.
self.assertRaises(exceptions.SSHExecCommandFailed,
- self.write_data, test_data, ssh_client_inst)
+ self.write_data_to_mounted_share,
+ test_data, remote_client_inst)
@tc.attr(base.TAG_POSITIVE, base.TAG_BACKEND)
def test_read_write_two_vms(self):
@@ -385,23 +164,23 @@
instance2 = self.wait_for_active_instance(instance2["id"])
# Write data to first VM
- ssh_client_inst1 = self.init_ssh(instance1)
+ remote_client_inst1 = self.init_remote_client(instance1)
self.provide_access_to_auxiliary_instance(instance1)
- self.mount_share(location, ssh_client_inst1)
+ self.mount_share(location, remote_client_inst1)
self.addCleanup(self.umount_share,
- ssh_client_inst1)
- self.write_data(test_data, ssh_client_inst1)
+ remote_client_inst1)
+ self.write_data_to_mounted_share(test_data, remote_client_inst1)
# Read from second VM
- ssh_client_inst2 = self.init_ssh(instance2)
- if not CONF.share.override_ip_for_nfs_access or self.use_ipv6:
+ 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.mount_share(location, ssh_client_inst2)
+ self.mount_share(location, remote_client_inst2)
self.addCleanup(self.umount_share,
- ssh_client_inst2)
- data = self.read_data(ssh_client_inst2)
+ remote_client_inst2)
+ data = self.read_data_from_mounted_share(remote_client_inst2)
self.assertEqual(test_data, data)
@tc.attr(base.TAG_POSITIVE, base.TAG_BACKEND)
@@ -425,6 +204,10 @@
raise self.skipException("Only NFS protocol supported "
"at this moment.")
+ if self.ipv6_enabled:
+ raise self.skipException("Share Migration using IPv6 is not "
+ "supported at this moment.")
+
pools = self.shares_admin_v2_client.list_pools(detail=True)['pools']
if len(pools) < 2:
@@ -448,29 +231,29 @@
dest_pool = dest_pool['name']
- ssh_client = self.init_ssh(instance)
+ remote_client = self.init_remote_client(instance)
self.provide_access_to_auxiliary_instance(instance)
- self.mount_share(exports[0], ssh_client)
+ self.mount_share(exports[0], remote_client)
- ssh_client.exec_command("sudo mkdir -p /mnt/f1")
- ssh_client.exec_command("sudo mkdir -p /mnt/f2")
- ssh_client.exec_command("sudo mkdir -p /mnt/f3")
- ssh_client.exec_command("sudo mkdir -p /mnt/f4")
- ssh_client.exec_command("sudo mkdir -p /mnt/f1/ff1")
- ssh_client.exec_command("sleep 1")
- ssh_client.exec_command(
+ remote_client.exec_command("sudo mkdir -p /mnt/f1")
+ remote_client.exec_command("sudo mkdir -p /mnt/f2")
+ remote_client.exec_command("sudo mkdir -p /mnt/f3")
+ remote_client.exec_command("sudo mkdir -p /mnt/f4")
+ remote_client.exec_command("sudo mkdir -p /mnt/f1/ff1")
+ remote_client.exec_command("sleep 1")
+ remote_client.exec_command(
"sudo dd if=/dev/zero of=/mnt/f1/1m1.bin bs=1M count=1")
- ssh_client.exec_command(
+ remote_client.exec_command(
"sudo dd if=/dev/zero of=/mnt/f2/1m2.bin bs=1M count=1")
- ssh_client.exec_command(
+ remote_client.exec_command(
"sudo dd if=/dev/zero of=/mnt/f3/1m3.bin bs=1M count=1")
- ssh_client.exec_command(
+ remote_client.exec_command(
"sudo dd if=/dev/zero of=/mnt/f4/1m4.bin bs=1M count=1")
- ssh_client.exec_command(
+ remote_client.exec_command(
"sudo dd if=/dev/zero of=/mnt/f1/ff1/1m5.bin bs=1M count=1")
- ssh_client.exec_command("sudo chmod -R 555 /mnt/f3")
- ssh_client.exec_command("sudo chmod -R 777 /mnt/f4")
+ remote_client.exec_command("sudo chmod -R 555 /mnt/f3")
+ remote_client.exec_command("sudo chmod -R 777 /mnt/f4")
task_state = (constants.TASK_STATE_DATA_COPYING_COMPLETED
if force_host_assisted
@@ -482,10 +265,10 @@
if force_host_assisted:
self.assertRaises(
exceptions.SSHExecCommandFailed,
- ssh_client.exec_command,
+ remote_client.exec_command,
"dd if=/dev/zero of=/mnt/f1/1m6.bin bs=1M count=1")
- self.umount_share(ssh_client)
+ self.umount_share(remote_client)
self.share = self.migration_complete(self.share['id'], dest_pool)
@@ -496,11 +279,11 @@
self.assertEqual(constants.TASK_STATE_MIGRATION_SUCCESS,
self.share['task_state'])
- self.mount_share(new_exports[0], ssh_client)
+ self.mount_share(new_exports[0], remote_client)
- output = ssh_client.exec_command("ls -lRA --ignore=lost+found /mnt")
+ output = remote_client.exec_command("ls -lRA --ignore=lost+found /mnt")
- self.umount_share(ssh_client)
+ self.umount_share(remote_client)
self.assertIn('1m1.bin', output)
self.assertIn('1m2.bin', output)
@@ -508,21 +291,6 @@
self.assertIn('1m4.bin', output)
self.assertIn('1m5.bin', output)
- def _get_user_export_locations(self, share=None, snapshot=None,
- error_on_invalid_ip_version=False):
- locations = None
- if share:
- locations = self._get_share_export_locations(share)
- elif snapshot:
- 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)
-
- return locations
-
@tc.attr(base.TAG_POSITIVE, base.TAG_BACKEND)
@testtools.skipUnless(
CONF.share.run_snapshot_tests, "Snapshot tests are disabled.")
@@ -540,7 +308,7 @@
self.addCleanup(self.servers_client.delete_server, instance['id'])
# 3 - SSH to UVM, ok, connected
- ssh_client = self.init_ssh(instance)
+ remote_client = self.init_remote_client(instance)
# 4 - Provide RW access to S1, ok, provided
self.provide_access_to_auxiliary_instance(instance, parent_share)
@@ -548,20 +316,20 @@
# 5 - Try mount S1 to UVM, ok, mounted
user_export_location = self._get_user_export_locations(parent_share)[0]
parent_share_dir = "/mnt/parent"
- ssh_client.exec_command("sudo mkdir -p %s" % parent_share_dir)
+ remote_client.exec_command("sudo mkdir -p %s" % parent_share_dir)
- self.mount_share(user_export_location, ssh_client, parent_share_dir)
- self.addCleanup(self.umount_share, ssh_client, parent_share_dir)
+ self.mount_share(user_export_location, remote_client, parent_share_dir)
+ self.addCleanup(self.umount_share, remote_client, parent_share_dir)
# 6 - Create "file1", ok, created
- ssh_client.exec_command("sudo touch %s/file1" % parent_share_dir)
+ remote_client.exec_command("sudo touch %s/file1" % parent_share_dir)
# 7 - Create snapshot SS1 from S1, ok, created
snapshot = self._create_snapshot(parent_share['id'])
# 8 - Create "file2" in share S1 - ok, created. We expect that
# snapshot will not contain any data created after snapshot creation.
- ssh_client.exec_command("sudo touch %s/file2" % parent_share_dir)
+ remote_client.exec_command("sudo touch %s/file2" % parent_share_dir)
# 9 - Create share S2 from SS1, ok, created
child_share = self.create_share(snapshot_id=snapshot["id"])
@@ -570,37 +338,40 @@
# did not get access rules from parent share.
user_export_location = self._get_user_export_locations(child_share)[0]
child_share_dir = "/mnt/child"
- ssh_client.exec_command("sudo mkdir -p %s" % child_share_dir)
+ remote_client.exec_command("sudo mkdir -p %s" % child_share_dir)
self.assertRaises(
exceptions.SSHExecCommandFailed,
self.mount_share,
- user_export_location, ssh_client, child_share_dir,
+ user_export_location, remote_client, child_share_dir,
)
# 11 - Provide RW access to S2, ok, provided
self.provide_access_to_auxiliary_instance(instance, child_share)
# 12 - Try mount S2, ok, mounted
- self.mount_share(user_export_location, ssh_client, child_share_dir)
- self.addCleanup(self.umount_share, ssh_client, child_share_dir)
+ self.mount_share(user_export_location, remote_client, child_share_dir)
+ self.addCleanup(self.umount_share, remote_client, child_share_dir)
# 13 - List files on S2, only "file1" exists
- output = ssh_client.exec_command("sudo ls -lRA %s" % child_share_dir)
+ output = remote_client.exec_command(
+ "sudo ls -lRA %s" % child_share_dir)
self.assertIn('file1', output)
self.assertNotIn('file2', output)
# 14 - Create file3 on S2, ok, file created
- ssh_client.exec_command("sudo touch %s/file3" % child_share_dir)
+ remote_client.exec_command("sudo touch %s/file3" % child_share_dir)
# 15 - List files on S1, two files exist - "file1" and "file2"
- output = ssh_client.exec_command("sudo ls -lRA %s" % parent_share_dir)
+ output = remote_client.exec_command(
+ "sudo ls -lRA %s" % parent_share_dir)
self.assertIn('file1', output)
self.assertIn('file2', output)
self.assertNotIn('file3', output)
# 16 - List files on S2, two files exist - "file1" and "file3"
- output = ssh_client.exec_command("sudo ls -lRA %s" % child_share_dir)
+ output = remote_client.exec_command(
+ "sudo ls -lRA %s" % child_share_dir)
self.assertIn('file1', output)
self.assertNotIn('file2', output)
self.assertIn('file3', output)
@@ -625,7 +396,7 @@
self.addCleanup(self.servers_client.delete_server, instance['id'])
# 3 - SSH to UVM, ok, connected
- ssh_client = self.init_ssh(instance)
+ remote_client = self.init_remote_client(instance)
# 4 - Provide RW access to S1, ok, provided
self.provide_access_to_auxiliary_instance(instance, parent_share)
@@ -634,21 +405,21 @@
user_export_location = self._get_user_export_locations(parent_share)[0]
parent_share_dir = "/mnt/parent"
snapshot_dir = "/mnt/snapshot_dir"
- ssh_client.exec_command("sudo mkdir -p %s" % parent_share_dir)
- ssh_client.exec_command("sudo mkdir -p %s" % snapshot_dir)
+ remote_client.exec_command("sudo mkdir -p %s" % parent_share_dir)
+ remote_client.exec_command("sudo mkdir -p %s" % snapshot_dir)
- self.mount_share(user_export_location, ssh_client, parent_share_dir)
- self.addCleanup(self.umount_share, ssh_client, parent_share_dir)
+ self.mount_share(user_export_location, remote_client, parent_share_dir)
+ self.addCleanup(self.umount_share, remote_client, parent_share_dir)
# 6 - Create "file1", ok, created
- ssh_client.exec_command("sudo touch %s/file1" % parent_share_dir)
+ remote_client.exec_command("sudo touch %s/file1" % parent_share_dir)
# 7 - Create snapshot SS1 from S1, ok, created
snapshot = self._create_snapshot(parent_share['id'])
# 8 - Create "file2" in share S1 - ok, created. We expect that
# snapshot will not contain any data created after snapshot creation.
- ssh_client.exec_command("sudo touch %s/file2" % parent_share_dir)
+ remote_client.exec_command("sudo touch %s/file2" % parent_share_dir)
# 9 - Allow access to SS1
self.provide_access_to_auxiliary_instance(instance, snapshot=snapshot)
@@ -656,45 +427,45 @@
# 10 - Mount SS1
user_export_location = self._get_user_export_locations(
snapshot=snapshot)[0]
- self.mount_share(user_export_location, ssh_client, snapshot_dir)
- self.addCleanup(self.umount_share, ssh_client, snapshot_dir)
+ self.mount_share(user_export_location, remote_client, snapshot_dir)
+ self.addCleanup(self.umount_share, remote_client, snapshot_dir)
# 11 - List files on SS1, only "file1" exists
# NOTE(lseki): using ls without recursion to avoid permission denied
# error while listing lost+found directory on LVM volumes
- output = ssh_client.exec_command("sudo ls -lA %s" % snapshot_dir)
+ output = remote_client.exec_command("sudo ls -lA %s" % snapshot_dir)
self.assertIn('file1', output)
self.assertNotIn('file2', output)
# 12 - Try to create a file on SS1, should fail
self.assertRaises(
exceptions.SSHExecCommandFailed,
- ssh_client.exec_command,
+ remote_client.exec_command,
"sudo touch %s/file3" % snapshot_dir)
class TestShareBasicOpsNFS(ShareBasicOpsBase):
protocol = "nfs"
- def mount_share(self, location, ssh_client, target_dir=None):
+ def mount_share(self, location, remote_client, target_dir=None):
- self._ping_export_location(location, ssh_client)
+ self._ping_host_from_export_location(location, remote_client)
target_dir = target_dir or "/mnt"
- ssh_client.exec_command(
+ remote_client.exec_command(
"sudo mount -vt nfs \"%s\" %s" % (location, target_dir))
class TestShareBasicOpsCIFS(ShareBasicOpsBase):
protocol = "cifs"
- def mount_share(self, location, ssh_client, target_dir=None):
+ def mount_share(self, location, remote_client, target_dir=None):
- self._ping_export_location(location, ssh_client)
+ self._ping_host_from_export_location(location, remote_client)
location = location.replace("\\", "/")
target_dir = target_dir or "/mnt"
- ssh_client.exec_command(
+ remote_client.exec_command(
"sudo mount.cifs \"%s\" %s -o guest" % (location, target_dir)
)