# Copyright 2020 toyou Corp.
# 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.

"""
Testing for acs5000 san storage driver
"""

import copy
import json
import random
import time
from unittest import mock

from eventlet import greenthread
from oslo_concurrency import processutils
from oslo_config import cfg
from oslo_utils import excutils
from oslo_utils import units
import paramiko

from cinder import context
import cinder.db
from cinder import exception
from cinder.objects import volume_attachment
from cinder import ssh_utils
from cinder.tests.unit import fake_constants as fake
from cinder.tests.unit import test
from cinder.tests.unit import utils as testutils
from cinder import utils as cinder_utils
from cinder.volume import configuration as conf
from cinder.volume.drivers.toyou.acs5000 import acs5000_common
from cinder.volume.drivers.toyou.acs5000 import acs5000_fc
from cinder.volume.drivers.toyou.acs5000 import acs5000_iscsi

POOLS_NAME = ['pool01', 'pool02']
VOLUME_PRE = acs5000_common.VOLUME_PREFIX
# luns number only for test
LUN_NUMS_AVAILABLE = range(0, 5)
# snapshot count on a volume, only for test
SNAPSHOTS_A_VOLUME = 3
# snapshot count on a system, only for test
SNAPSHOTS_ON_SYSTEM = 10
# volume count on a pool, only for test
VOLUME_LIMIT_ON_POOL = 10
# volume count on a pool, only for test
VOLUME_LIMIT_ON_SYSTEM = 16
# volume count on a system, only for test

CONF = cfg.CONF


