Merge "Move shared logic to base scenario test class"
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)
)