
InfiniBox v3.0 introduced volume compression on the storage array side. This change provides a new configuration option to control whether to create new volumes with compression enabled or not. Change-Id: Ia214fc45d960dada8e863ed2ca06be533048f410 Implements: blueprint infinidat-compression
631 lines
30 KiB
Python
631 lines
30 KiB
Python
# Copyright 2016 Infinidat Ltd.
|
|
# All Rights Reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
"""Unit tests for INFINIDAT InfiniBox volume driver."""
|
|
|
|
import mock
|
|
from oslo_utils import units
|
|
|
|
from cinder import exception
|
|
from cinder import test
|
|
from cinder.volume import configuration
|
|
from cinder.volume.drivers import infinidat
|
|
|
|
|
|
TEST_WWN_1 = '00:11:22:33:44:55:66:77'
|
|
TEST_WWN_2 = '11:11:22:33:44:55:66:77'
|
|
|
|
test_volume = mock.Mock(id=1, size=1, volume_type_id=1)
|
|
test_snapshot = mock.Mock(id=2, volume=test_volume, volume_id='1')
|
|
test_clone = mock.Mock(id=3, size=1)
|
|
test_group = mock.Mock(id=4)
|
|
test_snapgroup = mock.Mock(id=5, group=test_group)
|
|
test_connector = dict(wwpns=[TEST_WWN_1],
|
|
initiator='iqn.2012-07.org.fake:01')
|
|
|
|
|
|
class FakeInfinisdkException(Exception):
|
|
pass
|
|
|
|
|
|
class InfiniboxDriverTestCaseBase(test.TestCase):
|
|
def setUp(self):
|
|
super(InfiniboxDriverTestCaseBase, self).setUp()
|
|
|
|
# create mock configuration
|
|
self.configuration = mock.Mock(spec=configuration.Configuration)
|
|
self.configuration.infinidat_storage_protocol = 'fc'
|
|
self.configuration.san_ip = 'mockbox'
|
|
self.configuration.infinidat_pool_name = 'mockpool'
|
|
self.configuration.san_thin_provision = 'thin'
|
|
self.configuration.san_login = 'user'
|
|
self.configuration.san_password = 'pass'
|
|
self.configuration.volume_backend_name = 'mock'
|
|
self.configuration.volume_dd_blocksize = '1M'
|
|
self.configuration.use_multipath_for_image_xfer = False
|
|
self.configuration.enforce_multipath_for_image_xfer = False
|
|
self.configuration.num_volume_device_scan_tries = 1
|
|
self.configuration.san_is_local = False
|
|
self.configuration.chap_username = None
|
|
self.configuration.chap_password = None
|
|
self.configuration.infinidat_use_compression = None
|
|
|
|
self.driver = infinidat.InfiniboxVolumeDriver(
|
|
configuration=self.configuration)
|
|
self._system = self._infinibox_mock()
|
|
# mock external library dependencies
|
|
infinisdk = self.patch("cinder.volume.drivers.infinidat.infinisdk")
|
|
capacity = self.patch("cinder.volume.drivers.infinidat.capacity")
|
|
self.patch("cinder.volume.drivers.infinidat.iqn")
|
|
self.patch("cinder.volume.drivers.infinidat.wwn")
|
|
capacity.byte = 1
|
|
capacity.GiB = units.Gi
|
|
infinisdk.core.exceptions.InfiniSDKException = FakeInfinisdkException
|
|
infinisdk.InfiniBox.return_value = self._system
|
|
self.driver.do_setup(None)
|
|
|
|
def _infinibox_mock(self):
|
|
result = mock.Mock()
|
|
self._mock_volume = mock.Mock()
|
|
self._mock_volume.has_children.return_value = False
|
|
self._mock_volume.get_logical_units.return_value = []
|
|
self._mock_volume.create_child.return_value = self._mock_volume
|
|
self._mock_host = mock.Mock()
|
|
self._mock_host.get_luns.return_value = []
|
|
self._mock_host.map_volume().get_lun.return_value = 1
|
|
self._mock_pool = mock.Mock()
|
|
self._mock_pool.get_free_physical_capacity.return_value = units.Gi
|
|
self._mock_pool.get_physical_capacity.return_value = units.Gi
|
|
self._mock_ns = mock.Mock()
|
|
self._mock_ns.get_ips.return_value = [mock.Mock(ip_address='1.1.1.1')]
|
|
self._mock_group = mock.Mock()
|
|
self._mock_qos_policy = mock.Mock()
|
|
result.volumes.safe_get.return_value = self._mock_volume
|
|
result.volumes.create.return_value = self._mock_volume
|
|
result.pools.safe_get.return_value = self._mock_pool
|
|
result.hosts.safe_get.return_value = self._mock_host
|
|
result.cons_groups.safe_get.return_value = self._mock_group
|
|
result.cons_groups.create.return_value = self._mock_group
|
|
result.hosts.create.return_value = self._mock_host
|
|
result.network_spaces.safe_get.return_value = self._mock_ns
|
|
result.components.nodes.get_all.return_value = []
|
|
result.qos_policies.create.return_value = self._mock_qos_policy
|
|
result.qos_policies.safe_get.return_value = None
|
|
return result
|
|
|
|
def _raise_infinisdk(self, *args, **kwargs):
|
|
raise FakeInfinisdkException()
|
|
|
|
|
|
class InfiniboxDriverTestCase(InfiniboxDriverTestCaseBase):
|
|
def test_initialize_connection(self):
|
|
self._system.hosts.safe_get.return_value = None
|
|
result = self.driver.initialize_connection(test_volume, test_connector)
|
|
self.assertEqual(1, result["data"]["target_lun"])
|
|
|
|
def test_initialize_connection_host_exists(self):
|
|
result = self.driver.initialize_connection(test_volume, test_connector)
|
|
self.assertEqual(1, result["data"]["target_lun"])
|
|
|
|
def test_initialize_connection_mapping_exists(self):
|
|
mock_mapping = mock.Mock()
|
|
mock_mapping.get_volume.return_value = self._mock_volume
|
|
mock_mapping.get_lun.return_value = 888
|
|
self._mock_host.get_luns.return_value = [mock_mapping]
|
|
result = self.driver.initialize_connection(test_volume, test_connector)
|
|
self.assertEqual(888, result["data"]["target_lun"])
|
|
|
|
def test_initialize_connection_volume_doesnt_exist(self):
|
|
self._system.volumes.safe_get.return_value = None
|
|
self.assertRaises(exception.InvalidVolume,
|
|
self.driver.initialize_connection,
|
|
test_volume, test_connector)
|
|
|
|
def test_initialize_connection_create_fails(self):
|
|
self._system.hosts.safe_get.return_value = None
|
|
self._system.hosts.create.side_effect = self._raise_infinisdk
|
|
self.assertRaises(exception.VolumeBackendAPIException,
|
|
self.driver.initialize_connection,
|
|
test_volume, test_connector)
|
|
|
|
def test_initialize_connection_map_fails(self):
|
|
self._mock_host.map_volume.side_effect = self._raise_infinisdk
|
|
self.assertRaises(exception.VolumeBackendAPIException,
|
|
self.driver.initialize_connection,
|
|
test_volume, test_connector)
|
|
|
|
def test_initialize_connection_metadata(self):
|
|
self._system.hosts.safe_get.return_value = None
|
|
self.driver.initialize_connection(test_volume, test_connector)
|
|
self._mock_host.set_metadata_from_dict.assert_called_once()
|
|
|
|
def test_terminate_connection(self):
|
|
self.driver.terminate_connection(test_volume, test_connector)
|
|
|
|
def test_terminate_connection_delete_host(self):
|
|
self._mock_host.get_luns.return_value = [object()]
|
|
self.driver.terminate_connection(test_volume, test_connector)
|
|
self.assertEqual(0, self._mock_host.safe_delete.call_count)
|
|
self._mock_host.get_luns.return_value = []
|
|
self.driver.terminate_connection(test_volume, test_connector)
|
|
self.assertEqual(1, self._mock_host.safe_delete.call_count)
|
|
|
|
def test_terminate_connection_volume_doesnt_exist(self):
|
|
self._system.volumes.safe_get.return_value = None
|
|
self.assertRaises(exception.InvalidVolume,
|
|
self.driver.terminate_connection,
|
|
test_volume, test_connector)
|
|
|
|
def test_terminate_connection_api_fail(self):
|
|
self._mock_host.unmap_volume.side_effect = self._raise_infinisdk
|
|
self.assertRaises(exception.VolumeBackendAPIException,
|
|
self.driver.terminate_connection,
|
|
test_volume, test_connector)
|
|
|
|
def test_get_volume_stats_refreshes(self):
|
|
result = self.driver.get_volume_stats()
|
|
self.assertEqual(1, result["free_capacity_gb"])
|
|
# change the "free space" in the pool
|
|
self._mock_pool.get_free_physical_capacity.return_value = 0
|
|
# no refresh - free capacity should stay the same
|
|
result = self.driver.get_volume_stats(refresh=False)
|
|
self.assertEqual(1, result["free_capacity_gb"])
|
|
# refresh - free capacity should change to 0
|
|
result = self.driver.get_volume_stats(refresh=True)
|
|
self.assertEqual(0, result["free_capacity_gb"])
|
|
|
|
def test_get_volume_stats_pool_not_found(self):
|
|
self._system.pools.safe_get.return_value = None
|
|
self.assertRaises(exception.VolumeDriverException,
|
|
self.driver.get_volume_stats)
|
|
|
|
@mock.patch("cinder.volume.volume_types.get_volume_type_qos_specs")
|
|
def test_create_volume(self, *mocks):
|
|
self.driver.create_volume(test_volume)
|
|
|
|
def test_create_volume_pool_not_found(self):
|
|
self._system.pools.safe_get.return_value = None
|
|
self.assertRaises(exception.VolumeDriverException,
|
|
self.driver.create_volume, test_volume)
|
|
|
|
def test_create_volume_api_fail(self):
|
|
self._system.pools.safe_get.side_effect = self._raise_infinisdk
|
|
self.assertRaises(exception.VolumeBackendAPIException,
|
|
self.driver.create_volume, test_volume)
|
|
|
|
@mock.patch("cinder.volume.volume_types.get_volume_type_qos_specs")
|
|
def test_create_volume_metadata(self, *mocks):
|
|
self.driver.create_volume(test_volume)
|
|
self._mock_volume.set_metadata_from_dict.assert_called_once()
|
|
|
|
@mock.patch("cinder.volume.volume_types.get_volume_type_qos_specs")
|
|
def test_create_volume_compression_enabled(self, *mocks):
|
|
self.configuration.infinidat_use_compression = True
|
|
self.driver.create_volume(test_volume)
|
|
self.assertTrue(
|
|
self._system.volumes.create.call_args[1]["compression_enabled"]
|
|
)
|
|
|
|
@mock.patch("cinder.volume.volume_types.get_volume_type_qos_specs")
|
|
def test_create_volume_compression_not_enabled(self, *mocks):
|
|
self.configuration.infinidat_use_compression = False
|
|
self.driver.create_volume(test_volume)
|
|
self.assertFalse(
|
|
self._system.volumes.create.call_args[1]["compression_enabled"]
|
|
)
|
|
|
|
@mock.patch("cinder.volume.volume_types.get_volume_type_qos_specs")
|
|
def test_create_volume_compression_not_available(self, *mocks):
|
|
self._system.compat.has_compression.return_value = False
|
|
self.driver.create_volume(test_volume)
|
|
self.assertNotIn(
|
|
"compression_enabled",
|
|
self._system.volumes.create.call_args[1]
|
|
)
|
|
|
|
def test_delete_volume(self):
|
|
self.driver.delete_volume(test_volume)
|
|
|
|
def test_delete_volume_doesnt_exist(self):
|
|
self._system.volumes.safe_get.return_value = None
|
|
# should not raise an exception
|
|
self.driver.delete_volume(test_volume)
|
|
|
|
def test_delete_volume_with_children(self):
|
|
self._mock_volume.has_children.return_value = True
|
|
self.assertRaises(exception.VolumeIsBusy,
|
|
self.driver.delete_volume, test_volume)
|
|
|
|
def test_extend_volume(self):
|
|
self.driver.extend_volume(test_volume, 2)
|
|
|
|
def test_extend_volume_api_fail(self):
|
|
self._mock_volume.resize.side_effect = self._raise_infinisdk
|
|
self.assertRaises(exception.VolumeBackendAPIException,
|
|
self.driver.extend_volume, test_volume, 2)
|
|
|
|
def test_create_snapshot(self):
|
|
self.driver.create_snapshot(test_snapshot)
|
|
|
|
def test_create_snapshot_metadata(self):
|
|
self._mock_volume.create_snapshot.return_value = self._mock_volume
|
|
self.driver.create_snapshot(test_snapshot)
|
|
self._mock_volume.set_metadata_from_dict.assert_called_once()
|
|
|
|
def test_create_snapshot_volume_doesnt_exist(self):
|
|
self._system.volumes.safe_get.return_value = None
|
|
self.assertRaises(exception.InvalidVolume,
|
|
self.driver.create_snapshot, test_snapshot)
|
|
|
|
def test_create_snapshot_api_fail(self):
|
|
self._mock_volume.create_snapshot.side_effect = self._raise_infinisdk
|
|
self.assertRaises(exception.VolumeBackendAPIException,
|
|
self.driver.create_snapshot, test_snapshot)
|
|
|
|
@mock.patch("cinder.volume.utils.copy_volume")
|
|
@mock.patch("cinder.utils.brick_get_connector")
|
|
@mock.patch("cinder.utils.brick_get_connector_properties",
|
|
return_value=test_connector)
|
|
@mock.patch("cinder.volume.volume_types.get_volume_type_qos_specs")
|
|
def test_create_volume_from_snapshot(self, *mocks):
|
|
self.driver.create_volume_from_snapshot(test_clone, test_snapshot)
|
|
|
|
def test_create_volume_from_snapshot_doesnt_exist(self):
|
|
self._system.volumes.safe_get.return_value = None
|
|
self.assertRaises(exception.InvalidSnapshot,
|
|
self.driver.create_volume_from_snapshot,
|
|
test_clone, test_snapshot)
|
|
|
|
def test_create_volume_from_snapshot_create_fails(self):
|
|
self._mock_volume.create_child.side_effect = self._raise_infinisdk
|
|
self.assertRaises(exception.VolumeBackendAPIException,
|
|
self.driver.create_volume_from_snapshot,
|
|
test_clone, test_snapshot)
|
|
|
|
@mock.patch("cinder.utils.brick_get_connector_properties",
|
|
return_value=test_connector)
|
|
@mock.patch("cinder.volume.volume_types.get_volume_type_qos_specs")
|
|
def test_create_volume_from_snapshot_map_fails(self, *mocks):
|
|
self._mock_host.map_volume.side_effect = self._raise_infinisdk
|
|
self.assertRaises(exception.VolumeBackendAPIException,
|
|
self.driver.create_volume_from_snapshot,
|
|
test_clone, test_snapshot)
|
|
|
|
@mock.patch("cinder.volume.utils.copy_volume")
|
|
@mock.patch("cinder.utils.brick_get_connector")
|
|
@mock.patch("cinder.utils.brick_get_connector_properties",
|
|
return_value=test_connector)
|
|
def test_create_volume_from_snapshot_delete_clone_fails(self, *mocks):
|
|
self._mock_volume.delete.side_effect = self._raise_infinisdk
|
|
self.assertRaises(exception.VolumeBackendAPIException,
|
|
self.driver.create_volume_from_snapshot,
|
|
test_clone, test_snapshot)
|
|
|
|
def test_delete_snapshot(self):
|
|
self.driver.delete_snapshot(test_snapshot)
|
|
|
|
def test_delete_snapshot_doesnt_exist(self):
|
|
self._system.volumes.safe_get.return_value = None
|
|
# should not raise an exception
|
|
self.driver.delete_snapshot(test_snapshot)
|
|
|
|
def test_delete_snapshot_api_fail(self):
|
|
self._mock_volume.safe_delete.side_effect = self._raise_infinisdk
|
|
self.assertRaises(exception.VolumeBackendAPIException,
|
|
self.driver.delete_snapshot, test_snapshot)
|
|
|
|
@mock.patch("cinder.volume.utils.copy_volume")
|
|
@mock.patch("cinder.utils.brick_get_connector")
|
|
@mock.patch("cinder.utils.brick_get_connector_properties",
|
|
return_value=test_connector)
|
|
@mock.patch("cinder.volume.volume_types.get_volume_type_qos_specs")
|
|
def test_create_cloned_volume(self, *mocks):
|
|
self.driver.create_cloned_volume(test_clone, test_volume)
|
|
|
|
def test_create_cloned_volume_volume_already_mapped(self):
|
|
mock_mapping = mock.Mock()
|
|
mock_mapping.get_volume.return_value = self._mock_volume
|
|
self._mock_volume.get_logical_units.return_value = [mock_mapping]
|
|
self.assertRaises(exception.VolumeBackendAPIException,
|
|
self.driver.create_cloned_volume,
|
|
test_clone, test_volume)
|
|
|
|
def test_create_cloned_volume_create_fails(self):
|
|
self._system.volumes.create.side_effect = self._raise_infinisdk
|
|
self.assertRaises(exception.VolumeBackendAPIException,
|
|
self.driver.create_cloned_volume,
|
|
test_clone, test_volume)
|
|
|
|
@mock.patch("cinder.utils.brick_get_connector_properties",
|
|
return_value=test_connector)
|
|
@mock.patch("cinder.volume.volume_types.get_volume_type_qos_specs")
|
|
def test_create_cloned_volume_map_fails(self, *mocks):
|
|
self._mock_host.map_volume.side_effect = self._raise_infinisdk
|
|
self.assertRaises(exception.VolumeBackendAPIException,
|
|
self.driver.create_cloned_volume,
|
|
test_clone, test_volume)
|
|
|
|
@mock.patch('cinder.volume.utils.is_group_a_cg_snapshot_type',
|
|
return_value=True)
|
|
def test_create_group(self, *mocks):
|
|
self.driver.create_group(None, test_group)
|
|
|
|
@mock.patch('cinder.volume.utils.is_group_a_cg_snapshot_type',
|
|
return_value=True)
|
|
def test_create_group_metadata(self, *mocks):
|
|
self.driver.create_group(None, test_group)
|
|
self._mock_group.set_metadata_from_dict.assert_called_once()
|
|
|
|
@mock.patch('cinder.volume.utils.is_group_a_cg_snapshot_type',
|
|
return_value=True)
|
|
def test_create_group_twice(self, *mocks):
|
|
self.driver.create_group(None, test_group)
|
|
self.driver.create_group(None, test_group)
|
|
|
|
@mock.patch('cinder.volume.utils.is_group_a_cg_snapshot_type',
|
|
return_value=True)
|
|
def test_create_group_api_fail(self, *mocks):
|
|
self._system.cons_groups.create.side_effect = self._raise_infinisdk
|
|
self.assertRaises(exception.VolumeBackendAPIException,
|
|
self.driver.create_group,
|
|
None, test_group)
|
|
|
|
@mock.patch('cinder.volume.utils.is_group_a_cg_snapshot_type',
|
|
return_value=True)
|
|
def test_delete_group(self, *mocks):
|
|
self.driver.delete_group(None, test_group, [test_volume])
|
|
|
|
@mock.patch('cinder.volume.utils.is_group_a_cg_snapshot_type',
|
|
return_value=True)
|
|
def test_delete_group_doesnt_exist(self, *mocks):
|
|
self._system.cons_groups.safe_get.return_value = None
|
|
self.driver.delete_group(None, test_group, [test_volume])
|
|
|
|
@mock.patch('cinder.volume.utils.is_group_a_cg_snapshot_type',
|
|
return_value=True)
|
|
def test_delete_group_api_fail(self, *mocks):
|
|
self._mock_group.safe_delete.side_effect = self._raise_infinisdk
|
|
self.assertRaises(exception.VolumeBackendAPIException,
|
|
self.driver.delete_group,
|
|
None, test_group, [test_volume])
|
|
|
|
@mock.patch('cinder.volume.utils.is_group_a_cg_snapshot_type',
|
|
return_value=True)
|
|
def test_update_group_add_and_remove(self, *mocks):
|
|
self.driver.update_group(None, test_group,
|
|
[test_volume], [test_volume])
|
|
|
|
@mock.patch('cinder.volume.utils.is_group_a_cg_snapshot_type',
|
|
return_value=True)
|
|
def test_update_group_api_fail(self, *mocks):
|
|
self._mock_group.add_member.side_effect = self._raise_infinisdk
|
|
self.assertRaises(exception.VolumeBackendAPIException,
|
|
self.driver.update_group,
|
|
None, test_group,
|
|
[test_volume], [test_volume])
|
|
|
|
@mock.patch("cinder.volume.utils.copy_volume")
|
|
@mock.patch("cinder.utils.brick_get_connector")
|
|
@mock.patch("cinder.utils.brick_get_connector_properties",
|
|
return_value=test_connector)
|
|
@mock.patch('cinder.volume.utils.is_group_a_cg_snapshot_type',
|
|
return_value=True)
|
|
@mock.patch("cinder.volume.volume_types.get_volume_type_qos_specs")
|
|
def test_create_group_from_src_snaps(self, *mocks):
|
|
self.driver.create_group_from_src(None, test_group, [test_volume],
|
|
test_snapgroup, [test_snapshot],
|
|
None, None)
|
|
|
|
@mock.patch("cinder.volume.utils.copy_volume")
|
|
@mock.patch("cinder.utils.brick_get_connector")
|
|
@mock.patch("cinder.utils.brick_get_connector_properties",
|
|
return_value=test_connector)
|
|
@mock.patch('cinder.volume.utils.is_group_a_cg_snapshot_type',
|
|
return_value=True)
|
|
@mock.patch("cinder.volume.volume_types.get_volume_type_qos_specs")
|
|
def test_create_group_from_src_vols(self, *mocks):
|
|
self.driver.create_group_from_src(None, test_group, [test_volume],
|
|
None, None,
|
|
test_group, [test_volume])
|
|
|
|
@mock.patch('cinder.volume.utils.is_group_a_cg_snapshot_type',
|
|
return_value=True)
|
|
def test_create_group_snap(self, *mocks):
|
|
mock_snapgroup = mock.Mock()
|
|
mock_snapgroup.get_members.return_value = [self._mock_volume]
|
|
self._mock_volume.get_parent.return_value = self._mock_volume
|
|
self._mock_volume.get_name.return_value = ''
|
|
self._mock_group.create_snapshot.return_value = mock_snapgroup
|
|
self.driver.create_group_snapshot(None,
|
|
test_snapgroup,
|
|
[test_snapshot])
|
|
|
|
@mock.patch('cinder.volume.utils.is_group_a_cg_snapshot_type',
|
|
return_value=True)
|
|
def test_create_group_snap_api_fail(self, *mocks):
|
|
self._mock_group.create_snapshot.side_effect = self._raise_infinisdk
|
|
self.assertRaises(exception.VolumeBackendAPIException,
|
|
self.driver.create_group_snapshot, None,
|
|
test_snapgroup, [test_snapshot])
|
|
|
|
@mock.patch('cinder.volume.utils.is_group_a_cg_snapshot_type',
|
|
return_value=True)
|
|
def test_delete_group_snap(self, *mocks):
|
|
self.driver.delete_group_snapshot(None,
|
|
test_snapgroup,
|
|
[test_snapshot])
|
|
|
|
@mock.patch('cinder.volume.utils.is_group_a_cg_snapshot_type',
|
|
return_value=True)
|
|
def test_delete_group_snap_does_not_exist(self, *mocks):
|
|
self._system.cons_groups.safe_get.return_value = None
|
|
self.driver.delete_group_snapshot(None,
|
|
test_snapgroup,
|
|
[test_snapshot])
|
|
|
|
@mock.patch('cinder.volume.utils.is_group_a_cg_snapshot_type',
|
|
return_value=True)
|
|
def test_delete_group_snap_invalid_group(self, *mocks):
|
|
self._mock_group.is_snapgroup.return_value = False
|
|
self.assertRaises(exception.InvalidGroupSnapshot,
|
|
self.driver.delete_group_snapshot,
|
|
None, test_snapgroup, [test_snapshot])
|
|
|
|
@mock.patch('cinder.volume.utils.is_group_a_cg_snapshot_type',
|
|
return_value=True)
|
|
def test_delete_group_snap_api_fail(self, *mocks):
|
|
self._mock_group.safe_delete.side_effect = self._raise_infinisdk
|
|
self.assertRaises(exception.VolumeBackendAPIException,
|
|
self.driver.delete_group_snapshot,
|
|
None, test_snapgroup, [test_snapshot])
|
|
|
|
|
|
class InfiniboxDriverTestCaseFC(InfiniboxDriverTestCaseBase):
|
|
def test_initialize_connection_multiple_wwpns(self):
|
|
connector = {'wwpns': [TEST_WWN_1, TEST_WWN_2]}
|
|
result = self.driver.initialize_connection(test_volume, connector)
|
|
self.assertEqual(1, result["data"]["target_lun"])
|
|
|
|
|
|
class InfiniboxDriverTestCaseISCSI(InfiniboxDriverTestCaseBase):
|
|
def setUp(self):
|
|
super(InfiniboxDriverTestCaseISCSI, self).setUp()
|
|
self.configuration.infinidat_storage_protocol = 'iscsi'
|
|
self.configuration.infinidat_iscsi_netspaces = ['netspace1']
|
|
self.configuration.use_chap_auth = False
|
|
self.driver.do_setup(None)
|
|
|
|
def test_setup_without_netspaces_configured(self):
|
|
self.configuration.infinidat_iscsi_netspaces = []
|
|
self.assertRaises(exception.VolumeDriverException,
|
|
self.driver.do_setup, None)
|
|
|
|
def test_initialize_connection(self):
|
|
result = self.driver.initialize_connection(test_volume, test_connector)
|
|
self.assertEqual(1, result['data']['target_lun'])
|
|
|
|
def test_initialize_netspace_does_not_exist(self):
|
|
self._system.network_spaces.safe_get.return_value = None
|
|
self.assertRaises(exception.VolumeDriverException,
|
|
self.driver.initialize_connection,
|
|
test_volume, test_connector)
|
|
|
|
def test_initialize_netspace_has_no_ips(self):
|
|
self._mock_ns.get_ips.return_value = []
|
|
self.assertRaises(exception.VolumeDriverException,
|
|
self.driver.initialize_connection,
|
|
test_volume, test_connector)
|
|
|
|
def test_initialize_connection_with_chap(self):
|
|
self.configuration.use_chap_auth = True
|
|
result = self.driver.initialize_connection(test_volume, test_connector)
|
|
self.assertEqual(1, result['data']['target_lun'])
|
|
self.assertEqual('CHAP', result['data']['auth_method'])
|
|
self.assertIn('auth_username', result['data'])
|
|
self.assertIn('auth_password', result['data'])
|
|
|
|
def test_initialize_connection_multiple_netspaces(self):
|
|
self.configuration.infinidat_iscsi_netspaces = ['netspace1',
|
|
'netspace2']
|
|
result = self.driver.initialize_connection(test_volume, test_connector)
|
|
self.assertEqual(1, result['data']['target_lun'])
|
|
self.assertEqual(2, len(result['data']['target_luns']))
|
|
self.assertEqual(2, len(result['data']['target_iqns']))
|
|
self.assertEqual(2, len(result['data']['target_portals']))
|
|
|
|
def test_terminate_connection(self):
|
|
self.driver.terminate_connection(test_volume, test_connector)
|
|
|
|
|
|
class InfiniboxDriverTestCaseQoS(InfiniboxDriverTestCaseBase):
|
|
@mock.patch("cinder.volume.volume_types.get_volume_type_qos_specs")
|
|
def test_qos_max_ipos(self, qos_specs):
|
|
qos_specs.return_value = {'qos_specs': {'id': 'qos_name',
|
|
'consumer': 'back-end',
|
|
'specs': {'maxIOPS': 1000,
|
|
'maxBWS': None}}}
|
|
self.driver.create_volume(test_volume)
|
|
self._system.qos_policies.create.assert_called_once()
|
|
self._mock_qos_policy.assign_entity.assert_called_once()
|
|
|
|
@mock.patch("cinder.volume.volume_types.get_volume_type_qos_specs")
|
|
def test_qos_max_bws(self, qos_specs):
|
|
qos_specs.return_value = {'qos_specs': {'id': 'qos_name',
|
|
'consumer': 'back-end',
|
|
'specs': {'maxIOPS': None,
|
|
'maxBWS': 10000}}}
|
|
self.driver.create_volume(test_volume)
|
|
self._system.qos_policies.create.assert_called_once()
|
|
self._mock_qos_policy.assign_entity.assert_called_once()
|
|
|
|
@mock.patch("cinder.volume.volume_types.get_volume_type_qos_specs")
|
|
def test_qos_no_compat(self, qos_specs):
|
|
qos_specs.return_value = {'qos_specs': {'id': 'qos_name',
|
|
'consumer': 'back-end',
|
|
'specs': {'maxIOPS': 1000,
|
|
'maxBWS': 10000}}}
|
|
self._system.compat.has_qos.return_value = False
|
|
self.driver.create_volume(test_volume)
|
|
self._system.qos_policies.create.assert_not_called()
|
|
self._mock_qos_policy.assign_entity.assert_not_called()
|
|
|
|
@mock.patch("cinder.volume.volume_types.get_volume_type_qos_specs")
|
|
def test_qos_volume_type_id_none(self, qos_specs):
|
|
qos_specs.return_value = {'qos_specs': {'id': 'qos_name',
|
|
'consumer': 'back-end',
|
|
'specs': {'maxIOPS': 1000,
|
|
'maxBWS': 10000}}}
|
|
test_volume = mock.Mock(id=1, size=1, volume_type_id=None)
|
|
self.driver.create_volume(test_volume)
|
|
self._system.qos_policies.create.assert_not_called()
|
|
self._mock_qos_policy.assign_entity.assert_not_called()
|
|
|
|
@mock.patch("cinder.volume.volume_types.get_volume_type_qos_specs")
|
|
def test_qos_no_specs(self, qos_specs):
|
|
qos_specs.return_value = {'qos_specs': None}
|
|
self.driver.create_volume(test_volume)
|
|
self._system.qos_policies.create.assert_not_called()
|
|
self._mock_qos_policy.assign_entity.assert_not_called()
|
|
|
|
@mock.patch("cinder.volume.volume_types.get_volume_type_qos_specs")
|
|
def test_qos_front_end(self, qos_specs):
|
|
qos_specs.return_value = {'qos_specs': {'id': 'qos_name',
|
|
'consumer': 'front-end',
|
|
'specs': {'maxIOPS': 1000,
|
|
'maxBWS': 10000}}}
|
|
self.driver.create_volume(test_volume)
|
|
self._system.qos_policies.create.assert_not_called()
|
|
self._mock_qos_policy.assign_entity.assert_not_called()
|
|
|
|
@mock.patch("cinder.volume.volume_types.get_volume_type_qos_specs")
|
|
def test_qos_specs_empty(self, qos_specs):
|
|
qos_specs.return_value = {'qos_specs': {'id': 'qos_name',
|
|
'consumer': 'back-end',
|
|
'specs': {'maxIOPS': None,
|
|
'maxBWS': None}}}
|
|
self.driver.create_volume(test_volume)
|
|
self._system.qos_policies.create.assert_not_called()
|
|
self._mock_qos_policy.assign_entity.assert_not_called()
|
|
|
|
@mock.patch("cinder.volume.volume_types.get_volume_type_qos_specs")
|
|
def test_qos_policy_exists(self, qos_specs):
|
|
qos_specs.return_value = {'qos_specs': {'id': 'qos_name',
|
|
'consumer': 'back-end',
|
|
'specs': {'maxIOPS': 1000,
|
|
'maxBWS': 10000}}}
|
|
self._system.qos_policies.safe_get.return_value = self._mock_qos_policy
|
|
self.driver.create_volume(test_volume)
|
|
self._system.qos_policies.create.assert_not_called()
|
|
self._mock_qos_policy.assign_entity.assert_called()
|