class CommandSimulator(object):
    def __init__(self, pool_name):
        self._all_pools_name = {'acs5000_volpool_name': pool_name}
        self._pools_list = {
            'pool01': {
                'name': 'pool01',
                'capacity': '799090409472',
                'free_capacity': '795869184000',
                'used_capacity': '3221225472',
                'total_volumes': 0},
            'pool02': {
                'name': 'pool02',
                'capacity': '193273528320',
                'free_capacity': '190052302848',
                'used_capacity': '3221225472',
                'total_volumes': 0
            }}
        self._volumes_list = {}
        self._lun_maps_list = []
        self._snapshots_list = []
        self._controllers_list = [
            {'id': '0',
             'name': 'node1',
             'iscsi_name': 'iqn.2020-12.cn.com.toyou:'
                           'disk-array-000f12345:dev0.ctr1',
             'WWNN': '200008CA45D33768',
             'status': 'online'},
            {'id': '1',
             'name': 'node2',
             'iscsi_name': 'iqn.2020-04.cn.com.toyou:'
                           'disk-array-000f12345:dev0.ctr2',
             'WWNN': '200008CA45D33768',
             'status': 'online'}]
        self._iscsi_list = [
            {'ctrl_idx': 0,
             'id': 0,
             'name': 'lan1',
             'ip': '10.23.45.67',
             'mask': '255.255.255.0',
             'gw': '',
             'link': '1 Gb/s'},
            {'ctrl_idx': 0,
             'id': 1,
             'name': 'lan2',
             'ip': '10.23.45.68',
             'mask': '255.255.255.0',
             'gw': '',
             'link': '1 Gb/s'},
            {'ctrl_idx': 0,
             'id': 2,
             'name': 'lan3',
             'ip': '10.23.45.69',
             'mask': '255.255.255.0',
             'gw': '',
             'link': '1 Gb/s'},
            {'ctrl_idx': 1,
             'id': 0,
             'name': 'lan1',
             'ip': '10.23.45.70',
             'mask': '255.255.255.0',
             'gw': '',
             'link': '1 Gb/s'},
            {'ctrl_idx': 1,
             'id': 1,
             'name': 'lan2',
             'ip': '10.23.45.71',
             'mask': '255.255.255.0',
             'gw': '',
             'link': 'Down'},
            {'ctrl_idx': 1,
             'id': 2,
             'name': 'lan3',
             'ip': '10.23.45.72',
             'mask': '255.255.255.0',
             'gw': '',
             'link': 'Down'}]
        self._fc_list = [
            {'ctrl_idx': 0,
             'WWPN': str(random.randint(0, 9999999999999999)).zfill(16),
             'link': 'Up'},
            {'ctrl_idx': 0,
             'wwpn': str(random.randint(0, 9999999999999999)).zfill(16),
             'link': 'Up'},
            {'ctrl_idx': 0,
             'link': 'Up'},
            {'ctrl_idx': 1,
             'WWPN': str(random.randint(0, 9999999999999999)).zfill(16),
             'link': 'Up'},
            {'ctrl_idx': 1,
             'link': 'Up'},
            {'ctrl_idx': 1,
             'wwpn': str(random.randint(0, 9999999999999999)).zfill(16),
             'link': 'Down'}]
        self._system_info = {'version': '3.1.2.345678',
                             'vendor': 'TOYOU',
                             'system_name': 'Disk-Array',
                             'system_id': 'TY123456789ABCDEF',
                             'code_level': '1',
                             'ip': '10.0.0.1'}

        self._error = {
            'success': (0, 'Success'),
            'unknown': (1, 'unknown error'),
            'pool_not_exist': (101, 'The pool does not exist '
                                    'on the system.'),
            'pool_exceeds_size': (102, 'The pool cannot provide '
                                       'more storage space'),
            'volume_not_exist': (303, 'The volume does not exist '
                                      'on the system.'),
            'source_volume_not_exist': (304, 'A clone relation needs '
                                             'a source volume.'),
            'target_volume_not_exist': (305, 'A clone relation needs '
                                             'a target volume.'),
            'source_size_larger_target': (306, 'The source volume '
                                               'must not be larger '
                                               'than the target volume'
                                               ' in a clone relation '),
            'volume_limit_pool': (307, 'A pool only supports 96 volumes'),
            'volume_limit_system': (308, 'A system only supports 96 volumes'),
            'volume_name_exist': (310, 'A volume with same name '
                                       'already exists on the system.'),
            'volume_extend_min': (321, 'A volume capacity shall not be'
                                       ' less than the current size'),
            'volume_extend_size_equal': (322, 'A volume capacity shall not '
                                              'be equal to than the '
                                              'current size'),
            'lun_not_exist': (401, 'The volume does not exist '
                                   'on the system.'),
            'not_available_lun': (402, 'The system have no available lun.'),
            'host_empty': (403, 'The host is empty.'),
            'snap_over_system': (503, 'The system snapshots maximum quantity '
                                      'has been reached.'),
            'snap_over_volume': (504, 'A volume snapshots maximum quantity '
                                      'has been reached.'),
            'snap_not_exist': (505, 'The snapshot does not exist '
                                    'on the system.'),
            'snap_not_latest': (506, 'The snapshot is not the latest one.'),
            'snapshot_not_belong_volume': (507, 'The snapshot does not '
                                                'belong to the volume.'),
            'snap_name_existed': (508, 'A snapshot with same name '
                                       'already exists on the system.')
        }
        self._command_function = {
            'set_volume': 'set_volume_property',
            'error_ssh': 'error_ssh'
        }
        self._volume_type = {
            '0': 'RAID Volume',
            '10': 'BACKUP'
        }

    @staticmethod
    def _json_return(rows=None, msg='', key=0):
        json_data = {'key': key,
                     'msg': msg,
                     'arr': rows}
        return (json.dumps(json_data), '')

    @staticmethod
    def _create_id(lists, key='id'):
        ids = []
        if isinstance(lists, list):
            for v in lists:
                ids.append(int(v[key]))
        elif isinstance(lists, dict):
            for v in lists.values():
                ids.append(int(v[key]))
        new_id = 'ffffffffff'
        while True:
            new_id = str(random.randint(1000000000, 9999999999))
            if new_id not in ids:
                break
        return new_id

    def _clone_thread(self, vol_name, setting=None):
        intval = 0.1
        loop_times = int(self._volumes_list[vol_name]['size_gb'])
        chunk = int(100 / loop_times)
        if setting:
            for k, value in setting.items():
                for v in value:
                    self._volumes_list[k][v[0]] = v[1]
                    time.sleep(v[2])

        self._volumes_list[vol_name]['status'] = 'Cloning'
        while loop_times > 0:
            # volumes may be deleted
            if vol_name in self._volumes_list:
                src_vol = self._volumes_list[vol_name]
            else:
                return
            if src_vol['clone'] not in self._volumes_list:
                self._volumes_list[vol_name]['status'] = 'Online'
                self._volumes_list[vol_name]['r'] = ''
                return
            progress = src_vol['r']
            if not progress:
                progress = 0
            src_vol['r'] = str(int(progress) + chunk)
            loop_times -= 1
            self._volumes_list[vol_name] = src_vol
            time.sleep(intval)
        self._volumes_list[vol_name]['status'] = 'Online'
        self._volumes_list[vol_name]['r'] = ''

    def execute_command(self, cmd_list, check_exit_code=True):
        command = cmd_list[1]
        if command in self._command_function:
            command = self._command_function[command]
        func = getattr(self, '_sim_' + command)
        kwargs = {}
        for i in range(2, len(cmd_list)):
            if cmd_list[i].startswith('--'):
                key = cmd_list[i][2:]
                value = ''
                if cmd_list[i + 1]:
                    value = cmd_list[i + 1]
                    i += 1
                if key in kwargs.keys():
                    if not isinstance(kwargs[key], list):
                        kwargs[key] = [kwargs[key]]

                    kwargs[key].append(value)
                else:
                    kwargs[key] = value
        try:
            out, err = func(**kwargs)
            return (out, err)
        except Exception as e:
            with excutils.save_and_reraise_exception():
                if check_exit_code:
                    raise processutils.ProcessExecutionError(
                        exit_code=1,
                        stdout='out',
                        stderr=e,
                        cmd=' '.join(cmd_list))

    def _sim_get_system(self, **kwargs):
        return self._json_return(self._system_info)

    def _sim_ls_iscsi(self, **kwargs):
        return self._json_return(self._iscsi_list)

    def _sim_ls_fc(self, **kwargs):
        return self._json_return(self._fc_list)

    def _sim_get_pool(self, **kwargs):
        pool_name = kwargs['pool'].strip('\'\"')
        if pool_name in self._all_pools_name['acs5000_volpool_name']:
            vol_len = 0
            for vol in self._volumes_list.values():
                if vol['poolname'] == pool_name:
                    vol_len += 1
            if pool_name in self._pools_list:
                pool_data = self._pools_list[pool_name]
            else:
                pool_data = self._pools_list['pool01']
                pool_data['name'] = pool_name
            pool_data['total_volumes'] = str(vol_len)
            return self._json_return(pool_data)
        else:
            return self._json_return({})

    def _sim_get_volume(self, **kwargs):
        rows = []
        if 'volume' not in kwargs:
            volume_name = []
        elif isinstance(kwargs['volume'], list):
            volume_name = kwargs['volume']
        elif isinstance(kwargs['volume'], str):
            volume_name = [kwargs['volume']]
        for vol_name in volume_name:
            if vol_name in self._volumes_list.keys():
                rows.append(self._volumes_list[vol_name])

        return self._json_return(rows)

    def _sim_ls_controller(self, **kwargs):
        return self._json_return(self._controllers_list)

    def _sim_create_volume(self, **kwargs):
        volume_name = kwargs['volume']
        pool_name = kwargs['pool']
        size = kwargs['size']
        type = kwargs['type']
        if pool_name not in self._pools_list:
            return self._json_return(
                msg=self._error['pool_not_exist'][1],
                key=self._error['pool_not_exist'][0])
        if volume_name in self._volumes_list:
            return self._json_return(
                msg=self._error['volume_name_exist'][1],
                key=self._error['volume_name_exist'][0])
        elif len(self._volumes_list) >= VOLUME_LIMIT_ON_SYSTEM:
            return self._json_return(
                msg=self._error['volume_limit_system'][1],
                key=self._error['volume_limit_system'][0])

        volume_count_on_pool = 0
        for v in self._volumes_list.values():
            if v['poolname'] == pool_name:
                volume_count_on_pool += 1
        if volume_count_on_pool >= VOLUME_LIMIT_ON_POOL:
            return self._json_return(
                msg=self._error['volume_limit_pool'][1],
                key=self._error['volume_limit_pool'][0])
        avail_size = (int(self._pools_list[pool_name]['free_capacity'])
                      / units.Gi)
        if float(size) > avail_size:
            return self._json_return(
                msg=self._error['pool_exceeds_size'][1],
                key=self._error['pool_exceeds_size'][0])
        volume_info = {}
        volume_info['id'] = self._create_id(self._volumes_list)
        volume_info['name'] = volume_name
        volume_info['size_gb'] = size
        volume_info['size_mb'] = str(int(float(size) * 1024))
        volume_info['status'] = 'Online'
        volume_info['health'] = 'Optimal'
        volume_info['r'] = ''
        volume_info['poolname'] = pool_name
        volume_info['has_clone'] = 0
        volume_info['clone'] = 'N/A'
        volume_info['clone_snap'] = 'N/A'
        if type not in ('0', '10'):
            type = '0'
        volume_info['type'] = self._volume_type[type]
        self._volumes_list[volume_info['name']] = volume_info
        return self._json_return()

    def _sim_delete_volume(self, **kwargs):
        vol_name = kwargs['volume']
        if vol_name in self._volumes_list:
            del self._volumes_list[vol_name]
        return self._json_return()

    def _sim_extend_volume(self, **kwargs):
        vol_name = kwargs['volume']
        size = int(kwargs['size'])
        if vol_name not in self._volumes_list:
            return self._json_return(
                msg=self._error['volume_not_exist'][1],
                key=self._error['volume_not_exist'][0])
        volume = self._volumes_list[vol_name]
        curr_size = int(volume['size_mb']) / 1024
        pool = self._pools_list[volume['poolname']]
        avail_size = int(pool['free_capacity']) / units.Gi
        if curr_size > size:
            return self._json_return(
                msg=self._error['volume_extend_min'][1],
                key=self._error['volume_extend_min'][0])
        elif curr_size == size:
            return self._json_return(
                msg=self._error['volume_extend_size_equal'][1],
                key=self._error['volume_extend_size_equal'][0])
        elif (size - curr_size) > avail_size:
            return self._json_return(
                msg=self._error['pool_exceeds_size'][1],
                key=self._error['pool_exceeds_size'][0])
        self._volumes_list[vol_name]['size_gb'] = str(size)
        return self._json_return()

    def _sim_create_clone(self, **kwargs):
        src_name = kwargs['volume']
        tgt_name = kwargs['clone']
        src_exist = False
        tgt_exist = False
        for vol in self._volumes_list.values():
            if (vol['name'] == src_name
                    and vol['type'] == self._volume_type['0']):
                src_exist = True
            elif (vol['name'] == tgt_name
                    and vol['type'] == self._volume_type['10']):
                tgt_exist = True
            if src_exist and tgt_exist:
                break
        if not src_exist:
            return self._json_return(
                msg=self._error['source_volume_not_exist'][1],
                key=self._error['source_volume_not_exist'][0])
        elif not tgt_exist:
            return self._json_return(
                msg=self._error['target_volume_not_exist'][1],
                key=self._error['target_volume_not_exist'][0])
        src_size = int(self._volumes_list[src_name]['size_gb'])
        tgt_size = int(self._volumes_list[tgt_name]['size_gb'])
        if src_size > tgt_size:
            return self._json_return(
                msg=self._error['source_size_larger_target'][1],
                key=self._error['source_size_larger_target'][0])
        tgt_volume = self._volumes_list[tgt_name]
        self._volumes_list[src_name]['has_clone'] = 1
        self._volumes_list[src_name]['clone'] = tgt_volume['name']
        return self._json_return()

    def _sim_start_clone(self, **kwargs):
        vol_name = kwargs['volume']
        snapshot = kwargs['snapshot']
        if len(snapshot) > 0:
            snap_found = False
            for snap in self._snapshots_list:
                if snap['name'] == snapshot:
                    snap_found = True
                    break
            if not snap_found:
                return self._json_return(
                    msg=self._error['snap_not_exist'][1],
                    key=self._error['snap_not_exist'][0])
        else:
            snapshot = ('clone-' + str(random.randint(100, 999)))
            tmp_snap = {'volume': vol_name,
                        'snapshot': snapshot}
            self._sim_create_snapshot(**tmp_snap)
        self._volumes_list[vol_name]['status'] = 'Queued'
        self._volumes_list[vol_name]['clone_snap'] = snapshot
        greenthread.spawn_n(self._clone_thread, vol_name)
        return self._json_return()

    def _sim_delete_clone(self, **kwargs):
        vol_name = kwargs['volume']
        snapshot = kwargs['snapshot']
        if vol_name not in self._volumes_list:
            return self._json_return(
                msg=self._error['volume_not_exist'][1],
                key=self._error['volume_not_exist'][0])
        self._volumes_list[vol_name]['has_clone'] = 0
        clone_volume = self._volumes_list[vol_name]['clone']
        self._volumes_list[vol_name]['clone'] = 'N/A'
        clone_snap = self._volumes_list[vol_name]['clone_snap']
        self._volumes_list[vol_name]['clone_snap'] = 'N/A'
        self._volumes_list[clone_volume]['type'] = self._volume_type['0']
        if len(snapshot) == 0:
            for snap in self._snapshots_list:
                if clone_snap == snap['name']:
                    self._snapshots_list.remove(snap)
                    break
        return self._json_return()

    def _sim_create_lun_map(self, **kwargs):
        volume_name = kwargs.get('volume', None)
        protocol = kwargs.get('protocol', None)
        hosts = kwargs.get('host', None)
        if volume_name is None or protocol is None or hosts is None:
            return self._json_return(
                msg=self._error['unknown'][1],
                key=self._error['unknown'][0])
        if volume_name not in self._volumes_list:
            return self._json_return(
                msg=self._error['volume_not_exist'][1],
                key=self._error['volume_not_exist'][0])
        if isinstance(hosts, str):
            if hosts == '':
                return self._json_return(
                    msg=self._error['host_empty'][1],
                    key=self._error['host_empty'][0])
            hosts = [hosts]
        volume = self._volumes_list[volume_name]
        available_luns = LUN_NUMS_AVAILABLE
        existed_lun = -1
        for lun_row in self._lun_maps_list:
            if lun_row['vd_id'] == volume['id']:
                if lun_row['host'] in hosts:
                    existed_lun = lun_row['lun']
                    hosts = [h for h in hosts if h != lun_row['host']]
            else:
                if lun_row['protocol'] == protocol:
                    available_luns = [lun for lun in available_luns
                                      if lun != lun_row['lun']]
        if hosts and existed_lun > -1:
            return self._json_return({'lun': existed_lun})
        lun_info = {}
        lun_info['vd_id'] = volume['id']
        lun_info['vd_name'] = volume['name']
        lun_info['protocol'] = protocol
        if existed_lun > -1:
            lun_info['lun'] = existed_lun
        elif available_luns:
            lun_info['lun'] = available_luns[0]
        else:
            return self._json_return(
                msg=self._error['not_available_lun'][1],
                key=self._error['not_available_lun'][0])
        for host in hosts:
            lun_info['id'] = self._create_id(self._lun_maps_list)
            lun_info['host'] = host
            self._lun_maps_list.append(copy.deepcopy(lun_info))
        ret = {}
        if protocol == 'FC':
            ret = {'lun': lun_info['lun']}
        elif protocol == 'iSCSI':
            ret = {'lun': [],
                   'iscsi_name': [],
                   'portal': []}
            for iscsi in self._iscsi_list:
                if iscsi['link'] == 'Down':
                    continue
                ret['lun'].append(lun_info['lun'])
                ret['portal'].append('%s:3260' % iscsi['ip'])
                for control in self._controllers_list:
                    if iscsi['ctrl_idx'] == int(control['id']):
                        ret['iscsi_name'].append(control['iscsi_name'])
                        break
        return self._json_return(ret)

    def _sim_delete_lun_map(self, **kwargs):
        map_exist = False
        volume_name = kwargs['volume']
        protocol = kwargs['protocol']
        hosts = kwargs['host']
        all_host = False
        if hosts == '-1':
            all_host = True
        elif isinstance(hosts, str):
            hosts = [hosts]
        if volume_name not in self._volumes_list:
            return self._json_return(
                msg=self._error['volume_not_exist'][1],
                key=self._error['volume_not_exist'][0])
        volume = self._volumes_list[volume_name]
        lun_maps_list = self._lun_maps_list
        self._lun_maps_list = []
        for row in lun_maps_list:
            if (row['vd_id'] == volume['id']
                    and row['protocol'] == protocol
                    and (all_host or row['host'] in hosts)):
                map_exist = True
            else:
                map_exist = False
                self._lun_maps_list.append(row)
        if not map_exist:
            return self._json_return(
                msg=self._error['lun_not_exist'][1],
                key=self._error['lun_not_exist'][0])
        else:
            return self._json_return()

    def _sim_create_snapshot(self, **kwargs):
        volume_name = kwargs['volume']
        snapshot_name = kwargs['snapshot']
        if volume_name not in self._volumes_list:
            return self._json_return(
                msg=self._error['volume_not_exist'][1],
                key=self._error['volume_not_exist'][0])
        if len(self._snapshots_list) >= SNAPSHOTS_ON_SYSTEM:
            return self._json_return(
                msg=self._error['snap_over_system'][1],
                key=self._error['snap_over_system'][0])
        tag = -1
        volume_snap_count = 0
        for snap in self._snapshots_list:
            if snap['vd_name'] == volume_name:
                volume_snap_count += 1
                if int(snap['tag']) > tag:
                    tag = int(snap['tag'])
            if snap['name'] == snapshot_name:
                return self._json_return(
                    msg=self._error['snap_name_existed'][1],
                    key=self._error['snap_name_existed'][0])
        if volume_snap_count >= SNAPSHOTS_A_VOLUME:
            return self._json_return(
                msg=self._error['snap_over_volume'][1],
                key=self._error['snap_over_volume'][0])
        volume = self._volumes_list[volume_name]
        snapshot = {}
        snapshot['id'] = self._create_id(self._snapshots_list)
        snapshot['name'] = snapshot_name
        snapshot['vd_id'] = volume['id']
        snapshot['vd_name'] = volume['name']
        snapshot['tag'] = tag + 1
        snapshot['create_time'] = ''
        self._snapshots_list.append(snapshot)
        return self._json_return()

    def _sim_delete_snapshot(self, **kwargs):
        volume_name = kwargs['volume']
        snapshot_name = kwargs['snapshot']
        if volume_name not in self._volumes_list:
            return self._json_return(
                msg=self._error['volume_not_exist'][1],
                key=self._error['volume_not_exist'][0])
        snap_exist = False
        for snap in self._snapshots_list:
            if (snap['vd_name'] == volume_name
                    and snap['name'] == snapshot_name):
                snap_exist = True
                self._snapshots_list.remove(snap)
                break
        if not snap_exist:
            return self._json_return(
                msg=self._error['snap_not_exist'][1],
                key=self._error['snap_not_exist'][0])
        return self._json_return()

    def _sim_rollback_snapshot(self, **kwargs):
        volume_name = kwargs['volume']
        snapshot_name = kwargs['snapshot']
        if volume_name and volume_name not in self._volumes_list:
            return self._json_return(
                msg=self._error['volume_not_exist'][1],
                key=self._error['volume_not_exist'][0])
        snapshot = []
        for snap in self._snapshots_list:
            if snap['name'] == snapshot_name:
                snapshot = snap
                break
        if not snapshot:
            return self._json_return(
                msg=self._error['snap_not_exist'][1],
                key=self._error['snap_not_exist'][0])
        if volume_name and volume_name != snapshot['vd_name']:
            return self._json_return(
                msg=self._error['snapshot_not_belong_volume'][1],
                key=self._error['snapshot_not_belong_volume'][0])
        elif not volume_name:
            volume_name = snapshot['vd_name']
        for snap in self._snapshots_list:
            if (snap['vd_name'] == volume_name
                    and snapshot_name != snap['name']
                    and snap['tag'] > snapshot['tag']):
                return self._json_return(
                    msg=self._error['snap_not_latest'][1],
                    key=self._error['snap_not_latest'][0])
        return self._json_return()

    def _sim_set_volume_property(self, **kwargs):
        volume_name = kwargs['volume']
        kwargs.pop('volume')
        if len(kwargs) == 0:
            raise exception.InvalidInput(
                reason=self._error['unknown'][1])
        new_name = volume_name
        if 'new_name' in kwargs:
            new_name = kwargs['new_name']
            kwargs.pop('new_name')
        if volume_name not in self._volumes_list:
            return self._json_return(
                msg=self._error['volume_not_exist'][1],
                key=self._error['volume_not_exist'][0])
        volume = self._volumes_list[volume_name]
        volume['name'] = new_name
        for k, v in kwargs.items():
            if k in volume:
                volume[k] = v
            else:
                return ('', self._error['unknown'][1])

        if volume_name != new_name:
            del self._volumes_list[volume_name]
            self._volumes_list[new_name] = volume
        else:
            self._volumes_list[volume_name] = volume
        return self._json_return()

    def _sim_error_ssh(self, **kwargs):
        error = kwargs['error']
        if error == 'json_error':
            return ('This text is used for json errors.', '')
        elif error == 'dict_error':
            return (json.dumps('This text is used for dict errors.'), '')
        elif error == 'keys_error':
            keys = {'msg': 'This text is used for keys errors'}
            return (json.dumps(keys), '')
        elif error == 'key_false':
            keys = {'msg': 'This text is used for key non-0 error',
                    'key': 1,
                    'arr': {}}
            return (json.dumps(keys), '')


