cinder/cinder/tests/unit/volume/drivers/sandstone/test_sds_driver.py

456 lines
21 KiB
Python

# Copyright (c) 2019 SandStone data Technologies Co., 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.
"""Unittest for sds_client."""
from unittest import mock
import uuid
import ddt
from oslo_utils import units
from cinder import exception
from cinder import objects
from cinder import test
from cinder.volume import configuration as config
from cinder.volume.drivers.san import san
from cinder.volume.drivers.sandstone import sds_client
from cinder.volume.drivers.sandstone import sds_driver
class FakeSdsBaseDriver(sds_driver.SdsBaseDriver):
"""Fake sds base driver."""
def __init__(self):
"""Init conf client pool sds_client."""
self.configuration = config.Configuration(None)
self.configuration.append_config_values(sds_driver.sds_opts)
self.configuration.append_config_values(san.san_opts)
self.configuration.suppress_requests_ssl_warnings = True
self.client = None
self.poolid = 1
self.VERSION = '1.0'
self.address = "192.168.200.100"
self.user = "fake_user"
self.password = "fake_password"
self.pool = "fake_pool_name"
self.iscsi_info = {"iqn.1994-05.com.redhat:899c5f9d15d":
"1.1.1.1,1.1.1.2,1.1.1.3"}
self.default_target_ips = ["1.1.1.1", "1.1.1.2", "1.1.1.3"]
self.default_chap_info = "1234567891234,123456789123"
@ddt.ddt
class TestSdsBaseDriver(test.TestCase):
"""Testcase sds base driver."""
def setUp(self):
"""Setup."""
super(TestSdsBaseDriver, self).setUp()
self.fake_driver = FakeSdsBaseDriver()
self.fake_driver.client = sds_client.RestCmd('192.168.200.100',
'fake_user',
'fake_password',
True)
# @mock.patch.object(sds_client.RestCmd, 'login')
def test_do_setup(self):
"""Do setup."""
self.fake_driver.client = sds_client.RestCmd(
'fake_rest_ip', 'user', 'password', True)
self.fake_driver.configuration.san_ip = 'fake_rest_ip'
self.fake_driver.configuration.san_login = 'fake_san_user'
self.fake_driver.configuration.san_password = 'fake_san_password'
self.fake_driver.do_setup('context')
@mock.patch.object(sds_client.RestCmd, 'query_pool_info')
@mock.patch.object(sds_client.RestCmd, 'get_poolid_from_poolname')
@mock.patch.object(sds_client.RestCmd, 'login')
def test_check_for_setup_error(self, mock_login,
mock_get_poolid_from_poolname,
mock_query_pool_info):
"""Test pool status health or not."""
result1 = [
{'status': {'progress': 33, 'state': ['degraded'], 'flags': 4},
'pool_name': 'fake_pool_name', 'used': 1792950890,
'display_name': 'data', 'replicated_size': 2,
'storage_policy': '2', 'domain_name': 'sandstone',
'pool_id': 3, 'min_size': 1, 'erasure_code_profile': '',
'policy_type': 'replicated', 'rule_id': 1,
'size': 2},
{'status': {'progress': 33, 'state': ['degraded'], 'flags': 4},
'pool_name': 'vms1', 'used': 1792950890,
'display_name': 'data', 'replicated_size': 2,
'storage_policy': '2', 'domain_name': 'sandstone',
'pool_id': 3, 'min_size': 1, 'erasure_code_profile': '',
'policy_type': 'replicated', 'rule_id': 1,
'size': 2}]
result2 = [
{'status': {'progress': 33, 'state': ['degraded'], 'flags': 4},
'pool_name': 'vms', 'used': 1792950890,
'display_name': 'data', 'replicated_size': 2,
'storage_policy': '2', 'domain_name': 'sandstone',
'pool_id': 3, 'min_size': 1, 'erasure_code_profile': '',
'policy_type': 'replicated', 'rule_id': 1,
'size': 2},
{'status': {'progress': 33, 'state': ['degraded'], 'flags': 4},
'pool_name': 'vms1', 'used': 1792950890,
'display_name': 'data', 'replicated_size': 2,
'storage_policy': '2', 'domain_name': 'sandstone',
'pool_id': 3, 'min_size': 1, 'erasure_code_profile': '',
'policy_type': 'replicated', 'rule_id': 1,
'size': 2}]
mock_login.return_value = {"success": 1}
mock_get_poolid_from_poolname.return_value = (
{"fake_pool_name": 3})
mock_query_pool_info.return_value = result1
retval = self.fake_driver.check_for_setup_error()
self.assertIsNone(retval)
mock_query_pool_info.return_value = result2
try:
self.fake_driver.check_for_setup_error()
except Exception as e:
self.assertEqual(exception.InvalidInput, type(e))
@mock.patch.object(sds_client.RestCmd, 'query_capacity_info')
def test__update_volume_stats(self, mock_query_capacity_info):
"""Get cluster capacity."""
result1 = {
"capacity_bytes": 2 * units.Gi,
"free_bytes": units.Gi
}
mock_query_capacity_info.return_value = result1
retval = self.fake_driver._update_volume_stats(
pool_name="fake_pool_name")
self.assertDictEqual(
{"pools": [dict(
pool_name="fake_pool_name",
vendor_name = 'SandStone USP',
driver_version = self.fake_driver.VERSION,
total_capacity_gb=2.0,
free_capacity_gb=1.0,
QoS_support=True,
thin_provisioning_support=True,
multiattach=False,)
]}, retval)
mock_query_capacity_info.assert_called_once_with()
@mock.patch.object(sds_driver.SdsBaseDriver, 'get_volume_stats')
def test_get_volume_stats(self, mock_get_volume_stats):
"""Get cluster capacitys."""
result1 = {"pool": dict(
pool_name="fake_pool_name",
total_capacity_gb=2.0,
free_capacity_gb=1.0,
QoS_support=True,
thin_provisioning_support=True,
multiattach=False,)}
mock_get_volume_stats.return_value = result1
retval = self.fake_driver.get_volume_stats()
self.assertDictEqual(
{"pool": dict(
pool_name="fake_pool_name",
total_capacity_gb=2.0,
free_capacity_gb=1.0,
QoS_support=True,
thin_provisioning_support=True,
multiattach=False,
)}, retval)
@mock.patch.object(sds_client.RestCmd, 'create_lun')
def test_create_volume(self, mock_create_lun):
"""Test create volume."""
volume = objects.Volume(_name_id=uuid.uuid4(), size=1)
mock_create_lun.return_value = {'success': 1}
retval = self.fake_driver.create_volume(volume=volume)
self.assertIsNone(retval)
@mock.patch.object(sds_client.RestCmd, 'delete_lun')
def test_delete_volume(self, mock_delete_):
"""Test delete volume."""
mock_delete_.return_value = {'success': 1}
volume = objects.Volume(_name_id=uuid.uuid4(), size=1)
retval = self.fake_driver.delete_volume(volume)
self.assertIsNone(retval)
@mock.patch.object(sds_client.RestCmd, 'extend_lun')
@mock.patch.object(sds_client.RestCmd, 'create_lun_from_snapshot')
def test_create_volume_from_snapshot(self, mock_lun_from_snapshot,
mock_extend_lun):
"""Test create new volume from snapshot of src volume."""
volume = objects.Volume(_name_id=uuid.uuid4(), size=1)
snapshot = objects.Snapshot(
id=uuid.uuid4(), volume_size=2, volume=volume)
mock_lun_from_snapshot.return_value = {'success': 1}
mock_extend_lun.return_value = {'success': 1}
retval = self.fake_driver.create_volume_from_snapshot(volume, snapshot)
self.assertIsNone(retval)
@mock.patch.object(sds_client.RestCmd, 'extend_lun')
@mock.patch.object(sds_client.RestCmd, 'create_lun_from_lun')
@mock.patch.object(sds_driver.SdsBaseDriver, '_check_volume_exist')
def test_create_cloned_volume(self, mock__check_volume_exist,
mock_create_lun_from_lun,
mock_extend_lun):
"""Test create clone volume."""
mock__check_volume_exist.return_value = True
mock_create_lun_from_lun.return_value = {'success': 1}
mock_extend_lun.return_value = {'success': 1}
dst_volume = objects.Volume(_name_id=uuid.uuid4(), size=2)
src_volume = objects.Volume(_name_id=uuid.uuid4(), size=1)
retval = self.fake_driver.create_cloned_volume(dst_volume, src_volume)
self.assertIsNone(retval)
@mock.patch.object(sds_client.RestCmd, 'query_lun_by_name')
def test__check_volume_exist(self, mock_query_lun_by_name):
"""Test volume exist or not."""
mock_query_lun_by_name.return_value = {'success': 1}
volume = objects.Volume(_name_id=uuid.uuid4(), size=1)
retval = self.fake_driver._check_volume_exist(volume)
self.assertEqual({'success': 1}, retval)
@mock.patch.object(sds_client.RestCmd, 'extend_lun')
@mock.patch.object(sds_driver.SdsBaseDriver, '_check_volume_exist')
def test_extend_volume(self, mock__check_volume_exist, mock_extend_lun):
"""Test resize volume."""
volume = objects.Volume(_name_id=uuid.uuid4(), size=1)
new_size = 3
mock__check_volume_exist.return_value = {
'capacity_bytes': units.Gi * 1}
mock_extend_lun.return_value = {'success': 1}
retval = self.fake_driver.extend_volume(volume, new_size)
self.assertIsNone(retval)
@mock.patch.object(sds_client.RestCmd, 'create_snapshot')
def test_create_snapshot(self, mock_create_snapshot):
"""Test create snapshot of volume."""
volume = objects.Volume(_name_id=uuid.uuid4(), size=1)
snapshot = objects.Snapshot(
id=uuid.uuid4(), volume_size=2, volume=volume)
mock_create_snapshot.return_value = {'success': 1}
retval = self.fake_driver.create_snapshot(snapshot)
self.assertIsNone(retval)
@mock.patch.object(sds_client.RestCmd, 'query_snapshot_by_name')
def test__check_snapshot_exist(self, mock_query_snapshot_by_name):
"""Test snapshot exist or not."""
volume = objects.Volume(_name_id=uuid.uuid4(), size=1)
snapshot = objects.Snapshot(
id=uuid.uuid4(), volume_size=2, volume=volume)
mock_query_snapshot_by_name.return_value = {'success': 1}
retval = self.fake_driver._check_snapshot_exist(snapshot)
self.assertEqual({'success': 1}, retval)
@mock.patch.object(sds_client.RestCmd, 'delete_snapshot')
@mock.patch.object(sds_driver.SdsBaseDriver, '_check_snapshot_exist')
def test_delete_snapshot(self, mock__check_snapshot_exist,
mock_delete_snapshot):
"""Test delete snapshot."""
volume = objects.Volume(_name_id=uuid.uuid4(), size=1)
snapshot = objects.Snapshot(
id=uuid.uuid4(), volume_size=2, volume=volume)
mock__check_snapshot_exist.return_value = True
mock_delete_snapshot.return_value = {'success': 1}
retval = self.fake_driver.delete_snapshot(snapshot)
self.assertIsNone(retval)
class FakeSdsISCSIDriver(sds_driver.SdsISCSIDriver):
"""Fake sds iscsi driver, include attach, detach."""
def __init__(self):
"""Init conf client pool."""
self.configuration = config.Configuration(None)
self.client = None
self.address = "192.168.200.100"
self.user = "fake_user"
self.password = "fake_password"
self.pool = "fake_pool_name"
self.poolid = 1
self.iscsi_info = {"iqn.1994-05.com.redhat:899c5f9d15d":
"1.1.1.1,1.1.1.2,1.1.1.3"}
self.default_target_ips = ["1.1.1.1", "1.1.1.2", "1.1.1.3"]
self.chap_username = "123456789123"
self.chap_password = "1234567891234"
@ddt.ddt
class TestSdsISCSIDriver(test.TestCase):
"""Testcase sds iscsi driver, include attach, detach."""
def setUp(self):
"""Setup."""
super(TestSdsISCSIDriver, self).setUp()
self.fake_driver = FakeSdsISCSIDriver()
self.fake_driver.client = sds_client.RestCmd("192.168.200.100",
"fake_user",
"fake_password",
True)
@mock.patch.object(sds_client.RestCmd, 'query_target_by_name')
def test__check_target_exist(self, mock_query_target_by_name):
"""Test target exist or not."""
target_name = 'test_driver'
mock_query_target_by_name.return_value = {'success': 1}
retval = self.fake_driver._check_target_exist(target_name)
self.assertEqual({'success': 1}, retval)
@mock.patch.object(sds_client.RestCmd, 'query_initiator_by_name')
def test__check_initiator_exist(self, mock_query_initiator_by_name):
"""Test initiator exist or not."""
initiator_name = 'test_driver'
mock_query_initiator_by_name.return_value = {'success': 1}
retval = self.fake_driver._check_initiator_exist(initiator_name)
self.assertEqual({'success': 1}, retval)
@mock.patch.object(sds_client.RestCmd, 'query_target_initiatoracl')
def test__check_target_added_initiator(self,
mock_query_target_initiatoracl):
"""Test target added the initiator."""
mock_query_target_initiatoracl.return_value = {'success': 1}
target_name, initiator_name = 'test_driver', 'initiator_name'
retval = self.fake_driver._check_target_added_initiator(target_name,
initiator_name)
self.assertEqual({'success': 1}, retval)
@mock.patch.object(sds_client.RestCmd, 'query_target_lunacl')
def test__check_target_added_lun(self, mock_query_target_lunacl):
"""Test target added the lun."""
mock_query_target_lunacl.return_value = {'success': 1}
target_name, pool_name, volume_name = ('ccc', self.fake_driver.pool,
'fcc')
retval = self.fake_driver._check_target_added_lun(target_name,
pool_name,
volume_name)
self.assertEqual({'success': 1}, retval)
@mock.patch.object(sds_client.RestCmd, 'query_chapinfo_by_target')
def test__check_target_added_chap(self, mock_query_chapinfo_by_target):
"""Test target added chapuser."""
mock_query_chapinfo_by_target.return_value = {'success': 1}
target_name, user_name = 'ccc', 'fcc'
retval = self.fake_driver._check_target_added_chap(target_name,
user_name)
self.assertEqual({'success': 1}, retval)
def test__get_target_ip(self):
"""Test get target from targetip."""
initiator = 'iqn.1994-05.com.redhat:899c5f9d15d'
retval_target_ips = \
self.fake_driver._get_target_ip(initiator)
self.assertListEqual(['1.1.1.1', '1.1.1.2', '1.1.1.3'],
retval_target_ips)
self.fake_driver.default_target_ips = \
["1.1.1.1"]
initiator = 'vms'
retval_target_ips = \
self.fake_driver._get_target_ip(initiator)
self.assertListEqual(["1.1.1.1"], retval_target_ips)
@mock.patch.object(sds_client.RestCmd, 'add_chap_by_target')
@mock.patch.object(sds_driver.SdsISCSIDriver, '_check_target_added_chap')
@mock.patch.object(sds_driver.SdsISCSIDriver, '_check_target_added_lun')
@mock.patch.object(sds_client.RestCmd, 'mapping_lun')
@mock.patch.object(sds_client.RestCmd, 'add_initiator_to_target')
@mock.patch.object(sds_driver.SdsISCSIDriver,
'_check_target_added_initiator')
@mock.patch.object(sds_client.RestCmd, 'create_initiator')
@mock.patch.object(sds_driver.SdsISCSIDriver, '_check_initiator_exist')
@mock.patch.object(sds_client.RestCmd, 'create_target')
@mock.patch.object(sds_client.RestCmd, 'query_node_by_targetips')
@mock.patch.object(sds_driver.SdsISCSIDriver, '_check_target_exist')
@mock.patch.object(sds_driver.SdsISCSIDriver, '_get_target_ip')
def test_initialize_connection(self, mock__get_target_ip,
mock__check_target_exist,
mock_query_node_by_targetips,
mock_create_target,
mock__check_initiator_exist,
mock_create_initiator,
mock__check_target_added_initiator,
mock_add_initiator_to_target,
mock_mapping_lun,
mock__check_target_added_lun,
mock__check_target_added_chap,
mock_add_chap_by_target):
"""Test attach volume to kvm."""
mock__get_target_ip.return_value = (['1.1.1.1', '1.1.1.2', '1.1.1.3'])
mock__check_target_exist.return_value = False
mock__check_initiator_exist.return_value = False
mock__check_target_added_initiator.result_value = False
mock__check_target_added_chap.return_value = False
mock_query_node_by_targetips.return_value = {'host_id', 'address'}
mock_create_target.return_value = {'success': 1}
mock_create_initiator.return_value = {'success': 1}
mock_add_initiator_to_target.result_value = {'success': 1}
mock_mapping_lun.return_value = {'success': 1}
mock__check_target_added_lun.return_value = 1
mock_add_chap_by_target.return_value = {'success': 1}
volume1, connector1 = (objects.Volume(id=uuid.uuid4(),
_name_id=uuid.uuid4(), size=1),
{'initiator':
'iqn.1994-05.com.redhat:899c5f9d15d',
'multipath': True})
initiator_name = connector1['initiator']
iqn_end = initiator_name.split(':', 1)[1]
target_head = 'iqn.2014-10.com.szsandstone:storage:'
target_name = target_head + iqn_end
result1 = {
'driver_volume_type': 'iscsi',
'data': {'target_discovered': True,
'target_portals': ['1.1.1.1:3260',
'1.1.1.2:3260',
'1.1.1.3:3260'],
'volume_id': volume1.id,
'auth_method': 'CHAP',
'auth_username': '123456789123',
'auth_password': '1234567891234',
'target_iqns': [target_name, target_name, target_name],
'target_luns': [1, 1, 1]}}
retval = self.fake_driver.initialize_connection(volume1, connector1)
self.assertDictEqual(result1, retval)
volume2, connector2 = (objects.Volume(id=uuid.uuid4(),
_name_id=uuid.uuid4(),
size=2),
{'initiator':
'iqn.1994-05.com.redhat:899c5f9d15d'})
mock__get_target_ip.return_value = (['1.1.1.1', '1.1.1.2', '1.1.1.3'])
initiator_name = connector2['initiator']
iqn_end = initiator_name.split(':', 1)[1]
target_head = 'iqn.2014-10.com.szsandstone:storage:'
target_name = target_head + iqn_end
result2 = {'driver_volume_type': 'iscsi',
'data': {'target_discovered': True,
'target_portal': '1.1.1.1:3260',
'volume_id': volume2.id,
'target_iqn': target_name,
'target_lun': 1,
'auth_method': 'CHAP',
'auth_username': '123456789123',
'auth_password': '1234567891234'}}
retval = self.fake_driver.initialize_connection(volume2, connector2)
self.assertDictEqual(result2, retval)
@mock.patch.object(sds_client.RestCmd, 'unmap_lun')
def test_terminate_connection(self, mock_unmap_lun):
"""Test detach volume from kvm."""
volume, connector = (objects.Volume(_name_id=uuid.uuid4(), size=1),
{'initiator':
'iqn.1994-05.com.redhat:899c5f9d15d'})
mock_unmap_lun.result_value = {'success': 1}
retval = self.fake_driver.terminate_connection(volume, connector)
self.assertIsNone(retval)