"Fossies" - the Fresh Open Source Software Archive

Member "cinder-14.0.2/cinder/tests/unit/volume/drivers/hpe/test_hpe3par.py" (4 Oct 2019, 440690 Bytes) of package /linux/misc/openstack/cinder-14.0.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "test_hpe3par.py": 14.0.1_vs_14.0.2.

    1 #    (c) Copyright 2013-2015 Hewlett Packard Enterprise Development LP
    2 #    All Rights Reserved.
    3 #
    4 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
    5 #    not use this file except in compliance with the License. You may obtain
    6 #    a copy of the License at
    7 #
    8 #         http://www.apache.org/licenses/LICENSE-2.0
    9 #
   10 #    Unless required by applicable law or agreed to in writing, software
   11 #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
   12 #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
   13 #    License for the specific language governing permissions and limitations
   14 #    under the License.
   15 """Unit tests for OpenStack Cinder volume drivers."""
   16 
   17 import mock
   18 
   19 import ast
   20 
   21 from oslo_utils import units
   22 
   23 from cinder import context
   24 from cinder import exception
   25 from cinder.objects import fields
   26 from cinder import test
   27 from cinder.tests.unit import fake_volume
   28 from cinder.tests.unit.volume.drivers.hpe \
   29     import fake_hpe_3par_client as hpe3parclient
   30 from cinder.volume.drivers.hpe import hpe_3par_base as hpedriverbase
   31 from cinder.volume.drivers.hpe import hpe_3par_common as hpecommon
   32 from cinder.volume.drivers.hpe import hpe_3par_fc as hpefcdriver
   33 from cinder.volume.drivers.hpe import hpe_3par_iscsi as hpedriver
   34 from cinder.volume import qos_specs
   35 from cinder.volume import utils as volume_utils
   36 from cinder.volume import volume_types
   37 
   38 hpeexceptions = hpe3parclient.hpeexceptions
   39 
   40 
   41 HPE3PAR_CPG = 'OpenStackCPG'
   42 HPE3PAR_CPG2 = 'fakepool'
   43 HPE3PAR_CPG_QOS = 'qospool'
   44 HPE3PAR_CPG_SNAP = 'OpenStackCPGSnap'
   45 HPE3PAR_USER_NAME = 'testUser'
   46 HPE3PAR_USER_PASS = 'testPassword'
   47 HPE3PAR_SAN_IP = '2.2.2.2'
   48 HPE3PAR_SAN_SSH_PORT = 999
   49 HPE3PAR_SAN_SSH_CON_TIMEOUT = 44
   50 HPE3PAR_SAN_SSH_PRIVATE = 'foobar'
   51 GOODNESS_FUNCTION = \
   52     "stats.capacity_utilization < 0.6? 100:25"
   53 FILTER_FUNCTION = \
   54     "stats.total_volumes < 400 && stats.capacity_utilization < 0.8"
   55 
   56 CHAP_USER_KEY = "HPQ-cinder-CHAP-name"
   57 CHAP_PASS_KEY = "HPQ-cinder-CHAP-secret"
   58 
   59 FLASH_CACHE_ENABLED = 1
   60 FLASH_CACHE_DISABLED = 2
   61 
   62 # Input/output (total read/write) operations per second.
   63 THROUGHPUT = 'throughput'
   64 # Data processed (total read/write) per unit time: kilobytes per second.
   65 BANDWIDTH = 'bandwidth'
   66 # Response time (total read/write): microseconds.
   67 LATENCY = 'latency'
   68 # IO size (total read/write): kilobytes.
   69 IO_SIZE = 'io_size'
   70 # Queue length for processing IO requests
   71 QUEUE_LENGTH = 'queue_length'
   72 # Average busy percentage
   73 AVG_BUSY_PERC = 'avg_busy_perc'
   74 
   75 # replication constants
   76 HPE3PAR_CPG_REMOTE = 'DestOpenStackCPG'
   77 HPE3PAR_CPG2_REMOTE = 'destfakepool'
   78 HPE3PAR_CPG_MAP = 'OpenStackCPG:DestOpenStackCPG fakepool:destfakepool'
   79 SYNC_MODE = 1
   80 PERIODIC_MODE = 2
   81 SYNC_PERIOD = 900
   82 # EXISTENT_PATH error code returned from hpe3parclient
   83 EXISTENT_PATH = 73
   84 
   85 
   86 class Comment(object):
   87     def __init__(self, expected):
   88         self.expected = expected
   89 
   90     def __eq__(self, actual):
   91         return (dict(ast.literal_eval(actual)) == self.expected)
   92 
   93     def __ne__(self, other):
   94         return not self.__eq__(other)
   95 
   96 
   97 class HPE3PARBaseDriver(test.TestCase):
   98 
   99     VOLUME_ID = 'd03338a9-9115-48a3-8dfc-35cdfcdc15a7'
  100     SRC_CG_VOLUME_ID = 'bd21d11b-c765-4c68-896c-6b07f63cfcb6'
  101     CLONE_ID = 'd03338a9-9115-48a3-8dfc-000000000000'
  102     VOLUME_TYPE_ID_REPLICATED = 'be9181f1-4040-46f2-8298-e7532f2bf9db'
  103     VOLUME_TYPE_ID_DEDUP = 'd03338a9-9115-48a3-8dfc-11111111111'
  104     VOLUME_TYPE_ID_TIRAMISU = 'd03338a9-9115-48a3-8dfc-44444444444'
  105     VOL_TYPE_ID_DEDUP_COMPRESS = 'd03338a9-9115-48a3-8dfc-33333333333'
  106     VOLUME_TYPE_ID_FLASH_CACHE = 'd03338a9-9115-48a3-8dfc-22222222222'
  107     VOLUME_NAME = 'volume-' + VOLUME_ID
  108     SRC_CG_VOLUME_NAME = 'volume-' + SRC_CG_VOLUME_ID
  109     VOLUME_NAME_3PAR = 'osv-0DM4qZEVSKON-DXN-NwVpw'
  110     SNAPSHOT_ID = '2f823bdc-e36e-4dc8-bd15-de1c7a28ff31'
  111     SNAPSHOT_NAME = 'snapshot-2f823bdc-e36e-4dc8-bd15-de1c7a28ff31'
  112     VOLUME_3PAR_NAME = 'osv-0DM4qZEVSKON-DXN-NwVpw'
  113     SNAPSHOT_3PAR_NAME = 'oss-L4I73ONuTci9Fd4ceij-MQ'
  114     RCG_3PAR_NAME = 'rcg-0DM4qZEVSKON-DXN-N'
  115     RCG_3PAR_GROUP_NAME = 'rcg-YET.38iJR1KQDyA50k'
  116     GROUP_ID = '6044fedf-c889-4752-900f-2039d247a5df'
  117     CONSIS_GROUP_NAME = 'vvs-YET.38iJR1KQDyA50kel3w'
  118     SRC_CONSIS_GROUP_ID = '7d7dfa02-ac6e-48cb-96af-8a0cd3008d47'
  119     SRC_CONSIS_GROUP_NAME = 'vvs-fX36AqxuSMuWr4oM0wCNRw'
  120     CGSNAPSHOT_ID = 'e91c5ed5-daee-4e84-8724-1c9e31e7a1f2'
  121     CGSNAPSHOT_BASE_NAME = 'oss-6Rxe1druToSHJByeMeeh8g'
  122     CLIENT_ID = "12345"
  123     REPLICATION_CLIENT_ID = "54321"
  124     REPLICATION_BACKEND_ID = 'target'
  125     # fake host on the 3par
  126     FAKE_HOST = 'fakehost'
  127     FAKE_CINDER_HOST = 'fakehost@foo#' + HPE3PAR_CPG
  128     USER_ID = '2689d9a913974c008b1d859013f23607'
  129     PROJECT_ID = 'fac88235b9d64685a3530f73e490348f'
  130     VOLUME_ID_SNAP = '761fc5e5-5191-4ec7-aeba-33e36de44156'
  131     FAKE_DESC = 'test description name'
  132     FAKE_FC_PORTS = [{'portPos': {'node': 7, 'slot': 1, 'cardPort': 1},
  133                       'type': 1,
  134                       'portWWN': '0987654321234',
  135                       'protocol': 1,
  136                       'mode': 2,
  137                       'linkState': 4},
  138                      {'portPos': {'node': 6, 'slot': 1, 'cardPort': 1},
  139                       'type': 1,
  140                       'portWWN': '123456789000987',
  141                       'protocol': 1,
  142                       'mode': 2,
  143                       'linkState': 4}]
  144     QOS = {'qos:maxIOPS': '1000', 'qos:maxBWS': '50',
  145            'qos:minIOPS': '100', 'qos:minBWS': '25',
  146            'qos:latency': '25', 'qos:priority': 'low'}
  147     QOS_SPECS = {'maxIOPS': '1000', 'maxBWS': '50',
  148                  'minIOPS': '100', 'minBWS': '25',
  149                  'latency': '25', 'priority': 'low'}
  150     VVS_NAME = "myvvs"
  151     FAKE_ISCSI_PORT = {'portPos': {'node': 8, 'slot': 1, 'cardPort': 1},
  152                        'protocol': 2,
  153                        'mode': 2,
  154                        'IPAddr': '1.1.1.2',
  155                        'iSCSIName': ('iqn.2000-05.com.3pardata:'
  156                                      '21810002ac00383d'),
  157                        'linkState': 4}
  158     volume = {'name': VOLUME_NAME,
  159               'id': VOLUME_ID,
  160               'display_name': 'Foo Volume',
  161               'size': 2,
  162               'host': FAKE_CINDER_HOST,
  163               'volume_type': None,
  164               'volume_type_id': None}
  165 
  166     volume_src_cg = {'name': SRC_CG_VOLUME_NAME,
  167                      'id': SRC_CG_VOLUME_ID,
  168                      'display_name': 'Foo Volume',
  169                      'size': 2,
  170                      'host': FAKE_CINDER_HOST,
  171                      'volume_type': None,
  172                      'volume_type_id': None}
  173 
  174     volume_replicated = {'name': VOLUME_NAME,
  175                          'id': VOLUME_ID,
  176                          'display_name': 'Foo Volume',
  177                          'replication_status': 'disabled',
  178                          'provider_location': CLIENT_ID,
  179                          'size': 2,
  180                          'host': FAKE_CINDER_HOST,
  181                          'volume_type': 'replicated',
  182                          'volume_type_id': VOLUME_TYPE_ID_REPLICATED}
  183 
  184     volume_tiramisu = {'name': VOLUME_NAME,
  185                        'id': VOLUME_ID,
  186                        'display_name': 'Foo Volume',
  187                        'replication_status': 'disabled',
  188                        'provider_location': CLIENT_ID,
  189                        'size': 2,
  190                        'host': FAKE_CINDER_HOST,
  191                        'volume_type': 'group_replication',
  192                        'volume_type_id': VOLUME_TYPE_ID_TIRAMISU}
  193 
  194     replication_targets = [{'backend_id': REPLICATION_BACKEND_ID,
  195                             'cpg_map': HPE3PAR_CPG_MAP,
  196                             'hpe3par_api_url': 'https://1.1.1.1/api/v1',
  197                             'hpe3par_username': HPE3PAR_USER_NAME,
  198                             'hpe3par_password': HPE3PAR_USER_PASS,
  199                             'san_ip': HPE3PAR_SAN_IP,
  200                             'san_login': HPE3PAR_USER_NAME,
  201                             'san_password': HPE3PAR_USER_PASS,
  202                             'san_ssh_port': HPE3PAR_SAN_SSH_PORT,
  203                             'ssh_conn_timeout': HPE3PAR_SAN_SSH_CON_TIMEOUT,
  204                             'san_private_key': HPE3PAR_SAN_SSH_PRIVATE}]
  205 
  206     list_rep_targets = [{'backend_id': 'target'}]
  207 
  208     volume_encrypted = {'name': VOLUME_NAME,
  209                         'id': VOLUME_ID,
  210                         'display_name': 'Foo Volume',
  211                         'size': 2,
  212                         'host': FAKE_CINDER_HOST,
  213                         'volume_type': None,
  214                         'volume_type_id': None,
  215                         'encryption_key_id': 'fake_key'}
  216 
  217     volume_dedup_compression = {'name': VOLUME_NAME,
  218                                 'id': VOLUME_ID,
  219                                 'display_name': 'Foo Volume',
  220                                 'size': 16,
  221                                 'host': FAKE_CINDER_HOST,
  222                                 'volume_type': 'dedup_compression',
  223                                 'volume_type_id': VOL_TYPE_ID_DEDUP_COMPRESS}
  224 
  225     volume_dedup = {'name': VOLUME_NAME,
  226                     'id': VOLUME_ID,
  227                     'display_name': 'Foo Volume',
  228                     'size': 2,
  229                     'host': FAKE_CINDER_HOST,
  230                     'volume_type': 'dedup',
  231                     'volume_type_id': VOLUME_TYPE_ID_DEDUP}
  232 
  233     volume_pool = {'name': VOLUME_NAME,
  234                    'id': VOLUME_ID,
  235                    'display_name': 'Foo Volume',
  236                    'size': 2,
  237                    'host': volume_utils.append_host(FAKE_HOST, HPE3PAR_CPG2),
  238                    'volume_type': None,
  239                    'volume_type_id': None}
  240 
  241     volume_qos = {'name': VOLUME_NAME,
  242                   'id': VOLUME_ID,
  243                   'display_name': 'Foo Volume',
  244                   'size': 2,
  245                   'host': FAKE_CINDER_HOST,
  246                   'volume_type': None,
  247                   'volume_type_id': 'gold'}
  248 
  249     volume_flash_cache = {'name': VOLUME_NAME,
  250                           'id': VOLUME_ID,
  251                           'display_name': 'Foo Volume',
  252                           'size': 2,
  253                           'host': FAKE_CINDER_HOST,
  254                           'volume_type': None,
  255                           'volume_type_id': VOLUME_TYPE_ID_FLASH_CACHE}
  256 
  257     volume_hos = {'name': VOLUME_NAME,
  258                   'id': VOLUME_ID,
  259                   'display_name': 'Foo Volume',
  260                   'size': 2,
  261                   'host': FAKE_CINDER_HOST,
  262                   'volume_type': None,
  263                   'volume_type_id': 'hos'}
  264 
  265     snapshot = {'name': SNAPSHOT_NAME,
  266                 'id': SNAPSHOT_ID,
  267                 'user_id': USER_ID,
  268                 'project_id': PROJECT_ID,
  269                 'volume_id': VOLUME_ID_SNAP,
  270                 'volume_name': VOLUME_NAME,
  271                 'status': fields.SnapshotStatus.CREATING,
  272                 'progress': '0%',
  273                 'volume_size': 2,
  274                 'display_name': 'fakesnap',
  275                 'display_description': FAKE_DESC,
  276                 'volume': volume}
  277 
  278     wwn = ["123456789012345", "123456789054321"]
  279 
  280     connector = {'ip': '10.0.0.2',
  281                  'initiator': 'iqn.1993-08.org.debian:01:222',
  282                  'wwpns': [wwn[0], wwn[1]],
  283                  'wwnns': ["223456789012345", "223456789054321"],
  284                  'host': FAKE_HOST,
  285                  'multipath': False}
  286 
  287     connector_multipath_enabled = {'ip': '10.0.0.2',
  288                                    'initiator': ('iqn.1993-08.org'
  289                                                  '.debian:01:222'),
  290                                    'wwpns': [wwn[0], wwn[1]],
  291                                    'wwnns': ["223456789012345",
  292                                              "223456789054321"],
  293                                    'host': FAKE_HOST,
  294                                    'multipath': True}
  295 
  296     volume_type = {'name': 'gold',
  297                    'deleted': False,
  298                    'updated_at': None,
  299                    'extra_specs': {'cpg': HPE3PAR_CPG2,
  300                                    'qos:maxIOPS': '1000',
  301                                    'qos:maxBWS': '50',
  302                                    'qos:minIOPS': '100',
  303                                    'qos:minBWS': '25',
  304                                    'qos:latency': '25',
  305                                    'qos:priority': 'low'},
  306                    'deleted_at': None,
  307                    'id': 'gold'}
  308 
  309     volume_type_replicated = {'name': 'replicated',
  310                               'deleted': False,
  311                               'updated_at': None,
  312                               'extra_specs':
  313                                   {'replication_enabled': '<is> True'},
  314                               'deleted_at': None,
  315                               'id': VOLUME_TYPE_ID_REPLICATED}
  316 
  317     volume_type_dedup_compression = {'name': 'dedup',
  318                                      'deleted': False,
  319                                      'updated_at': None,
  320                                      'extra_specs': {'cpg': HPE3PAR_CPG2,
  321                                                      'provisioning': 'dedup',
  322                                                      'compression': 'true'},
  323                                      'deleted_at': None,
  324                                      'id': VOL_TYPE_ID_DEDUP_COMPRESS}
  325 
  326     volume_type_dedup = {'name': 'dedup',
  327                          'deleted': False,
  328                          'updated_at': None,
  329                          'extra_specs': {'cpg': HPE3PAR_CPG2,
  330                                          'provisioning': 'dedup'},
  331                          'deleted_at': None,
  332                          'id': VOLUME_TYPE_ID_DEDUP}
  333 
  334     volume_type_tiramisu = {'name': 'dedup',
  335                             'deleted': False,
  336                             'updated_at': None,
  337                             'extra_specs': {'cpg': HPE3PAR_CPG2,
  338                                             'hpe3par:group_replication':
  339                                             '<is> True',
  340                                             'replication_enabled': '<is> True',
  341                                             'replication:mode': 'sync'},
  342                             'deleted_at': None,
  343                             'id': VOLUME_TYPE_ID_TIRAMISU}
  344 
  345     volume_type_flash_cache = {'name': 'flash-cache-on',
  346                                'deleted': False,
  347                                'updated_at': None,
  348                                'extra_specs': {'cpg': HPE3PAR_CPG2,
  349                                                'hpe3par:flash_cache': 'true'},
  350                                'deleted_at': None,
  351                                'id': VOLUME_TYPE_ID_FLASH_CACHE}
  352 
  353     volume_type_hos = {'name': 'hos',
  354                        'deleted': False,
  355                        'updated_at': None,
  356                        'extra_specs': {'convert_to_base': False},
  357                        'deleted_at': None,
  358                        'id': 'hos'}
  359 
  360     flash_cache_3par_keys = {'flash_cache': 'true'}
  361 
  362     cpgs = [
  363         {'SAGrowth': {'LDLayout': {'diskPatterns': [{'diskType': 2}]},
  364                       'incrementMiB': 8192},
  365          'SAUsage': {'rawTotalMiB': 24576,
  366                      'rawUsedMiB': 768,
  367                      'totalMiB': 8192,
  368                      'usedMiB': 256},
  369          'SDGrowth': {'LDLayout': {'RAIDType': 4,
  370                       'diskPatterns': [{'diskType': 2}]},
  371                       'incrementMiB': 32768},
  372          'SDUsage': {'rawTotalMiB': 49152,
  373                      'rawUsedMiB': 1023,
  374                      'totalMiB': 36864,
  375                      'usedMiB': 1024 * 1},
  376          'UsrUsage': {'rawTotalMiB': 57344,
  377                       'rawUsedMiB': 43349,
  378                       'totalMiB': 43008,
  379                       'usedMiB': 1024 * 20},
  380          'additionalStates': [],
  381          'degradedStates': [],
  382          'failedStates': [],
  383          'id': 5,
  384          'name': HPE3PAR_CPG,
  385          'numFPVVs': 2,
  386          'numTPVVs': 0,
  387          'numTDVVs': 1,
  388          'state': 1,
  389          'uuid': '29c214aa-62b9-41c8-b198-543f6cf24edf'}]
  390 
  391     TASK_DONE = 1
  392     TASK_ACTIVE = 2
  393     STATUS_DONE = {'status': 1}
  394     STATUS_ACTIVE = {'status': 2}
  395 
  396     mock_client_conf = {
  397         'PORT_MODE_TARGET': 2,
  398         'PORT_STATE_READY': 4,
  399         'PORT_PROTO_ISCSI': 2,
  400         'PORT_PROTO_FC': 1,
  401         'PORT_TYPE_HOST': 1,
  402         'TASK_DONE': TASK_DONE,
  403         'TASK_ACTIVE': TASK_ACTIVE,
  404         'HOST_EDIT_ADD': 1,
  405         'HOST_EDIT_REMOVE': 2,
  406         'CHAP_INITIATOR': 1,
  407         'CHAP_TARGET': 2,
  408         'getPorts.return_value': {
  409             'members': FAKE_FC_PORTS + [FAKE_ISCSI_PORT]
  410         }
  411     }
  412 
  413     RETYPE_VVS_NAME = "yourvvs"
  414 
  415     RETYPE_HOST = {
  416         u'host': u'mark-stack1@3parfc',
  417         u'capabilities': {
  418             'QoS_support': True,
  419             u'location_info': u'HPE3PARDriver:1234567:MARK_TEST_CPG',
  420             u'timestamp': u'2014-06-04T19:03:32.485540',
  421             u'allocated_capacity_gb': 0,
  422             u'volume_backend_name': u'3parfc',
  423             u'free_capacity_gb': u'infinite',
  424             u'driver_version': u'3.0.0',
  425             u'total_capacity_gb': u'infinite',
  426             u'reserved_percentage': 0,
  427             u'vendor_name': u'Hewlett Packard Enterprise',
  428             u'storage_protocol': u'FC'
  429         }
  430     }
  431 
  432     RETYPE_HOST_NOT3PAR = {
  433         u'host': u'mark-stack1@3parfc',
  434         u'capabilities': {
  435             u'location_info': u'XXXDriverXXX:1610771:MARK_TEST_CPG',
  436         }
  437     }
  438 
  439     RETYPE_QOS_SPECS = {'maxIOPS': '1000', 'maxBWS': '50',
  440                         'minIOPS': '100', 'minBWS': '25',
  441                         'latency': '25', 'priority': 'high'}
  442 
  443     RETYPE_VOLUME_TYPE_ID = "FakeVolId"
  444 
  445     RETYPE_VOLUME_TYPE_0 = {
  446         'name': 'red',
  447         'id': RETYPE_VOLUME_TYPE_ID,
  448         'extra_specs': {
  449             'cpg': HPE3PAR_CPG,
  450             'snap_cpg': HPE3PAR_CPG_SNAP,
  451             'vvs': RETYPE_VVS_NAME,
  452             'qos': RETYPE_QOS_SPECS,
  453             'tpvv': True,
  454             'tdvv': False,
  455             'volume_type': volume_type
  456         }
  457     }
  458 
  459     RETYPE_VOLUME_TYPE_1 = {
  460         'name': 'white',
  461         'id': RETYPE_VOLUME_TYPE_ID,
  462         'extra_specs': {
  463             'cpg': HPE3PAR_CPG,
  464             'snap_cpg': HPE3PAR_CPG_SNAP,
  465             'vvs': VVS_NAME,
  466             'qos': QOS,
  467             'tpvv': True,
  468             'tdvv': False,
  469             'volume_type': volume_type
  470         }
  471     }
  472 
  473     RETYPE_VOLUME_TYPE_2 = {
  474         'name': 'blue',
  475         'id': RETYPE_VOLUME_TYPE_ID,
  476         'extra_specs': {
  477             'cpg': HPE3PAR_CPG_QOS,
  478             'snap_cpg': HPE3PAR_CPG_SNAP,
  479             'vvs': RETYPE_VVS_NAME,
  480             'qos': RETYPE_QOS_SPECS,
  481             'tpvv': True,
  482             'tdvv': False,
  483             'volume_type': volume_type
  484         }
  485     }
  486 
  487     RETYPE_VOLUME_TYPE_3 = {
  488         'name': 'purple',
  489         'id': RETYPE_VOLUME_TYPE_ID,
  490         'extra_specs': {
  491             'cpg': HPE3PAR_CPG_QOS,
  492             'snap_cpg': HPE3PAR_CPG_SNAP,
  493             'vvs': RETYPE_VVS_NAME,
  494             'qos': RETYPE_QOS_SPECS,
  495             'tpvv': False,
  496             'tdvv': True,
  497             'volume_type': volume_type
  498         }
  499     }
  500     RETYPE_VOLUME_TYPE_BAD_PERSONA = {
  501         'name': 'bad_persona',
  502         'id': 'any_id',
  503         'extra_specs': {
  504             'hpe3par:persona': '99 - invalid'
  505         }
  506     }
  507 
  508     RETYPE_VOLUME_TYPE_BAD_CPG = {
  509         'name': 'bad_cpg',
  510         'id': 'any_id',
  511         'extra_specs': {
  512             'cpg': 'bogus',
  513             'snap_cpg': 'bogus',
  514             'hpe3par:persona': '2 - Generic-ALUA'
  515         }
  516     }
  517 
  518     MANAGE_VOLUME_INFO = {
  519         'userCPG': 'testUserCpg0',
  520         'snapCPG': 'testSnapCpg0',
  521         'provisioningType': 1,
  522         'comment': "{'display_name': 'Foo Volume'}"
  523     }
  524 
  525     MV_INFO_WITH_NO_SNAPCPG = {
  526         'userCPG': 'testUserCpg0',
  527         'provisioningType': 1,
  528         'comment': "{'display_name': 'Foo Volume'}"
  529     }
  530 
  531     RETYPE_TEST_COMMENT = "{'retype_test': 'test comment'}"
  532 
  533     RETYPE_VOLUME_INFO_0 = {
  534         'name': VOLUME_NAME,
  535         'id': VOLUME_ID,
  536         'display_name': 'Retype Vol0',
  537         'size': 1,
  538         'host': RETYPE_HOST,
  539         'userCPG': 'testUserCpg0',
  540         'snapCPG': 'testSnapCpg0',
  541         'provisioningType': 1,
  542         'comment': RETYPE_TEST_COMMENT
  543     }
  544 
  545     RETYPE_TEST_COMMENT_1 = "{'retype_test': 'test comment 1'}"
  546 
  547     RETYPE_VOLUME_INFO_1 = {
  548         'name': VOLUME_NAME,
  549         'id': VOLUME_ID,
  550         'display_name': 'Retype Vol1',
  551         'size': 1,
  552         'host': RETYPE_HOST,
  553         'userCPG': HPE3PAR_CPG,
  554         'snapCPG': HPE3PAR_CPG_SNAP,
  555         'provisioningType': 1,
  556         'comment': RETYPE_TEST_COMMENT
  557     }
  558 
  559     RETYPE_TEST_COMMENT_2 = "{'retype_test': 'test comment 2'}"
  560 
  561     RETYPE_VOLUME_INFO_2 = {
  562         'name': VOLUME_NAME,
  563         'id': VOLUME_ID,
  564         'display_name': 'Retype Vol2',
  565         'size': 1,
  566         'host': RETYPE_HOST,
  567         'userCPG': HPE3PAR_CPG,
  568         'snapCPG': HPE3PAR_CPG_SNAP,
  569         'provisioningType': 3,
  570         'comment': RETYPE_TEST_COMMENT
  571     }
  572     # Test for when we don't get a snapCPG.
  573     RETYPE_VOLUME_INFO_NO_SNAP = {
  574         'name': VOLUME_NAME,
  575         'id': VOLUME_ID,
  576         'display_name': 'Retype Vol2',
  577         'size': 1,
  578         'host': RETYPE_HOST,
  579         'userCPG': 'testUserCpg2',
  580         'provisioningType': 1,
  581         'comment': '{}'
  582     }
  583 
  584     RETYPE_CONF = {
  585         'TASK_ACTIVE': TASK_ACTIVE,
  586         'TASK_DONE': TASK_DONE,
  587         'getTask.return_value': STATUS_DONE,
  588         'getStorageSystemInfo.return_value': {'id': CLIENT_ID,
  589                                               'serialNumber': '1234567'},
  590         'getVolume.return_value': RETYPE_VOLUME_INFO_0,
  591         'modifyVolume.return_value': ("anyResponse", {'taskid': 1})
  592     }
  593 
  594     # 3PAR retype currently doesn't use the diff.  Existing code and fresh info
  595     # from the array work better for the most part.  Some use of the diff was
  596     # intentionally removed to make _retype more usable for other use cases.
  597     RETYPE_DIFF = None
  598 
  599     wsapi_version_312 = {'major': 1,
  600                          'build': 30102422,
  601                          'minor': 3,
  602                          'revision': 1}
  603 
  604     wsapi_version_for_compression = {'major': 1,
  605                                      'build': 30301215,
  606                                      'minor': 6,
  607                                      'revision': 0}
  608 
  609     wsapi_version_for_dedup = {'major': 1,
  610                                'build': 30201120,
  611                                'minor': 4,
  612                                'revision': 1}
  613 
  614     wsapi_version_for_flash_cache = {'major': 1,
  615                                      'build': 30201200,
  616                                      'minor': 4,
  617                                      'revision': 2}
  618 
  619     wsapi_version_for_remote_copy = {'major': 1,
  620                                      'build': 30202290,
  621                                      'minor': 5,
  622                                      'revision': 0}
  623 
  624     # Use this to point to latest version of wsapi
  625     wsapi_version_latest = wsapi_version_for_compression
  626 
  627     standard_login = [
  628         mock.call.login(HPE3PAR_USER_NAME, HPE3PAR_USER_PASS),
  629         mock.call.setSSHOptions(
  630             HPE3PAR_SAN_IP,
  631             HPE3PAR_USER_NAME,
  632             HPE3PAR_USER_PASS,
  633             missing_key_policy='AutoAddPolicy',
  634             privatekey=HPE3PAR_SAN_SSH_PRIVATE,
  635             known_hosts_file=mock.ANY,
  636             port=HPE3PAR_SAN_SSH_PORT,
  637             conn_timeout=HPE3PAR_SAN_SSH_CON_TIMEOUT)]
  638 
  639     get_id_login = [
  640         mock.call.getWsApiVersion(),
  641         mock.call.login(HPE3PAR_USER_NAME, HPE3PAR_USER_PASS),
  642         mock.call.setSSHOptions(
  643             HPE3PAR_SAN_IP,
  644             HPE3PAR_USER_NAME,
  645             HPE3PAR_USER_PASS,
  646             missing_key_policy='AutoAddPolicy',
  647             privatekey=HPE3PAR_SAN_SSH_PRIVATE,
  648             known_hosts_file=mock.ANY,
  649             port=HPE3PAR_SAN_SSH_PORT,
  650             conn_timeout=HPE3PAR_SAN_SSH_CON_TIMEOUT),
  651         mock.call.getStorageSystemInfo()]
  652 
  653     standard_logout = [
  654         mock.call.logout()]
  655 
  656     class fake_volume_object(object):
  657         def __init__(self, vol_id='d03338a9-9115-48a3-8dfc-35cdfcdc15a7'):
  658             self.id = vol_id
  659             self.name = 'volume-d03338a9-9115-48a3-8dfc-35cdfcdc15a7'
  660             self.display_name = 'Foo Volume'
  661             self.size = 2
  662             self.host = 'fakehost@foo#OpenStackCPG'
  663             self.volume_type = None
  664             self.volume_type_id = None
  665             self.volume = {'volume_type_id': self.volume_type_id,
  666                            'host': self.host, 'id': self.id, 'volume_type':
  667                            self.volume_type}
  668 
  669         def get(self, parm):
  670             return self.volume[parm]
  671 
  672     class fake_group_object(object):
  673         def __init__(self, grp_id='6044fedf-c889-4752-900f-2039d247a5df'):
  674             self.id = grp_id
  675             self.volume_type_ids = ['d03338a9-9115-48a3-8dfc-33333333333']
  676             self.volume_types = ['d03338a9-9115-48a3-8dfc-33333333333']
  677             self.name = 'cg_name'
  678             self.group_snapshot_id = None
  679             self.host = 'fakehost@foo#OpenStackCPG'
  680             self.is_replicated = False
  681             self.description = 'consistency group'
  682 
  683     class fake_group_snapshot_object(object):
  684         def __init__(self, cgsnap_id='e91c5ed5-daee-4e84-8724-1c9e31e7a1f2'):
  685             self.id = cgsnap_id
  686             self.group_id = '6044fedf-c889-4752-900f-2039d247a5df'
  687             self.description = 'group_snapshot'
  688             self.readOnly = False
  689 
  690     def setup_configuration(self):
  691         configuration = mock.MagicMock()
  692         configuration.hpe3par_debug = False
  693         configuration.hpe3par_username = HPE3PAR_USER_NAME
  694         configuration.hpe3par_password = HPE3PAR_USER_PASS
  695         configuration.hpe3par_api_url = 'https://1.1.1.1/api/v1'
  696         configuration.hpe3par_cpg = [HPE3PAR_CPG, HPE3PAR_CPG2]
  697         configuration.hpe3par_cpg_snap = HPE3PAR_CPG_SNAP
  698         configuration.target_ip_address = '1.1.1.2'
  699         configuration.target_port = '1234'
  700         configuration.san_ip = HPE3PAR_SAN_IP
  701         configuration.san_login = HPE3PAR_USER_NAME
  702         configuration.san_password = HPE3PAR_USER_PASS
  703         configuration.san_ssh_port = HPE3PAR_SAN_SSH_PORT
  704         configuration.ssh_conn_timeout = HPE3PAR_SAN_SSH_CON_TIMEOUT
  705         configuration.san_private_key = HPE3PAR_SAN_SSH_PRIVATE
  706         configuration.hpe3par_snapshot_expiration = ""
  707         configuration.hpe3par_snapshot_retention = ""
  708         configuration.hpe3par_iscsi_ips = []
  709         configuration.hpe3par_iscsi_chap_enabled = False
  710         configuration.goodness_function = GOODNESS_FUNCTION
  711         configuration.filter_function = FILTER_FUNCTION
  712         configuration.image_volume_cache_enabled = False
  713         configuration.replication_device = None
  714         configuration.hpe3par_target_nsp = None
  715         return configuration
  716 
  717     @mock.patch(
  718         'hpe3parclient.client.HPE3ParClient',
  719         spec=True,
  720     )
  721     def setup_mock_client(self, _m_client, driver, conf=None, m_conf=None):
  722 
  723         _m_client = _m_client.return_value
  724 
  725         # Configure the base constants, defaults etc...
  726         _m_client.configure_mock(**self.mock_client_conf)
  727 
  728         _m_client.getWsApiVersion.return_value = self.wsapi_version_latest
  729 
  730         # If m_conf, drop those over the top of the base_conf.
  731         if m_conf is not None:
  732             _m_client.configure_mock(**m_conf)
  733 
  734         if conf is None:
  735             conf = self.setup_configuration()
  736         self.driver = driver(configuration=conf)
  737         self.driver.do_setup(None)
  738         return _m_client
  739 
  740     @mock.patch.object(volume_types, 'get_volume_type')
  741     def migrate_volume_attached(self, _mock_volume_types):
  742         _mock_volume_types.return_value = self.RETYPE_VOLUME_TYPE_1
  743         mock_client = self.setup_driver(mock_conf=self.RETYPE_CONF)
  744 
  745         volume = {'name': HPE3PARBaseDriver.VOLUME_NAME,
  746                   'volume_type_id': None,
  747                   'id': HPE3PARBaseDriver.CLONE_ID,
  748                   'display_name': 'Foo Volume',
  749                   'size': 2,
  750                   'status': 'available',
  751                   'host': HPE3PARBaseDriver.FAKE_HOST,
  752                   'source_volid': HPE3PARBaseDriver.VOLUME_ID}
  753 
  754         with mock.patch.object(hpecommon.HPE3PARCommon,
  755                                '_create_client') as mock_create_client:
  756             mock_create_client.return_value = mock_client
  757             common = self.driver._login()
  758 
  759             volume_name_3par = common._encode_name(volume['id'])
  760             osv_matcher = 'osv-' + volume_name_3par
  761 
  762             loc_info = 'HPE3PARDriver:1234567:CPG-FC1'
  763 
  764             protocol = "FC"
  765             if self.properties['driver_volume_type'] == "iscsi":
  766                 protocol = "iSCSI"
  767 
  768             host = {'host': 'stack@3parfc1',
  769                     'capabilities': {'location_info': loc_info,
  770                                      'storage_protocol': protocol}}
  771 
  772             result = self.driver.migrate_volume(context.get_admin_context(),
  773                                                 volume, host)
  774 
  775             new_comment = Comment({
  776                 "qos": {},
  777                 "retype_test": "test comment",
  778             })
  779             expected = [
  780                 mock.call.modifyVolume(osv_matcher,
  781                                        {'comment': new_comment,
  782                                         'snapCPG': 'OpenStackCPGSnap'}),
  783                 mock.call.modifyVolume(osv_matcher,
  784                                        {'action': 6,
  785                                         'userCPG': 'OpenStackCPG',
  786                                         'conversionOperation': 1,
  787                                         'tuneOperation': 1,
  788                                         'compression': False}),
  789                 mock.call.getTask(1),
  790                 mock.call.logout()
  791             ]
  792             mock_client.assert_has_calls(expected)
  793 
  794             self.assertIsNotNone(result)
  795             self.assertEqual((True, {'host': 'stack@3parfc1#OpenStackCPG'}),
  796                              result)
  797 
  798 
  799 class TestHPE3PARDriverBase(HPE3PARBaseDriver):
  800 
  801     def setup_driver(self, config=None, mock_conf=None, wsapi_version=None):
  802         self.ctxt = context.get_admin_context()
  803         mock_client = self.setup_mock_client(
  804             conf=config,
  805             m_conf=mock_conf,
  806             driver=hpedriverbase.HPE3PARDriverBase)
  807 
  808         if wsapi_version:
  809             mock_client.getWsApiVersion.return_value = (
  810                 wsapi_version)
  811         else:
  812             mock_client.getWsApiVersion.return_value = (
  813                 self.wsapi_version_latest)
  814 
  815         expected = [
  816             mock.call.getCPG(HPE3PAR_CPG),
  817             mock.call.getCPG(HPE3PAR_CPG2)]
  818         mock_client.assert_has_calls(
  819             self.standard_login +
  820             expected +
  821             self.standard_logout)
  822         mock_client.reset_mock()
  823         return mock_client
  824 
  825     @mock.patch('hpe3parclient.version', "3.0.9")
  826     def test_unsupported_client_version(self):
  827 
  828         self.assertRaises(exception.InvalidInput,
  829                           self.setup_driver)
  830 
  831     def test_ssh_options(self):
  832 
  833         expected_hosts_key_file = "test_hosts_key_file"
  834         self.flags(ssh_hosts_key_file=expected_hosts_key_file,
  835                    strict_ssh_host_key_policy=False)
  836 
  837         self.ctxt = context.get_admin_context()
  838         mock_client = self.setup_mock_client(
  839             driver=hpefcdriver.HPE3PARFCDriver)
  840 
  841         expected = [
  842             mock.call.login(HPE3PAR_USER_NAME, HPE3PAR_USER_PASS),
  843             mock.call.setSSHOptions(
  844                 HPE3PAR_SAN_IP,
  845                 HPE3PAR_USER_NAME,
  846                 HPE3PAR_USER_PASS,
  847                 privatekey=HPE3PAR_SAN_SSH_PRIVATE,
  848                 known_hosts_file=expected_hosts_key_file,
  849                 missing_key_policy="AutoAddPolicy",
  850                 port=HPE3PAR_SAN_SSH_PORT,
  851                 conn_timeout=HPE3PAR_SAN_SSH_CON_TIMEOUT),
  852             mock.call.getCPG(HPE3PAR_CPG),
  853             mock.call.getCPG(HPE3PAR_CPG2)]
  854         mock_client.assert_has_calls(
  855             expected +
  856             self.standard_logout)
  857 
  858     def test_ssh_options_strict(self):
  859 
  860         expected_hosts_key_file = "test_hosts_key_file"
  861         self.flags(ssh_hosts_key_file=expected_hosts_key_file,
  862                    strict_ssh_host_key_policy=True)
  863 
  864         self.ctxt = context.get_admin_context()
  865         mock_client = self.setup_mock_client(
  866             driver=hpefcdriver.HPE3PARFCDriver)
  867 
  868         expected = [
  869             mock.call.login(HPE3PAR_USER_NAME, HPE3PAR_USER_PASS),
  870             mock.call.setSSHOptions(
  871                 HPE3PAR_SAN_IP,
  872                 HPE3PAR_USER_NAME,
  873                 HPE3PAR_USER_PASS,
  874                 privatekey=HPE3PAR_SAN_SSH_PRIVATE,
  875                 known_hosts_file=expected_hosts_key_file,
  876                 missing_key_policy="RejectPolicy",
  877                 port=HPE3PAR_SAN_SSH_PORT,
  878                 conn_timeout=HPE3PAR_SAN_SSH_CON_TIMEOUT),
  879             mock.call.getCPG(HPE3PAR_CPG),
  880             mock.call.getCPG(HPE3PAR_CPG2)]
  881         mock_client.assert_has_calls(expected + self.standard_logout)
  882 
  883     def test_task_waiter(self):
  884 
  885         task_statuses = [self.STATUS_ACTIVE, self.STATUS_ACTIVE]
  886 
  887         def side_effect(*args):
  888             return task_statuses and task_statuses.pop(0) or self.STATUS_DONE
  889 
  890         conf = {'getTask.side_effect': side_effect}
  891         mock_client = self.setup_driver(mock_conf=conf)
  892 
  893         task_id = 1234
  894         interval = .001
  895 
  896         with mock.patch.object(hpecommon.HPE3PARCommon,
  897                                '_create_client') as mock_create_client:
  898             mock_create_client.return_value = mock_client
  899             common = self.driver._login()
  900             waiter = common.TaskWaiter(mock_client, task_id, interval)
  901             status = waiter.wait_for_task()
  902 
  903             expected = [
  904                 mock.call.getTask(task_id),
  905                 mock.call.getTask(task_id),
  906                 mock.call.getTask(task_id)
  907             ]
  908             mock_client.assert_has_calls(expected)
  909             self.assertEqual(self.STATUS_DONE, status)
  910 
  911     def test_create_volume(self):
  912         # setup_mock_client drive with default configuration
  913         # and return the mock HTTP 3PAR client
  914         mock_client = self.setup_driver()
  915         with mock.patch.object(hpecommon.HPE3PARCommon,
  916                                '_create_client') as mock_create_client:
  917             mock_create_client.return_value = mock_client
  918             self.driver.create_volume(self.volume)
  919             comment = Comment({
  920                 "display_name": "Foo Volume",
  921                 "type": "OpenStack",
  922                 "name": "volume-d03338a9-9115-48a3-8dfc-35cdfcdc15a7",
  923                 "volume_id": "d03338a9-9115-48a3-8dfc-35cdfcdc15a7"})
  924             expected = [
  925                 mock.call.createVolume(
  926                     self.VOLUME_3PAR_NAME,
  927                     HPE3PAR_CPG,
  928                     2048, {
  929                         'comment': comment,
  930                         'tpvv': True,
  931                         'tdvv': False,
  932                         'snapCPG': HPE3PAR_CPG_SNAP})]
  933 
  934             mock_client.assert_has_calls(
  935                 self.standard_login +
  936                 expected +
  937                 self.standard_logout)
  938 
  939     def test_create_volume_in_generic_group(self):
  940         # setup_mock_client drive with default configuration
  941         # and return the mock HTTP 3PAR client
  942         mock_client = self.setup_driver()
  943         volume = {'name': self.VOLUME_NAME,
  944                   'id': self.VOLUME_ID,
  945                   'display_name': 'Foo Volume',
  946                   'size': 2,
  947                   'group_id': '87101633-13e0-41ee-813b-deabc372267b',
  948                   'host': self.FAKE_CINDER_HOST,
  949                   'volume_type': None,
  950                   'volume_type_id': None}
  951         with mock.patch.object(hpecommon.HPE3PARCommon,
  952                                '_create_client') as mock_create_client:
  953             mock_create_client.return_value = mock_client
  954             self.driver.create_volume(volume)
  955             comment = Comment({
  956                 "display_name": "Foo Volume",
  957                 "type": "OpenStack",
  958                 "name": "volume-d03338a9-9115-48a3-8dfc-35cdfcdc15a7",
  959                 "volume_id": "d03338a9-9115-48a3-8dfc-35cdfcdc15a7"})
  960             expected = [
  961                 mock.call.createVolume(
  962                     self.VOLUME_3PAR_NAME,
  963                     HPE3PAR_CPG,
  964                     2048, {
  965                         'comment': comment,
  966                         'tpvv': True,
  967                         'tdvv': False,
  968                         'snapCPG': HPE3PAR_CPG_SNAP})]
  969 
  970             mock_client.assert_has_calls(
  971                 self.standard_login +
  972                 expected +
  973                 self.standard_logout)
  974 
  975     def test_create_volume_in_pool(self):
  976 
  977         # setup_mock_client drive with default configuration
  978         # and return the mock HTTP 3PAR client
  979         mock_client = self.setup_driver()
  980         with mock.patch.object(hpecommon.HPE3PARCommon,
  981                                '_create_client') as mock_create_client:
  982             mock_create_client.return_value = mock_client
  983 
  984             return_model = self.driver.create_volume(self.volume_pool)
  985             comment = Comment({
  986                 "display_name": "Foo Volume",
  987                 "type": "OpenStack",
  988                 "name": "volume-d03338a9-9115-48a3-8dfc-35cdfcdc15a7",
  989                 "volume_id": "d03338a9-9115-48a3-8dfc-35cdfcdc15a7"})
  990             expected = [
  991                 mock.call.createVolume(
  992                     self.VOLUME_3PAR_NAME,
  993                     HPE3PAR_CPG2,
  994                     2048, {
  995                         'comment': comment,
  996                         'tpvv': True,
  997                         'tdvv': False,
  998                         'snapCPG': HPE3PAR_CPG_SNAP})]
  999 
 1000             mock_client.assert_has_calls(
 1001                 self.standard_login +
 1002                 expected +
 1003                 self.standard_logout)
 1004             self.assertIsNone(return_model)
 1005 
 1006     @mock.patch.object(volume_types, 'get_volume_type')
 1007     def test_unsupported_dedup_volume_type(self, _mock_volume_types):
 1008 
 1009         mock_client = self.setup_driver(wsapi_version=self.wsapi_version_312)
 1010         _mock_volume_types.return_value = {
 1011             'name': 'dedup',
 1012             'extra_specs': {
 1013                 'cpg': HPE3PAR_CPG_QOS,
 1014                 'snap_cpg': HPE3PAR_CPG_SNAP,
 1015                 'vvs_name': self.VVS_NAME,
 1016                 'qos': self.QOS,
 1017                 'provisioning': 'dedup',
 1018                 'volume_type': self.volume_type_dedup}}
 1019 
 1020         with mock.patch.object(hpecommon.HPE3PARCommon,
 1021                                '_create_client') as mock_create_client:
 1022             mock_create_client.return_value = mock_client
 1023             common = self.driver._login()
 1024 
 1025             self.assertRaises(exception.InvalidInput,
 1026                               common.get_volume_settings_from_type_id,
 1027                               self.VOLUME_TYPE_ID_DEDUP,
 1028                               "mock")
 1029 
 1030     @mock.patch.object(volume_types, 'get_volume_type')
 1031     def test_get_snap_cpg_from_volume_type(self, _mock_volume_types):
 1032 
 1033         mock_client = self.setup_driver()
 1034         expected_type_snap_cpg = "type_snap_cpg"
 1035         _mock_volume_types.return_value = {
 1036             'name': 'gold',
 1037             'extra_specs': {
 1038                 'cpg': HPE3PAR_CPG,
 1039                 'snap_cpg': expected_type_snap_cpg,
 1040                 'volume_type': self.volume_type}}
 1041 
 1042         with mock.patch.object(hpecommon.HPE3PARCommon,
 1043                                '_create_client') as mock_create_client:
 1044             mock_create_client.return_value = mock_client
 1045             common = self.driver._login()
 1046 
 1047             result = common.get_volume_settings_from_type_id(
 1048                 "mock", self.driver.configuration.hpe3par_cpg)
 1049 
 1050             self.assertEqual(expected_type_snap_cpg, result['snap_cpg'])
 1051 
 1052     @mock.patch.object(volume_types, 'get_volume_type')
 1053     def test_get_snap_cpg_from_volume_type_cpg(self, _mock_volume_types):
 1054 
 1055         mock_client = self.setup_driver()
 1056         expected_cpg = 'use_extra_specs_cpg'
 1057         _mock_volume_types.return_value = {
 1058             'name': 'gold',
 1059             'extra_specs': {
 1060                 'cpg': expected_cpg,
 1061                 'volume_type': self.volume_type}}
 1062 
 1063         with mock.patch.object(hpecommon.HPE3PARCommon,
 1064                                '_create_client') as mock_create_client:
 1065             mock_create_client.return_value = mock_client
 1066             common = self.driver._login()
 1067 
 1068             result = common.get_volume_settings_from_type_id(
 1069                 "mock", self.driver.configuration.hpe3par_cpg)
 1070 
 1071             self.assertEqual(self.driver.configuration.hpe3par_cpg_snap,
 1072                              result['snap_cpg'])
 1073 
 1074     @mock.patch.object(volume_types, 'get_volume_type')
 1075     def test_get_snap_cpg_from_volume_type_conf_snap_cpg(
 1076             self, _mock_volume_types):
 1077         _mock_volume_types.return_value = {
 1078             'name': 'gold',
 1079             'extra_specs': {
 1080                 'volume_type': self.volume_type}}
 1081 
 1082         conf = self.setup_configuration()
 1083         expected_snap_cpg = conf.hpe3par_cpg_snap
 1084         mock_client = self.setup_driver(config=conf)
 1085         with mock.patch.object(hpecommon.HPE3PARCommon,
 1086                                '_create_client') as mock_create_client:
 1087             mock_create_client.return_value = mock_client
 1088             common = self.driver._login()
 1089 
 1090             result = common.get_volume_settings_from_type_id(
 1091                 "mock", self.driver.configuration.hpe3par_cpg)
 1092 
 1093         self.assertEqual(expected_snap_cpg, result['snap_cpg'])
 1094 
 1095     @mock.patch.object(volume_types, 'get_volume_type')
 1096     def test_get_snap_cpg_from_volume_type_conf_cpg(
 1097             self, _mock_volume_types):
 1098         _mock_volume_types.return_value = {
 1099             'name': 'gold',
 1100             'extra_specs': {
 1101                 'volume_type': self.volume_type}}
 1102 
 1103         conf = self.setup_configuration()
 1104         conf.hpe3par_cpg_snap = None
 1105         expected_cpg = conf.hpe3par_cpg
 1106         mock_client = self.setup_driver(config=conf)
 1107         with mock.patch.object(hpecommon.HPE3PARCommon,
 1108                                '_create_client') as mock_create_client:
 1109             mock_create_client.return_value = mock_client
 1110             common = self.driver._login()
 1111 
 1112             result = common.get_volume_settings_from_type_id(
 1113                 "mock", self.driver.configuration.hpe3par_cpg)
 1114 
 1115             self.assertEqual(expected_cpg, result['snap_cpg'])
 1116 
 1117     @mock.patch.object(volume_types, 'get_volume_type')
 1118     def test_create_volume_qos(self, _mock_volume_types):
 1119         # setup_mock_client drive with default configuration
 1120         # and return the mock HTTP 3PAR client
 1121         mock_client = self.setup_driver()
 1122 
 1123         _mock_volume_types.return_value = {
 1124             'name': 'gold',
 1125             'extra_specs': {
 1126                 'cpg': HPE3PAR_CPG_QOS,
 1127                 'snap_cpg': HPE3PAR_CPG_SNAP,
 1128                 'vvs_name': self.VVS_NAME,
 1129                 'qos': self.QOS,
 1130                 'tpvv': True,
 1131                 'tdvv': False,
 1132                 'volume_type': self.volume_type}}
 1133 
 1134         with mock.patch.object(hpecommon.HPE3PARCommon,
 1135                                '_create_client') as mock_create_client:
 1136             mock_create_client.return_value = mock_client
 1137 
 1138             return_model = self.driver.create_volume(self.volume_qos)
 1139             comment = Comment({
 1140                 "volume_type_name": "gold",
 1141                 "display_name": "Foo Volume",
 1142                 "name": "volume-d03338a9-9115-48a3-8dfc-35cdfcdc15a7",
 1143                 "volume_type_id": "gold",
 1144                 "volume_id": "d03338a9-9115-48a3-8dfc-35cdfcdc15a7",
 1145                 "qos": {},
 1146                 "type": "OpenStack"})
 1147 
 1148             expected = [
 1149                 mock.call.getCPG(HPE3PAR_CPG),
 1150                 mock.call.createVolume(
 1151                     self.VOLUME_3PAR_NAME,
 1152                     HPE3PAR_CPG,
 1153                     2048, {
 1154                         'comment': comment,
 1155                         'tpvv': True,
 1156                         'tdvv': False,
 1157                         'snapCPG': HPE3PAR_CPG_SNAP})]
 1158 
 1159             mock_client.assert_has_calls(
 1160                 self.standard_login +
 1161                 expected +
 1162                 self.standard_logout)
 1163             self.assertIsNone(return_model)
 1164 
 1165     @mock.patch.object(volume_types, 'get_volume_type')
 1166     def test_create_volume_replicated_periodic(self, _mock_volume_types):
 1167         # setup_mock_client drive with default configuration
 1168         # and return the mock HTTP 3PAR client
 1169         conf = self.setup_configuration()
 1170         self.replication_targets[0]['replication_mode'] = 'periodic'
 1171         conf.replication_device = self.replication_targets
 1172         mock_client = self.setup_driver(config=conf)
 1173         mock_client.getStorageSystemInfo.return_value = (
 1174             {'id': self.CLIENT_ID})
 1175         mock_client.getRemoteCopyGroup.side_effect = (
 1176             hpeexceptions.HTTPNotFound)
 1177         mock_client.getCPG.return_value = {'domain': None}
 1178         mock_replicated_client = self.setup_driver(config=conf)
 1179         mock_replicated_client.getStorageSystemInfo.return_value = (
 1180             {'id': self.REPLICATION_CLIENT_ID})
 1181 
 1182         _mock_volume_types.return_value = {
 1183             'name': 'replicated',
 1184             'extra_specs': {
 1185                 'replication_enabled': '<is> True',
 1186                 'replication:mode': 'periodic',
 1187                 'replication:sync_period': '900',
 1188                 'volume_type': self.volume_type_replicated}}
 1189 
 1190         with mock.patch.object(
 1191                 hpecommon.HPE3PARCommon,
 1192                 '_create_client') as mock_create_client, \
 1193             mock.patch.object(
 1194                 hpecommon.HPE3PARCommon,
 1195                 '_create_replication_client') as mock_replication_client:
 1196             mock_create_client.return_value = mock_client
 1197             mock_replication_client.return_value = mock_replicated_client
 1198 
 1199             return_model = self.driver.create_volume(self.volume_replicated)
 1200             comment = Comment({
 1201                 "volume_type_name": "replicated",
 1202                 "display_name": "Foo Volume",
 1203                 "name": "volume-d03338a9-9115-48a3-8dfc-35cdfcdc15a7",
 1204                 "volume_type_id": "be9181f1-4040-46f2-8298-e7532f2bf9db",
 1205                 "volume_id": "d03338a9-9115-48a3-8dfc-35cdfcdc15a7",
 1206                 "qos": {},
 1207                 "type": "OpenStack"})
 1208 
 1209             backend_id = self.replication_targets[0]['backend_id']
 1210             expected = [
 1211                 mock.call.createVolume(
 1212                     self.VOLUME_3PAR_NAME,
 1213                     HPE3PAR_CPG,
 1214                     2048, {
 1215                         'comment': comment,
 1216                         'tpvv': True,
 1217                         'tdvv': False,
 1218                         'snapCPG': HPE3PAR_CPG_SNAP}),
 1219                 mock.call.getRemoteCopyGroup(self.RCG_3PAR_NAME),
 1220                 mock.call.getCPG(HPE3PAR_CPG),
 1221                 mock.call.createRemoteCopyGroup(
 1222                     self.RCG_3PAR_NAME,
 1223                     [{'userCPG': HPE3PAR_CPG_REMOTE,
 1224                       'targetName': backend_id,
 1225                       'mode': PERIODIC_MODE,
 1226                       'snapCPG': HPE3PAR_CPG_REMOTE}],
 1227                     {'localUserCPG': HPE3PAR_CPG,
 1228                      'localSnapCPG': HPE3PAR_CPG_SNAP}),
 1229                 mock.call.addVolumeToRemoteCopyGroup(
 1230                     self.RCG_3PAR_NAME,
 1231                     self.VOLUME_3PAR_NAME,
 1232                     [{'secVolumeName': self.VOLUME_3PAR_NAME,
 1233                       'targetName': backend_id}],
 1234                     optional={'volumeAutoCreation': True}),
 1235                 mock.call.modifyRemoteCopyGroup(
 1236                     self.RCG_3PAR_NAME,
 1237                     {'targets': [{'syncPeriod': SYNC_PERIOD,
 1238                                   'targetName': backend_id}]}),
 1239                 mock.call.startRemoteCopy(self.RCG_3PAR_NAME)]
 1240             mock_client.assert_has_calls(
 1241                 self.get_id_login +
 1242                 self.standard_logout +
 1243                 self.standard_login +
 1244                 expected +
 1245                 self.standard_logout)
 1246             self.assertEqual({'replication_status': 'enabled',
 1247                               'provider_location': self.CLIENT_ID},
 1248                              return_model)
 1249 
 1250     @mock.patch.object(volume_types, 'get_volume_type')
 1251     def test_delete_volume_replicated_failedover(self, _mock_volume_types):
 1252         # setup_mock_client drive with default configuration
 1253         # and return the mock HTTP 3PAR client
 1254         conf = self.setup_configuration()
 1255         self.replication_targets[0]['replication_mode'] = 'periodic'
 1256         conf.replication_device = self.replication_targets
 1257         mock_client = self.setup_driver(config=conf)
 1258         mock_client.getStorageSystemInfo.return_value = (
 1259             {'id': self.CLIENT_ID})
 1260         mock_client.getRemoteCopyGroup.return_value = (
 1261             {'targets': [{'targetName': 'tgt'}]})
 1262         mock_client.getCPG.return_value = {'domain': None}
 1263         mock_replicated_client = self.setup_driver(config=conf)
 1264         mock_replicated_client.getStorageSystemInfo.return_value = (
 1265             {'id': self.REPLICATION_CLIENT_ID})
 1266 
 1267         _mock_volume_types.return_value = {
 1268             'name': 'replicated',
 1269             'extra_specs': {
 1270                 'replication_enabled': '<is> True',
 1271                 'replication:mode': 'periodic',
 1272                 'replication:sync_period': '900',
 1273                 'volume_type': self.volume_type_replicated}}
 1274 
 1275         with mock.patch.object(
 1276                 hpecommon.HPE3PARCommon,
 1277                 '_create_client') as mock_create_client, \
 1278             mock.patch.object(
 1279                 hpecommon.HPE3PARCommon,
 1280                 '_create_replication_client') as mock_replication_client:
 1281             mock_create_client.return_value = mock_client
 1282             mock_replication_client.return_value = mock_replicated_client
 1283 
 1284             volume = self.volume_replicated.copy()
 1285             volume['replication_status'] = 'failed-over'
 1286             self.driver.delete_volume(volume)
 1287 
 1288             rcg_name = self.RCG_3PAR_NAME + ".r" + self.CLIENT_ID
 1289             expected = [
 1290                 mock.call.getRemoteCopyGroup(rcg_name),
 1291                 mock.call.toggleRemoteCopyConfigMirror(
 1292                     'tgt',
 1293                     mirror_config=False),
 1294                 mock.call.stopRemoteCopy(rcg_name),
 1295                 mock.call.removeVolumeFromRemoteCopyGroup(
 1296                     rcg_name,
 1297                     self.VOLUME_3PAR_NAME,
 1298                     removeFromTarget=True),
 1299                 mock.call.removeRemoteCopyGroup(rcg_name),
 1300                 mock.call.deleteVolume(self.VOLUME_3PAR_NAME),
 1301                 mock.call.toggleRemoteCopyConfigMirror(
 1302                     'tgt',
 1303                     mirror_config=True)]
 1304             mock_client.assert_has_calls(
 1305                 self.get_id_login +
 1306                 self.standard_logout +
 1307                 self.standard_login +
 1308                 expected +
 1309                 self.standard_logout)
 1310 
 1311     @mock.patch.object(volume_types, 'get_volume_type')
 1312     def test_create_volume_replicated_sync(self, _mock_volume_types):
 1313         # setup_mock_client drive with default configuration
 1314         # and return the mock HTTP 3PAR client
 1315         conf = self.setup_configuration()
 1316         self.replication_targets[0]['replication_mode'] = 'sync'
 1317         conf.replication_device = self.replication_targets
 1318         mock_client = self.setup_driver(config=conf)
 1319         mock_client.getStorageSystemInfo.return_value = (
 1320             {'id': self.CLIENT_ID})
 1321         mock_client.getRemoteCopyGroup.side_effect = (
 1322             hpeexceptions.HTTPNotFound)
 1323         mock_client.getCPG.return_value = {'domain': None}
 1324         mock_replicated_client = self.setup_driver(config=conf)
 1325         mock_replicated_client.getStorageSystemInfo.return_value = (
 1326             {'id': self.REPLICATION_CLIENT_ID})
 1327 
 1328         _mock_volume_types.return_value = {
 1329             'name': 'replicated',
 1330             'extra_specs': {
 1331                 'replication_enabled': '<is> True',
 1332                 'replication:mode': 'sync',
 1333                 'volume_type': self.volume_type_replicated}}
 1334 
 1335         with mock.patch.object(
 1336                 hpecommon.HPE3PARCommon,
 1337                 '_create_client') as mock_create_client, \
 1338             mock.patch.object(
 1339                 hpecommon.HPE3PARCommon,
 1340                 '_create_replication_client') as mock_replication_client:
 1341             mock_create_client.return_value = mock_client
 1342             mock_replication_client.return_value = mock_replicated_client
 1343 
 1344             return_model = self.driver.create_volume(self.volume_replicated)
 1345             comment = Comment({
 1346                 "volume_type_name": "replicated",
 1347                 "display_name": "Foo Volume",
 1348                 "name": "volume-d03338a9-9115-48a3-8dfc-35cdfcdc15a7",
 1349                 "volume_type_id": "be9181f1-4040-46f2-8298-e7532f2bf9db",
 1350                 "volume_id": "d03338a9-9115-48a3-8dfc-35cdfcdc15a7",
 1351                 "qos": {},
 1352                 "type": "OpenStack"})
 1353 
 1354             backend_id = self.replication_targets[0]['backend_id']
 1355             expected = [
 1356                 mock.call.createVolume(
 1357                     self.VOLUME_3PAR_NAME,
 1358                     HPE3PAR_CPG,
 1359                     2048, {
 1360                         'comment': comment,
 1361                         'tpvv': True,
 1362                         'tdvv': False,
 1363                         'snapCPG': HPE3PAR_CPG_SNAP}),
 1364                 mock.call.getRemoteCopyGroup(self.RCG_3PAR_NAME),
 1365                 mock.call.getCPG(HPE3PAR_CPG),
 1366                 mock.call.createRemoteCopyGroup(
 1367                     self.RCG_3PAR_NAME,
 1368                     [{'userCPG': HPE3PAR_CPG_REMOTE,
 1369                       'targetName': backend_id,
 1370                       'mode': SYNC_MODE,
 1371                       'snapCPG': HPE3PAR_CPG_REMOTE}],
 1372                     {'localUserCPG': HPE3PAR_CPG,
 1373                      'localSnapCPG': HPE3PAR_CPG_SNAP}),
 1374                 mock.call.addVolumeToRemoteCopyGroup(
 1375                     self.RCG_3PAR_NAME,
 1376                     self.VOLUME_3PAR_NAME,
 1377                     [{'secVolumeName': self.VOLUME_3PAR_NAME,
 1378                       'targetName': backend_id}],
 1379                     optional={'volumeAutoCreation': True}),
 1380                 mock.call.startRemoteCopy(self.RCG_3PAR_NAME)]
 1381             mock_client.assert_has_calls(
 1382                 self.get_id_login +
 1383                 self.standard_logout +
 1384                 self.standard_login +
 1385                 expected +
 1386                 self.standard_logout)
 1387             self.assertEqual({'replication_status': 'enabled',
 1388                               'provider_location': self.CLIENT_ID},
 1389                              return_model)
 1390 
 1391     @mock.patch.object(volume_types, 'get_volume_type')
 1392     def test_create_volume_dedup_compression(self, _mock_volume_types):
 1393         # setup_mock_client drive with default configuration
 1394         # and return the mock HTTP 3PAR client
 1395 
 1396         mock_client = self.setup_driver()
 1397 
 1398         _mock_volume_types.return_value = {
 1399             'name': 'dedup_compression',
 1400             'extra_specs': {
 1401                 'cpg': HPE3PAR_CPG_QOS,
 1402                 'snap_cpg': HPE3PAR_CPG_SNAP,
 1403                 'vvs_name': self.VVS_NAME,
 1404                 'qos': self.QOS,
 1405                 'hpe3par:provisioning': 'dedup',
 1406                 'hpe3par:compression': 'True',
 1407                 'volume_type': self.volume_type_dedup_compression}}
 1408         mock_client.getStorageSystemInfo.return_value = {
 1409             'id': self.CLIENT_ID,
 1410             'serialNumber': '1234',
 1411             'licenseInfo': {
 1412                 'licenses': [{'name': 'Compression'},
 1413                              {'name': 'Thin Provisioning (102400G)'},
 1414                              {'name': 'System Reporter'}]
 1415             }
 1416         }
 1417         with mock.patch.object(hpecommon.HPE3PARCommon,
 1418                                '_create_client') as mock_create_client:
 1419             mock_create_client.return_value = mock_client
 1420 
 1421             return_model = self.driver.create_volume(
 1422                 self.volume_dedup_compression)
 1423             comment = Comment({
 1424                 "volume_type_name": "dedup_compression",
 1425                 "display_name": "Foo Volume",
 1426                 "name": "volume-d03338a9-9115-48a3-8dfc-35cdfcdc15a7",
 1427                 "volume_type_id": "d03338a9-9115-48a3-8dfc-33333333333",
 1428                 "volume_id": "d03338a9-9115-48a3-8dfc-35cdfcdc15a7",
 1429                 "qos": {},
 1430                 "type": "OpenStack"})
 1431             expectedcall = [
 1432                 mock.call.getStorageSystemInfo()]
 1433             expected = [
 1434                 mock.call.getCPG(HPE3PAR_CPG),
 1435                 mock.call.getStorageSystemInfo(),
 1436                 mock.call.createVolume(
 1437                     self.VOLUME_3PAR_NAME,
 1438                     HPE3PAR_CPG,
 1439                     16384, {
 1440                         'comment': comment,
 1441                         'tpvv': False,
 1442                         'tdvv': True,
 1443                         'compression': True,
 1444                         'snapCPG': HPE3PAR_CPG_SNAP})]
 1445             mock_client.assert_has_calls(
 1446                 self.standard_login +
 1447                 expectedcall +
 1448                 self.standard_logout +
 1449                 self.standard_login +
 1450                 expected +
 1451                 self.standard_logout)
 1452             self.assertIsNone(return_model)
 1453 
 1454     @mock.patch.object(volume_types, 'get_volume_type')
 1455     def test_create_volume_dedup(self, _mock_volume_types):
 1456         # setup_mock_client drive with default configuration
 1457         # and return the mock HTTP 3PAR client
 1458         mock_client = self.setup_driver()
 1459 
 1460         _mock_volume_types.return_value = {
 1461             'name': 'dedup',
 1462             'extra_specs': {
 1463                 'cpg': HPE3PAR_CPG_QOS,
 1464                 'snap_cpg': HPE3PAR_CPG_SNAP,
 1465                 'vvs_name': self.VVS_NAME,
 1466                 'qos': self.QOS,
 1467                 'provisioning': 'dedup',
 1468                 'volume_type': self.volume_type_dedup}}
 1469 
 1470         with mock.patch.object(hpecommon.HPE3PARCommon,
 1471                                '_create_client') as mock_create_client:
 1472             mock_create_client.return_value = mock_client
 1473 
 1474             return_model = self.driver.create_volume(self.volume_dedup)
 1475             comment = Comment({
 1476                 "volume_type_name": "dedup",
 1477                 "display_name": "Foo Volume",
 1478                 "name": "volume-d03338a9-9115-48a3-8dfc-35cdfcdc15a7",
 1479                 "volume_type_id": "d03338a9-9115-48a3-8dfc-11111111111",
 1480                 "volume_id": "d03338a9-9115-48a3-8dfc-35cdfcdc15a7",
 1481                 "qos": {},
 1482                 "type": "OpenStack"})
 1483 
 1484             expected = [
 1485                 mock.call.getCPG(HPE3PAR_CPG),
 1486                 mock.call.createVolume(
 1487                     self.VOLUME_3PAR_NAME,
 1488                     HPE3PAR_CPG,
 1489                     2048, {
 1490                         'comment': comment,
 1491                         'tpvv': False,
 1492                         'tdvv': True,
 1493                         'snapCPG': HPE3PAR_CPG_SNAP})]
 1494             mock_client.assert_has_calls(
 1495                 self.standard_login +
 1496                 expected +
 1497                 self.standard_logout)
 1498             self.assertIsNone(return_model)
 1499 
 1500     @mock.patch.object(volume_types, 'get_volume_type')
 1501     def test_create_volume_flash_cache(self, _mock_volume_types):
 1502         # Setup_mock_client drive with default configuration
 1503         # and return the mock HTTP 3PAR client
 1504         mock_client = self.setup_driver()
 1505         mock_client.getStorageSystemInfo.return_value = {'id': self.CLIENT_ID}
 1506 
 1507         _mock_volume_types.return_value = {
 1508             'name': 'flash-cache-on',
 1509             'extra_specs': {
 1510                 'cpg': HPE3PAR_CPG2,
 1511                 'snap_cpg': HPE3PAR_CPG_SNAP,
 1512                 'vvs_name': self.VVS_NAME,
 1513                 'qos': self.QOS,
 1514                 'tpvv': True,
 1515                 'tdvv': False,
 1516                 'hpe3par:flash_cache': 'true',
 1517                 'volume_type': self.volume_type_flash_cache}}
 1518 
 1519         with mock.patch.object(hpecommon.HPE3PARCommon,
 1520                                '_create_client') as mock_create_client:
 1521             mock_create_client.return_value = mock_client
 1522             mock_client.getCPG.return_value = {'domain': None}
 1523             mock_client.FLASH_CACHE_ENABLED = FLASH_CACHE_ENABLED
 1524             mock_client.FLASH_CACHE_DISABLED = FLASH_CACHE_DISABLED
 1525 
 1526             return_model = self.driver.create_volume(self.volume_flash_cache)
 1527             comment = Comment({
 1528                 "volume_type_name": "flash-cache-on",
 1529                 "display_name": "Foo Volume",
 1530                 "name": "volume-d03338a9-9115-48a3-8dfc-35cdfcdc15a7",
 1531                 "volume_type_id": "d03338a9-9115-48a3-8dfc-22222222222",
 1532                 "volume_id": "d03338a9-9115-48a3-8dfc-35cdfcdc15a7",
 1533                 "qos": {}, "type": "OpenStack"})
 1534 
 1535             expected = [
 1536                 mock.call.getCPG(HPE3PAR_CPG),
 1537                 mock.call.createVolume(
 1538                     self.VOLUME_3PAR_NAME,
 1539                     HPE3PAR_CPG,
 1540                     2048, {
 1541                         'comment': comment,
 1542                         'tpvv': True,
 1543                         'tdvv': False,
 1544                         'snapCPG': HPE3PAR_CPG_SNAP}),
 1545                 mock.call.getCPG(HPE3PAR_CPG),
 1546                 mock.call.createVolumeSet('vvs-0DM4qZEVSKON-DXN-NwVpw', None),
 1547                 mock.call.createQoSRules(
 1548                     'vvs-0DM4qZEVSKON-DXN-NwVpw',
 1549                     {'priority': 2}
 1550                 ),
 1551                 mock.call.modifyVolumeSet(
 1552                     'vvs-0DM4qZEVSKON-DXN-NwVpw', flashCachePolicy=1),
 1553                 mock.call.addVolumeToVolumeSet(
 1554                     'vvs-0DM4qZEVSKON-DXN-NwVpw',
 1555                     'osv-0DM4qZEVSKON-DXN-NwVpw')]
 1556 
 1557             mock_client.assert_has_calls(
 1558                 self.get_id_login +
 1559                 self.standard_logout +
 1560                 self.standard_login +
 1561                 expected +
 1562                 self.standard_logout)
 1563             self.assertIsNone(return_model)
 1564 
 1565     @mock.patch.object(volume_types, 'get_volume_type')
 1566     def test_unsupported_flash_cache_volume(self, _mock_volume_types):
 1567 
 1568         mock_client = self.setup_driver(wsapi_version=self.wsapi_version_312)
 1569         _mock_volume_types.return_value = {
 1570             'name': 'flash-cache-on',
 1571             'extra_specs': {
 1572                 'cpg': HPE3PAR_CPG2,
 1573                 'snap_cpg': HPE3PAR_CPG_SNAP,
 1574                 'vvs_name': self.VVS_NAME,
 1575                 'qos': self.QOS,
 1576                 'tpvv': True,
 1577                 'tdvv': False,
 1578                 'hpe3par:flash_cache': 'true',
 1579                 'volume_type': self.volume_type_flash_cache}}
 1580 
 1581         with mock.patch.object(hpecommon.HPE3PARCommon,
 1582                                '_create_client') as mock_create_client:
 1583             mock_create_client.return_value = mock_client
 1584             common = self.driver._login()
 1585 
 1586             self.assertRaises(exception.InvalidInput,
 1587                               common.get_flash_cache_policy,
 1588                               self.flash_cache_3par_keys)
 1589 
 1590     @mock.patch.object(volume_types, 'get_volume_type')
 1591     def test_retype_not_3par(self, _mock_volume_types):
 1592         _mock_volume_types.return_value = self.RETYPE_VOLUME_TYPE_1
 1593         mock_client = self.setup_driver(mock_conf=self.RETYPE_CONF)
 1594         mock_client.getVolumeSnapshots.return_value = []
 1595 
 1596         with mock.patch.object(hpecommon.HPE3PARCommon,
 1597                                '_create_client') as mock_create_client:
 1598             mock_create_client.return_value = mock_client
 1599             self.assertRaises(exception.InvalidHost,
 1600                               self.driver.retype,
 1601                               self.ctxt,
 1602                               self.RETYPE_VOLUME_INFO_0,
 1603                               self.RETYPE_VOLUME_TYPE_1,
 1604                               self.RETYPE_DIFF,
 1605                               self.RETYPE_HOST_NOT3PAR)
 1606 
 1607             expected = [mock.call.getVolumeSnapshots(self.VOLUME_3PAR_NAME),
 1608                         mock.call.getVolume(self.VOLUME_3PAR_NAME)]
 1609             mock_client.assert_has_calls(
 1610                 self.standard_login +
 1611                 expected +
 1612                 self.standard_logout)
 1613 
 1614     @mock.patch.object(volume_types, 'get_volume_type')
 1615     def test_retype_volume_not_found(self, _mock_volume_types):
 1616         _mock_volume_types.return_value = self.RETYPE_VOLUME_TYPE_1
 1617         mock_client = self.setup_driver(mock_conf=self.RETYPE_CONF)
 1618         mock_client.getVolumeSnapshots.return_value = []
 1619         mock_client.getVolume.side_effect = hpeexceptions.HTTPNotFound
 1620 
 1621         with mock.patch.object(hpecommon.HPE3PARCommon,
 1622                                '_create_client') as mock_create_client:
 1623             mock_create_client.return_value = mock_client
 1624             self.assertRaises(hpeexceptions.HTTPNotFound,
 1625                               self.driver.retype,
 1626                               self.ctxt,
 1627                               self.RETYPE_VOLUME_INFO_0,
 1628                               self.RETYPE_VOLUME_TYPE_1,
 1629                               self.RETYPE_DIFF,
 1630                               self.RETYPE_HOST)
 1631 
 1632             expected = [mock.call.getVolumeSnapshots(self.VOLUME_3PAR_NAME),
 1633                         mock.call.getVolume(self.VOLUME_3PAR_NAME)]
 1634             mock_client.assert_has_calls(
 1635                 self.standard_login +
 1636                 expected +
 1637                 self.standard_logout)
 1638 
 1639     @mock.patch.object(volume_types, 'get_volume_type')
 1640     def test_retype_specs_error_reverts_snap_cpg(self, _mock_volume_types):
 1641         _mock_volume_types.side_effect = [
 1642             self.RETYPE_VOLUME_TYPE_1, self.RETYPE_VOLUME_TYPE_0]
 1643         mock_client = self.setup_driver(mock_conf=self.RETYPE_CONF)
 1644         mock_client.getVolume.return_value = self.RETYPE_VOLUME_INFO_0
 1645 
 1646         # Fail the QOS setting to test the revert of the snap CPG rename.
 1647         mock_client.addVolumeToVolumeSet.side_effect = \
 1648             hpeexceptions.HTTPForbidden
 1649 
 1650         with mock.patch.object(hpecommon.HPE3PARCommon,
 1651                                '_create_client') as mock_create_client:
 1652             mock_create_client.return_value = mock_client
 1653             self.assertRaises(hpeexceptions.HTTPForbidden,
 1654                               self.driver.retype,
 1655                               self.ctxt,
 1656                               {'id': self.VOLUME_ID},
 1657                               self.RETYPE_VOLUME_TYPE_0,
 1658                               self.RETYPE_DIFF,
 1659                               self.RETYPE_HOST)
 1660 
 1661             old_settings = {
 1662                 'snapCPG': self.RETYPE_VOLUME_INFO_0['snapCPG'],
 1663                 'comment': self.RETYPE_VOLUME_INFO_0['comment']}
 1664             new_settings = {
 1665                 'snapCPG': (
 1666                     self.RETYPE_VOLUME_TYPE_1['extra_specs']['snap_cpg']),
 1667                 'comment': mock.ANY}
 1668 
 1669             expected = [
 1670                 mock.call.modifyVolume(self.VOLUME_3PAR_NAME, new_settings)
 1671             ]
 1672             mock_client.assert_has_calls(expected)
 1673             expected = [
 1674                 mock.call.modifyVolume(self.VOLUME_3PAR_NAME, old_settings)
 1675             ]
 1676             mock_client.assert_has_calls(expected + self.standard_logout)
 1677 
 1678     @mock.patch.object(volume_types, 'get_volume_type')
 1679     def test_retype_revert_comment(self, _mock_volume_types):
 1680         _mock_volume_types.side_effect = [
 1681             self.RETYPE_VOLUME_TYPE_2, self.RETYPE_VOLUME_TYPE_1]
 1682         mock_client = self.setup_driver(mock_conf=self.RETYPE_CONF)
 1683         mock_client.getVolume.return_value = self.RETYPE_VOLUME_INFO_1
 1684 
 1685         # Fail the QOS setting to test the revert of the snap CPG rename.
 1686         mock_client.deleteVolumeSet.side_effect = hpeexceptions.HTTPForbidden
 1687 
 1688         with mock.patch.object(hpecommon.HPE3PARCommon,
 1689                                '_create_client') as mock_create_client:
 1690             mock_create_client.return_value = mock_client
 1691             self.assertRaises(hpeexceptions.HTTPForbidden,
 1692                               self.driver.retype,
 1693                               self.ctxt,
 1694                               {'id': self.VOLUME_ID},
 1695                               self.RETYPE_VOLUME_TYPE_2,
 1696                               self.RETYPE_DIFF,
 1697                               self.RETYPE_HOST)
 1698 
 1699             original = {
 1700                 'snapCPG': self.RETYPE_VOLUME_INFO_1['snapCPG'],
 1701                 'comment': self.RETYPE_VOLUME_INFO_1['comment']}
 1702 
 1703             expected = [
 1704                 mock.call.modifyVolume('osv-0DM4qZEVSKON-DXN-NwVpw', original)]
 1705             mock_client.assert_has_calls(expected + self.standard_logout)
 1706 
 1707     @mock.patch.object(volume_types, 'get_volume_type')
 1708     def test_retype_different_array(self, _mock_volume_types):
 1709         _mock_volume_types.return_value = self.RETYPE_VOLUME_TYPE_1
 1710         mock_client = self.setup_driver(mock_conf=self.RETYPE_CONF)
 1711         mock_client.getVolumeSnapshots.return_value = []
 1712 
 1713         mock_client.getStorageSystemInfo.return_value = {
 1714             'id': self.CLIENT_ID,
 1715             'serialNumber': 'XXXXXXX'}
 1716 
 1717         with mock.patch.object(hpecommon.HPE3PARCommon,
 1718                                '_create_client') as mock_create_client:
 1719             mock_create_client.return_value = mock_client
 1720             self.assertRaises(exception.InvalidHost,
 1721                               self.driver.retype,
 1722                               self.ctxt,
 1723                               self.RETYPE_VOLUME_INFO_0,
 1724                               self.RETYPE_VOLUME_TYPE_1,
 1725                               self.RETYPE_DIFF,
 1726                               self.RETYPE_HOST)
 1727 
 1728             expected = [
 1729                 mock.call.getVolumeSnapshots(self.VOLUME_3PAR_NAME),
 1730                 mock.call.getVolume(self.VOLUME_3PAR_NAME),
 1731                 mock.call.getStorageSystemInfo()]
 1732 
 1733             mock_client.assert_has_calls(
 1734                 self.standard_login +
 1735                 expected +
 1736                 self.standard_logout)
 1737 
 1738     @mock.patch.object(volume_types, 'get_volume_type')
 1739     def test_retype_across_cpg_domains(self, _mock_volume_types):
 1740         _mock_volume_types.return_value = self.RETYPE_VOLUME_TYPE_1
 1741         mock_client = self.setup_driver(mock_conf=self.RETYPE_CONF)
 1742         mock_client.getVolumeSnapshots.return_value = []
 1743 
 1744         mock_client.getCPG.side_effect = [
 1745             {'domain': 'domain1'},
 1746             {'domain': 'domain2'},
 1747         ]
 1748 
 1749         with mock.patch.object(hpecommon.HPE3PARCommon,
 1750                                '_create_client') as mock_create_client:
 1751             mock_create_client.return_value = mock_client
 1752             self.assertRaises(exception.Invalid3PARDomain,
 1753                               self.driver.retype,
 1754                               self.ctxt,
 1755                               self.RETYPE_VOLUME_INFO_0,
 1756                               self.RETYPE_VOLUME_TYPE_1,
 1757                               self.RETYPE_DIFF,
 1758                               self.RETYPE_HOST)
 1759 
 1760             expected = [
 1761                 mock.call.getVolumeSnapshots(self.VOLUME_3PAR_NAME),
 1762                 mock.call.getVolume(self.VOLUME_3PAR_NAME),
 1763                 mock.call.getStorageSystemInfo(),
 1764                 mock.call.getCPG(self.RETYPE_VOLUME_INFO_0['userCPG']),
 1765                 mock.call.getCPG(
 1766                     self.RETYPE_VOLUME_TYPE_1['extra_specs']['cpg'])
 1767             ]
 1768             mock_client.assert_has_calls(
 1769                 self.standard_login +
 1770                 expected +
 1771                 self.standard_logout)
 1772 
 1773     @mock.patch.object(volume_types, 'get_volume_type')
 1774     def test_retype_across_snap_cpg_domains(self, _mock_volume_types):
 1775         _mock_volume_types.return_value = self.RETYPE_VOLUME_TYPE_1
 1776         mock_client = self.setup_driver(mock_conf=self.RETYPE_CONF)
 1777         mock_client.getVolumeSnapshots.return_value = []
 1778 
 1779         mock_client.getCPG.side_effect = [
 1780             {'domain': 'cpg_domain'},
 1781             {'domain': 'cpg_domain'},
 1782             {'domain': 'snap_cpg_domain_1'},
 1783         ]
 1784 
 1785         with mock.patch.object(hpecommon.HPE3PARCommon,
 1786                                '_create_client') as mock_create_client:
 1787             mock_create_client.return_value = mock_client
 1788             self.assertRaises(exception.Invalid3PARDomain,
 1789                               self.driver.retype,
 1790                               self.ctxt,
 1791                               self.RETYPE_VOLUME_INFO_0,
 1792                               self.RETYPE_VOLUME_TYPE_1,
 1793                               self.RETYPE_DIFF,
 1794                               self.RETYPE_HOST)
 1795 
 1796             expected = [
 1797                 mock.call.getVolumeSnapshots(self.VOLUME_3PAR_NAME),
 1798                 mock.call.getVolume(self.VOLUME_3PAR_NAME),
 1799                 mock.call.getStorageSystemInfo(),
 1800                 mock.call.getCPG(self.RETYPE_VOLUME_INFO_0['userCPG']),
 1801                 mock.call.getCPG(
 1802                     self.RETYPE_VOLUME_TYPE_1['extra_specs']['cpg']),
 1803                 mock.call.getCPG(
 1804                     self.RETYPE_VOLUME_TYPE_1['extra_specs']['snap_cpg'])
 1805             ]
 1806             mock_client.assert_has_calls(
 1807                 self.standard_login +
 1808                 expected +
 1809                 self.standard_logout)
 1810 
 1811     @mock.patch.object(volume_types, 'get_volume_type')
 1812     def test_retype_to_bad_persona(self, _mock_volume_types):
 1813         _mock_volume_types.return_value = self.RETYPE_VOLUME_TYPE_BAD_PERSONA
 1814         mock_client = self.setup_driver(mock_conf=self.RETYPE_CONF)
 1815         mock_client.getVolumeSnapshots.return_value = []
 1816 
 1817         with mock.patch.object(hpecommon.HPE3PARCommon,
 1818                                '_create_client') as mock_create_client:
 1819             mock_create_client.return_value = mock_client
 1820             self.assertRaises(exception.InvalidInput,
 1821                               self.driver.retype,
 1822                               self.ctxt,
 1823                               self.RETYPE_VOLUME_INFO_0,
 1824                               self.RETYPE_VOLUME_TYPE_BAD_PERSONA,
 1825                               self.RETYPE_DIFF,
 1826                               self.RETYPE_HOST)
 1827 
 1828             expected = [mock.call.getVolumeSnapshots(self.VOLUME_3PAR_NAME),
 1829                         mock.call.getVolume(self.VOLUME_3PAR_NAME)]
 1830             mock_client.assert_has_calls(
 1831                 self.standard_login +
 1832                 expected +
 1833                 self.standard_logout)
 1834 
 1835     @mock.patch.object(volume_types, 'get_volume_type')
 1836     def test_retype_tune(self, _mock_volume_types):
 1837         _mock_volume_types.return_value = self.RETYPE_VOLUME_TYPE_1
 1838         mock_client = self.setup_driver(mock_conf=self.RETYPE_CONF)
 1839 
 1840         qos_ref = qos_specs.create(self.ctxt, 'qos-specs-1', self.QOS)
 1841         type_ref = volume_types.create(self.ctxt,
 1842                                        "type1", {"qos:maxIOPS": "100",
 1843                                                  "qos:maxBWS": "50",
 1844                                                  "qos:minIOPS": "10",
 1845                                                  "qos:minBWS": "20",
 1846                                                  "qos:latency": "5",
 1847                                                  "qos:priority": "high"})
 1848         qos_specs.associate_qos_with_type(self.ctxt,
 1849                                           qos_ref['id'],
 1850                                           type_ref['id'])
 1851 
 1852         type_ref = volume_types.get_volume_type(self.ctxt, type_ref['id'])
 1853 
 1854         volume = {'id': HPE3PARBaseDriver.CLONE_ID}
 1855 
 1856         with mock.patch.object(hpecommon.HPE3PARCommon,
 1857                                '_create_client') as mock_create_client:
 1858             mock_create_client.return_value = mock_client
 1859 
 1860             retyped = self.driver.retype(
 1861                 self.ctxt, volume, type_ref, None, self.RETYPE_HOST)
 1862             self.assertTrue(retyped[0])
 1863 
 1864             expected = [
 1865                 mock.call.modifyVolume('osv-0DM4qZEVSKON-AAAAAAAAA',
 1866                                        {'comment': mock.ANY,
 1867                                         'snapCPG': 'OpenStackCPGSnap'}),
 1868                 mock.call.deleteVolumeSet('vvs-0DM4qZEVSKON-AAAAAAAAA'),
 1869                 mock.call.addVolumeToVolumeSet('myvvs',
 1870                                                'osv-0DM4qZEVSKON-AAAAAAAAA'),
 1871                 mock.call.modifyVolume('osv-0DM4qZEVSKON-AAAAAAAAA',
 1872                                        {'action': 6,
 1873                                         'userCPG': 'OpenStackCPG',
 1874                                         'conversionOperation': 1,
 1875                                         'compression': False,
 1876                                         'tuneOperation': 1}),
 1877                 mock.call.getTask(1),
 1878             ]
 1879             mock_client.assert_has_calls(expected + self.standard_logout)
 1880 
 1881     @mock.patch.object(volume_types, 'get_volume_type')
 1882     def test_retype_non_rep_type_to_rep_type(self, _mock_volume_types):
 1883 
 1884         conf = self.setup_configuration()
 1885         self.replication_targets[0]['replication_mode'] = 'periodic'
 1886         conf.replication_device = self.replication_targets
 1887         mock_client = self.setup_driver(config=conf)
 1888         mock_client.getStorageSystemInfo.return_value = (
 1889             {'id': self.CLIENT_ID})
 1890         mock_client.getRemoteCopyGroup.side_effect = (
 1891             hpeexceptions.HTTPNotFound)
 1892         mock_client.getCPG.return_value = {'domain': None}
 1893         mock_replicated_client = self.setup_driver(config=conf)
 1894         mock_client.getStorageSystemInfo.return_value = {
 1895             'id': self.REPLICATION_CLIENT_ID,
 1896             'serialNumber': '1234567'
 1897         }
 1898         mock_client.modifyVolume.return_value = ("anyResponse", {'taskid': 1})
 1899         mock_client.getTask.return_value = self.STATUS_DONE
 1900 
 1901         _mock_volume_types.return_value = {
 1902             'name': 'replicated',
 1903             'extra_specs': {
 1904                 'replication_enabled': '<is> True',
 1905                 'replication:mode': 'periodic',
 1906                 'replication:sync_period': '900',
 1907                 'volume_type': self.volume_type_replicated}}
 1908 
 1909         mock_client.getVolume.return_value = {
 1910             'name': mock.ANY,
 1911             'snapCPG': mock.ANY,
 1912             'comment': "{'display_name': 'Foo Volume'}",
 1913             'provisioningType': mock.ANY,
 1914             'userCPG': 'OpenStackCPG',
 1915             'snapCPG': 'OpenStackCPGSnap'}
 1916 
 1917         with mock.patch.object(
 1918                 hpecommon.HPE3PARCommon,
 1919                 '_create_client') as mock_create_client, \
 1920             mock.patch.object(
 1921                 hpecommon.HPE3PARCommon,
 1922                 '_create_replication_client') as mock_replication_client:
 1923             mock_create_client.return_value = mock_client
 1924             mock_replication_client.return_value = mock_replicated_client
 1925 
 1926             retyped = self.driver.retype(
 1927                 self.ctxt,
 1928                 self.volume,
 1929                 self.volume_type_replicated,
 1930                 None,
 1931                 self.RETYPE_HOST)
 1932             self.assertTrue(retyped[0])
 1933             backend_id = self.replication_targets[0]['backend_id']
 1934             expected = [
 1935                 mock.call.createRemoteCopyGroup(
 1936                     self.RCG_3PAR_NAME,
 1937                     [{'userCPG': HPE3PAR_CPG_REMOTE,
 1938                       'targetName': backend_id,
 1939                       'mode': PERIODIC_MODE,
 1940                       'snapCPG': HPE3PAR_CPG_REMOTE}],
 1941                     {'localUserCPG': HPE3PAR_CPG,
 1942                      'localSnapCPG': HPE3PAR_CPG_SNAP}),
 1943                 mock.call.addVolumeToRemoteCopyGroup(
 1944                     self.RCG_3PAR_NAME,
 1945                     self.VOLUME_3PAR_NAME,
 1946                     [{'secVolumeName': self.VOLUME_3PAR_NAME,
 1947                       'targetName': backend_id}],
 1948                     optional={'volumeAutoCreation': True}),
 1949                 mock.call.modifyRemoteCopyGroup(
 1950                     self.RCG_3PAR_NAME,
 1951                     {'targets': [{'syncPeriod': SYNC_PERIOD,
 1952                                   'targetName': backend_id}]}),
 1953                 mock.call.startRemoteCopy(self.RCG_3PAR_NAME)]
 1954             mock_client.assert_has_calls(expected + self.standard_logout)
 1955 
 1956     @mock.patch.object(volume_types, 'get_volume_type')
 1957     def test_retype_rep_type_to_non_rep_type(self, _mock_volume_types):
 1958 
 1959         conf = self.setup_configuration()
 1960         self.replication_targets[0]['replication_mode'] = 'periodic'
 1961         conf.replication_device = self.replication_targets
 1962         mock_client = self.setup_driver(config=conf)
 1963         mock_client.getStorageSystemInfo.return_value = (
 1964             {'id': self.CLIENT_ID})
 1965         mock_client.getRemoteCopyGroup.side_effect = (
 1966             hpeexceptions.HTTPNotFound)
 1967         mock_client.getCPG.return_value = {'domain': None}
 1968         mock_replicated_client = self.setup_driver(config=conf)
 1969         mock_client.getStorageSystemInfo.return_value = {
 1970             'id': self.REPLICATION_CLIENT_ID,
 1971             'serialNumber': '1234567'
 1972         }
 1973         mock_client.modifyVolume.return_value = ("anyResponse", {'taskid': 1})
 1974         mock_client.getTask.return_value = self.STATUS_DONE
 1975 
 1976         volume_1 = {'name': self.VOLUME_NAME,
 1977                     'id': self.VOLUME_ID,
 1978                     'display_name': 'Foo Volume',
 1979                     'replication_status': 'disabled',
 1980                     'provider_location': self.CLIENT_ID,
 1981                     'size': 2,
 1982                     'host': self.FAKE_CINDER_HOST,
 1983                     'volume_type': 'replicated',
 1984                     'volume_type_id': 'gold'}
 1985 
 1986         volume_type = {'name': 'replicated',
 1987                        'deleted': False,
 1988                        'updated_at': None,
 1989                        'deleted_at': None,
 1990                        'extra_specs': {'replication_enabled': 'False'},
 1991                        'id': 'silver'}
 1992 
 1993         def get_side_effect(*args):
 1994             data = {'value': None}
 1995             if args[1] == 'gold':
 1996                 data['value'] = {
 1997                     'name': 'replicated',
 1998                     'id': 'gold',
 1999                     'extra_specs': {
 2000                         'replication_enabled': '<is> True',
 2001                         'replication:mode': 'periodic',
 2002                         'replication:sync_period': '900',
 2003                         'volume_type': self.volume_type_replicated}}
 2004             elif args[1] == 'silver':
 2005                 data['value'] = {'name': 'silver',
 2006                                  'deleted': False,
 2007                                  'updated_at': None,
 2008                                  'extra_specs': {
 2009                                      'replication_enabled': 'False'},
 2010                                  'deleted_at': None,
 2011                                  'id': 'silver'}
 2012             return data['value']
 2013 
 2014         _mock_volume_types.side_effect = get_side_effect
 2015 
 2016         mock_client.getVolume.return_value = {
 2017             'name': mock.ANY,
 2018             'snapCPG': mock.ANY,
 2019             'comment': "{'display_name': 'Foo Volume'}",
 2020             'provisioningType': mock.ANY,
 2021             'userCPG': 'OpenStackCPG',
 2022             'snapCPG': 'OpenStackCPGSnap'}
 2023 
 2024         with mock.patch.object(
 2025                 hpecommon.HPE3PARCommon,
 2026                 '_create_client') as mock_create_client, \
 2027             mock.patch.object(
 2028                 hpecommon.HPE3PARCommon,
 2029                 '_create_replication_client') as mock_replication_client:
 2030             mock_create_client.return_value = mock_client
 2031             mock_replication_client.return_value = mock_replicated_client
 2032 
 2033             retyped = self.driver.retype(
 2034                 self.ctxt, volume_1, volume_type, None, self.RETYPE_HOST)
 2035             self.assertTrue(retyped[0])
 2036 
 2037             expected = [
 2038                 mock.call.stopRemoteCopy(self.RCG_3PAR_NAME),
 2039                 mock.call.removeVolumeFromRemoteCopyGroup(
 2040                     self.RCG_3PAR_NAME,
 2041                     self.VOLUME_3PAR_NAME,
 2042                     removeFromTarget=True),
 2043                 mock.call.removeRemoteCopyGroup(self.RCG_3PAR_NAME)]
 2044 
 2045             mock_client.assert_has_calls(
 2046                 self.get_id_login +
 2047                 self.standard_logout +
 2048                 self.standard_login +
 2049                 expected +
 2050                 self.standard_logout, any_order =True)
 2051 
 2052     @mock.patch.object(volume_types, 'get_volume_type')
 2053     def test_retype_rep_type_to_rep_type(self, _mock_volume_types):
 2054 
 2055         conf = self.setup_configuration()
 2056         self.replication_targets[0]['replication_mode'] = 'periodic'
 2057         conf.replication_device = self.replication_targets
 2058         mock_client = self.setup_driver(config=conf)
 2059         mock_client.getStorageSystemInfo.return_value = (
 2060             {'id': self.CLIENT_ID})
 2061         mock_client.getRemoteCopyGroup.side_effect = (
 2062             hpeexceptions.HTTPNotFound)
 2063         mock_client.getCPG.return_value = {'domain': None}
 2064         mock_replicated_client = self.setup_driver(config=conf)
 2065         mock_client.getStorageSystemInfo.return_value = {
 2066             'id': self.REPLICATION_CLIENT_ID,
 2067             'serialNumber': '1234567'
 2068         }
 2069         mock_client.modifyVolume.return_value = ("anyResponse", {'taskid': 1})
 2070         mock_client.getTask.return_value = self.STATUS_DONE
 2071 
 2072         volume_1 = {'name': self.VOLUME_NAME,
 2073                     'id': self.VOLUME_ID,
 2074                     'display_name': 'Foo Volume',
 2075                     'replication_status': 'disabled',
 2076                     'provider_location': self.CLIENT_ID,
 2077                     'size': 2,
 2078                     'host': self.FAKE_CINDER_HOST,
 2079                     'volume_type': 'replicated',
 2080                     'volume_type_id': 'gold'}
 2081 
 2082         volume_type = {'name': 'replicated',
 2083                        'deleted': False,
 2084                        'updated_at': None,
 2085                        'deleted_at': None,
 2086                        'extra_specs': {'replication_enabled': '<is> True'},
 2087                        'id': 'silver'}
 2088 
 2089         def get_side_effect(*args):
 2090             data = {'value': None}
 2091             if args[1] == 'gold':
 2092                 data['value'] = {
 2093                     'name': 'replicated',
 2094                     'id': 'gold',
 2095                     'extra_specs': {
 2096                         'replication_enabled': '<is> True',
 2097                         'replication:mode': 'periodic',
 2098                         'replication:sync_period': '900',
 2099                         'volume_type': self.volume_type_replicated}}
 2100             elif args[1] == 'silver':
 2101                 data['value'] = {
 2102                     'name': 'silver',
 2103                     'deleted': False,
 2104                     'updated_at': None,
 2105                     'extra_specs': {
 2106                         'replication_enabled': '<is> True',
 2107                         'replication:mode': 'periodic',
 2108                         'replication:sync_period': '1500',
 2109                         'volume_type': self.volume_type_replicated},
 2110                     'deleted_at': None,
 2111                     'id': 'silver'}
 2112             return data['value']
 2113 
 2114         _mock_volume_types.side_effect = get_side_effect
 2115 
 2116         mock_client.getVolume.return_value = {
 2117             'name': mock.ANY,
 2118             'snapCPG': mock.ANY,
 2119             'comment': "{'display_name': 'Foo Volume'}",
 2120             'provisioningType': mock.ANY,
 2121             'userCPG': 'OpenStackCPG',
 2122             'snapCPG': 'OpenStackCPGSnap'}
 2123 
 2124         with mock.patch.object(
 2125                 hpecommon.HPE3PARCommon,
 2126                 '_create_client') as mock_create_client, \
 2127             mock.patch.object(
 2128                 hpecommon.HPE3PARCommon,
 2129                 '_create_replication_client') as mock_replication_client:
 2130             mock_create_client.return_value = mock_client
 2131             mock_replication_client.return_value = mock_replicated_client
 2132 
 2133             backend_id = self.replication_targets[0]['backend_id']
 2134             retyped = self.driver.retype(
 2135                 self.ctxt, volume_1, volume_type, None, self.RETYPE_HOST)
 2136             self.assertTrue(retyped[0])
 2137 
 2138             expected = [
 2139                 mock.call.stopRemoteCopy(self.RCG_3PAR_NAME),
 2140                 mock.call.removeVolumeFromRemoteCopyGroup(
 2141                     self.RCG_3PAR_NAME,
 2142                     self.VOLUME_3PAR_NAME,
 2143                     removeFromTarget=True),
 2144                 mock.call.removeRemoteCopyGroup(self.RCG_3PAR_NAME),
 2145                 mock.call.createRemoteCopyGroup(
 2146                     self.RCG_3PAR_NAME,
 2147                     [{'userCPG': HPE3PAR_CPG_REMOTE,
 2148                       'targetName': backend_id,
 2149                       'mode': PERIODIC_MODE,
 2150                       'snapCPG': HPE3PAR_CPG_REMOTE}],
 2151                     {'localUserCPG': HPE3PAR_CPG,
 2152                      'localSnapCPG': HPE3PAR_CPG_SNAP}),
 2153                 mock.call.addVolumeToRemoteCopyGroup(
 2154                     self.RCG_3PAR_NAME,
 2155                     self.VOLUME_3PAR_NAME,
 2156                     [{'secVolumeName': self.VOLUME_3PAR_NAME,
 2157                       'targetName': backend_id}],
 2158                     optional={'volumeAutoCreation': True}),
 2159                 mock.call.startRemoteCopy(self.RCG_3PAR_NAME)]
 2160 
 2161             mock_client.assert_has_calls(
 2162                 self.get_id_login +
 2163                 self.standard_logout +
 2164                 self.standard_login +
 2165                 expected +
 2166                 self.standard_logout, any_order =True)
 2167 
 2168     @mock.patch.object(volume_types, 'get_volume_type')
 2169     def test_retype_qos_spec(self, _mock_volume_types):
 2170         _mock_volume_types.return_value = self.RETYPE_VOLUME_TYPE_1
 2171         mock_client = self.setup_driver(mock_conf=self.RETYPE_CONF)
 2172 
 2173         cpg = "any_cpg"
 2174         snap_cpg = "any_cpg"
 2175 
 2176         with mock.patch.object(hpecommon.HPE3PARCommon,
 2177                                '_create_client') as mock_create_client:
 2178             mock_create_client.return_value = mock_client
 2179             common = self.driver._login()
 2180             common._retype(self.volume,
 2181                            HPE3PARBaseDriver.VOLUME_3PAR_NAME,
 2182                            "old_type", "old_type_id",
 2183                            HPE3PARBaseDriver.RETYPE_HOST,
 2184                            None, cpg, cpg, snap_cpg, snap_cpg,
 2185                            True, False, False, True, None, None,
 2186                            self.QOS_SPECS, self.RETYPE_QOS_SPECS,
 2187                            None, None,
 2188                            "{}", None)
 2189 
 2190             expected = [
 2191                 mock.call.createVolumeSet('vvs-0DM4qZEVSKON-DXN-NwVpw', None),
 2192                 mock.call.createQoSRules(
 2193                     'vvs-0DM4qZEVSKON-DXN-NwVpw',
 2194                     {'ioMinGoal': 100, 'ioMaxLimit': 1000,
 2195                      'bwMinGoalKB': 25600, 'bwMaxLimitKB': 51200,
 2196                      'priority': 3,
 2197                      'latencyGoal': 25}
 2198                 ),
 2199                 mock.call.addVolumeToVolumeSet(
 2200                     'vvs-0DM4qZEVSKON-DXN-NwVpw',
 2201                     'osv-0DM4qZEVSKON-DXN-NwVpw')]
 2202             mock_client.assert_has_calls(expected)
 2203 
 2204     @mock.patch.object(volume_types, 'get_volume_type')
 2205     def test_retype_dedup(self, _mock_volume_types):
 2206         _mock_volume_types.return_value = self.RETYPE_VOLUME_TYPE_3
 2207         mock_client = self.setup_driver(mock_conf=self.RETYPE_CONF)
 2208 
 2209         cpg = "any_cpg"
 2210         snap_cpg = "any_cpg"
 2211         with mock.patch.object(hpecommon.HPE3PARCommon,
 2212                                '_create_client') as mock_create_client:
 2213             mock_create_client.return_value = mock_client
 2214             common = self.driver._login()
 2215             common._retype(self.volume,
 2216                            HPE3PARBaseDriver.VOLUME_3PAR_NAME,
 2217                            "old_type", "old_type_id",
 2218                            HPE3PARBaseDriver.RETYPE_HOST,
 2219                            None, cpg, cpg, snap_cpg, snap_cpg,
 2220                            True, False, False, True, None, None,
 2221                            self.QOS_SPECS, self.RETYPE_QOS_SPECS,
 2222                            None, None,
 2223                            "{}", None)
 2224 
 2225             expected = [
 2226                 mock.call.addVolumeToVolumeSet(u'vvs-0DM4qZEVSKON-DXN-NwVpw',
 2227                                                'osv-0DM4qZEVSKON-DXN-NwVpw'),
 2228                 mock.call.modifyVolume('osv-0DM4qZEVSKON-DXN-NwVpw',
 2229                                        {'action': 6,
 2230                                         'userCPG': 'any_cpg',
 2231                                         'conversionOperation': 3,
 2232                                         'compression': False,
 2233                                         'tuneOperation': 1}),
 2234                 mock.call.getTask(1)]
 2235             mock_client.assert_has_calls(expected)
 2236 
 2237     def test_delete_volume(self):
 2238         # setup_mock_client drive with default configuration
 2239         # and return the mock HTTP 3PAR client
 2240         mock_client = self.setup_driver()
 2241         with mock.patch.object(hpecommon.HPE3PARCommon,
 2242                                '_create_client') as mock_create_client:
 2243             mock_create_client.return_value = mock_client
 2244             self.driver.delete_volume(self.volume)
 2245 
 2246             expected = [mock.call.deleteVolume(self.VOLUME_3PAR_NAME)]
 2247 
 2248             mock_client.assert_has_calls(
 2249                 self.standard_login +
 2250                 expected +
 2251                 self.standard_logout)
 2252 
 2253     def test_delete_volume_online_clone_active(self):
 2254         # setup_mock_client drive with default configuration
 2255         # and return the mock HTTP 3PAR client
 2256         mock_client = self.setup_driver()
 2257         with mock.patch.object(hpecommon.HPE3PARCommon,
 2258                                '_create_client') as mock_create_client:
 2259             mock_create_client.return_value = mock_client
 2260             ex = hpeexceptions.HTTPConflict("Online clone is active.")
 2261             ex._error_code = 151
 2262             mock_client.deleteVolume = mock.Mock(side_effect=ex)
 2263             mock_client.isOnlinePhysicalCopy.return_value = True
 2264             self.driver.delete_volume(self.volume)
 2265 
 2266             expected = [
 2267                 mock.call.deleteVolume(self.VOLUME_3PAR_NAME),
 2268                 mock.call.isOnlinePhysicalCopy(self.VOLUME_3PAR_NAME),
 2269                 mock.call.stopOnlinePhysicalCopy(self.VOLUME_3PAR_NAME)]
 2270 
 2271             mock_client.assert_has_calls(
 2272                 self.standard_login +
 2273                 expected +
 2274                 self.standard_logout)
 2275 
 2276     def _FakeRetrying(wait_func=None,
 2277                       original_retrying = hpecommon.utils.retrying.Retrying,
 2278                       *args, **kwargs):
 2279         return original_retrying(wait_func=lambda *a, **k: 0,
 2280                                  *args, **kwargs)
 2281 
 2282     @mock.patch('retrying.Retrying', _FakeRetrying)
 2283     def test_delete_volume_online_active_done(self):
 2284         # setup_mock_client drive with default configuration
 2285         # and return the mock HTTP 3PAR client
 2286         mock_client = self.setup_driver()
 2287         ex = hpeexceptions.HTTPConflict("Online clone is active.")
 2288         ex._error_code = 151
 2289         mock_client.deleteVolume = mock.Mock(side_effect=[ex, 200])
 2290         mock_client.isOnlinePhysicalCopy.return_value = False
 2291 
 2292         with mock.patch.object(hpecommon.HPE3PARCommon,
 2293                                '_create_client') as mock_create_client:
 2294             mock_create_client.return_value = mock_client
 2295             self.driver.delete_volume(self.volume)
 2296 
 2297             expected = [
 2298                 mock.call.deleteVolume(self.VOLUME_3PAR_NAME),
 2299                 mock.call.isOnlinePhysicalCopy(self.VOLUME_3PAR_NAME),
 2300                 mock.call.deleteVolume(self.VOLUME_3PAR_NAME)]
 2301 
 2302             mock_client.assert_has_calls(
 2303                 self.standard_login +
 2304                 expected +
 2305                 self.standard_logout)
 2306 
 2307     @mock.patch.object(volume_types, 'get_volume_type')
 2308     def test_delete_volume_replicated(self, _mock_volume_types):
 2309         # setup_mock_client drive with default configuration
 2310         # and return the mock HTTP 3PAR client
 2311         mock_client = self.setup_driver()
 2312         mock_client.getStorageSystemInfo.return_value = {'id': self.CLIENT_ID}
 2313         ex = hpeexceptions.HTTPConflict("In use")
 2314         ex._error_code = 34
 2315         mock_client.deleteVolume = mock.Mock(side_effect=[ex, 200])
 2316         mock_client.findVolumeSet.return_value = self.VVS_NAME
 2317         _mock_volume_types.return_value = {
 2318             'name': 'replicated',
 2319             'extra_specs': {
 2320                 'cpg': HPE3PAR_CPG_QOS,
 2321                 'snap_cpg': HPE3PAR_CPG_SNAP,
 2322                 'vvs_name': self.VVS_NAME,
 2323                 'qos': self.QOS,
 2324                 'replication_enabled': '<is> True',
 2325                 'replication:mode': 'periodic',
 2326                 'replication:sync_period': '900',
 2327                 'volume_type': self.volume_type_replicated}}
 2328         with mock.patch.object(hpecommon.HPE3PARCommon,
 2329                                '_create_client') as mock_create_client:
 2330             mock_create_client.return_value = mock_client
 2331             self.driver.delete_volume(self.volume_replicated)
 2332 
 2333             expected = [
 2334                 mock.call.stopRemoteCopy(self.RCG_3PAR_NAME),
 2335                 mock.call.removeVolumeFromRemoteCopyGroup(
 2336                     self.RCG_3PAR_NAME,
 2337                     self.VOLUME_3PAR_NAME,
 2338                     removeFromTarget=True),
 2339                 mock.call.removeRemoteCopyGroup(self.RCG_3PAR_NAME),
 2340                 mock.call.deleteVolume(self.VOLUME_3PAR_NAME),
 2341                 mock.call.findVolumeSet(self.VOLUME_3PAR_NAME),
 2342                 mock.call.removeVolumeFromVolumeSet(self.VVS_NAME,
 2343                                                     self.VOLUME_3PAR_NAME),
 2344                 mock.call.deleteVolume(self.VOLUME_3PAR_NAME)]
 2345 
 2346             mock_client.assert_has_calls(
 2347                 self.get_id_login +
 2348                 self.standard_logout +
 2349                 self.standard_login +
 2350                 expected +
 2351                 self.standard_logout)
 2352 
 2353     def test_get_cpg_with_volume_return_usercpg(self):
 2354         # setup_mock_client drive with default configuration
 2355         # and return the mock HTTP 3PAR client
 2356         mock_client = self.setup_driver()
 2357         mock_client.getVolume.return_value = {'name': mock.ANY,
 2358                                               'userCPG': HPE3PAR_CPG2}
 2359         with mock.patch.object(hpecommon.HPE3PARCommon,
 2360                                '_create_client') as mock_create_client:
 2361             mock_create_client.return_value = mock_client
 2362             volume = {'id': HPE3PARBaseDriver.VOLUME_ID,
 2363                       'name': HPE3PARBaseDriver.VOLUME_NAME,
 2364                       'display_name': 'Foo Volume',
 2365                       'size': 2,
 2366                       'host': volume_utils.append_host(self.FAKE_HOST,
 2367                                                        HPE3PAR_CPG2)}
 2368             common = self.driver._login()
 2369             user_cpg = common.get_cpg(volume)
 2370             common = hpecommon.HPE3PARCommon(None)
 2371             vol_name = common._get_3par_vol_name(volume['id'])
 2372             self.assertEqual(HPE3PAR_CPG2, user_cpg)
 2373             expected = [mock.call.getVolume(vol_name)]
 2374 
 2375             mock_client.assert_has_calls(
 2376                 self.standard_login +
 2377                 expected)
 2378 
 2379     def test_get_cpg_with_volume_return_snapcpg(self):
 2380         # setup_mock_client drive with default configuration
 2381         # and return the mock HTTP 3PAR client
 2382         mock_client = self.setup_driver()
 2383         mock_client.getVolume.return_value = {'name': mock.ANY,
 2384                                               'snapCPG': HPE3PAR_CPG2}
 2385         with mock.patch.object(hpecommon.HPE3PARCommon,
 2386                                '_create_client') as mock_create_client:
 2387             mock_create_client.return_value = mock_client
 2388             volume = {'id': HPE3PARBaseDriver.VOLUME_ID,
 2389                       'name': HPE3PARBaseDriver.VOLUME_NAME,
 2390                       'display_name': 'Foo Volume',
 2391                       'size': 2,
 2392                       'host': volume_utils.append_host(self.FAKE_HOST,
 2393                                                        HPE3PAR_CPG2)}
 2394             common = self.driver._login()
 2395             snap_cpg = common.get_cpg(volume, allowSnap=True)
 2396             common = hpecommon.HPE3PARCommon(None)
 2397             vol_name = common._get_3par_vol_name(volume['id'])
 2398             self.assertEqual(HPE3PAR_CPG2, snap_cpg)
 2399             expected = [mock.call.getVolume(vol_name)]
 2400 
 2401             mock_client.assert_has_calls(
 2402                 self.standard_login +
 2403                 expected)
 2404 
 2405     def test_get_cpg_with_volume_return_no_cpg(self):
 2406         # setup_mock_client drive with default configuration
 2407         # and return the mock HTTP 3PAR client
 2408         mock_client = self.setup_driver()
 2409         mock_client.getVolume.return_value = {'name': mock.ANY}
 2410         with mock.patch.object(hpecommon.HPE3PARCommon,
 2411                                '_create_client') as mock_create_client:
 2412             mock_create_client.return_value = mock_client
 2413             volume = {'id': HPE3PARBaseDriver.VOLUME_ID,
 2414                       'name': HPE3PARBaseDriver.VOLUME_NAME,
 2415                       'display_name': 'Foo Volume',
 2416                       'size': 2,
 2417                       'host': volume_utils.append_host(self.FAKE_HOST,
 2418                                                        HPE3PAR_CPG2)}
 2419             common = self.driver._login()
 2420             cpg_name = common.get_cpg(volume)
 2421             common = hpecommon.HPE3PARCommon(None)
 2422             vol_name = common._get_3par_vol_name(volume['id'])
 2423             self.assertEqual(HPE3PAR_CPG2, cpg_name)
 2424             expected = [mock.call.getVolume(vol_name)]
 2425 
 2426             mock_client.assert_has_calls(
 2427                 self.standard_login +
 2428                 expected)
 2429 
 2430     def test_create_cloned_volume(self):
 2431         # setup_mock_client drive with default configuration
 2432         # and return the mock HTTP 3PAR client
 2433         mock_client = self.setup_driver()
 2434         mock_client.getVolume.return_value = {'name': mock.ANY}
 2435         mock_client.copyVolume.return_value = {'taskid': 1}
 2436         mock_client.getStorageSystemInfo.return_value = {
 2437             'id': self.CLIENT_ID,
 2438             'serialNumber': 'XXXXXXX'}
 2439 
 2440         with mock.patch.object(hpecommon.HPE3PARCommon,
 2441                                '_create_client') as mock_create_client:
 2442             mock_create_client.return_value = mock_client
 2443 
 2444             volume = {'name': HPE3PARBaseDriver.VOLUME_NAME,
 2445                       'id': HPE3PARBaseDriver.CLONE_ID,
 2446                       'display_name': 'Foo Volume',
 2447                       'size': 2,
 2448                       'host': volume_utils.append_host(self.FAKE_HOST,
 2449                                                        HPE3PAR_CPG2),
 2450                       'source_volid': HPE3PARBaseDriver.VOLUME_ID}
 2451             src_vref = {'id': HPE3PARBaseDriver.VOLUME_ID,
 2452                         'name': HPE3PARBaseDriver.VOLUME_NAME,
 2453                         'size': 2, 'status': 'available'}
 2454             model_update = self.driver.create_cloned_volume(volume, src_vref)
 2455             self.assertIsNone(model_update)
 2456             common = hpecommon.HPE3PARCommon(None)
 2457             vol_name = common._get_3par_vol_name(src_vref['id'])
 2458             # snapshot name is random
 2459             snap_name = mock.ANY
 2460             optional = mock.ANY
 2461             expectedcall = [
 2462                 mock.call.getStorageSystemInfo()]
 2463 
 2464             expected = [
 2465                 mock.call.createSnapshot(snap_name, vol_name, optional),
 2466                 mock.call.getVolume(snap_name),
 2467                 mock.call.copyVolume(
 2468                     snap_name,
 2469                     'osv-0DM4qZEVSKON-AAAAAAAAA',
 2470                     HPE3PAR_CPG2,
 2471                     {'snapCPG': 'OpenStackCPGSnap', 'tpvv': True,
 2472                      'tdvv': False, 'online': True})]
 2473 
 2474             mock_client.assert_has_calls(
 2475                 self.standard_login +
 2476                 expectedcall +
 2477                 self.standard_logout +
 2478                 self.standard_login +
 2479                 expected +
 2480                 self.standard_logout)
 2481 
 2482     @mock.patch.object(volume_types, 'get_volume_type')
 2483     def test_clone_volume_with_vvs(self, _mock_volume_types):
 2484         # Setup_mock_client drive with default configuration
 2485         # and return the mock HTTP 3PAR client
 2486         conf = self.setup_configuration()
 2487         mock_client = self.setup_driver(config=conf)
 2488 
 2489         _mock_volume_types.return_value = {
 2490             'name': 'gold',
 2491             'id': 'gold-id',
 2492             'extra_specs': {'vvs': self.VVS_NAME}}
 2493 
 2494         mock_client.getVolume.return_value = {'name': mock.ANY}
 2495         mock_client.copyVolume.return_value = {'taskid': 1}
 2496 
 2497         with mock.patch.object(hpecommon.HPE3PARCommon,
 2498                                '_create_client') as mock_create_client:
 2499             mock_create_client.return_value = mock_client
 2500             common = self.driver._login()
 2501 
 2502             volume_vvs = {'id': self.CLONE_ID,
 2503                           'name': self.VOLUME_NAME,
 2504                           'display_name': 'Foo Volume',
 2505                           'size': 2,
 2506                           'host': self.FAKE_CINDER_HOST,
 2507                           'volume_type': 'gold',
 2508                           'volume_type_id': 'gold-id'}
 2509 
 2510             src_vref = {'id': self.VOLUME_ID,
 2511                         'name': self.VOLUME_NAME,
 2512                         'size': 2, 'status': 'available',
 2513                         'volume_type': 'gold',
 2514                         'host': self.FAKE_CINDER_HOST,
 2515                         'volume_type_id': 'gold-id'}
 2516             # creation of the temp snapshot
 2517             common = hpecommon.HPE3PARCommon(conf)
 2518             snap_name = mock.ANY
 2519             vol_name = common._get_3par_vol_name(src_vref['id'])
 2520             optional = mock.ANY
 2521 
 2522             model_update = self.driver.create_cloned_volume(volume_vvs,
 2523                                                             src_vref)
 2524             self.assertIsNone(model_update)
 2525 
 2526             clone_vol_vvs = common.get_volume_settings_from_type(volume_vvs)
 2527             source_vol_vvs = common.get_volume_settings_from_type(src_vref)
 2528 
 2529             self.assertEqual(clone_vol_vvs, source_vol_vvs)
 2530 
 2531             expected = [
 2532                 mock.call.createSnapshot(snap_name, vol_name, optional),
 2533                 mock.call.getVolume(snap_name),
 2534                 mock.call.copyVolume(
 2535                     snap_name,
 2536                     'osv-0DM4qZEVSKON-AAAAAAAAA',
 2537                     'OpenStackCPG',
 2538                     {'snapCPG': 'OpenStackCPGSnap', 'tpvv': True,
 2539                      'tdvv': False, 'online': True}),
 2540                 mock.call.addVolumeToVolumeSet(
 2541                     self.VVS_NAME,
 2542                     'osv-0DM4qZEVSKON-AAAAAAAAA')]
 2543 
 2544             mock_client.assert_has_calls(
 2545                 self.standard_login +
 2546                 expected +
 2547                 self.standard_logout)
 2548 
 2549     def test_backup_iscsi_volume_with_chap_disabled(self):
 2550         # setup_mock_client drive with default configuration
 2551         # and return the mock HTTP 3PAR client
 2552         mock_client = self.setup_driver()
 2553         mock_client.getVolume.return_value = {'name': mock.ANY}
 2554         mock_client.copyVolume.return_value = {'taskid': 1}
 2555         mock_client.getVolumeMetaData.side_effect = hpeexceptions.HTTPNotFound
 2556 
 2557         with mock.patch.object(hpecommon.HPE3PARCommon,
 2558                                '_create_client') as mock_create_client:
 2559             mock_create_client.return_value = mock_client
 2560 
 2561             volume = {'name': HPE3PARBaseDriver.VOLUME_NAME,
 2562                       'id': HPE3PARBaseDriver.CLONE_ID,
 2563                       'display_name': 'Foo Volume',
 2564                       'size': 2,
 2565                       'host': volume_utils.append_host(self.FAKE_HOST,
 2566                                                        HPE3PAR_CPG2)}
 2567             src_vref = {'id': HPE3PARBaseDriver.VOLUME_ID,
 2568                         'name': HPE3PARBaseDriver.VOLUME_NAME,
 2569                         'size': 2, 'status': 'backing-up'}
 2570             model_update = self.driver.create_cloned_volume(volume, src_vref)
 2571             self.assertIsNone(model_update)
 2572             # creation of the temp snapshot
 2573             common = hpecommon.HPE3PARCommon(None)
 2574             snap_name = mock.ANY
 2575             vol_name = common._get_3par_vol_name(src_vref['id'])
 2576             optional = mock.ANY
 2577 
 2578             expected = [
 2579                 mock.call.createSnapshot(snap_name, vol_name, optional),
 2580                 mock.call.getVolume(snap_name),
 2581                 mock.call.copyVolume(
 2582                     snap_name,
 2583                     'osv-0DM4qZEVSKON-AAAAAAAAA',
 2584                     HPE3PAR_CPG2,
 2585                     {'snapCPG': 'OpenStackCPGSnap', 'tpvv': True,
 2586                      'tdvv': False, 'online': True})]
 2587 
 2588             mock_client.assert_has_calls(
 2589                 self.standard_login +
 2590                 expected +
 2591                 self.standard_logout)
 2592 
 2593     def test_create_clone_iscsi_volume_with_chap_disabled(self):
 2594         # setup_mock_client drive with default configuration
 2595         # and return the mock HTTP 3PAR client
 2596         config = self.setup_configuration()
 2597         config.hpe3par_iscsi_chap_enabled = True
 2598         mock_client = self.setup_driver(config=config)
 2599         mock_client.getVolume.return_value = {'name': mock.ANY}
 2600         mock_client.copyVolume.return_value = {'taskid': 1}
 2601         mock_client.getVolumeMetaData.side_effect = hpeexceptions.HTTPNotFound
 2602 
 2603         with mock.patch.object(hpecommon.HPE3PARCommon,
 2604                                '_create_client') as mock_create_client:
 2605             mock_create_client.return_value = mock_client
 2606 
 2607             volume = {'name': HPE3PARBaseDriver.VOLUME_NAME,
 2608                       'id': HPE3PARBaseDriver.CLONE_ID,
 2609                       'display_name': 'Foo Volume',
 2610                       'size': 2,
 2611                       'host': volume_utils.append_host(self.FAKE_HOST,
 2612                                                        HPE3PAR_CPG2)}
 2613             src_vref = {'id': HPE3PARBaseDriver.VOLUME_ID,
 2614                         'name': HPE3PARBaseDriver.VOLUME_NAME,
 2615                         'size': 2, 'status': 'available'}
 2616             model_update = self.driver.create_cloned_volume(volume, src_vref)
 2617             self.assertIsNone(model_update)
 2618 
 2619             common = hpecommon.HPE3PARCommon(None)
 2620             snap_name = mock.ANY
 2621             vol_name = common._get_3par_vol_name(src_vref['id'])
 2622             optional = mock.ANY
 2623 
 2624             expected = [
 2625                 mock.call.getVolumeMetaData(vol_name,
 2626                                             'HPQ-cinder-CHAP-name'),
 2627                 mock.call.createSnapshot(snap_name, vol_name, optional),
 2628                 mock.call.getVolume(snap_name),
 2629                 mock.call.copyVolume(
 2630                     snap_name,
 2631                     'osv-0DM4qZEVSKON-AAAAAAAAA',
 2632                     HPE3PAR_CPG2,
 2633                     {'snapCPG': 'OpenStackCPGSnap', 'tpvv': True,
 2634                      'tdvv': False, 'online': True})]
 2635 
 2636             mock_client.assert_has_calls(
 2637                 self.standard_login +
 2638                 expected +
 2639                 self.standard_logout)
 2640 
 2641     def test_backup_iscsi_volume_with_chap_enabled(self):
 2642         # setup_mock_client drive with default configuration
 2643         # and return the mock HTTP 3PAR client
 2644         config = self.setup_configuration()
 2645         config.hpe3par_iscsi_chap_enabled = True
 2646         mock_client = self.setup_driver(config=config)
 2647         mock_client.getVolume.return_value = {'name': mock.ANY}
 2648         task_id = 1
 2649         mock_client.copyVolume.return_value = {'taskid': task_id}
 2650         mock_client.getVolumeMetaData.return_value = {
 2651             'value': 'random-key'}
 2652         mock_client.getTask.return_value = {'status': 1}
 2653         with mock.patch.object(hpecommon.HPE3PARCommon,
 2654                                '_create_client') as mock_create_client:
 2655             mock_create_client.return_value = mock_client
 2656 
 2657             volume = {'name': HPE3PARBaseDriver.VOLUME_NAME,
 2658                       'id': HPE3PARBaseDriver.CLONE_ID,
 2659                       'display_name': 'Foo Volume',
 2660                       'size': 5,
 2661                       'host': volume_utils.append_host(self.FAKE_HOST,
 2662                                                        HPE3PAR_CPG2),
 2663                       'source_volid': HPE3PARBaseDriver.VOLUME_ID}
 2664             src_vref = {'id': HPE3PARBaseDriver.VOLUME_ID,
 2665                         'name': HPE3PARBaseDriver.VOLUME_NAME,
 2666                         'size': 5, 'status': 'backing-up'}
 2667             model_update = self.driver.create_cloned_volume(volume, src_vref)
 2668             self.assertIsNone(model_update)
 2669 
 2670             common = hpecommon.HPE3PARCommon(None)
 2671             vol_name = common._get_3par_vol_name(volume['id'])
 2672             src_vol_name = common._get_3par_vol_name(src_vref['id'])
 2673             optional = {'priority': 1}
 2674             comment = mock.ANY
 2675 
 2676             expected = [
 2677                 mock.call.getVolumeMetaData(src_vol_name,
 2678                                             'HPQ-cinder-CHAP-name'),
 2679                 mock.call.createVolume(vol_name, 'fakepool',
 2680                                        5120, comment),
 2681                 mock.call.copyVolume(
 2682                     src_vol_name,
 2683                     vol_name,
 2684                     None,
 2685                     optional=optional),
 2686                 mock.call.getTask(task_id),
 2687             ]
 2688 
 2689             mock_client.assert_has_calls(
 2690                 self.standard_login +
 2691                 expected +
 2692                 self.standard_logout)
 2693 
 2694     def test_create_cloned_volume_offline_copy(self):
 2695         # setup_mock_client drive with default configuration
 2696         # and return the mock HTTP 3PAR client
 2697         mock_client = self.setup_driver()
 2698         mock_client.getVolume.return_value = {'name': mock.ANY}
 2699         task_id = 1
 2700         mock_client.copyVolume.return_value = {'taskid': task_id}
 2701         mock_client.getTask.return_value = {'status': 1}
 2702         with mock.patch.object(hpecommon.HPE3PARCommon,
 2703                                '_create_client') as mock_create_client:
 2704             mock_create_client.return_value = mock_client
 2705 
 2706             volume = {'name': HPE3PARBaseDriver.VOLUME_NAME,
 2707                       'id': HPE3PARBaseDriver.CLONE_ID,
 2708                       'display_name': 'Foo Volume',
 2709                       'size': 5,
 2710                       'host': volume_utils.append_host(self.FAKE_HOST,
 2711                                                        HPE3PAR_CPG2),
 2712                       'source_volid': HPE3PARBaseDriver.VOLUME_ID}
 2713             src_vref = {'id': HPE3PARBaseDriver.VOLUME_ID,
 2714                         'name': HPE3PARBaseDriver.VOLUME_NAME,
 2715                         'size': 2, 'status': 'available'}
 2716             model_update = self.driver.create_cloned_volume(volume, src_vref)
 2717             self.assertIsNone(model_update)
 2718 
 2719             common = hpecommon.HPE3PARCommon(None)
 2720             vol_name = common._get_3par_vol_name(volume['id'])
 2721             src_vol_name = common._get_3par_vol_name(src_vref['id'])
 2722             optional = {'priority': 1}
 2723             comment = mock.ANY
 2724 
 2725             expected = [
 2726                 mock.call.createVolume(vol_name, 'fakepool',
 2727                                        5120, comment),
 2728                 mock.call.copyVolume(
 2729                     src_vol_name,
 2730                     vol_name,
 2731                     None,
 2732                     optional=optional),
 2733                 mock.call.getTask(task_id),
 2734             ]
 2735 
 2736             mock_client.assert_has_calls(
 2737                 self.standard_login +
 2738                 expected +
 2739                 self.standard_logout)
 2740 
 2741     @mock.patch.object(volume_types, 'get_volume_type')
 2742     def test_create_cloned_qos_volume(self, _mock_volume_types):
 2743         _mock_volume_types.return_value = self.RETYPE_VOLUME_TYPE_2
 2744         mock_client = self.setup_driver()
 2745         mock_client.getVolume.return_value = {'name': mock.ANY}
 2746         mock_client.copyVolume.return_value = {'taskid': 1}
 2747         with mock.patch.object(hpecommon.HPE3PARCommon,
 2748                                '_create_client') as mock_create_client:
 2749             mock_create_client.return_value = mock_client
 2750 
 2751             src_vref = {'id': HPE3PARBaseDriver.CLONE_ID,
 2752                         'name': HPE3PARBaseDriver.VOLUME_NAME,
 2753                         'size': 2, 'status': 'available'}
 2754             volume = self.volume_qos.copy()
 2755             host = "TEST_HOST"
 2756             pool = "TEST_POOL"
 2757             volume_host = volume_utils.append_host(host, pool)
 2758             expected_cpg = pool
 2759             volume['id'] = HPE3PARBaseDriver.VOLUME_ID
 2760             volume['host'] = volume_host
 2761             volume['source_volid'] = HPE3PARBaseDriver.CLONE_ID
 2762             model_update = self.driver.create_cloned_volume(volume, src_vref)
 2763             self.assertIsNone(model_update)
 2764             # creation of the temp snapshot
 2765             common = hpecommon.HPE3PARCommon(None)
 2766             snap_name = mock.ANY
 2767             vol_name = common._get_3par_vol_name(src_vref['id'])
 2768             optional = mock.ANY
 2769 
 2770             expected = [
 2771                 mock.call.getCPG(expected_cpg),
 2772                 mock.call.createSnapshot(snap_name, vol_name, optional),
 2773                 mock.call.getVolume(snap_name),
 2774                 mock.call.copyVolume(
 2775                     snap_name,
 2776                     self.VOLUME_3PAR_NAME,
 2777                     expected_cpg,
 2778                     {'snapCPG': 'OpenStackCPGSnap', 'tpvv': True,
 2779                      'tdvv': False, 'online': True}),
 2780                 mock.call.addVolumeToVolumeSet(
 2781                     'yourvvs',
 2782                     'osv-0DM4qZEVSKON-DXN-NwVpw')]
 2783 
 2784             mock_client.assert_has_calls(
 2785                 self.standard_login +
 2786                 expected +
 2787                 self.standard_logout)
 2788 
 2789     def test_migrate_volume(self):
 2790 
 2791         conf = {
 2792             'getStorageSystemInfo.return_value': {
 2793                 'id': self.CLIENT_ID,
 2794                 'serialNumber': '1234'},
 2795             'getTask.return_value': {
 2796                 'status': 1},
 2797             'getCPG.return_value': {},
 2798             'copyVolume.return_value': {'taskid': 1},
 2799             'getVolume.return_value': self.RETYPE_VOLUME_INFO_1
 2800         }
 2801 
 2802         mock_client = self.setup_driver(mock_conf=conf)
 2803 
 2804         mock_client.getVolume.return_value = self.MANAGE_VOLUME_INFO
 2805         mock_client.modifyVolume.return_value = ("anyResponse", {'taskid': 1})
 2806         mock_client.getTask.return_value = self.STATUS_DONE
 2807 
 2808         volume = {'name': HPE3PARBaseDriver.VOLUME_NAME,
 2809                   'id': HPE3PARBaseDriver.CLONE_ID,
 2810                   'display_name': 'Foo Volume',
 2811                   'volume_type_id': None,
 2812                   'size': 2,
 2813                   'status': 'available',
 2814                   'host': HPE3PARBaseDriver.FAKE_HOST,
 2815                   'source_volid': HPE3PARBaseDriver.VOLUME_ID}
 2816         with mock.patch.object(hpecommon.HPE3PARCommon,
 2817                                '_create_client') as mock_create_client:
 2818             mock_create_client.return_value = mock_client
 2819             common = self.driver._login()
 2820 
 2821             volume_name_3par = common._encode_name(volume['id'])
 2822 
 2823             loc_info = 'HPE3PARDriver:1234:CPG-FC1'
 2824             host = {'host': 'stack@3parfc1#CPG-FC1',
 2825                     'capabilities': {'location_info': loc_info}}
 2826 
 2827             result = self.driver.migrate_volume(context.get_admin_context(),
 2828                                                 volume, host)
 2829             self.assertIsNotNone(result)
 2830             self.assertEqual((True, None), result)
 2831 
 2832             osv_matcher = 'osv-' + volume_name_3par
 2833 
 2834             comment = Comment({
 2835                 "display_name": "Foo Volume",
 2836                 "qos": {},
 2837             })
 2838 
 2839             expected = [
 2840                 mock.call.modifyVolume(
 2841                     osv_matcher,
 2842                     {'comment': comment,
 2843                      'snapCPG': HPE3PAR_CPG_SNAP}),
 2844                 mock.call.modifyVolume(osv_matcher,
 2845                                        {'action': 6,
 2846                                         'userCPG': 'CPG-FC1',
 2847                                         'conversionOperation': 1,
 2848                                         'compression': False,
 2849                                         'tuneOperation': 1}),
 2850                 mock.call.getTask(mock.ANY)
 2851             ]
 2852 
 2853             mock_client.assert_has_calls(expected + self.standard_logout)
 2854 
 2855     @mock.patch.object(volume_types, 'get_volume_type')
 2856     def test_migrate_volume_with_type(self, _mock_volume_types):
 2857         _mock_volume_types.return_value = self.RETYPE_VOLUME_TYPE_2
 2858 
 2859         conf = {
 2860             'getStorageSystemInfo.return_value': {
 2861                 'id': self.CLIENT_ID,
 2862                 'serialNumber': '1234'},
 2863             'getTask.return_value': {
 2864                 'status': 1},
 2865             'getCPG.return_value': {},
 2866             'copyVolume.return_value': {'taskid': 1},
 2867             'getVolume.return_value': self.RETYPE_VOLUME_INFO_1
 2868         }
 2869 
 2870         mock_client = self.setup_driver(mock_conf=conf)
 2871 
 2872         mock_client.getVolume.return_value = self.MANAGE_VOLUME_INFO
 2873         mock_client.modifyVolume.return_value = ("anyResponse", {'taskid': 1})
 2874         mock_client.getTask.return_value = self.STATUS_DONE
 2875 
 2876         display_name = 'Foo Volume'
 2877         volume = {'name': HPE3PARBaseDriver.VOLUME_NAME,
 2878                   'id': HPE3PARBaseDriver.CLONE_ID,
 2879                   'display_name': display_name,
 2880                   "volume_type_id": self.RETYPE_VOLUME_TYPE_2['id'],
 2881                   'size': 2,
 2882                   'status': 'available',
 2883                   'host': HPE3PARBaseDriver.FAKE_HOST,
 2884                   'source_volid': HPE3PARBaseDriver.VOLUME_ID}
 2885 
 2886         with mock.patch.object(hpecommon.HPE3PARCommon,
 2887                                '_create_client') as mock_create_client:
 2888             mock_create_client.return_value = mock_client
 2889             common = self.driver._login()
 2890 
 2891             volume_name_3par = common._encode_name(volume['id'])
 2892 
 2893             loc_info = 'HPE3PARDriver:1234:CPG-FC1'
 2894             instance_host = 'stack@3parfc1#CPG-FC1'
 2895             host = {'host': instance_host,
 2896                     'capabilities': {'location_info': loc_info}}
 2897 
 2898             result = self.driver.migrate_volume(context.get_admin_context(),
 2899                                                 volume, host)
 2900             self.assertIsNotNone(result)
 2901             # when the host and pool are the same we'll get None
 2902             self.assertEqual((True, None), result)
 2903 
 2904             osv_matcher = 'osv-' + volume_name_3par
 2905 
 2906             expected_comment = Comment({
 2907                 "display_name": display_name,
 2908                 "volume_type_id": self.RETYPE_VOLUME_TYPE_2['id'],
 2909                 "volume_type_name": self.RETYPE_VOLUME_TYPE_2['name'],
 2910                 "vvs": self.RETYPE_VOLUME_TYPE_2['extra_specs']['vvs']
 2911             })
 2912 
 2913             expected = [
 2914                 mock.call.modifyVolume(
 2915                     osv_matcher,
 2916                     {'comment': expected_comment,
 2917                      'snapCPG': self.RETYPE_VOLUME_TYPE_2
 2918                      ['extra_specs']['snap_cpg']}),
 2919                 mock.call.modifyVolume(
 2920                     osv_matcher,
 2921                     {'action': 6,
 2922                      'userCPG': 'CPG-FC1',
 2923                      'conversionOperation': 1,
 2924                      'tuneOperation': 1,
 2925                      'compression': False}),
 2926                 mock.call.getTask(mock.ANY)
 2927             ]
 2928 
 2929             mock_client.assert_has_calls(
 2930                 expected +
 2931                 self.standard_logout)
 2932 
 2933     def test_migrate_volume_diff_host(self):
 2934         conf = {
 2935             'getStorageSystemInfo.return_value': {
 2936                 'id': self.CLIENT_ID,
 2937                 'serialNumber': 'different'},
 2938         }
 2939 
 2940         mock_client = self.setup_driver(mock_conf=conf)
 2941 
 2942         volume = {'name': HPE3PARBaseDriver.VOLUME_NAME,
 2943                   'id': HPE3PARBaseDriver.CLONE_ID,
 2944                   'display_name': 'Foo Volume',
 2945                   'volume_type_id': None,
 2946                   'size': 2,
 2947                   'status': 'available',
 2948                   'host': HPE3PARBaseDriver.FAKE_HOST,
 2949                   'source_volid': HPE3PARBaseDriver.VOLUME_ID}
 2950 
 2951         loc_info = 'HPE3PARDriver:1234:CPG-FC1'
 2952         host = {'host': 'stack@3parfc1',
 2953                 'capabilities': {'location_info': loc_info}}
 2954 
 2955         with mock.patch.object(hpecommon.HPE3PARCommon,
 2956                                '_create_client') as mock_create_client:
 2957             mock_create_client.return_value = mock_client
 2958             result = self.driver.migrate_volume(context.get_admin_context(),
 2959                                                 volume, host)
 2960             self.assertIsNotNone(result)
 2961             self.assertEqual((False, None), result)
 2962 
 2963     @mock.patch.object(volume_types, 'get_volume_type')
 2964     def test_migrate_volume_diff_domain(self, _mock_volume_types):
 2965         _mock_volume_types.return_value = self.volume_type
 2966 
 2967         conf = {
 2968             'getStorageSystemInfo.return_value': {
 2969                 'id': self.CLIENT_ID,
 2970                 'serialNumber': '1234'},
 2971             'getTask.return_value': {
 2972                 'status': 1},
 2973             'getCPG.return_value': {},
 2974             'copyVolume.return_value': {'taskid': 1},
 2975             'getVolume.return_value': self.RETYPE_VOLUME_INFO_1
 2976         }
 2977 
 2978         mock_client = self.setup_driver(mock_conf=conf)
 2979 
 2980         mock_client.getVolume.return_value = self.MANAGE_VOLUME_INFO
 2981         mock_client.modifyVolume.return_value = ("anyResponse", {'taskid': 1})
 2982         mock_client.getTask.return_value = self.STATUS_DONE
 2983 
 2984         volume = {'name': HPE3PARBaseDriver.VOLUME_NAME,
 2985                   'id': HPE3PARBaseDriver.CLONE_ID,
 2986                   'display_name': 'Foo Volume',
 2987                   'volume_type_id': None,
 2988                   'size': 2,
 2989                   'status': 'available',
 2990                   'host': HPE3PARBaseDriver.FAKE_HOST,
 2991                   'source_volid': HPE3PARBaseDriver.VOLUME_ID}
 2992 
 2993         with mock.patch.object(hpecommon.HPE3PARCommon,
 2994                                '_create_client') as mock_create_client:
 2995             mock_create_client.return_value = mock_client
 2996             common = self.driver._login()
 2997 
 2998             volume_name_3par = common._encode_name(volume['id'])
 2999 
 3000             loc_info = 'HPE3PARDriver:1234:CPG-FC1'
 3001             host = {'host': 'stack@3parfc1#CPG-FC1',
 3002                     'capabilities': {'location_info': loc_info}}
 3003 
 3004             result = self.driver.migrate_volume(context.get_admin_context(),
 3005                                                 volume, host)
 3006             self.assertIsNotNone(result)
 3007             self.assertEqual((True, None), result)
 3008 
 3009             osv_matcher = 'osv-' + volume_name_3par
 3010 
 3011         comment = Comment({"qos": {}, "display_name": "Foo Volume"})
 3012 
 3013         expected = [
 3014             mock.call.modifyVolume(
 3015                 osv_matcher,
 3016                 {'comment': comment,
 3017                  'snapCPG': HPE3PAR_CPG_SNAP}),
 3018             mock.call.modifyVolume(osv_matcher,
 3019                                    {'action': 6,
 3020                                     'userCPG': 'CPG-FC1',
 3021                                     'conversionOperation': 1,
 3022                                     'tuneOperation': 1,
 3023                                     'compression': False}),
 3024             mock.call.getTask(mock.ANY),
 3025         ]
 3026 
 3027         mock_client.assert_has_calls(expected + self.standard_logout)
 3028 
 3029     @mock.patch.object(volume_types, 'get_volume_type')
 3030     def test_migrate_volume_attached_diff_protocol(self, _mock_volume_types):
 3031         _mock_volume_types.return_value = self.RETYPE_VOLUME_TYPE_1
 3032         mock_client = self.setup_driver(mock_conf=self.RETYPE_CONF)
 3033 
 3034         protocol = "OTHER"
 3035 
 3036         volume = {'name': HPE3PARBaseDriver.VOLUME_NAME,
 3037                   'volume_type_id': None,
 3038                   'id': HPE3PARBaseDriver.CLONE_ID,
 3039                   'display_name': 'Foo Volume',
 3040                   'size': 2,
 3041                   'status': 'in-use',
 3042                   'host': HPE3PARBaseDriver.FAKE_HOST,
 3043                   'source_volid': HPE3PARBaseDriver.VOLUME_ID}
 3044 
 3045         loc_info = 'HPE3PARDriver:1234567:CPG-FC1'
 3046         host = {'host': 'stack@3parfc1',
 3047                 'capabilities': {'location_info': loc_info,
 3048                                  'storage_protocol': protocol}}
 3049 
 3050         result = self.driver.migrate_volume(context.get_admin_context(),
 3051                                             volume, host)
 3052 
 3053         self.assertIsNotNone(result)
 3054         self.assertEqual((False, None), result)
 3055         expected = []
 3056         mock_client.assert_has_calls(expected)
 3057 
 3058     def test_update_migrated_volume(self):
 3059         mock_client = self.setup_driver()
 3060         fake_old_volume = {'id': self.VOLUME_ID}
 3061         provider_location = 'foo'
 3062         fake_new_volume = {'id': self.CLONE_ID,
 3063                            '_name_id': self.CLONE_ID,
 3064                            'provider_location': provider_location}
 3065         original_volume_status = 'available'
 3066         with mock.patch.object(hpecommon.HPE3PARCommon,
 3067                                '_create_client') as mock_create_client:
 3068             mock_create_client.return_value = mock_client
 3069             actual_update = self.driver.update_migrated_volume(
 3070                 context.get_admin_context(), fake_old_volume,
 3071                 fake_new_volume, original_volume_status)
 3072 
 3073             expected_update = {'_name_id': None,
 3074                                'provider_location': None}
 3075             self.assertEqual(expected_update, actual_update)
 3076 
 3077             expected = [
 3078                 mock.call.modifyVolume(
 3079                     'osv-0DM4qZEVSKON-DXN-NwVpw',
 3080                     {'newName': u'tsv-0DM4qZEVSKON-DXN-NwVpw'}),
 3081                 mock.call.modifyVolume(
 3082                     'osv-0DM4qZEVSKON-AAAAAAAAA',
 3083                     {'newName': u'osv-0DM4qZEVSKON-DXN-NwVpw'}),
 3084                 mock.call.modifyVolume(
 3085                     'tsv-0DM4qZEVSKON-DXN-NwVpw',
 3086                     {'newName': u'osv-0DM4qZEVSKON-AAAAAAAAA'})
 3087             ]
 3088 
 3089             mock_client.assert_has_calls(
 3090                 self.standard_login +
 3091                 expected +
 3092                 self.standard_logout)
 3093 
 3094     def test_update_migrated_volume_attached(self):
 3095         mock_client = self.setup_driver()
 3096         fake_old_volume = {'id': self.VOLUME_ID}
 3097         provider_location = 'foo'
 3098         fake_new_volume = {'id': self.CLONE_ID,
 3099                            '_name_id': self.CLONE_ID,
 3100                            'provider_location': provider_location}
 3101         original_volume_status = 'in-use'
 3102 
 3103         with mock.patch.object(hpecommon.HPE3PARCommon,
 3104                                '_create_client') as mock_create_client:
 3105             mock_create_client.return_value = mock_client
 3106             actual_update = self.driver.update_migrated_volume(
 3107                 context.get_admin_context(), fake_old_volume,
 3108                 fake_new_volume, original_volume_status)
 3109 
 3110             expected_update = {'_name_id': fake_new_volume['_name_id'],
 3111                                'provider_location': provider_location}
 3112             self.assertEqual(expected_update, actual_update)
 3113 
 3114     def test_create_snapshot(self):
 3115         # setup_mock_client drive with default configuration
 3116         # and return the mock HTTP 3PAR client
 3117         mock_client = self.setup_driver()
 3118         with mock.patch.object(hpecommon.HPE3PARCommon,
 3119                                '_create_client') as mock_create_client:
 3120             mock_create_client.return_value = mock_client
 3121             self.driver.create_snapshot(self.snapshot)
 3122 
 3123             comment = Comment({
 3124                 "volume_id": "761fc5e5-5191-4ec7-aeba-33e36de44156",
 3125                 "display_name": "fakesnap",
 3126                 "description": "test description name",
 3127                 "volume_name":
 3128                 "volume-d03338a9-9115-48a3-8dfc-35cdfcdc15a7",
 3129             })
 3130             expected = [
 3131                 mock.call.createSnapshot(
 3132                     'oss-L4I73ONuTci9Fd4ceij-MQ',
 3133                     'osv-dh-F5VGRTseuujPjbeRBVg',
 3134                     {
 3135                         'comment': comment,
 3136                         'readOnly': True})]
 3137 
 3138             mock_client.assert_has_calls(
 3139                 self.standard_login +
 3140                 expected +
 3141                 self.standard_logout)
 3142 
 3143     def test_revert_to_snapshot(self):
 3144         # setup_mock_client drive with default configuration
 3145         # and return the mock HTTP 3PAR client
 3146         volume = {'name': self.VOLUME_NAME,
 3147                   'id': self.VOLUME_ID_SNAP,
 3148                   'display_name': 'Foo Volume',
 3149                   'size': 2,
 3150                   'host': self.FAKE_CINDER_HOST,
 3151                   'volume_type': None,
 3152                   'volume_type_id': None}
 3153 
 3154         mock_client = self.setup_driver()
 3155         mock_client.isOnlinePhysicalCopy.return_value = False
 3156         mock_client.promoteVirtualCopy.return_value = {'taskid': 1}
 3157         mock_client.getTask.return_value = {'status': 1}
 3158 
 3159         with mock.patch.object(hpecommon.HPE3PARCommon,
 3160                                '_create_client') as mock_create_client:
 3161             mock_create_client.return_value = mock_client
 3162             self.driver.revert_to_snapshot(self.ctxt, volume, self.snapshot)
 3163 
 3164             expected = [
 3165                 mock.call.isOnlinePhysicalCopy('osv-dh-F5VGRTseuujPjbeRBVg'),
 3166                 mock.call.promoteVirtualCopy('oss-L4I73ONuTci9Fd4ceij-MQ',
 3167                                              optional={}),
 3168                 mock.call.getTask(1)
 3169             ]
 3170 
 3171             mock_client.assert_has_calls(
 3172                 self.standard_login +
 3173                 expected +
 3174                 self.standard_logout)
 3175 
 3176     @mock.patch.object(volume_types, 'get_volume_type')
 3177     def test_revert_to_snapshot_replicated_volume(self, _mock_volume_types):
 3178 
 3179         _mock_volume_types.return_value = {
 3180             'name': 'replicated',
 3181             'extra_specs': {
 3182                 'replication_enabled': '<is> True',
 3183                 'volume_type': self.volume_type_replicated}}
 3184 
 3185         mock_client = self.setup_driver()
 3186         mock_client.isOnlinePhysicalCopy.return_value = True
 3187         mock_client.getStorageSystemInfo.return_value = mock.ANY
 3188         mock_client.promoteVirtualCopy.return_value = {'taskid': 1}
 3189         mock_client.getTask.return_value = {'status': 1}
 3190 
 3191         with mock.patch.object(hpecommon.HPE3PARCommon,
 3192                                '_create_client') as mock_create_client:
 3193             mock_create_client.return_value = mock_client
 3194             self.driver.revert_to_snapshot(
 3195                 self.ctxt,
 3196                 self.volume_replicated,
 3197                 self.snapshot)
 3198             expected = [
 3199                 mock.call.stopRemoteCopy('rcg-0DM4qZEVSKON-DXN-N'),
 3200                 mock.call.isOnlinePhysicalCopy('osv-0DM4qZEVSKON-DXN-NwVpw'),
 3201                 mock.call.promoteVirtualCopy(
 3202                     'oss-L4I73ONuTci9Fd4ceij-MQ',
 3203                     optional={'online': True, 'allowRemoteCopyParent': True}),
 3204                 mock.call.getTask(1),
 3205                 mock.call.startRemoteCopy('rcg-0DM4qZEVSKON-DXN-N')
 3206             ]
 3207             mock_client.assert_has_calls(
 3208                 self.get_id_login +
 3209                 self.standard_logout +
 3210                 self.standard_login +
 3211                 expected +
 3212                 self.standard_logout)
 3213 
 3214     def test_delete_snapshot(self):
 3215         # setup_mock_client drive with default configuration
 3216         # and return the mock HTTP 3PAR client
 3217         mock_client = self.setup_driver()
 3218         with mock.patch.object(hpecommon.HPE3PARCommon,
 3219                                '_create_client') as mock_create_client:
 3220             mock_create_client.return_value = mock_client
 3221             self.driver.delete_snapshot(self.snapshot)
 3222 
 3223             expected = [
 3224                 mock.call.deleteVolume('oss-L4I73ONuTci9Fd4ceij-MQ')]
 3225 
 3226             mock_client.assert_has_calls(
 3227                 self.standard_login +
 3228                 expected +
 3229                 self.standard_logout)
 3230 
 3231     def test_delete_snapshot_in_use(self):
 3232         # setup_mock_client drive with default configuration
 3233         # and return the mock HTTP 3PAR client
 3234         mock_client = self.setup_driver()
 3235         with mock.patch.object(hpecommon.HPE3PARCommon,
 3236                                '_create_client') as mock_create_client:
 3237             mock_create_client.return_value = mock_client
 3238             self.driver._login()
 3239             volume = self.volume.copy()
 3240             model_update = self.driver.create_volume_from_snapshot(
 3241                 volume,
 3242                 self.snapshot)
 3243             self.assertEqual(model_update, {})
 3244 
 3245             comment = Comment({
 3246                 "snapshot_id": "2f823bdc-e36e-4dc8-bd15-de1c7a28ff31",
 3247                 "display_name": "Foo Volume",
 3248                 "volume_id": "d03338a9-9115-48a3-8dfc-35cdfcdc15a7",
 3249             })
 3250 
 3251             expected = [
 3252                 mock.call.createSnapshot(
 3253                     self.VOLUME_3PAR_NAME,
 3254                     'oss-L4I73ONuTci9Fd4ceij-MQ',
 3255                     {
 3256                         'comment': comment,
 3257                         'readOnly': False})]
 3258 
 3259             mock_client.assert_has_calls(
 3260                 self.standard_login +
 3261                 expected +
 3262                 self.standard_logout)
 3263 
 3264             ex = hpeexceptions.HTTPConflict("In use")
 3265             ex._error_code = 32
 3266             mock_client.deleteVolume = mock.Mock(side_effect=ex)
 3267 
 3268             # Deleting the snapshot that a volume is dependent on should fail
 3269             self.assertRaises(exception.SnapshotIsBusy,
 3270                               self.driver.delete_snapshot,
 3271                               self.snapshot)
 3272 
 3273     def test_delete_snapshot_not_found(self):
 3274         # setup_mock_client drive with default configuration
 3275         # and return the mock HTTP 3PAR client
 3276         mock_client = self.setup_driver()
 3277 
 3278         with mock.patch.object(hpecommon.HPE3PARCommon,
 3279                                '_create_client') as mock_create_client:
 3280             mock_create_client.return_value = mock_client
 3281             self.driver.create_snapshot(self.snapshot)
 3282 
 3283             try:
 3284                 ex = hpeexceptions.HTTPNotFound("not found")
 3285                 mock_client.deleteVolume = mock.Mock(side_effect=ex)
 3286                 self.driver.delete_snapshot(self.snapshot)
 3287             except Exception:
 3288                 self.fail("Deleting a snapshot that is missing should act "
 3289                           "as if it worked.")
 3290 
 3291     def test_create_volume_from_snapshot(self):
 3292         # setup_mock_client drive with default configuration
 3293         # and return the mock HTTP 3PAR client
 3294         mock_client = self.setup_driver()
 3295         with mock.patch.object(hpecommon.HPE3PARCommon,
 3296                                '_create_client') as mock_create_client:
 3297             mock_create_client.return_value = mock_client
 3298             self.driver._login()
 3299             volume = self.volume.copy()
 3300             model_update = self.driver.create_volume_from_snapshot(
 3301                 volume,
 3302                 self.snapshot)
 3303             self.assertEqual(model_update, {})
 3304 
 3305             comment = Comment({
 3306                 "snapshot_id": "2f823bdc-e36e-4dc8-bd15-de1c7a28ff31",
 3307                 "display_name": "Foo Volume",
 3308                 "volume_id": "d03338a9-9115-48a3-8dfc-35cdfcdc15a7",
 3309             })
 3310 
 3311             expected = [
 3312                 mock.call.createSnapshot(
 3313                     self.VOLUME_3PAR_NAME,
 3314                     'oss-L4I73ONuTci9Fd4ceij-MQ',
 3315                     {
 3316                         'comment': comment,
 3317                         'readOnly': False})]
 3318 
 3319             mock_client.assert_has_calls(
 3320                 self.standard_login +
 3321                 expected +
 3322                 self.standard_logout)
 3323 
 3324     def test_create_volume_from_snapshot_and_extend(self):
 3325         # setup_mock_client drive with default configuration
 3326         # and return the mock HTTP 3PAR client
 3327         conf = {
 3328             'getTask.return_value': {
 3329                 'status': 1},
 3330             'copyVolume.return_value': {'taskid': 1},
 3331             'getVolume.return_value': {}
 3332         }
 3333 
 3334         mock_client = self.setup_driver(mock_conf=conf)
 3335         with mock.patch.object(hpecommon.HPE3PARCommon,
 3336                                '_create_client') as mock_create_client:
 3337             mock_create_client.return_value = mock_client
 3338             common = self.driver._login()
 3339 
 3340             volume = self.volume.copy()
 3341             volume['size'] = self.volume['size'] + 10
 3342             model_update = self.driver.create_volume_from_snapshot(
 3343                 volume,
 3344                 self.snapshot)
 3345             self.assertIsNone(model_update)
 3346 
 3347             comment = Comment({
 3348                 "snapshot_id": "2f823bdc-e36e-4dc8-bd15-de1c7a28ff31",
 3349                 "display_name": "Foo Volume",
 3350                 "volume_id": "d03338a9-9115-48a3-8dfc-35cdfcdc15a7",
 3351             })
 3352             volume_name_3par = common._encode_name(volume['id'])
 3353             osv_matcher = 'osv-' + volume_name_3par
 3354             omv_matcher = 'omv-' + volume_name_3par
 3355 
 3356             expected = [
 3357                 mock.call.createSnapshot(
 3358                     self.VOLUME_3PAR_NAME,
 3359                     'oss-L4I73ONuTci9Fd4ceij-MQ',
 3360                     {
 3361                         'comment': comment,
 3362                         'readOnly': False}),
 3363                 mock.call.copyVolume(
 3364                     osv_matcher, omv_matcher, HPE3PAR_CPG, mock.ANY),
 3365                 mock.call.getTask(mock.ANY),
 3366                 mock.call.getVolume(osv_matcher),
 3367                 mock.call.deleteVolume(osv_matcher),
 3368                 mock.call.modifyVolume(omv_matcher, {'newName': osv_matcher}),
 3369                 mock.call.growVolume(osv_matcher, 10 * 1024)]
 3370 
 3371             mock_client.assert_has_calls(
 3372                 self.standard_login +
 3373                 expected +
 3374                 self.standard_logout)
 3375 
 3376     @mock.patch.object(volume_types, 'get_volume_type')
 3377     def test_create_volume_from_snapshot_and_extend_with_qos(
 3378             self, _mock_volume_types):
 3379         # setup_mock_client drive with default configuration
 3380         # and return the mock HTTP 3PAR client
 3381         conf = {
 3382             'getTask.return_value': {
 3383                 'status': 1},
 3384             'copyVolume.return_value': {'taskid': 1},
 3385             'getVolume.return_value': {}
 3386         }
 3387 
 3388         mock_client = self.setup_driver(mock_conf=conf)
 3389         _mock_volume_types.return_value = {
 3390             'name': 'gold',
 3391             'extra_specs': {
 3392                 'cpg': HPE3PAR_CPG_QOS,
 3393                 'snap_cpg': HPE3PAR_CPG_SNAP,
 3394                 'vvs_name': self.VVS_NAME,
 3395                 'qos': self.QOS,
 3396                 'tpvv': True,
 3397                 'tdvv': False,
 3398                 'volume_type': self.volume_type}}
 3399 
 3400         with mock.patch.object(hpecommon.HPE3PARCommon,
 3401                                '_create_client') as mock_create_client:
 3402             mock_create_client.return_value = mock_client
 3403             common = self.driver._login()
 3404 
 3405             volume = self.volume_qos.copy()
 3406             volume['size'] = self.volume['size'] + 10
 3407             model_update = self.driver.create_volume_from_snapshot(
 3408                 volume,
 3409                 self.snapshot)
 3410             self.assertIsNone(model_update)
 3411 
 3412             comment = Comment({
 3413                 "snapshot_id": "2f823bdc-e36e-4dc8-bd15-de1c7a28ff31",
 3414                 "display_name": "Foo Volume",
 3415                 "volume_id": "d03338a9-9115-48a3-8dfc-35cdfcdc15a7",
 3416             })
 3417 
 3418             volume_name_3par = common._encode_name(volume['id'])
 3419             osv_matcher = 'osv-' + volume_name_3par
 3420             omv_matcher = 'omv-' + volume_name_3par
 3421 
 3422             expected = [
 3423                 mock.call.createSnapshot(
 3424                     self.VOLUME_3PAR_NAME,
 3425                     'oss-L4I73ONuTci9Fd4ceij-MQ',
 3426                     {
 3427                         'comment': comment,
 3428                         'readOnly': False}),
 3429                 mock.call.getCPG(HPE3PAR_CPG),
 3430                 mock.call.copyVolume(
 3431                     osv_matcher, omv_matcher, HPE3PAR_CPG, mock.ANY),
 3432                 mock.call.getTask(mock.ANY),
 3433                 mock.call.getVolume(osv_matcher),
 3434                 mock.call.deleteVolume(osv_matcher),
 3435                 mock.call.modifyVolume(omv_matcher, {'newName': osv_matcher}),
 3436                 mock.call.growVolume(osv_matcher, 10 * 1024)]
 3437 
 3438             mock_client.assert_has_calls(
 3439                 self.standard_login +
 3440                 expected +
 3441                 self.standard_logout)
 3442 
 3443     def test_create_volume_from_snapshot_and_extend_copy_fail(self):
 3444         # setup_mock_client drive with default configuration
 3445         # and return the mock HTTP 3PAR client
 3446         conf = {
 3447             'getTask.return_value': {
 3448                 'status': 4,
 3449                 'failure message': 'out of disk space'},
 3450             'copyVolume.return_value': {'taskid': 1},
 3451             'getVolume.return_value': {}
 3452         }
 3453 
 3454         mock_client = self.setup_driver(mock_conf=conf)
 3455 
 3456         with mock.patch.object(hpecommon.HPE3PARCommon,
 3457                                '_create_client') as mock_create_client:
 3458             mock_create_client.return_value = mock_client
 3459             volume = self.volume.copy()
 3460             volume['size'] = self.volume['size'] + 10
 3461 
 3462             self.assertRaises(exception.CinderException,
 3463                               self.driver.create_volume_from_snapshot,
 3464                               volume, self.snapshot)
 3465 
 3466     @mock.patch.object(volume_types, 'get_volume_type')
 3467     def test_create_volume_from_snapshot_qos(self, _mock_volume_types):
 3468         # setup_mock_client drive with default configuration
 3469         # and return the mock HTTP 3PAR client
 3470         mock_client = self.setup_driver()
 3471         _mock_volume_types.return_value = {
 3472             'name': 'gold',
 3473             'extra_specs': {
 3474                 'cpg': HPE3PAR_CPG,
 3475                 'snap_cpg': HPE3PAR_CPG_SNAP,
 3476                 'vvs_name': self.VVS_NAME,
 3477                 'qos': self.QOS,
 3478                 'tpvv': True,
 3479                 'tdvv': False,
 3480                 'volume_type': self.volume_type}}
 3481         with mock.patch.object(hpecommon.HPE3PARCommon,
 3482                                '_create_client') as mock_create_client:
 3483             mock_create_client.return_value = mock_client
 3484             self.driver._login()
 3485             volume = self.volume_qos.copy()
 3486             model_update = self.driver.create_volume_from_snapshot(
 3487                 volume, self.snapshot)
 3488             self.assertEqual(model_update, {})
 3489 
 3490             comment = Comment({
 3491                 "snapshot_id": "2f823bdc-e36e-4dc8-bd15-de1c7a28ff31",
 3492                 "display_name": "Foo Volume",
 3493                 "volume_id": "d03338a9-9115-48a3-8dfc-35cdfcdc15a7",
 3494             })
 3495 
 3496             expected = [
 3497                 mock.call.createSnapshot(
 3498                     self.VOLUME_3PAR_NAME,
 3499                     'oss-L4I73ONuTci9Fd4ceij-MQ', {
 3500                         'comment': comment,
 3501                         'readOnly': False})]
 3502 
 3503             mock_client.assert_has_calls(
 3504                 self.standard_login +
 3505                 expected +
 3506                 self.standard_logout)
 3507 
 3508     @mock.patch.object(volume_types, 'get_volume_type')
 3509     def test_create_volume_from_snapshot_as_child(self, _mock_volume_types):
 3510         # setup_mock_client drive with default configuration
 3511         # and return the mock HTTP 3PAR client
 3512         mock_client = self.setup_driver()
 3513         volume_type_hos = self.volume_type_hos
 3514         volume_type_hos['extra_specs']['convert_to_base'] = False
 3515         _mock_volume_types.return_value = volume_type_hos
 3516 
 3517         with mock.patch.object(hpecommon.HPE3PARCommon,
 3518                                '_create_client') as mock_create_client:
 3519             mock_create_client.return_value = mock_client
 3520             self.driver._login()
 3521             volume = self.volume_hos.copy()
 3522             model_update = self.driver.create_volume_from_snapshot(
 3523                 volume,
 3524                 self.snapshot)
 3525             self.assertEqual(model_update, {})
 3526 
 3527             comment = Comment({
 3528                 "snapshot_id": "2f823bdc-e36e-4dc8-bd15-de1c7a28ff31",
 3529                 "display_name": "Foo Volume",
 3530                 "volume_id": "d03338a9-9115-48a3-8dfc-35cdfcdc15a7",
 3531             })
 3532 
 3533             expected = [
 3534                 mock.call.createSnapshot(
 3535                     self.VOLUME_3PAR_NAME,
 3536                     'oss-L4I73ONuTci9Fd4ceij-MQ',
 3537                     {
 3538                         'comment': comment,
 3539                         'readOnly': False})]
 3540 
 3541             mock_client.assert_has_calls(
 3542                 self.standard_login +
 3543                 expected +
 3544                 self.standard_logout)
 3545 
 3546     @mock.patch.object(volume_types, 'get_volume_type')
 3547     def test_create_volume_from_snapshot_as_base(self, _mock_volume_types):
 3548         # setup_mock_client drive with default configuration
 3549         # and return the mock HTTP 3PAR client
 3550         conf = {
 3551             'getTask.return_value': {
 3552                 'status': 1},
 3553             'copyVolume.return_value': {'taskid': 1},
 3554             'getVolume.return_value': {}
 3555         }
 3556         mock_client = self.setup_driver(mock_conf=conf)
 3557         volume_type_hos = self.volume_type_hos
 3558         volume_type_hos['extra_specs']['convert_to_base'] = True
 3559         _mock_volume_types.return_value = volume_type_hos
 3560         with mock.patch.object(hpecommon.HPE3PARCommon,
 3561                                '_create_client') as mock_create_client:
 3562             mock_create_client.return_value = mock_client
 3563             common = self.driver._login()
 3564             volume = self.volume_hos.copy()
 3565             model_update = self.driver.create_volume_from_snapshot(
 3566                 volume,
 3567                 self.snapshot)
 3568             self.assertIsNone(model_update)
 3569 
 3570             comment = Comment({
 3571                 "snapshot_id": "2f823bdc-e36e-4dc8-bd15-de1c7a28ff31",
 3572                 "display_name": "Foo Volume",
 3573                 "volume_id": "d03338a9-9115-48a3-8dfc-35cdfcdc15a7",
 3574             })
 3575             volume_name_3par = common._encode_name(volume['id'])
 3576             osv_matcher = 'osv-' + volume_name_3par
 3577             omv_matcher = 'omv-' + volume_name_3par
 3578 
 3579             expected = [
 3580                 mock.call.createSnapshot(
 3581                     self.VOLUME_3PAR_NAME,
 3582                     'oss-L4I73ONuTci9Fd4ceij-MQ',
 3583                     {
 3584                         'comment': comment,
 3585                         'readOnly': False}),
 3586                 mock.call.copyVolume(
 3587                     osv_matcher, omv_matcher, HPE3PAR_CPG, mock.ANY),
 3588                 mock.call.getTask(mock.ANY),
 3589                 mock.call.getVolume(osv_matcher),
 3590                 mock.call.deleteVolume(osv_matcher),
 3591                 mock.call.modifyVolume(omv_matcher, {'newName': osv_matcher})]
 3592 
 3593             mock_client.assert_has_calls(
 3594                 self.standard_login +
 3595                 expected +
 3596                 self.standard_logout)
 3597 
 3598     @mock.patch.object(volume_types, 'get_volume_type')
 3599     def test_create_volume_from_snapshot_as_child_and_extend(
 3600             self, _mock_volume_types):
 3601         # setup_mock_client drive with default configuration
 3602         # and return the mock HTTP 3PAR client
 3603         conf = {
 3604             'getTask.return_value': {
 3605                 'status': 1},
 3606             'copyVolume.return_value': {'taskid': 1},
 3607             'getVolume.return_value': {}
 3608         }
 3609         mock_client = self.setup_driver(mock_conf=conf)
 3610         volume_type_hos = self.volume_type_hos
 3611         volume_type_hos['extra_specs']['convert_to_base'] = False
 3612         _mock_volume_types.return_value = volume_type_hos
 3613         with mock.patch.object(hpecommon.HPE3PARCommon,
 3614                                '_create_client') as mock_create_client:
 3615             mock_create_client.return_value = mock_client
 3616             common = self.driver._login()
 3617             volume = self.volume_hos.copy()
 3618             volume['size'] = self.volume['size'] + 10
 3619             model_update = self.driver.create_volume_from_snapshot(
 3620                 volume,
 3621                 self.snapshot)
 3622             self.assertIsNone(model_update)
 3623 
 3624             comment = Comment({
 3625                 "snapshot_id": "2f823bdc-e36e-4dc8-bd15-de1c7a28ff31",
 3626                 "display_name": "Foo Volume",
 3627                 "volume_id": "d03338a9-9115-48a3-8dfc-35cdfcdc15a7",
 3628             })
 3629             volume_name_3par = common._encode_name(volume['id'])
 3630             osv_matcher = 'osv-' + volume_name_3par
 3631             omv_matcher = 'omv-' + volume_name_3par
 3632 
 3633             expected = [
 3634                 mock.call.createSnapshot(
 3635                     self.VOLUME_3PAR_NAME,
 3636                     'oss-L4I73ONuTci9Fd4ceij-MQ',
 3637                     {
 3638                         'comment': comment,
 3639                         'readOnly': False}),
 3640                 mock.call.copyVolume(
 3641                     osv_matcher, omv_matcher, HPE3PAR_CPG, mock.ANY),
 3642                 mock.call.getTask(mock.ANY),
 3643                 mock.call.getVolume(osv_matcher),
 3644                 mock.call.deleteVolume(osv_matcher),
 3645                 mock.call.modifyVolume(omv_matcher, {'newName': osv_matcher}),
 3646                 mock.call.growVolume(osv_matcher, 10 * 1024)]
 3647 
 3648             mock_client.assert_has_calls(
 3649                 self.standard_login +
 3650                 expected +
 3651                 self.standard_logout)
 3652 
 3653     @mock.patch.object(volume_types, 'get_volume_type')
 3654     def test_create_volume_from_snapshot_as_base_and_extend(
 3655             self, _mock_volume_types):
 3656         # setup_mock_client drive with default configuration
 3657         # and return the mock HTTP 3PAR client
 3658         conf = {
 3659             'getTask.return_value': {
 3660                 'status': 1},
 3661             'copyVolume.return_value': {'taskid': 1},
 3662             'getVolume.return_value': {}
 3663         }
 3664         mock_client = self.setup_driver(mock_conf=conf)
 3665         volume_type_hos = self.volume_type_hos
 3666         volume_type_hos['extra_specs']['convert_to_base'] = True
 3667         _mock_volume_types.return_value = volume_type_hos
 3668         with mock.patch.object(hpecommon.HPE3PARCommon,
 3669                                '_create_client') as mock_create_client:
 3670             mock_create_client.return_value = mock_client
 3671             common = self.driver._login()
 3672             volume = self.volume_hos.copy()
 3673             volume['size'] = self.volume['size'] + 10
 3674             model_update = self.driver.create_volume_from_snapshot(
 3675                 volume,
 3676                 self.snapshot)
 3677             self.assertIsNone(model_update)
 3678 
 3679             comment = Comment({
 3680                 "snapshot_id": "2f823bdc-e36e-4dc8-bd15-de1c7a28ff31",
 3681                 "display_name": "Foo Volume",
 3682                 "volume_id": "d03338a9-9115-48a3-8dfc-35cdfcdc15a7",
 3683             })
 3684             volume_name_3par = common._encode_name(volume['id'])
 3685             osv_matcher = 'osv-' + volume_name_3par
 3686             omv_matcher = 'omv-' + volume_name_3par
 3687 
 3688             expected = [
 3689                 mock.call.createSnapshot(
 3690                     self.VOLUME_3PAR_NAME,
 3691                     'oss-L4I73ONuTci9Fd4ceij-MQ',
 3692                     {
 3693                         'comment': comment,
 3694                         'readOnly': False}),
 3695                 mock.call.copyVolume(
 3696                     osv_matcher, omv_matcher, HPE3PAR_CPG, mock.ANY),
 3697                 mock.call.getTask(mock.ANY),
 3698                 mock.call.getVolume(osv_matcher),
 3699                 mock.call.deleteVolume(osv_matcher),
 3700                 mock.call.modifyVolume(omv_matcher, {'newName': osv_matcher}),
 3701                 mock.call.growVolume(osv_matcher, 10 * 1024)]
 3702 
 3703             mock_client.assert_has_calls(
 3704                 self.standard_login +
 3705                 expected +
 3706                 self.standard_logout)
 3707 
 3708     def test_terminate_connection_from_primary_when_failed_over(self):
 3709         # setup_mock_client drive with default configuration
 3710         # and return the mock HTTP 3PAR client
 3711         mock_client = self.setup_driver()
 3712         mock_client.getHostVLUNs.side_effect = hpeexceptions.HTTPNotFound(
 3713             error={'desc': 'The host does not exist.'})
 3714 
 3715         with mock.patch.object(hpecommon.HPE3PARCommon,
 3716                                '_create_client') as mock_create_client:
 3717             mock_create_client.return_value = mock_client
 3718 
 3719             self.driver._active_backend_id = 'some_id'
 3720             self.driver.terminate_connection(
 3721                 self.volume,
 3722                 self.connector,
 3723                 force=True)
 3724 
 3725             # When the volume is still attached to the primary array after a
 3726             # fail-over, there should be no call to delete the VLUN(s) or the
 3727             # host. We can assert these methods were not called to make sure
 3728             # the proper exceptions are being raised.
 3729             self.assertEqual(0, mock_client.deleteVLUN.call_count)
 3730 
 3731     def test_terminate_connection_from_primary_when_group_failed_over(self):
 3732         mock_conf = {
 3733             'getStorageSystemInfo.return_value': {
 3734                 'id': self.REPLICATION_CLIENT_ID,
 3735                 'name': 'CSIM-EOS12_1611702'}}
 3736 
 3737         conf = self.setup_configuration()
 3738         conf.replication_device = self.replication_targets
 3739         mock_client = self.setup_driver(config=conf, mock_conf=mock_conf)
 3740 
 3741         mock_client.getHostVLUNs.side_effect = hpeexceptions.HTTPNotFound(
 3742             error={'desc': 'The host does not exist.'})
 3743 
 3744         with mock.patch.object(hpecommon.HPE3PARCommon,
 3745                                '_create_client') as mock_create_client:
 3746             mock_create_client.return_value = mock_client
 3747 
 3748             volume = self.volume_tiramisu.copy()
 3749             volume['replication_status'] = 'failed-over'
 3750             volume['replication_driver_data'] = self.REPLICATION_CLIENT_ID
 3751 
 3752             self.driver._active_backend_id = "CSIM-EOS12_1611702"
 3753             self.driver.terminate_connection(
 3754                 self.volume,
 3755                 self.connector,
 3756                 force=True)
 3757 
 3758             # When the volume is still attached to the primary array after a
 3759             # fail-over, there should be no call to delete the VLUN(s) or the
 3760             # host. We can assert these methods were not called to make sure
 3761             # the proper exceptions are being raised.
 3762             self.assertEqual(0, mock_client.deleteVLUN.call_count)
 3763 
 3764     def test_extend_volume(self):
 3765         # setup_mock_client drive with default configuration
 3766         # and return the mock HTTP 3PAR client
 3767         mock_client = self.setup_driver()
 3768         with mock.patch.object(hpecommon.HPE3PARCommon,
 3769                                '_create_client') as mock_create_client:
 3770             mock_create_client.return_value = mock_client
 3771             grow_size = 3
 3772             old_size = self.volume['size']
 3773             new_size = old_size + grow_size
 3774             self.driver.extend_volume(self.volume, str(new_size))
 3775             growth_size_mib = grow_size * units.Ki
 3776 
 3777             expected = [
 3778                 mock.call.growVolume(self.VOLUME_3PAR_NAME, growth_size_mib)]
 3779 
 3780             mock_client.assert_has_calls(expected)
 3781 
 3782     def test_extend_volume_non_base(self):
 3783         extend_ex = hpeexceptions.HTTPForbidden(error={'code': 150})
 3784         conf = {
 3785             'getTask.return_value': {
 3786                 'status': 1},
 3787             'getCPG.return_value': {},
 3788             'copyVolume.return_value': {'taskid': 1},
 3789             'getVolume.return_value': {},
 3790             # Throw an exception first time only
 3791             'growVolume.side_effect': [extend_ex,
 3792                                        None],
 3793         }
 3794 
 3795         mock_client = self.setup_driver(mock_conf=conf)
 3796         with mock.patch.object(hpecommon.HPE3PARCommon,
 3797                                '_create_client') as mock_create_client:
 3798             mock_create_client.return_value = mock_client
 3799             grow_size = 3
 3800             old_size = self.volume['size']
 3801             new_size = old_size + grow_size
 3802             self.driver.extend_volume(self.volume, str(new_size))
 3803 
 3804             self.assertEqual(2, mock_client.growVolume.call_count)
 3805 
 3806     def test_extend_volume_non_base_failure(self):
 3807         extend_ex = hpeexceptions.HTTPForbidden(error={'code': 150})
 3808         conf = {
 3809             'getTask.return_value': {
 3810                 'status': 1},
 3811             'getCPG.return_value': {},
 3812             'copyVolume.return_value': {'taskid': 1},
 3813             'getVolume.return_value': {},
 3814             # Always fail
 3815             'growVolume.side_effect': extend_ex
 3816         }
 3817 
 3818         mock_client = self.setup_driver(mock_conf=conf)
 3819         with mock.patch.object(hpecommon.HPE3PARCommon,
 3820                                '_create_client') as mock_create_client:
 3821             mock_create_client.return_value = mock_client
 3822             grow_size = 3
 3823             old_size = self.volume['size']
 3824             new_size = old_size + grow_size
 3825             self.assertRaises(hpeexceptions.HTTPForbidden,
 3826                               self.driver.extend_volume,
 3827                               self.volume,
 3828                               str(new_size))
 3829 
 3830     @mock.patch.object(volume_types, 'get_volume_type')
 3831     def test_extend_volume_replicated(self, _mock_volume_types):
 3832         # Managed vs. unmanaged and periodic vs. sync are not relevant when
 3833         # extending a replicated volume type.
 3834         # We will use managed and periodic as the default.
 3835         conf = self.setup_configuration()
 3836         self.replication_targets[0]['replication_mode'] = 'periodic'
 3837         conf.replication_device = self.replication_targets
 3838         mock_client = self.setup_driver(config=conf)
 3839         mock_client.getStorageSystemInfo.return_value = (
 3840             {'id': self.CLIENT_ID})
 3841 
 3842         _mock_volume_types.return_value = {
 3843             'name': 'replicated',
 3844             'extra_specs': {
 3845                 'cpg': HPE3PAR_CPG,
 3846                 'snap_cpg': HPE3PAR_CPG_SNAP,
 3847                 'replication_enabled': '<is> True',
 3848                 'replication:mode': 'periodic',
 3849                 'replication:sync_period': '900',
 3850                 'volume_type': self.volume_type_replicated}}
 3851 
 3852         with mock.patch.object(
 3853                 hpecommon.HPE3PARCommon,
 3854                 '_create_client') as mock_create_client:
 3855             mock_create_client.return_value = mock_client
 3856 
 3857             grow_size = 3
 3858             old_size = self.volume_replicated['size']
 3859             new_size = old_size + grow_size
 3860 
 3861             # Test a successful extend.
 3862             self.driver.extend_volume(
 3863                 self.volume_replicated,
 3864                 new_size)
 3865             expected = [
 3866                 mock.call.stopRemoteCopy(self.RCG_3PAR_NAME),
 3867                 mock.call.growVolume(self.VOLUME_3PAR_NAME, grow_size * 1024),
 3868                 mock.call.startRemoteCopy(self.RCG_3PAR_NAME)]
 3869             mock_client.assert_has_calls(
 3870                 self.get_id_login +
 3871                 self.standard_logout +
 3872                 self.standard_login +
 3873                 expected +
 3874                 self.standard_logout)
 3875 
 3876             # Test an unsuccessful extend. growVolume will fail but remote
 3877             # copy should still be started again.
 3878             mock_client.growVolume.side_effect = (
 3879                 hpeexceptions.HTTPForbidden("Error: The volume cannot be "
 3880                                             "extended."))
 3881             self.assertRaises(
 3882                 hpeexceptions.HTTPForbidden,
 3883                 self.driver.extend_volume,
 3884                 self.volume_replicated,
 3885                 new_size)
 3886             expected = [
 3887                 mock.call.stopRemoteCopy(self.RCG_3PAR_NAME),
 3888                 mock.call.growVolume(self.VOLUME_3PAR_NAME, grow_size * 1024),
 3889                 mock.call.startRemoteCopy(self.RCG_3PAR_NAME)]
 3890             mock_client.assert_has_calls(
 3891                 self.get_id_login +
 3892                 self.standard_logout +
 3893                 self.standard_login +
 3894                 expected +
 3895                 self.standard_logout)
 3896 
 3897     def test_get_ports(self):
 3898         # setup_mock_client drive with default configuration
 3899         # and return the mock HTTP 3PAR client
 3900         mock_client = self.setup_driver()
 3901         mock_client.getPorts.return_value = {
 3902             'members': [
 3903                 {'portPos': {'node': 0, 'slot': 8, 'cardPort': 2},
 3904                  'protocol': 2,
 3905                  'IPAddr': '10.10.120.252',
 3906                  'linkState': 4,
 3907                  'device': [],
 3908                  'iSCSIName': 'iqn.2000-05.com.3pardata:21810002ac00383d',
 3909                  'mode': 2,
 3910                  'HWAddr': '2C27D75375D2',
 3911                  'type': 8},
 3912                 {'portPos': {'node': 1, 'slot': 8, 'cardPort': 1},
 3913                  'protocol': 2,
 3914                  'IPAddr': '10.10.220.253',
 3915                  'linkState': 4,
 3916                  'device': [],
 3917                  'iSCSIName': 'iqn.2000-05.com.3pardata:21810002ac00383d',
 3918                  'mode': 2,
 3919                  'HWAddr': '2C27D75375D6',
 3920                  'type': 8},
 3921                 {'portWWN': '20210002AC00383D',
 3922                  'protocol': 1,
 3923                  'linkState': 4,
 3924                  'mode': 2,
 3925                  'device': ['cage2'],
 3926                  'nodeWWN': '20210002AC00383D',
 3927                  'type': 2,
 3928                  'portPos': {'node': 0, 'slot': 6, 'cardPort': 3}}]}
 3929 
 3930         with mock.patch.object(hpecommon.HPE3PARCommon,
 3931                                '_create_client') as mock_create_client:
 3932             mock_create_client.return_value = mock_client
 3933             common = self.driver._login()
 3934             ports = common.get_ports()['members']
 3935             self.assertEqual(3, len(ports))
 3936 
 3937     def test_get_by_qos_spec_with_scoping(self):
 3938         mock_client = self.setup_driver()
 3939         with mock.patch.object(hpecommon.HPE3PARCommon,
 3940                                '_create_client') as mock_create_client:
 3941             mock_create_client.return_value = mock_client
 3942             common = self.driver._login()
 3943             qos_ref = qos_specs.create(self.ctxt, 'qos-specs-1', self.QOS)
 3944             type_ref = volume_types.create(self.ctxt,
 3945                                            "type1", {"qos:maxIOPS": "100",
 3946                                                      "qos:maxBWS": "50",
 3947                                                      "qos:minIOPS": "10",
 3948                                                      "qos:minBWS": "20",
 3949                                                      "qos:latency": "5",
 3950                                                      "qos:priority": "high"})
 3951             qos_specs.associate_qos_with_type(self.ctxt,
 3952                                               qos_ref['id'],
 3953                                               type_ref['id'])
 3954             type_ref = volume_types.get_volume_type(self.ctxt, type_ref['id'])
 3955             qos = common._get_qos_by_volume_type(type_ref)
 3956             self.assertEqual({'maxIOPS': '1000', 'maxBWS': '50',
 3957                               'minIOPS': '100', 'minBWS': '25',
 3958                               'latency': '25', 'priority': 'low'}, qos)
 3959 
 3960     def test_get_by_qos_spec(self):
 3961         mock_client = self.setup_driver()
 3962         with mock.patch.object(hpecommon.HPE3PARCommon,
 3963                                '_create_client') as mock_create_client:
 3964             mock_create_client.return_value = mock_client
 3965             common = self.driver._login()
 3966             qos_ref = qos_specs.create(
 3967                 self.ctxt,
 3968                 'qos-specs-1',
 3969                 self.QOS_SPECS)
 3970             type_ref = volume_types.create(self.ctxt,
 3971                                            "type1", {"qos:maxIOPS": "100",
 3972                                                      "qos:maxBWS": "50",
 3973                                                      "qos:minIOPS": "10",
 3974                                                      "qos:minBWS": "20",
 3975                                                      "qos:latency": "5",
 3976                                                      "qos:priority": "high"})
 3977             qos_specs.associate_qos_with_type(self.ctxt,
 3978                                               qos_ref['id'],
 3979                                               type_ref['id'])
 3980             type_ref = volume_types.get_volume_type(self.ctxt, type_ref['id'])
 3981             qos = common._get_qos_by_volume_type(type_ref)
 3982             self.assertEqual({'maxIOPS': '1000', 'maxBWS': '50',
 3983                               'minIOPS': '100', 'minBWS': '25',
 3984                               'latency': '25', 'priority': 'low'}, qos)
 3985 
 3986     def test_get_by_qos_by_type_only(self):
 3987         mock_client = self.setup_driver()
 3988         with mock.patch.object(hpecommon.HPE3PARCommon,
 3989                                '_create_client') as mock_create_client:
 3990             mock_create_client.return_value = mock_client
 3991             common = self.driver._login()
 3992             type_ref = volume_types.create(self.ctxt,
 3993                                            "type1", {"qos:maxIOPS": "100",
 3994                                                      "qos:maxBWS": "50",
 3995                                                      "qos:minIOPS": "10",
 3996                                                      "qos:minBWS": "20",
 3997                                                      "qos:latency": "5",
 3998                                                      "qos:priority": "high"})
 3999             type_ref = volume_types.get_volume_type(self.ctxt, type_ref['id'])
 4000             qos = common._get_qos_by_volume_type(type_ref)
 4001             self.assertEqual({'maxIOPS': '100', 'maxBWS': '50',
 4002                               'minIOPS': '10', 'minBWS': '20',
 4003                               'latency': '5', 'priority': 'high'}, qos)
 4004 
 4005     def test_create_vlun(self):
 4006         host = 'fake-host'
 4007         lun_id = 11
 4008         nsp = '1:2:3'
 4009         mock_client = self.setup_driver()
 4010         with mock.patch.object(hpecommon.HPE3PARCommon,
 4011                                '_create_client') as mock_create_client:
 4012             mock_create_client.return_value = mock_client
 4013             location = ("%(name)s,%(lunid)s,%(host)s,%(nsp)s" %
 4014                         {'name': self.VOLUME_NAME,
 4015                          'lunid': lun_id,
 4016                          'host': host,
 4017                          'nsp': nsp})
 4018             mock_client.createVLUN.return_value = location
 4019 
 4020             expected_info = {'volume_name': self.VOLUME_NAME,
 4021                              'lun_id': lun_id,
 4022                              'host_name': host,
 4023                              'nsp': nsp}
 4024             common = self.driver._login()
 4025             vlun_info = common._create_3par_vlun(
 4026                 self.VOLUME_NAME,
 4027                 host,
 4028                 nsp)
 4029             self.assertEqual(expected_info, vlun_info)
 4030 
 4031             location = ("%(name)s,%(lunid)s,%(host)s" %
 4032                         {'name': self.VOLUME_NAME,
 4033                          'lunid': lun_id,
 4034                          'host': host})
 4035             mock_client.createVLUN.return_value = location
 4036             expected_info = {'volume_name': self.VOLUME_NAME,
 4037                              'lun_id': lun_id,
 4038                              'host_name': host}
 4039             vlun_info = common._create_3par_vlun(
 4040                 self.VOLUME_NAME,
 4041                 host,
 4042                 None)
 4043             self.assertEqual(expected_info, vlun_info)
 4044 
 4045     def test_create_vlun_vlunid_zero(self):
 4046         # This will test "auto" for deactive when Lun ID is 0
 4047         host = 'fake-host'
 4048         lun_id = 0
 4049         nsp = '0:1:1'
 4050         port = {'node': 0, 'slot': 1, 'cardPort': 1}
 4051 
 4052         mock_client = self.setup_driver()
 4053         with mock.patch.object(hpecommon.HPE3PARCommon,
 4054                                '_create_client') as mock_create_client:
 4055             mock_create_client.return_value = mock_client
 4056 
 4057             # _create_3par_vlun with nsp
 4058             location = ("%(name)s,%(lunid)s,%(host)s,%(nsp)s" %
 4059                         {'name': self.VOLUME_NAME,
 4060                          'lunid': lun_id,
 4061                          'host': host,
 4062                          'nsp': nsp})
 4063             mock_client.createVLUN.return_value = location
 4064             expected_info = {'volume_name': self.VOLUME_NAME,
 4065                              'lun_id': lun_id,
 4066                              'host_name': host,
 4067                              'nsp': nsp}
 4068             common = self.driver._login()
 4069             vlun_info = common._create_3par_vlun(
 4070                 self.VOLUME_NAME,
 4071                 host,
 4072                 nsp,
 4073                 lun_id=lun_id)
 4074             self.assertEqual(expected_info, vlun_info)
 4075             mock_client.createVLUN.assert_called_once_with(self.VOLUME_NAME,
 4076                                                            hostname=host,
 4077                                                            auto=False,
 4078                                                            portPos=port,
 4079                                                            lun=lun_id)
 4080 
 4081             # _create_3par_vlun without nsp
 4082             mock_client.reset_mock()
 4083             location = ("%(name)s,%(lunid)s,%(host)s" %
 4084                         {'name': self.VOLUME_NAME,
 4085                          'lunid': lun_id,
 4086                          'host': host})
 4087             mock_client.createVLUN.return_value = location
 4088             expected_info = {'volume_name': self.VOLUME_NAME,
 4089                              'lun_id': lun_id,
 4090                              'host_name': host}
 4091             vlun_info = common._create_3par_vlun(
 4092                 self.VOLUME_NAME,
 4093                 host,
 4094                 None,
 4095                 lun_id=lun_id)
 4096             self.assertEqual(expected_info, vlun_info)
 4097             mock_client.createVLUN.assert_called_once_with(self.VOLUME_NAME,
 4098                                                            hostname=host,
 4099                                                            auto=False,
 4100                                                            lun=lun_id)
 4101 
 4102     def test__get_existing_volume_ref_name(self):
 4103         mock_client = self.setup_driver()
 4104         with mock.patch.object(hpecommon.HPE3PARCommon,
 4105                                '_create_client') as mock_create_client:
 4106             mock_create_client.return_value = mock_client
 4107             common = self.driver._login()
 4108 
 4109             unm_matcher = common._get_3par_unm_name(self.volume['id'])
 4110             ums_matcher = common._get_3par_ums_name(self.volume['id'])
 4111 
 4112             existing_ref = {'source-name': unm_matcher}
 4113             result = common._get_existing_volume_ref_name(existing_ref)
 4114             self.assertEqual(unm_matcher, result)
 4115 
 4116             existing_ref = {'source-id': self.volume['id']}
 4117             result = common._get_existing_volume_ref_name(existing_ref)
 4118             self.assertEqual(unm_matcher, result)
 4119 
 4120             existing_ref = {'source-id': self.volume['id']}
 4121             result = common._get_existing_volume_ref_name(existing_ref, True)
 4122             self.assertEqual(ums_matcher, result)
 4123 
 4124             existing_ref = {'bad-key': 'foo'}
 4125             self.assertRaises(
 4126                 exception.ManageExistingInvalidReference,
 4127                 common._get_existing_volume_ref_name,
 4128                 existing_ref)
 4129 
 4130     @mock.patch.object(volume_types, 'get_volume_type')
 4131     def test_manage_existing(self, _mock_volume_types):
 4132         _mock_volume_types.return_value = self.volume_type
 4133         mock_client = self.setup_driver()
 4134 
 4135         new_comment = Comment({
 4136             "display_name": "Foo Volume",
 4137             "name": "volume-007dbfce-7579-40bc-8f90-a20b3902283e",
 4138             "volume_id": "007dbfce-7579-40bc-8f90-a20b3902283e",
 4139             "type": "OpenStack",
 4140         })
 4141         volume = {'display_name': None,
 4142                   'host': self.FAKE_CINDER_HOST,
 4143                   'volume_type': 'gold',
 4144                   'volume_type_id': 'acfa9fa4-54a0-4340-a3d8-bfcf19aea65e',
 4145                   'id': '007dbfce-7579-40bc-8f90-a20b3902283e'}
 4146 
 4147         mock_client.getVolume.return_value = self.MANAGE_VOLUME_INFO
 4148         mock_client.modifyVolume.return_value = ("anyResponse", {'taskid': 1})
 4149         mock_client.getTask.return_value = self.STATUS_DONE
 4150 
 4151         with mock.patch.object(hpecommon.HPE3PARCommon,
 4152                                '_create_client') as mock_create_client:
 4153             mock_create_client.return_value = mock_client
 4154             common = self.driver._login()
 4155 
 4156             unm_matcher = common._get_3par_unm_name(self.volume['id'])
 4157             osv_matcher = common._get_3par_vol_name(volume['id'])
 4158             vvs_matcher = common._get_3par_vvs_name(volume['id'])
 4159             existing_ref = {'source-name': unm_matcher}
 4160 
 4161             expected_obj = {'display_name': 'Foo Volume'}
 4162 
 4163             obj = self.driver.manage_existing(volume, existing_ref)
 4164 
 4165             expected_manage = [
 4166                 mock.call.getVolume(existing_ref['source-name']),
 4167                 mock.call.modifyVolume(existing_ref['source-name'],
 4168                                        {'newName': osv_matcher,
 4169                                         'comment': new_comment}),
 4170             ]
 4171 
 4172             retype_comment_qos = Comment({
 4173                 "display_name": "Foo Volume",
 4174                 "volume_type_name": self.volume_type['name'],
 4175                 "volume_type_id": self.volume_type['id'],
 4176                 "qos": {
 4177                     'maxIOPS': '1000',
 4178                     'maxBWS': '50',
 4179                     'minIOPS': '100',
 4180                     'minBWS': '25',
 4181                     'latency': '25',
 4182                     'priority': 'low'
 4183                 }
 4184             })
 4185 
 4186             expected_snap_cpg = HPE3PAR_CPG_SNAP
 4187             expected_retype_modify = [
 4188                 mock.call.modifyVolume(osv_matcher,
 4189                                        {'comment': retype_comment_qos,
 4190                                         'snapCPG': expected_snap_cpg}),
 4191                 mock.call.deleteVolumeSet(vvs_matcher),
 4192             ]
 4193 
 4194             expected_retype_specs = [
 4195                 mock.call.createVolumeSet(vvs_matcher, None),
 4196                 mock.call.createQoSRules(
 4197                     vvs_matcher,
 4198                     {'ioMinGoal': 100, 'ioMaxLimit': 1000,
 4199                      'bwMinGoalKB': 25600, 'priority': 1, 'latencyGoal': 25,
 4200                      'bwMaxLimitKB': 51200}),
 4201                 mock.call.addVolumeToVolumeSet(vvs_matcher, osv_matcher),
 4202                 mock.call.modifyVolume(
 4203                     osv_matcher,
 4204                     {'action': 6,
 4205                      'userCPG': HPE3PAR_CPG,
 4206                      'conversionOperation': 1, 'tuneOperation': 1,
 4207                      'compression': False}),
 4208                 mock.call.getTask(1)
 4209             ]
 4210 
 4211             mock_client.assert_has_calls(self.standard_login + expected_manage)
 4212             mock_client.assert_has_calls(expected_retype_modify)
 4213             mock_client.assert_has_calls(
 4214                 expected_retype_specs +
 4215                 self.standard_logout)
 4216             self.assertEqual(expected_obj, obj)
 4217 
 4218     @mock.patch.object(volume_types, 'get_volume_type')
 4219     def test_manage_existing_with_no_snap_cpg(self, _mock_volume_types):
 4220         _mock_volume_types.return_value = self.volume_type
 4221         mock_client = self.setup_driver()
 4222 
 4223         new_comment = Comment({
 4224             "display_name": "Foo Volume",
 4225             "name": "volume-007dbfce-7579-40bc-8f90-a20b3902283e",
 4226             "volume_id": "007dbfce-7579-40bc-8f90-a20b3902283e",
 4227             "type": "OpenStack",
 4228         })
 4229 
 4230         volume = {'display_name': None,
 4231                   'host': 'my-stack1@3parxxx#CPGNOTUSED',
 4232                   'volume_type': 'gold',
 4233                   'volume_type_id': 'acfa9fa4-54a0-4340-a3d8-bfcf19aea65e',
 4234                   'id': '007dbfce-7579-40bc-8f90-a20b3902283e'}
 4235 
 4236         mock_client.getVolume.return_value = self.MV_INFO_WITH_NO_SNAPCPG
 4237         mock_client.modifyVolume.return_value = ("anyResponse", {'taskid': 1})
 4238         mock_client.getTask.return_value = self.STATUS_DONE
 4239 
 4240         with mock.patch.object(hpecommon.HPE3PARCommon,
 4241                                '_create_client') as mock_create_client:
 4242             mock_create_client.return_value = mock_client
 4243             common = self.driver._login()
 4244 
 4245             unm_matcher = common._get_3par_unm_name(self.volume['id'])
 4246             osv_matcher = common._get_3par_vol_name(volume['id'])
 4247             existing_ref = {'source-name': unm_matcher}
 4248 
 4249             expected_obj = {'display_name': 'Foo Volume'}
 4250 
 4251             obj = self.driver.manage_existing(volume, existing_ref)
 4252 
 4253             expected_manage = [
 4254                 mock.call.getVolume(existing_ref['source-name']),
 4255                 mock.call.modifyVolume(
 4256                     existing_ref['source-name'],
 4257                     {'newName': osv_matcher,
 4258                      'comment': new_comment,
 4259                      # manage_existing() should be setting
 4260                      # blank snapCPG to the userCPG
 4261                      'snapCPG': 'testUserCpg0'})
 4262             ]
 4263 
 4264             mock_client.assert_has_calls(self.standard_login + expected_manage)
 4265             self.assertEqual(expected_obj, obj)
 4266 
 4267     @mock.patch.object(volume_types, 'get_volume_type')
 4268     def test_manage_existing_vvs(self, _mock_volume_types):
 4269         test_volume_type = self.RETYPE_VOLUME_TYPE_2
 4270         vvs = test_volume_type['extra_specs']['vvs']
 4271         _mock_volume_types.return_value = test_volume_type
 4272         mock_client = self.setup_driver()
 4273 
 4274         mock_client.getVolume.return_value = self.MANAGE_VOLUME_INFO
 4275         mock_client.modifyVolume.return_value = ("anyResponse", {'taskid': 1})
 4276         mock_client.getTask.return_value = self.STATUS_DONE
 4277 
 4278         id = '007abcde-7579-40bc-8f90-a20b3902283e'
 4279         new_comment = Comment({
 4280             "display_name": "Test Volume",
 4281             "name": ("volume-%s" % id),
 4282             "volume_id": id,
 4283             "type": "OpenStack",
 4284         })
 4285         volume = {'display_name': 'Test Volume',
 4286                   'host': 'my-stack1@3parxxx#CPGNOTUSED',
 4287                   'volume_type': 'gold',
 4288                   'volume_type_id': 'acfa9fa4-54a0-4340-a3d8-bfcf19aea65e',
 4289                   'id': id}
 4290 
 4291         with mock.patch.object(hpecommon.HPE3PARCommon,
 4292                                '_create_client') as mock_create_client:
 4293             mock_create_client.return_value = mock_client
 4294             common = self.driver._login()
 4295 
 4296             unm_matcher = common._get_3par_unm_name(self.volume['id'])
 4297             osv_matcher = common._get_3par_vol_name(volume['id'])
 4298             vvs_matcher = common._get_3par_vvs_name(volume['id'])
 4299 
 4300             existing_ref = {'source-name': unm_matcher}
 4301 
 4302             obj = self.driver.manage_existing(volume, existing_ref)
 4303 
 4304             expected_obj = {'display_name': 'Test Volume'}
 4305             expected_manage = [
 4306                 mock.call.getVolume(existing_ref['source-name']),
 4307                 mock.call.modifyVolume(existing_ref['source-name'],
 4308                                        {'newName': osv_matcher,
 4309                                         'comment': new_comment})
 4310             ]
 4311 
 4312             retype_comment_vvs = Comment({
 4313                 "display_name": "Foo Volume",
 4314                 "volume_type_name": test_volume_type['name'],
 4315                 "volume_type_id": test_volume_type['id'],
 4316                 "vvs": vvs
 4317             })
 4318 
 4319             expected_retype = [
 4320                 mock.call.modifyVolume(osv_matcher,
 4321                                        {'comment': retype_comment_vvs,
 4322                                         'snapCPG': 'OpenStackCPGSnap'}),
 4323                 mock.call.deleteVolumeSet(vvs_matcher),
 4324                 mock.call.addVolumeToVolumeSet(vvs, osv_matcher),
 4325                 mock.call.modifyVolume(osv_matcher,
 4326                                        {'action': 6,
 4327                                         'userCPG': 'CPGNOTUSED',
 4328                                         'conversionOperation': 1,
 4329                                         'tuneOperation': 1,
 4330                                         'compression': False}),
 4331                 mock.call.getTask(1)
 4332             ]
 4333 
 4334             mock_client.assert_has_calls(self.standard_login + expected_manage)
 4335             mock_client.assert_has_calls(
 4336                 expected_retype +
 4337                 self.standard_logout)
 4338             self.assertEqual(expected_obj, obj)
 4339 
 4340     def test_manage_existing_no_volume_type(self):
 4341         mock_client = self.setup_driver()
 4342 
 4343         comment = repr({"display_name": "Foo Volume"})
 4344         new_comment = Comment({
 4345             "type": "OpenStack",
 4346             "display_name": "Foo Volume",
 4347             "name": "volume-007dbfce-7579-40bc-8f90-a20b3902283e",
 4348             "volume_id": "007dbfce-7579-40bc-8f90-a20b3902283e",
 4349         })
 4350         volume = {'display_name': None,
 4351                   'volume_type': None,
 4352                   'volume_type_id': None,
 4353                   'id': '007dbfce-7579-40bc-8f90-a20b3902283e'}
 4354 
 4355         mock_client.getVolume.return_value = {'comment': comment,
 4356                                               'userCPG': 'testUserCpg0'}
 4357 
 4358         with mock.patch.object(hpecommon.HPE3PARCommon,
 4359                                '_create_client') as mock_create_client:
 4360             mock_create_client.return_value = mock_client
 4361             common = self.driver._login()
 4362             unm_matcher = common._get_3par_unm_name(self.volume['id'])
 4363             osv_matcher = common._get_3par_vol_name(volume['id'])
 4364             existing_ref = {'source-name': unm_matcher}
 4365 
 4366             obj = self.driver.manage_existing(volume, existing_ref)
 4367 
 4368             expected_obj = {'display_name': 'Foo Volume'}
 4369             expected = [
 4370                 mock.call.getVolume(existing_ref['source-name']),
 4371                 mock.call.modifyVolume(existing_ref['source-name'],
 4372                                        {'newName': osv_matcher,
 4373                                         'comment': new_comment,
 4374                                         # manage_existing() should be setting
 4375                                         # blank snapCPG to the userCPG
 4376                                         'snapCPG': 'testUserCpg0'})
 4377             ]
 4378 
 4379             mock_client.assert_has_calls(
 4380                 self.standard_login +
 4381                 expected +
 4382                 self.standard_logout)
 4383             self.assertEqual(expected_obj, obj)
 4384 
 4385             volume['display_name'] = 'Test Volume'
 4386 
 4387             obj = self.driver.manage_existing(volume, existing_ref)
 4388 
 4389             expected_obj = {'display_name': 'Test Volume'}
 4390             expected = [
 4391                 mock.call.getVolume(existing_ref['source-name']),
 4392                 mock.call.modifyVolume(existing_ref['source-name'],
 4393                                        {'newName': osv_matcher,
 4394                                         'comment': new_comment,
 4395                                         # manage_existing() should be setting
 4396                                         # blank snapCPG to the userCPG
 4397                                         'snapCPG': 'testUserCpg0'})
 4398             ]
 4399 
 4400             mock_client.assert_has_calls(
 4401                 self.standard_login +
 4402                 expected +
 4403                 self.standard_logout)
 4404             self.assertEqual(expected_obj, obj)
 4405 
 4406             mock_client.getVolume.return_value = {'userCPG': 'testUserCpg0'}
 4407             volume['display_name'] = None
 4408             common = self.driver._login()
 4409 
 4410             obj = self.driver.manage_existing(volume, existing_ref)
 4411 
 4412             expected_obj = {'display_name': None}
 4413             expected = [
 4414                 mock.call.getVolume(existing_ref['source-name']),
 4415                 mock.call.modifyVolume(existing_ref['source-name'],
 4416                                        {'newName': osv_matcher,
 4417                                         'comment': new_comment,
 4418                                         # manage_existing() should be setting
 4419                                         # blank snapCPG to the userCPG
 4420                                         'snapCPG': 'testUserCpg0'})
 4421             ]
 4422 
 4423             mock_client.assert_has_calls(
 4424                 self.standard_login +
 4425                 expected +
 4426                 self.standard_logout)
 4427             self.assertEqual(expected_obj, obj)
 4428 
 4429     def test_manage_existing_invalid_input(self):
 4430         mock_client = self.setup_driver()
 4431 
 4432         volume = {'display_name': None,
 4433                   'volume_type': None,
 4434                   'id': '007dbfce-7579-40bc-8f90-a20b3902283e'}
 4435 
 4436         mock_client.getVolume.side_effect = hpeexceptions.HTTPNotFound('fake')
 4437 
 4438         with mock.patch.object(hpecommon.HPE3PARCommon,
 4439                                '_create_client') as mock_create_client:
 4440             mock_create_client.return_value = mock_client
 4441             common = self.driver._login()
 4442             unm_matcher = common._get_3par_unm_name(self.volume['id'])
 4443             existing_ref = {'source-name': unm_matcher}
 4444 
 4445             self.assertRaises(exception.InvalidInput,
 4446                               self.driver.manage_existing,
 4447                               volume=volume,
 4448                               existing_ref=existing_ref)
 4449 
 4450             expected = [mock.call.getVolume(existing_ref['source-name'])]
 4451 
 4452             mock_client.assert_has_calls(
 4453                 self.standard_login +
 4454                 expected +
 4455                 self.standard_logout)
 4456 
 4457     def test_manage_existing_volume_type_exception(self):
 4458         mock_client = self.setup_driver()
 4459 
 4460         comment = repr({"display_name": "Foo Volume"})
 4461         volume = {'display_name': None,
 4462                   'volume_type': 'gold',
 4463                   'volume_type_id': 'bcfa9fa4-54a0-4340-a3d8-bfcf19aea65e',
 4464                   'id': '007dbfce-7579-40bc-8f90-a20b3902283e'}
 4465 
 4466         mock_client.getVolume.return_value = {'comment': comment}
 4467 
 4468         with mock.patch.object(hpecommon.HPE3PARCommon,
 4469                                '_create_client') as mock_create_client:
 4470             mock_create_client.return_value = mock_client
 4471             common = self.driver._login()
 4472             unm_matcher = common._get_3par_unm_name(self.volume['id'])
 4473             existing_ref = {'source-name': unm_matcher}
 4474 
 4475             self.assertRaises(exception.ManageExistingVolumeTypeMismatch,
 4476                               self.driver.manage_existing,
 4477                               volume=volume,
 4478                               existing_ref=existing_ref)
 4479 
 4480             expected = [mock.call.getVolume(existing_ref['source-name'])]
 4481 
 4482             mock_client.assert_has_calls(
 4483                 self.standard_login +
 4484                 expected +
 4485                 self.standard_logout)
 4486 
 4487     @mock.patch.object(volume_types, 'get_volume_type')
 4488     def test_manage_existing_retype_exception(self, _mock_volume_types):
 4489         mock_client = self.setup_driver()
 4490         _mock_volume_types.return_value = {
 4491             'name': 'gold',
 4492             'id': 'gold-id',
 4493             'extra_specs': {
 4494                 'cpg': HPE3PAR_CPG,
 4495                 'snap_cpg': HPE3PAR_CPG_SNAP,
 4496                 'vvs_name': self.VVS_NAME,
 4497                 'qos': self.QOS,
 4498                 'tpvv': True,
 4499                 'tdvv': False,
 4500                 'volume_type': self.volume_type}}
 4501 
 4502         volume = {'display_name': None,
 4503                   'host': 'stack1@3pariscsi#POOL1',
 4504                   'volume_type': 'gold',
 4505                   'volume_type_id': 'bcfa9fa4-54a0-4340-a3d8-bfcf19aea65e',
 4506                   'id': '007dbfce-7579-40bc-8f90-a20b3902283e'}
 4507 
 4508         mock_client.getVolume.return_value = self.MANAGE_VOLUME_INFO
 4509         mock_client.modifyVolume.return_value = ("anyResponse", {'taskid': 1})
 4510         mock_client.getTask.return_value = self.STATUS_DONE
 4511         mock_client.getCPG.side_effect = [
 4512             {'domain': 'domain1'},
 4513             {'domain': 'domain2'},
 4514             {'domain': 'domain3'},
 4515         ]
 4516 
 4517         with mock.patch.object(hpecommon.HPE3PARCommon,
 4518                                '_create_client') as mock_create_client:
 4519             mock_create_client.return_value = mock_client
 4520             common = self.driver._login()
 4521 
 4522             unm_matcher = common._get_3par_unm_name(self.volume['id'])
 4523             osv_matcher = common._get_3par_vol_name(volume['id'])
 4524 
 4525             existing_ref = {'source-name': unm_matcher}
 4526 
 4527             self.assertRaises(exception.Invalid3PARDomain,
 4528                               self.driver.manage_existing,
 4529                               volume=volume,
 4530                               existing_ref=existing_ref)
 4531 
 4532             expected = [
 4533 
 4534                 mock.call.getVolume(unm_matcher),
 4535                 mock.call.modifyVolume(
 4536                     unm_matcher, {
 4537                         'newName': osv_matcher,
 4538                         'comment': mock.ANY}),
 4539                 mock.call.getCPG('POOL1'),
 4540                 mock.call.getVolume(osv_matcher),
 4541                 mock.call.getCPG('testUserCpg0'),
 4542                 mock.call.getCPG('POOL1'),
 4543                 mock.call.modifyVolume(
 4544                     osv_matcher, {'newName': unm_matcher,
 4545                                   'comment': self.MANAGE_VOLUME_INFO
 4546                                   ['comment']})
 4547             ]
 4548 
 4549             mock_client.assert_has_calls(
 4550                 self.standard_login +
 4551                 expected +
 4552                 self.standard_logout)
 4553 
 4554     def test_manage_existing_snapshot(self):
 4555         mock_client = self.setup_driver()
 4556 
 4557         new_comment = Comment({
 4558             "display_name": "snap",
 4559             "volume_name": self.VOLUME_NAME,
 4560             "volume_id": self.VOLUME_ID,
 4561             "description": "",
 4562         })
 4563 
 4564         volume = {'id': self.VOLUME_ID}
 4565 
 4566         snapshot = {
 4567             'display_name': None,
 4568             'id': self.SNAPSHOT_ID,
 4569             'volume': volume,
 4570         }
 4571 
 4572         mock_client.getVolume.return_value = {
 4573             "comment": "{'display_name': 'snap'}",
 4574             'copyOf': self.VOLUME_NAME_3PAR,
 4575         }
 4576 
 4577         with mock.patch.object(hpecommon.HPE3PARCommon,
 4578                                '_create_client') as mock_create_client:
 4579             mock_create_client.return_value = mock_client
 4580             common = self.driver._login()
 4581 
 4582             oss_matcher = common._get_3par_snap_name(snapshot['id'])
 4583             ums_matcher = common._get_3par_ums_name(snapshot['id'])
 4584             existing_ref = {'source-name': ums_matcher}
 4585             expected_obj = {'display_name': 'snap'}
 4586 
 4587             obj = self.driver.manage_existing_snapshot(snapshot, existing_ref)
 4588 
 4589             expected = [
 4590                 mock.call.getVolume(existing_ref['source-name']),
 4591                 mock.call.modifyVolume(existing_ref['source-name'],
 4592                                        {'newName': oss_matcher,
 4593                                         'comment': new_comment}),
 4594             ]
 4595             mock_client.assert_has_calls(
 4596                 self.standard_login +
 4597                 expected +
 4598                 self.standard_logout)
 4599             self.assertEqual(expected_obj, obj)
 4600 
 4601     def test_manage_existing_snapshot_invalid_parent(self):
 4602         mock_client = self.setup_driver()
 4603 
 4604         volume = {'id': self.VOLUME_ID}
 4605 
 4606         snapshot = {
 4607             'display_name': None,
 4608             'id': '007dbfce-7579-40bc-8f90-a20b3902283e',
 4609             'volume': volume,
 4610         }
 4611 
 4612         mock_client.getVolume.return_value = {
 4613             "comment": "{'display_name': 'snap'}",
 4614             'copyOf': 'fake-invalid',
 4615         }
 4616 
 4617         with mock.patch.object(hpecommon.HPE3PARCommon,
 4618                                '_create_client') as mock_create_client:
 4619             mock_create_client.return_value = mock_client
 4620             common = self.driver._login()
 4621 
 4622             ums_matcher = common._get_3par_ums_name(snapshot['id'])
 4623             existing_ref = {'source-name': ums_matcher}
 4624 
 4625             self.assertRaises(exception.InvalidInput,
 4626                               self.driver.manage_existing_snapshot,
 4627                               snapshot=snapshot,
 4628                               existing_ref=existing_ref)
 4629 
 4630             expected = [
 4631                 mock.call.getVolume(existing_ref['source-name']),
 4632             ]
 4633 
 4634             mock_client.assert_has_calls(
 4635                 self.standard_login +
 4636                 expected +
 4637                 self.standard_logout)
 4638 
 4639     def test_manage_existing_snapshot_failed_over_volume(self):
 4640         mock_client = self.setup_driver()
 4641 
 4642         volume = {
 4643             'id': self.VOLUME_ID,
 4644             'replication_status': 'failed-over',
 4645         }
 4646 
 4647         snapshot = {
 4648             'display_name': None,
 4649             'id': '007dbfce-7579-40bc-8f90-a20b3902283e',
 4650             'volume': volume,
 4651         }
 4652 
 4653         mock_client.getVolume.return_value = {
 4654             "comment": "{'display_name': 'snap'}",
 4655             'copyOf': self.VOLUME_NAME_3PAR,
 4656         }
 4657 
 4658         with mock.patch.object(hpecommon.HPE3PARCommon,
 4659                                '_create_client') as mock_create_client:
 4660             mock_create_client.return_value = mock_client
 4661             common = self.driver._login()
 4662 
 4663             ums_matcher = common._get_3par_ums_name(snapshot['id'])
 4664             existing_ref = {'source-name': ums_matcher}
 4665 
 4666             self.assertRaises(exception.InvalidInput,
 4667                               self.driver.manage_existing_snapshot,
 4668                               snapshot=snapshot,
 4669                               existing_ref=existing_ref)
 4670 
 4671     def test_manage_existing_get_size(self):
 4672         mock_client = self.setup_driver()
 4673         mock_client.getVolume.return_value = {'sizeMiB': 2048}
 4674 
 4675         with mock.patch.object(hpecommon.HPE3PARCommon,
 4676                                '_create_client') as mock_create_client:
 4677             mock_create_client.return_value = mock_client
 4678             common = self.driver._login()
 4679             unm_matcher = common._get_3par_unm_name(self.volume['id'])
 4680             volume = {}
 4681             existing_ref = {'source-name': unm_matcher}
 4682 
 4683             size = self.driver.manage_existing_get_size(volume, existing_ref)
 4684 
 4685             expected_size = 2
 4686             expected = [mock.call.getVolume(existing_ref['source-name'])]
 4687 
 4688             mock_client.assert_has_calls(
 4689                 self.standard_login +
 4690                 expected +
 4691                 self.standard_logout)
 4692             self.assertEqual(expected_size, size)
 4693 
 4694     def test_manage_existing_get_size_invalid_reference(self):
 4695         mock_client = self.setup_driver()
 4696         with mock.patch.object(hpecommon.HPE3PARCommon,
 4697                                '_create_client') as mock_create_client:
 4698             mock_create_client.return_value = mock_client
 4699             volume = {}
 4700             existing_ref = {'source-name': self.VOLUME_3PAR_NAME}
 4701 
 4702             self.assertRaises(exception.ManageExistingInvalidReference,
 4703                               self.driver.manage_existing_get_size,
 4704                               volume=volume,
 4705                               existing_ref=existing_ref)
 4706 
 4707             mock_client.assert_has_calls(
 4708                 self.standard_login +
 4709                 self.standard_logout)
 4710 
 4711             existing_ref = {}
 4712 
 4713             self.assertRaises(exception.ManageExistingInvalidReference,
 4714                               self.driver.manage_existing_get_size,
 4715                               volume=volume,
 4716                               existing_ref=existing_ref)
 4717 
 4718             mock_client.assert_has_calls(
 4719                 self.standard_login +
 4720                 self.standard_logout)
 4721 
 4722     def test_manage_existing_get_size_invalid_input(self):
 4723         mock_client = self.setup_driver()
 4724         mock_client.getVolume.side_effect = hpeexceptions.HTTPNotFound('fake')
 4725 
 4726         with mock.patch.object(hpecommon.HPE3PARCommon,
 4727                                '_create_client') as mock_create_client:
 4728             mock_create_client.return_value = mock_client
 4729             common = self.driver._login()
 4730             unm_matcher = common._get_3par_unm_name(self.volume['id'])
 4731             volume = {}
 4732             existing_ref = {'source-name': unm_matcher}
 4733 
 4734             self.assertRaises(exception.InvalidInput,
 4735                               self.driver.manage_existing_get_size,
 4736                               volume=volume,
 4737                               existing_ref=existing_ref)
 4738 
 4739             expected = [mock.call.getVolume(existing_ref['source-name'])]
 4740 
 4741             mock_client.assert_has_calls(
 4742                 self.standard_login +
 4743                 expected +
 4744                 self.standard_logout)
 4745 
 4746     def test_manage_existing_snapshot_get_size(self):
 4747         mock_client = self.setup_driver()
 4748         mock_client.getVolume.return_value = {'sizeMiB': 2048}
 4749 
 4750         with mock.patch.object(hpecommon.HPE3PARCommon,
 4751                                '_create_client') as mock_create_client:
 4752             mock_create_client.return_value = mock_client
 4753             common = self.driver._login()
 4754 
 4755             ums_matcher = common._get_3par_ums_name(self.snapshot['id'])
 4756             snapshot = {}
 4757             existing_ref = {'source-name': ums_matcher}
 4758 
 4759             size = self.driver.manage_existing_snapshot_get_size(snapshot,
 4760                                                                  existing_ref)
 4761 
 4762             expected_size = 2
 4763             expected = [mock.call.getVolume(existing_ref['source-name'])]
 4764 
 4765             mock_client.assert_has_calls(
 4766                 self.standard_login +
 4767                 expected +
 4768                 self.standard_logout)
 4769             self.assertEqual(expected_size, size)
 4770 
 4771     def test_manage_existing_snapshot_get_size_invalid_reference(self):
 4772         mock_client = self.setup_driver()
 4773 
 4774         with mock.patch.object(hpecommon.HPE3PARCommon,
 4775                                '_create_client') as mock_create_client:
 4776             mock_create_client.return_value = mock_client
 4777 
 4778             snapshot = {}
 4779             existing_ref = {'source-name': self.SNAPSHOT_3PAR_NAME}
 4780 
 4781             self.assertRaises(exception.ManageExistingInvalidReference,
 4782                               self.driver.manage_existing_snapshot_get_size,
 4783                               snapshot=snapshot,
 4784                               existing_ref=existing_ref)
 4785 
 4786             mock_client.assert_has_calls(
 4787                 self.standard_login +
 4788                 self.standard_logout)
 4789 
 4790             existing_ref = {}
 4791 
 4792             self.assertRaises(exception.ManageExistingInvalidReference,
 4793                               self.driver.manage_existing_snapshot_get_size,
 4794                               snapshot=snapshot,
 4795                               existing_ref=existing_ref)
 4796 
 4797             mock_client.assert_has_calls(
 4798                 self.standard_login +
 4799                 self.standard_logout)
 4800 
 4801     def test_manage_existing_snapshot_get_size_invalid_input(self):
 4802         mock_client = self.setup_driver()
 4803         mock_client.getVolume.side_effect = hpeexceptions.HTTPNotFound('fake')
 4804 
 4805         with mock.patch.object(hpecommon.HPE3PARCommon,
 4806                                '_create_client') as mock_create_client:
 4807             mock_create_client.return_value = mock_client
 4808             common = self.driver._login()
 4809 
 4810             ums_matcher = common._get_3par_ums_name(self.snapshot['id'])
 4811             snapshot = {}
 4812             existing_ref = {'source-name': ums_matcher}
 4813 
 4814             self.assertRaises(exception.InvalidInput,
 4815                               self.driver.manage_existing_snapshot_get_size,
 4816                               snapshot=snapshot,
 4817                               existing_ref=existing_ref)
 4818 
 4819             expected = [mock.call.getVolume(existing_ref['source-name'])]
 4820 
 4821             mock_client.assert_has_calls(
 4822                 self.standard_login +
 4823                 expected +
 4824                 self.standard_logout)
 4825 
 4826     def test_unmanage(self):
 4827         mock_client = self.setup_driver()
 4828         with mock.patch.object(hpecommon.HPE3PARCommon,
 4829                                '_create_client') as mock_create_client:
 4830             mock_create_client.return_value = mock_client
 4831             common = self.driver._login()
 4832             self.driver.unmanage(self.volume)
 4833 
 4834             osv_matcher = common._get_3par_vol_name(self.volume['id'])
 4835             unm_matcher = common._get_3par_unm_name(self.volume['id'])
 4836 
 4837             expected = [
 4838                 mock.call.modifyVolume(osv_matcher, {'newName': unm_matcher})
 4839             ]
 4840 
 4841             mock_client.assert_has_calls(
 4842                 self.standard_login +
 4843                 expected +
 4844                 self.standard_logout)
 4845 
 4846     def test_unmanage_snapshot(self):
 4847         mock_client = self.setup_driver()
 4848         with mock.patch.object(hpecommon.HPE3PARCommon,
 4849                                '_create_client') as mock_create_client:
 4850             mock_create_client.return_value = mock_client
 4851             common = self.driver._login()
 4852             self.driver.unmanage_snapshot(self.snapshot)
 4853 
 4854             oss_matcher = common._get_3par_snap_name(self.snapshot['id'])
 4855             ums_matcher = common._get_3par_ums_name(self.snapshot['id'])
 4856 
 4857             expected = [
 4858                 mock.call.modifyVolume(oss_matcher, {'newName': ums_matcher})
 4859             ]
 4860 
 4861             mock_client.assert_has_calls(
 4862                 self.standard_login +
 4863                 expected +
 4864                 self.standard_logout)
 4865 
 4866     def test_unmanage_snapshot_failed_over_volume(self):
 4867         mock_client = self.setup_driver()
 4868 
 4869         volume = {'replication_status': 'failed-over', }
 4870         snapshot = {'id': self.SNAPSHOT_ID,
 4871                     'display_name': 'fake_snap',
 4872                     'volume': volume, }
 4873 
 4874         with mock.patch.object(hpecommon.HPE3PARCommon,
 4875                                '_create_client') as mock_create_client:
 4876             mock_create_client.return_value = mock_client
 4877 
 4878             self.assertRaises(exception.SnapshotIsBusy,
 4879                               self.driver.unmanage_snapshot,
 4880                               snapshot=snapshot)
 4881 
 4882     def test__safe_hostname(self):
 4883         long_hostname = "abc123abc123abc123abc123abc123abc123"
 4884         fixed_hostname = "abc123abc123abc123abc123abc123a"
 4885         common = hpecommon.HPE3PARCommon(None)
 4886         safe_host = common._safe_hostname(long_hostname)
 4887         self.assertEqual(fixed_hostname, safe_host)
 4888 
 4889     @mock.patch('cinder.volume.drivers.hpe.hpe_3par_common.HPE3PARCommon.'
 4890                 'is_volume_group_snap_type')
 4891     @mock.patch('cinder.volume.utils.is_group_a_cg_snapshot_type')
 4892     def test_create_group(self, cg_ss_enable, vol_ss_enable):
 4893         cg_ss_enable.return_value = True
 4894         vol_ss_enable.return_value = True
 4895         mock_client = self.setup_driver()
 4896         mock_client.getStorageSystemInfo.return_value = {'id': self.CLIENT_ID}
 4897 
 4898         comment = Comment({
 4899             'group_id': self.GROUP_ID
 4900         })
 4901 
 4902         with mock.patch.object(hpecommon.HPE3PARCommon,
 4903                                '_create_client') as mock_create_client:
 4904             mock_create_client.return_value = mock_client
 4905             mock_client.getCPG.return_value = {'domain': None}
 4906             # create a group
 4907             group = self.fake_group_object()
 4908             self.driver.create_group(context.get_admin_context(), group)
 4909 
 4910             expected = [
 4911                 mock.call.getCPG(HPE3PAR_CPG),
 4912                 mock.call.createVolumeSet(
 4913                     self.CONSIS_GROUP_NAME,
 4914                     domain=None,
 4915                     comment=comment)]
 4916 
 4917             mock_client.assert_has_calls(
 4918                 self.get_id_login +
 4919                 self.standard_logout +
 4920                 self.standard_login +
 4921                 expected +
 4922                 self.standard_logout)
 4923 
 4924     @mock.patch('cinder.volume.drivers.hpe.hpe_3par_common.HPE3PARCommon.'
 4925                 'is_volume_group_snap_type')
 4926     @mock.patch('cinder.volume.utils.is_group_a_cg_snapshot_type')
 4927     def test_create_group_with_replication_enabled(self, cg_ss_enable,
 4928                                                    vol_ss_enable):
 4929         cg_ss_enable.return_value = True
 4930         vol_ss_enable.return_value = True
 4931         conf = self.setup_configuration()
 4932         self.replication_targets[0]['replication_mode'] = 'sync'
 4933         conf.replication_device = self.replication_targets
 4934         mock_client = self.setup_driver(config=conf)
 4935         mock_client.getStorageSystemInfo.return_value = (
 4936             {'id': self.CLIENT_ID})
 4937         mock_replicated_client = self.setup_driver(config=conf)
 4938         mock_replicated_client.getStorageSystemInfo.return_value = (
 4939             {'id': self.REPLICATION_CLIENT_ID})
 4940 
 4941         comment = Comment({
 4942             'group_id': self.GROUP_ID
 4943         })
 4944         mock_client.getRemoteCopyGroup.return_value = (
 4945             {'volumes': []})
 4946         with mock.patch.object(
 4947                 hpecommon.HPE3PARCommon,
 4948                 '_create_client') as mock_create_client, \
 4949             mock.patch.object(
 4950                 hpecommon.HPE3PARCommon,
 4951                 '_create_replication_client') as mock_replication_client:
 4952             mock_create_client.return_value = mock_client
 4953             mock_replication_client.return_value = mock_replicated_client
 4954             mock_client.getCPG.return_value = {'domain': None}
 4955             # create a group
 4956             group = self.fake_group_object()
 4957             group.is_replicated = True
 4958             group.volume_types = [self.volume_type_tiramisu]
 4959             backend_id = self.replication_targets[0]['backend_id']
 4960             exp_model_update = {'status': fields.GroupStatus.AVAILABLE,
 4961                                 'replication_status':