# 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 utils
from cinder.tests.unit.volume.drivers.infortrend import test_infortrend_cli
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.assertIsNone(model_update)
        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)