class Acs5000ISCSIFakeDriver(acs5000_iscsi.Acs5000ISCSIDriver):
    def __init__(self, *args, **kwargs):
        super(Acs5000ISCSIFakeDriver, self).__init__(*args, **kwargs)

    def set_fake_storage(self, fake):
        self.fake_storage = fake

    def _run_ssh(self, cmd_list, check_exit_code=True):
        cinder_utils.check_ssh_injection(cmd_list)
        ret = self.fake_storage.execute_command(cmd_list, check_exit_code)

        return ret


class Acs5000FCFakeDriver(acs5000_fc.Acs5000FCDriver):
    def __init__(self, *args, **kwargs):
        super(Acs5000FCFakeDriver, self).__init__(*args, **kwargs)

    def set_fake_storage(self, fake):
        self.fake_storage = fake

    def _run_ssh(self, cmd_list, check_exit_code=True):
        cinder_utils.check_ssh_injection(cmd_list)
        ret = self.fake_storage.execute_command(cmd_list, check_exit_code)

        return ret


class Acs5000ISCSIDriverTestCase(test.TestCase):
    @mock.patch.object(time, 'sleep')
    def setUp(self, mock_sleep):
        super(Acs5000ISCSIDriverTestCase, self).setUp()
        self.configuration = mock.Mock(conf.Configuration)
        self.configuration.san_is_local = False
        self.configuration.san_ip = '23.44.56.78'
        self.configuration.san_login = 'cliuser'
        self.configuration.san_password = 'clipassword'
        self.configuration.acs5000_volpool_name = ['pool01']
        self.configuration.acs5000_multiattach = True
        self.iscsi_driver = Acs5000ISCSIFakeDriver(
            configuration=self.configuration)
        initiator = 'test.iqn.%s' % str(random.randint(10000, 99999))
        self._connector = {'ip': '1.234.56.78',
                           'host': 'stack',
                           'wwpns': [],
                           'initiator': initiator}
        self.sim = CommandSimulator(POOLS_NAME)
        self.iscsi_driver.set_fake_storage(self.sim)
        self.ctxt = context.get_admin_context()

        self.db = cinder.db
        self.iscsi_driver.db = self.db
        self.iscsi_driver.get_driver_options()
        self.iscsi_driver.do_setup(None)
        self.iscsi_driver.check_for_setup_error()

    def _create_volume(self, **kwargs):
        prop = {'host': 'stack@ty1#%s' % POOLS_NAME[0],
                'size': 1,
                'volume_type_id': self.vt['id']}
        for p in prop.keys():
            if p not in kwargs:
                kwargs[p] = prop[p]
        vol = testutils.create_volume(self.ctxt, **kwargs)
        self.iscsi_driver.create_volume(vol)
        return vol

    def _delete_volume(self, volume):
        self.iscsi_driver.delete_volume(volume)
        self.db.volume_destroy(self.ctxt, volume['id'])

    def _assert_lun_exists(self, vol_id, exists):
        lun_maps = self.sim._lun_maps_list
        is_lun_defined = False
        luns = []
        volume_name = VOLUME_PRE + vol_id[-12:]
        for lun in lun_maps:
            if volume_name == lun['vd_name']:
                luns.append(lun)
        if len(luns):
            is_lun_defined = True
        self.assertEqual(exists, is_lun_defined)
        return luns

    def test_validate_connector(self):
        conn_neither = {'host': 'host'}
        conn_iscsi = {'host': 'host', 'initiator': 'iqn.123'}
        conn_fc = {'host': 'host', 'wwpns': 'fff123'}
        conn_both = {'host': 'host', 'initiator': 'iqn.123', 'wwpns': 'fff123'}

        self.iscsi_driver._state['enabled_protocols'] = set(['iSCSI'])
        self.iscsi_driver.validate_connector(conn_iscsi)
        self.iscsi_driver.validate_connector(conn_both)
        self.assertRaises(exception.InvalidConnectorException,
                          self.iscsi_driver.validate_connector, conn_fc)
        self.assertRaises(exception.InvalidConnectorException,
                          self.iscsi_driver.validate_connector, conn_neither)

    def test_initialize_connection(self):
        volume = self._create_volume()
        result = self.iscsi_driver.initialize_connection(volume,
                                                         self._connector)
        ip_connect = self.sim._iscsi_list
        ip_count = 0
        for iscsi in ip_connect:
            if iscsi['link'] != 'Down':
                ip_count += 1
        self.assertEqual('iscsi', result['driver_volume_type'])
        self.assertEqual(ip_count,
                         len(result['data']['target_iqns']))
        self.assertEqual(ip_count,
                         len(result['data']['target_portals']))
        self.assertEqual(volume['id'], result['data']['volume_id'])
        self.assertEqual(ip_count,
                         len(result['data']['target_portals']))
        self._delete_volume(volume)

    def test_initialize_connection_not_found(self):
        prop = {'host': 'stack@ty1#%s' % POOLS_NAME[0],
                'size': 1,
                'volume_type_id': self.vt['id']}
        vol = testutils.create_volume(self.ctxt, **prop)
        self.assertRaises(exception.VolumeNotFound,
                          self.iscsi_driver.initialize_connection,
                          vol, self._connector)
        self.db.volume_destroy(self.ctxt, vol['id'])

    def test_initialize_connection_available_lun(self):
        volume_list = []
        for i in LUN_NUMS_AVAILABLE:
            vol = self._create_volume()
            self.iscsi_driver.initialize_connection(
                vol, self._connector)
            volume_list.append(vol)

        vol = self._create_volume()
        self.assertRaises(exception.ISCSITargetAttachFailed,
                          self.iscsi_driver.initialize_connection,
                          vol, self._connector)
        self._delete_volume(vol)
        for v in volume_list:
            self.iscsi_driver.terminate_connection(
                v, self._connector)
            self._delete_volume(v)

    def test_initialize_connection_exception(self):
        vol = self._create_volume()
        connector = self._connector
        connector['initiator'] = ''
        self.assertRaises(exception.VolumeBackendAPIException,
                          self.iscsi_driver.initialize_connection,
                          vol, connector)
        self._delete_volume(vol)

    def test_initialize_connection_multi_host(self):
        connector = self._connector
        initiator1 = ('test.iqn.%s'
                      % str(random.randint(10000, 99999)))
        initiator2 = ('test.iqn.%s'
                      % str(random.randint(10000, 99999)))
        connector['initiator'] = [initiator1, initiator2]
        volume = self._create_volume()
        self.iscsi_driver.initialize_connection(
            volume, connector)
        lun_maps = self._assert_lun_exists(volume['id'], True)
        hosts = []
        for lun in lun_maps:
            hosts.append(lun['host'])
        self.assertIn(initiator1, hosts)
        self.assertIn(initiator2, hosts)
        self.iscsi_driver.terminate_connection(
            volume, connector)
        self._assert_lun_exists(volume['id'], False)
        self._delete_volume(volume)

    def test_initialize_connection_protocol(self):
        volume = self._create_volume()
        protocol = self.iscsi_driver.protocol
        self.iscsi_driver.protocol = 'error_protocol'
        self.assertRaises(exception.VolumeBackendAPIException,
                          self.iscsi_driver.initialize_connection,
                          volume, self._connector)
        self.iscsi_driver.protocol = protocol
        self._delete_volume(volume)

    def test_terminate_connection(self):
        volume = self._create_volume()
        self.iscsi_driver.initialize_connection(volume,
                                                self._connector)
        self.iscsi_driver.terminate_connection(volume,
                                               self._connector)
        self._assert_lun_exists(volume['id'], False)
        self._delete_volume(volume)

    def test_terminate_connection_multi_attached(self):
        vol = self._create_volume()
        connector = self._connector
        connector['uuid'] = fake.UUID1
        self.iscsi_driver.initialize_connection(vol, connector)
        self._assert_lun_exists(vol.id, True)
        attachment1 = volume_attachment.VolumeAttachment()
        attachment2 = volume_attachment.VolumeAttachment()
        attachment1.connector = connector
        attachment2.connector = connector
        vol.volume_attachment.objects.append(attachment1)
        vol.volume_attachment.objects.append(attachment2)
        self.iscsi_driver.terminate_connection(vol, connector)
        self._assert_lun_exists(vol.id, True)
        vol.volume_attachment.objects = [attachment1]
        self.iscsi_driver.terminate_connection(vol, connector)
        self._assert_lun_exists(vol.id, False)
        self.iscsi_driver.initialize_connection(vol, connector)
        self._assert_lun_exists(vol.id, True)
        self.iscsi_driver.terminate_connection(vol, None)
        self._assert_lun_exists(vol.id, False)
        self._delete_volume(vol)


