cinder/cinder/tests/unit/test_infortrend_common.py

2074 lines
76 KiB
Python

# Copyright (c) 2015 Infortrend Technology, Inc.
# 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.
import copy
import mock
from cinder import exception
from cinder import test
from cinder.tests.unit import test_infortrend_cli
from cinder.tests.unit import utils
from cinder.volume import configuration
from cinder.volume.drivers.infortrend.eonstor_ds_cli import common_cli
SUCCEED = (0, '')
FAKE_ERROR_RETURN = (-1, '')
class InfortrendTestCass(test.TestCase):
def __init__(self, *args, **kwargs):
super(InfortrendTestCass, self).__init__(*args, **kwargs)
def setUp(self):
super(InfortrendTestCass, self).setUp()
self.cli_data = test_infortrend_cli.InfortrendCLITestData()
self.configuration = configuration.Configuration(None)
self.configuration.append_config_values = mock.Mock(return_value=0)
self.configuration.safe_get = self._fake_safe_get
def _fake_safe_get(self, key):
return getattr(self.configuration, key)
def _driver_setup(self, mock_commands, configuration=None):
if configuration is None:
configuration = self.configuration
self.driver = self._get_driver(configuration)
mock_commands_execute = self._mock_command_execute(mock_commands)
mock_cli = mock.Mock(side_effect=mock_commands_execute)
self.driver._execute_command = mock_cli
def _get_driver(self, conf):
raise NotImplementedError
def _mock_command_execute(self, mock_commands):
def fake_execute_command(cli_type, *args, **kwargs):
if cli_type in mock_commands.keys():
if isinstance(mock_commands[cli_type], list):
ret = mock_commands[cli_type][0]
del mock_commands[cli_type][0]
return ret
elif isinstance(mock_commands[cli_type], tuple):
return mock_commands[cli_type]
else:
return mock_commands[cli_type](*args, **kwargs)
return FAKE_ERROR_RETURN
return fake_execute_command
def _mock_show_lv_for_migrate(self, *args, **kwargs):
if 'tier' in args:
return self.cli_data.get_test_show_lv_tier_for_migration()
return self.cli_data.get_test_show_lv()
def _mock_show_lv(self, *args, **kwargs):
if 'tier' in args:
return self.cli_data.get_test_show_lv_tier()
return self.cli_data.get_test_show_lv()
def _assert_cli_has_calls(self, expect_cli_cmd):
self.driver._execute_command.assert_has_calls(expect_cli_cmd)
class InfortrendFCCommonTestCase(InfortrendTestCass):
def __init__(self, *args, **kwargs):
super(InfortrendFCCommonTestCase, self).__init__(*args, **kwargs)
def setUp(self):
super(InfortrendFCCommonTestCase, self).setUp()
self.configuration.volume_backend_name = 'infortrend_backend_1'
self.configuration.san_ip = self.cli_data.fake_manage_port_ip[0]
self.configuration.san_password = '111111'
self.configuration.infortrend_provisioning = 'full'
self.configuration.infortrend_tiering = '0'
self.configuration.infortrend_pools_name = 'LV-1, LV-2'
self.configuration.infortrend_slots_a_channels_id = '0,5'
self.configuration.infortrend_slots_b_channels_id = '0,5'
self.configuration.infortrend_cli_timeout = 30
def _get_driver(self, conf):
return common_cli.InfortrendCommon('FC', configuration=conf)
def test_normal_channel(self):
test_map_dict = {
'slot_a': {'0': [], '5': []},
'slot_b': {},
}
test_target_dict = {
'slot_a': {'0': '112', '5': '112'},
'slot_b': {},
}
mock_commands = {
'ShowChannel': self.cli_data.get_test_show_channel(),
}
self._driver_setup(mock_commands)
self.driver._init_map_info(True)
self.assertDictMatch(test_map_dict, self.driver.map_dict)
self.assertDictMatch(test_target_dict, self.driver.target_dict)
def test_normal_channel_with_r_model(self):
test_map_dict = {
'slot_a': {'0': [], '5': []},
'slot_b': {'0': [], '5': []},
}
test_target_dict = {
'slot_a': {'0': '112', '5': '112'},
'slot_b': {'0': '113', '5': '113'},
}
mock_commands = {
'ShowChannel': self.cli_data.get_test_show_channel_r_model(),
}
self._driver_setup(mock_commands)
self.driver._init_map_info(True)
self.assertDictMatch(test_map_dict, self.driver.map_dict)
self.assertDictMatch(test_target_dict, self.driver.target_dict)
@mock.patch.object(common_cli.LOG, 'info', mock.Mock())
def test_initialize_connection(self):
test_volume = self.cli_data.test_volume
test_connector = self.cli_data.test_connector_fc
mock_commands = {
'ShowChannel': self.cli_data.get_test_show_channel_without_mcs(),
'ShowMap': self.cli_data.get_test_show_map(),
'CreateMap': SUCCEED,
'ShowWWN': self.cli_data.get_test_show_wwn_with_g_model(),
}
self._driver_setup(mock_commands)
properties = self.driver.initialize_connection(
test_volume, test_connector)
self.assertDictMatch(self.cli_data.test_fc_properties, properties)
@mock.patch.object(common_cli.LOG, 'info', mock.Mock())
def test_initialize_connection_specific_channel(self):
test_volume = self.cli_data.test_volume
test_connector = self.cli_data.test_connector_fc
configuration = copy.copy(self.configuration)
configuration.infortrend_slots_a_channels_id = '5'
mock_commands = {
'ShowChannel': self.cli_data.get_test_show_channel(),
'ShowMap': self.cli_data.get_test_show_map(),
'CreateMap': SUCCEED,
'ShowWWN': self.cli_data.get_test_show_wwn_with_g_model(),
}
self._driver_setup(mock_commands, configuration)
properties = self.driver.initialize_connection(
test_volume, test_connector)
self.assertDictMatch(
self.cli_data.test_fc_properties_with_specific_channel, properties)
@mock.patch.object(common_cli.LOG, 'info', mock.Mock())
def test_initialize_connection_with_diff_target_id(self):
test_volume = self.cli_data.test_volume
test_connector = self.cli_data.test_connector_fc
test_initiator_wwpns = test_connector['wwpns']
test_partition_id = self.cli_data.fake_partition_id[0]
configuration = copy.copy(self.configuration)
configuration.infortrend_slots_a_channels_id = '5'
mock_commands = {
'ShowChannel':
self.cli_data.get_test_show_channel_with_diff_target_id(),
'ShowMap': self.cli_data.get_test_show_map(),
'CreateMap': SUCCEED,
'ShowWWN': self.cli_data.get_test_show_wwn_with_g_model(),
}
self._driver_setup(mock_commands, configuration)
properties = self.driver.initialize_connection(
test_volume, test_connector)
expect_cli_cmd = [
mock.call('ShowChannel'),
mock.call('ShowMap'),
mock.call('ShowWWN'),
mock.call('CreateMap', 'part', test_partition_id, '5', '48', '0',
'wwn=%s' % test_initiator_wwpns[0]),
]
self._assert_cli_has_calls(expect_cli_cmd)
self.assertDictMatch(
self.cli_data.test_fc_properties_with_specific_channel, properties)
@mock.patch.object(common_cli.LOG, 'info', mock.Mock())
def test_initialize_connection_multipath_with_r_model(self):
test_volume = self.cli_data.test_volume
test_connector = copy.deepcopy(self.cli_data.test_connector_fc)
mock_commands = {
'ShowChannel': self.cli_data.get_test_show_channel_r_model(),
'ShowMap': self.cli_data.get_test_show_map(),
'CreateMap': SUCCEED,
'ShowWWN': self.cli_data.get_test_show_wwn(),
}
self._driver_setup(mock_commands)
properties = self.driver.initialize_connection(
test_volume, test_connector)
self.assertDictMatch(
self.cli_data.test_fc_properties_multipath_r_model, properties)
def test_initialize_connection_with_get_wwn_fail(self):
test_volume = self.cli_data.test_volume
test_connector = self.cli_data.test_connector_fc
mock_commands = {
'ShowChannel': self.cli_data.get_test_show_channel(),
'ShowMap': self.cli_data.get_test_show_map(),
'CreateMap': SUCCEED,
'ShowWWN': FAKE_ERROR_RETURN,
}
self._driver_setup(mock_commands)
self.assertRaises(
exception.InfortrendCliException,
self.driver.initialize_connection,
test_volume,
test_connector)
@mock.patch.object(common_cli.LOG, 'info', mock.Mock())
def test_initialize_connection_with_zoning(self):
test_volume = self.cli_data.test_volume
test_connector = self.cli_data.test_connector_fc
test_initiator_wwpns = test_connector['wwpns']
test_partition_id = self.cli_data.fake_partition_id[0]
test_all_target_wwpns = self.cli_data.fake_target_wwpns[0:2]
test_lookup_map = self.cli_data.fake_lookup_map
mock_commands = {
'ShowChannel': self.cli_data.get_test_show_channel(),
'ShowMap': self.cli_data.get_test_show_map(),
'CreateMap': SUCCEED,
'ShowWWN': self.cli_data.get_test_show_wwn_with_g_model(),
}
self._driver_setup(mock_commands)
self.driver.fc_lookup_service = mock.Mock()
get_device_mapping_from_network = (
self.driver.fc_lookup_service.get_device_mapping_from_network
)
get_device_mapping_from_network.return_value = test_lookup_map
properties = self.driver.initialize_connection(
test_volume, test_connector)
get_device_mapping_from_network.assert_has_calls(
[mock.call(test_connector['wwpns'], test_all_target_wwpns)])
expect_cli_cmd = [
mock.call('ShowChannel'),
mock.call('ShowMap'),
mock.call('ShowWWN'),
mock.call('CreateMap', 'part', test_partition_id, '0', '112', '0',
'wwn=%s' % test_initiator_wwpns[0]),
mock.call('CreateMap', 'part', test_partition_id, '5', '112', '0',
'wwn=%s' % test_initiator_wwpns[0]),
mock.call('CreateMap', 'part', test_partition_id, '0', '112', '0',
'wwn=%s' % test_initiator_wwpns[1]),
mock.call('CreateMap', 'part', test_partition_id, '5', '112', '0',
'wwn=%s' % test_initiator_wwpns[1]),
]
self._assert_cli_has_calls(expect_cli_cmd)
self.assertDictMatch(
self.cli_data.test_fc_properties_zoning, properties)
@mock.patch.object(common_cli.LOG, 'info', mock.Mock())
def test_initialize_connection_with_zoning_r_model(self):
test_volume = self.cli_data.test_volume
test_connector = self.cli_data.test_connector_fc
test_initiator_wwpns = test_connector['wwpns']
test_partition_id = self.cli_data.fake_partition_id[0]
test_all_target_wwpns = self.cli_data.fake_target_wwpns[:]
test_all_target_wwpns[1] = self.cli_data.fake_target_wwpns[2]
test_all_target_wwpns[2] = self.cli_data.fake_target_wwpns[1]
test_lookup_map = self.cli_data.fake_lookup_map_r_model
mock_commands = {
'ShowChannel': self.cli_data.get_test_show_channel_r_model(),
'ShowMap': self.cli_data.get_test_show_map(),
'CreateMap': SUCCEED,
'ShowWWN': self.cli_data.get_test_show_wwn(),
}
self._driver_setup(mock_commands)
self.driver.fc_lookup_service = mock.Mock()
get_device_mapping_from_network = (
self.driver.fc_lookup_service.get_device_mapping_from_network
)
get_device_mapping_from_network.return_value = test_lookup_map
properties = self.driver.initialize_connection(
test_volume, test_connector)
get_device_mapping_from_network.assert_has_calls(
[mock.call(test_connector['wwpns'], test_all_target_wwpns)])
expect_cli_cmd = [
mock.call('ShowChannel'),
mock.call('ShowMap'),
mock.call('ShowWWN'),
mock.call('CreateMap', 'part', test_partition_id, '5', '112', '0',
'wwn=%s' % test_initiator_wwpns[0]),
mock.call('CreateMap', 'part', test_partition_id, '0', '113', '0',
'wwn=%s' % test_initiator_wwpns[0]),
mock.call('CreateMap', 'part', test_partition_id, '5', '112', '0',
'wwn=%s' % test_initiator_wwpns[1]),
mock.call('CreateMap', 'part', test_partition_id, '0', '113', '0',
'wwn=%s' % test_initiator_wwpns[1]),
]
self._assert_cli_has_calls(expect_cli_cmd)
self.assertDictMatch(
self.cli_data.test_fc_properties_zoning_r_model, properties)
@mock.patch.object(common_cli.LOG, 'info', mock.Mock())
def test_initialize_connection_with_zoning_r_model_diff_target_id(self):
test_volume = self.cli_data.test_volume
test_connector = self.cli_data.test_connector_fc
test_initiator_wwpns = test_connector['wwpns']
test_partition_id = self.cli_data.fake_partition_id[0]
test_all_target_wwpns = self.cli_data.fake_target_wwpns[:]
test_all_target_wwpns[1] = self.cli_data.fake_target_wwpns[2]
test_all_target_wwpns[2] = self.cli_data.fake_target_wwpns[1]
test_lookup_map = self.cli_data.fake_lookup_map_r_model
mock_commands = {
'ShowChannel':
self.cli_data.get_test_show_channel_r_model_diff_target_id(),
'ShowMap': self.cli_data.get_test_show_map(),
'CreateMap': SUCCEED,
'ShowWWN': self.cli_data.get_test_show_wwn_with_diff_target_id(),
}
self._driver_setup(mock_commands)
self.driver.fc_lookup_service = mock.Mock()
get_device_mapping_from_network = (
self.driver.fc_lookup_service.get_device_mapping_from_network
)
get_device_mapping_from_network.return_value = test_lookup_map
properties = self.driver.initialize_connection(
test_volume, test_connector)
get_device_mapping_from_network.assert_has_calls(
[mock.call(test_connector['wwpns'], test_all_target_wwpns)])
expect_cli_cmd = [
mock.call('ShowChannel'),
mock.call('ShowMap'),
mock.call('ShowWWN'),
mock.call('CreateMap', 'part', test_partition_id, '5', '48', '0',
'wwn=%s' % test_initiator_wwpns[0]),
mock.call('CreateMap', 'part', test_partition_id, '0', '33', '0',
'wwn=%s' % test_initiator_wwpns[0]),
mock.call('CreateMap', 'part', test_partition_id, '5', '48', '0',
'wwn=%s' % test_initiator_wwpns[1]),
mock.call('CreateMap', 'part', test_partition_id, '0', '33', '0',
'wwn=%s' % test_initiator_wwpns[1]),
]
self._assert_cli_has_calls(expect_cli_cmd)
self.assertDictMatch(
self.cli_data.test_fc_properties_zoning_r_model, properties)
@mock.patch.object(common_cli.LOG, 'info', mock.Mock())
def test_terminate_connection(self):
test_volume = self.cli_data.test_volume
test_partition_id = self.cli_data.fake_partition_id[0]
test_connector = self.cli_data.test_connector_fc
mock_commands = {
'DeleteMap': SUCCEED,
'ShowMap': self.cli_data.get_test_show_map(),
}
self._driver_setup(mock_commands)
self.driver.terminate_connection(test_volume, test_connector)
expect_cli_cmd = [
mock.call('DeleteMap', 'part', test_partition_id, '-y'),
mock.call('ShowMap'),
]
self._assert_cli_has_calls(expect_cli_cmd)
@mock.patch.object(common_cli.LOG, 'info', mock.Mock())
def test_terminate_connection_with_zoning(self):
test_volume = self.cli_data.test_volume
test_partition_id = self.cli_data.fake_partition_id[0]
test_connector = self.cli_data.test_connector_fc
test_all_target_wwpns = self.cli_data.fake_target_wwpns[0:2]
test_lookup_map = self.cli_data.fake_lookup_map
mock_commands = {
'DeleteMap': SUCCEED,
'ShowMap': self.cli_data.get_test_show_map(),
'ShowWWN': self.cli_data.get_test_show_wwn_with_g_model(),
}
self._driver_setup(mock_commands)
self.driver.map_dict = {
'slot_a': {'0': [], '5': []},
'slot_b': {},
}
self.driver.fc_lookup_service = mock.Mock()
get_device_mapping_from_network = (
self.driver.fc_lookup_service.get_device_mapping_from_network
)
get_device_mapping_from_network.return_value = test_lookup_map
conn_info = self.driver.terminate_connection(
test_volume, test_connector)
get_device_mapping_from_network.assert_has_calls(
[mock.call(test_connector['wwpns'], test_all_target_wwpns)])
expect_cli_cmd = [
mock.call('DeleteMap', 'part', test_partition_id, '-y'),
mock.call('ShowMap'),
mock.call('ShowWWN'),
]
self._assert_cli_has_calls(expect_cli_cmd)
self.assertDictMatch(
self.cli_data.test_fc_terminate_conn_info, conn_info)
@mock.patch.object(common_cli.LOG, 'info', mock.Mock())
def test_terminate_connection_with_zoning_and_lun_map_exist(self):
test_volume = self.cli_data.test_volume
test_partition_id = self.cli_data.fake_partition_id[0]
test_connector = self.cli_data.test_connector_fc
mock_commands = {
'DeleteMap': SUCCEED,
'ShowMap': self.cli_data.get_show_map_with_lun_map_on_zoning(),
}
self._driver_setup(mock_commands)
self.driver.map_dict = {
'slot_a': {'0': [], '5': []},
'slot_b': {},
}
self.driver.target_dict = {
'slot_a': {'0': '112', '5': '112'},
'slot_b': {},
}
self.driver.fc_lookup_service = mock.Mock()
conn_info = self.driver.terminate_connection(
test_volume, test_connector)
expect_cli_cmd = [
mock.call('DeleteMap', 'part', test_partition_id, '-y'),
mock.call('ShowMap'),
]
self._assert_cli_has_calls(expect_cli_cmd)
self.assertIsNone(conn_info)
class InfortrendiSCSICommonTestCase(InfortrendTestCass):
def __init__(self, *args, **kwargs):
super(InfortrendiSCSICommonTestCase, self).__init__(*args, **kwargs)
def setUp(self):
super(InfortrendiSCSICommonTestCase, self).setUp()
self.configuration.volume_backend_name = 'infortrend_backend_1'
self.configuration.san_ip = self.cli_data.fake_manage_port_ip[0]
self.configuration.san_password = '111111'
self.configuration.infortrend_provisioning = 'full'
self.configuration.infortrend_tiering = '0'
self.configuration.infortrend_pools_name = 'LV-1, LV-2'
self.configuration.infortrend_slots_a_channels_id = '1,2,4'
self.configuration.infortrend_slots_b_channels_id = '1,2,4'
def _get_driver(self, conf):
return common_cli.InfortrendCommon('iSCSI', configuration=conf)
@mock.patch.object(common_cli.LOG, 'warning')
def test_create_map_warning_return_code(self, log_warning):
FAKE_RETURN_CODE = (20, '')
mock_commands = {
'CreateMap': FAKE_RETURN_CODE,
}
self._driver_setup(mock_commands)
self.driver._execute('CreateMap')
self.assertEqual(1, log_warning.call_count)
@mock.patch.object(common_cli.LOG, 'warning')
def test_delete_map_warning_return_code(self, log_warning):
FAKE_RETURN_CODE = (11, '')
mock_commands = {
'DeleteMap': FAKE_RETURN_CODE,
}
self._driver_setup(mock_commands)
self.driver._execute('DeleteMap')
self.assertEqual(1, log_warning.call_count)
@mock.patch.object(common_cli.LOG, 'warning')
def test_create_iqn_warning_return_code(self, log_warning):
FAKE_RETURN_CODE = (20, '')
mock_commands = {
'CreateIQN': FAKE_RETURN_CODE,
}
self._driver_setup(mock_commands)
self.driver._execute('CreateIQN')
self.assertEqual(1, log_warning.call_count)
@mock.patch.object(common_cli.LOG, 'warning')
def test_delete_iqn_warning_return_code_has_map(self, log_warning):
FAKE_RETURN_CODE = (20, '')
mock_commands = {
'DeleteIQN': FAKE_RETURN_CODE,
}
self._driver_setup(mock_commands)
self.driver._execute('DeleteIQN')
self.assertEqual(1, log_warning.call_count)
@mock.patch.object(common_cli.LOG, 'warning')
def test_delete_iqn_warning_return_code_no_such_name(self, log_warning):
FAKE_RETURN_CODE = (11, '')
mock_commands = {
'DeleteIQN': FAKE_RETURN_CODE,
}
self._driver_setup(mock_commands)
self.driver._execute('DeleteIQN')
self.assertEqual(1, log_warning.call_count)
def test_normal_channel(self):
test_map_dict = {
'slot_a': {'1': [], '2': [], '4': []},
'slot_b': {},
}
test_target_dict = {
'slot_a': {'1': '0', '2': '0', '4': '0'},
'slot_b': {},
}
mock_commands = {
'ShowChannel': self.cli_data.get_test_show_channel(),
}
self._driver_setup(mock_commands)
self.driver._init_map_info()
self.assertDictMatch(test_map_dict, self.driver.map_dict)
self.assertDictMatch(test_target_dict, self.driver.target_dict)
def test_normal_channel_with_multipath(self):
test_map_dict = {
'slot_a': {'1': [], '2': [], '4': []},
'slot_b': {'1': [], '2': [], '4': []},
}
test_target_dict = {
'slot_a': {'1': '0', '2': '0', '4': '0'},
'slot_b': {'1': '1', '2': '1', '4': '1'},
}
mock_commands = {
'ShowChannel': self.cli_data.get_test_show_channel_r_model(),
}
self._driver_setup(mock_commands)
self.driver._init_map_info(multipath=True)
self.assertDictMatch(test_map_dict, self.driver.map_dict)
self.assertDictMatch(test_target_dict, self.driver.target_dict)
def test_specific_channel(self):
configuration = copy.copy(self.configuration)
configuration.infortrend_slots_a_channels_id = '2, 4'
test_map_dict = {
'slot_a': {'2': [], '4': []},
'slot_b': {},
}
test_target_dict = {
'slot_a': {'2': '0', '4': '0'},
'slot_b': {},
}
mock_commands = {
'ShowChannel': self.cli_data.get_test_show_channel(),
}
self._driver_setup(mock_commands, configuration)
self.driver._init_map_info()
self.assertDictMatch(test_map_dict, self.driver.map_dict)
self.assertDictMatch(test_target_dict, self.driver.target_dict)
def test_update_mcs_dict(self):
configuration = copy.copy(self.configuration)
configuration.use_multipath_for_image_xfer = True
test_mcs_dict = {
'slot_a': {'1': ['1', '2'], '2': ['4']},
'slot_b': {},
}
mock_commands = {
'ShowChannel': self.cli_data.get_test_show_channel_with_mcs(),
}
self._driver_setup(mock_commands, configuration)
self.driver._init_map_info()
self.assertDictMatch(test_mcs_dict, self.driver.mcs_dict)
def test_mapping_info_with_mcs(self):
configuration = copy.copy(self.configuration)
configuration.use_multipath_for_image_xfer = True
fake_mcs_dict = {
'slot_a': {'0': ['1', '2'], '2': ['4']},
'slot_b': {},
}
lun_list = list(range(0, 127))
fake_map_dict = {
'slot_a': {'1': lun_list[2:], '2': lun_list[:], '4': lun_list[1:]},
'slot_b': {},
}
test_map_chl = {
'slot_a': ['1', '2'],
}
test_map_lun = ['2']
test_mcs_id = '0'
self.driver = self._get_driver(configuration)
self.driver.mcs_dict = fake_mcs_dict
self.driver.map_dict = fake_map_dict
map_chl, map_lun, mcs_id = self.driver._get_mapping_info_with_mcs()
self.assertDictMatch(test_map_chl, map_chl)
self.assertEqual(test_map_lun, map_lun)
self.assertEqual(test_mcs_id, mcs_id)
def test_mapping_info_with_mcs_multi_group(self):
configuration = copy.copy(self.configuration)
configuration.use_multipath_for_image_xfer = True
fake_mcs_dict = {
'slot_a': {'0': ['1', '2'], '1': ['3', '4'], '2': ['5']},
'slot_b': {},
}
lun_list = list(range(0, 127))
fake_map_dict = {
'slot_a': {
'1': lun_list[2:],
'2': lun_list[:],
'3': lun_list[:],
'4': lun_list[1:],
'5': lun_list[:],
},
'slot_b': {},
}
test_map_chl = {
'slot_a': ['3', '4'],
}
test_map_lun = ['1']
test_mcs_id = '1'
self.driver = self._get_driver(configuration)
self.driver.mcs_dict = fake_mcs_dict
self.driver.map_dict = fake_map_dict
map_chl, map_lun, mcs_id = self.driver._get_mapping_info_with_mcs()
self.assertDictMatch(test_map_chl, map_chl)
self.assertEqual(test_map_lun, map_lun)
self.assertEqual(test_mcs_id, mcs_id)
def test_specific_channel_with_multipath(self):
configuration = copy.copy(self.configuration)
configuration.infortrend_slots_a_channels_id = '1,2'
test_map_dict = {
'slot_a': {'1': [], '2': []},
'slot_b': {},
}
test_target_dict = {
'slot_a': {'1': '0', '2': '0'},
'slot_b': {},
}
mock_commands = {
'ShowChannel': self.cli_data.get_test_show_channel(),
}
self._driver_setup(mock_commands, configuration)
self.driver._init_map_info(multipath=True)
self.assertDictMatch(test_map_dict, self.driver.map_dict)
self.assertDictMatch(test_target_dict, self.driver.target_dict)
def test_specific_channel_with_multipath_r_model(self):
configuration = copy.copy(self.configuration)
configuration.infortrend_slots_a_channels_id = '1,2'
configuration.infortrend_slots_b_channels_id = '1'
test_map_dict = {
'slot_a': {'1': [], '2': []},
'slot_b': {'1': []},
}
test_target_dict = {
'slot_a': {'1': '0', '2': '0'},
'slot_b': {'1': '1'},
}
mock_commands = {
'ShowChannel': self.cli_data.get_test_show_channel_r_model(),
}
self._driver_setup(mock_commands, configuration)
self.driver._init_map_info(multipath=True)
self.assertDictMatch(test_map_dict, self.driver.map_dict)
self.assertDictMatch(test_target_dict, self.driver.target_dict)
@mock.patch.object(common_cli.LOG, 'info')
def test_create_volume(self, log_info):
test_volume = self.cli_data.test_volume
test_model_update = {
'provider_location': 'system_id^%s@partition_id^%s' % (
int(self.cli_data.fake_system_id[0], 16),
self.cli_data.fake_partition_id[0]),
}
mock_commands = {
'CreatePartition': SUCCEED,
'ShowPartition': self.cli_data.get_test_show_partition(),
'ShowDevice': self.cli_data.get_test_show_device(),
'ShowLV': self._mock_show_lv,
}
self._driver_setup(mock_commands)
model_update = self.driver.create_volume(test_volume)
self.assertDictMatch(test_model_update, model_update)
self.assertEqual(1, log_info.call_count)
@mock.patch.object(common_cli.LOG, 'info', mock.Mock())
def test_create_volume_with_create_fail(self):
test_volume = self.cli_data.test_volume
mock_commands = {
'CreatePartition': FAKE_ERROR_RETURN,
'ShowPartition': self.cli_data.get_test_show_partition(),
'ShowDevice': self.cli_data.get_test_show_device(),
'ShowLV': self._mock_show_lv,
}
self._driver_setup(mock_commands)
self.assertRaises(
exception.InfortrendCliException,
self.driver.create_volume,
test_volume)
@mock.patch.object(common_cli.LOG, 'info')
def test_delete_volume(self, log_info):
test_volume = self.cli_data.test_volume
test_partition_id = self.cli_data.fake_partition_id[0]
test_snapshot_id = self.cli_data.fake_snapshot_id
test_pair_id = self.cli_data.fake_pair_id
mock_commands = {
'ShowPartition':
self.cli_data.get_test_show_partition_detail_for_map(
test_partition_id),
'ShowReplica': self.cli_data.get_test_show_replica_detail(),
'DeleteReplica': SUCCEED,
'ShowSnapshot': self.cli_data.get_test_show_snapshot(),
'DeleteSnapshot': SUCCEED,
'ShowMap': self.cli_data.get_test_show_map(),
'DeleteMap': SUCCEED,
'DeletePartition': SUCCEED,
}
self._driver_setup(mock_commands)
self.driver.delete_volume(test_volume)
expect_cli_cmd = [
mock.call('ShowPartition', '-l'),
mock.call('ShowReplica', '-l'),
mock.call('DeleteReplica', test_pair_id[0], '-y'),
mock.call('ShowSnapshot', 'part=%s' % test_partition_id),
mock.call('DeleteSnapshot', test_snapshot_id[0], '-y'),
mock.call('DeleteSnapshot', test_snapshot_id[1], '-y'),
mock.call('ShowMap', 'part=%s' % test_partition_id),
mock.call('DeleteMap', 'part', test_partition_id, '-y'),
mock.call('DeletePartition', test_partition_id, '-y'),
]
self._assert_cli_has_calls(expect_cli_cmd)
self.assertEqual(1, log_info.call_count)
@mock.patch.object(common_cli.LOG, 'warning', mock.Mock())
def test_delete_volume_with_sync_pair(self):
test_volume = self.cli_data.test_volume
test_partition_id = self.cli_data.fake_partition_id[0]
mock_commands = {
'ShowPartition':
self.cli_data.get_test_show_partition_detail_for_map(
test_partition_id),
'ShowReplica':
self.cli_data.get_test_show_replica_detail_for_sync_pair(),
}
self._driver_setup(mock_commands)
self.assertRaises(
exception.VolumeDriverException,
self.driver.delete_volume,
test_volume)
def test_delete_volume_with_delete_fail(self):
test_volume = self.cli_data.test_volume
test_partition_id = self.cli_data.fake_partition_id[0]
mock_commands = {
'ShowPartition':
self.cli_data.get_test_show_partition_detail_for_map(
test_partition_id),
'ShowReplica': self.cli_data.get_test_show_replica_detail(),
'DeleteReplica': SUCCEED,
'ShowSnapshot': self.cli_data.get_test_show_snapshot(),
'DeleteSnapshot': SUCCEED,
'ShowMap': self.cli_data.get_test_show_map(),
'DeleteMap': SUCCEED,
'DeletePartition': FAKE_ERROR_RETURN,
}
self._driver_setup(mock_commands)
self.assertRaises(
exception.InfortrendCliException,
self.driver.delete_volume,
test_volume)
@mock.patch.object(common_cli.LOG, 'warning')
def test_delete_volume_with_partiton_not_found(self, log_warning):
test_volume = self.cli_data.test_volume
mock_commands = {
'ShowPartition': self.cli_data.get_test_show_empty_list(),
}
self._driver_setup(mock_commands)
self.driver.delete_volume(test_volume)
self.assertEqual(1, log_warning.call_count)
@mock.patch.object(common_cli.LOG, 'info')
def test_delete_volume_without_provider(self, log_info):
test_system_id = self.cli_data.fake_system_id[0]
test_volume = copy.deepcopy(self.cli_data.test_volume)
test_volume['provider_location'] = 'system_id^%s@partition_id^%s' % (
int(test_system_id, 16), 'None')
test_partition_id = self.cli_data.fake_partition_id[0]
mock_commands = {
'ShowPartition':
self.cli_data.get_test_show_partition_detail_for_map(
test_partition_id),
'ShowReplica': self.cli_data.get_test_show_replica_detail(),
'DeleteReplica': SUCCEED,
'ShowSnapshot': self.cli_data.get_test_show_snapshot(),
'DeleteSnapshot': SUCCEED,
'ShowMap': self.cli_data.get_test_show_map(),
'DeleteMap': SUCCEED,
'DeletePartition': SUCCEED,
}
self._driver_setup(mock_commands)
self.driver.delete_volume(test_volume)
self.assertEqual(1, log_info.call_count)
@mock.patch('oslo_service.loopingcall.FixedIntervalLoopingCall',
new=utils.ZeroIntervalLoopingCall)
@mock.patch.object(common_cli.LOG, 'info')
def test_create_cloned_volume(self, log_info):
fake_partition_id = self.cli_data.fake_partition_id[0]
test_dst_volume = self.cli_data.test_dst_volume
test_dst_volume_id = test_dst_volume['id'].replace('-', '')
test_src_volume = self.cli_data.test_volume
test_dst_part_id = self.cli_data.fake_partition_id[1]
test_model_update = {
'provider_location': 'system_id^%s@partition_id^%s' % (
int(self.cli_data.fake_system_id[0], 16),
self.cli_data.fake_partition_id[1]),
}
mock_commands = {
'CreatePartition': SUCCEED,
'ShowPartition': self.cli_data.get_test_show_partition(),
'ShowDevice': self.cli_data.get_test_show_device(),
'CreateReplica': SUCCEED,
'ShowLV': self._mock_show_lv,
'ShowReplica':
self.cli_data.get_test_show_replica_detail_for_migrate(
fake_partition_id, test_dst_part_id, test_dst_volume_id),
'DeleteReplica': SUCCEED,
}
self._driver_setup(mock_commands)
model_update = self.driver.create_cloned_volume(
test_dst_volume, test_src_volume)
self.assertDictMatch(test_model_update, model_update)
self.assertEqual(1, log_info.call_count)
@mock.patch.object(common_cli.LOG, 'info', mock.Mock())
def test_create_cloned_volume_with_create_replica_fail(self):
test_dst_volume = self.cli_data.test_dst_volume
test_src_volume = self.cli_data.test_volume
mock_commands = {
'CreatePartition': SUCCEED,
'ShowPartition': self.cli_data.get_test_show_partition(),
'ShowDevice': self.cli_data.get_test_show_device(),
'CreateReplica': FAKE_ERROR_RETURN,
'ShowLV': self._mock_show_lv,
}
self._driver_setup(mock_commands)
self.assertRaises(
exception.InfortrendCliException,
self.driver.create_cloned_volume,
test_dst_volume,
test_src_volume)
@mock.patch.object(common_cli.LOG, 'info', mock.Mock())
def test_create_export(self):
test_volume = self.cli_data.test_volume
test_model_update = {
'provider_location': test_volume['provider_location'],
}
self.driver = self._get_driver(self.configuration)
model_update = self.driver.create_export(None, test_volume)
self.assertDictMatch(test_model_update, model_update)
@mock.patch.object(common_cli.LOG, 'info', mock.Mock())
def test_get_volume_stats(self):
test_volume_states = self.cli_data.test_volume_states
mock_commands = {
'ShowLicense': self.cli_data.get_test_show_license(),
'ShowLV': self.cli_data.get_test_show_lv(),
'ShowPartition': self.cli_data.get_test_show_partition_detail(),
}
self._driver_setup(mock_commands)
self.driver.VERSION = '99.99'
volume_states = self.driver.get_volume_stats(True)
self.assertDictMatch(test_volume_states, volume_states)
def test_get_volume_stats_fail(self):
mock_commands = {
'ShowLicense': self.cli_data.get_test_show_license(),
'ShowLV': FAKE_ERROR_RETURN,
}
self._driver_setup(mock_commands)
self.assertRaises(
exception.InfortrendCliException,
self.driver.get_volume_stats)
@mock.patch.object(common_cli.LOG, 'info', mock.Mock())
def test_create_snapshot(self):
fake_partition_id = self.cli_data.fake_partition_id[0]
fake_snapshot_id = self.cli_data.fake_snapshot_id[0]
mock_commands = {
'CreateSnapshot': SUCCEED,
'ShowSnapshot': self.cli_data.get_test_show_snapshot(
partition_id=fake_partition_id,
snapshot_id=fake_snapshot_id),
'ShowPartition': self.cli_data.get_test_show_partition(),
}
self._driver_setup(mock_commands)
model_update = self.driver.create_snapshot(self.cli_data.test_snapshot)
self.assertEqual(fake_snapshot_id, model_update['provider_location'])
@mock.patch.object(common_cli.LOG, 'info', mock.Mock())
def test_create_snapshot_without_partition_id(self):
fake_partition_id = self.cli_data.fake_partition_id[0]
fake_snapshot_id = self.cli_data.fake_snapshot_id[0]
test_snapshot = self.cli_data.test_snapshot
mock_commands = {
'CreateSnapshot': SUCCEED,
'ShowSnapshot': self.cli_data.get_test_show_snapshot(
partition_id=fake_partition_id,
snapshot_id=fake_snapshot_id),
'ShowPartition': FAKE_ERROR_RETURN,
}
self._driver_setup(mock_commands)
self.assertRaises(
exception.InfortrendCliException,
self.driver.create_snapshot,
test_snapshot)
def test_create_snapshot_with_create_fail(self):
fake_partition_id = self.cli_data.fake_partition_id[0]
fake_snapshot_id = self.cli_data.fake_snapshot_id[0]
test_snapshot = self.cli_data.test_snapshot
mock_commands = {
'CreateSnapshot': FAKE_ERROR_RETURN,
'ShowSnapshot': self.cli_data.get_test_show_snapshot(
partition_id=fake_partition_id,
snapshot_id=fake_snapshot_id),
'ShowPartition': self.cli_data.get_test_show_partition(),
}
self._driver_setup(mock_commands)
self.assertRaises(
exception.InfortrendCliException,
self.driver.create_snapshot,
test_snapshot)
def test_create_snapshot_with_show_fail(self):
test_snapshot = self.cli_data.test_snapshot
mock_commands = {
'CreateSnapshot': SUCCEED,
'ShowSnapshot': FAKE_ERROR_RETURN,
'ShowPartition': self.cli_data.get_test_show_partition(),
}
self._driver_setup(mock_commands)
self.assertRaises(
exception.InfortrendCliException,
self.driver.create_snapshot,
test_snapshot)
@mock.patch.object(common_cli.LOG, 'info')
def test_delete_snapshot(self, log_info):
test_snapshot = self.cli_data.test_snapshot
mock_commands = {
'ShowReplica': self.cli_data.get_test_show_replica_detail(),
'DeleteSnapshot': SUCCEED,
}
self._driver_setup(mock_commands)
self.driver.delete_snapshot(test_snapshot)
self.assertEqual(1, log_info.call_count)
def test_delete_snapshot_without_provider_location(self):
test_snapshot = self.cli_data.test_snapshot
self.driver = self._get_driver(self.configuration)
self.driver._get_raid_snapshot_id = mock.Mock(return_value=None)
self.assertRaises(
exception.VolumeBackendAPIException,
self.driver.delete_snapshot,
test_snapshot)
def test_delete_snapshot_with_fail(self):
test_snapshot = self.cli_data.test_snapshot
mock_commands = {
'ShowReplica': self.cli_data.get_test_show_replica_detail(),
'DeleteSnapshot': FAKE_ERROR_RETURN,
}
self._driver_setup(mock_commands)
self.assertRaises(
exception.InfortrendCliException,
self.driver.delete_snapshot,
test_snapshot)
@mock.patch.object(common_cli.LOG, 'warning', mock.Mock())
def test_delete_snapshot_with_sync_pair(self):
test_snapshot = self.cli_data.test_snapshot
mock_commands = {
'ShowReplica':
self.cli_data.get_test_show_replica_detail_for_si_sync_pair(),
'DeleteSnapshot': FAKE_ERROR_RETURN,
}
self._driver_setup(mock_commands)
self.assertRaises(
exception.VolumeDriverException,
self.driver.delete_snapshot,
test_snapshot)
@mock.patch('oslo_service.loopingcall.FixedIntervalLoopingCall',
new=utils.ZeroIntervalLoopingCall)
@mock.patch.object(common_cli.LOG, 'info')
def test_create_volume_from_snapshot(self, log_info):
test_snapshot = self.cli_data.test_snapshot
test_snapshot_id = self.cli_data.fake_snapshot_id[0]
test_dst_volume = self.cli_data.test_dst_volume
test_dst_volume_id = test_dst_volume['id'].replace('-', '')
test_dst_part_id = self.cli_data.fake_partition_id[1]
test_model_update = {
'provider_location': 'system_id^%s@partition_id^%s' % (
int(self.cli_data.fake_system_id[0], 16),
self.cli_data.fake_partition_id[1]),
}
mock_commands = {
'ShowSnapshot':
self.cli_data.get_test_show_snapshot_detail_filled_block(),
'CreatePartition': SUCCEED,
'ShowPartition': self.cli_data.get_test_show_partition(),
'ShowDevice': self.cli_data.get_test_show_device(),
'CreateReplica': SUCCEED,
'ShowLV': self._mock_show_lv,
'ShowReplica':
self.cli_data.get_test_show_replica_detail_for_migrate(
test_snapshot_id, test_dst_part_id, test_dst_volume_id),
'DeleteReplica': SUCCEED,
}
self._driver_setup(mock_commands)
model_update = self.driver.create_volume_from_snapshot(
test_dst_volume, test_snapshot)
self.assertDictMatch(test_model_update, model_update)
self.assertEqual(1, log_info.call_count)
@mock.patch('oslo_service.loopingcall.FixedIntervalLoopingCall',
new=utils.ZeroIntervalLoopingCall)
@mock.patch.object(common_cli.LOG, 'info')
def test_create_volume_from_snapshot_without_filled_block(self, log_info):
test_snapshot = self.cli_data.test_snapshot
test_snapshot_id = self.cli_data.fake_snapshot_id[0]
test_dst_volume = self.cli_data.test_dst_volume
test_dst_volume_id = test_dst_volume['id'].replace('-', '')
test_dst_part_id = self.cli_data.fake_partition_id[1]
test_src_part_id = self.cli_data.fake_partition_id[0]
test_model_update = {
'provider_location': 'system_id^%s@partition_id^%s' % (
int(self.cli_data.fake_system_id[0], 16),
self.cli_data.fake_partition_id[1]),
}
mock_commands = {
'ShowSnapshot': self.cli_data.get_test_show_snapshot_detail(),
'CreatePartition': SUCCEED,
'ShowPartition': self.cli_data.get_test_show_partition(),
'ShowDevice': self.cli_data.get_test_show_device(),
'CreateReplica': SUCCEED,
'ShowLV': self._mock_show_lv,
'ShowReplica': [
self.cli_data.get_test_show_replica_detail_for_migrate(
test_src_part_id, test_dst_part_id, test_dst_volume_id),
self.cli_data.get_test_show_replica_detail_for_migrate(
test_snapshot_id, test_dst_part_id, test_dst_volume_id),
],
'DeleteReplica': SUCCEED,
}
self._driver_setup(mock_commands)
model_update = self.driver.create_volume_from_snapshot(
test_dst_volume, test_snapshot)
self.assertDictMatch(test_model_update, model_update)
self.assertEqual(1, log_info.call_count)
def test_create_volume_from_snapshot_without_provider_location(
self):
test_snapshot = self.cli_data.test_snapshot
test_dst_volume = self.cli_data.test_dst_volume
self.driver = self._get_driver(self.configuration)
self.driver._get_raid_snapshot_id = mock.Mock(return_value=None)
self.assertRaises(
exception.VolumeBackendAPIException,
self.driver.create_volume_from_snapshot,
test_dst_volume,
test_snapshot)
@mock.patch.object(common_cli.LOG, 'info', mock.Mock())
def test_initialize_connection(self):
test_volume = self.cli_data.test_volume
test_partition_id = self.cli_data.fake_partition_id[0]
test_connector = copy.deepcopy(self.cli_data.test_connector_iscsi)
test_iscsi_properties = self.cli_data.test_iscsi_properties
test_target_protal = [test_iscsi_properties['data']['target_portal']]
test_target_iqn = [test_iscsi_properties['data']['target_iqn']]
test_connector['multipath'] = False
mock_commands = {
'ShowChannel': self.cli_data.get_test_show_channel(),
'ShowMap': self.cli_data.get_test_show_map(),
'ShowIQN': self.cli_data.get_test_show_iqn(),
'CreateMap': SUCCEED,
'ShowNet': self.cli_data.get_test_show_net(),
'ExecuteCommand': self.cli_data.get_fake_discovery(
test_target_iqn, test_target_protal),
}
self._driver_setup(mock_commands)
properties = self.driver.initialize_connection(
test_volume, test_connector)
self.assertDictMatch(test_iscsi_properties, properties)
expect_cli_cmd = [
mock.call('CreateMap', 'part', test_partition_id, '2', '0', '0',
'iqn=%s' % test_connector['initiator']),
]
self._assert_cli_has_calls(expect_cli_cmd)
@mock.patch.object(common_cli.LOG, 'info', mock.Mock())
def test_initialize_connection_with_iqn_not_exist(self):
test_volume = self.cli_data.test_volume
test_partition_id = self.cli_data.fake_partition_id[0]
test_initiator = copy.deepcopy(self.cli_data.fake_initiator_iqn[1])
test_connector = copy.deepcopy(self.cli_data.test_connector_iscsi)
test_iscsi_properties = self.cli_data.test_iscsi_properties
test_target_protal = [test_iscsi_properties['data']['target_portal']]
test_target_iqn = [test_iscsi_properties['data']['target_iqn']]
test_connector['multipath'] = False
test_connector['initiator'] = test_initiator
mock_commands = {
'ShowChannel': self.cli_data.get_test_show_channel(),
'ShowMap': self.cli_data.get_test_show_map(),
'ShowIQN': self.cli_data.get_test_show_iqn(),
'CreateIQN': SUCCEED,
'CreateMap': SUCCEED,
'ShowNet': self.cli_data.get_test_show_net(),
'ExecuteCommand': self.cli_data.get_fake_discovery(
test_target_iqn, test_target_protal),
}
self._driver_setup(mock_commands)
properties = self.driver.initialize_connection(
test_volume, test_connector)
self.assertDictMatch(test_iscsi_properties, properties)
expect_cli_cmd = [
mock.call('CreateIQN', test_initiator, test_initiator[-16:]),
mock.call('CreateMap', 'part', test_partition_id, '2', '0', '0',
'iqn=%s' % test_connector['initiator']),
]
self._assert_cli_has_calls(expect_cli_cmd)
@mock.patch.object(common_cli.LOG, 'info', mock.Mock())
def test_initialize_connection_with_empty_map(self):
test_volume = self.cli_data.test_volume
test_connector = copy.deepcopy(self.cli_data.test_connector_iscsi)
test_iscsi_properties = self.cli_data.test_iscsi_properties_empty_map
test_target_protal = [test_iscsi_properties['data']['target_portal']]
test_target_iqn = [test_iscsi_properties['data']['target_iqn']]
test_connector['multipath'] = False
mock_commands = {
'ShowChannel': self.cli_data.get_test_show_channel(),
'ShowMap': self.cli_data.get_test_show_empty_list(),
'ShowIQN': self.cli_data.get_test_show_iqn(),
'CreateMap': SUCCEED,
'ShowNet': self.cli_data.get_test_show_net(),
'ExecuteCommand': self.cli_data.get_fake_discovery(
test_target_iqn, test_target_protal),
}
self._driver_setup(mock_commands)
properties = self.driver.initialize_connection(
test_volume, test_connector)
self.assertDictMatch(
self.cli_data.test_iscsi_properties_empty_map, properties)
def test_initialize_connection_with_create_map_fail(self):
test_volume = self.cli_data.test_volume
test_connector = self.cli_data.test_connector_iscsi
mock_commands = {
'ShowChannel': self.cli_data.get_test_show_channel_r_model(),
'ShowMap': self.cli_data.get_test_show_map(),
'ShowIQN': self.cli_data.get_test_show_iqn(),
'CreateMap': FAKE_ERROR_RETURN,
'ShowNet': SUCCEED,
}
self._driver_setup(mock_commands)
self.assertRaises(
exception.InfortrendCliException,
self.driver.initialize_connection,
test_volume,
test_connector)
def test_initialize_connection_with_get_ip_fail(self):
test_volume = self.cli_data.test_volume
test_connector = self.cli_data.test_connector_iscsi
mock_commands = {
'ShowChannel': self.cli_data.get_test_show_channel(),
'ShowMap': self.cli_data.get_test_show_map(),
'ShowIQN': self.cli_data.get_test_show_iqn(),
'CreateMap': SUCCEED,
'ShowNet': FAKE_ERROR_RETURN,
}
self._driver_setup(mock_commands)
self.assertRaises(
exception.InfortrendCliException,
self.driver.initialize_connection,
test_volume,
test_connector)
@mock.patch.object(common_cli.LOG, 'info', mock.Mock())
def test_initialize_connection_with_mcs(self):
configuration = copy.copy(self.configuration)
configuration.use_multipath_for_image_xfer = True
test_volume = self.cli_data.test_volume
test_partition_id = self.cli_data.fake_partition_id[0]
test_connector = copy.deepcopy(self.cli_data.test_connector_iscsi)
test_iscsi_properties = self.cli_data.test_iscsi_properties_with_mcs
test_target_protal = [test_iscsi_properties['data']['target_portal']]
test_target_iqn = [test_iscsi_properties['data']['target_iqn']]
test_connector['multipath'] = False
mock_commands = {
'ShowChannel': self.cli_data.get_test_show_channel_with_mcs(),
'ShowMap': self.cli_data.get_test_show_map(),
'ShowIQN': self.cli_data.get_test_show_iqn(),
'CreateMap': SUCCEED,
'ShowNet': self.cli_data.get_test_show_net(),
'ExecuteCommand': self.cli_data.get_fake_discovery(
test_target_iqn, test_target_protal),
}
self._driver_setup(mock_commands, configuration)
properties = self.driver.initialize_connection(
test_volume, test_connector)
self.assertDictMatch(test_iscsi_properties, properties)
expect_cli_cmd = [
mock.call('CreateMap', 'part', test_partition_id, '1', '0', '2',
'iqn=%s' % test_connector['initiator']),
]
self._assert_cli_has_calls(expect_cli_cmd)
@mock.patch.object(common_cli.LOG, 'info', mock.Mock())
def test_extend_volume(self):
test_volume = self.cli_data.test_volume
test_partition_id = self.cli_data.fake_partition_id[0]
test_new_size = 10
test_expand_size = test_new_size - test_volume['size']
mock_commands = {
'SetPartition': SUCCEED,
}
self._driver_setup(mock_commands)
self.driver.extend_volume(test_volume, test_new_size)
expect_cli_cmd = [
mock.call('SetPartition', 'expand', test_partition_id,
'size=%sGB' % test_expand_size),
]
self._assert_cli_has_calls(expect_cli_cmd)
@mock.patch.object(common_cli.LOG, 'info', mock.Mock())
def test_extend_volume_mb(self):
test_volume = self.cli_data.test_volume
test_partition_id = self.cli_data.fake_partition_id[0]
test_new_size = 5.5
test_expand_size = round((test_new_size - test_volume['size']) * 1024)
mock_commands = {
'SetPartition': SUCCEED,
}
self._driver_setup(mock_commands)
self.driver.extend_volume(test_volume, test_new_size)
expect_cli_cmd = [
mock.call('SetPartition', 'expand', test_partition_id,
'size=%sMB' % test_expand_size),
]
self._assert_cli_has_calls(expect_cli_cmd)
def test_extend_volume_fail(self):
test_volume = self.cli_data.test_volume
test_new_size = 10
mock_commands = {
'SetPartition': FAKE_ERROR_RETURN,
}
self._driver_setup(mock_commands)
self.assertRaises(
exception.InfortrendCliException,
self.driver.extend_volume,
test_volume,
test_new_size)
@mock.patch.object(common_cli.LOG, 'info', mock.Mock())
def test_terminate_connection(self):
test_volume = self.cli_data.test_volume
test_partition_id = self.cli_data.fake_partition_id[0]
test_connector = self.cli_data.test_connector_iscsi
mock_commands = {
'DeleteMap': SUCCEED,
'DeleteIQN': SUCCEED,
'ShowMap': self.cli_data.get_test_show_map(),
}
self._driver_setup(mock_commands)
self.driver.terminate_connection(test_volume, test_connector)
expect_cli_cmd = [
mock.call('DeleteMap', 'part', test_partition_id, '-y'),
mock.call('DeleteIQN', test_connector['initiator'][-16:]),
mock.call('ShowMap'),
]
self._assert_cli_has_calls(expect_cli_cmd)
def test_terminate_connection_fail(self):
test_volume = self.cli_data.test_volume
test_connector = self.cli_data.test_connector_iscsi
mock_commands = {
'DeleteMap': FAKE_ERROR_RETURN,
}
self._driver_setup(mock_commands)
self.assertRaises(
exception.InfortrendCliException,
self.driver.terminate_connection,
test_volume,
test_connector)
@mock.patch('oslo_service.loopingcall.FixedIntervalLoopingCall',
new=utils.ZeroIntervalLoopingCall)
def test_migrate_volume(self):
test_host = copy.deepcopy(self.cli_data.test_migrate_host)
fake_pool = copy.deepcopy(self.cli_data.fake_pool)
test_volume = self.cli_data.test_volume
test_volume_id = test_volume['id'].replace('-', '')
test_src_part_id = self.cli_data.fake_partition_id[0]
test_dst_part_id = self.cli_data.fake_partition_id[2]
test_pair_id = self.cli_data.fake_pair_id[0]
test_model_update = {
'provider_location': 'system_id^%s@partition_id^%s' % (
int(self.cli_data.fake_system_id[0], 16),
test_dst_part_id),
}
mock_commands = {
'CreatePartition': SUCCEED,
'ShowPartition': self.cli_data.get_test_show_partition(
test_volume_id, fake_pool['pool_id']),
'CreateReplica': SUCCEED,
'ShowLV': self._mock_show_lv_for_migrate,
'ShowReplica':
self.cli_data.get_test_show_replica_detail_for_migrate(
test_src_part_id, test_dst_part_id, test_volume_id),
'DeleteReplica': SUCCEED,
'DeleteMap': SUCCEED,
'DeletePartition': SUCCEED,
}
self._driver_setup(mock_commands)
rc, model_update = self.driver.migrate_volume(test_volume, test_host)
expect_cli_cmd = [
mock.call('CreatePartition',
fake_pool['pool_id'],
test_volume['id'].replace('-', ''),
'size=%s' % (test_volume['size'] * 1024),
''),
mock.call('ShowPartition'),
mock.call('CreateReplica',
'Cinder-Migrate',
'part', test_src_part_id,
'part', test_dst_part_id,
'type=mirror'),
mock.call('ShowReplica', '-l'),
mock.call('DeleteReplica', test_pair_id, '-y'),
mock.call('DeleteMap', 'part', test_src_part_id, '-y'),
mock.call('DeletePartition', test_src_part_id, '-y'),
]
self._assert_cli_has_calls(expect_cli_cmd)
self.assertTrue(rc)
self.assertDictMatch(test_model_update, model_update)
@mock.patch.object(common_cli.LOG, 'warning')
def test_migrate_volume_with_invalid_storage(self, log_warning):
fake_host = self.cli_data.fake_host
test_volume = self.cli_data.test_volume
mock_commands = {
'ShowLV': self._mock_show_lv_for_migrate,
}
self._driver_setup(mock_commands)
rc, model_update = self.driver.migrate_volume(test_volume, fake_host)
self.assertFalse(rc)
self.assertTrue(model_update is None)
self.assertEqual(1, log_warning.call_count)
def test_migrate_volume_with_get_part_id_fail(self):
test_host = copy.deepcopy(self.cli_data.test_migrate_host)
test_volume = self.cli_data.test_volume
mock_commands = {
'CreatePartition': SUCCEED,
'ShowPartition': self.cli_data.get_test_show_partition(),
'DeleteMap': SUCCEED,
'CreateReplica': SUCCEED,
'CreateMap': SUCCEED,
'ShowLV': self._mock_show_lv_for_migrate,
}
self._driver_setup(mock_commands)
self.assertRaises(
exception.VolumeDriverException,
self.driver.migrate_volume,
test_volume,
test_host)
def test_migrate_volume_with_create_replica_fail(self):
test_host = copy.deepcopy(self.cli_data.test_migrate_host)
fake_pool = copy.deepcopy(self.cli_data.fake_pool)
test_volume = self.cli_data.test_volume
mock_commands = {
'CreatePartition': SUCCEED,
'ShowPartition': self.cli_data.get_test_show_partition(
test_volume['id'].replace('-', ''), fake_pool['pool_id']),
'DeleteMap': SUCCEED,
'CreateReplica': FAKE_ERROR_RETURN,
'CreateMap': SUCCEED,
'ShowLV': self._mock_show_lv_for_migrate,
}
self._driver_setup(mock_commands)
self.assertRaises(
exception.InfortrendCliException,
self.driver.migrate_volume,
test_volume,
test_host)
@mock.patch('oslo_service.loopingcall.FixedIntervalLoopingCall',
new=utils.ZeroIntervalLoopingCall)
def test_migrate_volume_timeout(self):
test_host = copy.deepcopy(self.cli_data.test_migrate_host)
fake_pool = copy.deepcopy(self.cli_data.fake_pool)
test_volume = self.cli_data.test_volume
test_volume_id = test_volume['id'].replace('-', '')
test_src_part_id = self.cli_data.fake_partition_id[0]
test_dst_part_id = self.cli_data.fake_partition_id[2]
configuration = copy.copy(self.configuration)
configuration.infortrend_cli_timeout = 0
mock_commands = {
'CreatePartition': SUCCEED,
'ShowPartition': self.cli_data.get_test_show_partition(
test_volume_id, fake_pool['pool_id']),
'CreateReplica': SUCCEED,
'ShowLV': self._mock_show_lv_for_migrate,
'ShowReplica':
self.cli_data.get_test_show_replica_detail_for_migrate(
test_src_part_id, test_dst_part_id, test_volume_id,
'Copy'),
}
self._driver_setup(mock_commands, configuration)
self.assertRaises(
exception.VolumeDriverException,
self.driver.migrate_volume,
test_volume,
test_host)
def test_manage_existing_get_size(self):
test_volume = self.cli_data.test_volume
test_ref_volume = self.cli_data.test_ref_volume
test_pool = self.cli_data.fake_lv_id[0]
test_partition_id = self.cli_data.fake_partition_id[2]
test_ref_volume_id = test_ref_volume['source-id'].replace('-', '')
mock_commands = {
'ShowPartition': self.cli_data.get_test_show_partition_detail(
'cinder-unmanaged-%s' % test_ref_volume_id[:-17], test_pool),
'ShowMap': SUCCEED,
}
self._driver_setup(mock_commands)
size = self.driver.manage_existing_get_size(
test_volume, test_ref_volume)
expect_cli_cmd = [
mock.call('ShowMap', 'part=%s' % test_partition_id),
]
self._assert_cli_has_calls(expect_cli_cmd)
self.assertEqual(1, size)
def test_manage_existing_get_size_with_import(self):
test_volume = self.cli_data.test_volume
test_ref_volume = self.cli_data.test_ref_volume_with_import
test_pool = self.cli_data.fake_lv_id[0]
test_partition_id = self.cli_data.fake_partition_id[2]
mock_commands = {
'ShowPartition': self.cli_data.get_test_show_partition_detail(
test_ref_volume['source-name'], test_pool),
'ShowMap': SUCCEED,
}
self._driver_setup(mock_commands)
size = self.driver.manage_existing_get_size(
test_volume, test_ref_volume)
expect_cli_cmd = [
mock.call('ShowMap', 'part=%s' % test_partition_id),
]
self._assert_cli_has_calls(expect_cli_cmd)
self.assertEqual(1, size)
def test_manage_existing_get_size_in_use(self):
test_volume = self.cli_data.test_volume
test_ref_volume = self.cli_data.test_ref_volume
test_pool = self.cli_data.fake_lv_id[0]
test_ref_volume_id = test_ref_volume['source-id'].replace('-', '')
mock_commands = {
'ShowPartition': self.cli_data.get_test_show_partition_detail(
'cinder-unmanaged-%s' % test_ref_volume_id[:-17], test_pool),
'ShowMap': self.cli_data.get_test_show_map(),
}
self._driver_setup(mock_commands)
self.assertRaises(
exception.VolumeBackendAPIException,
self.driver.manage_existing_get_size,
test_volume,
test_ref_volume)
def test_manage_existing_get_size_no_source_id(self):
test_volume = self.cli_data.test_volume
test_ref_volume = self.cli_data.test_dst_volume
self.driver = self._get_driver(self.configuration)
self.assertRaises(
exception.ManageExistingInvalidReference,
self.driver.manage_existing_get_size,
test_volume,
test_ref_volume)
def test_manage_existing_get_size_show_part_fail(self):
test_volume = self.cli_data.test_volume
test_ref_volume = self.cli_data.test_ref_volume
mock_commands = {
'ShowPartition': FAKE_ERROR_RETURN,
'ShowMap': SUCCEED,
}
self._driver_setup(mock_commands)
self.assertRaises(
exception.InfortrendCliException,
self.driver.manage_existing_get_size,
test_volume,
test_ref_volume)
def test_manage_existing_get_size_show_map_fail(self):
test_volume = self.cli_data.test_volume
test_ref_volume = self.cli_data.test_ref_volume
test_pool = self.cli_data.fake_lv_id[0]
test_ref_volume_id = test_ref_volume['source-id'].replace('-', '')
mock_commands = {
'ShowPartition': self.cli_data.get_test_show_partition_detail(
'cinder-unmanaged-%s' % test_ref_volume_id[:-17], test_pool),
'ShowMap': FAKE_ERROR_RETURN,
}
self._driver_setup(mock_commands)
self.assertRaises(
exception.InfortrendCliException,
self.driver.manage_existing_get_size,
test_volume,
test_ref_volume)
@mock.patch.object(common_cli.LOG, 'info')
def test_manage_existing(self, log_info):
test_volume = self.cli_data.test_volume
test_ref_volume = self.cli_data.test_ref_volume
test_pool = self.cli_data.fake_lv_id[0]
test_partition_id = self.cli_data.fake_partition_id[2]
test_ref_volume_id = test_ref_volume['source-id'].replace('-', '')
test_model_update = {
'provider_location': 'system_id^%s@partition_id^%s' % (
int(self.cli_data.fake_system_id[0], 16),
test_partition_id),
}
mock_commands = {
'ShowPartition': self.cli_data.get_test_show_partition_detail(
'cinder-unmanaged-%s' % test_ref_volume_id[:-17], test_pool),
'SetPartition': SUCCEED,
'ShowDevice': self.cli_data.get_test_show_device(),
}
self._driver_setup(mock_commands)
model_update = self.driver.manage_existing(
test_volume, test_ref_volume)
expect_cli_cmd = [
mock.call('SetPartition', test_partition_id,
'name=%s' % test_volume['id'].replace('-', '')),
]
self._assert_cli_has_calls(expect_cli_cmd)
self.assertEqual(1, log_info.call_count)
self.assertDictMatch(test_model_update, model_update)
def test_manage_existing_rename_fail(self):
test_volume = self.cli_data.test_volume
test_ref_volume = self.cli_data.test_ref_volume
test_pool = self.cli_data.fake_lv_id[0]
test_ref_volume_id = test_ref_volume['source-id'].replace('-', '')
mock_commands = {
'ShowPartition': self.cli_data.get_test_show_partition_detail(
'cinder-unmanaged-%s' % test_ref_volume_id[:-17], test_pool),
'SetPartition': FAKE_ERROR_RETURN,
}
self._driver_setup(mock_commands)
self.assertRaises(
exception.InfortrendCliException,
self.driver.manage_existing,
test_volume,
test_ref_volume)
def test_manage_existing_with_part_not_found(self):
test_volume = self.cli_data.test_volume
test_ref_volume = self.cli_data.test_ref_volume
mock_commands = {
'ShowPartition':
self.cli_data.get_test_show_partition_detail(),
'SetPartition': SUCCEED,
}
self._driver_setup(mock_commands)
self.assertRaises(
exception.ManageExistingInvalidReference,
self.driver.manage_existing,
test_volume,
test_ref_volume)
@mock.patch.object(common_cli.LOG, 'info')
def test_manage_existing_with_import(self, log_info):
test_volume = self.cli_data.test_volume
test_ref_volume = self.cli_data.test_ref_volume_with_import
test_pool = self.cli_data.fake_lv_id[0]
test_partition_id = self.cli_data.fake_partition_id[2]
test_model_update = {
'provider_location': 'system_id^%s@partition_id^%s' % (
int(self.cli_data.fake_system_id[0], 16),
test_partition_id),
}
mock_commands = {
'ShowPartition': self.cli_data.get_test_show_partition_detail(
test_ref_volume['source-name'], test_pool),
'SetPartition': SUCCEED,
'ShowDevice': self.cli_data.get_test_show_device(),
}
self._driver_setup(mock_commands)
model_update = self.driver.manage_existing(
test_volume, test_ref_volume)
expect_cli_cmd = [
mock.call('SetPartition', test_partition_id,
'name=%s' % test_volume['id'].replace('-', '')),
]
self._assert_cli_has_calls(expect_cli_cmd)
self.assertEqual(1, log_info.call_count)
self.assertDictMatch(test_model_update, model_update)
@mock.patch.object(common_cli.LOG, 'info')
def test_unmanage(self, log_info):
test_volume = self.cli_data.test_volume
test_volume_id = test_volume['id'].replace('-', '')
test_partition_id = self.cli_data.fake_partition_id[0]
mock_commands = {
'SetPartition': SUCCEED,
}
self._driver_setup(mock_commands)
self.driver.unmanage(test_volume)
expect_cli_cmd = [
mock.call(
'SetPartition',
test_partition_id,
'name=cinder-unmanaged-%s' % test_volume_id[:-17]),
]
self._assert_cli_has_calls(expect_cli_cmd)
self.assertEqual(1, log_info.call_count)
@mock.patch.object(common_cli.LOG, 'info')
def test_retype_without_change(self, log_info):
test_volume = self.cli_data.test_volume
test_new_type = self.cli_data.test_new_type
test_diff = {'extra_specs': {}}
test_host = self.cli_data.test_migrate_host_2
self.driver = self._get_driver(self.configuration)
rc = self.driver.retype(
None, test_volume, test_new_type, test_diff, test_host)
self.assertTrue(rc)
self.assertEqual(1, log_info.call_count)
@mock.patch.object(common_cli.LOG, 'warning')
def test_retype_with_change_provision(self, log_warning):
test_volume = self.cli_data.test_volume
test_new_type = self.cli_data.test_new_type
test_diff = self.cli_data.test_diff
test_host = self.cli_data.test_migrate_host_2
self.driver = self._get_driver(self.configuration)
rc = self.driver.retype(
None, test_volume, test_new_type, test_diff, test_host)
self.assertFalse(rc)
self.assertEqual(1, log_warning.call_count)
@mock.patch.object(common_cli.LOG, 'info', mock.Mock())
def test_retype_with_migrate(self):
fake_pool = copy.deepcopy(self.cli_data.fake_pool)
test_host = copy.deepcopy(self.cli_data.test_migrate_host)
test_volume = self.cli_data.test_volume
test_volume_id = test_volume['id'].replace('-', '')
test_new_type = self.cli_data.test_new_type
test_diff = self.cli_data.test_diff
test_src_part_id = self.cli_data.fake_partition_id[0]
test_dst_part_id = self.cli_data.fake_partition_id[2]
test_pair_id = self.cli_data.fake_pair_id[0]
test_model_update = {
'provider_location': 'system_id^%s@partition_id^%s' % (
int(self.cli_data.fake_system_id[0], 16),
test_dst_part_id),
}
mock_commands = {
'ShowSnapshot': SUCCEED,
'CreatePartition': SUCCEED,
'ShowPartition': self.cli_data.get_test_show_partition(
test_volume_id, fake_pool['pool_id']),
'CreateReplica': SUCCEED,
'ShowLV': self._mock_show_lv_for_migrate,
'ShowReplica':
self.cli_data.get_test_show_replica_detail_for_migrate(
test_src_part_id, test_dst_part_id, test_volume_id),
'DeleteReplica': SUCCEED,
'DeleteMap': SUCCEED,
'DeletePartition': SUCCEED,
}
self._driver_setup(mock_commands)
rc, model_update = self.driver.retype(
None, test_volume, test_new_type, test_diff, test_host)
min_size = int(test_volume['size'] * 1024 * 0.2)
create_params = {'init': 'disable', 'min': '%sMB' % min_size}
create_params = ' '.join('%s=%s' % (key, value)
for key, value in create_params.items())
expect_cli_cmd = [
mock.call('ShowSnapshot', 'part=%s' % test_src_part_id),
mock.call(
'CreatePartition',
fake_pool['pool_id'],
test_volume['id'].replace('-', ''),
'size=%s' % (test_volume['size'] * 1024),
create_params,
),
mock.call('ShowPartition'),
mock.call(
'CreateReplica',
'Cinder-Migrate',
'part', test_src_part_id,
'part', test_dst_part_id,
'type=mirror'
),
mock.call('ShowReplica', '-l'),
mock.call('DeleteReplica', test_pair_id, '-y'),
mock.call('DeleteMap', 'part', test_src_part_id, '-y'),
mock.call('DeletePartition', test_src_part_id, '-y'),
]
self._assert_cli_has_calls(expect_cli_cmd)
self.assertTrue(rc)
self.assertDictMatch(test_model_update, model_update)
@mock.patch.object(common_cli.LOG, 'debug', mock.Mock())
@mock.patch.object(common_cli.LOG, 'info', mock.Mock())
def test_update_migrated_volume(self):
src_volume = self.cli_data.test_volume
dst_volume = copy.deepcopy(self.cli_data.test_dst_volume)
test_dst_part_id = self.cli_data.fake_partition_id[1]
dst_volume['provider_location'] = 'system_id^%s@partition_id^%s' % (
int(self.cli_data.fake_system_id[0], 16), test_dst_part_id)
test_model_update = {
'_name_id': None,
'provider_location': dst_volume['provider_location'],
}
mock_commands = {
'SetPartition': SUCCEED,
}
self._driver_setup(mock_commands)
model_update = self.driver.update_migrated_volume(
None, src_volume, dst_volume, 'available')
expect_cli_cmd = [
mock.call('SetPartition', test_dst_part_id,
'name=%s' % src_volume['id'].replace('-', '')),
]
self._assert_cli_has_calls(expect_cli_cmd)
self.assertDictMatch(test_model_update, model_update)
@mock.patch.object(common_cli.LOG, 'debug', mock.Mock())
def test_update_migrated_volume_rename_fail(self):
src_volume = self.cli_data.test_volume
dst_volume = self.cli_data.test_dst_volume
dst_volume['_name_id'] = 'fake_name_id'
test_dst_part_id = self.cli_data.fake_partition_id[1]
dst_volume['provider_location'] = 'system_id^%s@partition_id^%s' % (
int(self.cli_data.fake_system_id[0], 16), test_dst_part_id)
mock_commands = {
'SetPartition': FAKE_ERROR_RETURN
}
self._driver_setup(mock_commands)
model_update = self.driver.update_migrated_volume(
None, src_volume, dst_volume, 'available')
self.assertEqual({'_name_id': 'fake_name_id'}, model_update)