cinder/cinder/tests/unit/volume/drivers/test_rsd.py

1297 lines
55 KiB
Python

# 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.
import sys
from unittest import mock
import fixtures
from cinder import exception
from cinder.i18n import _
from cinder.tests.unit import test
from cinder.tests.unit.volume import test_driver
MOCK_URL = "http://www.mock.url.com:4242"
MOCK_USER = "mock_user"
MOCK_PASSWORD = "mock_password"
class MockHTTPError(Exception):
def __init__(self, msg):
super(MockHTTPError, self).__init__(msg)
class MockConnectionError(Exception):
def __init__(self, msg):
super(MockConnectionError, self).__init__(msg)
class MockResourceNotFoundError(Exception):
def __init__(self, msg):
super(MockResourceNotFoundError, self).__init__(msg)
class MockBadRequestError(Exception):
def __init__(self, msg):
super(MockBadRequestError, self).__init__(msg)
self.body = {
"@Message.ExtendedInfo":
[{"Message":
"Cannot delete source snapshot volume when "
"other clone volumes are based on this snapshot."}]}
class MockInvalidParameterValueError(Exception):
def __init__(self, msg):
super(MockInvalidParameterValueError, self).__init__(msg)
fake_RSDLib = mock.Mock()
fake_rsd_lib = mock.Mock()
fake_rsd_lib.RSDLib = mock.MagicMock(return_value=fake_RSDLib)
fake_sushy = mock.Mock()
fake_sushy.exceptions = mock.Mock()
fake_sushy.exceptions.HTTPError = MockHTTPError
fake_sushy.exceptions.ConnectionError = MockConnectionError
fake_sushy.exceptions.ResourceNotFoundError = MockResourceNotFoundError
fake_sushy.exceptions.BadRequestError = MockBadRequestError
fake_sushy.exceptions.InvalidParameterValueError = (
MockInvalidParameterValueError)
sys.modules['rsd_lib'] = fake_rsd_lib
sys.modules['sushy'] = fake_sushy
from cinder.volume.drivers import rsd as rsd_driver # noqa
class RSDClientTestCase(test.TestCase):
def setUp(self):
super(RSDClientTestCase, self).setUp()
self.mock_rsd_lib = mock.Mock()
self.mock_rsd_lib._rsd_api_version = "2.4.0"
self.mock_rsd_lib._redfish_version = "1.1.0"
self.mock_rsd_lib_factory = mock.MagicMock(
return_value=self.mock_rsd_lib)
fake_RSDLib.factory = self.mock_rsd_lib_factory
self.rsd_client = rsd_driver.RSDClient(self.mock_rsd_lib)
self.uuid = "84cff9ea-de0f-4841-8645-58620adf49b2"
self.url = "/redfish/v1/Resource/Type"
self.resource_url = self.url + "/" + self.uuid
def _generate_rsd_storage_objects(self):
self._mock_stor_obj_1 = mock.Mock()
self._mock_stor_obj_2 = mock.Mock()
self._mock_stor_obj_3 = mock.Mock()
self._mock_drive_obj_1 = mock.Mock()
self._mock_drive_obj_2 = mock.Mock()
self._mock_drive_obj_3 = mock.Mock()
self._mock_drive_obj_1.protocol = "NVMe"
self._mock_drive_obj_2.protocol = "Blank"
self._mock_drive_obj_3.protocol = ""
self._mock_stor_obj_1.drives.get_members = mock.MagicMock(
return_value=[self._mock_drive_obj_1])
self._mock_stor_obj_2.drives.get_members = mock.MagicMock(
return_value=[self._mock_drive_obj_2])
self._mock_stor_obj_3.drives.get_members = mock.MagicMock(
return_value=[self._mock_drive_obj_3])
self._mock_stor_collection = [self._mock_stor_obj_1,
self._mock_stor_obj_2,
self._mock_stor_obj_3]
def test_initialize(self):
rsd_client = rsd_driver.RSDClient.initialize(MOCK_URL, MOCK_USER,
MOCK_PASSWORD,
verify=True)
self.assertTrue(isinstance(rsd_client, rsd_driver.RSDClient))
def test_initialize_rsd_api_incorrect_version(self):
self.mock_rsd_lib._rsd_api_version = "2.3.0"
rsd_client_init = rsd_driver.RSDClient.initialize
self.assertRaises(exception.VolumeBackendAPIException,
rsd_client_init, MOCK_URL, MOCK_USER,
MOCK_PASSWORD, False)
def test_initialize_rsd_api_higher_version(self):
self.mock_rsd_lib._rsd_api_version = "2.5.0"
rsd_client = rsd_driver.RSDClient.initialize(MOCK_URL, MOCK_USER,
MOCK_PASSWORD,
verify=True)
self.assertTrue(isinstance(rsd_client, rsd_driver.RSDClient))
def test_initialize_rsd_lib_incorrect_version(self):
self.mock_rsd_lib._redfish_version = "1.0.0"
rsd_client_init = rsd_driver.RSDClient.initialize
self.assertRaises(exception.VolumeBackendAPIException,
rsd_client_init, MOCK_URL, MOCK_USER,
MOCK_PASSWORD, False)
def test_initialize_rsd_lib_higher_version(self):
self.mock_rsd_lib._redfish_version = "1.5.0"
rsd_client = rsd_driver.RSDClient.initialize(MOCK_URL, MOCK_USER,
MOCK_PASSWORD,
verify=True)
self.assertTrue(isinstance(rsd_client, rsd_driver.RSDClient))
def test_initialize_invalid_credentials(self):
self.mock_rsd_lib_factory.side_effect = (
fixtures._fixtures.timeout.TimeoutException)
rsd_client_init = rsd_driver.RSDClient.initialize
self.assertRaises(exception.VolumeBackendAPIException,
rsd_client_init, MOCK_URL, MOCK_USER,
MOCK_PASSWORD, False)
def test_get_storage(self):
mock_stor_serv = mock.Mock()
self.mock_rsd_lib.get_storage_service = mock.MagicMock(
return_value=mock_stor_serv)
stor_serv = self.rsd_client._get_storage(self.resource_url)
self.assertEqual(mock_stor_serv, stor_serv)
self.mock_rsd_lib.get_storage_service.assert_called_with(self.url)
def test_get_storages(self):
self._generate_rsd_storage_objects()
get_mem = self.mock_rsd_lib.get_storage_service_collection.return_value
get_mem.get_members.return_value = self._mock_stor_collection
storages = self.rsd_client._get_storages()
self.assertEqual([self._mock_stor_obj_1], storages)
def test_get_storages_non_nvme(self):
self._generate_rsd_storage_objects()
get_mem = self.mock_rsd_lib.get_storage_service_collection.return_value
get_mem.get_members.return_value = self._mock_stor_collection
storages = self.rsd_client._get_storages(False)
self.assertEqual([self._mock_stor_obj_1, self._mock_stor_obj_2,
self._mock_stor_obj_3], storages)
def test_get_storages_empty_storage(self):
self._generate_rsd_storage_objects()
get_mem = self.mock_rsd_lib.get_storage_service_collection.return_value
get_mem.get_members.return_value = []
storages = self.rsd_client._get_storages()
self.assertEqual([], storages)
def test_get_storages_empty_drive(self):
self._generate_rsd_storage_objects()
get_mem = self.mock_rsd_lib.get_storage_service_collection.return_value
get_mem.get_members.return_value = self._mock_stor_collection
self._mock_stor_obj_1.drives.get_members = mock.MagicMock(
return_value=[])
storages = self.rsd_client._get_storages()
self.assertEqual([], storages)
def test_get_volume(self):
mock_stor_serv = mock.Mock()
mock_vol_serv = mock.Mock()
self.mock_rsd_lib.get_storage_service = mock.MagicMock(
return_value=mock_stor_serv)
mock_stor_serv.volumes.get_member = mock.MagicMock(
return_value=mock_vol_serv)
vol_serv = self.rsd_client._get_volume(self.resource_url)
self.assertEqual(mock_vol_serv, vol_serv)
self.mock_rsd_lib.get_storage_service.assert_called_with(self.url)
mock_stor_serv.volumes.get_member.assert_called_with(self.resource_url)
def test_get_providing_pool(self):
mock_providing_pool_collection = mock.Mock()
mock_providing_pool_collection.path = mock.Mock()
mock_providing_pool = mock.Mock()
mock_providing_pool.get_members = mock.Mock(
return_value=[mock_providing_pool_collection])
mock_volume = mock.Mock()
mock_volume.capacity_sources = [mock.Mock()]
mock_volume.capacity_sources[0].providing_pools = [mock_providing_pool]
provider_pool = self.rsd_client._get_providing_pool(mock_volume)
self.assertEqual(mock_providing_pool_collection.path, provider_pool)
def test_get_providing_pool_no_capacity(self):
mock_volume = mock.Mock()
mock_volume.capacity_sources = []
self.assertRaises(exception.ValidationError,
self.rsd_client._get_providing_pool,
mock_volume)
def test_get_providing_pool_no_pools(self):
mock_volume = mock.Mock()
mock_volume.capacity_sources = [mock.Mock()]
mock_volume.capacity_sources[0].providing_pools = []
self.assertRaises(exception.ValidationError,
self.rsd_client._get_providing_pool,
mock_volume)
def test_get_providing_pool_too_many_pools(self):
mock_volume = mock.Mock()
mock_volume.capacity_sources = [mock.Mock()]
mock_volume.capacity_sources[0].providing_pools = [mock.Mock(),
mock.Mock()]
self.assertRaises(exception.ValidationError,
self.rsd_client._get_providing_pool,
mock_volume)
def test_create_vol_or_snap(self):
mock_stor = mock.Mock()
size_in_bytes = 10737418240
mock_stor.volumes.create_volume = mock.Mock(
return_value=self.resource_url)
stor_url = self.rsd_client._create_vol_or_snap(mock_stor,
size_in_bytes)
self.assertEqual(self.resource_url, stor_url)
mock_stor.volumes.create_volume.assert_called_with(
size_in_bytes, capacity_sources=None, replica_infos=None)
def test_create_vol_or_snap_stor_pool(self):
mock_stor = mock.Mock()
size_in_bytes = 10737418240
stor_uuid = "/redfish/v1/StorageService/NvMeoE1/StoragePools/2"
expected_capacity = [{
"ProvidingPools": [{
"@odata.id": stor_uuid
}]
}]
mock_stor.volumes.create_volume = mock.Mock(
return_value=self.resource_url)
stor_url = self.rsd_client._create_vol_or_snap(mock_stor,
size_in_bytes,
pool_url=stor_uuid)
self.assertEqual(self.resource_url, stor_url)
mock_stor.volumes.create_volume.assert_called_with(
size_in_bytes,
capacity_sources=expected_capacity,
replica_infos=None)
def test_create_vol_or_snap_source_snap(self):
mock_stor = mock.Mock()
size_in_bytes = 10737418240
stor_uuid = "/redfish/v1/StorageService/NvMeoE1/StoragePools/2"
expected_replica = [{
"ReplicaType": "Clone",
"Replica": {"@odata.id": stor_uuid}
}]
mock_stor.volumes.create_volume = mock.Mock(
return_value=self.resource_url)
stor_url = self.rsd_client._create_vol_or_snap(mock_stor,
size_in_bytes,
source_snap=stor_uuid)
self.assertEqual(self.resource_url, stor_url)
mock_stor.volumes.create_volume.assert_called_with(
size_in_bytes,
capacity_sources=None,
replica_infos=expected_replica)
def test_create_vol_or_snap_source_vol(self):
mock_stor = mock.Mock()
size_in_bytes = 10737418240
stor_uuid = "/redfish/v1/StorageService/NvMeoE1/StoragePools/2"
expected_replica = [{
"ReplicaType": "Snapshot",
"Replica": {"@odata.id": stor_uuid}
}]
mock_stor.volumes.create_volume = mock.Mock(
return_value=self.resource_url)
stor_url = self.rsd_client._create_vol_or_snap(mock_stor,
size_in_bytes,
source_vol=stor_uuid)
self.assertEqual(self.resource_url, stor_url)
mock_stor.volumes.create_volume.assert_called_with(
size_in_bytes,
capacity_sources=None,
replica_infos=expected_replica)
def test_create_vol_or_snap_source_snap_vol(self):
mock_stor = mock.Mock()
size_in_bytes = 10737418240
stor_uuid = "/redfish/v1/StorageService/NvMeoE1/StoragePools/2"
mock_stor.volumes.create_volume = mock.Mock(
return_value=self.resource_url)
self.assertRaises(exception.InvalidInput,
self.rsd_client._create_vol_or_snap,
mock_stor, size_in_bytes, source_snap=stor_uuid,
source_vol=stor_uuid)
def test_create_volume(self):
self._generate_rsd_storage_objects()
size_in_Gb = 10
expected_size_in_bytes = 10737418240
self._mock_stor_obj_1.volumes.create_volume = mock.Mock(
return_value=self.resource_url)
self.rsd_client._get_storages = mock.Mock(
return_value=[self._mock_stor_obj_1])
stor_url = self.rsd_client.create_volume(size_in_Gb)
self._mock_stor_obj_1.volumes.create_volume.assert_called_with(
expected_size_in_bytes, capacity_sources=None, replica_infos=None)
self.assertEqual(self.resource_url, stor_url)
def test_create_volume_no_storage(self):
self._generate_rsd_storage_objects()
size_in_Gb = 10
self.rsd_client._get_storages = mock.Mock(
return_value=[])
self.assertRaises(exception.VolumeBackendAPIException,
self.rsd_client.create_volume, size_in_Gb)
def test_create_volume_multiple_storages(self):
self._generate_rsd_storage_objects()
size_in_Gb = 10
expected_size_in_bytes = 10737418240
mock_resp = mock.Mock()
mock_resp.status = "404"
self._mock_stor_obj_1.volumes.create_volume = mock.Mock(
return_value=self.resource_url)
self._mock_stor_obj_2.volumes.create_volume = mock.Mock(
side_effect=MockHTTPError("HTTP Error"))
self._mock_stor_obj_3.volumes.create_volume = mock.Mock(
side_effect=MockConnectionError("Connection Error"))
self.rsd_client._get_storages = mock.Mock(
return_value=[self._mock_stor_obj_3,
self._mock_stor_obj_2,
self._mock_stor_obj_1])
stor_url = self.rsd_client.create_volume(size_in_Gb)
self._mock_stor_obj_1.volumes.create_volume.assert_called_with(
expected_size_in_bytes, capacity_sources=None,
replica_infos=None)
self.assertEqual(self.resource_url, stor_url)
def test_clone_volume(self):
mock_volume = mock.Mock()
mock_volume.capacity_bytes = 10737418240
mock_volume.capacity_sources = [mock.Mock()]
mock_volume.capacity_sources[0].providing_pools = [mock.Mock()]
mock_storage = mock.Mock()
self.rsd_client._get_volume = mock.Mock(return_value=mock_volume)
self.rsd_client._get_storage = mock.Mock(return_value=mock_storage)
self.rsd_client._create_vol_or_snap = mock.Mock(
return_value=self.resource_url)
self.rsd_client._get_providing_pool = mock.Mock(
return_value=self.resource_url)
vol_url, snap_url = self.rsd_client.clone_volume(self.resource_url)
self.assertEqual(self.resource_url, vol_url)
self.assertEqual(self.resource_url, snap_url)
self.rsd_client._create_vol_or_snap.assert_called_with(
mock.ANY, 10737418240, pool_url=self.resource_url,
source_snap=self.resource_url)
def test_clone_volume_size_increase(self):
mock_volume = mock.Mock()
mock_volume.capacity_bytes = 10737418240
new_size = 20
mock_volume.capacity_sources = [mock.Mock()]
mock_volume.capacity_sources[0].providing_pools = [mock.Mock()]
mock_storage = mock.Mock()
self.rsd_client._get_volume = mock.Mock(return_value=mock_volume)
self.rsd_client._get_storage = mock.Mock(return_value=mock_storage)
self.rsd_client._create_vol_or_snap = mock.Mock(
return_value=self.resource_url)
self.rsd_client._get_providing_pool = mock.Mock(
return_value=self.resource_url)
vol_url, snap_url = self.rsd_client.clone_volume(self.resource_url,
new_size)
self.assertEqual(self.resource_url, vol_url)
self.assertEqual(self.resource_url, snap_url)
self.rsd_client._create_vol_or_snap.assert_called_with(
mock.ANY, 21474836480, pool_url=self.resource_url,
source_snap=self.resource_url)
def test_clone_volume_fail(self):
mock_volume = mock.Mock()
mock_volume.capacity_bytes = 10737418240
mock_volume.capacity_sources = [mock.Mock()]
mock_volume.capacity_sources[0].providing_pools = [mock.Mock()]
mock_storage = mock.Mock()
self.rsd_client._get_volume = mock.Mock(return_value=mock_volume)
self.rsd_client._get_storage = mock.Mock(return_value=mock_storage)
self.rsd_client.delete_vol_or_snap = mock.Mock()
self.rsd_client._create_vol_or_snap = mock.Mock(
return_value=self.resource_url,
side_effect=[None, exception.InvalidInput(
reason=(_("_create_vol_or_snap failed")))])
self.rsd_client._get_providing_pool = mock.Mock(
return_value=self.resource_url)
self.assertRaises(exception.VolumeBackendAPIException,
self.rsd_client.clone_volume,
self.resource_url)
self.rsd_client.delete_vol_or_snap.assert_called_once()
def test_create_volume_from_snap(self):
mock_snap = mock.Mock()
mock_storage = mock.Mock()
mock_snap.capacity_bytes = 10737418240
self.rsd_client._get_storage = mock.Mock(return_value=mock_storage)
self.rsd_client._get_volume = mock.Mock(return_value=mock_snap)
self.rsd_client._get_providing_pool = mock.Mock(
return_value=self.resource_url)
self.rsd_client._create_vol_or_snap = mock.Mock(
return_value=self.resource_url)
volume_url = self.rsd_client.create_volume_from_snap(self.resource_url)
self.assertEqual(self.resource_url, volume_url)
self.rsd_client._create_vol_or_snap.assert_called_with(
mock.ANY,
10737418240,
pool_url=self.resource_url,
source_snap=self.resource_url)
def test_create_volume_from_snap_with_size(self):
mock_snap = mock.Mock()
mock_storage = mock.Mock()
mock_snap.capacity_bytes = 10737418240
expected_capacity_bytes = 21474836480
self.rsd_client._get_storage = mock.Mock(return_value=mock_storage)
self.rsd_client._get_volume = mock.Mock(return_value=mock_snap)
self.rsd_client._get_providing_pool = mock.Mock(
return_value=self.resource_url)
self.rsd_client._create_vol_or_snap = mock.Mock(
return_value=self.resource_url)
volume_url = self.rsd_client.create_volume_from_snap(
self.resource_url, 20)
self.assertEqual(self.resource_url, volume_url)
self.rsd_client._create_vol_or_snap.assert_called_with(
mock.ANY,
expected_capacity_bytes,
pool_url=self.resource_url,
source_snap=self.resource_url)
def test_create_volume_from_snap_create_failed(self):
mock_snap = mock.Mock()
mock_storage = mock.Mock()
mock_snap.capacity_bytes = 10737418240
self.rsd_client._get_storage = mock.Mock(return_value=mock_storage)
self.rsd_client._get_volume = mock.Mock(return_value=mock_snap)
self.rsd_client._get_providing_pool = mock.Mock(
return_value=self.resource_url)
self.rsd_client._create_vol_or_snap = mock.Mock(
return_value=self.resource_url,
side_effect=[exception.InvalidInput(
reason=_("_create_vol_or_snap failed."))])
self.assertRaises(
exception.VolumeBackendAPIException,
self.rsd_client.create_volume_from_snap,
self.resource_url)
def test_delete_vol_or_snap(self):
mock_volume = mock.Mock()
mock_volume.links.endpoints = []
mock_volume.delete = mock.Mock()
self.rsd_client._get_volume = mock.Mock(return_value=mock_volume)
self.rsd_client.delete_vol_or_snap(self.resource_url)
mock_volume.delete.assert_called_once()
def test_delete_vol_or_snap_failed_delete(self):
mock_volume = mock.Mock()
mock_volume.links.endpoints = []
mock_volume.delete = mock.Mock(side_effect=[
RuntimeError("delete error")])
self.rsd_client._get_volume = mock.Mock(return_value=mock_volume)
self.assertRaises(
exception.VolumeBackendAPIException,
self.rsd_client.delete_vol_or_snap,
self.resource_url)
def test_delete_vol_or_snap_non_exist(self):
mock_volume = mock.Mock()
mock_volume.links.endpoints = []
mock_volume.delete = mock.Mock()
self.rsd_client._get_volume = mock.Mock(
side_effect=MockResourceNotFoundError("volume doesn't exist!"))
self.assertRaises(exception.VolumeBackendAPIException,
self.rsd_client.delete_vol_or_snap,
self.resource_url,
ignore_non_exist=True)
mock_volume.delete.assert_not_called()
def test_delete_vol_or_snap_has_endpoints(self):
mock_volume = mock.Mock()
mock_volume.links.endpoints = [mock.Mock()]
mock_volume.delete = mock.Mock()
self.rsd_client._get_volume = mock.Mock(return_value=mock_volume)
self.assertRaises(exception.VolumeBackendAPIException,
self.rsd_client.delete_vol_or_snap,
self.resource_url)
mock_volume.delete.assert_not_called()
def test_delete_vol_or_snap_has_deps(self):
mock_volume = mock.Mock()
mock_volume.links.endpoints = [mock.Mock()]
mock_volume.delete = mock.Mock(
side_effect=MockBadRequestError("busy!"))
self.rsd_client._get_volume = mock.Mock(return_value=mock_volume)
self.rsd_client.delete_vol_or_snap = mock.Mock(
side_effect=[None, exception.VolumeBackendAPIException(
data="error")])
self.rsd_client.delete_vol_or_snap(self.resource_url)
self.rsd_client.delete_vol_or_snap.assert_called_once()
def test_attach_volume_to_node_invalid_vol_url(self):
self.rsd_client._get_volume = mock.Mock(side_effect=[
RuntimeError("_get_volume failed")])
self.rsd_client._get_node = mock.Mock()
self.assertRaises(
exception.VolumeBackendAPIException,
self.rsd_client.attach_volume_to_node,
self.resource_url,
self.resource_url)
self.rsd_client._get_volume.assert_called_once()
self.rsd_client._get_node.assert_not_called()
def test_attach_volume_to_node_invalid_node_url(self):
mock_volume = mock.Mock()
self.rsd_client._get_volume = mock.Mock(return_value=mock_volume)
self.rsd_client._get_node = mock.Mock(side_effect=[
RuntimeError("_get_node failed")])
self.assertRaises(
exception.VolumeBackendAPIException,
self.rsd_client.attach_volume_to_node,
self.resource_url,
self.resource_url)
self.rsd_client._get_volume.assert_called_once()
self.rsd_client._get_node.assert_called_once()
def test_attach_volume_to_node_already_attached(self):
mock_volume = mock.Mock()
mock_node = mock.Mock()
mock_volume.links.endpoints = [mock.Mock()]
self.rsd_client._get_volume = mock.Mock(return_value=mock_volume)
self.rsd_client._get_node = mock.Mock(return_value=mock_node)
self.assertRaises(
exception.VolumeBackendAPIException,
self.rsd_client.attach_volume_to_node,
self.resource_url,
self.resource_url)
self.rsd_client._get_volume.assert_called_once()
self.rsd_client._get_node.assert_called_once()
@mock.patch('time.sleep')
def test_attach_volume_to_node_too_few_endpoints(self, mock_sleep):
mock_volume = mock.Mock()
mock_node = mock.Mock()
mock_volume.links.endpoints = []
mock_node.detach_endpoint = mock.Mock()
self.rsd_client._get_volume = mock.Mock(return_value=mock_volume)
self.rsd_client._get_node = mock.Mock(return_value=mock_node)
self.rsd_client._get_nqn_endpoints = mock.Mock(return_value=[])
self.assertRaises(
rsd_driver.RSDRetryableException,
self.rsd_client.attach_volume_to_node,
self.resource_url,
self.resource_url)
self.assertEqual(5, mock_node.attach_endpoint.call_count)
self.assertEqual(5, mock_node.detach_endpoint.call_count)
@mock.patch('time.sleep')
def test_attach_volume_to_node_too_many_endpoints(self, mock_sleep):
mock_volume = mock.Mock()
mock_node = mock.Mock()
mock_volume.links.endpoints = []
self.rsd_client._get_volume = mock.Mock(return_value=mock_volume)
self.rsd_client._get_node = mock.Mock(return_value=mock_node)
self.rsd_client._get_nqn_endpoints = mock.Mock(return_value=[
mock.Mock(),
mock.Mock()])
self.assertRaises(
rsd_driver.RSDRetryableException,
self.rsd_client.attach_volume_to_node,
self.resource_url,
self.resource_url)
self.assertEqual(5, mock_node.attach_endpoint.call_count)
self.assertEqual(5, mock_node.detach_endpoint.call_count)
@mock.patch('time.sleep')
def test_attach_volume_to_node_too_few_ip_transport(self, mock_sleep):
mock_volume = mock.Mock()
mock_node = mock.Mock()
mock_target_nqn = mock.Mock()
v_endpoints = {"IPTransportDetails": []}
mock_v_endpoints = [(mock_target_nqn, v_endpoints)]
mock_volume.links.endpoints = []
self.rsd_client._get_volume = mock.Mock(return_value=mock_volume)
self.rsd_client._get_node = mock.Mock(return_value=mock_node)
self.rsd_client._get_nqn_endpoints = mock.Mock(
return_value=mock_v_endpoints)
self.assertRaises(
rsd_driver.RSDRetryableException,
self.rsd_client.attach_volume_to_node,
self.resource_url,
self.resource_url)
self.assertEqual(5, mock_node.attach_endpoint.call_count)
self.assertEqual(5, mock_node.detach_endpoint.call_count)
@mock.patch('time.sleep')
def test_attach_volume_to_node_too_many_ip_transport(self, mock_sleep):
mock_volume = mock.Mock()
mock_node = mock.Mock()
mock_target_nqn = mock.Mock()
v_endpoints = {"IPTransportDetails": [mock.Mock(), mock.Mock()]}
mock_v_endpoints = [(mock_target_nqn, v_endpoints)]
mock_volume.links.endpoints = []
self.rsd_client._get_volume = mock.Mock(return_value=mock_volume)
self.rsd_client._get_node = mock.Mock(return_value=mock_node)
self.rsd_client._get_nqn_endpoints = mock.Mock(
return_value=mock_v_endpoints)
self.assertRaises(
rsd_driver.RSDRetryableException,
self.rsd_client.attach_volume_to_node,
self.resource_url,
self.resource_url)
self.assertEqual(5, mock_node.attach_endpoint.call_count)
self.assertEqual(5, mock_node.detach_endpoint.call_count)
@mock.patch('time.sleep')
def test_attach_volume_to_node_no_n_endpoints(self, mock_sleep):
mock_volume = mock.Mock()
mock_node = mock.Mock()
mock_target_nqn = mock.Mock()
mock_ip = '0.0.0.0'
mock_port = 5446
target_ip = {"Address": mock_ip}
ip_transport = {"IPv4Address": target_ip, "Port": mock_port}
v_endpoints = {"IPTransportDetails": [ip_transport]}
mock_v_endpoints = [(mock_target_nqn, v_endpoints)]
mock_volume.links.endpoints = []
mock_node_system = mock.Mock()
mock_node_system.json = {"Links": {"Endpoints": []}}
self.mock_rsd_lib.get_system = mock.MagicMock(
return_value=mock_node_system)
self.rsd_client._get_volume = mock.Mock(return_value=mock_volume)
self.rsd_client._get_node = mock.Mock(return_value=mock_node)
self.rsd_client._get_nqn_endpoints = mock.Mock(side_effect=[
mock_v_endpoints, [],
mock_v_endpoints, [],
mock_v_endpoints, [],
mock_v_endpoints, [],
mock_v_endpoints, []])
self.assertRaises(
rsd_driver.RSDRetryableException,
self.rsd_client.attach_volume_to_node,
self.resource_url,
self.resource_url)
self.assertEqual(5, mock_node.attach_endpoint.call_count)
self.assertEqual(5, mock_node.detach_endpoint.call_count)
@mock.patch('time.sleep')
def test_attach_volume_to_node_retry_attach(self, mock_sleep):
mock_volume = mock.Mock()
mock_node = mock.Mock()
mock_target_nqn = mock.Mock()
mock_ip = '0.0.0.0'
mock_port = 5446
mock_host_nqn = 'host_nqn'
target_ip = {"Address": mock_ip}
ip_transport = {"IPv4Address": target_ip, "Port": mock_port}
v_endpoints = {"IPTransportDetails": [ip_transport]}
mock_v_endpoints = [(mock_target_nqn, v_endpoints)]
mock_n_endpoints = [(mock_host_nqn, v_endpoints)]
mock_volume.links.endpoints = []
mock_node_system = mock.Mock()
mock_node_system.json = {"Links": {"Endpoints": []}}
self.mock_rsd_lib.get_system = mock.MagicMock(
return_value=mock_node_system)
self.rsd_client._get_volume = mock.Mock(return_value=mock_volume)
self.rsd_client._get_node = mock.Mock(return_value=mock_node)
self.rsd_client._get_nqn_endpoints = mock.Mock(side_effect=[
mock_v_endpoints,
mock_n_endpoints])
mock_node.attach_endpoint = mock.Mock(side_effect=[
MockInvalidParameterValueError("invalid resource"), None])
ret_tuple = self.rsd_client.attach_volume_to_node(self.resource_url,
self.resource_url)
self.assertEqual((mock_ip, mock_port, mock_target_nqn,
mock_host_nqn), ret_tuple)
self.assertEqual(2, mock_node.attach_endpoint.call_count)
mock_node.detach_endpoint.assert_not_called()
@mock.patch('time.sleep')
def test_attach_volume_to_node_retry_post_attach(self, mock_sleep):
mock_volume = mock.Mock()
mock_node = mock.Mock()
mock_target_nqn = mock.Mock()
mock_ip = '0.0.0.0'
mock_port = 5446
mock_host_nqn = 'host_nqn'
target_ip = {"Address": mock_ip}
ip_transport = {"IPv4Address": target_ip, "Port": mock_port}
v_endpoints = {"IPTransportDetails": [ip_transport]}
mock_v_endpoints = [(mock_target_nqn, v_endpoints)]
mock_n_endpoints = [(mock_host_nqn, v_endpoints)]
mock_volume.links.endpoints = []
mock_node_system = mock.Mock()
mock_node_system.json = {"Links": {"Endpoints": []}}
self.mock_rsd_lib.get_system = mock.MagicMock(
return_value=mock_node_system)
self.rsd_client._get_volume = mock.Mock(return_value=mock_volume)
self.rsd_client._get_node = mock.Mock(return_value=mock_node)
self.rsd_client._get_nqn_endpoints = mock.Mock(side_effect=[
mock_v_endpoints,
[],
mock_v_endpoints,
mock_n_endpoints])
ret_tuple = self.rsd_client.attach_volume_to_node(self.resource_url,
self.resource_url)
self.assertEqual((mock_ip, mock_port, mock_target_nqn, mock_host_nqn),
ret_tuple)
self.assertEqual(2, mock_node.attach_endpoint.call_count)
mock_node.detach_endpoint.assert_called_once()
def test_attach_volume_to_node(self):
mock_volume = mock.Mock()
mock_node = mock.Mock()
mock_target_nqn = mock.Mock()
mock_ip = '0.0.0.0'
mock_port = 5446
mock_host_nqn = 'host_nqn'
target_ip = {"Address": mock_ip}
ip_transport = {"IPv4Address": target_ip, "Port": mock_port}
v_endpoints = {"IPTransportDetails": [ip_transport]}
mock_v_endpoints = [(mock_target_nqn, v_endpoints)]
mock_n_endpoints = [(mock_host_nqn, v_endpoints)]
mock_volume.links.endpoints = []
mock_node_system = mock.Mock()
mock_node_system.json = {"Links": {"Endpoints": []}}
self.mock_rsd_lib.get_system = mock.MagicMock(
return_value=mock_node_system)
self.rsd_client._get_volume = mock.Mock(return_value=mock_volume)
self.rsd_client._get_node = mock.Mock(return_value=mock_node)
self.rsd_client._get_nqn_endpoints = mock.Mock(side_effect=[
mock_v_endpoints,
mock_n_endpoints])
ret_tuple = self.rsd_client.attach_volume_to_node(self.resource_url,
self.resource_url)
self.assertEqual((mock_ip, mock_port, mock_target_nqn, mock_host_nqn),
ret_tuple)
mock_node.attach_endpoint.assert_called_once()
mock_node.detach_endpoint.assert_not_called()
def test_get_node_url_by_uuid(self):
mock_node = mock.Mock()
mock_node.path = self.resource_url
mock_node_system = mock.Mock()
mock_node_system.uuid = self.uuid
self.mock_rsd_lib.get_system = mock.MagicMock(
return_value=mock_node_system)
get_mem = self.mock_rsd_lib.get_node_collection.return_value
get_mem.get_members.return_value = [mock_node]
node_url = self.rsd_client.get_node_url_by_uuid(self.uuid.lower())
self.assertEqual(self.resource_url, node_url)
def test_get_node_url_by_uuid_uuid_not_present(self):
mock_node = mock.Mock()
mock_node.path = self.resource_url
mock_node_system = mock.Mock()
mock_node_system.uuid = self.uuid
self.mock_rsd_lib.get_system = mock.MagicMock(
return_value=mock_node_system)
get_mem = self.mock_rsd_lib.get_node_collection.return_value
get_mem.get_members.return_value = []
node_url = self.rsd_client.get_node_url_by_uuid(self.uuid.lower())
self.assertEqual("", node_url)
def test_get_node_url_by_uuid_multiple_uuids(self):
mock_node = mock.Mock()
mock_node.path = self.resource_url
mock_node_system = mock.Mock()
mock_node_system.uuid = self.uuid
second_uuid = "9f9244dd-59a1-4532-b548-df784c7"
mock_node_dummy = mock.Mock()
mock_node_dummy.path = self.url + "/" + second_uuid
mock_node_dummy_system = mock.Mock()
mock_node_dummy_system.uuid = second_uuid
self.mock_rsd_lib.get_system = mock.MagicMock(
side_effect=[mock_node_dummy_system, mock_node_system])
get_mem = self.mock_rsd_lib.get_node_collection.return_value
get_mem.get_members.return_value = [mock_node_dummy, mock_node]
node_url = self.rsd_client.get_node_url_by_uuid(self.uuid.lower())
self.assertEqual(self.resource_url, node_url)
def test_get_node_url_by_uuid_exception(self):
mock_node = mock.Mock()
mock_node.path = self.resource_url
mock_node_system = mock.Mock()
mock_node_system.uuid = self.uuid
self.mock_rsd_lib.get_system = mock.MagicMock(
return_value=mock_node_system)
get_mem = self.mock_rsd_lib.get_node_collection.return_value
get_mem.get_members.side_effect = [RuntimeError("Mock Exception")]
node_url = self.rsd_client.get_node_url_by_uuid(self.uuid.lower())
self.assertEqual("", node_url)
def test_get_stats(self):
mock_str_pool_1 = mock.Mock()
mock_str_pool_2 = mock.Mock()
mock_str_pool_3 = mock.Mock()
mock_str_pool_1.capacity.allocated_bytes = 10737418240
mock_str_pool_2.capacity.allocated_bytes = 21474836480
mock_str_pool_3.capacity.allocated_bytes = 32212254720
mock_str_pool_1.capacity.consumed_bytes = 5368709120
mock_str_pool_2.capacity.consumed_bytes = 10737418240
mock_str_pool_3.capacity.consumed_bytes = 21474836480
self._generate_rsd_storage_objects()
self._mock_stor_obj_1.storage_pools.get_members = mock.Mock(
return_value=[mock_str_pool_1])
self._mock_stor_obj_2.storage_pools.get_members = mock.Mock(
return_value=[mock_str_pool_2])
self._mock_stor_obj_3.storage_pools.get_members = mock.Mock(
return_value=[mock_str_pool_3])
self._mock_stor_obj_1.volumes.members_identities = [mock.Mock()]
self._mock_stor_obj_2.volumes.members_identities = [mock.Mock(),
mock.Mock()]
self._mock_stor_obj_3.volumes.members_identities = [mock.Mock(),
mock.Mock(),
mock.Mock()]
self.rsd_client._get_storages = mock.Mock(
return_value=self._mock_stor_collection)
stat_tuple = self.rsd_client.get_stats()
self.assertEqual((25.0, 60.0, 35.0, 6), stat_tuple)
def test_get_stats_fail(self):
self.rsd_client._get_storages = mock.Mock()
self.rsd_client._get_storages.side_effect = [
RuntimeError("Connection Error")]
stat_tuple = self.rsd_client.get_stats()
self.assertEqual((0, 0, 0, 0), stat_tuple)
class RSDDriverTestCase(test_driver.BaseDriverTestCase):
driver_name = "cinder.volume.drivers.rsd.RSDDriver"
def setUp(self):
super(RSDDriverTestCase, self).setUp()
self.mock_volume = mock.MagicMock()
self.mock_dict = {'size': 10}
self.volume.driver.rsdClient = mock.MagicMock()
self.rsd_client = self.volume.driver.rsdClient
self.uuid = "84cff9ea-de0f-4841-8645-58620adf49b2"
self.url = "/redfish/v1/Storage/StorageService"
self.resource_url = self.url + "/" + self.uuid
def test_create_volume(self):
self.rsd_client.create_volume = mock.Mock(
return_value=self.resource_url)
vol_update = self.volume.driver.create_volume(self.mock_dict)
self.assertEqual({'provider_location': self.resource_url}, vol_update)
def test_delete_volume(self):
self.rsd_client.delete_vol_or_snap = mock.Mock(
return_value=True)
self.mock_dict['provider_location'] = self.resource_url
self.mock_volume.__getitem__.side_effect = self.mock_dict.__getitem__
self.mock_volume.metadata.get = mock.Mock(
return_value=self.resource_url)
self.assertIsNone(self.volume.driver.delete_volume(self.mock_volume))
self.rsd_client.delete_vol_or_snap.assert_called()
self.assertEqual(2, self.rsd_client.delete_vol_or_snap.call_count)
def test_delete_volume_no_snapshot(self):
self.rsd_client.delete_vol_or_snap = mock.Mock(
return_value=True)
self.mock_dict['provider_location'] = self.resource_url
self.mock_volume.__getitem__.side_effect = self.mock_dict.__getitem__
self.mock_volume.metadata.get = mock.Mock(return_value=None)
self.assertIsNone(self.volume.driver.delete_volume(self.mock_volume))
self.rsd_client.delete_vol_or_snap.assert_called_once()
def test_delete_volume_no_volume_url(self):
self.rsd_client.delete_vol_or_snap = mock.Mock(
return_value=True)
self.mock_dict['provider_location'] = None
self.mock_volume.__getitem__.side_effect = self.mock_dict.__getitem__
self.assertIsNone(self.volume.driver.delete_volume(self.mock_volume))
self.rsd_client.delete_vol_or_snap.assert_not_called()
def test_delete_volume_busy_volume(self):
self.rsd_client.delete_vol_or_snap = mock.Mock(
side_effect=[exception.VolumeIsBusy(
volume_name=self.mock_volume.name)])
self.mock_dict['provider_location'] = self.resource_url
self.mock_volume.__getitem__.side_effect = self.mock_dict.__getitem__
self.assertRaises(exception.VolumeIsBusy,
self.volume.driver.delete_volume, self.mock_volume)
self.rsd_client.delete_vol_or_snap.assert_called_once()
def test_delete_volume_snap_deletion_error(self):
self.rsd_client.delete_vol_or_snap = mock.Mock(
side_effect=[None, exception.VolumeBackendAPIException(
data="error")])
self.mock_dict['provider_location'] = self.resource_url
self.mock_volume.__getitem__.side_effect = self.mock_dict.__getitem__
self.assertRaises(exception.VolumeBackendAPIException,
self.volume.driver.delete_volume, self.mock_volume)
self.rsd_client.delete_vol_or_snap.assert_called()
self.assertEqual(2, self.rsd_client.delete_vol_or_snap.call_count)
def test_get_volume_stats(self):
ret_tuple = (25.0, 60.0, 35.0, 6)
self.rsd_client.get_stats = mock.Mock(return_value=ret_tuple)
stats = self.volume.driver.get_volume_stats()
self.assertEqual({}, stats)
def test_get_volume_stats_refresh(self):
ret_tuple = (25.0, 60.0, 35.0, 6)
self.rsd_client.get_stats = mock.Mock(return_value=ret_tuple)
expected_stats = {'driver_version': '1.0.0',
'pools': [{
'allocated_capacity_gb': 35.0,
'free_capacity_gb': 25.0,
'multiattach': False,
'pool_name': 'RSD',
'thick_provisioning_support': True,
'thin_provisioning_support': True,
'total_capacity_gb': 60.0}],
'storage_protocol': 'nvmeof',
'vendor_name': 'Intel',
'volume_backend_name': 'RSD'}
stats = self.volume.driver.get_volume_stats(refresh=True)
self.assertEqual(expected_stats, stats)
def test_initialize_connection(self):
mock_connector = {'system uuid':
"281bbc50-e76f-40e7-a757-06b916a83d6f"}
self.mock_dict['provider_location'] = self.resource_url
self.mock_volume.__getitem__.side_effect = self.mock_dict.__getitem__
self.rsd_client.get_node_url_by_uuid = mock.Mock(
return_value=self.resource_url)
ret_tuple = ("0.0.0.0", 5467, "target.mock.nqn", "initiator.mock.nqn")
self.rsd_client.attach_volume_to_node = mock.Mock(
return_value=ret_tuple)
expected_conn_info = {
'driver_volume_type': 'nvmeof',
'data': {
'transport_type': 'rdma',
'host_nqn': "initiator.mock.nqn",
'nqn': "target.mock.nqn",
'target_port': 5467,
'target_portal': "0.0.0.0",
}
}
conn_info = self.volume.driver.initialize_connection(self.mock_volume,
mock_connector)
self.assertEqual(expected_conn_info, conn_info)
def test_initialize_connection_node_not_found(self):
mock_connector = {'system uuid':
"281bbc50-e76f-40e7-a757-06b916a83d6f"}
self.mock_dict['provider_location'] = self.resource_url
self.mock_volume.__getitem__.side_effect = self.mock_dict.__getitem__
self.rsd_client.get_node_url_by_uuid = mock.Mock(
return_value="")
ret_tuple = ("0.0.0.0", 5467, "target.mock.nqn", "initiator.mock.nqn")
self.rsd_client.attach_volume_to_node = mock.Mock(
return_value=ret_tuple)
self.assertRaises(exception.VolumeBackendAPIException,
self.volume.driver.initialize_connection,
self.mock_volume, mock_connector)
self.rsd_client.attach_volume_to_node.assert_not_called()
self.rsd_client.get_node_url_by_uuid.assert_called_once()
def test_initialize_connection_no_system_uuid(self):
mock_connector = {}
self.mock_dict['provider_location'] = self.resource_url
self.mock_volume.__getitem__.side_effect = self.mock_dict.__getitem__
self.rsd_client.get_node_url_by_uuid = mock.Mock(
return_value=self.resource_url)
ret_tuple = ("0.0.0.0", 5467, "target.mock.nqn", "initiator.mock.nqn")
self.rsd_client.attach_volume_to_node = mock.Mock(
return_value=ret_tuple)
self.assertRaises(exception.VolumeBackendAPIException,
self.volume.driver.initialize_connection,
self.mock_volume, mock_connector)
self.rsd_client.attach_volume_to_node.assert_not_called()
self.rsd_client.get_node_url_by_uuid.assert_not_called()
def test_terminate_connection(self):
mock_connector = {'system uuid':
"281bbc50-e76f-40e7-a757-06b916a83d6f"}
self.mock_dict['provider_location'] = self.resource_url
self.mock_volume.__getitem__.side_effect = self.mock_dict.__getitem__
self.rsd_client.get_node_url_by_uuid = mock.Mock(
return_value=self.resource_url)
self.volume.driver.terminate_connection(self.mock_volume,
mock_connector)
self.rsd_client.get_node_url_by_uuid.assert_called_once()
self.rsd_client.detach_volume_from_node.assert_called_once()
def test_terminate_connection_no_node(self):
mock_connector = {'system uuid':
"281bbc50-e76f-40e7-a757-06b916a83d6f"}
self.mock_dict['provider_location'] = self.resource_url
self.mock_volume.__getitem__.side_effect = self.mock_dict.__getitem__
self.rsd_client.get_node_url_by_uuid = mock.Mock(
return_value="")
self.assertRaises(exception.VolumeBackendAPIException,
self.volume.driver.terminate_connection,
self.mock_volume, mock_connector)
self.rsd_client.get_node_url_by_uuid.assert_called_once()
self.rsd_client.detach_volume_from_node.assert_not_called()
def test_terminate_connection_no_connector(self):
mock_connector = None
self.mock_dict['provider_location'] = self.resource_url
self.mock_volume.__getitem__.side_effect = self.mock_dict.__getitem__
self.rsd_client.get_node_url_by_uuid = mock.Mock(
return_value=self.resource_url)
self.volume.driver.terminate_connection(
self.mock_volume, mock_connector)
self.rsd_client.detach_all_node_connections_for_volume. \
assert_called_once()
self.rsd_client.get_node_url_by_uuid.assert_not_called()
self.rsd_client.detach_volume_from_node.assert_not_called()
def test_terminate_connection_no_system_uuid(self):
mock_connector = {}
self.mock_dict['provider_location'] = self.resource_url
self.mock_volume.__getitem__.side_effect = self.mock_dict.__getitem__
self.rsd_client.get_node_url_by_uuid = mock.Mock(
return_value=self.resource_url)
self.assertRaises(exception.VolumeBackendAPIException,
self.volume.driver.terminate_connection,
self.mock_volume, mock_connector)
self.rsd_client.get_node_url_by_uuid.assert_not_called()
self.rsd_client.detach_volume_from_node.assert_not_called()
def test_create_volume_from_snapshot(self):
mock_snap = mock.Mock()
mock_snap.provider_location = self.resource_url
mock_snap.volume_size = 10
self.mock_volume.size = 10
self.rsd_client.create_volume_from_snap = mock.Mock(
return_value=self.resource_url)
self.rsd_client.delete_vol_or_snap = mock.Mock()
ret_dict = self.volume.driver.create_volume_from_snapshot(
self.mock_volume, mock_snap)
self.assertEqual({'provider_location': self.resource_url}, ret_dict)
self.rsd_client.create_volume_from_snap.assert_called_once()
self.rsd_client.extend_volume.assert_not_called()
self.rsd_client.delete_vol_or_snap.assert_not_called()
def test_create_volume_from_snapshot_diff_size(self):
mock_snap = mock.Mock()
mock_snap.provider_location = self.resource_url
mock_snap.volume_size = 10
self.mock_volume.size = 20
self.rsd_client.create_volume_from_snap = mock.Mock(
return_value=self.resource_url)
self.rsd_client.extend_volume = mock.Mock()
self.rsd_client.delete_vol_or_snap = mock.Mock()
ret_dict = self.volume.driver.create_volume_from_snapshot(
self.mock_volume, mock_snap)
self.assertEqual({'provider_location': self.resource_url}, ret_dict)
self.rsd_client.create_volume_from_snap.assert_called_once()
self.rsd_client.extend_volume.assert_called_once()
self.rsd_client.delete_vol_or_snap.assert_not_called()
def test_create_volume_from_snapshot_diff_size_fail(self):
mock_snap = mock.Mock()
mock_snap.provider_location = self.resource_url
mock_snap.volume_size = 10
self.mock_volume.size = 20
self.rsd_client.create_volume_from_snap = mock.Mock(
return_value=self.resource_url)
self.rsd_client.extend_volume = mock.Mock(
side_effect=[exception.VolumeBackendAPIException(
data="extend fail")])
self.rsd_client.delete_vol_or_snap = mock.Mock()
self.assertRaises(exception.VolumeBackendAPIException,
self.volume.driver.create_volume_from_snapshot,
self.mock_volume, mock_snap)
self.rsd_client.create_volume_from_snap.assert_called_once()
self.rsd_client.extend_volume.assert_called_once()
self.rsd_client.delete_vol_or_snap.assert_called_once()
def test_delete_snapshot(self):
mock_snap = mock.Mock()
mock_snap.provider_location = self.resource_url
mock_snap.name = "mock_snapshot"
self.rsd_client.delete_vol_or_snap = mock.Mock(return_value=True)
self.volume.driver.delete_snapshot(mock_snap)
self.rsd_client.delete_vol_or_snap.assert_called_once()
def test_delete_snapshot_no_url(self):
mock_snap = mock.Mock()
mock_snap.provider_location = ""
mock_snap.name = "mock_snapshot"
self.rsd_client.delete_vol_or_snap = mock.Mock(return_value=True)
self.volume.driver.delete_snapshot(mock_snap)
self.rsd_client.delete_vol_or_snap.assert_not_called()
def test_delete_snapshot_unable_to_delete(self):
mock_snap = mock.Mock()
mock_snap.provider_location = self.resource_url
mock_snap.name = "mock_snapshot"
self.rsd_client.delete_vol_or_snap = mock.Mock(
side_effect=[exception.SnapshotIsBusy(
snapshot_name=mock_snap.name)])
self.assertRaises(exception.SnapshotIsBusy,
self.volume.driver.delete_snapshot, mock_snap)
self.rsd_client.delete_vol_or_snap.assert_called_once()
def test_create_cloned_volume(self):
mock_vref = mock.Mock()
mock_vref.provider_location = self.resource_url
mock_vref.size = 10
self.mock_volume.size = 10
self.rsd_client.clone_volume = mock.Mock(
return_value=(self.resource_url, self.resource_url))
self.rsd_client.extend_volume = mock.Mock()
self.rsd_client.delete_vol_or_snap = mock.Mock()
self.volume.driver.create_cloned_volume(self.mock_volume, mock_vref)
self.rsd_client.clone_volume.assert_called_once()
self.rsd_client.extend_volume.assert_not_called()
self.rsd_client.delete_vol_or_snap.assert_not_called()
def test_create_cloned_volume_extend_vol(self):
mock_vref = mock.Mock()
mock_vref.provider_location = self.resource_url
mock_vref.size = 20
self.mock_volume.size = 10
self.rsd_client.clone_volume = mock.Mock(
return_value=(self.resource_url, self.resource_url))
self.rsd_client.extend_volume = mock.Mock()
self.rsd_client.delete_vol_or_snap = mock.Mock()
self.volume.driver.create_cloned_volume(self.mock_volume, mock_vref)
self.rsd_client.clone_volume.assert_called_once()
self.rsd_client.extend_volume.assert_called_once()
self.rsd_client.delete_vol_or_snap.assert_not_called()
def test_create_cloned_volume_extend_vol_fail(self):
mock_vref = mock.Mock()
mock_vref.provider_location = self.resource_url
mock_vref.size = 20
self.mock_volume.size = 10
self.rsd_client.clone_volume = mock.Mock(
return_value=(self.resource_url, self.resource_url))
self.rsd_client.extend_volume = mock.Mock(
side_effect=exception.VolumeBackendAPIException(
data="extend fail"))
self.rsd_client.delete_vol_or_snap = mock.Mock()
self.assertRaises(exception.VolumeBackendAPIException,
self.volume.driver.create_cloned_volume,
self.mock_volume, mock_vref)
self.rsd_client.clone_volume.assert_called_once()
self.rsd_client.extend_volume.assert_called_once()
self.assertEqual(2, self.rsd_client.delete_vol_or_snap.call_count)