class Acs5000FCDriverTestCase(test.TestCase):
    @mock.patch.object(time, 'sleep')
    def setUp(self, mock_sleep):
        super(Acs5000FCDriverTestCase, self).setUp()
        self.configuration = mock.Mock(conf.Configuration)
        self.configuration.san_is_local = False
        self.configuration.san_ip = '23.44.56.78'
        self.configuration.san_login = 'cliuser'
        self.configuration.san_password = 'clipassword'
        self.configuration.acs5000_volpool_name = ['pool01']
        self.configuration.acs5000_multiattach = True
        self.fc_driver = Acs5000FCFakeDriver(
            configuration=self.configuration)
        wwpns = [
            str(random.randint(0, 9999999999999999)).zfill(16),
            str(random.randint(0, 9999999999999999)).zfill(16)]
        initiator = 'test.iqn.%s' % str(random.randint(10000, 99999))
        self._connector = {'ip': '1.234.56.78',
                           'host': 'stack',
                           'wwpns': wwpns,
                           'initiator': initiator}
        self.sim = CommandSimulator(POOLS_NAME)
        self.fc_driver.set_fake_storage(self.sim)
        self.ctxt = context.get_admin_context()

        self.db = cinder.db
        self.fc_driver.db = self.db
        self.fc_driver.get_driver_options()
        self.fc_driver.do_setup(None)
        self.fc_driver.check_for_setup_error()

    def _create_volume(self, **kwargs):
        prop = {'host': 'stack@ty1#%s' % POOLS_NAME[0],
                'size': 1,
                'volume_type_id': self.vt['id']}
        for p in prop.keys():
            if p not in kwargs:
                kwargs[p] = prop[p]
        vol = testutils.create_volume(self.ctxt, **kwargs)
        self.fc_driver.create_volume(vol)
        return vol

    def _delete_volume(self, volume):
        self.fc_driver.delete_volume(volume)
        self.db.volume_destroy(self.ctxt, volume['id'])

    def _assert_lun_exists(self, vol_id, exists):
        lun_maps = self.sim._lun_maps_list
        is_lun_defined = False
        luns = []
        volume_name = VOLUME_PRE + vol_id[-12:]
        for lun in lun_maps:
            if volume_name == lun['vd_name']:
                luns.append(lun)
        if len(luns):
            is_lun_defined = True
        self.assertEqual(exists, is_lun_defined)
        return luns

    def test_validate_connector(self):
        conn_neither = {'host': 'host'}
        conn_iscsi = {'host': 'host', 'initiator': 'iqn.123'}
        conn_fc = {'host': 'host', 'wwpns': 'fff123'}
        conn_both = {'host': 'host', 'initiator': 'iqn.123', 'wwpns': 'fff123'}

        self.fc_driver.validate_connector(conn_fc)
        self.fc_driver.validate_connector(conn_both)
        self.assertRaises(exception.InvalidConnectorException,
                          self.fc_driver.validate_connector, conn_iscsi)
        self.assertRaises(exception.InvalidConnectorException,
                          self.fc_driver.validate_connector, conn_neither)

    def test_initialize_connection(self):
        volume = self._create_volume()
        result = self.fc_driver.initialize_connection(volume,
                                                      self._connector)
        fc_list = self.sim._fc_list
        up_wwpns = []
        for port in fc_list:
            if port['link'] == 'Up':
                if 'WWPN' in port:
                    up_wwpns.append(port['WWPN'])
                elif 'wwpn' in port:
                    up_wwpns.append(port['wwpn'])
        self.assertEqual('fibre_channel', result['driver_volume_type'])
        self.assertEqual(up_wwpns.sort(), result['data']['target_wwn'].sort())
        self.assertEqual(volume['id'], result['data']['volume_id'])
        self.assertIsNotNone(result['data']['target_lun'])
        self._delete_volume(volume)

    def test_initialize_connection_not_found(self):
        prop = {'host': 'stack@ty1#%s' % POOLS_NAME[0],
                'size': 1,
                'volume_type_id': self.vt['id']}
        vol = testutils.create_volume(self.ctxt, **prop)
        self.assertRaises(exception.VolumeNotFound,
                          self.fc_driver.initialize_connection,
                          vol, self._connector)
        self.db.volume_destroy(self.ctxt, vol['id'])

    def test_initialize_connection_failure(self):
        volume_list = []
        for i in LUN_NUMS_AVAILABLE:
            vol = self._create_volume()
            self.fc_driver.initialize_connection(
                vol, self._connector)
            volume_list.append(vol)

        vol = self._create_volume()
        self.assertRaises(exception.VolumeBackendAPIException,
                          self.fc_driver.initialize_connection,
                          vol, self._connector)
        self._delete_volume(vol)
        for v in volume_list:
            self.fc_driver.terminate_connection(
                v, self._connector)
            self._delete_volume(v)

    def test_initialize_connection_exception(self):
        vol = self._create_volume()
        connector = self._connector
        self.fc_driver.protocol = 'error_protocol'
        self.assertRaises(exception.VolumeBackendAPIException,
                          self.fc_driver.initialize_connection,
                          vol, connector)
        self.fc_driver.protocol = acs5000_fc.Acs5000FCDriver.PROTOCOL
        fc_list = self.sim._fc_list
        self.sim._fc_list = []
        self.assertRaises(exception.VolumeBackendAPIException,
                          self.fc_driver.initialize_connection,
                          vol, connector)
        # _check_multi_attached then delete_lun_map
        connector['uuid'] = fake.UUID1
        attachment1 = volume_attachment.VolumeAttachment()
        attachment2 = volume_attachment.VolumeAttachment()
        attachment1.connector = connector
        attachment2.connector = connector
        vol.volume_attachment.objects.append(attachment1)
        vol.volume_attachment.objects.append(attachment2)
        self.assertRaises(exception.VolumeBackendAPIException,
                          self.fc_driver.initialize_connection,
                          vol, connector)
        self.sim._fc_list = fc_list
        self._delete_volume(vol)

    def test_terminate_connection(self):
        volume = self._create_volume()
        self.fc_driver.initialize_connection(volume,
                                             self._connector)
        self.fc_driver.terminate_connection(volume,
                                            self._connector)
        self._assert_lun_exists(volume['id'], False)
        self._delete_volume(volume)

    def test_terminate_connection_warn(self):
        volume = self._create_volume()
        connector = self._connector
        connector['uuid'] = fake.UUID1
        self.fc_driver.initialize_connection(volume, connector)
        self.fc_driver.terminate_connection(volume, None)
        self._assert_lun_exists(volume.id, False)
        self.fc_driver.initialize_connection(volume, connector)
        attachment1 = volume_attachment.VolumeAttachment()
        attachment2 = volume_attachment.VolumeAttachment()
        attachment1.connector = connector
        attachment2.connector = connector
        volume.volume_attachment.objects.append(attachment1)
        volume.volume_attachment.objects.append(attachment2)
        self.fc_driver.terminate_connection(volume, connector)
        self._assert_lun_exists(volume.id, True)
        fc_list = self.sim._fc_list
        self.sim._fc_list = []
        volume.volume_attachment.objects = [attachment1]
        self.fc_driver.terminate_connection(volume, connector)
        self.sim._fc_list = fc_list
        self._assert_lun_exists(volume.id, False)
        self._delete_volume(volume)


class Acs5000CommonDriverTestCase(test.TestCase):
    @mock.patch.object(time, 'sleep')
    def setUp(self, mock_sleep):
        super(Acs5000CommonDriverTestCase, self).setUp()

        self.configuration = mock.Mock(conf.Configuration)
        self.configuration.san_is_local = False
        self.configuration.san_ip = '23.44.56.78'
        self.configuration.san_ssh_port = '22'
        self.configuration.san_login = 'cliuser'
        self.configuration.san_password = 'clipassword'
        self.configuration.acs5000_volpool_name = POOLS_NAME
        self.configuration.acs5000_copy_interval = 0.01
        self.configuration.acs5000_multiattach = True
        self.configuration.reserved_percentage = 0
        options = acs5000_iscsi.Acs5000ISCSIDriver.get_driver_options()
        config = conf.Configuration(options, conf.SHARED_CONF_GROUP)
        self._driver = Acs5000ISCSIFakeDriver(
            configuration=self.configuration)
        self.override_config('san_ip', '23.44.56.78', conf.SHARED_CONF_GROUP)
        self.override_config('san_ssh_port', '22', conf.SHARED_CONF_GROUP)
        self.override_config('san_login', 'cliuser', conf.SHARED_CONF_GROUP)
        self.override_config('san_password', 'clipassword',
                             conf.SHARED_CONF_GROUP)
        self.override_config('acs5000_volpool_name', POOLS_NAME,
                             conf.SHARED_CONF_GROUP)
        self._driver.configuration.safe_get = self._safe_get
        self._iscsi_driver = acs5000_iscsi.Acs5000ISCSIDriver(
            configuration=config)
        initiator = 'test.iqn.%s' % str(random.randint(10000, 99999))
        self._connector = {'ip': '1.234.56.78',
                           'host': 'stack',
                           'wwpns': [],
                           'initiator': initiator}
        self.sim = CommandSimulator(POOLS_NAME)
        self._driver.set_fake_storage(self.sim)
        self.ctxt = context.get_admin_context()

        self.db = cinder.db
        self._driver.db = self.db
        self._driver.do_setup(None)
        self._driver.check_for_setup_error()

    def _safe_get(self, key):
        try:
            return getattr(self._driver.configuration, key)
        except AttributeError:
            return None

    def _assert_vol_exists(self, name, exists):
        volume = self._driver._cmd.get_volume(VOLUME_PRE + name[-12:])
        is_vol_defined = False
        if volume:
            is_vol_defined = True
        self.assertEqual(exists, is_vol_defined)
        return volume

    def _assert_snap_exists(self, name, exists):
        snap_name = VOLUME_PRE + name[-12:]
        snapshot_list = self.sim._snapshots_list
        is_snap_defined = False
        snapshot = {}
        for snap in snapshot_list:
            if snap['name'] == snap_name:
                is_snap_defined = True
                snapshot = snap
                break
        self.assertEqual(exists, is_snap_defined)
        return snapshot

    def _create_volume(self, **kwargs):
        prop = {'host': 'stack@ty1#%s' % POOLS_NAME[0],
                'size': 1,
                'volume_type_id': self.vt['id']}
        driver = True
        if 'driver' in kwargs:
            if not kwargs['driver']:
                driver = False
            kwargs.pop('driver')
        for p in prop.keys():
            if p not in kwargs:
                kwargs[p] = prop[p]
        vol = testutils.create_volume(self.ctxt, **kwargs)
        if driver:
            self._driver.create_volume(vol)
        return vol

    def _delete_volume(self, volume, driver=True):
        if driver:
            self._driver.delete_volume(volume)
        self.db.volume_destroy(self.ctxt, volume['id'])

    def _create_snapshot(self, vol_id, driver=True):
        snap = testutils.create_snapshot(self.ctxt, vol_id)
        if driver:
            self._driver.create_snapshot(snap)
        return snap

    def _delete_snapshot(self, snap, driver=True):
        if driver:
            self._driver.delete_snapshot(snap)
        self.db.snapshot_destroy(self.ctxt, snap['id'])

    def test_run_ssh_failure(self):
        self.assertRaises(exception.VolumeBackendAPIException,
                          self._driver._build_pool_stats,
                          'error_pool')
        ssh_cmd = ['error_ssh', '--error', 'json_error']
        self.assertRaises(exception.VolumeBackendAPIException,
                          self._driver._cmd.run_ssh_info, ssh_cmd)
        ssh_cmd = ['error_ssh', '--error', 'dict_error']
        self.assertRaises(exception.VolumeBackendAPIException,
                          self._driver._cmd.run_ssh_info, ssh_cmd)
        ssh_cmd = ['error_ssh', '--error', 'keys_error']
        self.assertRaises(exception.VolumeBackendAPIException,
                          self._driver._cmd.run_ssh_info, ssh_cmd)
        ssh_cmd = ['error_ssh', '--error', 'key_false']
        self.assertRaises(exception.VolumeBackendAPIException,
                          self._driver._cmd.run_ssh_info, ssh_cmd)

    @mock.patch.object(ssh_utils, 'SSHPool')
    @mock.patch.object(processutils, 'ssh_execute')
    def test_run_ssh_with_ip(self, mock_ssh_execute, mock_ssh_pool):
        ssh_cmd = ['run_ssh']
        self._iscsi_driver._run_ssh(ssh_cmd)
        mock_ssh_pool.assert_called_once_with(
            self._iscsi_driver.configuration.san_ip,
            self._iscsi_driver.configuration.san_ssh_port,
            self._iscsi_driver.configuration.ssh_conn_timeout,
            self._iscsi_driver.configuration.san_login,
            password=self._iscsi_driver.configuration.san_password,
            min_size=self._iscsi_driver.configuration.ssh_min_pool_conn,
            max_size=self._iscsi_driver.configuration.ssh_max_pool_conn)

        mock_ssh_pool.side_effect = [paramiko.SSHException, mock.MagicMock()]
        self._iscsi_driver._run_ssh(ssh_cmd)
        mock_ssh_pool.assert_called_once_with(
            self._iscsi_driver.configuration.san_ip,
            self._iscsi_driver.configuration.san_ssh_port,
            self._iscsi_driver.configuration.ssh_conn_timeout,
            self._iscsi_driver.configuration.san_login,
            password=self._iscsi_driver.configuration.san_password,
            min_size=self._iscsi_driver.configuration.ssh_min_pool_conn,
            max_size=self._iscsi_driver.configuration.ssh_max_pool_conn)

    @mock.patch.object(ssh_utils, 'SSHPool')
    @mock.patch.object(processutils, 'ssh_execute')
    def test_run_ssh_with_exception(self, mock_ssh_execute, mock_ssh_pool):
        mock_ssh_execute.side_effect = [processutils.ProcessExecutionError,
                                        mock.MagicMock()]
        self.override_config('acs5000_volpool_name', None,
                             self._iscsi_driver.configuration.config_group)
        ssh_cmd = ['run_ssh']
        self.assertRaises(processutils.ProcessExecutionError,
                          self._iscsi_driver._run_ssh, ssh_cmd)

    def test_do_setup(self):
        system_info = self.sim._system_info
        self.assertEqual(system_info['vendor'], self._driver._state['vendor'])
        self.assertIn('iSCSI', self._driver._state['enabled_protocols'])
        self.assertEqual(2, len(self._driver._state['controller']))
        iscsi_list = self.sim._iscsi_list
        self.sim._iscsi_list = []
        self._driver._state['enabled_protocols'] = set()
        self._driver.do_setup(None)
        self.assertEqual(set(), self._driver._state['enabled_protocols'])
        self.sim._iscsi_list = iscsi_list
        self._driver.do_setup(None)
        self.assertEqual({'iSCSI'}, self._driver._state['enabled_protocols'])

    def test_do_setup_no_pools(self):
        self._driver.pools = ['pool_error']
        self.assertRaises(exception.InvalidInput,
                          self._driver.do_setup, None)

    def test_create_volume(self):
        vol = self._create_volume()
        self._assert_vol_exists(vol['id'], True)
        self._delete_volume(vol)

    def test_create_volume_same_name(self):
        vol = self._create_volume()
        self._assert_vol_exists(vol['id'], True)
        self.assertRaises(exception.VolumeBackendAPIException,
                          self._driver.create_volume, vol)
        self._delete_volume(vol)

    def test_create_volume_size_exceeds_limit(self):
        prop = {
            'host': 'stack@ty2#%s' % POOLS_NAME[1],
            'size': 200,
            'driver': False
        }
        self._driver.get_volume_stats()
        vol = self._create_volume(**prop)
        self._assert_vol_exists(vol['id'], False)
        self.assertRaises(exception.VolumeSizeExceedsLimit,
                          self._driver.create_volume,
                          vol)
        self._delete_volume(vol, False)

    def test_create_volume_number_exceeds_pool_limit(self):
        volume_list = []
        for i in range(VOLUME_LIMIT_ON_POOL):
            vol = self._create_volume()
            self._assert_vol_exists(vol['id'], True)
            volume_list.append(vol)
        vol = self._create_volume(driver=False)
        self.assertRaises(exception.VolumeLimitExceeded,
                          self._driver.create_volume,
                          vol)
        self._delete_volume(vol, False)
        for v in volume_list:
            self._delete_volume(v)

    def test_create_volume_number_exceeds_system_limit(self):
        volume_list = []
        volume_count_on_pool = int(VOLUME_LIMIT_ON_SYSTEM
                                   / len(POOLS_NAME))
        for i in range(volume_count_on_pool):
            for x in range(len(POOLS_NAME)):
                vol = self._create_volume(
                    host='stack@ty1#%s' % POOLS_NAME[x])
                self._assert_vol_exists(vol['id'], True)
                volume_list.append(vol)
        vol = self._create_volume(driver=False)
        self.assertRaises(exception.VolumeLimitExceeded,
                          self._driver.create_volume,
                          vol)
        self._delete_volume(vol, False)
        for v in volume_list:
            self._delete_volume(v)

    def test_create_volume_pool_not_existed(self):
        prop = {
            'host': 'stack@ty2#no_pool',
            'driver': False
        }
        self._driver.get_volume_stats()
        vol = self._create_volume(**prop)
        self._assert_vol_exists(vol['id'], False)
        self.assertRaises(exception.VolumeBackendAPIException,
                          self._driver.create_volume,
                          vol)
        self._delete_volume(vol, False)

    def test_delete_volume(self):
        vol = self._create_volume()
        self._assert_vol_exists(vol['id'], True)
        self._delete_volume(vol)
        self._assert_vol_exists(vol['id'], False)

    def test_create_snapshot(self):
        vol = self._create_volume()
        self._assert_vol_exists(vol['id'], True)
        snap = self._create_snapshot(vol['id'])
        self._assert_snap_exists(snap['id'], True)
        self._delete_snapshot(snap)
        self._delete_volume(vol)

    def test_create_snapshot_exceed_limit(self):
        vol = self._create_volume()
        self._assert_vol_exists(vol['id'], True)
        snapshot_list = []
        for i in range(SNAPSHOTS_A_VOLUME):
            snap = self._create_snapshot(vol['id'])
            self._assert_snap_exists(snap['id'], True)
            snapshot_list.append(snap)
        snap = self._create_snapshot(vol['id'], False)
        self.assertRaises(exception.SnapshotLimitExceeded,
                          self._driver.create_snapshot, snap)
        self._delete_snapshot(snap, False)
        vol_list = [vol]
        snap_count = SNAPSHOTS_A_VOLUME
        while snap_count < SNAPSHOTS_ON_SYSTEM:
            vol = self._create_volume()
            vol_list.append(vol)
            for x in range(SNAPSHOTS_A_VOLUME):
                snap = self._create_snapshot(vol['id'])
                self._assert_snap_exists(snap['id'], True)
                snapshot_list.append(snap)
                snap_count += 1
                if snap_count >= SNAPSHOTS_ON_SYSTEM:
                    break

        vol = self._create_volume()
        vol_list.append(vol)
        snap = self._create_snapshot(vol['id'], False)
        self.assertRaises(exception.SnapshotLimitExceeded,
                          self._driver.create_snapshot, snap)
        for sp in snapshot_list:
            self._delete_snapshot(sp)
        for vol in vol_list:
            self._delete_volume(vol)

    def test_create_snapshot_name_existed(self):
        vol = self._create_volume()
        snap = self._create_snapshot(vol['id'])
        self._assert_vol_exists(vol['id'], True)
        self._assert_snap_exists(snap['id'], True)
        self.assertRaises(exception.VolumeBackendAPIException,
                          self._driver.create_snapshot, snap)
        self._delete_snapshot(snap)
        self._delete_volume(vol)

    def test_delete_snapshot(self):
        vol = self._create_volume()
        self._assert_vol_exists(vol['id'], True)
        snap = self._create_snapshot(vol['id'])
        self._assert_snap_exists(snap['id'], True)
        self._delete_snapshot(snap)
        self._assert_snap_exists(snap['id'], False)
        self._delete_volume(vol)

    def test_delete_snapshot_not_found(self):
        vol = self._create_volume()
        self._assert_vol_exists(vol['id'], True)
        snap = self._create_snapshot(vol['id'], False)
        self._assert_snap_exists(snap['id'], False)
        self.assertRaises(exception.SnapshotNotFound,
                          self._driver.delete_snapshot,
                          snap)
        self._delete_snapshot(snap, False)
        self._delete_volume(vol)

    def test_delete_snapshot_volume_not_found(self):
        vol = self._create_volume()
        snap = self._create_snapshot(vol['id'])
        self._delete_volume(vol)
        self._assert_vol_exists(vol['id'], False)
        self._assert_snap_exists(snap['id'], True)
        self.assertRaises(exception.VolumeBackendAPIException,
                          self._driver.delete_snapshot, snap)
        self._driver.create_volume(vol)
        self._delete_snapshot(snap)
        self._driver.delete_volume(vol)

    def test_create_volume_from_snapshot(self):
        prop = {'size': 2}
        vol = self._create_volume(**prop)
        self._assert_vol_exists(vol['id'], True)
        snap = self._create_snapshot(vol['id'])
        self._assert_snap_exists(snap['id'], True)
        prop['driver'] = False
        new_vol = self._create_volume(**prop)
        self._driver.create_volume_from_snapshot(new_vol, snap)
        new_volume = self._assert_vol_exists(new_vol['id'], True)
        self.assertEqual(1, len(new_volume))
        self.assertEqual('2', new_volume[0]['size_gb'])
        self.assertEqual('RAID Volume', new_volume[0]['type'])
        self._delete_volume(new_vol)
        self._delete_snapshot(snap)
        self._delete_volume(vol)

    def test_create_volume_from_snapshot_not_found(self):
        vol = self._create_volume()
        self._assert_vol_exists(vol['id'], True)
        snap = self._create_snapshot(vol['id'], False)
        self._assert_snap_exists(snap['id'], False)
        new_vol = self._create_volume(driver=False)
        self._assert_vol_exists(new_vol['id'], False)
        self.assertRaises(exception.SnapshotNotFound,
                          self._driver.create_volume_from_snapshot,
                          new_vol, snap)
        self._delete_volume(new_vol, False)
        self._delete_snapshot(snap, False)
        self._delete_volume(vol)

    def test_create_snapshot_volume_not_found(self):
        vol = self._create_volume(driver=False)
        self._assert_vol_exists(vol['id'], False)
        self.assertRaises(exception.VolumeNotFound,
                          self._create_snapshot, vol['id'])
        self._delete_volume(vol, driver=False)

    def test_create_cloned_volume(self):
        src_volume = self._create_volume()
        self._assert_vol_exists(src_volume['id'], True)
        tgt_volume = self._create_volume(driver=False)
        self._driver.create_cloned_volume(tgt_volume, src_volume)
        volume = self._assert_vol_exists(tgt_volume['id'], True)
        self.assertEqual(1, len(volume))
        self.assertEqual('RAID Volume', volume[0]['type'])
        self._delete_volume(src_volume)
        self._delete_volume(tgt_volume)

    def test_create_cloned_volume_with_size(self):
        prop = {'size': 2}
        src_volume = self._create_volume(**prop)
        volume = self._assert_vol_exists(src_volume['id'], True)
        prop['driver'] = False
        tgt_volume = self._create_volume(**prop)
        self._driver.create_cloned_volume(tgt_volume, src_volume)
        clone_volume = self._assert_vol_exists(tgt_volume['id'], True)
        self.assertEqual(1, len(volume))
        self.assertEqual(1, len(clone_volume))
        self.assertEqual('RAID Volume', volume[0]['type'])
        self.assertEqual('RAID Volume', clone_volume[0]['type'])
        self.assertEqual('2', volume[0]['size_gb'])
        self.assertEqual('2', clone_volume[0]['size_gb'])
        self._delete_volume(src_volume)
        self._delete_volume(tgt_volume)

    def test_create_cloned_volume_size_failure(self):
        prop = {'size': 10}
        src_volume = self._create_volume(**prop)
        self._assert_vol_exists(src_volume['id'], True)
        prop = {'size': 5, 'driver': False}
        tgt_volume = self._create_volume(**prop)
        self.assertRaises(exception.VolumeBackendAPIException,
                          self._driver.create_cloned_volume,
                          tgt_volume, src_volume)
        self._assert_vol_exists(tgt_volume['id'], False)
        self._delete_volume(src_volume)
        self._delete_volume(tgt_volume, False)

    def test_create_cloned_volume_failure(self):
        self.assertRaises(exception.VolumeBackendAPIException,
                          self._driver._local_clone_copy,
                          None, None)
        self.assertRaises(exception.VolumeBackendAPIException,
                          self._driver._local_clone_copy,
                          'src_test', 'tgt_test')
        src_volume = self._create_volume()
        src_name = VOLUME_PRE + src_volume['id'][-12:]
        self.assertRaises(exception.VolumeBackendAPIException,
                          self._driver._local_clone_copy,
                          src_name, 'tgt_test')
        self._delete_volume(src_volume)

    def test_wait_volume_copy(self):
        src_volume = self._create_volume(size=2)
        src_info = self._assert_vol_exists(src_volume['id'], True)[0]
        tgt_volume = self._create_volume(size=2)
        tgt_info = self._assert_vol_exists(tgt_volume['id'], True)[0]
        self._driver._cmd.set_volume_property(
            src_info['name'], {'status': 'Queued',
                               'clone_snap': tgt_info['name']})
        self._driver._cmd.set_volume_property(tgt_info['name'],
                                              {'type': 'BACKUP'})
        src_name = VOLUME_PRE + src_volume['id'][-12:]
        tgt_name = VOLUME_PRE + tgt_volume['id'][-12:]
        self._driver._cmd.create_clone(src_name, tgt_name)
        tgt_set = {
            tgt_name: [('status', 'Erasing', 0.2)],
            src_name: [('status', 'Erasing', 0.2)],
        }
        greenthread.spawn_n(self.sim._clone_thread,
                            src_name, tgt_set)
        ret = self._driver._wait_volume_copy(src_name, tgt_name,
                                             'test_func', 'test_action')
        self.assertTrue(ret)
        self._driver._cmd.set_volume_property(
            src_info['name'], {'status': 'error',
                               'clone_snap': tgt_info['name']})
        ret = self._driver._wait_volume_copy(src_name, tgt_name,
                                             'test_func', 'test_action')
        self.assertFalse(ret)
        self._driver._cmd.set_volume_property(
            src_info['name'], {'status': 'Online',
                               'clone_snap': tgt_info['name']})
        self._delete_volume(tgt_volume)
        self._assert_vol_exists(tgt_volume['id'], False)
        ret = self._driver._wait_volume_copy(src_name, tgt_name,
                                             'test_func', 'test_action')
        self.assertFalse(ret)
        self._driver._cmd.set_volume_property(src_info['name'],
                                              {'type': 'BACKUP'})
        ret = self._driver._wait_volume_copy(tgt_name, 'backup_test',
                                             'test_func', 'test_action')
        self.assertFalse(ret)
        self._delete_volume(src_volume)

    def test_extend_volume(self):
        volume = self._create_volume(size=10)
        vol_info = self._assert_vol_exists(volume['id'], True)
        self.assertEqual('10', vol_info[0]['size_gb'])
        self._driver.extend_volume(volume, '100')
        extend_vol = self._assert_vol_exists(volume['id'], True)
        self.assertEqual('100', extend_vol[0]['size_gb'])
        self._delete_volume(volume)

    def test_extend_volume_not_found(self):
        volume = self._create_volume(driver=False)
        self.assertRaises(exception.VolumeNotFound,
                          self._driver.extend_volume,
                          volume, 10)
        self._delete_volume(volume, False)

    def test_extend_volume_size_less(self):
        volume = self._create_volume(size=100)
        vol_info = self._assert_vol_exists(volume['id'], True)
        self.assertEqual('100', vol_info[0]['size_gb'])
        self.assertRaises(exception.VolumeBackendAPIException,
                          self._driver.extend_volume,
                          volume, '10')
        self._delete_volume(volume)

    def test_extend_volume_size_exceeds_limit(self):
        host = 'stack@ty2#%s' % POOLS_NAME[1]
        self._driver.get_volume_stats()
        volume = self._create_volume(size=10, host=host)
        vol_info = self._assert_vol_exists(volume['id'], True)
        self.assertEqual('10', vol_info[0]['size_gb'])
        self.assertEqual(POOLS_NAME[1], vol_info[0]['poolname'])
        self.assertRaises(exception.VolumeSizeExceedsLimit,
                          self._driver.extend_volume,
                          volume, '200')
        self._delete_volume(volume)

    def test_extend_volume_size_equal(self):
        volume = self._create_volume(size=10)
        vol_info = self._assert_vol_exists(volume['id'], True)
        self.assertEqual('10', vol_info[0]['size_gb'])
        self.assertRaises(exception.VolumeBackendAPIException,
                          self._driver.extend_volume,
                          volume, '10')
        self._delete_volume(volume)

    def test_migrate_volume_same_pool(self):
        host = 'stack@ty1#%s' % POOLS_NAME[0]
        volume = self._create_volume(host=host)
        target_host = {
            'host': 'stack_new@ty1#%s' % POOLS_NAME[0],
            'capabilities': {
                'system_id': self.sim._system_info['system_id'],
                'pool_name': POOLS_NAME[0]
            }
        }
        ret = self._driver.migrate_volume(self.ctxt, volume, target_host)
        self.assertEqual((True, None), ret)

    def test_migrate_volume_different_system(self):
        host = 'stack@ty1#%s' % POOLS_NAME[0]
        volume = self._create_volume(host=host)
        target_host = {
            'host': 'stack_new@ty1#%s' % POOLS_NAME[0],
            'capabilities': {
                'system_id': 'test_system_id',
                'pool_name': POOLS_NAME[0]
            }
        }
        ret = self._driver.migrate_volume(self.ctxt, volume, target_host)
        self.assertEqual((False, None), ret)
        target_host = {
            'host': 'stack_new@ty1#%s' % POOLS_NAME[0],
            'capabilities': {
                'pool_name': POOLS_NAME[0]
            }
        }
        ret = self._driver.migrate_volume(self.ctxt, volume, target_host)
        self.assertEqual((False, None), ret)

    def test_migrate_volume_same_system_different_pool(self):
        host = 'stack@ty1#%s' % POOLS_NAME[0]
        volume = self._create_volume(host=host, size=2)
        target_host = {
            'host': 'stack_new@ty1#%s' % POOLS_NAME[1],
            'capabilities': {
                'system_id': self.sim._system_info['system_id'],
                'pool_name': POOLS_NAME[1]
            }
        }
        ret = self._driver.migrate_volume(self.ctxt, volume, target_host)
        self.assertEqual((True, None), ret)
        vol_info = self._assert_vol_exists(volume['id'], True)
        self.assertEqual(POOLS_NAME[1], vol_info[0]['poolname'])
        self.assertEqual('2', vol_info[0]['size_gb'])

    def test_get_volume_stats(self):
        self.assertEqual({}, self._driver._stats)
        self._driver.get_volume_stats()
        stats = self._driver._stats
        system_info = self.sim._system_info
        self.assertEqual(system_info['vendor'], stats['vendor_name'])

    def test_get_volume_none(self):
        ret = self._driver._cmd.get_volume('')
        self.assertEqual([], ret)
        ret = self._driver._cmd.get_volume('test_volume')
        self.assertEqual([], ret)
        vol1 = self._create_volume()
        vol2 = self._create_volume()
        vol1_name = VOLUME_PRE + vol1['id'][-12:]
        vol2_name = VOLUME_PRE + vol2['id'][-12:]
        ret = self._driver._cmd.get_volume([vol1_name, vol2_name])
        self.assertEqual(2, len(ret))
        vol_name = []
        for vol in ret:
            vol_name.append(vol['name'])
        self.assertEqual(sorted([vol1_name, vol2_name]), sorted(vol_name))
        ret = self._driver._cmd.get_volume({'test_key': 'test_value'})
        self.assertEqual([], ret)
        self._delete_volume(vol1)
        self._delete_volume(vol2)

    def test_check_for_setup_error_failure(self):
        self._driver._state['system_name'] = None
        self.assertRaises(exception.VolumeBackendAPIException,
                          self._driver.check_for_setup_error)
        self._driver.do_setup(None)
        self._driver._state['system_id'] = None
        self.assertRaises(exception.VolumeBackendAPIException,
                          self._driver.check_for_setup_error)
        self._driver.do_setup(None)
        self._driver._state['controller'] = []
        self.assertRaises(exception.VolumeDriverException,
                          self._driver.check_for_setup_error)
        self._driver.do_setup(None)
        self._driver._state['enabled_protocols'] = set()
        self.assertRaises(exception.InvalidInput,
                          self._driver.check_for_setup_error)
        self._driver.do_setup(None)
        password = self._driver.configuration.san_password
        self._driver.configuration.san_password = None
        self.assertRaises(exception.InvalidInput,
                          self._driver.check_for_setup_error)
        self._driver.configuration.san_password = password
        san_ip = self._driver.configuration.san_ip
        self._driver.configuration.san_ip = None
        self.assertRaises(exception.InvalidInput,
                          self._driver.check_for_setup_error)
        self._driver.configuration.san_ip = san_ip

    def test_build_pool_stats_no_pool(self):
        self.assertRaises(exception.VolumeBackendAPIException,
                          self._driver._build_pool_stats,
                          'pool_test')

    def test_set_volume_property_failure(self):
        volume = self._create_volume()
        self._assert_vol_exists(volume['id'], True)
        volume_name = VOLUME_PRE + volume['id'][-12:]
        self.assertRaises(exception.VolumeBackendAPIException,
                          self._driver._cmd.set_volume_property,
                          volume_name, {'error_key': 'error'})
        self.assertRaises(exception.VolumeBackendAPIException,
                          self._driver._cmd.set_volume_property,
                          volume_name, {})
        self._delete_volume(volume)

    def test_snapshot_revert_use_temp_snapshot(self):
        ret = self._driver.snapshot_revert_use_temp_snapshot()
        self.assertFalse(ret)

    def test_revert_to_snapshot(self):
        volume = self._create_volume()
        snapshot = self._create_snapshot(volume.id)
        self._driver.revert_to_snapshot(self.ctxt, volume, snapshot)
        self._delete_snapshot(snapshot)
        self._delete_volume(volume)

    def test_revert_to_snapshot_volume_not_found(self):
        volume = self._create_volume(driver=False)
        snapshot = self._create_snapshot(volume.id, driver=False)
        self.assertRaises(exception.VolumeNotFound,
                          self._driver.revert_to_snapshot,
                          self.ctxt, volume, snapshot)
        self._delete_snapshot(snapshot, driver=False)
        self._delete_volume(volume, driver=False)

    def test_revert_to_snapshot_snapshot_not_found(self):
        volume = self._create_volume()
        snapshot = self._create_snapshot(volume.id, driver=False)
        self.assertRaises(exception.SnapshotNotFound,
                          self._driver.revert_to_snapshot,
                          self.ctxt, volume, snapshot)
        self._delete_snapshot(snapshot, driver=False)
        self._delete_volume(volume)

    def test_revert_to_snapshot_not_latest_one(self):
        volume = self._create_volume()
        snapshot1 = self._create_snapshot(volume.id)
        snapshot2 = self._create_snapshot(volume.id)
        self.assertRaises(exception.InvalidSnapshot,
                          self._driver.revert_to_snapshot,
                          self.ctxt, volume, snapshot1)
        self._delete_snapshot(snapshot2)
        self._delete_snapshot(snapshot1)
        self._delete_volume(volume)

    def test_revert_to_snapshot_not_belong(self):
        volume1 = self._create_volume()
        volume2 = self._create_volume()
        snapshot = self._create_snapshot(volume2.id)
        self.assertRaises(exception.VolumeBackendAPIException,
                          self._driver.revert_to_snapshot,
                          self.ctxt, volume1, snapshot)
        self._delete_snapshot(snapshot)
        self._delete_volume(volume1)
        self._delete_volume(volume2)

    def test_convert_name(self):
        name = self._driver._convert_name('')
        self.assertEqual(len(acs5000_common.VOLUME_PREFIX) + 12,
                         len(name))
        name = self._driver._convert_name('test_name')
        self.assertEqual(len(acs5000_common.VOLUME_PREFIX) + 12,
                         len(name))
        name = self._driver._convert_name(fake.UUID1)
        self.assertEqual(len(acs5000_common.VOLUME_PREFIX) + 12,
                         len(name))

    def test_check_multi_attached(self):
        connector = self._connector
        volume = self._create_volume(driver=False)
        connector['uuid'] = fake.UUID1
        attachment1 = volume_attachment.VolumeAttachment()
        attachment2 = volume_attachment.VolumeAttachment()
        volume.volume_attachment.objects.append(attachment1)
        volume.volume_attachment.objects.append(attachment2)
        count = self._driver._check_multi_attached(volume, connector)
        self.assertEqual(0, count)
        attachment1.connector = connector
        attachment2.connector = connector
        volume.volume_attachment.objects.append(attachment1)
        volume.volume_attachment.objects.append(attachment2)
        count = self._driver._check_multi_attached(volume, connector)
        self.assertEqual(4, count)
        self._delete_volume(volume, driver=False)

    def test_update_migrated_volume(self):
        old_vol = self._create_volume(driver=False)
        self._assert_vol_exists(old_vol.id, False)
        new_vol = self._create_volume()
        self._assert_vol_exists(new_vol.id, True)
        ret = self._driver.update_migrated_volume(
            self.ctxt, old_vol, new_vol, None)
        self.assertEqual({'_name_id': None}, ret)
        self._assert_vol_exists(old_vol.id, True)
        self._assert_vol_exists(new_vol.id, False)
        self._delete_volume(old_vol)
        self._delete_volume(new_vol, False)

    def test_update_migrated_volume_existed(self):
        old_vol = self._create_volume()
        self._assert_vol_exists(old_vol.id, True)
        new_vol = self._create_volume()
        self._assert_vol_exists(new_vol.id, True)
        ret = self._driver.update_migrated_volume(
            self.ctxt, old_vol, new_vol, None)
        self.assertEqual({'_name_id': new_vol.id}, ret)
        self._delete_volume(old_vol)
        self._delete_volume(new_vol)

    def test_manage_existing(self):
        volume_name = fake.UUID1
        self._driver._cmd.create_volume(volume_name, '1', POOLS_NAME[0])
        volume = self._driver._cmd.get_volume(volume_name)
        self.assertEqual(1, len(volume))
        self.assertEqual(volume_name, volume[0]['name'])
        new_volume = self._create_volume(driver=False)
        self._assert_vol_exists(new_volume.id, False)
        self.assertRaises(exception.ManageExistingInvalidReference,
                          self._driver.manage_existing,
                          new_volume, {})
        self._driver.manage_existing(new_volume,
                                     {'source-name': volume_name})
        self._assert_vol_exists(new_volume.id, True)
        self._delete_volume(new_volume)

    def test_manage_existing_get_size(self):
        volume_name = fake.UUID1
        self._driver._cmd.create_volume(volume_name, '1', POOLS_NAME[0])
        vol = self._create_volume(size=1, driver=False)
        self._assert_vol_exists(vol.id, False)
        ret = self._driver.manage_existing_get_size(
            vol, {'source-name': volume_name})
        self.assertEqual(1, ret)
        self._driver._cmd.delete_volume(volume_name)
        self._delete_volume(vol, False)

    def test_manage_existing_get_size_extend(self):
        volume_name = fake.UUID1
        size_str = '1.2'
        size_gb = 2
        self._driver._cmd.create_volume(volume_name, size_str, POOLS_NAME[0])
        volume = self._driver._cmd.get_volume(volume_name)
        self.assertEqual(1, len(volume))
        self.assertEqual(volume_name, volume[0]['name'])
        vol = self._create_volume(driver=False)
        self._assert_vol_exists(vol.id, False)
        ret = self._driver.manage_existing_get_size(
            vol, {'source-name': volume_name})
        self.assertEqual(size_gb, ret)
        self._driver._cmd.delete_volume(volume_name)
        self._delete_volume(vol, driver=False)

    def test_manage_get_volume(self):
        vol = self._create_volume()
        vol_backend = self._assert_vol_exists(vol.id, True)
        vol_name = vol_backend[0]['name']
        ret = self._driver._manage_get_volume({'source-name': vol_name})
        self.assertEqual(vol_backend[0], ret)
        self.assertRaises(exception.ManageExistingInvalidReference,
                          self._driver._manage_get_volume, {})
        self.assertRaises(exception.ManageExistingInvalidReference,
                          self._driver._manage_get_volume,
                          {'source-name': 'error_volume'})
        self.assertRaises(exception.ManageExistingInvalidReference,
                          self._driver._manage_get_volume,
                          {'source-name': vol_name}, 'error_pool')
        self._delete_volume(vol)
