"Fossies" - the Fresh Open Source Software Archive

Member "manila-8.1.4/manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_lib_base.py" (19 Nov 2020, 236116 Bytes) of package /linux/misc/openstack/manila-8.1.4.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_lib_base.py": 8.1.3_vs_8.1.4.

    1 # Copyright (c) 2015 Clinton Knight.  All rights reserved.
    2 # Copyright (c) 2015 Tom Barron.  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 """
   16 Unit tests for the NetApp Data ONTAP cDOT base storage driver library.
   17 """
   18 
   19 import copy
   20 import json
   21 import math
   22 import socket
   23 import time
   24 
   25 import ddt
   26 import mock
   27 from oslo_log import log
   28 from oslo_service import loopingcall
   29 from oslo_utils import timeutils
   30 from oslo_utils import units
   31 from oslo_utils import uuidutils
   32 
   33 from manila.common import constants
   34 from manila import exception
   35 from manila.share.drivers.netapp.dataontap.client import api as netapp_api
   36 from manila.share.drivers.netapp.dataontap.client import client_cmode
   37 from manila.share.drivers.netapp.dataontap.cluster_mode import data_motion
   38 from manila.share.drivers.netapp.dataontap.cluster_mode import lib_base
   39 from manila.share.drivers.netapp.dataontap.cluster_mode import performance
   40 from manila.share.drivers.netapp.dataontap.protocols import cifs_cmode
   41 from manila.share.drivers.netapp.dataontap.protocols import nfs_cmode
   42 from manila.share.drivers.netapp import utils as na_utils
   43 from manila.share import share_types
   44 from manila.share import utils as share_utils
   45 from manila import test
   46 from manila.tests import fake_share
   47 from manila.tests.share.drivers.netapp.dataontap import fakes as fake
   48 from manila.tests import utils
   49 
   50 
   51 def fake_replica(**kwargs):
   52     return fake_share.fake_replica(for_manager=True, **kwargs)
   53 
   54 
   55 @ddt.ddt
   56 class NetAppFileStorageLibraryTestCase(test.TestCase):
   57 
   58     def setUp(self):
   59         super(NetAppFileStorageLibraryTestCase, self).setUp()
   60 
   61         self.mock_object(na_utils, 'validate_driver_instantiation')
   62         self.mock_object(na_utils, 'setup_tracing')
   63 
   64         # Mock loggers as themselves to allow logger arg validation
   65         mock_logger = log.getLogger('mock_logger')
   66         self.mock_object(lib_base.LOG,
   67                          'info',
   68                          mock.Mock(side_effect=mock_logger.info))
   69         self.mock_object(lib_base.LOG,
   70                          'warning',
   71                          mock.Mock(side_effect=mock_logger.warning))
   72         self.mock_object(lib_base.LOG,
   73                          'error',
   74                          mock.Mock(side_effect=mock_logger.error))
   75         self.mock_object(lib_base.LOG,
   76                          'debug',
   77                          mock.Mock(side_effect=mock_logger.debug))
   78 
   79         kwargs = {
   80             'configuration': fake.get_config_cmode(),
   81             'private_storage': mock.Mock(),
   82             'app_version': fake.APP_VERSION
   83         }
   84         self.library = lib_base.NetAppCmodeFileStorageLibrary(fake.DRIVER_NAME,
   85                                                               **kwargs)
   86         self.library._client = mock.Mock()
   87         self.library._perf_library = mock.Mock()
   88         self.client = self.library._client
   89         self.context = mock.Mock()
   90         self.fake_replica = copy.deepcopy(fake.SHARE)
   91         self.fake_replica_2 = copy.deepcopy(fake.SHARE)
   92         self.fake_replica_2['id'] = fake.SHARE_ID2
   93         self.fake_replica_2['replica_state'] = (
   94             constants.REPLICA_STATE_OUT_OF_SYNC)
   95         self.mock_dm_session = mock.Mock()
   96         self.mock_object(data_motion, "DataMotionSession",
   97                          mock.Mock(return_value=self.mock_dm_session))
   98         self.mock_object(data_motion, 'get_client_for_backend')
   99 
  100     def _mock_api_error(self, code='fake', message='fake'):
  101         return mock.Mock(side_effect=netapp_api.NaApiError(code=code,
  102                                                            message=message))
  103 
  104     def test_init(self):
  105         self.assertEqual(fake.DRIVER_NAME, self.library.driver_name)
  106         self.assertEqual(1, na_utils.validate_driver_instantiation.call_count)
  107         self.assertEqual(1, na_utils.setup_tracing.call_count)
  108         self.assertListEqual([], self.library._licenses)
  109         self.assertDictEqual({}, self.library._clients)
  110         self.assertDictEqual({}, self.library._ssc_stats)
  111         self.assertIsNotNone(self.library._app_version)
  112 
  113     def test_do_setup(self):
  114         mock_get_api_client = self.mock_object(self.library, '_get_api_client')
  115         self.mock_object(
  116             performance, 'PerformanceLibrary',
  117             mock.Mock(return_value='fake_perf_library'))
  118         self.mock_object(
  119             self.library._client, 'check_for_cluster_credentials',
  120             mock.Mock(return_value=True))
  121         self.mock_object(
  122             self.library, '_check_snaprestore_license',
  123             mock.Mock(return_value=True))
  124         self.mock_object(
  125             self.library,
  126             '_get_licenses',
  127             mock.Mock(return_value=fake.LICENSES))
  128         self.library.do_setup(self.context)
  129 
  130         self.assertEqual(fake.LICENSES, self.library._licenses)
  131         mock_get_api_client.assert_called_once_with()
  132         (self.library._client.check_for_cluster_credentials.
  133             assert_called_once_with())
  134         self.assertEqual('fake_perf_library', self.library._perf_library)
  135         self.mock_object(self.library._client,
  136                          'check_for_cluster_credentials',
  137                          mock.Mock(return_value=True))
  138         self.mock_object(
  139             self.library, '_check_snaprestore_license',
  140             mock.Mock(return_value=True))
  141         mock_set_cluster_info = self.mock_object(
  142             self.library, '_set_cluster_info')
  143         self.library.do_setup(self.context)
  144         mock_set_cluster_info.assert_called_once()
  145 
  146     def test_set_cluster_info(self):
  147         self.library._set_cluster_info()
  148         self.assertTrue(self.library._cluster_info['nve_support'],
  149                         fake.CLUSTER_NODES)
  150 
  151     def test_check_for_setup_error(self):
  152         mock_start_periodic_tasks = self.mock_object(self.library,
  153                                                      '_start_periodic_tasks')
  154         self.library.check_for_setup_error()
  155 
  156         mock_start_periodic_tasks.assert_called_once_with()
  157 
  158     def test_get_vserver(self):
  159         self.assertRaises(NotImplementedError, self.library._get_vserver)
  160 
  161     def test_get_api_client(self):
  162 
  163         client_kwargs = fake.CLIENT_KWARGS.copy()
  164 
  165         # First call should proceed normally.
  166         mock_client_constructor = self.mock_object(client_cmode,
  167                                                    'NetAppCmodeClient')
  168         client1 = self.library._get_api_client()
  169         self.assertIsNotNone(client1)
  170         mock_client_constructor.assert_called_once_with(**client_kwargs)
  171 
  172         # Second call should yield the same object.
  173         mock_client_constructor = self.mock_object(client_cmode,
  174                                                    'NetAppCmodeClient')
  175         client2 = self.library._get_api_client()
  176         self.assertEqual(client1, client2)
  177         self.assertFalse(mock_client_constructor.called)
  178 
  179     def test_get_api_client_with_vserver(self):
  180 
  181         client_kwargs = fake.CLIENT_KWARGS.copy()
  182         client_kwargs['vserver'] = fake.VSERVER1
  183 
  184         # First call should proceed normally.
  185         mock_client_constructor = self.mock_object(client_cmode,
  186                                                    'NetAppCmodeClient')
  187         client1 = self.library._get_api_client(vserver=fake.VSERVER1)
  188         self.assertIsNotNone(client1)
  189         mock_client_constructor.assert_called_once_with(**client_kwargs)
  190 
  191         # Second call should yield the same object.
  192         mock_client_constructor = self.mock_object(client_cmode,
  193                                                    'NetAppCmodeClient')
  194         client2 = self.library._get_api_client(vserver=fake.VSERVER1)
  195         self.assertEqual(client1, client2)
  196         self.assertFalse(mock_client_constructor.called)
  197 
  198         # A different vserver should work normally without caching.
  199         mock_client_constructor = self.mock_object(client_cmode,
  200                                                    'NetAppCmodeClient')
  201         client3 = self.library._get_api_client(vserver=fake.VSERVER2)
  202         self.assertNotEqual(client1, client3)
  203         client_kwargs['vserver'] = fake.VSERVER2
  204         mock_client_constructor.assert_called_once_with(**client_kwargs)
  205 
  206     def test_get_licenses_both_protocols(self):
  207         self.library._have_cluster_creds = True
  208         self.mock_object(self.client,
  209                          'get_licenses',
  210                          mock.Mock(return_value=fake.LICENSES))
  211 
  212         result = self.library._get_licenses()
  213 
  214         self.assertSequenceEqual(fake.LICENSES, result)
  215         self.assertEqual(0, lib_base.LOG.error.call_count)
  216         self.assertEqual(1, lib_base.LOG.info.call_count)
  217 
  218     def test_get_licenses_one_protocol(self):
  219         self.library._have_cluster_creds = True
  220         licenses = list(fake.LICENSES)
  221         licenses.remove('nfs')
  222         self.mock_object(self.client,
  223                          'get_licenses',
  224                          mock.Mock(return_value=licenses))
  225 
  226         result = self.library._get_licenses()
  227 
  228         self.assertListEqual(licenses, result)
  229         self.assertEqual(0, lib_base.LOG.error.call_count)
  230         self.assertEqual(1, lib_base.LOG.info.call_count)
  231 
  232     def test_get_licenses_no_protocols(self):
  233         self.library._have_cluster_creds = True
  234         licenses = list(fake.LICENSES)
  235         licenses.remove('nfs')
  236         licenses.remove('cifs')
  237         self.mock_object(self.client,
  238                          'get_licenses',
  239                          mock.Mock(return_value=licenses))
  240 
  241         result = self.library._get_licenses()
  242 
  243         self.assertListEqual(licenses, result)
  244         self.assertEqual(1, lib_base.LOG.error.call_count)
  245         self.assertEqual(1, lib_base.LOG.info.call_count)
  246 
  247     def test_get_licenses_no_cluster_creds(self):
  248         self.library._have_cluster_creds = False
  249 
  250         result = self.library._get_licenses()
  251 
  252         self.assertListEqual([], result)
  253         self.assertEqual(1, lib_base.LOG.debug.call_count)
  254 
  255     def test_start_periodic_tasks(self):
  256 
  257         mock_update_ssc_info = self.mock_object(self.library,
  258                                                 '_update_ssc_info')
  259         mock_handle_ems_logging = self.mock_object(self.library,
  260                                                    '_handle_ems_logging')
  261         mock_handle_housekeeping_tasks = self.mock_object(
  262             self.library, '_handle_housekeeping_tasks')
  263         mock_ssc_periodic_task = mock.Mock()
  264         mock_ems_periodic_task = mock.Mock()
  265         mock_housekeeping_periodic_task = mock.Mock()
  266         mock_loopingcall = self.mock_object(
  267             loopingcall,
  268             'FixedIntervalLoopingCall',
  269             mock.Mock(side_effect=[mock_ssc_periodic_task,
  270                                    mock_ems_periodic_task,
  271                                    mock_housekeeping_periodic_task]))
  272 
  273         self.library._start_periodic_tasks()
  274 
  275         self.assertTrue(mock_update_ssc_info.called)
  276         self.assertFalse(mock_handle_ems_logging.called)
  277         self.assertFalse(mock_housekeeping_periodic_task.called)
  278         mock_loopingcall.assert_has_calls(
  279             [mock.call(mock_update_ssc_info),
  280              mock.call(mock_handle_ems_logging),
  281              mock.call(mock_handle_housekeeping_tasks)])
  282         self.assertTrue(mock_ssc_periodic_task.start.called)
  283         self.assertTrue(mock_ems_periodic_task.start.called)
  284         self.assertTrue(mock_housekeeping_periodic_task.start.called)
  285 
  286     def test_get_backend_share_name(self):
  287 
  288         result = self.library._get_backend_share_name(fake.SHARE_ID)
  289         expected = (fake.VOLUME_NAME_TEMPLATE %
  290                     {'share_id': fake.SHARE_ID.replace('-', '_')})
  291 
  292         self.assertEqual(expected, result)
  293 
  294     def test_get_backend_snapshot_name(self):
  295 
  296         result = self.library._get_backend_snapshot_name(fake.SNAPSHOT_ID)
  297         expected = 'share_snapshot_' + fake.SNAPSHOT_ID.replace('-', '_')
  298 
  299         self.assertEqual(expected, result)
  300 
  301     def test_get_backend_cg_snapshot_name(self):
  302 
  303         result = self.library._get_backend_cg_snapshot_name(fake.SNAPSHOT_ID)
  304         expected = 'share_cg_snapshot_' + fake.SNAPSHOT_ID.replace('-', '_')
  305 
  306         self.assertEqual(expected, result)
  307 
  308     def test_get_aggregate_space_cluster_creds(self):
  309 
  310         self.library._have_cluster_creds = True
  311         self.mock_object(self.library,
  312                          '_find_matching_aggregates',
  313                          mock.Mock(return_value=fake.AGGREGATES))
  314         self.mock_object(self.library._client,
  315                          'get_cluster_aggregate_capacities',
  316                          mock.Mock(return_value=fake.AGGREGATE_CAPACITIES))
  317 
  318         result = self.library._get_aggregate_space()
  319 
  320         (self.library._client.get_cluster_aggregate_capacities.
  321             assert_called_once_with(fake.AGGREGATES))
  322         self.assertDictEqual(fake.AGGREGATE_CAPACITIES, result)
  323 
  324     def test_get_aggregate_space_no_cluster_creds(self):
  325 
  326         self.library._have_cluster_creds = False
  327         self.mock_object(self.library,
  328                          '_find_matching_aggregates',
  329                          mock.Mock(return_value=fake.AGGREGATES))
  330         self.mock_object(self.library._client,
  331                          'get_vserver_aggregate_capacities',
  332                          mock.Mock(return_value=fake.AGGREGATE_CAPACITIES))
  333 
  334         result = self.library._get_aggregate_space()
  335 
  336         (self.library._client.get_vserver_aggregate_capacities.
  337             assert_called_once_with(fake.AGGREGATES))
  338         self.assertDictEqual(fake.AGGREGATE_CAPACITIES, result)
  339 
  340     def test_check_snaprestore_license_admin_notfound(self):
  341         self.library._have_cluster_creds = True
  342         licenses = list(fake.LICENSES)
  343         licenses.remove('snaprestore')
  344         self.mock_object(self.client,
  345                          'get_licenses',
  346                          mock.Mock(return_value=licenses))
  347         result = self.library._check_snaprestore_license()
  348         self.assertIs(False, result)
  349 
  350     def test_check_snaprestore_license_admin_found(self):
  351         self.library._have_cluster_creds = True
  352         self.library._licenses = fake.LICENSES
  353         result = self.library._check_snaprestore_license()
  354         self.assertIs(True, result)
  355 
  356     def test_check_snaprestore_license_svm_scoped_notfound(self):
  357         self.library._have_cluster_creds = False
  358         self.mock_object(self.library._client,
  359                          'restore_snapshot',
  360                          mock.Mock(side_effect=netapp_api.NaApiError(
  361                                    code=netapp_api.EAPIERROR,
  362                                    message=fake.NO_SNAPRESTORE_LICENSE)))
  363         result = self.library._check_snaprestore_license()
  364         self.assertIs(False, result)
  365 
  366     def test_check_snaprestore_license_svm_scoped_found(self):
  367         self.library._have_cluster_creds = False
  368         self.mock_object(self.library._client,
  369                          'restore_snapshot',
  370                          mock.Mock(side_effect=netapp_api.NaApiError(
  371                                    code=netapp_api.EAPIERROR,
  372                                    message='Other error')))
  373         result = self.library._check_snaprestore_license()
  374         self.assertIs(True, result)
  375 
  376     def test_check_snaprestore_license_svm_scoped_found_exception(self):
  377         self.mock_object(lib_base.LOG, 'exception')
  378         self.library._have_cluster_creds = False
  379         self.mock_object(self.library._client,
  380                          'restore_snapshot',
  381                          mock.Mock(return_value=None))
  382 
  383         self.assertRaises(
  384             exception.NetAppException,
  385             self.library._check_snaprestore_license)
  386         lib_base.LOG.exception.assert_called_once()
  387 
  388     def test_get_aggregate_node_cluster_creds(self):
  389 
  390         self.library._have_cluster_creds = True
  391         self.mock_object(self.library._client,
  392                          'get_node_for_aggregate',
  393                          mock.Mock(return_value=fake.CLUSTER_NODE))
  394 
  395         result = self.library._get_aggregate_node(fake.AGGREGATE)
  396 
  397         (self.library._client.get_node_for_aggregate.
  398             assert_called_once_with(fake.AGGREGATE))
  399         self.assertEqual(fake.CLUSTER_NODE, result)
  400 
  401     def test_get_aggregate_node_no_cluster_creds(self):
  402 
  403         self.library._have_cluster_creds = False
  404         self.mock_object(self.library._client, 'get_node_for_aggregate')
  405 
  406         result = self.library._get_aggregate_node(fake.AGGREGATE)
  407 
  408         self.assertFalse(self.library._client.get_node_for_aggregate.called)
  409         self.assertIsNone(result)
  410 
  411     def test_get_default_filter_function(self):
  412 
  413         result = self.library.get_default_filter_function()
  414 
  415         self.assertEqual(self.library.DEFAULT_FILTER_FUNCTION, result)
  416 
  417     def test_get_default_goodness_function(self):
  418 
  419         result = self.library.get_default_goodness_function()
  420 
  421         self.assertEqual(self.library.DEFAULT_GOODNESS_FUNCTION, result)
  422 
  423     def test_get_share_stats(self):
  424 
  425         mock_get_pools = self.mock_object(
  426             self.library, '_get_pools',
  427             mock.Mock(return_value=fake.POOLS))
  428 
  429         result = self.library.get_share_stats(filter_function='filter',
  430                                               goodness_function='goodness')
  431 
  432         expected = {
  433             'share_backend_name': fake.BACKEND_NAME,
  434             'driver_name': fake.DRIVER_NAME,
  435             'vendor_name': 'NetApp',
  436             'driver_version': '1.0',
  437             'netapp_storage_family': 'ontap_cluster',
  438             'storage_protocol': 'NFS_CIFS',
  439             'pools': fake.POOLS,
  440             'share_group_stats': {'consistent_snapshot_support': 'host'},
  441         }
  442         self.assertDictEqual(expected, result)
  443         mock_get_pools.assert_called_once_with(filter_function='filter',
  444                                                goodness_function='goodness')
  445 
  446     def test_get_share_stats_with_replication(self):
  447 
  448         self.library.configuration.replication_domain = "fake_domain"
  449         mock_get_pools = self.mock_object(
  450             self.library, '_get_pools',
  451             mock.Mock(return_value=fake.POOLS))
  452 
  453         result = self.library.get_share_stats(filter_function='filter',
  454                                               goodness_function='goodness')
  455 
  456         expected = {
  457             'share_backend_name': fake.BACKEND_NAME,
  458             'driver_name': fake.DRIVER_NAME,
  459             'vendor_name': 'NetApp',
  460             'driver_version': '1.0',
  461             'netapp_storage_family': 'ontap_cluster',
  462             'storage_protocol': 'NFS_CIFS',
  463             'replication_type': 'dr',
  464             'replication_domain': 'fake_domain',
  465             'pools': fake.POOLS,
  466             'share_group_stats': {'consistent_snapshot_support': 'host'},
  467         }
  468         self.assertDictEqual(expected, result)
  469         mock_get_pools.assert_called_once_with(filter_function='filter',
  470                                                goodness_function='goodness')
  471 
  472     def test_get_share_server_pools(self):
  473 
  474         self.mock_object(self.library,
  475                          '_get_pools',
  476                          mock.Mock(return_value=fake.POOLS))
  477 
  478         result = self.library.get_share_server_pools(fake.SHARE_SERVER)
  479 
  480         self.assertListEqual(fake.POOLS, result)
  481 
  482     def test_get_pools(self):
  483 
  484         self.mock_object(
  485             self.library, '_get_aggregate_space',
  486             mock.Mock(return_value=fake.AGGREGATE_CAPACITIES))
  487         self.library._have_cluster_creds = True
  488         self.library._revert_to_snapshot_support = True
  489         self.library._cluster_info = fake.CLUSTER_INFO
  490         self.library._ssc_stats = fake.SSC_INFO
  491         self.library._perf_library.get_node_utilization_for_pool = (
  492             mock.Mock(side_effect=[30.0, 42.0]))
  493 
  494         result = self.library._get_pools(filter_function='filter',
  495                                          goodness_function='goodness')
  496 
  497         self.assertListEqual(fake.POOLS, result)
  498 
  499     def test_get_pools_vserver_creds(self):
  500 
  501         self.mock_object(
  502             self.library, '_get_aggregate_space',
  503             mock.Mock(return_value=fake.AGGREGATE_CAPACITIES_VSERVER_CREDS))
  504         self.library._have_cluster_creds = False
  505         self.library._revert_to_snapshot_support = True
  506         self.library._cluster_info = fake.CLUSTER_INFO
  507         self.library._ssc_stats = fake.SSC_INFO_VSERVER_CREDS
  508         self.library._perf_library.get_node_utilization_for_pool = (
  509             mock.Mock(side_effect=[50.0, 50.0]))
  510 
  511         result = self.library._get_pools()
  512 
  513         self.assertListEqual(fake.POOLS_VSERVER_CREDS, result)
  514 
  515     def test_handle_ems_logging(self):
  516 
  517         self.mock_object(self.library,
  518                          '_build_ems_log_message_0',
  519                          mock.Mock(return_value=fake.EMS_MESSAGE_0))
  520         self.mock_object(self.library,
  521                          '_build_ems_log_message_1',
  522                          mock.Mock(return_value=fake.EMS_MESSAGE_1))
  523 
  524         self.library._handle_ems_logging()
  525 
  526         self.library._client.send_ems_log_message.assert_has_calls([
  527             mock.call(fake.EMS_MESSAGE_0),
  528             mock.call(fake.EMS_MESSAGE_1),
  529         ])
  530 
  531     def test_build_ems_log_message_0(self):
  532 
  533         self.mock_object(socket,
  534                          'gethostname',
  535                          mock.Mock(return_value=fake.HOST_NAME))
  536 
  537         result = self.library._build_ems_log_message_0()
  538 
  539         self.assertDictEqual(fake.EMS_MESSAGE_0, result)
  540 
  541     def test_build_ems_log_message_1(self):
  542 
  543         pool_info = {
  544             'pools': {
  545                 'vserver': 'fake_vserver',
  546                 'aggregates': ['aggr1', 'aggr2'],
  547             },
  548         }
  549         self.mock_object(socket,
  550                          'gethostname',
  551                          mock.Mock(return_value=fake.HOST_NAME))
  552         self.mock_object(self.library,
  553                          '_get_ems_pool_info',
  554                          mock.Mock(return_value=pool_info))
  555 
  556         result = self.library._build_ems_log_message_1()
  557 
  558         self.assertDictEqual(pool_info,
  559                              json.loads(result['event-description']))
  560         result['event-description'] = ''
  561         self.assertDictEqual(fake.EMS_MESSAGE_1, result)
  562 
  563     def test_get_ems_pool_info(self):
  564         self.assertRaises(NotImplementedError,
  565                           self.library._get_ems_pool_info)
  566 
  567     def test_find_matching_aggregates(self):
  568         self.assertRaises(NotImplementedError,
  569                           self.library._find_matching_aggregates)
  570 
  571     @ddt.data(('NFS', nfs_cmode.NetAppCmodeNFSHelper),
  572               ('nfs', nfs_cmode.NetAppCmodeNFSHelper),
  573               ('CIFS', cifs_cmode.NetAppCmodeCIFSHelper),
  574               ('cifs', cifs_cmode.NetAppCmodeCIFSHelper))
  575     @ddt.unpack
  576     def test_get_helper(self, protocol, helper_type):
  577 
  578         fake_share = fake.SHARE.copy()
  579         fake_share['share_proto'] = protocol
  580         mock_check_license_for_protocol = self.mock_object(
  581             self.library, '_check_license_for_protocol')
  582 
  583         result = self.library._get_helper(fake_share)
  584 
  585         mock_check_license_for_protocol.assert_called_once_with(
  586             protocol.lower())
  587         self.assertEqual(helper_type, type(result))
  588 
  589     def test_get_helper_invalid_protocol(self):
  590 
  591         fake_share = fake.SHARE.copy()
  592         fake_share['share_proto'] = 'iSCSI'
  593         self.mock_object(self.library, '_check_license_for_protocol')
  594 
  595         self.assertRaises(exception.NetAppException,
  596                           self.library._get_helper,
  597                           fake_share)
  598 
  599     def test_check_license_for_protocol_no_cluster_creds(self):
  600 
  601         self.library._have_cluster_creds = False
  602 
  603         result = self.library._check_license_for_protocol('fake_protocol')
  604 
  605         self.assertIsNone(result)
  606 
  607     def test_check_license_for_protocol_have_license(self):
  608 
  609         self.library._have_cluster_creds = True
  610         self.library._licenses = ['base', 'fake_protocol']
  611 
  612         result = self.library._check_license_for_protocol('FAKE_PROTOCOL')
  613 
  614         self.assertIsNone(result)
  615 
  616     def test_check_license_for_protocol_newly_licensed_protocol(self):
  617 
  618         self.library._have_cluster_creds = True
  619         self.mock_object(self.library,
  620                          '_get_licenses',
  621                          mock.Mock(return_value=['base', 'nfs']))
  622         self.library._licenses = ['base']
  623 
  624         result = self.library._check_license_for_protocol('NFS')
  625 
  626         self.assertIsNone(result)
  627         self.assertTrue(self.library._get_licenses.called)
  628 
  629     def test_check_license_for_protocol_unlicensed_protocol(self):
  630 
  631         self.library._have_cluster_creds = True
  632         self.mock_object(self.library,
  633                          '_get_licenses',
  634                          mock.Mock(return_value=['base']))
  635         self.library._licenses = ['base']
  636 
  637         self.assertRaises(exception.NetAppException,
  638                           self.library._check_license_for_protocol,
  639                           'NFS')
  640 
  641     def test_get_pool_has_pool(self):
  642         result = self.library.get_pool(fake.SHARE)
  643         self.assertEqual(fake.POOL_NAME, result)
  644         self.assertFalse(self.client.get_aggregate_for_volume.called)
  645 
  646     def test_get_pool_no_pool(self):
  647 
  648         fake_share = copy.deepcopy(fake.SHARE)
  649         fake_share['host'] = '%(host)s@%(backend)s' % {
  650             'host': fake.HOST_NAME, 'backend': fake.BACKEND_NAME}
  651         self.client.get_aggregate_for_volume.return_value = fake.POOL_NAME
  652 
  653         result = self.library.get_pool(fake_share)
  654 
  655         self.assertEqual(fake.POOL_NAME, result)
  656         self.assertTrue(self.client.get_aggregate_for_volume.called)
  657 
  658     def test_get_pool_raises(self):
  659 
  660         fake_share = copy.deepcopy(fake.SHARE)
  661         fake_share['host'] = '%(host)s@%(backend)s' % {
  662             'host': fake.HOST_NAME, 'backend': fake.BACKEND_NAME}
  663         self.client.get_aggregate_for_volume.side_effect = (
  664             exception.NetAppException)
  665 
  666         self.assertRaises(exception.NetAppException,
  667                           self.library.get_pool,
  668                           fake_share)
  669 
  670     def test_create_share(self):
  671 
  672         vserver_client = mock.Mock()
  673         self.mock_object(self.library,
  674                          '_get_vserver',
  675                          mock.Mock(return_value=(fake.VSERVER1,
  676                                                  vserver_client)))
  677         mock_allocate_container = self.mock_object(self.library,
  678                                                    '_allocate_container')
  679         mock_create_export = self.mock_object(
  680             self.library,
  681             '_create_export',
  682             mock.Mock(return_value='fake_export_location'))
  683 
  684         result = self.library.create_share(self.context,
  685                                            fake.SHARE,
  686                                            share_server=fake.SHARE_SERVER)
  687 
  688         mock_allocate_container.assert_called_once_with(fake.SHARE,
  689                                                         fake.VSERVER1,
  690                                                         vserver_client)
  691         mock_create_export.assert_called_once_with(fake.SHARE,
  692                                                    fake.SHARE_SERVER,
  693                                                    fake.VSERVER1,
  694                                                    vserver_client)
  695         self.assertEqual('fake_export_location', result)
  696 
  697     def test_create_share_from_snapshot(self):
  698 
  699         vserver_client = mock.Mock()
  700         self.mock_object(self.library,
  701                          '_get_vserver',
  702                          mock.Mock(return_value=(fake.VSERVER1,
  703                                                  vserver_client)))
  704         mock_allocate_container_from_snapshot = self.mock_object(
  705             self.library,
  706             '_allocate_container_from_snapshot')
  707         mock_create_export = self.mock_object(
  708             self.library,
  709             '_create_export',
  710             mock.Mock(return_value='fake_export_location'))
  711 
  712         result = self.library.create_share_from_snapshot(
  713             self.context,
  714             fake.SHARE,
  715             fake.SNAPSHOT,
  716             share_server=fake.SHARE_SERVER)
  717 
  718         mock_allocate_container_from_snapshot.assert_called_once_with(
  719             fake.SHARE,
  720             fake.SNAPSHOT,
  721             fake.VSERVER1,
  722             vserver_client)
  723         mock_create_export.assert_called_once_with(fake.SHARE,
  724                                                    fake.SHARE_SERVER,
  725                                                    fake.VSERVER1,
  726                                                    vserver_client)
  727         self.assertEqual('fake_export_location', result)
  728 
  729     @ddt.data(False, True)
  730     def test_allocate_container(self, hide_snapdir):
  731 
  732         provisioning_options = copy.deepcopy(fake.PROVISIONING_OPTIONS)
  733         provisioning_options['hide_snapdir'] = hide_snapdir
  734         self.mock_object(self.library, '_get_backend_share_name', mock.Mock(
  735             return_value=fake.SHARE_NAME))
  736         self.mock_object(share_utils, 'extract_host', mock.Mock(
  737             return_value=fake.POOL_NAME))
  738         mock_get_provisioning_opts = self.mock_object(
  739             self.library, '_get_provisioning_options_for_share',
  740             mock.Mock(return_value=provisioning_options))
  741         vserver_client = mock.Mock()
  742 
  743         self.library._allocate_container(fake.SHARE_INSTANCE,
  744                                          fake.VSERVER1,
  745                                          vserver_client)
  746 
  747         mock_get_provisioning_opts.assert_called_once_with(
  748             fake.SHARE_INSTANCE, fake.VSERVER1, replica=False)
  749 
  750         vserver_client.create_volume.assert_called_once_with(
  751             fake.POOL_NAME, fake.SHARE_NAME, fake.SHARE['size'],
  752             thin_provisioned=True, snapshot_policy='default',
  753             language='en-US', dedup_enabled=True, split=True, encrypt=False,
  754             compression_enabled=False, max_files=5000, snapshot_reserve=8)
  755 
  756         if hide_snapdir:
  757             vserver_client.set_volume_snapdir_access.assert_called_once_with(
  758                 fake.SHARE_NAME, hide_snapdir)
  759         else:
  760             vserver_client.set_volume_snapdir_access.assert_not_called()
  761 
  762     def test_remap_standard_boolean_extra_specs(self):
  763 
  764         extra_specs = copy.deepcopy(fake.OVERLAPPING_EXTRA_SPEC)
  765 
  766         result = self.library._remap_standard_boolean_extra_specs(extra_specs)
  767 
  768         self.assertDictEqual(fake.REMAPPED_OVERLAPPING_EXTRA_SPEC, result)
  769 
  770     def test_allocate_container_as_replica(self):
  771         self.mock_object(self.library, '_get_backend_share_name', mock.Mock(
  772             return_value=fake.SHARE_NAME))
  773         self.mock_object(share_utils, 'extract_host', mock.Mock(
  774             return_value=fake.POOL_NAME))
  775         mock_get_provisioning_opts = self.mock_object(
  776             self.library, '_get_provisioning_options_for_share',
  777             mock.Mock(return_value=copy.deepcopy(fake.PROVISIONING_OPTIONS)))
  778         vserver_client = mock.Mock()
  779 
  780         self.library._allocate_container(fake.SHARE_INSTANCE, fake.VSERVER1,
  781                                          vserver_client, replica=True)
  782 
  783         mock_get_provisioning_opts.assert_called_once_with(
  784             fake.SHARE_INSTANCE, fake.VSERVER1, replica=True)
  785 
  786         vserver_client.create_volume.assert_called_once_with(
  787             fake.POOL_NAME, fake.SHARE_NAME, fake.SHARE['size'],
  788             thin_provisioned=True, snapshot_policy='default',
  789             language='en-US', dedup_enabled=True, split=True,
  790             compression_enabled=False, max_files=5000, encrypt=False,
  791             snapshot_reserve=8, volume_type='dp')
  792 
  793     def test_allocate_container_no_pool_name(self):
  794         self.mock_object(self.library, '_get_backend_share_name', mock.Mock(
  795             return_value=fake.SHARE_NAME))
  796         self.mock_object(share_utils, 'extract_host', mock.Mock(
  797             return_value=None))
  798         self.mock_object(self.library, '_check_extra_specs_validity')
  799         self.mock_object(self.library, '_get_provisioning_options')
  800         vserver_client = mock.Mock()
  801 
  802         self.assertRaises(exception.InvalidHost,
  803                           self.library._allocate_container,
  804                           fake.SHARE_INSTANCE, fake.VSERVER1, vserver_client)
  805 
  806         self.library._get_backend_share_name.assert_called_once_with(
  807             fake.SHARE_INSTANCE['id'])
  808         share_utils.extract_host.assert_called_once_with(
  809             fake.SHARE_INSTANCE['host'], level='pool')
  810         self.assertEqual(0,
  811                          self.library._check_extra_specs_validity.call_count)
  812         self.assertEqual(0, self.library._get_provisioning_options.call_count)
  813 
  814     def test_check_extra_specs_validity(self):
  815         boolean_extra_spec_keys = list(
  816             self.library.BOOLEAN_QUALIFIED_EXTRA_SPECS_MAP)
  817         mock_bool_check = self.mock_object(
  818             self.library, '_check_boolean_extra_specs_validity')
  819         mock_string_check = self.mock_object(
  820             self.library, '_check_string_extra_specs_validity')
  821 
  822         self.library._check_extra_specs_validity(
  823             fake.SHARE_INSTANCE, fake.EXTRA_SPEC)
  824 
  825         mock_bool_check.assert_called_once_with(
  826             fake.SHARE_INSTANCE, fake.EXTRA_SPEC, boolean_extra_spec_keys)
  827         mock_string_check.assert_called_once_with(
  828             fake.SHARE_INSTANCE, fake.EXTRA_SPEC)
  829 
  830     def test_check_extra_specs_validity_empty_spec(self):
  831         result = self.library._check_extra_specs_validity(
  832             fake.SHARE_INSTANCE, fake.EMPTY_EXTRA_SPEC)
  833 
  834         self.assertIsNone(result)
  835 
  836     def test_check_extra_specs_validity_invalid_value(self):
  837         self.assertRaises(
  838             exception.Invalid, self.library._check_extra_specs_validity,
  839             fake.SHARE_INSTANCE, fake.INVALID_EXTRA_SPEC)
  840 
  841     def test_check_string_extra_specs_validity(self):
  842         result = self.library._check_string_extra_specs_validity(
  843             fake.SHARE_INSTANCE, fake.EXTRA_SPEC)
  844 
  845         self.assertIsNone(result)
  846 
  847     def test_check_string_extra_specs_validity_empty_spec(self):
  848         result = self.library._check_string_extra_specs_validity(
  849             fake.SHARE_INSTANCE, fake.EMPTY_EXTRA_SPEC)
  850 
  851         self.assertIsNone(result)
  852 
  853     def test_check_string_extra_specs_validity_invalid_value(self):
  854         self.assertRaises(
  855             exception.NetAppException,
  856             self.library._check_string_extra_specs_validity,
  857             fake.SHARE_INSTANCE, fake.INVALID_MAX_FILE_EXTRA_SPEC)
  858 
  859     def test_check_boolean_extra_specs_validity_invalid_value(self):
  860         self.assertRaises(
  861             exception.Invalid,
  862             self.library._check_boolean_extra_specs_validity,
  863             fake.SHARE_INSTANCE, fake.INVALID_EXTRA_SPEC,
  864             list(self.library.BOOLEAN_QUALIFIED_EXTRA_SPECS_MAP))
  865 
  866     def test_check_extra_specs_validity_invalid_combination(self):
  867         self.assertRaises(
  868             exception.Invalid,
  869             self.library._check_boolean_extra_specs_validity,
  870             fake.SHARE_INSTANCE, fake.INVALID_EXTRA_SPEC_COMBO,
  871             list(self.library.BOOLEAN_QUALIFIED_EXTRA_SPECS_MAP))
  872 
  873     @ddt.data({'extra_specs': fake.EXTRA_SPEC, 'is_replica': False},
  874               {'extra_specs': fake.EXTRA_SPEC_WITH_QOS, 'is_replica': True},
  875               {'extra_specs': fake.EXTRA_SPEC, 'is_replica': False},
  876               {'extra_specs': fake.EXTRA_SPEC_WITH_QOS, 'is_replica': True})
  877     @ddt.unpack
  878     def test_get_provisioning_options_for_share(self, extra_specs, is_replica):
  879 
  880         qos = True if fake.QOS_EXTRA_SPEC in extra_specs else False
  881         mock_get_extra_specs_from_share = self.mock_object(
  882             share_types, 'get_extra_specs_from_share',
  883             mock.Mock(return_value=extra_specs))
  884         mock_remap_standard_boolean_extra_specs = self.mock_object(
  885             self.library, '_remap_standard_boolean_extra_specs',
  886             mock.Mock(return_value=extra_specs))
  887         mock_check_extra_specs_validity = self.mock_object(
  888             self.library, '_check_extra_specs_validity')
  889         mock_get_provisioning_options = self.mock_object(
  890             self.library, '_get_provisioning_options',
  891             mock.Mock(return_value=fake.PROVISIONING_OPTIONS))
  892         mock_get_normalized_qos_specs = self.mock_object(
  893             self.library, '_get_normalized_qos_specs',
  894             mock.Mock(return_value={fake.QOS_NORMALIZED_SPEC: 3000}))
  895         mock_create_qos_policy_group = self.mock_object(
  896             self.library, '_create_qos_policy_group', mock.Mock(
  897                 return_value=fake.QOS_POLICY_GROUP_NAME))
  898 
  899         result = self.library._get_provisioning_options_for_share(
  900             fake.SHARE_INSTANCE, fake.VSERVER1, replica=is_replica)
  901 
  902         if qos and is_replica:
  903             expected_provisioning_opts = fake.PROVISIONING_OPTIONS
  904             self.assertFalse(mock_create_qos_policy_group.called)
  905         else:
  906             expected_provisioning_opts = fake.PROVISIONING_OPTIONS_WITH_QOS
  907             mock_create_qos_policy_group.assert_called_once_with(
  908                 fake.SHARE_INSTANCE, fake.VSERVER1,
  909                 {fake.QOS_NORMALIZED_SPEC: 3000})
  910 
  911         self.assertEqual(expected_provisioning_opts, result)
  912         mock_get_extra_specs_from_share.assert_called_once_with(
  913             fake.SHARE_INSTANCE)
  914         mock_remap_standard_boolean_extra_specs.assert_called_once_with(
  915             extra_specs)
  916         mock_check_extra_specs_validity.assert_called_once_with(
  917             fake.SHARE_INSTANCE, extra_specs)
  918         mock_get_provisioning_options.assert_called_once_with(extra_specs)
  919         mock_get_normalized_qos_specs.assert_called_once_with(extra_specs)
  920 
  921     def test_get_provisioning_options_implicit_false(self):
  922         result = self.library._get_provisioning_options(
  923             fake.EMPTY_EXTRA_SPEC)
  924 
  925         expected = {
  926             'language': None,
  927             'max_files': None,
  928             'snapshot_policy': None,
  929             'thin_provisioned': False,
  930             'compression_enabled': False,
  931             'dedup_enabled': False,
  932             'split': False,
  933             'encrypt': False,
  934             'hide_snapdir': False,
  935         }
  936 
  937         self.assertEqual(expected, result)
  938 
  939     def test_get_boolean_provisioning_options(self):
  940         result = self.library._get_boolean_provisioning_options(
  941             fake.SHORT_BOOLEAN_EXTRA_SPEC,
  942             self.library.BOOLEAN_QUALIFIED_EXTRA_SPECS_MAP)
  943 
  944         self.assertEqual(fake.PROVISIONING_OPTIONS_BOOLEAN, result)
  945 
  946     def test_get_boolean_provisioning_options_missing_spec(self):
  947         result = self.library._get_boolean_provisioning_options(
  948             fake.SHORT_BOOLEAN_EXTRA_SPEC,
  949             self.library.BOOLEAN_QUALIFIED_EXTRA_SPECS_MAP)
  950 
  951         self.assertEqual(fake.PROVISIONING_OPTIONS_BOOLEAN, result)
  952 
  953     def test_get_boolean_provisioning_options_implicit_false(self):
  954         expected = {
  955             'thin_provisioned': False,
  956             'dedup_enabled': False,
  957             'compression_enabled': False,
  958             'split': False,
  959             'hide_snapdir': False,
  960         }
  961 
  962         result = self.library._get_boolean_provisioning_options(
  963             fake.EMPTY_EXTRA_SPEC,
  964             self.library.BOOLEAN_QUALIFIED_EXTRA_SPECS_MAP)
  965 
  966         self.assertEqual(expected, result)
  967 
  968     def test_get_string_provisioning_options(self):
  969         result = self.library._get_string_provisioning_options(
  970             fake.STRING_EXTRA_SPEC,
  971             self.library.STRING_QUALIFIED_EXTRA_SPECS_MAP)
  972 
  973         self.assertEqual(fake.PROVISIONING_OPTIONS_STRING, result)
  974 
  975     def test_get_string_provisioning_options_missing_spec(self):
  976         result = self.library._get_string_provisioning_options(
  977             fake.SHORT_STRING_EXTRA_SPEC,
  978             self.library.STRING_QUALIFIED_EXTRA_SPECS_MAP)
  979 
  980         self.assertEqual(fake.PROVISIONING_OPTIONS_STRING_MISSING_SPECS,
  981                          result)
  982 
  983     def test_get_string_provisioning_options_implicit_false(self):
  984         result = self.library._get_string_provisioning_options(
  985             fake.EMPTY_EXTRA_SPEC,
  986             self.library.STRING_QUALIFIED_EXTRA_SPECS_MAP)
  987 
  988         self.assertEqual(fake.PROVISIONING_OPTIONS_STRING_DEFAULT, result)
  989 
  990     @ddt.data({}, {'foo': 'bar'}, {'netapp:maxiops': '3000'},
  991               {'qos': True, 'netapp:absiops': '3000'},
  992               {'qos': True, 'netapp:maxiops:': '3000'})
  993     def test_get_normalized_qos_specs_no_qos_specs(self, extra_specs):
  994         if 'qos' in extra_specs:
  995             self.assertRaises(exception.NetAppException,
  996                               self.library._get_normalized_qos_specs,
  997                               extra_specs)
  998         else:
  999             self.assertDictMatch(
 1000                 {}, self.library._get_normalized_qos_specs(extra_specs))
 1001 
 1002     @ddt.data({'qos': True, 'netapp:maxiops': '3000', 'netapp:maxbps': '9000'},
 1003               {'qos': True, 'netapp:maxiopspergib': '1000',
 1004                'netapp:maxiops': '1000'})
 1005     def test_get_normalized_qos_specs_multiple_qos_specs(self, extra_specs):
 1006         self.assertRaises(exception.NetAppException,
 1007                           self.library._get_normalized_qos_specs,
 1008                           extra_specs)
 1009 
 1010     @ddt.data({'qos': True, 'netapp:maxIOPS': '3000'},
 1011               {'qos': True, 'netapp:MAxBPs': '3000', 'clem': 'son'},
 1012               {'qos': True, 'netapp:maxbps': '3000', 'tig': 'ers'},
 1013               {'qos': True, 'netapp:MAXiopSPerGib': '3000', 'kin': 'gsof'},
 1014               {'qos': True, 'netapp:maxiopspergib': '3000', 'coll': 'ege'},
 1015               {'qos': True, 'netapp:maxBPSperGiB': '3000', 'foot': 'ball'})
 1016     def test_get_normalized_qos_specs(self, extra_specs):
 1017         expected_normalized_spec = {
 1018             key.lower().split('netapp:')[1]: value
 1019             for key, value in extra_specs.items() if 'netapp:' in key
 1020         }
 1021 
 1022         qos_specs = self.library._get_normalized_qos_specs(extra_specs)
 1023 
 1024         self.assertDictMatch(expected_normalized_spec, qos_specs)
 1025         self.assertEqual(1, len(qos_specs))
 1026 
 1027     @ddt.data({'qos': {'maxiops': '3000'}, 'expected': '3000iops'},
 1028               {'qos': {'maxbps': '3000'}, 'expected': '3000B/s'},
 1029               {'qos': {'maxbpspergib': '3000'}, 'expected': '12000B/s'},
 1030               {'qos': {'maxiopspergib': '3000'}, 'expected': '12000iops'})
 1031     @ddt.unpack
 1032     def test_get_max_throughput(self, qos, expected):
 1033 
 1034         throughput = self.library._get_max_throughput(4, qos)
 1035 
 1036         self.assertEqual(expected, throughput)
 1037 
 1038     def test_create_qos_policy_group(self):
 1039         mock_qos_policy_create = self.mock_object(
 1040             self.library._client, 'qos_policy_group_create')
 1041 
 1042         self.library._create_qos_policy_group(
 1043             fake.SHARE, fake.VSERVER1, {'maxiops': '3000'})
 1044 
 1045         expected_policy_name = 'qos_share_' + fake.SHARE['id'].replace(
 1046             '-', '_')
 1047         mock_qos_policy_create.assert_called_once_with(
 1048             expected_policy_name, fake.VSERVER1, max_throughput='3000iops')
 1049 
 1050     def test_check_if_max_files_is_valid_with_negative_integer(self):
 1051         self.assertRaises(exception.NetAppException,
 1052                           self.library._check_if_max_files_is_valid,
 1053                           fake.SHARE, -1)
 1054 
 1055     def test_check_if_max_files_is_valid_with_string(self):
 1056         self.assertRaises(ValueError,
 1057                           self.library._check_if_max_files_is_valid,
 1058                           fake.SHARE, 'abc')
 1059 
 1060     def test_allocate_container_no_pool(self):
 1061 
 1062         vserver_client = mock.Mock()
 1063         fake_share_inst = copy.deepcopy(fake.SHARE_INSTANCE)
 1064         fake_share_inst['host'] = fake_share_inst['host'].split('#')[0]
 1065 
 1066         self.assertRaises(exception.InvalidHost,
 1067                           self.library._allocate_container,
 1068                           fake_share_inst,
 1069                           fake.VSERVER1,
 1070                           vserver_client)
 1071 
 1072     def test_check_aggregate_extra_specs_validity(self):
 1073 
 1074         self.library._have_cluster_creds = True
 1075         self.library._ssc_stats = fake.SSC_INFO
 1076 
 1077         result = self.library._check_aggregate_extra_specs_validity(
 1078             fake.AGGREGATES[0], fake.EXTRA_SPEC)
 1079 
 1080         self.assertIsNone(result)
 1081 
 1082     def test_check_aggregate_extra_specs_validity_no_match(self):
 1083 
 1084         self.library._have_cluster_creds = True
 1085         self.library._ssc_stats = fake.SSC_INFO
 1086 
 1087         self.assertRaises(exception.NetAppException,
 1088                           self.library._check_aggregate_extra_specs_validity,
 1089                           fake.AGGREGATES[1],
 1090                           fake.EXTRA_SPEC)
 1091 
 1092     @ddt.data({'provider_location': None, 'size': 50, 'hide_snapdir': True},
 1093               {'provider_location': 'fake_location', 'size': 30,
 1094                'hide_snapdir': False},
 1095               {'provider_location': 'fake_location', 'size': 20,
 1096                'hide_snapdir': True})
 1097     @ddt.unpack
 1098     def test_allocate_container_from_snapshot(
 1099             self, provider_location, size, hide_snapdir):
 1100 
 1101         provisioning_options = copy.deepcopy(fake.PROVISIONING_OPTIONS)
 1102         provisioning_options['hide_snapdir'] = hide_snapdir
 1103         mock_get_provisioning_opts = self.mock_object(
 1104             self.library, '_get_provisioning_options_for_share',
 1105             mock.Mock(return_value=provisioning_options))
 1106         vserver = fake.VSERVER1
 1107         vserver_client = mock.Mock()
 1108         original_snapshot_size = 20
 1109 
 1110         fake_share_inst = copy.deepcopy(fake.SHARE_INSTANCE)
 1111         fake_share_inst['size'] = size
 1112         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 1113         fake_snapshot['provider_location'] = provider_location
 1114         fake_snapshot['size'] = original_snapshot_size
 1115 
 1116         self.library._allocate_container_from_snapshot(fake_share_inst,
 1117                                                        fake_snapshot,
 1118                                                        vserver,
 1119                                                        vserver_client)
 1120 
 1121         share_name = self.library._get_backend_share_name(
 1122             fake_share_inst['id'])
 1123         parent_share_name = self.library._get_backend_share_name(
 1124             fake_snapshot['share_id'])
 1125         parent_snapshot_name = self.library._get_backend_snapshot_name(
 1126             fake_snapshot['id']) if not provider_location else 'fake_location'
 1127         mock_get_provisioning_opts.assert_called_once_with(
 1128             fake_share_inst, fake.VSERVER1)
 1129         vserver_client.create_volume_clone.assert_called_once_with(
 1130             share_name, parent_share_name, parent_snapshot_name,
 1131             thin_provisioned=True, snapshot_policy='default',
 1132             language='en-US', dedup_enabled=True, split=True, encrypt=False,
 1133             compression_enabled=False, max_files=5000)
 1134         if size > original_snapshot_size:
 1135             vserver_client.set_volume_size.assert_called_once_with(
 1136                 share_name, size)
 1137         else:
 1138             vserver_client.set_volume_size.assert_not_called()
 1139 
 1140         if hide_snapdir:
 1141             vserver_client.set_volume_snapdir_access.assert_called_once_with(
 1142                 fake.SHARE_INSTANCE_NAME, hide_snapdir)
 1143         else:
 1144             vserver_client.set_volume_snapdir_access.assert_not_called()
 1145 
 1146     def test_share_exists(self):
 1147 
 1148         vserver_client = mock.Mock()
 1149         vserver_client.volume_exists.return_value = True
 1150 
 1151         result = self.library._share_exists(fake.SHARE_NAME, vserver_client)
 1152 
 1153         self.assertTrue(result)
 1154 
 1155     def test_share_exists_not_found(self):
 1156 
 1157         vserver_client = mock.Mock()
 1158         vserver_client.volume_exists.return_value = False
 1159 
 1160         result = self.library._share_exists(fake.SHARE_NAME, vserver_client)
 1161 
 1162         self.assertFalse(result)
 1163 
 1164     def test_delete_share(self):
 1165 
 1166         vserver_client = mock.Mock()
 1167         self.mock_object(self.library,
 1168                          '_get_vserver',
 1169                          mock.Mock(return_value=(fake.VSERVER1,
 1170                                                  vserver_client)))
 1171         mock_share_exists = self.mock_object(self.library,
 1172                                              '_share_exists',
 1173                                              mock.Mock(return_value=True))
 1174         mock_remove_export = self.mock_object(self.library, '_remove_export')
 1175         mock_deallocate_container = self.mock_object(self.library,
 1176                                                      '_deallocate_container')
 1177 
 1178         self.library.delete_share(self.context,
 1179                                   fake.SHARE,
 1180                                   share_server=fake.SHARE_SERVER)
 1181 
 1182         share_name = self.library._get_backend_share_name(fake.SHARE['id'])
 1183         qos_policy_name = self.library._get_backend_qos_policy_group_name(
 1184             fake.SHARE['id'])
 1185         mock_share_exists.assert_called_once_with(share_name, vserver_client)
 1186         mock_remove_export.assert_called_once_with(fake.SHARE, vserver_client)
 1187         mock_deallocate_container.assert_called_once_with(share_name,
 1188                                                           vserver_client)
 1189         (self.library._client.mark_qos_policy_group_for_deletion
 1190          .assert_called_once_with(qos_policy_name))
 1191         self.assertEqual(0, lib_base.LOG.info.call_count)
 1192 
 1193     @ddt.data(exception.InvalidInput(reason='fake_reason'),
 1194               exception.VserverNotSpecified(),
 1195               exception.VserverNotFound(vserver='fake_vserver'))
 1196     def test_delete_share_no_share_server(self, get_vserver_exception):
 1197 
 1198         self.mock_object(self.library,
 1199                          '_get_vserver',
 1200                          mock.Mock(side_effect=get_vserver_exception))
 1201         mock_share_exists = self.mock_object(self.library,
 1202                                              '_share_exists',
 1203                                              mock.Mock(return_value=False))
 1204         mock_remove_export = self.mock_object(self.library, '_remove_export')
 1205         mock_deallocate_container = self.mock_object(self.library,
 1206                                                      '_deallocate_container')
 1207 
 1208         self.library.delete_share(self.context,
 1209                                   fake.SHARE,
 1210                                   share_server=fake.SHARE_SERVER)
 1211 
 1212         self.assertFalse(mock_share_exists.called)
 1213         self.assertFalse(mock_remove_export.called)
 1214         self.assertFalse(mock_deallocate_container.called)
 1215         self.assertFalse(
 1216             self.library._client.mark_qos_policy_group_for_deletion.called)
 1217         self.assertEqual(1, lib_base.LOG.warning.call_count)
 1218 
 1219     def test_delete_share_not_found(self):
 1220 
 1221         vserver_client = mock.Mock()
 1222         self.mock_object(self.library,
 1223                          '_get_vserver',
 1224                          mock.Mock(return_value=(fake.VSERVER1,
 1225                                                  vserver_client)))
 1226         mock_share_exists = self.mock_object(self.library,
 1227                                              '_share_exists',
 1228                                              mock.Mock(return_value=False))
 1229         mock_remove_export = self.mock_object(self.library, '_remove_export')
 1230         mock_deallocate_container = self.mock_object(self.library,
 1231                                                      '_deallocate_container')
 1232 
 1233         self.library.delete_share(self.context,
 1234                                   fake.SHARE,
 1235                                   share_server=fake.SHARE_SERVER)
 1236 
 1237         share_name = self.library._get_backend_share_name(fake.SHARE['id'])
 1238         mock_share_exists.assert_called_once_with(share_name, vserver_client)
 1239         self.assertFalse(mock_remove_export.called)
 1240         self.assertFalse(mock_deallocate_container.called)
 1241         self.assertFalse(
 1242             self.library._client.mark_qos_policy_group_for_deletion.called)
 1243         self.assertEqual(1, lib_base.LOG.info.call_count)
 1244 
 1245     def test_deallocate_container(self):
 1246 
 1247         vserver_client = mock.Mock()
 1248 
 1249         self.library._deallocate_container(fake.SHARE_NAME, vserver_client)
 1250 
 1251         vserver_client.unmount_volume.assert_called_with(fake.SHARE_NAME,
 1252                                                          force=True)
 1253         vserver_client.offline_volume.assert_called_with(fake.SHARE_NAME)
 1254         vserver_client.delete_volume.assert_called_with(fake.SHARE_NAME)
 1255 
 1256     def test_create_export(self):
 1257 
 1258         protocol_helper = mock.Mock()
 1259         callback = (lambda export_address, export_path='fake_export_path':
 1260                     ':'.join([export_address, export_path]))
 1261         protocol_helper.create_share.return_value = callback
 1262         self.mock_object(self.library,
 1263                          '_get_helper',
 1264                          mock.Mock(return_value=protocol_helper))
 1265         vserver_client = mock.Mock()
 1266         vserver_client.get_network_interfaces.return_value = fake.LIFS
 1267         fake_interface_addresses_with_metadata = copy.deepcopy(
 1268             fake.INTERFACE_ADDRESSES_WITH_METADATA)
 1269         mock_get_export_addresses_with_metadata = self.mock_object(
 1270             self.library, '_get_export_addresses_with_metadata',
 1271             mock.Mock(return_value=fake_interface_addresses_with_metadata))
 1272 
 1273         result = self.library._create_export(fake.SHARE,
 1274                                              fake.SHARE_SERVER,
 1275                                              fake.VSERVER1,
 1276                                              vserver_client)
 1277 
 1278         self.assertEqual(fake.NFS_EXPORTS, result)
 1279         mock_get_export_addresses_with_metadata.assert_called_once_with(
 1280             fake.SHARE, fake.SHARE_SERVER, fake.LIFS)
 1281         protocol_helper.create_share.assert_called_once_with(
 1282             fake.SHARE, fake.SHARE_NAME, clear_current_export_policy=True)
 1283 
 1284     def test_create_export_lifs_not_found(self):
 1285 
 1286         self.mock_object(self.library, '_get_helper')
 1287         vserver_client = mock.Mock()
 1288         vserver_client.get_network_interfaces.return_value = []
 1289 
 1290         self.assertRaises(exception.NetAppException,
 1291                           self.library._create_export,
 1292                           fake.SHARE,
 1293                           fake.SHARE_SERVER,
 1294                           fake.VSERVER1,
 1295                           vserver_client)
 1296 
 1297     def test_get_export_addresses_with_metadata(self):
 1298 
 1299         mock_get_aggregate_node = self.mock_object(
 1300             self.library, '_get_aggregate_node',
 1301             mock.Mock(return_value=fake.CLUSTER_NODES[0]))
 1302         mock_get_admin_addresses_for_share_server = self.mock_object(
 1303             self.library, '_get_admin_addresses_for_share_server',
 1304             mock.Mock(return_value=[fake.LIF_ADDRESSES[1]]))
 1305 
 1306         result = self.library._get_export_addresses_with_metadata(
 1307             fake.SHARE, fake.SHARE_SERVER, fake.LIFS)
 1308 
 1309         self.assertEqual(fake.INTERFACE_ADDRESSES_WITH_METADATA, result)
 1310         mock_get_aggregate_node.assert_called_once_with(fake.POOL_NAME)
 1311         mock_get_admin_addresses_for_share_server.assert_called_once_with(
 1312             fake.SHARE_SERVER)
 1313 
 1314     def test_get_export_addresses_with_metadata_node_unknown(self):
 1315 
 1316         mock_get_aggregate_node = self.mock_object(
 1317             self.library, '_get_aggregate_node',
 1318             mock.Mock(return_value=None))
 1319         mock_get_admin_addresses_for_share_server = self.mock_object(
 1320             self.library, '_get_admin_addresses_for_share_server',
 1321             mock.Mock(return_value=[fake.LIF_ADDRESSES[1]]))
 1322 
 1323         result = self.library._get_export_addresses_with_metadata(
 1324             fake.SHARE, fake.SHARE_SERVER, fake.LIFS)
 1325 
 1326         expected = copy.deepcopy(fake.INTERFACE_ADDRESSES_WITH_METADATA)
 1327         for key, value in expected.items():
 1328             value['preferred'] = False
 1329 
 1330         self.assertEqual(expected, result)
 1331         mock_get_aggregate_node.assert_called_once_with(fake.POOL_NAME)
 1332         mock_get_admin_addresses_for_share_server.assert_called_once_with(
 1333             fake.SHARE_SERVER)
 1334 
 1335     def test_get_admin_addresses_for_share_server(self):
 1336 
 1337         result = self.library._get_admin_addresses_for_share_server(
 1338             fake.SHARE_SERVER)
 1339 
 1340         self.assertEqual([fake.ADMIN_NETWORK_ALLOCATIONS[0]['ip_address']],
 1341                          result)
 1342 
 1343     def test_get_admin_addresses_for_share_server_no_share_server(self):
 1344 
 1345         result = self.library._get_admin_addresses_for_share_server(None)
 1346 
 1347         self.assertEqual([], result)
 1348 
 1349     @ddt.data(True, False)
 1350     def test_sort_export_locations_by_preferred_paths(self, reverse):
 1351 
 1352         export_locations = copy.copy(fake.NFS_EXPORTS)
 1353         if reverse:
 1354             export_locations.reverse()
 1355 
 1356         result = self.library._sort_export_locations_by_preferred_paths(
 1357             export_locations)
 1358 
 1359         self.assertEqual(fake.NFS_EXPORTS, result)
 1360 
 1361     def test_remove_export(self):
 1362 
 1363         protocol_helper = mock.Mock()
 1364         protocol_helper.get_target.return_value = 'fake_target'
 1365         self.mock_object(self.library,
 1366                          '_get_helper',
 1367                          mock.Mock(return_value=protocol_helper))
 1368         vserver_client = mock.Mock()
 1369 
 1370         self.library._remove_export(fake.SHARE, vserver_client)
 1371 
 1372         protocol_helper.set_client.assert_called_once_with(vserver_client)
 1373         protocol_helper.get_target.assert_called_once_with(fake.SHARE)
 1374         protocol_helper.delete_share.assert_called_once_with(fake.SHARE,
 1375                                                              fake.SHARE_NAME)
 1376 
 1377     def test_remove_export_target_not_found(self):
 1378 
 1379         protocol_helper = mock.Mock()
 1380         protocol_helper.get_target.return_value = None
 1381         self.mock_object(self.library,
 1382                          '_get_helper',
 1383                          mock.Mock(return_value=protocol_helper))
 1384         vserver_client = mock.Mock()
 1385 
 1386         self.library._remove_export(fake.SHARE, vserver_client)
 1387 
 1388         protocol_helper.set_client.assert_called_once_with(vserver_client)
 1389         protocol_helper.get_target.assert_called_once_with(fake.SHARE)
 1390         self.assertFalse(protocol_helper.delete_share.called)
 1391 
 1392     def test_create_snapshot(self):
 1393 
 1394         vserver_client = mock.Mock()
 1395         self.mock_object(self.library,
 1396                          '_get_vserver',
 1397                          mock.Mock(return_value=(fake.VSERVER1,
 1398                                                  vserver_client)))
 1399 
 1400         model_update = self.library.create_snapshot(
 1401             self.context, fake.SNAPSHOT, share_server=fake.SHARE_SERVER)
 1402 
 1403         share_name = self.library._get_backend_share_name(
 1404             fake.SNAPSHOT['share_id'])
 1405         snapshot_name = self.library._get_backend_snapshot_name(
 1406             fake.SNAPSHOT['id'])
 1407         vserver_client.create_snapshot.assert_called_once_with(share_name,
 1408                                                                snapshot_name)
 1409         self.assertEqual(snapshot_name, model_update['provider_location'])
 1410 
 1411     @ddt.data(True, False)
 1412     def test_revert_to_snapshot(self, use_snap_provider_location):
 1413 
 1414         vserver_client = mock.Mock()
 1415         self.mock_object(self.library,
 1416                          '_get_vserver',
 1417                          mock.Mock(return_value=(fake.VSERVER1,
 1418                                                  vserver_client)))
 1419         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 1420         if use_snap_provider_location:
 1421             fake_snapshot['provider_location'] = 'fake-provider-location'
 1422         else:
 1423             del fake_snapshot['provider_location']
 1424 
 1425         result = self.library.revert_to_snapshot(
 1426             self.context, fake_snapshot, share_server=fake.SHARE_SERVER)
 1427 
 1428         self.assertIsNone(result)
 1429         share_name = self.library._get_backend_share_name(
 1430             fake_snapshot['share_id'])
 1431         snapshot_name = (self.library._get_backend_snapshot_name(
 1432             fake_snapshot['id']) if not use_snap_provider_location
 1433             else 'fake-provider-location')
 1434         vserver_client.restore_snapshot.assert_called_once_with(share_name,
 1435                                                                 snapshot_name)
 1436 
 1437     def test_delete_snapshot(self):
 1438 
 1439         vserver_client = mock.Mock()
 1440         self.mock_object(self.library,
 1441                          '_get_vserver',
 1442                          mock.Mock(return_value=(fake.VSERVER1,
 1443                                                  vserver_client)))
 1444         mock_delete_snapshot = self.mock_object(self.library,
 1445                                                 '_delete_snapshot')
 1446 
 1447         self.library.delete_snapshot(self.context,
 1448                                      fake.SNAPSHOT,
 1449                                      share_server=fake.SHARE_SERVER)
 1450 
 1451         share_name = self.library._get_backend_share_name(
 1452             fake.SNAPSHOT['share_id'])
 1453         snapshot_name = self.library._get_backend_snapshot_name(
 1454             fake.SNAPSHOT['id'])
 1455         mock_delete_snapshot.assert_called_once_with(
 1456             vserver_client, share_name, snapshot_name)
 1457 
 1458     def test_delete_snapshot_with_provider_location(self):
 1459         vserver_client = mock.Mock()
 1460         vserver_client.get_snapshot.return_value = fake.CDOT_SNAPSHOT
 1461         self.mock_object(self.library,
 1462                          '_get_vserver',
 1463                          mock.Mock(return_value=(fake.VSERVER1,
 1464                                                  vserver_client)))
 1465         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 1466         fake_snapshot['provider_location'] = 'fake_provider_location'
 1467 
 1468         self.library.delete_snapshot(self.context,
 1469                                      fake_snapshot,
 1470                                      share_server=fake.SHARE_SERVER)
 1471 
 1472         share_name = self.library._get_backend_share_name(
 1473             fake_snapshot['share_id'])
 1474         vserver_client.delete_snapshot.assert_called_once_with(
 1475             share_name,  fake_snapshot['provider_location'])
 1476 
 1477     @ddt.data(exception.InvalidInput(reason='fake_reason'),
 1478               exception.VserverNotSpecified(),
 1479               exception.VserverNotFound(vserver='fake_vserver'))
 1480     def test_delete_snapshot_no_share_server(self, get_vserver_exception):
 1481 
 1482         self.mock_object(self.library,
 1483                          '_get_vserver',
 1484                          mock.Mock(side_effect=get_vserver_exception))
 1485         mock_delete_snapshot = self.mock_object(self.library,
 1486                                                 '_delete_snapshot')
 1487 
 1488         self.library.delete_snapshot(self.context,
 1489                                      fake.SNAPSHOT,
 1490                                      share_server=fake.SHARE_SERVER)
 1491 
 1492         self.assertFalse(mock_delete_snapshot.called)
 1493 
 1494     def test_delete_snapshot_not_found(self):
 1495 
 1496         vserver_client = mock.Mock()
 1497         self.mock_object(self.library,
 1498                          '_get_vserver',
 1499                          mock.Mock(return_value=(fake.VSERVER1,
 1500                                                  vserver_client)))
 1501         mock_delete_snapshot = self.mock_object(
 1502             self.library, '_delete_snapshot',
 1503             mock.Mock(side_effect=exception.SnapshotResourceNotFound(
 1504                 name=fake.SNAPSHOT_NAME)))
 1505 
 1506         self.library.delete_snapshot(self.context,
 1507                                      fake.SNAPSHOT,
 1508                                      share_server=fake.SHARE_SERVER)
 1509 
 1510         share_name = self.library._get_backend_share_name(
 1511             fake.SNAPSHOT['share_id'])
 1512         snapshot_name = self.library._get_backend_snapshot_name(
 1513             fake.SNAPSHOT['id'])
 1514         mock_delete_snapshot.assert_called_once_with(
 1515             vserver_client, share_name, snapshot_name)
 1516 
 1517     def test_delete_snapshot_not_unique(self):
 1518 
 1519         vserver_client = mock.Mock()
 1520         self.mock_object(self.library,
 1521                          '_get_vserver',
 1522                          mock.Mock(return_value=(fake.VSERVER1,
 1523                                                  vserver_client)))
 1524         mock_delete_snapshot = self.mock_object(
 1525             self.library, '_delete_snapshot',
 1526             mock.Mock(side_effect=exception.NetAppException()))
 1527 
 1528         self.assertRaises(exception.NetAppException,
 1529                           self.library.delete_snapshot,
 1530                           self.context,
 1531                           fake.SNAPSHOT,
 1532                           share_server=fake.SHARE_SERVER)
 1533 
 1534         share_name = self.library._get_backend_share_name(
 1535             fake.SNAPSHOT['share_id'])
 1536         snapshot_name = self.library._get_backend_snapshot_name(
 1537             fake.SNAPSHOT['id'])
 1538         mock_delete_snapshot.assert_called_once_with(
 1539             vserver_client, share_name, snapshot_name)
 1540 
 1541     def test__delete_snapshot(self):
 1542 
 1543         vserver_client = mock.Mock()
 1544         vserver_client.get_snapshot.return_value = fake.CDOT_SNAPSHOT
 1545 
 1546         self.library._delete_snapshot(vserver_client,
 1547                                       fake.SHARE_NAME,
 1548                                       fake.SNAPSHOT_NAME)
 1549 
 1550         vserver_client.delete_snapshot.assert_called_once_with(
 1551             fake.SHARE_NAME, fake.SNAPSHOT_NAME)
 1552         self.assertFalse(vserver_client.get_clone_children_for_snapshot.called)
 1553         self.assertFalse(vserver_client.split_volume_clone.called)
 1554         self.assertFalse(vserver_client.soft_delete_snapshot.called)
 1555 
 1556     def test__delete_snapshot_busy_volume_clone(self):
 1557 
 1558         vserver_client = mock.Mock()
 1559         vserver_client.get_snapshot.return_value = (
 1560             fake.CDOT_SNAPSHOT_BUSY_VOLUME_CLONE)
 1561         vserver_client.get_clone_children_for_snapshot.return_value = (
 1562             fake.CDOT_CLONE_CHILDREN)
 1563 
 1564         self.library._delete_snapshot(vserver_client,
 1565                                       fake.SHARE_NAME,
 1566                                       fake.SNAPSHOT_NAME)
 1567 
 1568         self.assertFalse(vserver_client.delete_snapshot.called)
 1569         vserver_client.get_clone_children_for_snapshot.assert_called_once_with(
 1570             fake.SHARE_NAME, fake.SNAPSHOT_NAME)
 1571         vserver_client.split_volume_clone.assert_has_calls([
 1572             mock.call(fake.CDOT_CLONE_CHILD_1),
 1573             mock.call(fake.CDOT_CLONE_CHILD_2),
 1574         ])
 1575         vserver_client.soft_delete_snapshot.assert_called_once_with(
 1576             fake.SHARE_NAME, fake.SNAPSHOT_NAME)
 1577 
 1578     def test__delete_snapshot_busy_snapmirror(self):
 1579 
 1580         vserver_client = mock.Mock()
 1581         vserver_client.get_snapshot.return_value = (
 1582             fake.CDOT_SNAPSHOT_BUSY_SNAPMIRROR)
 1583 
 1584         self.assertRaises(exception.ShareSnapshotIsBusy,
 1585                           self.library._delete_snapshot,
 1586                           vserver_client,
 1587                           fake.SHARE_NAME,
 1588                           fake.SNAPSHOT_NAME)
 1589 
 1590         self.assertFalse(vserver_client.delete_snapshot.called)
 1591         self.assertFalse(vserver_client.get_clone_children_for_snapshot.called)
 1592         self.assertFalse(vserver_client.split_volume_clone.called)
 1593         self.assertFalse(vserver_client.soft_delete_snapshot.called)
 1594 
 1595     @ddt.data(None, fake.VSERVER1)
 1596     def test_manage_existing(self, fake_vserver):
 1597 
 1598         vserver_client = mock.Mock()
 1599         mock__get_vserver = self.mock_object(
 1600             self.library, '_get_vserver',
 1601             mock.Mock(return_value=(fake.VSERVER1, vserver_client)))
 1602         mock_manage_container = self.mock_object(
 1603             self.library,
 1604             '_manage_container',
 1605             mock.Mock(return_value=fake.SHARE_SIZE))
 1606         mock_create_export = self.mock_object(
 1607             self.library,
 1608             '_create_export',
 1609             mock.Mock(return_value=fake.NFS_EXPORTS))
 1610 
 1611         result = self.library.manage_existing(fake.SHARE, {},
 1612                                               share_server=fake_vserver)
 1613 
 1614         expected = {
 1615             'size': fake.SHARE_SIZE,
 1616             'export_locations': fake.NFS_EXPORTS
 1617         }
 1618 
 1619         mock__get_vserver.assert_called_once_with(share_server=fake_vserver)
 1620         mock_manage_container.assert_called_once_with(fake.SHARE,
 1621                                                       fake.VSERVER1,
 1622                                                       vserver_client)
 1623 
 1624         mock_create_export.assert_called_once_with(fake.SHARE,
 1625                                                    fake_vserver,
 1626                                                    fake.VSERVER1,
 1627                                                    vserver_client)
 1628         self.assertDictEqual(expected, result)
 1629 
 1630     @ddt.data(None, fake.VSERVER1)
 1631     def test_unmanage(self, fake_vserver):
 1632 
 1633         result = self.library.unmanage(fake.SHARE, share_server=fake_vserver)
 1634 
 1635         self.assertIsNone(result)
 1636 
 1637     @ddt.data(True, False)
 1638     def test_manage_container_with_qos(self, qos):
 1639 
 1640         vserver_client = mock.Mock()
 1641         qos_policy_group_name = fake.QOS_POLICY_GROUP_NAME if qos else None
 1642         extra_specs = fake.EXTRA_SPEC_WITH_QOS if qos else fake.EXTRA_SPEC
 1643         provisioning_opts = self.library._get_provisioning_options(extra_specs)
 1644         if qos:
 1645             provisioning_opts['qos_policy_group'] = fake.QOS_POLICY_GROUP_NAME
 1646 
 1647         share_to_manage = copy.deepcopy(fake.SHARE)
 1648         share_to_manage['export_location'] = fake.EXPORT_LOCATION
 1649 
 1650         mock_helper = mock.Mock()
 1651         mock_helper.get_share_name_for_share.return_value = fake.FLEXVOL_NAME
 1652         self.mock_object(self.library,
 1653                          '_get_helper',
 1654                          mock.Mock(return_value=mock_helper))
 1655 
 1656         mock_get_volume_to_manage = self.mock_object(
 1657             vserver_client,
 1658             'get_volume_to_manage',
 1659             mock.Mock(return_value=fake.FLEXVOL_TO_MANAGE))
 1660         mock_validate_volume_for_manage = self.mock_object(
 1661             self.library,
 1662             '_validate_volume_for_manage')
 1663         self.mock_object(share_types,
 1664                          'get_extra_specs_from_share',
 1665                          mock.Mock(return_value=extra_specs))
 1666         mock_check_extra_specs_validity = self.mock_object(
 1667             self.library,
 1668             '_check_extra_specs_validity')
 1669         mock_check_aggregate_extra_specs_validity = self.mock_object(
 1670             self.library,
 1671             '_check_aggregate_extra_specs_validity')
 1672         mock_modify_or_create_qos_policy = self.mock_object(
 1673             self.library, '_modify_or_create_qos_for_existing_share',
 1674             mock.Mock(return_value=qos_policy_group_name))
 1675 
 1676         result = self.library._manage_container(share_to_manage,
 1677                                                 fake.VSERVER1,
 1678                                                 vserver_client)
 1679 
 1680         mock_get_volume_to_manage.assert_called_once_with(
 1681             fake.POOL_NAME, fake.FLEXVOL_NAME)
 1682         mock_check_extra_specs_validity.assert_called_once_with(
 1683             share_to_manage, extra_specs)
 1684         mock_check_aggregate_extra_specs_validity.assert_called_once_with(
 1685             fake.POOL_NAME, extra_specs)
 1686         vserver_client.unmount_volume.assert_called_once_with(
 1687             fake.FLEXVOL_NAME)
 1688         vserver_client.set_volume_name.assert_called_once_with(
 1689             fake.FLEXVOL_NAME, fake.SHARE_NAME)
 1690         vserver_client.mount_volume.assert_called_once_with(
 1691             fake.SHARE_NAME)
 1692         vserver_client.modify_volume.assert_called_once_with(
 1693             fake.POOL_NAME, fake.SHARE_NAME, **provisioning_opts)
 1694         mock_modify_or_create_qos_policy.assert_called_once_with(
 1695             share_to_manage, extra_specs, fake.VSERVER1, vserver_client)
 1696         mock_validate_volume_for_manage.assert_called()
 1697 
 1698         original_data = {
 1699             'original_name': fake.FLEXVOL_TO_MANAGE['name'],
 1700             'original_junction_path': fake.FLEXVOL_TO_MANAGE['junction-path'],
 1701         }
 1702         self.library.private_storage.update.assert_called_once_with(
 1703             fake.SHARE['id'], original_data)
 1704 
 1705         expected_size = int(
 1706             math.ceil(float(fake.FLEXVOL_TO_MANAGE['size']) / units.Gi))
 1707         self.assertEqual(expected_size, result)
 1708 
 1709     def test_manage_container_invalid_export_location(self):
 1710 
 1711         vserver_client = mock.Mock()
 1712 
 1713         share_to_manage = copy.deepcopy(fake.SHARE)
 1714         share_to_manage['export_location'] = fake.EXPORT_LOCATION
 1715 
 1716         mock_helper = mock.Mock()
 1717         mock_helper.get_share_name_for_share.return_value = None
 1718         self.mock_object(self.library,
 1719                          '_get_helper',
 1720                          mock.Mock(return_value=mock_helper))
 1721 
 1722         self.assertRaises(exception.ManageInvalidShare,
 1723                           self.library._manage_container,
 1724                           share_to_manage,
 1725                           fake.VSERVER1,
 1726                           vserver_client)
 1727 
 1728     def test_manage_container_not_found(self):
 1729 
 1730         vserver_client = mock.Mock()
 1731 
 1732         share_to_manage = copy.deepcopy(fake.SHARE)
 1733         share_to_manage['export_location'] = fake.EXPORT_LOCATION
 1734 
 1735         mock_helper = mock.Mock()
 1736         mock_helper.get_share_name_for_share.return_value = fake.FLEXVOL_NAME
 1737         self.mock_object(self.library,
 1738                          '_get_helper',
 1739                          mock.Mock(return_value=mock_helper))
 1740 
 1741         self.mock_object(vserver_client,
 1742                          'get_volume_to_manage',
 1743                          mock.Mock(return_value=None))
 1744 
 1745         self.assertRaises(exception.ManageInvalidShare,
 1746                           self.library._manage_container,
 1747                           share_to_manage,
 1748                           fake.VSERVER1,
 1749                           vserver_client)
 1750 
 1751     def test_manage_container_invalid_extra_specs(self):
 1752 
 1753         vserver_client = mock.Mock()
 1754 
 1755         share_to_manage = copy.deepcopy(fake.SHARE)
 1756         share_to_manage['export_location'] = fake.EXPORT_LOCATION
 1757 
 1758         mock_helper = mock.Mock()
 1759         mock_helper.get_share_name_for_share.return_value = fake.FLEXVOL_NAME
 1760         self.mock_object(self.library,
 1761                          '_get_helper',
 1762                          mock.Mock(return_value=mock_helper))
 1763 
 1764         self.mock_object(vserver_client,
 1765                          'get_volume_to_manage',
 1766                          mock.Mock(return_value=fake.FLEXVOL_TO_MANAGE))
 1767         self.mock_object(self.library, '_validate_volume_for_manage')
 1768         self.mock_object(share_types,
 1769                          'get_extra_specs_from_share',
 1770                          mock.Mock(return_value=fake.EXTRA_SPEC))
 1771         self.mock_object(self.library,
 1772                          '_check_extra_specs_validity',
 1773                          mock.Mock(side_effect=exception.NetAppException))
 1774 
 1775         self.assertRaises(exception.ManageExistingShareTypeMismatch,
 1776                           self.library._manage_container,
 1777                           share_to_manage,
 1778                           fake.VSERVER1,
 1779                           vserver_client)
 1780 
 1781     def test_validate_volume_for_manage(self):
 1782 
 1783         vserver_client = mock.Mock()
 1784         vserver_client.volume_has_luns = mock.Mock(return_value=False)
 1785         vserver_client.volume_has_junctioned_volumes = mock.Mock(
 1786             return_value=False)
 1787         vserver_client.volume_has_snapmirror_relationships = mock.Mock(
 1788             return_value=False)
 1789 
 1790         result = self.library._validate_volume_for_manage(
 1791             fake.FLEXVOL_TO_MANAGE, vserver_client)
 1792 
 1793         self.assertIsNone(result)
 1794 
 1795     @ddt.data({
 1796         'attribute': 'type',
 1797         'value': 'dp',
 1798     }, {
 1799         'attribute': 'style',
 1800         'value': 'infinitevol',
 1801     })
 1802     @ddt.unpack
 1803     def test_validate_volume_for_manage_invalid_volume(self, attribute, value):
 1804 
 1805         flexvol_to_manage = copy.deepcopy(fake.FLEXVOL_TO_MANAGE)
 1806         flexvol_to_manage[attribute] = value
 1807 
 1808         vserver_client = mock.Mock()
 1809         vserver_client.volume_has_luns = mock.Mock(return_value=False)
 1810         vserver_client.volume_has_junctioned_volumes = mock.Mock(
 1811             return_value=False)
 1812         vserver_client.volume_has_snapmirror_relationships = mock.Mock(
 1813             return_value=False)
 1814 
 1815         self.assertRaises(exception.ManageInvalidShare,
 1816                           self.library._validate_volume_for_manage,
 1817                           flexvol_to_manage,
 1818                           vserver_client)
 1819 
 1820     def test_validate_volume_for_manage_luns_present(self):
 1821 
 1822         vserver_client = mock.Mock()
 1823         vserver_client.volume_has_luns = mock.Mock(return_value=True)
 1824         vserver_client.volume_has_junctioned_volumes = mock.Mock(
 1825             return_value=False)
 1826         vserver_client.volume_has_snapmirror_relationships = mock.Mock(
 1827             return_value=False)
 1828 
 1829         self.assertRaises(exception.ManageInvalidShare,
 1830                           self.library._validate_volume_for_manage,
 1831                           fake.FLEXVOL_TO_MANAGE,
 1832                           vserver_client)
 1833 
 1834     def test_validate_volume_for_manage_junctioned_volumes_present(self):
 1835 
 1836         vserver_client = mock.Mock()
 1837         vserver_client.volume_has_luns = mock.Mock(return_value=False)
 1838         vserver_client.volume_has_junctioned_volumes = mock.Mock(
 1839             return_value=True)
 1840         vserver_client.volume_has_snapmirror_relationships = mock.Mock(
 1841             return_value=False)
 1842 
 1843         self.assertRaises(exception.ManageInvalidShare,
 1844                           self.library._validate_volume_for_manage,
 1845                           fake.FLEXVOL_TO_MANAGE,
 1846                           vserver_client)
 1847 
 1848     @ddt.data(None, fake.VSERVER1)
 1849     def test_manage_existing_snapshot(self, fake_vserver):
 1850 
 1851         vserver_client = mock.Mock()
 1852         mock_get_vserver = self.mock_object(
 1853             self.library, '_get_vserver',
 1854             mock.Mock(return_value=(fake.VSERVER1, vserver_client)))
 1855         vserver_client.get_volume.return_value = fake.FLEXVOL_TO_MANAGE
 1856         vserver_client.volume_has_snapmirror_relationships.return_value = False
 1857         result = self.library.manage_existing_snapshot(
 1858             fake.SNAPSHOT_TO_MANAGE, {}, share_server=fake_vserver)
 1859 
 1860         share_name = self.library._get_backend_share_name(
 1861             fake.SNAPSHOT['share_id'])
 1862         new_snapshot_name = self.library._get_backend_snapshot_name(
 1863             fake.SNAPSHOT['id'])
 1864         mock_get_vserver.assert_called_once_with(share_server=fake_vserver)
 1865         (vserver_client.volume_has_snapmirror_relationships.
 1866             assert_called_once_with(fake.FLEXVOL_TO_MANAGE))
 1867         vserver_client.rename_snapshot.assert_called_once_with(
 1868             share_name, fake.SNAPSHOT_NAME, new_snapshot_name)
 1869         self.library.private_storage.update.assert_called_once_with(
 1870             fake.SNAPSHOT['id'], {'original_name': fake.SNAPSHOT_NAME})
 1871         self.assertEqual({'size': 2, 'provider_location': new_snapshot_name},
 1872                          result)
 1873 
 1874     def test_manage_existing_snapshot_no_snapshot_name(self):
 1875 
 1876         vserver_client = mock.Mock()
 1877         self.mock_object(self.library,
 1878                          '_get_vserver',
 1879                          mock.Mock(return_value=(fake.VSERVER1,
 1880                                                  vserver_client)))
 1881         vserver_client.get_volume.return_value = fake.FLEXVOL_TO_MANAGE
 1882         vserver_client.volume_has_snapmirror_relationships.return_value = False
 1883         fake_snapshot = copy.deepcopy(fake.SNAPSHOT_TO_MANAGE)
 1884         fake_snapshot['provider_location'] = ''
 1885 
 1886         self.assertRaises(exception.ManageInvalidShareSnapshot,
 1887                           self.library.manage_existing_snapshot,
 1888                           fake_snapshot, {})
 1889 
 1890     @ddt.data(netapp_api.NaApiError,
 1891               exception.NetAppException)
 1892     def test_manage_existing_snapshot_get_volume_error(self, exception_type):
 1893 
 1894         vserver_client = mock.Mock()
 1895         self.mock_object(self.library,
 1896                          '_get_vserver',
 1897                          mock.Mock(return_value=(fake.VSERVER1,
 1898                                                  vserver_client)))
 1899         vserver_client.get_volume.side_effect = exception_type
 1900         self.mock_object(self.client,
 1901                          'volume_has_snapmirror_relationships',
 1902                          mock.Mock(return_value=False))
 1903 
 1904         self.assertRaises(exception.ShareNotFound,
 1905                           self.library.manage_existing_snapshot,
 1906                           fake.SNAPSHOT_TO_MANAGE, {})
 1907 
 1908     def test_manage_existing_snapshot_mirrors_present(self):
 1909 
 1910         vserver_client = mock.Mock()
 1911         self.mock_object(self.library,
 1912                          '_get_vserver',
 1913                          mock.Mock(return_value=(fake.VSERVER1,
 1914                                                  vserver_client)))
 1915         vserver_client.get_volume.return_value = fake.FLEXVOL_TO_MANAGE
 1916         vserver_client.volume_has_snapmirror_relationships.return_value = True
 1917 
 1918         self.assertRaises(exception.ManageInvalidShareSnapshot,
 1919                           self.library.manage_existing_snapshot,
 1920                           fake.SNAPSHOT_TO_MANAGE, {})
 1921 
 1922     def test_manage_existing_snapshot_rename_snapshot_error(self):
 1923 
 1924         vserver_client = mock.Mock()
 1925         self.mock_object(self.library,
 1926                          '_get_vserver',
 1927                          mock.Mock(return_value=(fake.VSERVER1,
 1928                                                  vserver_client)))
 1929         vserver_client.get_volume.return_value = fake.FLEXVOL_TO_MANAGE
 1930         vserver_client.volume_has_snapmirror_relationships.return_value = False
 1931         vserver_client.rename_snapshot.side_effect = netapp_api.NaApiError
 1932 
 1933         self.assertRaises(exception.ManageInvalidShareSnapshot,
 1934                           self.library.manage_existing_snapshot,
 1935                           fake.SNAPSHOT_TO_MANAGE, {})
 1936 
 1937     @ddt.data(None, fake.VSERVER1)
 1938     def test_unmanage_snapshot(self, fake_vserver):
 1939 
 1940         result = self.library.unmanage_snapshot(fake.SNAPSHOT, fake_vserver)
 1941 
 1942         self.assertIsNone(result)
 1943 
 1944     def test_validate_volume_for_manage_snapmirror_relationships_present(self):
 1945 
 1946         vserver_client = mock.Mock()
 1947         vserver_client.volume_has_luns.return_value = False
 1948         vserver_client.volume_has_junctioned_volumes.return_value = False
 1949         vserver_client.volume_has_snapmirror_relationships.return_value = True
 1950 
 1951         self.assertRaises(exception.ManageInvalidShare,
 1952                           self.library._validate_volume_for_manage,
 1953                           fake.FLEXVOL_TO_MANAGE,
 1954                           vserver_client)
 1955 
 1956     def test_create_consistency_group_from_cgsnapshot(self):
 1957 
 1958         vserver_client = mock.Mock()
 1959         mock_get_vserver = self.mock_object(
 1960             self.library, '_get_vserver',
 1961             mock.Mock(return_value=(fake.VSERVER1, vserver_client)))
 1962         mock_allocate_container_from_snapshot = self.mock_object(
 1963             self.library, '_allocate_container_from_snapshot')
 1964         mock_create_export = self.mock_object(
 1965             self.library, '_create_export',
 1966             mock.Mock(side_effect=[['loc3'], ['loc4']]))
 1967 
 1968         result = self.library.create_consistency_group_from_cgsnapshot(
 1969             self.context,
 1970             fake.CONSISTENCY_GROUP_DEST,
 1971             fake.CG_SNAPSHOT,
 1972             share_server=fake.SHARE_SERVER)
 1973 
 1974         share_update_list = [
 1975             {'id': fake.SHARE_ID3, 'export_locations': ['loc3']},
 1976             {'id': fake.SHARE_ID4, 'export_locations': ['loc4']}
 1977         ]
 1978         expected = (None, share_update_list)
 1979         self.assertEqual(expected, result)
 1980 
 1981         mock_allocate_container_from_snapshot.assert_has_calls([
 1982             mock.call(fake.COLLATED_CGSNAPSHOT_INFO[0]['share'],
 1983                       fake.COLLATED_CGSNAPSHOT_INFO[0]['snapshot'],
 1984                       fake.VSERVER1,
 1985                       vserver_client,
 1986                       mock.ANY),
 1987             mock.call(fake.COLLATED_CGSNAPSHOT_INFO[1]['share'],
 1988                       fake.COLLATED_CGSNAPSHOT_INFO[1]['snapshot'],
 1989                       fake.VSERVER1,
 1990                       vserver_client,
 1991                       mock.ANY),
 1992         ])
 1993         mock_create_export.assert_has_calls([
 1994             mock.call(fake.COLLATED_CGSNAPSHOT_INFO[0]['share'],
 1995                       fake.SHARE_SERVER,
 1996                       fake.VSERVER1,
 1997                       vserver_client),
 1998             mock.call(fake.COLLATED_CGSNAPSHOT_INFO[1]['share'],
 1999                       fake.SHARE_SERVER,
 2000                       fake.VSERVER1,
 2001                       vserver_client),
 2002         ])
 2003         mock_get_vserver.assert_called_once_with(
 2004             share_server=fake.SHARE_SERVER)
 2005 
 2006     def test_create_consistency_group_from_cgsnapshot_no_members(self):
 2007 
 2008         vserver_client = mock.Mock()
 2009         mock_get_vserver = self.mock_object(
 2010             self.library, '_get_vserver',
 2011             mock.Mock(return_value=(fake.VSERVER1, vserver_client)))
 2012         mock_allocate_container_from_snapshot = self.mock_object(
 2013             self.library, '_allocate_container_from_snapshot')
 2014         mock_create_export = self.mock_object(
 2015             self.library, '_create_export',
 2016             mock.Mock(side_effect=[['loc3'], ['loc4']]))
 2017 
 2018         fake_cg_snapshot = copy.deepcopy(fake.CG_SNAPSHOT)
 2019         fake_cg_snapshot['share_group_snapshot_members'] = []
 2020 
 2021         result = self.library.create_consistency_group_from_cgsnapshot(
 2022             self.context,
 2023             fake.CONSISTENCY_GROUP_DEST,
 2024             fake_cg_snapshot,
 2025             share_server=fake.SHARE_SERVER)
 2026 
 2027         self.assertEqual((None, None), result)
 2028 
 2029         self.assertFalse(mock_allocate_container_from_snapshot.called)
 2030         self.assertFalse(mock_create_export.called)
 2031         mock_get_vserver.assert_called_once_with(
 2032             share_server=fake.SHARE_SERVER)
 2033 
 2034     def test_collate_cg_snapshot_info(self):
 2035 
 2036         result = self.library._collate_cg_snapshot_info(
 2037             fake.CONSISTENCY_GROUP_DEST, fake.CG_SNAPSHOT)
 2038 
 2039         self.assertEqual(fake.COLLATED_CGSNAPSHOT_INFO, result)
 2040 
 2041     def test_collate_cg_snapshot_info_invalid(self):
 2042 
 2043         fake_cg_snapshot = copy.deepcopy(fake.CG_SNAPSHOT)
 2044         fake_cg_snapshot['share_group_snapshot_members'] = []
 2045 
 2046         self.assertRaises(exception.InvalidShareGroup,
 2047                           self.library._collate_cg_snapshot_info,
 2048                           fake.CONSISTENCY_GROUP_DEST, fake_cg_snapshot)
 2049 
 2050     def test_create_cgsnapshot(self):
 2051 
 2052         vserver_client = mock.Mock()
 2053         mock_get_vserver = self.mock_object(
 2054             self.library, '_get_vserver',
 2055             mock.Mock(return_value=(fake.VSERVER1, vserver_client)))
 2056 
 2057         result = self.library.create_cgsnapshot(
 2058             self.context,
 2059             fake.CG_SNAPSHOT,
 2060             share_server=fake.SHARE_SERVER)
 2061 
 2062         share_names = [
 2063             self.library._get_backend_share_name(
 2064                 fake.CG_SNAPSHOT_MEMBER_1['share_id']),
 2065             self.library._get_backend_share_name(
 2066                 fake.CG_SNAPSHOT_MEMBER_2['share_id'])
 2067         ]
 2068         snapshot_name = self.library._get_backend_cg_snapshot_name(
 2069             fake.CG_SNAPSHOT['id'])
 2070         vserver_client.create_cg_snapshot.assert_called_once_with(
 2071             share_names, snapshot_name)
 2072         self.assertEqual((None, None), result)
 2073         mock_get_vserver.assert_called_once_with(
 2074             share_server=fake.SHARE_SERVER)
 2075 
 2076     def test_create_cgsnapshot_no_members(self):
 2077 
 2078         vserver_client = mock.Mock()
 2079         mock_get_vserver = self.mock_object(
 2080             self.library, '_get_vserver',
 2081             mock.Mock(return_value=(fake.VSERVER1, vserver_client)))
 2082 
 2083         fake_cg_snapshot = copy.deepcopy(fake.CG_SNAPSHOT)
 2084         fake_cg_snapshot['share_group_snapshot_members'] = []
 2085 
 2086         result = self.library.create_cgsnapshot(
 2087             self.context,
 2088             fake_cg_snapshot,
 2089             share_server=fake.SHARE_SERVER)
 2090 
 2091         self.assertFalse(vserver_client.create_cg_snapshot.called)
 2092         self.assertEqual((None, None), result)
 2093         mock_get_vserver.assert_called_once_with(
 2094             share_server=fake.SHARE_SERVER)
 2095 
 2096     def test_delete_cgsnapshot(self):
 2097 
 2098         vserver_client = mock.Mock()
 2099         mock_get_vserver = self.mock_object(
 2100             self.library, '_get_vserver',
 2101             mock.Mock(return_value=(fake.VSERVER1, vserver_client)))
 2102         mock_delete_snapshot = self.mock_object(self.library,
 2103                                                 '_delete_snapshot')
 2104 
 2105         result = self.library.delete_cgsnapshot(
 2106             self.context,
 2107             fake.CG_SNAPSHOT,
 2108             share_server=fake.SHARE_SERVER)
 2109 
 2110         share_names = [
 2111             self.library._get_backend_share_name(
 2112                 fake.CG_SNAPSHOT_MEMBER_1['share_id']),
 2113             self.library._get_backend_share_name(
 2114                 fake.CG_SNAPSHOT_MEMBER_2['share_id'])
 2115         ]
 2116         snapshot_name = self.library._get_backend_cg_snapshot_name(
 2117             fake.CG_SNAPSHOT['id'])
 2118 
 2119         mock_delete_snapshot.assert_has_calls([
 2120             mock.call(vserver_client, share_names[0], snapshot_name),
 2121             mock.call(vserver_client, share_names[1], snapshot_name)
 2122         ])
 2123         self.assertEqual((None, None), result)
 2124         mock_get_vserver.assert_called_once_with(
 2125             share_server=fake.SHARE_SERVER)
 2126 
 2127     def test_delete_cgsnapshot_no_members(self):
 2128 
 2129         vserver_client = mock.Mock()
 2130         mock_get_vserver = self.mock_object(
 2131             self.library, '_get_vserver',
 2132             mock.Mock(return_value=(fake.VSERVER1, vserver_client)))
 2133         mock_delete_snapshot = self.mock_object(self.library,
 2134                                                 '_delete_snapshot')
 2135 
 2136         fake_cg_snapshot = copy.deepcopy(fake.CG_SNAPSHOT)
 2137         fake_cg_snapshot['share_group_snapshot_members'] = []
 2138 
 2139         result = self.library.delete_cgsnapshot(
 2140             self.context,
 2141             fake_cg_snapshot,
 2142             share_server=fake.SHARE_SERVER)
 2143 
 2144         self.assertFalse(mock_delete_snapshot.called)
 2145         self.assertEqual((None, None), result)
 2146         mock_get_vserver.assert_called_once_with(
 2147             share_server=fake.SHARE_SERVER)
 2148 
 2149     def test_delete_cgsnapshot_snapshots_not_found(self):
 2150 
 2151         vserver_client = mock.Mock()
 2152         mock_get_vserver = self.mock_object(
 2153             self.library, '_get_vserver',
 2154             mock.Mock(return_value=(fake.VSERVER1, vserver_client)))
 2155         mock_delete_snapshot = self.mock_object(
 2156             self.library, '_delete_snapshot',
 2157             mock.Mock(side_effect=exception.SnapshotResourceNotFound(
 2158                 name='fake')))
 2159 
 2160         result = self.library.delete_cgsnapshot(
 2161             self.context,
 2162             fake.CG_SNAPSHOT,
 2163             share_server=fake.SHARE_SERVER)
 2164 
 2165         share_names = [
 2166             self.library._get_backend_share_name(
 2167                 fake.CG_SNAPSHOT_MEMBER_1['share_id']),
 2168             self.library._get_backend_share_name(
 2169                 fake.CG_SNAPSHOT_MEMBER_2['share_id'])
 2170         ]
 2171         snapshot_name = self.library._get_backend_cg_snapshot_name(
 2172             fake.CG_SNAPSHOT['id'])
 2173 
 2174         mock_delete_snapshot.assert_has_calls([
 2175             mock.call(vserver_client, share_names[0], snapshot_name),
 2176             mock.call(vserver_client, share_names[1], snapshot_name)
 2177         ])
 2178         self.assertEqual((None, None), result)
 2179         mock_get_vserver.assert_called_once_with(
 2180             share_server=fake.SHARE_SERVER)
 2181 
 2182     @ddt.data(exception.InvalidInput(reason='fake_reason'),
 2183               exception.VserverNotSpecified(),
 2184               exception.VserverNotFound(vserver='fake_vserver'))
 2185     def test_delete_cgsnapshot_no_share_server(self,
 2186                                                get_vserver_exception):
 2187 
 2188         mock_get_vserver = self.mock_object(
 2189             self.library, '_get_vserver',
 2190             mock.Mock(side_effect=get_vserver_exception))
 2191 
 2192         result = self.library.delete_cgsnapshot(
 2193             self.context,
 2194             fake.EMPTY_CONSISTENCY_GROUP,
 2195             share_server=fake.SHARE_SERVER)
 2196 
 2197         self.assertEqual((None, None), result)
 2198         self.assertEqual(1, lib_base.LOG.warning.call_count)
 2199         mock_get_vserver.assert_called_once_with(
 2200             share_server=fake.SHARE_SERVER)
 2201 
 2202     def test_adjust_qos_policy_with_volume_resize_no_cluster_creds(self):
 2203         self.library._have_cluster_creds = False
 2204         self.mock_object(share_types, 'get_extra_specs_from_share')
 2205 
 2206         retval = self.library._adjust_qos_policy_with_volume_resize(
 2207             fake.SHARE, 10, mock.Mock())
 2208 
 2209         self.assertIsNone(retval)
 2210         share_types.get_extra_specs_from_share.assert_not_called()
 2211 
 2212     def test_adjust_qos_policy_with_volume_resize_no_qos_on_share(self):
 2213         self.library._have_cluster_creds = True
 2214         self.mock_object(share_types, 'get_extra_specs_from_share')
 2215         vserver_client = mock.Mock()
 2216         self.mock_object(vserver_client, 'get_volume',
 2217                          mock.Mock(return_value=fake.FLEXVOL_WITHOUT_QOS))
 2218 
 2219         retval = self.library._adjust_qos_policy_with_volume_resize(
 2220             fake.SHARE, 10, vserver_client)
 2221 
 2222         self.assertIsNone(retval)
 2223         share_types.get_extra_specs_from_share.assert_not_called()
 2224 
 2225     def test_adjust_qos_policy_with_volume_resize_no_size_dependent_qos(self):
 2226         self.library._have_cluster_creds = True
 2227         self.mock_object(share_types, 'get_extra_specs_from_share',
 2228                          mock.Mock(return_value=fake.EXTRA_SPEC_WITH_QOS))
 2229         vserver_client = mock.Mock()
 2230         self.mock_object(vserver_client, 'get_volume',
 2231                          mock.Mock(return_value=fake.FLEXVOL_WITH_QOS))
 2232         self.mock_object(self.library, '_get_max_throughput')
 2233         self.mock_object(self.library._client, 'qos_policy_group_modify')
 2234 
 2235         retval = self.library._adjust_qos_policy_with_volume_resize(
 2236             fake.SHARE, 10, vserver_client)
 2237 
 2238         self.assertIsNone(retval)
 2239         share_types.get_extra_specs_from_share.assert_called_once_with(
 2240             fake.SHARE)
 2241         self.library._get_max_throughput.assert_not_called()
 2242         self.library._client.qos_policy_group_modify.assert_not_called()
 2243 
 2244     def test_adjust_qos_policy_with_volume_resize(self):
 2245         self.library._have_cluster_creds = True
 2246         self.mock_object(
 2247             share_types, 'get_extra_specs_from_share',
 2248             mock.Mock(return_value=fake.EXTRA_SPEC_WITH_SIZE_DEPENDENT_QOS))
 2249         vserver_client = mock.Mock()
 2250         self.mock_object(vserver_client, 'get_volume',
 2251                          mock.Mock(return_value=fake.FLEXVOL_WITH_QOS))
 2252         self.mock_object(self.library._client, 'qos_policy_group_modify')
 2253 
 2254         retval = self.library._adjust_qos_policy_with_volume_resize(
 2255             fake.SHARE, 10, vserver_client)
 2256 
 2257         expected_max_throughput = '10000B/s'
 2258         self.assertIsNone(retval)
 2259         share_types.get_extra_specs_from_share.assert_called_once_with(
 2260             fake.SHARE)
 2261         self.library._client.qos_policy_group_modify.assert_called_once_with(
 2262             fake.QOS_POLICY_GROUP_NAME, expected_max_throughput)
 2263 
 2264     def test_extend_share(self):
 2265 
 2266         vserver_client = mock.Mock()
 2267         self.mock_object(self.library,
 2268                          '_get_vserver',
 2269                          mock.Mock(return_value=(fake.VSERVER1,
 2270                                                  vserver_client)))
 2271         mock_adjust_qos_policy = self.mock_object(
 2272             self.library, '_adjust_qos_policy_with_volume_resize')
 2273 
 2274         mock_set_volume_size = self.mock_object(vserver_client,
 2275                                                 'set_volume_size')
 2276         new_size = fake.SHARE['size'] * 2
 2277 
 2278         self.library.extend_share(fake.SHARE, new_size)
 2279 
 2280         mock_set_volume_size.assert_called_once_with(fake.SHARE_NAME, new_size)
 2281         mock_adjust_qos_policy.assert_called_once_with(
 2282             fake.SHARE, new_size, vserver_client)
 2283 
 2284     def test_shrink_share(self):
 2285 
 2286         vserver_client = mock.Mock()
 2287         self.mock_object(self.library,
 2288                          '_get_vserver',
 2289                          mock.Mock(return_value=(fake.VSERVER1,
 2290                                                  vserver_client)))
 2291         mock_adjust_qos_policy = self.mock_object(
 2292             self.library, '_adjust_qos_policy_with_volume_resize')
 2293         mock_set_volume_size = self.mock_object(vserver_client,
 2294                                                 'set_volume_size')
 2295         new_size = fake.SHARE['size'] - 1
 2296 
 2297         self.library.shrink_share(fake.SHARE, new_size)
 2298 
 2299         mock_set_volume_size.assert_called_once_with(fake.SHARE_NAME, new_size)
 2300         mock_adjust_qos_policy.assert_called_once_with(
 2301             fake.SHARE, new_size, vserver_client)
 2302 
 2303     def test_shrinking_possible_data_loss(self):
 2304 
 2305         naapi_error = self._mock_api_error(code=netapp_api.EVOLOPNOTSUPP,
 2306                                            message='Possible data loss')
 2307 
 2308         vserver_client = mock.Mock()
 2309         self.mock_object(self.library,
 2310                          '_get_vserver',
 2311                          mock.Mock(return_value=(fake.VSERVER1,
 2312                                                  vserver_client)))
 2313 
 2314         mock_set_volume_size = self.mock_object(
 2315             vserver_client, 'set_volume_size', naapi_error)
 2316 
 2317         new_size = fake.SHARE['size'] - 1
 2318 
 2319         self.assertRaises(exception.ShareShrinkingPossibleDataLoss,
 2320                           self.library.shrink_share,
 2321                           fake.SHARE, new_size)
 2322 
 2323         self.library._get_vserver.assert_called_once_with(share_server=None)
 2324         mock_set_volume_size.assert_called_once_with(fake.SHARE_NAME, new_size)
 2325 
 2326     def test_update_access(self):
 2327 
 2328         vserver_client = mock.Mock()
 2329         mock_get_vserver = self.mock_object(
 2330             self.library, '_get_vserver',
 2331             mock.Mock(return_value=(fake.VSERVER1, vserver_client)))
 2332         protocol_helper = mock.Mock()
 2333         protocol_helper.update_access.return_value = None
 2334         self.mock_object(self.library,
 2335                          '_get_helper',
 2336                          mock.Mock(return_value=protocol_helper))
 2337         mock_share_exists = self.mock_object(self.library,
 2338                                              '_share_exists',
 2339                                              mock.Mock(return_value=True))
 2340 
 2341         self.library.update_access(self.context,
 2342                                    fake.SHARE,
 2343                                    [fake.SHARE_ACCESS],
 2344                                    [],
 2345                                    [],
 2346                                    share_server=fake.SHARE_SERVER)
 2347 
 2348         mock_get_vserver.assert_called_once_with(
 2349             share_server=fake.SHARE_SERVER)
 2350         share_name = self.library._get_backend_share_name(fake.SHARE['id'])
 2351         mock_share_exists.assert_called_once_with(share_name, vserver_client)
 2352         protocol_helper.set_client.assert_called_once_with(vserver_client)
 2353         protocol_helper.update_access.assert_called_once_with(
 2354             fake.SHARE, fake.SHARE_NAME, [fake.SHARE_ACCESS])
 2355 
 2356     @ddt.data(exception.InvalidInput(reason='fake_reason'),
 2357               exception.VserverNotSpecified(),
 2358               exception.VserverNotFound(vserver='fake_vserver'))
 2359     def test_update_access_no_share_server(self, get_vserver_exception):
 2360 
 2361         mock_get_vserver = self.mock_object(
 2362             self.library, '_get_vserver',
 2363             mock.Mock(side_effect=get_vserver_exception))
 2364         protocol_helper = mock.Mock()
 2365         protocol_helper.update_access.return_value = None
 2366         self.mock_object(self.library,
 2367                          '_get_helper',
 2368                          mock.Mock(return_value=protocol_helper))
 2369         mock_share_exists = self.mock_object(self.library, '_share_exists')
 2370 
 2371         self.library.update_access(self.context,
 2372                                    fake.SHARE,
 2373                                    [fake.SHARE_ACCESS],
 2374                                    [],
 2375                                    [],
 2376                                    share_server=fake.SHARE_SERVER)
 2377 
 2378         mock_get_vserver.assert_called_once_with(
 2379             share_server=fake.SHARE_SERVER)
 2380         self.assertFalse(mock_share_exists.called)
 2381         self.assertFalse(protocol_helper.set_client.called)
 2382         self.assertFalse(protocol_helper.update_access.called)
 2383 
 2384     def test_update_access_share_not_found(self):
 2385 
 2386         vserver_client = mock.Mock()
 2387         mock_get_vserver = self.mock_object(
 2388             self.library, '_get_vserver',
 2389             mock.Mock(return_value=(fake.VSERVER1, vserver_client)))
 2390         protocol_helper = mock.Mock()
 2391         protocol_helper.update_access.return_value = None
 2392         self.mock_object(self.library,
 2393                          '_get_helper',
 2394                          mock.Mock(return_value=protocol_helper))
 2395         mock_share_exists = self.mock_object(self.library,
 2396                                              '_share_exists',
 2397                                              mock.Mock(return_value=False))
 2398 
 2399         self.assertRaises(exception.ShareResourceNotFound,
 2400                           self.library.update_access,
 2401                           self.context,
 2402                           fake.SHARE,
 2403                           [fake.SHARE_ACCESS],
 2404                           [],
 2405                           [],
 2406                           share_server=fake.SHARE_SERVER)
 2407 
 2408         mock_get_vserver.assert_called_once_with(
 2409             share_server=fake.SHARE_SERVER)
 2410         share_name = self.library._get_backend_share_name(fake.SHARE['id'])
 2411         mock_share_exists.assert_called_once_with(share_name, vserver_client)
 2412         self.assertFalse(protocol_helper.set_client.called)
 2413         self.assertFalse(protocol_helper.update_access.called)
 2414 
 2415     def test_update_access_to_active_replica(self):
 2416         fake_share = copy.deepcopy(fake.SHARE)
 2417         fake_share['replica_state'] = constants.REPLICA_STATE_ACTIVE
 2418         vserver_client = mock.Mock()
 2419         mock_get_vserver = self.mock_object(
 2420             self.library, '_get_vserver',
 2421             mock.Mock(return_value=(fake.VSERVER1, vserver_client)))
 2422         protocol_helper = mock.Mock()
 2423         protocol_helper.update_access.return_value = None
 2424         self.mock_object(self.library,
 2425                          '_get_helper',
 2426                          mock.Mock(return_value=protocol_helper))
 2427         mock_share_exists = self.mock_object(self.library,
 2428                                              '_share_exists',
 2429                                              mock.Mock(return_value=True))
 2430 
 2431         self.library.update_access(self.context,
 2432                                    fake_share,
 2433                                    [fake.SHARE_ACCESS],
 2434                                    [],
 2435                                    [],
 2436                                    share_server=fake.SHARE_SERVER)
 2437 
 2438         mock_get_vserver.assert_called_once_with(
 2439             share_server=fake.SHARE_SERVER)
 2440         share_name = self.library._get_backend_share_name(fake.SHARE['id'])
 2441         mock_share_exists.assert_called_once_with(share_name, vserver_client)
 2442         protocol_helper.set_client.assert_called_once_with(vserver_client)
 2443         protocol_helper.update_access.assert_called_once_with(
 2444             fake.SHARE, fake.SHARE_NAME, [fake.SHARE_ACCESS])
 2445 
 2446     def test_update_access_to_in_sync_replica(self):
 2447         fake_share = copy.deepcopy(fake.SHARE)
 2448         fake_share['replica_state'] = constants.REPLICA_STATE_IN_SYNC
 2449         self.library.update_access(self.context,
 2450                                    fake_share,
 2451                                    [fake.SHARE_ACCESS],
 2452                                    [],
 2453                                    [],
 2454                                    share_server=fake.SHARE_SERVER)
 2455 
 2456     def test_setup_server(self):
 2457         self.assertRaises(NotImplementedError,
 2458                           self.library.setup_server,
 2459                           fake.NETWORK_INFO)
 2460 
 2461     def test_teardown_server(self):
 2462         self.assertRaises(NotImplementedError,
 2463                           self.library.teardown_server,
 2464                           fake.SHARE_SERVER['backend_details'])
 2465 
 2466     def test_get_network_allocations_number(self):
 2467         self.assertRaises(NotImplementedError,
 2468                           self.library.get_network_allocations_number)
 2469 
 2470     def test_update_ssc_info(self):
 2471 
 2472         self.mock_object(self.library,
 2473                          '_find_matching_aggregates',
 2474                          mock.Mock(return_value=fake.AGGREGATES))
 2475         mock_update_ssc_aggr_info = self.mock_object(self.library,
 2476                                                      '_update_ssc_aggr_info')
 2477 
 2478         self.library._update_ssc_info()
 2479 
 2480         expected = {
 2481             fake.AGGREGATES[0]: {
 2482                 'netapp_aggregate': fake.AGGREGATES[0],
 2483             },
 2484             fake.AGGREGATES[1]: {
 2485                 'netapp_aggregate': fake.AGGREGATES[1],
 2486             }
 2487         }
 2488 
 2489         self.assertDictEqual(expected, self.library._ssc_stats)
 2490         self.assertTrue(mock_update_ssc_aggr_info.called)
 2491 
 2492     def test_update_ssc_info_no_aggregates(self):
 2493 
 2494         self.mock_object(self.library,
 2495                          '_find_matching_aggregates',
 2496                          mock.Mock(return_value=[]))
 2497         mock_update_ssc_aggr_info = self.mock_object(self.library,
 2498                                                      '_update_ssc_aggr_info')
 2499 
 2500         self.library._update_ssc_info()
 2501 
 2502         self.assertDictEqual({}, self.library._ssc_stats)
 2503         self.assertFalse(mock_update_ssc_aggr_info.called)
 2504 
 2505     def test_update_ssc_aggr_info(self):
 2506 
 2507         self.library._have_cluster_creds = True
 2508         mock_get_aggregate = self.mock_object(
 2509             self.client, 'get_aggregate',
 2510             mock.Mock(side_effect=fake.SSC_AGGREGATES))
 2511         mock_get_aggregate_disk_types = self.mock_object(
 2512             self.client, 'get_aggregate_disk_types',
 2513             mock.Mock(side_effect=fake.SSC_DISK_TYPES))
 2514         ssc_stats = {
 2515             fake.AGGREGATES[0]: {
 2516                 'netapp_aggregate': fake.AGGREGATES[0],
 2517             },
 2518             fake.AGGREGATES[1]: {
 2519                 'netapp_aggregate': fake.AGGREGATES[1],
 2520             },
 2521         }
 2522 
 2523         self.library._update_ssc_aggr_info(fake.AGGREGATES, ssc_stats)
 2524 
 2525         self.assertDictEqual(fake.SSC_INFO, ssc_stats)
 2526         mock_get_aggregate.assert_has_calls([
 2527             mock.call(fake.AGGREGATES[0]),
 2528             mock.call(fake.AGGREGATES[1]),
 2529         ])
 2530         mock_get_aggregate_disk_types.assert_has_calls([
 2531             mock.call(fake.AGGREGATES[0]),
 2532             mock.call(fake.AGGREGATES[1]),
 2533         ])
 2534 
 2535     def test_update_ssc_aggr_info_not_found(self):
 2536 
 2537         self.library._have_cluster_creds = True
 2538         self.mock_object(self.client,
 2539                          'get_aggregate',
 2540                          mock.Mock(return_value={}))
 2541         self.mock_object(self.client,
 2542                          'get_aggregate_disk_types',
 2543                          mock.Mock(return_value=None))
 2544         ssc_stats = {
 2545             fake.AGGREGATES[0]: {},
 2546             fake.AGGREGATES[1]: {},
 2547         }
 2548 
 2549         self.library._update_ssc_aggr_info(fake.AGGREGATES, ssc_stats)
 2550 
 2551         expected = {
 2552             fake.AGGREGATES[0]: {
 2553                 'netapp_raid_type': None,
 2554                 'netapp_disk_type': None,
 2555                 'netapp_hybrid_aggregate': None,
 2556             },
 2557             fake.AGGREGATES[1]: {
 2558                 'netapp_raid_type': None,
 2559                 'netapp_disk_type': None,
 2560                 'netapp_hybrid_aggregate': None,
 2561             }
 2562         }
 2563         self.assertDictEqual(expected, ssc_stats)
 2564 
 2565     def test_update_ssc_aggr_info_no_cluster_creds(self):
 2566 
 2567         self.library._have_cluster_creds = False
 2568         ssc_stats = {}
 2569 
 2570         self.library._update_ssc_aggr_info(fake.AGGREGATES, ssc_stats)
 2571 
 2572         self.assertDictEqual({}, ssc_stats)
 2573         self.assertFalse(self.library._client.get_aggregate_raid_types.called)
 2574 
 2575     def test_create_replica(self):
 2576         self.mock_object(self.library,
 2577                          '_allocate_container')
 2578         mock_dm_session = mock.Mock()
 2579         self.mock_object(data_motion, "DataMotionSession",
 2580                          mock.Mock(return_value=mock_dm_session))
 2581         self.mock_object(data_motion, 'get_client_for_backend')
 2582         self.mock_object(mock_dm_session, 'get_vserver_from_share',
 2583                          mock.Mock(return_value=fake.VSERVER1))
 2584         expected_model_update = {
 2585             'export_locations': [],
 2586             'replica_state': constants.REPLICA_STATE_OUT_OF_SYNC,
 2587             'access_rules_status': constants.STATUS_ACTIVE,
 2588         }
 2589 
 2590         model_update = self.library.create_replica(
 2591             None, [fake.SHARE], fake.SHARE, [], [],
 2592             share_server=None)
 2593 
 2594         self.assertDictMatch(expected_model_update, model_update)
 2595         mock_dm_session.create_snapmirror.assert_called_once_with(fake.SHARE,
 2596                                                                   fake.SHARE)
 2597         data_motion.get_client_for_backend.assert_called_once_with(
 2598             fake.BACKEND_NAME, vserver_name=fake.VSERVER1)
 2599 
 2600     def test_create_replica_with_share_server(self):
 2601         self.mock_object(self.library,
 2602                          '_allocate_container',
 2603                          mock.Mock())
 2604         mock_dm_session = mock.Mock()
 2605         self.mock_object(data_motion, "DataMotionSession",
 2606                          mock.Mock(return_value=mock_dm_session))
 2607         self.mock_object(data_motion, 'get_client_for_backend')
 2608         self.mock_object(mock_dm_session, 'get_vserver_from_share',
 2609                          mock.Mock(return_value=fake.VSERVER1))
 2610 
 2611         expected_model_update = {
 2612             'export_locations': [],
 2613             'replica_state': constants.REPLICA_STATE_OUT_OF_SYNC,
 2614             'access_rules_status': constants.STATUS_ACTIVE,
 2615         }
 2616 
 2617         model_update = self.library.create_replica(
 2618             None, [fake.SHARE], fake.SHARE, [], [],
 2619             share_server=fake.SHARE_SERVER)
 2620 
 2621         self.assertDictMatch(expected_model_update, model_update)
 2622         mock_dm_session.create_snapmirror.assert_called_once_with(fake.SHARE,
 2623                                                                   fake.SHARE)
 2624         data_motion.get_client_for_backend.assert_called_once_with(
 2625             fake.BACKEND_NAME, vserver_name=fake.VSERVER1)
 2626 
 2627     def test_delete_replica(self):
 2628 
 2629         active_replica = fake_replica(
 2630             replica_state=constants.REPLICA_STATE_ACTIVE)
 2631         replica_1 = fake_replica(
 2632             replica_state=constants.REPLICA_STATE_IN_SYNC,
 2633             host=fake.MANILA_HOST_NAME)
 2634         replica_2 = fake_replica(
 2635             replica_state=constants.REPLICA_STATE_OUT_OF_SYNC)
 2636         replica_list = [active_replica, replica_1, replica_2]
 2637 
 2638         self.mock_object(self.library,
 2639                          '_deallocate_container',
 2640                          mock.Mock())
 2641         self.mock_object(self.library,
 2642                          '_share_exists',
 2643                          mock.Mock(return_value=False))
 2644         mock_dm_session = mock.Mock()
 2645         self.mock_object(data_motion, "DataMotionSession",
 2646                          mock.Mock(return_value=mock_dm_session))
 2647         self.mock_object(data_motion, 'get_client_for_backend')
 2648         self.mock_object(mock_dm_session, 'get_vserver_from_share',
 2649                          mock.Mock(return_value=fake.VSERVER1))
 2650 
 2651         result = self.library.delete_replica(None,
 2652                                              replica_list,
 2653                                              replica_1,
 2654                                              [],
 2655                                              share_server=None)
 2656         self.assertIsNone(result)
 2657         mock_dm_session.delete_snapmirror.assert_has_calls([
 2658             mock.call(active_replica, replica_1),
 2659             mock.call(replica_2, replica_1),
 2660             mock.call(replica_1, replica_2),
 2661             mock.call(replica_1, active_replica)],
 2662             any_order=True)
 2663         self.assertEqual(4, mock_dm_session.delete_snapmirror.call_count)
 2664         data_motion.get_client_for_backend.assert_called_with(
 2665             fake.BACKEND_NAME, vserver_name=mock.ANY)
 2666         self.assertEqual(1, data_motion.get_client_for_backend.call_count)
 2667 
 2668     def test_delete_replica_with_share_server(self):
 2669 
 2670         active_replica = fake_replica(
 2671             replica_state=constants.REPLICA_STATE_ACTIVE)
 2672         replica = fake_replica(replica_state=constants.REPLICA_STATE_IN_SYNC,
 2673                                host=fake.MANILA_HOST_NAME)
 2674         replica_list = [active_replica, replica]
 2675 
 2676         self.mock_object(self.library,
 2677                          '_deallocate_container',
 2678                          mock.Mock())
 2679         self.mock_object(self.library,
 2680                          '_share_exists',
 2681                          mock.Mock(return_value=False))
 2682         mock_dm_session = mock.Mock()
 2683         self.mock_object(data_motion, "DataMotionSession",
 2684                          mock.Mock(return_value=mock_dm_session))
 2685         self.mock_object(data_motion, 'get_client_for_backend')
 2686         self.mock_object(mock_dm_session, 'get_vserver_from_share',
 2687                          mock.Mock(return_value=fake.VSERVER1))
 2688 
 2689         result = self.library.delete_replica(None,
 2690                                              replica_list,
 2691                                              replica,
 2692                                              [],
 2693                                              share_server=fake.SHARE_SERVER)
 2694         self.assertIsNone(result)
 2695         mock_dm_session.delete_snapmirror.assert_has_calls([
 2696             mock.call(active_replica, replica),
 2697             mock.call(replica, active_replica)],
 2698             any_order=True)
 2699         data_motion.get_client_for_backend.assert_called_once_with(
 2700             fake.BACKEND_NAME, vserver_name=fake.VSERVER1)
 2701 
 2702     def test_delete_replica_share_absent_on_backend(self):
 2703         active_replica = fake_replica(
 2704             replica_state=constants.REPLICA_STATE_ACTIVE)
 2705         replica = fake_replica(replica_state=constants.REPLICA_STATE_IN_SYNC,
 2706                                host=fake.MANILA_HOST_NAME)
 2707         replica_list = [active_replica, replica]
 2708 
 2709         self.mock_object(self.library,
 2710                          '_deallocate_container',
 2711                          mock.Mock())
 2712         self.mock_object(self.library,
 2713                          '_share_exists',
 2714                          mock.Mock(return_value=False))
 2715         mock_dm_session = mock.Mock()
 2716         self.mock_object(data_motion,
 2717                          "DataMotionSession",
 2718                          mock.Mock(return_value=mock_dm_session))
 2719         self.mock_object(data_motion, 'get_client_for_backend')
 2720         self.mock_object(mock_dm_session,
 2721                          'get_vserver_from_share',
 2722                          mock.Mock(return_value=fake.VSERVER1))
 2723 
 2724         result = self.library.delete_replica(None,
 2725                                              replica_list,
 2726                                              replica,
 2727                                              [],
 2728                                              share_server=None)
 2729 
 2730         self.assertIsNone(result)
 2731         self.assertFalse(self.library._deallocate_container.called)
 2732         mock_dm_session.delete_snapmirror.assert_has_calls([
 2733             mock.call(active_replica, replica),
 2734             mock.call(replica, active_replica)],
 2735             any_order=True)
 2736         data_motion.get_client_for_backend.assert_called_with(
 2737             fake.BACKEND_NAME, vserver_name=mock.ANY)
 2738         self.assertEqual(1, data_motion.get_client_for_backend.call_count)
 2739 
 2740     def test_update_replica_state_no_snapmirror_share_creating(self):
 2741         vserver_client = mock.Mock()
 2742         self.mock_object(vserver_client, 'volume_exists',
 2743                          mock.Mock(return_value=True))
 2744         self.mock_object(self.library,
 2745                          '_get_vserver',
 2746                          mock.Mock(return_value=(fake.VSERVER1,
 2747                                                  vserver_client)))
 2748         self.mock_dm_session.get_snapmirrors = mock.Mock(return_value=[])
 2749 
 2750         replica = copy.deepcopy(fake.SHARE)
 2751         replica['status'] = constants.STATUS_CREATING
 2752 
 2753         result = self.library.update_replica_state(
 2754             None, [replica], replica, None, [], share_server=None)
 2755 
 2756         self.assertFalse(self.mock_dm_session.create_snapmirror.called)
 2757         self.assertEqual(constants.STATUS_OUT_OF_SYNC, result)
 2758 
 2759     def test_update_replica_state_share_reverting_to_snapshot(self):
 2760         vserver_client = mock.Mock()
 2761         self.mock_object(vserver_client, 'volume_exists',
 2762                          mock.Mock(return_value=True))
 2763         self.mock_object(self.library,
 2764                          '_get_vserver',
 2765                          mock.Mock(return_value=(fake.VSERVER1,
 2766                                                  vserver_client)))
 2767         self.mock_dm_session.get_snapmirrors = mock.Mock(return_value=[])
 2768 
 2769         replica = copy.deepcopy(fake.SHARE)
 2770         replica['status'] = constants.STATUS_REVERTING
 2771 
 2772         result = self.library.update_replica_state(
 2773             None, [replica], replica, None, [], share_server=None)
 2774 
 2775         self.assertFalse(self.mock_dm_session.get_snapmirrors.called)
 2776         self.assertFalse(self.mock_dm_session.create_snapmirror.called)
 2777         self.assertIsNone(result)
 2778 
 2779     def test_update_replica_state_no_snapmirror_create_failed(self):
 2780         vserver_client = mock.Mock()
 2781         self.mock_object(vserver_client, 'volume_exists',
 2782                          mock.Mock(return_value=True))
 2783         self.mock_object(self.library,
 2784                          '_get_vserver',
 2785                          mock.Mock(return_value=(fake.VSERVER1,
 2786                                                  vserver_client)))
 2787         self.mock_dm_session.get_snapmirrors = mock.Mock(return_value=[])
 2788         self.mock_dm_session.create_snapmirror.side_effect = (
 2789             netapp_api.NaApiError(code=0))
 2790 
 2791         replica = copy.deepcopy(fake.SHARE)
 2792         replica['status'] = constants.REPLICA_STATE_OUT_OF_SYNC
 2793 
 2794         result = self.library.update_replica_state(
 2795             None, [replica], replica, None, [], share_server=None)
 2796 
 2797         self.assertTrue(self.mock_dm_session.create_snapmirror.called)
 2798         self.assertEqual(constants.STATUS_ERROR, result)
 2799 
 2800     @ddt.data(constants.STATUS_ERROR, constants.STATUS_AVAILABLE)
 2801     def test_update_replica_state_no_snapmirror(self, status):
 2802         vserver_client = mock.Mock()
 2803         self.mock_object(vserver_client, 'volume_exists',
 2804                          mock.Mock(return_value=True))
 2805         self.mock_object(self.library,
 2806                          '_get_vserver',
 2807                          mock.Mock(return_value=(fake.VSERVER1,
 2808                                                  vserver_client)))
 2809         self.mock_dm_session.get_snapmirrors = mock.Mock(return_value=[])
 2810 
 2811         replica = copy.deepcopy(fake.SHARE)
 2812         replica['status'] = status
 2813 
 2814         result = self.library.update_replica_state(
 2815             None, [replica], replica, None, [], share_server=None)
 2816 
 2817         self.assertEqual(1, self.mock_dm_session.create_snapmirror.call_count)
 2818         self.assertEqual(constants.STATUS_OUT_OF_SYNC, result)
 2819 
 2820     def test_update_replica_state_broken_snapmirror(self):
 2821         fake_snapmirror = {
 2822             'mirror-state': 'broken-off',
 2823             'relationship-status': 'idle',
 2824             'source-vserver': fake.VSERVER2,
 2825             'source-volume': 'fake_volume',
 2826             'last-transfer-end-timestamp': '%s' % float(time.time() - 10000)
 2827         }
 2828         vserver_client = mock.Mock()
 2829         self.mock_object(vserver_client, 'volume_exists',
 2830                          mock.Mock(return_value=True))
 2831         self.mock_object(self.library,
 2832                          '_get_vserver',
 2833                          mock.Mock(return_value=(fake.VSERVER1,
 2834                                                  vserver_client)))
 2835         self.mock_dm_session.get_snapmirrors = mock.Mock(
 2836             return_value=[fake_snapmirror])
 2837 
 2838         result = self.library.update_replica_state(None, [fake.SHARE],
 2839                                                    fake.SHARE, None, [],
 2840                                                    share_server=None)
 2841 
 2842         vserver_client.resync_snapmirror.assert_called_once_with(
 2843             fake.VSERVER2, 'fake_volume', fake.VSERVER1, fake.SHARE['name']
 2844         )
 2845 
 2846         self.assertEqual(constants.REPLICA_STATE_OUT_OF_SYNC, result)
 2847 
 2848     def test_update_replica_state_snapmirror_still_initializing(self):
 2849         fake_snapmirror = {
 2850             'mirror-state': 'uninitialized',
 2851             'relationship-status': 'transferring',
 2852             'source-vserver': fake.VSERVER2,
 2853             'source-volume': 'fake_volume',
 2854             'last-transfer-end-timestamp': '%s' % float(time.time() - 10000)
 2855         }
 2856         vserver_client = mock.Mock()
 2857         self.mock_object(vserver_client, 'volume_exists',
 2858                          mock.Mock(return_value=True))
 2859         self.mock_object(self.library,
 2860                          '_get_vserver',
 2861                          mock.Mock(return_value=(fake.VSERVER1,
 2862                                                  vserver_client)))
 2863         self.mock_dm_session.get_snapmirrors = mock.Mock(
 2864             return_value=[fake_snapmirror])
 2865 
 2866         result = self.library.update_replica_state(None, [fake.SHARE],
 2867                                                    fake.SHARE, None, [],
 2868                                                    share_server=None)
 2869 
 2870         self.assertEqual(constants.REPLICA_STATE_OUT_OF_SYNC, result)
 2871 
 2872     def test_update_replica_state_fail_to_get_snapmirrors(self):
 2873         vserver_client = mock.Mock()
 2874         self.mock_object(vserver_client, 'volume_exists',
 2875                          mock.Mock(return_value=True))
 2876         self.mock_object(self.library,
 2877                          '_get_vserver',
 2878                          mock.Mock(return_value=(fake.VSERVER1,
 2879                                                  vserver_client)))
 2880         self.mock_dm_session.get_snapmirrors.side_effect = (
 2881             netapp_api.NaApiError(code=0))
 2882 
 2883         result = self.library.update_replica_state(None, [fake.SHARE],
 2884                                                    fake.SHARE, None, [],
 2885                                                    share_server=None)
 2886         self.assertTrue(self.mock_dm_session.get_snapmirrors.called)
 2887         self.assertEqual(constants.STATUS_ERROR, result)
 2888 
 2889     def test_update_replica_state_broken_snapmirror_resync_error(self):
 2890         fake_snapmirror = {
 2891             'mirror-state': 'broken-off',
 2892             'relationship-status': 'idle',
 2893             'source-vserver': fake.VSERVER2,
 2894             'source-volume': 'fake_volume',
 2895             'last-transfer-end-timestamp': '%s' % float(time.time() - 10000)
 2896         }
 2897         vserver_client = mock.Mock()
 2898         self.mock_object(vserver_client, 'volume_exists',
 2899                          mock.Mock(return_value=True))
 2900         self.mock_object(self.library,
 2901                          '_get_vserver',
 2902                          mock.Mock(return_value=(fake.VSERVER1,
 2903                                                  vserver_client)))
 2904         self.mock_dm_session.get_snapmirrors = mock.Mock(
 2905             return_value=[fake_snapmirror])
 2906         vserver_client.resync_snapmirror.side_effect = netapp_api.NaApiError
 2907 
 2908         result = self.library.update_replica_state(None, [fake.SHARE],
 2909                                                    fake.SHARE, None, [],
 2910                                                    share_server=None)
 2911 
 2912         vserver_client.resync_snapmirror.assert_called_once_with(
 2913             fake.VSERVER2, 'fake_volume', fake.VSERVER1, fake.SHARE['name']
 2914         )
 2915 
 2916         self.assertEqual(constants.STATUS_ERROR, result)
 2917 
 2918     def test_update_replica_state_stale_snapmirror(self):
 2919         fake_snapmirror = {
 2920             'mirror-state': 'snapmirrored',
 2921             'last-transfer-end-timestamp': '%s' % float(
 2922                 timeutils.utcnow_ts() - 10000)
 2923         }
 2924         vserver_client = mock.Mock()
 2925         self.mock_object(vserver_client, 'volume_exists',
 2926                          mock.Mock(return_value=True))
 2927         self.mock_object(self.library,
 2928                          '_get_vserver',
 2929                          mock.Mock(return_value=(fake.VSERVER1,
 2930                                                  vserver_client)))
 2931         self.mock_dm_session.get_snapmirrors = mock.Mock(
 2932             return_value=[fake_snapmirror])
 2933 
 2934         result = self.library.update_replica_state(None, [fake.SHARE],
 2935                                                    fake.SHARE, None, [],
 2936                                                    share_server=None)
 2937 
 2938         self.assertEqual(constants.REPLICA_STATE_OUT_OF_SYNC, result)
 2939 
 2940     def test_update_replica_state_in_sync(self):
 2941         fake_snapmirror = {
 2942             'mirror-state': 'snapmirrored',
 2943             'relationship-status': 'idle',
 2944             'last-transfer-end-timestamp': '%s' % float(time.time())
 2945         }
 2946         vserver_client = mock.Mock()
 2947         self.mock_object(vserver_client, 'volume_exists',
 2948                          mock.Mock(return_value=True))
 2949         self.mock_object(self.library,
 2950                          '_get_vserver',
 2951                          mock.Mock(return_value=(fake.VSERVER1,
 2952                                                  vserver_client)))
 2953         self.mock_dm_session.get_snapmirrors = mock.Mock(
 2954             return_value=[fake_snapmirror])
 2955 
 2956         result = self.library.update_replica_state(None, [fake.SHARE],
 2957                                                    fake.SHARE, None, [],
 2958                                                    share_server=None)
 2959 
 2960         self.assertEqual(constants.REPLICA_STATE_IN_SYNC, result)
 2961 
 2962     def test_update_replica_state_backend_volume_absent(self):
 2963         vserver_client = mock.Mock()
 2964         self.mock_object(vserver_client, 'volume_exists',
 2965                          mock.Mock(return_value=False))
 2966         self.mock_object(self.library,
 2967                          '_get_vserver',
 2968                          mock.Mock(return_value=(fake.VSERVER1,
 2969                                                  vserver_client)))
 2970 
 2971         self.assertRaises(exception.ShareResourceNotFound,
 2972                           self.library.update_replica_state,
 2973                           None, [fake.SHARE], fake.SHARE, None, [],
 2974                           share_server=None)
 2975 
 2976     def test_update_replica_state_in_sync_with_snapshots(self):
 2977         fake_snapmirror = {
 2978             'mirror-state': 'snapmirrored',
 2979             'relationship-status': 'idle',
 2980             'last-transfer-end-timestamp': '%s' % float(time.time())
 2981         }
 2982         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 2983         fake_snapshot['share_id'] = fake.SHARE['id']
 2984         snapshots = [{'share_replica_snapshot': fake_snapshot}]
 2985         vserver_client = mock.Mock()
 2986         self.mock_object(vserver_client, 'snapshot_exists', mock.Mock(
 2987             return_value=True))
 2988         self.mock_object(self.library,
 2989                          '_get_vserver',
 2990                          mock.Mock(return_value=(fake.VSERVER1,
 2991                                                  vserver_client)))
 2992         self.mock_dm_session.get_snapmirrors = mock.Mock(
 2993             return_value=[fake_snapmirror])
 2994 
 2995         result = self.library.update_replica_state(None, [fake.SHARE],
 2996                                                    fake.SHARE, None, snapshots,
 2997                                                    share_server=None)
 2998 
 2999         self.assertEqual(constants.REPLICA_STATE_IN_SYNC, result)
 3000 
 3001     def test_update_replica_state_missing_snapshot(self):
 3002         fake_snapmirror = {
 3003             'mirror-state': 'snapmirrored',
 3004             'relationship-status': 'idle',
 3005             'last-transfer-end-timestamp': '%s' % float(time.time())
 3006         }
 3007         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 3008         fake_snapshot['share_id'] = fake.SHARE['id']
 3009         snapshots = [{'share_replica_snapshot': fake_snapshot}]
 3010         vserver_client = mock.Mock()
 3011         self.mock_object(vserver_client, 'snapshot_exists', mock.Mock(
 3012             return_value=False))
 3013         self.mock_object(self.library,
 3014                          '_get_vserver',
 3015                          mock.Mock(return_value=(fake.VSERVER1,
 3016                                                  vserver_client)))
 3017         self.mock_dm_session.get_snapmirrors = mock.Mock(
 3018             return_value=[fake_snapmirror])
 3019 
 3020         result = self.library.update_replica_state(None, [fake.SHARE],
 3021                                                    fake.SHARE, None, snapshots,
 3022                                                    share_server=None)
 3023 
 3024         self.assertEqual(constants.REPLICA_STATE_OUT_OF_SYNC, result)
 3025 
 3026     def test_promote_replica(self):
 3027         self.mock_object(self.library,
 3028                          '_get_vserver',
 3029                          mock.Mock(return_value=(fake.VSERVER1,
 3030                                                  mock.Mock())))
 3031         protocol_helper = mock.Mock()
 3032         self.mock_object(self.library,
 3033                          '_get_helper',
 3034                          mock.Mock(return_value=protocol_helper))
 3035         self.mock_object(self.library, '_create_export',
 3036                          mock.Mock(return_value='fake_export_location'))
 3037         self.mock_object(self.library, '_unmount_orig_active_replica')
 3038         self.mock_object(self.library, '_handle_qos_on_replication_change')
 3039 
 3040         mock_dm_session = mock.Mock()
 3041         self.mock_object(data_motion, "DataMotionSession",
 3042                          mock.Mock(return_value=mock_dm_session))
 3043         self.mock_object(mock_dm_session, 'get_vserver_from_share',
 3044                          mock.Mock(return_value=fake.VSERVER1))
 3045         self.mock_object(self.client, 'cleanup_demoted_replica')
 3046 
 3047         replicas = self.library.promote_replica(
 3048             None, [self.fake_replica, self.fake_replica_2],
 3049             self.fake_replica_2, [], share_server=None)
 3050 
 3051         mock_dm_session.change_snapmirror_source.assert_called_once_with(
 3052             self.fake_replica, self.fake_replica, self.fake_replica_2,
 3053             mock.ANY
 3054         )
 3055         self.assertEqual(2, len(replicas))
 3056         actual_replica_1 = list(filter(
 3057             lambda x: x['id'] == self.fake_replica['id'], replicas))[0]
 3058         self.assertEqual(constants.REPLICA_STATE_OUT_OF_SYNC,
 3059                          actual_replica_1['replica_state'])
 3060         actual_replica_2 = list(filter(
 3061             lambda x: x['id'] == self.fake_replica_2['id'], replicas))[0]
 3062         self.assertEqual(constants.REPLICA_STATE_ACTIVE,
 3063                          actual_replica_2['replica_state'])
 3064         self.assertEqual('fake_export_location',
 3065                          actual_replica_2['export_locations'])
 3066         self.assertEqual(constants.STATUS_ACTIVE,
 3067                          actual_replica_2['access_rules_status'])
 3068         self.library._unmount_orig_active_replica.assert_called_once_with(
 3069             self.fake_replica, fake.VSERVER1)
 3070         self.library._handle_qos_on_replication_change.assert_called_once()
 3071         protocol_helper.cleanup_demoted_replica.assert_called_once_with(
 3072             self.fake_replica, fake.SHARE['name'])
 3073 
 3074     def test_promote_replica_cleanup_demoted_storage_error(self):
 3075         self.mock_object(self.library,
 3076                          '_get_vserver',
 3077                          mock.Mock(return_value=(fake.VSERVER1,
 3078                                                  mock.Mock())))
 3079         protocol_helper = mock.Mock()
 3080         self.mock_object(self.library,
 3081                          '_get_helper',
 3082                          mock.Mock(return_value=protocol_helper))
 3083         self.mock_object(self.library, '_create_export',
 3084                          mock.Mock(return_value='fake_export_location'))
 3085         self.mock_object(self.library, '_unmount_orig_active_replica')
 3086         self.mock_object(self.library, '_handle_qos_on_replication_change')
 3087 
 3088         mock_dm_session = mock.Mock()
 3089         self.mock_object(data_motion, "DataMotionSession",
 3090                          mock.Mock(return_value=mock_dm_session))
 3091         self.mock_object(mock_dm_session, 'get_vserver_from_share',
 3092                          mock.Mock(return_value=fake.VSERVER1))
 3093         self.mock_object(
 3094             protocol_helper, 'cleanup_demoted_replica',
 3095             mock.Mock(side_effect=exception.StorageCommunicationException))
 3096         mock_log = self.mock_object(lib_base.LOG, 'exception')
 3097 
 3098         self.library.promote_replica(
 3099             None, [self.fake_replica, self.fake_replica_2],
 3100             self.fake_replica_2, [], share_server=None)
 3101 
 3102         mock_dm_session.change_snapmirror_source.assert_called_once_with(
 3103             self.fake_replica, self.fake_replica, self.fake_replica_2,
 3104             mock.ANY
 3105         )
 3106         protocol_helper.cleanup_demoted_replica.assert_called_once_with(
 3107             self.fake_replica, fake.SHARE['name'])
 3108         mock_log.assert_called_once()
 3109 
 3110     def test_promote_replica_destination_unreachable(self):
 3111         self.mock_object(self.library,
 3112                          '_get_vserver',
 3113                          mock.Mock(return_value=(fake.VSERVER1,
 3114                                                  mock.Mock())))
 3115         self.mock_object(self.library,
 3116                          '_get_helper',
 3117                          mock.Mock(return_value=mock.Mock()))
 3118         self.mock_object(self.library, '_unmount_orig_active_replica')
 3119         self.mock_object(self.library, '_handle_qos_on_replication_change')
 3120 
 3121         self.mock_object(self.library, '_create_export',
 3122                          mock.Mock(return_value='fake_export_location'))
 3123         self.mock_object(
 3124             self.library, '_convert_destination_replica_to_independent',
 3125             mock.Mock(side_effect=exception.StorageCommunicationException))
 3126 
 3127         replicas = self.library.promote_replica(
 3128             None, [self.fake_replica, self.fake_replica_2],
 3129             self.fake_replica_2, [], share_server=None)
 3130 
 3131         self.assertEqual(1, len(replicas))
 3132         actual_replica = replicas[0]
 3133         self.assertEqual(constants.STATUS_ERROR,
 3134                          actual_replica['replica_state'])
 3135         self.assertEqual(constants.STATUS_ERROR,
 3136                          actual_replica['status'])
 3137         self.assertFalse(
 3138             self.library._unmount_orig_active_replica.called)
 3139         self.assertFalse(
 3140             self.library._handle_qos_on_replication_change.called)
 3141 
 3142     def test_promote_replica_more_than_two_replicas(self):
 3143         fake_replica_3 = copy.deepcopy(self.fake_replica_2)
 3144         fake_replica_3['id'] = fake.SHARE_ID3
 3145         fake_replica_3['replica_state'] = constants.REPLICA_STATE_OUT_OF_SYNC
 3146         self.mock_object(self.library,
 3147                          '_get_vserver',
 3148                          mock.Mock(return_value=(fake.VSERVER1,
 3149                                                  mock.Mock())))
 3150         self.mock_object(self.library, '_unmount_orig_active_replica')
 3151         self.mock_object(self.library, '_handle_qos_on_replication_change')
 3152         self.mock_object(self.library,
 3153                          '_get_helper',
 3154                          mock.Mock(return_value=mock.Mock()))
 3155 
 3156         self.mock_object(self.library, '_create_export',
 3157                          mock.Mock(return_value='fake_export_location'))
 3158         mock_dm_session = mock.Mock()
 3159         self.mock_object(data_motion, "DataMotionSession",
 3160                          mock.Mock(return_value=mock_dm_session))
 3161         self.mock_object(mock_dm_session, 'get_vserver_from_share',
 3162                          mock.Mock(return_value=fake.VSERVER1))
 3163 
 3164         replicas = self.library.promote_replica(
 3165             None, [self.fake_replica, self.fake_replica_2, fake_replica_3],
 3166             self.fake_replica_2, [], share_server=None)
 3167 
 3168         mock_dm_session.change_snapmirror_source.assert_has_calls([
 3169             mock.call(fake_replica_3, self.fake_replica, self.fake_replica_2,
 3170                       mock.ANY),
 3171             mock.call(self.fake_replica, self.fake_replica,
 3172                       self.fake_replica_2, mock.ANY)
 3173         ], any_order=True)
 3174 
 3175         self.assertEqual(3, len(replicas))
 3176         actual_replica_1 = list(filter(
 3177             lambda x: x['id'] == self.fake_replica['id'], replicas))[0]
 3178         self.assertEqual(constants.REPLICA_STATE_OUT_OF_SYNC,
 3179                          actual_replica_1['replica_state'])
 3180         actual_replica_2 = list(filter(
 3181             lambda x: x['id'] == self.fake_replica_2['id'], replicas))[0]
 3182         self.assertEqual(constants.REPLICA_STATE_ACTIVE,
 3183                          actual_replica_2['replica_state'])
 3184         self.assertEqual('fake_export_location',
 3185                          actual_replica_2['export_locations'])
 3186         actual_replica_3 = list(filter(
 3187             lambda x: x['id'] == fake_replica_3['id'], replicas))[0]
 3188         self.assertEqual(constants.REPLICA_STATE_OUT_OF_SYNC,
 3189                          actual_replica_3['replica_state'])
 3190         self.library._unmount_orig_active_replica.assert_called_once_with(
 3191             self.fake_replica, fake.VSERVER1)
 3192         self.library._handle_qos_on_replication_change.assert_called_once()
 3193 
 3194     def test_promote_replica_with_access_rules(self):
 3195         self.mock_object(self.library,
 3196                          '_get_vserver',
 3197                          mock.Mock(return_value=(fake.VSERVER1,
 3198                                                  mock.Mock())))
 3199         self.mock_object(self.library, '_unmount_orig_active_replica')
 3200         self.mock_object(self.library, '_handle_qos_on_replication_change')
 3201         mock_helper = mock.Mock()
 3202         self.mock_object(self.library,
 3203                          '_get_helper',
 3204                          mock.Mock(return_value=mock_helper))
 3205         self.mock_object(self.library, '_create_export',
 3206                          mock.Mock(return_value='fake_export_location'))
 3207 
 3208         mock_dm_session = mock.Mock()
 3209         self.mock_object(data_motion, "DataMotionSession",
 3210                          mock.Mock(return_value=mock_dm_session))
 3211         self.mock_object(mock_dm_session, 'get_vserver_from_share',
 3212                          mock.Mock(return_value=fake.VSERVER1))
 3213 
 3214         replicas = self.library.promote_replica(
 3215             None, [self.fake_replica, self.fake_replica_2],
 3216             self.fake_replica_2, [fake.SHARE_ACCESS], share_server=None)
 3217 
 3218         mock_dm_session.change_snapmirror_source.assert_has_calls([
 3219             mock.call(self.fake_replica, self.fake_replica,
 3220                       self.fake_replica_2, mock.ANY)
 3221         ], any_order=True)
 3222         self.assertEqual(2, len(replicas))
 3223         share_name = self.library._get_backend_share_name(
 3224             self.fake_replica_2['id'])
 3225         mock_helper.update_access.assert_called_once_with(self.fake_replica_2,
 3226                                                           share_name,
 3227                                                           [fake.SHARE_ACCESS])
 3228         self.library._unmount_orig_active_replica.assert_called_once_with(
 3229             self.fake_replica, fake.VSERVER1)
 3230         self.library._handle_qos_on_replication_change.assert_called_once()
 3231 
 3232     def test_unmount_orig_active_replica(self):
 3233         self.mock_object(share_utils, 'extract_host', mock.Mock(
 3234             return_value=fake.MANILA_HOST_NAME))
 3235         self.mock_object(data_motion, 'get_client_for_backend')
 3236         self.mock_object(self.library, '_get_backend_share_name', mock.Mock(
 3237             return_value=fake.SHARE_NAME))
 3238 
 3239         result = self.library._unmount_orig_active_replica(fake.SHARE)
 3240         self.assertIsNone(result)
 3241 
 3242     @ddt.data({'extra_specs': {'netapp:snapshot_policy': 'none'},
 3243                'have_cluster_creds': True},
 3244               # Test Case 2 isn't possible input
 3245               {'extra_specs': {'qos': True, 'netapp:maxiops': '3000'},
 3246                'have_cluster_creds': False})
 3247     @ddt.unpack
 3248     def test_handle_qos_on_replication_change_nothing_to_handle(
 3249             self, extra_specs, have_cluster_creds):
 3250 
 3251         self.library._have_cluster_creds = have_cluster_creds
 3252         self.mock_object(lib_base.LOG, 'exception')
 3253         self.mock_object(lib_base.LOG, 'info')
 3254         self.mock_object(share_types, 'get_extra_specs_from_share',
 3255                          mock.Mock(return_value=extra_specs))
 3256 
 3257         retval = self.library._handle_qos_on_replication_change(
 3258             self.mock_dm_session, self.fake_replica_2, self.fake_replica,
 3259             share_server=fake.SHARE_SERVER)
 3260 
 3261         self.assertIsNone(retval)
 3262         lib_base.LOG.exception.assert_not_called()
 3263         lib_base.LOG.info.assert_not_called()
 3264 
 3265     def test_handle_qos_on_replication_change_exception(self):
 3266         self.library._have_cluster_creds = True
 3267         extra_specs = {'qos': True, fake.QOS_EXTRA_SPEC: '3000'}
 3268         vserver_client = mock.Mock()
 3269         self.mock_object(lib_base.LOG, 'exception')
 3270         self.mock_object(lib_base.LOG, 'info')
 3271         self.mock_object(share_types, 'get_extra_specs_from_share',
 3272                          mock.Mock(return_value=extra_specs))
 3273         self.mock_object(self.library, '_get_vserver', mock.Mock(
 3274             return_value=(fake.VSERVER1, vserver_client)))
 3275         self.mock_object(self.library._client, 'qos_policy_group_exists',
 3276                          mock.Mock(return_value=True))
 3277         self.mock_object(self.library._client, 'qos_policy_group_modify',
 3278                          mock.Mock(side_effect=netapp_api.NaApiError))
 3279 
 3280         retval = self.library._handle_qos_on_replication_change(
 3281             self.mock_dm_session, self.fake_replica_2, self.fake_replica,
 3282             share_server=fake.SHARE_SERVER)
 3283 
 3284         self.assertIsNone(retval)
 3285         (self.mock_dm_session.remove_qos_on_old_active_replica
 3286          .assert_called_once_with(self.fake_replica))
 3287         lib_base.LOG.exception.assert_called_once()
 3288         lib_base.LOG.info.assert_not_called()
 3289         vserver_client.set_qos_policy_group_for_volume.assert_not_called()
 3290 
 3291     def test_handle_qos_on_replication_change_modify_existing_policy(self):
 3292         self.library._have_cluster_creds = True
 3293         extra_specs = {'qos': True, fake.QOS_EXTRA_SPEC: '3000'}
 3294         vserver_client = mock.Mock()
 3295         volume_name_on_backend = self.library._get_backend_share_name(
 3296             self.fake_replica_2['id'])
 3297         self.mock_object(lib_base.LOG, 'exception')
 3298         self.mock_object(lib_base.LOG, 'info')
 3299         self.mock_object(share_types, 'get_extra_specs_from_share',
 3300                          mock.Mock(return_value=extra_specs))
 3301         self.mock_object(self.library, '_get_vserver', mock.Mock(
 3302             return_value=(fake.VSERVER1, vserver_client)))
 3303         self.mock_object(self.library._client, 'qos_policy_group_exists',
 3304                          mock.Mock(return_value=True))
 3305         self.mock_object(self.library._client, 'qos_policy_group_modify')
 3306         self.mock_object(self.library, '_create_qos_policy_group')
 3307 
 3308         retval = self.library._handle_qos_on_replication_change(
 3309             self.mock_dm_session, self.fake_replica_2, self.fake_replica,
 3310             share_server=fake.SHARE_SERVER)
 3311 
 3312         self.assertIsNone(retval)
 3313         self.library._client.qos_policy_group_modify.assert_called_once_with(
 3314             'qos_' + volume_name_on_backend, '3000iops')
 3315         vserver_client.set_qos_policy_group_for_volume.assert_called_once_with(
 3316             volume_name_on_backend, 'qos_' + volume_name_on_backend)
 3317         self.library._create_qos_policy_group.assert_not_called()
 3318         lib_base.LOG.exception.assert_not_called()
 3319         lib_base.LOG.info.assert_called_once()
 3320 
 3321     def test_handle_qos_on_replication_change_create_new_policy(self):
 3322         self.library._have_cluster_creds = True
 3323         extra_specs = {'qos': True, fake.QOS_EXTRA_SPEC: '3000'}
 3324         vserver_client = mock.Mock()
 3325         self.mock_object(lib_base.LOG, 'exception')
 3326         self.mock_object(lib_base.LOG, 'info')
 3327         self.mock_object(share_types, 'get_extra_specs_from_share',
 3328                          mock.Mock(return_value=extra_specs))
 3329         self.mock_object(self.library, '_get_vserver', mock.Mock(
 3330             return_value=(fake.VSERVER1, vserver_client)))
 3331         self.mock_object(self.library._client, 'qos_policy_group_exists',
 3332                          mock.Mock(return_value=False))
 3333         self.mock_object(self.library._client, 'qos_policy_group_modify')
 3334         self.mock_object(self.library, '_create_qos_policy_group')
 3335 
 3336         retval = self.library._handle_qos_on_replication_change(
 3337             self.mock_dm_session, self.fake_replica_2, self.fake_replica,
 3338             share_server=fake.SHARE_SERVER)
 3339 
 3340         self.assertIsNone(retval)
 3341         self.library._create_qos_policy_group.assert_called_once_with(
 3342             self.fake_replica_2, fake.VSERVER1, {'maxiops': '3000'})
 3343         self.library._client.qos_policy_group_modify.assert_not_called()
 3344         lib_base.LOG.exception.assert_not_called()
 3345         lib_base.LOG.info.assert_called_once()
 3346 
 3347     def test_convert_destination_replica_to_independent(self):
 3348         self.mock_object(self.library,
 3349                          '_get_vserver',
 3350                          mock.Mock(return_value=(fake.VSERVER1,
 3351                                                  mock.Mock())))
 3352         self.mock_object(self.library,
 3353                          '_get_helper',
 3354                          mock.Mock(return_value=mock.Mock()))
 3355         self.mock_object(self.library, '_create_export',
 3356                          mock.Mock(return_value='fake_export_location'))
 3357 
 3358         replica = self.library._convert_destination_replica_to_independent(
 3359             None, self.mock_dm_session, self.fake_replica,
 3360             self.fake_replica_2, [], share_server=None)
 3361 
 3362         self.mock_dm_session.update_snapmirror.assert_called_once_with(
 3363             self.fake_replica, self.fake_replica_2)
 3364         self.mock_dm_session.break_snapmirror.assert_called_once_with(
 3365             self.fake_replica, self.fake_replica_2)
 3366 
 3367         self.assertEqual('fake_export_location',
 3368                          replica['export_locations'])
 3369         self.assertEqual(constants.REPLICA_STATE_ACTIVE,
 3370                          replica['replica_state'])
 3371 
 3372     def test_convert_destination_replica_to_independent_update_failed(self):
 3373         self.mock_object(self.library,
 3374                          '_get_vserver',
 3375                          mock.Mock(return_value=(fake.VSERVER1,
 3376                                                  mock.Mock())))
 3377         self.mock_object(self.library,
 3378                          '_get_helper',
 3379                          mock.Mock(return_value=mock.Mock()))
 3380         self.mock_object(self.library, '_create_export',
 3381                          mock.Mock(return_value='fake_export_location'))
 3382         self.mock_object(
 3383             self.mock_dm_session, 'update_snapmirror',
 3384             mock.Mock(side_effect=exception.StorageCommunicationException))
 3385 
 3386         replica = self.library._convert_destination_replica_to_independent(
 3387             None, self.mock_dm_session, self.fake_replica,
 3388             self.fake_replica_2, [], share_server=None)
 3389 
 3390         self.mock_dm_session.update_snapmirror.assert_called_once_with(
 3391             self.fake_replica, self.fake_replica_2)
 3392         self.mock_dm_session.break_snapmirror.assert_called_once_with(
 3393             self.fake_replica, self.fake_replica_2)
 3394 
 3395         self.assertEqual('fake_export_location',
 3396                          replica['export_locations'])
 3397         self.assertEqual(constants.REPLICA_STATE_ACTIVE,
 3398                          replica['replica_state'])
 3399 
 3400     def test_promote_replica_fail_to_set_access_rules(self):
 3401         fake_helper = mock.Mock()
 3402         fake_helper.update_access.side_effect = Exception
 3403         fake_access_rules = [
 3404             {'access_to': "0.0.0.0",
 3405              'access_level': constants.ACCESS_LEVEL_RO},
 3406             {'access_to': "10.10.10.10",
 3407              'access_level': constants.ACCESS_LEVEL_RW},
 3408         ]
 3409         self.mock_object(self.library,
 3410                          '_get_vserver',
 3411                          mock.Mock(return_value=(fake.VSERVER1,
 3412                                                  mock.Mock())))
 3413         self.mock_object(self.library, '_handle_qos_on_replication_change')
 3414         self.mock_object(self.library,
 3415                          '_get_helper',
 3416                          mock.Mock(return_value=fake_helper))
 3417         self.mock_object(self.library, '_create_export',
 3418                          mock.Mock(return_value='fake_export_location'))
 3419 
 3420         replicas = self.library.promote_replica(
 3421             None, [self.fake_replica, self.fake_replica_2],
 3422             self.fake_replica_2, fake_access_rules, share_server=None)
 3423 
 3424         self.mock_dm_session.change_snapmirror_source.assert_called_once_with(
 3425             self.fake_replica, self.fake_replica, self.fake_replica_2,
 3426             mock.ANY
 3427         )
 3428 
 3429         self.assertEqual(2, len(replicas))
 3430         actual_replica_1 = list(filter(
 3431             lambda x: x['id'] == self.fake_replica['id'], replicas))[0]
 3432         self.assertEqual(constants.REPLICA_STATE_OUT_OF_SYNC,
 3433                          actual_replica_1['replica_state'])
 3434         actual_replica_2 = list(filter(
 3435             lambda x: x['id'] == self.fake_replica_2['id'], replicas))[0]
 3436         self.assertEqual(constants.REPLICA_STATE_ACTIVE,
 3437                          actual_replica_2['replica_state'])
 3438         self.assertEqual('fake_export_location',
 3439                          actual_replica_2['export_locations'])
 3440         self.assertEqual(constants.SHARE_INSTANCE_RULES_SYNCING,
 3441                          actual_replica_2['access_rules_status'])
 3442         self.library._handle_qos_on_replication_change.assert_called_once()
 3443 
 3444     def test_convert_destination_replica_to_independent_with_access_rules(
 3445             self):
 3446         fake_helper = mock.Mock()
 3447         fake_helper.update_access.side_effect = Exception
 3448         fake_access_rules = [
 3449             {'access_to': "0.0.0.0",
 3450              'access_level': constants.ACCESS_LEVEL_RO},
 3451             {'access_to': "10.10.10.10",
 3452              'access_level': constants.ACCESS_LEVEL_RW},
 3453         ]
 3454         self.mock_object(self.library,
 3455                          '_get_vserver',
 3456                          mock.Mock(return_value=(fake.VSERVER1,
 3457                                                  mock.Mock())))
 3458         self.mock_object(self.library,
 3459                          '_get_helper',
 3460                          mock.Mock(return_value=fake_helper))
 3461         self.mock_object(self.library, '_create_export',
 3462                          mock.Mock(return_value='fake_export_location'))
 3463 
 3464         replica = self.library._convert_destination_replica_to_independent(
 3465             None, self.mock_dm_session, self.fake_replica,
 3466             self.fake_replica_2, fake_access_rules, share_server=None)
 3467 
 3468         self.mock_dm_session.update_snapmirror.assert_called_once_with(
 3469             self.fake_replica, self.fake_replica_2)
 3470         self.mock_dm_session.break_snapmirror.assert_called_once_with(
 3471             self.fake_replica, self.fake_replica_2)
 3472 
 3473         self.assertEqual('fake_export_location',
 3474                          replica['export_locations'])
 3475         self.assertEqual(constants.REPLICA_STATE_ACTIVE,
 3476                          replica['replica_state'])
 3477         self.assertEqual(constants.SHARE_INSTANCE_RULES_SYNCING,
 3478                          replica['access_rules_status'])
 3479 
 3480     def test_convert_destination_replica_to_independent_failed_access_rules(
 3481             self):
 3482         fake_helper = mock.Mock()
 3483         fake_access_rules = [
 3484             {'access_to': "0.0.0.0",
 3485              'access_level': constants.ACCESS_LEVEL_RO},
 3486             {'access_to': "10.10.10.10",
 3487              'access_level': constants.ACCESS_LEVEL_RW},
 3488         ]
 3489         self.mock_object(self.library,
 3490                          '_get_vserver',
 3491                          mock.Mock(return_value=(fake.VSERVER1,
 3492                                                  mock.Mock())))
 3493         self.mock_object(self.library,
 3494                          '_get_helper',
 3495                          mock.Mock(return_value=fake_helper))
 3496         self.mock_object(self.library, '_create_export',
 3497                          mock.Mock(return_value='fake_export_location'))
 3498 
 3499         replica = self.library._convert_destination_replica_to_independent(
 3500             None, self.mock_dm_session, self.fake_replica,
 3501             self.fake_replica_2, fake_access_rules, share_server=None)
 3502 
 3503         self.mock_dm_session.update_snapmirror.assert_called_once_with(
 3504             self.fake_replica, self.fake_replica_2)
 3505         self.mock_dm_session.break_snapmirror.assert_called_once_with(
 3506             self.fake_replica, self.fake_replica_2)
 3507 
 3508         fake_helper.assert_has_calls([
 3509             mock.call.set_client(mock.ANY),
 3510             mock.call.update_access(mock.ANY, mock.ANY, fake_access_rules),
 3511         ])
 3512 
 3513         self.assertEqual('fake_export_location',
 3514                          replica['export_locations'])
 3515         self.assertEqual(constants.REPLICA_STATE_ACTIVE,
 3516                          replica['replica_state'])
 3517         self.assertEqual(constants.STATUS_ACTIVE,
 3518                          replica['access_rules_status'])
 3519 
 3520     def test_safe_change_replica_source(self):
 3521         fake_replica_3 = copy.deepcopy(self.fake_replica_2)
 3522         fake_replica_3['id'] = fake.SHARE_ID3
 3523         fake_replica_3['replica_state'] = constants.REPLICA_STATE_OUT_OF_SYNC
 3524         replica = self.library._safe_change_replica_source(
 3525             self.mock_dm_session, self.fake_replica, self.fake_replica_2,
 3526             fake_replica_3, [self.fake_replica, self.fake_replica_2,
 3527                              fake_replica_3]
 3528         )
 3529         self.assertEqual([], replica['export_locations'])
 3530         self.assertEqual(constants.REPLICA_STATE_OUT_OF_SYNC,
 3531                          replica['replica_state'])
 3532 
 3533     def test_safe_change_replica_source_destination_unreachable(self):
 3534         self.mock_dm_session.change_snapmirror_source.side_effect = (
 3535             exception.StorageCommunicationException
 3536         )
 3537 
 3538         fake_replica_3 = copy.deepcopy(self.fake_replica_2)
 3539         fake_replica_3['id'] = fake.SHARE_ID3
 3540         fake_replica_3['replica_state'] = constants.REPLICA_STATE_OUT_OF_SYNC
 3541         replica = self.library._safe_change_replica_source(
 3542             self.mock_dm_session, self.fake_replica, self.fake_replica_2,
 3543             fake_replica_3, [self.fake_replica, self.fake_replica_2,
 3544                              fake_replica_3]
 3545         )
 3546         self.assertEqual([], replica['export_locations'])
 3547         self.assertEqual(constants.STATUS_ERROR,
 3548                          replica['replica_state'])
 3549         self.assertEqual(constants.STATUS_ERROR,
 3550                          replica['status'])
 3551 
 3552     def test_safe_change_replica_source_error(self):
 3553         self.mock_dm_session.change_snapmirror_source.side_effect = (
 3554             netapp_api.NaApiError(code=0)
 3555         )
 3556 
 3557         fake_replica_3 = copy.deepcopy(self.fake_replica_2)
 3558         fake_replica_3['id'] = fake.SHARE_ID3
 3559         fake_replica_3['replica_state'] = constants.REPLICA_STATE_OUT_OF_SYNC
 3560         replica = self.library._safe_change_replica_source(
 3561             self.mock_dm_session, self.fake_replica, self.fake_replica_2,
 3562             fake_replica_3, [self.fake_replica, self.fake_replica_2,
 3563                              fake_replica_3]
 3564         )
 3565         self.assertEqual([], replica['export_locations'])
 3566         self.assertEqual(constants.STATUS_ERROR,
 3567                          replica['replica_state'])
 3568 
 3569     def test_create_replicated_snapshot(self):
 3570         fake_replica_3 = copy.deepcopy(self.fake_replica_2)
 3571         fake_replica_3['id'] = fake.SHARE_ID3
 3572         replica_list = [self.fake_replica, self.fake_replica_2, fake_replica_3]
 3573         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 3574         fake_snapshot['share_id'] = self.fake_replica['id']
 3575         fake_snapshot_2 = copy.deepcopy(fake.SNAPSHOT)
 3576         fake_snapshot_2['id'] = uuidutils.generate_uuid()
 3577         fake_snapshot_2['share_id'] = self.fake_replica_2['id']
 3578         fake_snapshot_3 = copy.deepcopy(fake.SNAPSHOT)
 3579         fake_snapshot_3['id'] = uuidutils.generate_uuid()
 3580         fake_snapshot_3['share_id'] = fake_replica_3['id']
 3581         snapshot_list = [fake_snapshot, fake_snapshot_2, fake_snapshot_3]
 3582 
 3583         vserver_client = mock.Mock()
 3584         self.mock_object(self.library,
 3585                          '_get_vserver',
 3586                          mock.Mock(return_value=(fake.VSERVER1,
 3587                                                  vserver_client)))
 3588 
 3589         model_list = self.library.create_replicated_snapshot(
 3590             self.context, replica_list, snapshot_list,
 3591             share_server=fake.SHARE_SERVER)
 3592 
 3593         share_name = self.library._get_backend_share_name(
 3594             fake_snapshot['share_id'])
 3595         snapshot_name = self.library._get_backend_snapshot_name(
 3596             fake_snapshot['id'])
 3597         vserver_client.create_snapshot.assert_called_once_with(share_name,
 3598                                                                snapshot_name)
 3599         self.assertEqual(3, len(model_list))
 3600         for snapshot in model_list:
 3601             self.assertEqual(snapshot['provider_location'], snapshot_name)
 3602         actual_active_snapshot = list(filter(
 3603             lambda x: x['id'] == fake_snapshot['id'], model_list))[0]
 3604         self.assertEqual(constants.STATUS_AVAILABLE,
 3605                          actual_active_snapshot['status'])
 3606         actual_non_active_snapshot_list = list(filter(
 3607             lambda x: x['id'] != fake_snapshot['id'], model_list))
 3608         for snapshot in actual_non_active_snapshot_list:
 3609             self.assertEqual(constants.STATUS_CREATING, snapshot['status'])
 3610         self.mock_dm_session.update_snapmirror.assert_has_calls(
 3611             [mock.call(self.fake_replica, self.fake_replica_2),
 3612              mock.call(self.fake_replica, fake_replica_3)],
 3613             any_order=True
 3614         )
 3615 
 3616     def test_create_replicated_snapshot_with_creating_replica(self):
 3617         fake_replica_3 = copy.deepcopy(self.fake_replica_2)
 3618         fake_replica_3['id'] = fake.SHARE_ID3
 3619         fake_replica_3['host'] = None
 3620         replica_list = [self.fake_replica, self.fake_replica_2, fake_replica_3]
 3621         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 3622         fake_snapshot['share_id'] = self.fake_replica['id']
 3623         fake_snapshot_2 = copy.deepcopy(fake.SNAPSHOT)
 3624         fake_snapshot_2['id'] = uuidutils.generate_uuid()
 3625         fake_snapshot_2['share_id'] = self.fake_replica_2['id']
 3626         fake_snapshot_3 = copy.deepcopy(fake.SNAPSHOT)
 3627         fake_snapshot_3['id'] = uuidutils.generate_uuid()
 3628         fake_snapshot_3['share_id'] = fake_replica_3['id']
 3629         snapshot_list = [fake_snapshot, fake_snapshot_2, fake_snapshot_3]
 3630 
 3631         vserver_client = mock.Mock()
 3632         self.mock_object(self.library,
 3633                          '_get_vserver',
 3634                          mock.Mock(return_value=(fake.VSERVER1,
 3635                                                  vserver_client)))
 3636 
 3637         model_list = self.library.create_replicated_snapshot(
 3638             self.context, replica_list, snapshot_list,
 3639             share_server=fake.SHARE_SERVER)
 3640 
 3641         share_name = self.library._get_backend_share_name(
 3642             fake_snapshot['share_id'])
 3643         snapshot_name = self.library._get_backend_snapshot_name(
 3644             fake_snapshot['id'])
 3645         vserver_client.create_snapshot.assert_called_once_with(share_name,
 3646                                                                snapshot_name)
 3647         self.assertEqual(3, len(model_list))
 3648         for snapshot in model_list:
 3649             self.assertEqual(snapshot['provider_location'], snapshot_name)
 3650         actual_active_snapshot = list(filter(
 3651             lambda x: x['id'] == fake_snapshot['id'], model_list))[0]
 3652         self.assertEqual(constants.STATUS_AVAILABLE,
 3653                          actual_active_snapshot['status'])
 3654         actual_non_active_snapshot_list = list(filter(
 3655             lambda x: x['id'] != fake_snapshot['id'], model_list))
 3656         for snapshot in actual_non_active_snapshot_list:
 3657             self.assertEqual(constants.STATUS_CREATING, snapshot['status'])
 3658         self.mock_dm_session.update_snapmirror.assert_has_calls(
 3659             [mock.call(self.fake_replica, self.fake_replica_2)],
 3660             any_order=True
 3661         )
 3662 
 3663     def test_create_replicated_snapshot_no_snapmirror(self):
 3664         self.mock_dm_session.update_snapmirror.side_effect = [
 3665             None,
 3666             netapp_api.NaApiError(code=netapp_api.EOBJECTNOTFOUND)
 3667         ]
 3668         fake_replica_3 = copy.deepcopy(self.fake_replica_2)
 3669         fake_replica_3['id'] = fake.SHARE_ID3
 3670         replica_list = [self.fake_replica, self.fake_replica_2, fake_replica_3]
 3671         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 3672         fake_snapshot['share_id'] = self.fake_replica['id']
 3673         fake_snapshot_2 = copy.deepcopy(fake.SNAPSHOT)
 3674         fake_snapshot_2['id'] = uuidutils.generate_uuid()
 3675         fake_snapshot_2['share_id'] = self.fake_replica_2['id']
 3676         fake_snapshot_3 = copy.deepcopy(fake.SNAPSHOT)
 3677         fake_snapshot_3['id'] = uuidutils.generate_uuid()
 3678         fake_snapshot_3['share_id'] = fake_replica_3['id']
 3679         snapshot_list = [fake_snapshot, fake_snapshot_2, fake_snapshot_3]
 3680 
 3681         vserver_client = mock.Mock()
 3682         self.mock_object(self.library,
 3683                          '_get_vserver',
 3684                          mock.Mock(return_value=(fake.VSERVER1,
 3685                                                  vserver_client)))
 3686 
 3687         model_list = self.library.create_replicated_snapshot(
 3688             self.context, replica_list, snapshot_list,
 3689             share_server=fake.SHARE_SERVER)
 3690 
 3691         share_name = self.library._get_backend_share_name(
 3692             fake_snapshot['share_id'])
 3693         snapshot_name = self.library._get_backend_snapshot_name(
 3694             fake_snapshot['id'])
 3695         vserver_client.create_snapshot.assert_called_once_with(share_name,
 3696                                                                snapshot_name)
 3697         self.assertEqual(3, len(model_list))
 3698         for snapshot in model_list:
 3699             self.assertEqual(snapshot['provider_location'], snapshot_name)
 3700         actual_active_snapshot = list(filter(
 3701             lambda x: x['id'] == fake_snapshot['id'], model_list))[0]
 3702         self.assertEqual(constants.STATUS_AVAILABLE,
 3703                          actual_active_snapshot['status'])
 3704         actual_non_active_snapshot_list = list(filter(
 3705             lambda x: x['id'] != fake_snapshot['id'], model_list))
 3706         for snapshot in actual_non_active_snapshot_list:
 3707             self.assertEqual(constants.STATUS_CREATING, snapshot['status'])
 3708         self.mock_dm_session.update_snapmirror.assert_has_calls(
 3709             [mock.call(self.fake_replica, self.fake_replica_2),
 3710              mock.call(self.fake_replica, fake_replica_3)],
 3711             any_order=True
 3712         )
 3713 
 3714     def test_create_replicated_snapshot_update_error(self):
 3715         self.mock_dm_session.update_snapmirror.side_effect = [
 3716             None,
 3717             netapp_api.NaApiError()
 3718         ]
 3719         fake_replica_3 = copy.deepcopy(self.fake_replica_2)
 3720         fake_replica_3['id'] = fake.SHARE_ID3
 3721         replica_list = [self.fake_replica, self.fake_replica_2, fake_replica_3]
 3722         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 3723         fake_snapshot['share_id'] = self.fake_replica['id']
 3724         fake_snapshot_2 = copy.deepcopy(fake.SNAPSHOT)
 3725         fake_snapshot_2['id'] = uuidutils.generate_uuid()
 3726         fake_snapshot_2['share_id'] = self.fake_replica_2['id']
 3727         fake_snapshot_3 = copy.deepcopy(fake.SNAPSHOT)
 3728         fake_snapshot_3['id'] = uuidutils.generate_uuid()
 3729         fake_snapshot_3['share_id'] = fake_replica_3['id']
 3730         snapshot_list = [fake_snapshot, fake_snapshot_2, fake_snapshot_3]
 3731 
 3732         vserver_client = mock.Mock()
 3733         self.mock_object(self.library,
 3734                          '_get_vserver',
 3735                          mock.Mock(return_value=(fake.VSERVER1,
 3736                                                  vserver_client)))
 3737 
 3738         self.assertRaises(netapp_api.NaApiError,
 3739                           self.library.create_replicated_snapshot,
 3740                           self.context, replica_list, snapshot_list,
 3741                           share_server=fake.SHARE_SERVER)
 3742 
 3743     def test_delete_replicated_snapshot(self):
 3744         fake_replica_3 = copy.deepcopy(self.fake_replica_2)
 3745         fake_replica_3['id'] = fake.SHARE_ID3
 3746         replica_list = [self.fake_replica, self.fake_replica_2, fake_replica_3]
 3747         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 3748         fake_snapshot['share_id'] = self.fake_replica['id']
 3749         share_name = self.library._get_backend_share_name(
 3750             fake_snapshot['share_id'])
 3751         snapshot_name = self.library._get_backend_snapshot_name(
 3752             fake_snapshot['id'])
 3753         fake_snapshot['provider_location'] = snapshot_name
 3754         fake_snapshot_2 = copy.deepcopy(fake.SNAPSHOT)
 3755         fake_snapshot_2['id'] = uuidutils.generate_uuid()
 3756         fake_snapshot_2['share_id'] = self.fake_replica_2['id']
 3757         fake_snapshot_2['provider_location'] = snapshot_name
 3758         fake_snapshot_3 = copy.deepcopy(fake.SNAPSHOT)
 3759         fake_snapshot_3['id'] = uuidutils.generate_uuid()
 3760         fake_snapshot_3['share_id'] = fake_replica_3['id']
 3761         fake_snapshot_3['provider_location'] = snapshot_name
 3762 
 3763         snapshot_list = [fake_snapshot, fake_snapshot_2, fake_snapshot_3]
 3764 
 3765         vserver_client = mock.Mock()
 3766         vserver_client.get_snapshot.return_value = fake.CDOT_SNAPSHOT
 3767         self.mock_object(self.library,
 3768                          '_get_vserver',
 3769                          mock.Mock(return_value=(fake.VSERVER1,
 3770                                                  vserver_client)))
 3771 
 3772         self.library.delete_replicated_snapshot(
 3773             self.context, replica_list, snapshot_list,
 3774             share_server=fake.SHARE_SERVER)
 3775 
 3776         vserver_client.delete_snapshot.assert_called_once_with(share_name,
 3777                                                                snapshot_name)
 3778 
 3779         self.mock_dm_session.update_snapmirror.assert_has_calls(
 3780             [mock.call(self.fake_replica, self.fake_replica_2),
 3781              mock.call(self.fake_replica, fake_replica_3)],
 3782             any_order=True
 3783         )
 3784 
 3785     def test_delete_replicated_snapshot_replica_still_creating(self):
 3786         fake_replica_3 = copy.deepcopy(self.fake_replica_2)
 3787         fake_replica_3['id'] = fake.SHARE_ID3
 3788         fake_replica_3['host'] = None
 3789         replica_list = [self.fake_replica, self.fake_replica_2, fake_replica_3]
 3790         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 3791         fake_snapshot['share_id'] = self.fake_replica['id']
 3792         share_name = self.library._get_backend_share_name(
 3793             fake_snapshot['share_id'])
 3794         snapshot_name = self.library._get_backend_snapshot_name(
 3795             fake_snapshot['id'])
 3796         fake_snapshot['provider_location'] = snapshot_name
 3797         fake_snapshot_2 = copy.deepcopy(fake.SNAPSHOT)
 3798         fake_snapshot_2['id'] = uuidutils.generate_uuid()
 3799         fake_snapshot_2['share_id'] = self.fake_replica_2['id']
 3800         fake_snapshot_2['provider_location'] = snapshot_name
 3801         fake_snapshot_3 = copy.deepcopy(fake.SNAPSHOT)
 3802         fake_snapshot_3['id'] = uuidutils.generate_uuid()
 3803         fake_snapshot_3['share_id'] = fake_replica_3['id']
 3804         fake_snapshot_3['provider_location'] = snapshot_name
 3805 
 3806         snapshot_list = [fake_snapshot, fake_snapshot_2, fake_snapshot_3]
 3807 
 3808         vserver_client = mock.Mock()
 3809         vserver_client.get_snapshot.return_value = fake.CDOT_SNAPSHOT
 3810         self.mock_object(self.library,
 3811                          '_get_vserver',
 3812                          mock.Mock(return_value=(fake.VSERVER1,
 3813                                                  vserver_client)))
 3814 
 3815         self.library.delete_replicated_snapshot(
 3816             self.context, replica_list, snapshot_list,
 3817             share_server=fake.SHARE_SERVER)
 3818 
 3819         vserver_client.delete_snapshot.assert_called_once_with(share_name,
 3820                                                                snapshot_name)
 3821 
 3822         self.mock_dm_session.update_snapmirror.assert_has_calls(
 3823             [mock.call(self.fake_replica, self.fake_replica_2)],
 3824             any_order=True
 3825         )
 3826 
 3827     def test_delete_replicated_snapshot_missing_snapmirror(self):
 3828         self.mock_dm_session.update_snapmirror.side_effect = [
 3829             None,
 3830             netapp_api.NaApiError(code=netapp_api.EOBJECTNOTFOUND)
 3831         ]
 3832         fake_replica_3 = copy.deepcopy(self.fake_replica_2)
 3833         fake_replica_3['id'] = fake.SHARE_ID3
 3834         replica_list = [self.fake_replica, self.fake_replica_2, fake_replica_3]
 3835         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 3836         fake_snapshot['share_id'] = self.fake_replica['id']
 3837         share_name = self.library._get_backend_share_name(
 3838             fake_snapshot['share_id'])
 3839         snapshot_name = self.library._get_backend_snapshot_name(
 3840             fake_snapshot['id'])
 3841         fake_snapshot['provider_location'] = snapshot_name
 3842         fake_snapshot['busy'] = False
 3843 
 3844         fake_snapshot_2 = copy.deepcopy(fake.SNAPSHOT)
 3845         fake_snapshot_2['id'] = uuidutils.generate_uuid()
 3846         fake_snapshot_2['share_id'] = self.fake_replica_2['id']
 3847         fake_snapshot_2['provider_location'] = snapshot_name
 3848         fake_snapshot_3 = copy.deepcopy(fake.SNAPSHOT)
 3849         fake_snapshot_3['id'] = uuidutils.generate_uuid()
 3850         fake_snapshot_3['share_id'] = fake_replica_3['id']
 3851         fake_snapshot_3['provider_location'] = snapshot_name
 3852 
 3853         snapshot_list = [fake_snapshot, fake_snapshot_2, fake_snapshot_3]
 3854 
 3855         vserver_client = mock.Mock()
 3856         vserver_client.get_snapshot.return_value = fake_snapshot
 3857         self.mock_object(self.library,
 3858                          '_get_vserver',
 3859                          mock.Mock(return_value=(fake.VSERVER1,
 3860                                                  vserver_client)))
 3861 
 3862         self.library.delete_replicated_snapshot(
 3863             self.context, replica_list, snapshot_list,
 3864             share_server=fake.SHARE_SERVER)
 3865 
 3866         vserver_client.delete_snapshot.assert_called_once_with(share_name,
 3867                                                                snapshot_name)
 3868 
 3869         self.mock_dm_session.update_snapmirror.assert_has_calls(
 3870             [mock.call(self.fake_replica, self.fake_replica_2),
 3871              mock.call(self.fake_replica, fake_replica_3)],
 3872             any_order=True
 3873         )
 3874 
 3875     def test_delete_replicated_snapshot_update_error(self):
 3876         self.mock_dm_session.update_snapmirror.side_effect = [
 3877             None,
 3878             netapp_api.NaApiError()
 3879         ]
 3880         fake_replica_3 = copy.deepcopy(self.fake_replica_2)
 3881         fake_replica_3['id'] = fake.SHARE_ID3
 3882         replica_list = [self.fake_replica, self.fake_replica_2, fake_replica_3]
 3883         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 3884         fake_snapshot['share_id'] = self.fake_replica['id']
 3885         snapshot_name = self.library._get_backend_snapshot_name(
 3886             fake_snapshot['id'])
 3887         fake_snapshot['provider_location'] = snapshot_name
 3888         fake_snapshot['busy'] = False
 3889 
 3890         fake_snapshot_2 = copy.deepcopy(fake.SNAPSHOT)
 3891         fake_snapshot_2['id'] = uuidutils.generate_uuid()
 3892         fake_snapshot_2['share_id'] = self.fake_replica_2['id']
 3893         fake_snapshot_2['provider_location'] = snapshot_name
 3894         fake_snapshot_3 = copy.deepcopy(fake.SNAPSHOT)
 3895         fake_snapshot_3['id'] = uuidutils.generate_uuid()
 3896         fake_snapshot_3['share_id'] = fake_replica_3['id']
 3897         fake_snapshot_3['provider_location'] = snapshot_name
 3898 
 3899         snapshot_list = [fake_snapshot, fake_snapshot_2, fake_snapshot_3]
 3900 
 3901         vserver_client = mock.Mock()
 3902         vserver_client.get_snapshot.return_value = fake_snapshot
 3903         self.mock_object(self.library,
 3904                          '_get_vserver',
 3905                          mock.Mock(return_value=(fake.VSERVER1,
 3906                                                  vserver_client)))
 3907 
 3908         self.assertRaises(netapp_api.NaApiError,
 3909                           self.library.delete_replicated_snapshot,
 3910                           self.context, replica_list, snapshot_list,
 3911                           share_server=fake.SHARE_SERVER)
 3912 
 3913     def test_update_replicated_snapshot_still_creating(self):
 3914         vserver_client = mock.Mock()
 3915         vserver_client.snapshot_exists.return_value = False
 3916         self.mock_object(self.library,
 3917                          '_get_vserver',
 3918                          mock.Mock(return_value=(fake.VSERVER1,
 3919                                                  vserver_client)))
 3920         replica_list = [self.fake_replica, self.fake_replica_2]
 3921         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 3922         fake_snapshot['status'] = constants.STATUS_CREATING
 3923         fake_snapshot['share_id'] = self.fake_replica_2['id']
 3924         snapshot_name = self.library._get_backend_snapshot_name(
 3925             fake_snapshot['id'])
 3926         fake_snapshot['provider_location'] = snapshot_name
 3927 
 3928         model_update = self.library.update_replicated_snapshot(
 3929             replica_list, self.fake_replica_2, [fake_snapshot], fake_snapshot)
 3930 
 3931         self.assertIsNone(model_update)
 3932         self.mock_dm_session.update_snapmirror.assert_called_once_with(
 3933             self.fake_replica, self.fake_replica_2
 3934         )
 3935 
 3936     def test_update_replicated_snapshot_still_creating_no_host(self):
 3937         self.fake_replica_2['host'] = None
 3938         vserver_client = mock.Mock()
 3939         vserver_client.snapshot_exists.return_value = False
 3940         self.mock_object(self.library,
 3941                          '_get_vserver',
 3942                          mock.Mock(return_value=(fake.VSERVER1,
 3943                                                  vserver_client)))
 3944         replica_list = [self.fake_replica, self.fake_replica_2]
 3945         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 3946         fake_snapshot['status'] = constants.STATUS_CREATING
 3947         fake_snapshot['share_id'] = self.fake_replica_2['id']
 3948         snapshot_name = self.library._get_backend_snapshot_name(
 3949             fake_snapshot['id'])
 3950         fake_snapshot['provider_location'] = snapshot_name
 3951 
 3952         model_update = self.library.update_replicated_snapshot(
 3953             replica_list, self.fake_replica_2, [fake_snapshot], fake_snapshot)
 3954 
 3955         self.assertIsNone(model_update)
 3956         self.mock_dm_session.update_snapmirror.assert_called_once_with(
 3957             self.fake_replica, self.fake_replica_2
 3958         )
 3959 
 3960     def test_update_replicated_snapshot_no_snapmirror(self):
 3961         vserver_client = mock.Mock()
 3962         vserver_client.snapshot_exists.return_value = False
 3963         self.mock_dm_session.update_snapmirror.side_effect = (
 3964             netapp_api.NaApiError(code=netapp_api.EOBJECTNOTFOUND)
 3965         )
 3966         self.mock_object(self.library,
 3967                          '_get_vserver',
 3968                          mock.Mock(return_value=(fake.VSERVER1,
 3969                                                  vserver_client)))
 3970         replica_list = [self.fake_replica, self.fake_replica_2]
 3971         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 3972         fake_snapshot['status'] = constants.STATUS_CREATING
 3973         fake_snapshot['share_id'] = self.fake_replica_2['id']
 3974         snapshot_name = self.library._get_backend_snapshot_name(
 3975             fake_snapshot['id'])
 3976         fake_snapshot['provider_location'] = snapshot_name
 3977 
 3978         model_update = self.library.update_replicated_snapshot(
 3979             replica_list, self.fake_replica_2, [fake_snapshot], fake_snapshot)
 3980 
 3981         self.assertIsNone(model_update)
 3982         self.mock_dm_session.update_snapmirror.assert_called_once_with(
 3983             self.fake_replica, self.fake_replica_2
 3984         )
 3985 
 3986     def test_update_replicated_snapshot_update_error(self):
 3987         vserver_client = mock.Mock()
 3988         vserver_client.snapshot_exists.return_value = False
 3989         self.mock_dm_session.update_snapmirror.side_effect = (
 3990             netapp_api.NaApiError()
 3991         )
 3992         self.mock_object(self.library,
 3993                          '_get_vserver',
 3994                          mock.Mock(return_value=(fake.VSERVER1,
 3995                                                  vserver_client)))
 3996         replica_list = [self.fake_replica, self.fake_replica_2]
 3997         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 3998         fake_snapshot['status'] = constants.STATUS_CREATING
 3999         fake_snapshot['share_id'] = self.fake_replica_2['id']
 4000         snapshot_name = self.library._get_backend_snapshot_name(
 4001             fake_snapshot['id'])
 4002         fake_snapshot['provider_location'] = snapshot_name
 4003 
 4004         self.assertRaises(netapp_api.NaApiError,
 4005                           self.library.update_replicated_snapshot,
 4006                           replica_list, self.fake_replica_2,
 4007                           [fake_snapshot], fake_snapshot)
 4008 
 4009     def test_update_replicated_snapshot_still_deleting(self):
 4010         vserver_client = mock.Mock()
 4011         vserver_client.snapshot_exists.return_value = True
 4012         vserver_client.get_snapshot.return_value = fake.CDOT_SNAPSHOT
 4013         self.mock_object(self.library,
 4014                          '_get_vserver',
 4015                          mock.Mock(return_value=(fake.VSERVER1,
 4016                                                  vserver_client)))
 4017 
 4018         replica_list = [self.fake_replica]
 4019         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 4020         fake_snapshot['status'] = constants.STATUS_DELETING
 4021         fake_snapshot['share_id'] = self.fake_replica['id']
 4022         snapshot_name = self.library._get_backend_snapshot_name(
 4023             fake_snapshot['id'])
 4024         fake_snapshot['provider_location'] = snapshot_name
 4025 
 4026         model_update = self.library.update_replicated_snapshot(
 4027             replica_list, self.fake_replica, [fake_snapshot], fake_snapshot)
 4028 
 4029         self.assertIsNone(model_update)
 4030 
 4031     def test_update_replicated_snapshot_created(self):
 4032         vserver_client = mock.Mock()
 4033         vserver_client.snapshot_exists.return_value = True
 4034         self.mock_object(self.library,
 4035                          '_get_vserver',
 4036                          mock.Mock(return_value=(fake.VSERVER1,
 4037                                                  vserver_client)))
 4038         replica_list = [self.fake_replica]
 4039         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 4040         fake_snapshot['status'] = constants.STATUS_CREATING
 4041         fake_snapshot['share_id'] = self.fake_replica['id']
 4042         snapshot_name = self.library._get_backend_snapshot_name(
 4043             fake_snapshot['id'])
 4044         fake_snapshot['provider_location'] = snapshot_name
 4045 
 4046         model_update = self.library.update_replicated_snapshot(
 4047             replica_list, self.fake_replica, [fake_snapshot], fake_snapshot)
 4048 
 4049         self.assertEqual(constants.STATUS_AVAILABLE, model_update['status'])
 4050         self.assertEqual(snapshot_name, model_update['provider_location'])
 4051 
 4052     def test_update_replicated_snapshot_created_no_provider_location(self):
 4053         vserver_client = mock.Mock()
 4054         vserver_client.snapshot_exists.return_value = True
 4055         self.mock_object(self.library,
 4056                          '_get_vserver',
 4057                          mock.Mock(return_value=(fake.VSERVER1,
 4058                                                  vserver_client)))
 4059         replica_list = [self.fake_replica, self.fake_replica_2]
 4060         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 4061         fake_snapshot['status'] = constants.STATUS_ACTIVE
 4062         fake_snapshot['share_id'] = self.fake_replica['id']
 4063         snapshot_name = self.library._get_backend_snapshot_name(
 4064             fake_snapshot['id'])
 4065         fake_snapshot['provider_location'] = snapshot_name
 4066         fake_snapshot_2 = copy.deepcopy(fake.SNAPSHOT)
 4067         fake_snapshot_2['status'] = constants.STATUS_CREATING
 4068         fake_snapshot_2['share_id'] = self.fake_replica_2['id']
 4069 
 4070         model_update = self.library.update_replicated_snapshot(
 4071             replica_list, self.fake_replica_2,
 4072             [fake_snapshot, fake_snapshot_2], fake_snapshot_2)
 4073 
 4074         self.assertEqual(constants.STATUS_AVAILABLE, model_update['status'])
 4075         self.assertEqual(snapshot_name, model_update['provider_location'])
 4076 
 4077     def test_update_replicated_snapshot_deleted(self):
 4078         vserver_client = mock.Mock()
 4079         vserver_client.snapshot_exists.return_value = False
 4080         self.mock_object(self.library,
 4081                          '_get_vserver',
 4082                          mock.Mock(return_value=(fake.VSERVER1,
 4083                                                  vserver_client)))
 4084         replica_list = [self.fake_replica]
 4085         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 4086         fake_snapshot['status'] = constants.STATUS_DELETING
 4087         fake_snapshot['share_id'] = self.fake_replica['id']
 4088         snapshot_name = self.library._get_backend_snapshot_name(
 4089             fake_snapshot['id'])
 4090         fake_snapshot['provider_location'] = snapshot_name
 4091 
 4092         self.assertRaises(exception.SnapshotResourceNotFound,
 4093                           self.library.update_replicated_snapshot,
 4094                           replica_list, self.fake_replica, [fake_snapshot],
 4095                           fake_snapshot)
 4096 
 4097     def test_update_replicated_snapshot_no_provider_locations(self):
 4098         vserver_client = mock.Mock()
 4099         vserver_client.snapshot_exists.return_value = True
 4100         self.mock_object(self.library,
 4101                          '_get_vserver',
 4102                          mock.Mock(return_value=(fake.VSERVER1,
 4103                                                  vserver_client)))
 4104         replica_list = [self.fake_replica]
 4105         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 4106         fake_snapshot['status'] = constants.STATUS_CREATING
 4107         fake_snapshot['share_id'] = self.fake_replica['id']
 4108         fake_snapshot['provider_location'] = None
 4109 
 4110         model_update = self.library.update_replicated_snapshot(
 4111             replica_list, self.fake_replica, [fake_snapshot], fake_snapshot)
 4112 
 4113         self.assertIsNone(model_update)
 4114 
 4115     def _get_fake_replicas_and_snapshots(self):
 4116 
 4117         fake_replica_3 = copy.deepcopy(self.fake_replica_2)
 4118         fake_replica_3['id'] = fake.SHARE_ID3
 4119         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 4120         fake_snapshot['share_id'] = self.fake_replica['id']
 4121         snapshot_name = self.library._get_backend_snapshot_name(
 4122             fake_snapshot['id'])
 4123         fake_snapshot['provider_location'] = snapshot_name
 4124         fake_snapshot_2 = copy.deepcopy(fake.SNAPSHOT)
 4125         fake_snapshot_2['id'] = uuidutils.generate_uuid()
 4126         fake_snapshot_2['share_id'] = self.fake_replica_2['id']
 4127         fake_snapshot_2['provider_location'] = snapshot_name
 4128         fake_snapshot_3 = copy.deepcopy(fake.SNAPSHOT)
 4129         fake_snapshot_3['id'] = uuidutils.generate_uuid()
 4130         fake_snapshot_3['share_id'] = fake_replica_3['id']
 4131         fake_snapshot_3['provider_location'] = snapshot_name
 4132         replica_list = [self.fake_replica, self.fake_replica_2, fake_replica_3]
 4133         snapshot_list = [fake_snapshot, fake_snapshot_2, fake_snapshot_3]
 4134         return replica_list, snapshot_list
 4135 
 4136     @ddt.data(True, False)
 4137     def test_revert_to_replicated_snapshot(self, use_snap_provider_location):
 4138 
 4139         replica_list, snapshot_list = self._get_fake_replicas_and_snapshots()
 4140         fake_replica, fake_replica_2, fake_replica_3 = replica_list
 4141         fake_snapshot, fake_snapshot_2, fake_snapshot_3 = snapshot_list
 4142 
 4143         if not use_snap_provider_location:
 4144             del fake_snapshot['provider_location']
 4145             del fake_snapshot_2['provider_location']
 4146             del fake_snapshot_3['provider_location']
 4147 
 4148         share_name = self.library._get_backend_share_name(
 4149             fake_snapshot['share_id'])
 4150         snapshot_name = self.library._get_backend_snapshot_name(
 4151             fake_snapshot['id'])
 4152 
 4153         vserver_client = mock.Mock()
 4154         vserver_client.get_snapshot.return_value = fake.CDOT_SNAPSHOT
 4155         vserver_client.list_snapmirror_snapshots.return_value = ['sm_snap']
 4156         self.mock_object(self.library,
 4157                          '_get_vserver',
 4158                          mock.Mock(return_value=(fake.VSERVER1,
 4159                                                  vserver_client)))
 4160 
 4161         self.library.revert_to_replicated_snapshot(
 4162             self.context, self.fake_replica, replica_list, fake_snapshot,
 4163             snapshot_list, share_server=fake.SHARE_SERVER)
 4164 
 4165         vserver_client.get_snapshot.assert_called_once_with(
 4166             share_name, snapshot_name)
 4167         vserver_client.list_snapmirror_snapshots.assert_called_once_with(
 4168             share_name)
 4169         vserver_client.delete_snapshot.assert_called_once_with(
 4170             share_name, 'sm_snap', ignore_owners=True)
 4171         vserver_client.restore_snapshot.assert_called_once_with(
 4172             share_name, snapshot_name)
 4173 
 4174         self.mock_dm_session.break_snapmirror.assert_has_calls(
 4175             [mock.call(self.fake_replica, self.fake_replica_2, mount=False),
 4176              mock.call(self.fake_replica, fake_replica_3, mount=False)],
 4177             any_order=True)
 4178         self.mock_dm_session.resync_snapmirror.assert_has_calls(
 4179             [mock.call(self.fake_replica, self.fake_replica_2),
 4180              mock.call(self.fake_replica, fake_replica_3)],
 4181             any_order=True)
 4182 
 4183     def test_revert_to_replicated_snapshot_not_found(self):
 4184 
 4185         replica_list, snapshot_list = self._get_fake_replicas_and_snapshots()
 4186         fake_snapshot, fake_snapshot_2, fake_snapshot_3 = snapshot_list
 4187         share_name = self.library._get_backend_share_name(
 4188             fake_snapshot['share_id'])
 4189         snapshot_name = self.library._get_backend_snapshot_name(
 4190             fake_snapshot['id'])
 4191 
 4192         vserver_client = mock.Mock()
 4193         vserver_client.get_snapshot.side_effect = netapp_api.NaApiError
 4194         vserver_client.list_snapmirror_snapshots.return_value = ['sm_snap']
 4195         self.mock_object(self.library,
 4196                          '_get_vserver',
 4197                          mock.Mock(return_value=(fake.VSERVER1,
 4198                                                  vserver_client)))
 4199 
 4200         self.assertRaises(
 4201             netapp_api.NaApiError, self.library.revert_to_replicated_snapshot,
 4202             self.context, self.fake_replica, replica_list, fake_snapshot,
 4203             snapshot_list, share_server=fake.SHARE_SERVER)
 4204 
 4205         vserver_client.get_snapshot.assert_called_once_with(
 4206             share_name, snapshot_name)
 4207         self.assertFalse(vserver_client.list_snapmirror_snapshots.called)
 4208         self.assertFalse(vserver_client.delete_snapshot.called)
 4209         self.assertFalse(vserver_client.restore_snapshot.called)
 4210         self.assertFalse(self.mock_dm_session.break_snapmirror.called)
 4211         self.assertFalse(self.mock_dm_session.resync_snapmirror.called)
 4212 
 4213     def test_revert_to_replicated_snapshot_snapmirror_break_error(self):
 4214 
 4215         replica_list, snapshot_list = self._get_fake_replicas_and_snapshots()
 4216         fake_snapshot, fake_snapshot_2, fake_snapshot_3 = snapshot_list
 4217 
 4218         vserver_client = mock.Mock()
 4219         vserver_client.get_snapshot.return_value = fake.CDOT_SNAPSHOT
 4220         vserver_client.list_snapmirror_snapshots.return_value = ['sm_snap']
 4221         self.mock_object(self.library,
 4222                          '_get_vserver',
 4223                          mock.Mock(return_value=(fake.VSERVER1,
 4224                                                  vserver_client)))
 4225         self.mock_dm_session.break_snapmirror.side_effect = (
 4226             netapp_api.NaApiError)
 4227 
 4228         self.assertRaises(
 4229             netapp_api.NaApiError, self.library.revert_to_replicated_snapshot,
 4230             self.context, self.fake_replica, replica_list, fake_snapshot,
 4231             snapshot_list, share_server=fake.SHARE_SERVER)
 4232 
 4233     def test_revert_to_replicated_snapshot_snapmirror_break_not_found(self):
 4234 
 4235         replica_list, snapshot_list = self._get_fake_replicas_and_snapshots()
 4236         fake_replica, fake_replica_2, fake_replica_3 = replica_list
 4237         fake_snapshot, fake_snapshot_2, fake_snapshot_3 = snapshot_list
 4238         share_name = self.library._get_backend_share_name(
 4239             fake_snapshot['share_id'])
 4240         snapshot_name = self.library._get_backend_snapshot_name(
 4241             fake_snapshot['id'])
 4242 
 4243         vserver_client = mock.Mock()
 4244         vserver_client.get_snapshot.return_value = fake.CDOT_SNAPSHOT
 4245         vserver_client.list_snapmirror_snapshots.return_value = ['sm_snap']
 4246         self.mock_object(self.library,
 4247                          '_get_vserver',
 4248                          mock.Mock(return_value=(fake.VSERVER1,
 4249                                                  vserver_client)))
 4250         self.mock_dm_session.break_snapmirror.side_effect = (
 4251             netapp_api.NaApiError(code=netapp_api.EOBJECTNOTFOUND))
 4252 
 4253         self.library.revert_to_replicated_snapshot(
 4254             self.context, self.fake_replica, replica_list, fake_snapshot,
 4255             snapshot_list, share_server=fake.SHARE_SERVER)
 4256 
 4257         vserver_client.get_snapshot.assert_called_once_with(
 4258             share_name, snapshot_name)
 4259         vserver_client.list_snapmirror_snapshots.assert_called_once_with(
 4260             share_name)
 4261         vserver_client.delete_snapshot.assert_called_once_with(
 4262             share_name, 'sm_snap', ignore_owners=True)
 4263         vserver_client.restore_snapshot.assert_called_once_with(
 4264             share_name, snapshot_name)
 4265 
 4266         self.mock_dm_session.break_snapmirror.assert_has_calls(
 4267             [mock.call(self.fake_replica, self.fake_replica_2, mount=False),
 4268              mock.call(self.fake_replica, fake_replica_3, mount=False)],
 4269             any_order=True)
 4270         self.mock_dm_session.resync_snapmirror.assert_has_calls(
 4271             [mock.call(self.fake_replica, self.fake_replica_2),
 4272              mock.call(self.fake_replica, fake_replica_3)],
 4273             any_order=True)
 4274 
 4275     def test_revert_to_replicated_snapshot_snapmirror_resync_error(self):
 4276 
 4277         replica_list, snapshot_list = self._get_fake_replicas_and_snapshots()
 4278         fake_snapshot, fake_snapshot_2, fake_snapshot_3 = snapshot_list
 4279 
 4280         vserver_client = mock.Mock()
 4281         vserver_client.get_snapshot.return_value = fake.CDOT_SNAPSHOT
 4282         vserver_client.list_snapmirror_snapshots.return_value = ['sm_snap']
 4283         self.mock_object(self.library,
 4284                          '_get_vserver',
 4285                          mock.Mock(return_value=(fake.VSERVER1,
 4286                                                  vserver_client)))
 4287         self.mock_dm_session.resync_snapmirror.side_effect = (
 4288             netapp_api.NaApiError)
 4289 
 4290         self.assertRaises(
 4291             netapp_api.NaApiError, self.library.revert_to_replicated_snapshot,
 4292             self.context, self.fake_replica, replica_list, fake_snapshot,
 4293             snapshot_list, share_server=fake.SHARE_SERVER)
 4294 
 4295     def test_revert_to_replicated_snapshot_snapmirror_resync_not_found(self):
 4296 
 4297         replica_list, snapshot_list = self._get_fake_replicas_and_snapshots()
 4298         fake_replica, fake_replica_2, fake_replica_3 = replica_list
 4299         fake_snapshot, fake_snapshot_2, fake_snapshot_3 = snapshot_list
 4300         share_name = self.library._get_backend_share_name(
 4301             fake_snapshot['share_id'])
 4302         snapshot_name = self.library._get_backend_snapshot_name(
 4303             fake_snapshot['id'])
 4304 
 4305         vserver_client = mock.Mock()
 4306         vserver_client.get_snapshot.return_value = fake.CDOT_SNAPSHOT
 4307         vserver_client.list_snapmirror_snapshots.return_value = ['sm_snap']
 4308         self.mock_object(self.library,
 4309                          '_get_vserver',
 4310                          mock.Mock(return_value=(fake.VSERVER1,
 4311                                                  vserver_client)))
 4312         self.mock_dm_session.resync_snapmirror.side_effect = (
 4313             netapp_api.NaApiError(code=netapp_api.EOBJECTNOTFOUND))
 4314 
 4315         self.library.revert_to_replicated_snapshot(
 4316             self.context, self.fake_replica, replica_list, fake_snapshot,
 4317             snapshot_list, share_server=fake.SHARE_SERVER)
 4318 
 4319         vserver_client.get_snapshot.assert_called_once_with(
 4320             share_name, snapshot_name)
 4321         vserver_client.list_snapmirror_snapshots.assert_called_once_with(
 4322             share_name)
 4323         vserver_client.delete_snapshot.assert_called_once_with(
 4324             share_name, 'sm_snap', ignore_owners=True)
 4325         vserver_client.restore_snapshot.assert_called_once_with(
 4326             share_name, snapshot_name)
 4327 
 4328         self.mock_dm_session.break_snapmirror.assert_has_calls(
 4329             [mock.call(self.fake_replica, self.fake_replica_2, mount=False),
 4330              mock.call(self.fake_replica, fake_replica_3, mount=False)],
 4331             any_order=True)
 4332         self.mock_dm_session.resync_snapmirror.assert_has_calls(
 4333             [mock.call(self.fake_replica, self.fake_replica_2),
 4334              mock.call(self.fake_replica, fake_replica_3)],
 4335             any_order=True)
 4336 
 4337     def test_migration_check_compatibility_no_cluster_credentials(self):
 4338         self.library._have_cluster_creds = False
 4339         self.mock_object(data_motion, 'get_backend_configuration')
 4340         mock_warning_log = self.mock_object(lib_base.LOG, 'warning')
 4341 
 4342         migration_compatibility = self.library.migration_check_compatibility(
 4343             self.context, fake_share.fake_share_instance(),
 4344             fake_share.fake_share_instance(), share_server=None,
 4345             destination_share_server=fake.SHARE_SERVER)
 4346 
 4347         expected_compatibility = {
 4348             'compatible': False,
 4349             'writable': False,
 4350             'nondisruptive': False,
 4351             'preserve_metadata': False,
 4352             'preserve_snapshots': False,
 4353         }
 4354         self.assertDictMatch(expected_compatibility, migration_compatibility)
 4355         mock_warning_log.assert_called_once()
 4356         self.assertFalse(data_motion.get_backend_configuration.called)
 4357 
 4358     @ddt.data((None, exception.NetAppException),
 4359               (exception.Invalid, None))
 4360     @ddt.unpack
 4361     def test_migration_check_compatibility_extra_specs_invalid(
 4362             self, side_effect_1, side_effect_2):
 4363         self.library._have_cluster_creds = True
 4364         self.mock_object(self.library, '_get_backend_share_name',
 4365                          mock.Mock(return_value=fake.SHARE_NAME))
 4366         mock_exception_log = self.mock_object(lib_base.LOG, 'exception')
 4367         self.mock_object(share_types, 'get_extra_specs_from_share')
 4368         self.mock_object(self.library, '_check_extra_specs_validity',
 4369                          mock.Mock(side_effect=side_effect_1))
 4370         self.mock_object(self.library,
 4371                          '_check_aggregate_extra_specs_validity',
 4372                          mock.Mock(side_effect=side_effect_2))
 4373         self.mock_object(data_motion, 'get_backend_configuration')
 4374 
 4375         migration_compatibility = self.library.migration_check_compatibility(
 4376             self.context, fake_share.fake_share_instance(),
 4377             fake_share.fake_share_instance(), share_server=fake.SHARE_SERVER,
 4378             destination_share_server=None)
 4379 
 4380         expected_compatibility = {
 4381             'compatible': False,
 4382             'writable': False,
 4383             'nondisruptive': False,
 4384             'preserve_metadata': False,
 4385             'preserve_snapshots': False,
 4386         }
 4387         self.assertDictMatch(expected_compatibility, migration_compatibility)
 4388         mock_exception_log.assert_called_once()
 4389         self.assertFalse(data_motion.get_backend_configuration.called)
 4390 
 4391     def test_migration_check_compatibility_destination_not_configured(self):
 4392         self.library._have_cluster_creds = True
 4393         self.mock_object(self.library, '_get_backend_share_name',
 4394                          mock.Mock(return_value=fake.SHARE_NAME))
 4395         self.mock_object(
 4396             data_motion, 'get_backend_configuration',
 4397             mock.Mock(side_effect=exception.BadConfigurationException))
 4398         self.mock_object(self.library, '_get_vserver')
 4399         mock_exception_log = self.mock_object(lib_base.LOG, 'exception')
 4400         self.mock_object(share_utils, 'extract_host', mock.Mock(
 4401             return_value='destination_backend'))
 4402         self.mock_object(share_types, 'get_extra_specs_from_share')
 4403         self.mock_object(self.library, '_check_extra_specs_validity')
 4404         self.mock_object(self.library, '_check_aggregate_extra_specs_validity')
 4405         mock_vserver_compatibility_check = self.mock_object(
 4406             self.library, '_check_destination_vserver_for_vol_move')
 4407         self.mock_object(self.library, '_get_dest_flexvol_encryption_value',
 4408                          mock.Mock(return_value=False))
 4409 
 4410         migration_compatibility = self.library.migration_check_compatibility(
 4411             self.context, fake_share.fake_share_instance(),
 4412             fake_share.fake_share_instance(), share_server=fake.SHARE_SERVER,
 4413             destination_share_server=None)
 4414 
 4415         expected_compatibility = {
 4416             'compatible': False,
 4417             'writable': False,
 4418             'nondisruptive': False,
 4419             'preserve_metadata': False,
 4420             'preserve_snapshots': False,
 4421         }
 4422         self.assertDictMatch(expected_compatibility, migration_compatibility)
 4423         mock_exception_log.assert_called_once()
 4424         data_motion.get_backend_configuration.assert_called_once_with(
 4425             'destination_backend')
 4426         self.assertFalse(mock_vserver_compatibility_check.called)
 4427         self.assertFalse(self.library._get_vserver.called)
 4428 
 4429     @ddt.data(
 4430         utils.annotated(
 4431             'dest_share_server_not_expected',
 4432             (('src_vserver', None), exception.InvalidParameterValue)),
 4433         utils.annotated(
 4434             'src_share_server_not_expected',
 4435             (exception.InvalidParameterValue, ('dest_vserver', None))))
 4436     def test_migration_check_compatibility_errors(self, side_effects):
 4437         self.library._have_cluster_creds = True
 4438         self.mock_object(share_types, 'get_extra_specs_from_share')
 4439         self.mock_object(self.library, '_check_extra_specs_validity')
 4440         self.mock_object(self.library, '_check_aggregate_extra_specs_validity')
 4441         self.mock_object(self.library, '_get_backend_share_name',
 4442                          mock.Mock(return_value=fake.SHARE_NAME))
 4443         self.mock_object(data_motion, 'get_backend_configuration')
 4444         self.mock_object(self.library, '_get_vserver',
 4445                          mock.Mock(side_effect=side_effects))
 4446         mock_exception_log = self.mock_object(lib_base.LOG, 'exception')
 4447         self.mock_object(share_utils, 'extract_host', mock.Mock(
 4448             return_value='destination_backend'))
 4449         mock_compatibility_check = self.mock_object(
 4450             self.client, 'check_volume_move')
 4451 
 4452         migration_compatibility = self.library.migration_check_compatibility(
 4453             self.context, fake_share.fake_share_instance(),
 4454             fake_share.fake_share_instance(), share_server=fake.SHARE_SERVER,
 4455             destination_share_server=None)
 4456 
 4457         expected_compatibility = {
 4458             'compatible': False,
 4459             'writable': False,
 4460             'nondisruptive': False,
 4461             'preserve_metadata': False,
 4462             'preserve_snapshots': False,
 4463         }
 4464         self.assertDictMatch(expected_compatibility, migration_compatibility)
 4465         mock_exception_log.assert_called_once()
 4466         data_motion.get_backend_configuration.assert_called_once_with(
 4467             'destination_backend')
 4468         self.assertFalse(mock_compatibility_check.called)
 4469 
 4470     def test_migration_check_compatibility_incompatible_vservers(self):
 4471         self.library._have_cluster_creds = True
 4472         self.mock_object(share_types, 'get_extra_specs_from_share')
 4473         self.mock_object(self.library, '_check_extra_specs_validity')
 4474         self.mock_object(self.library, '_check_aggregate_extra_specs_validity')
 4475         self.mock_object(self.library, '_get_backend_share_name',
 4476                          mock.Mock(return_value=fake.SHARE_NAME))
 4477         self.mock_object(data_motion, 'get_backend_configuration')
 4478         mock_exception_log = self.mock_object(lib_base.LOG, 'exception')
 4479         get_vserver_returns = [
 4480             (fake.VSERVER1, mock.Mock()),
 4481             (fake.VSERVER2, mock.Mock()),
 4482         ]
 4483         self.mock_object(self.library, '_get_vserver',
 4484                          mock.Mock(side_effect=get_vserver_returns))
 4485         self.mock_object(share_utils, 'extract_host', mock.Mock(
 4486             side_effect=['destination_backend', 'destination_pool']))
 4487         mock_move_check = self.mock_object(self.client, 'check_volume_move')
 4488 
 4489         migration_compatibility = self.library.migration_check_compatibility(
 4490             self.context, fake_share.fake_share_instance(),
 4491             fake_share.fake_share_instance(), share_server=fake.SHARE_SERVER,
 4492             destination_share_server='dst_srv')
 4493 
 4494         expected_compatibility = {
 4495             'compatible': False,
 4496             'writable': False,
 4497             'nondisruptive': False,
 4498             'preserve_metadata': False,
 4499             'preserve_snapshots': False,
 4500         }
 4501         self.assertDictMatch(expected_compatibility, migration_compatibility)
 4502         mock_exception_log.assert_called_once()
 4503         data_motion.get_backend_configuration.assert_called_once_with(
 4504             'destination_backend')
 4505         self.assertFalse(mock_move_check.called)
 4506         self.library._get_vserver.assert_has_calls(
 4507             [mock.call(share_server=fake.SHARE_SERVER),
 4508              mock.call(share_server='dst_srv')])
 4509 
 4510     def test_migration_check_compatibility_client_error(self):
 4511         self.library._have_cluster_creds = True
 4512         self.mock_object(share_types, 'get_extra_specs_from_share')
 4513         self.mock_object(self.library, '_check_extra_specs_validity')
 4514         self.mock_object(self.library, '_check_aggregate_extra_specs_validity')
 4515         self.mock_object(self.library, '_get_backend_share_name',
 4516                          mock.Mock(return_value=fake.SHARE_NAME))
 4517         mock_exception_log = self.mock_object(lib_base.LOG, 'exception')
 4518         self.mock_object(data_motion, 'get_backend_configuration')
 4519         self.mock_object(self.library, '_get_vserver',
 4520                          mock.Mock(return_value=(fake.VSERVER1, mock.Mock())))
 4521         self.mock_object(share_utils, 'extract_host', mock.Mock(
 4522             side_effect=['destination_backend', 'destination_pool']))
 4523         mock_move_check = self.mock_object(
 4524             self.client, 'check_volume_move',
 4525             mock.Mock(side_effect=netapp_api.NaApiError))
 4526         self.mock_object(self.library, '_get_dest_flexvol_encryption_value',
 4527                          mock.Mock(return_value=False))
 4528 
 4529         migration_compatibility = self.library.migration_check_compatibility(
 4530             self.context, fake_share.fake_share_instance(),
 4531             fake_share.fake_share_instance(), share_server=fake.SHARE_SERVER,
 4532             destination_share_server='dst_srv')
 4533 
 4534         expected_compatibility = {
 4535             'compatible': False,
 4536             'writable': False,
 4537             'nondisruptive': False,
 4538             'preserve_metadata': False,
 4539             'preserve_snapshots': False,
 4540         }
 4541         self.assertDictMatch(expected_compatibility, migration_compatibility)
 4542         mock_exception_log.assert_called_once()
 4543         data_motion.get_backend_configuration.assert_called_once_with(
 4544             'destination_backend')
 4545         mock_move_check.assert_called_once_with(
 4546             fake.SHARE_NAME, fake.VSERVER1, 'destination_pool',
 4547             encrypt_destination=False)
 4548         self.library._get_vserver.assert_has_calls(
 4549             [mock.call(share_server=fake.SHARE_SERVER),
 4550              mock.call(share_server='dst_srv')])
 4551 
 4552     def test_migration_check_compatibility(self):
 4553         self.library._have_cluster_creds = True
 4554         self.mock_object(share_types, 'get_extra_specs_from_share')
 4555         self.mock_object(self.library, '_check_extra_specs_validity')
 4556         self.mock_object(self.library, '_check_aggregate_extra_specs_validity')
 4557         self.mock_object(self.library, '_get_backend_share_name',
 4558                          mock.Mock(return_value=fake.SHARE_NAME))
 4559         self.mock_object(data_motion, 'get_backend_configuration')
 4560         self.mock_object(self.library, '_get_vserver',
 4561                          mock.Mock(return_value=(fake.VSERVER1, mock.Mock())))
 4562         self.mock_object(share_utils, 'extract_host', mock.Mock(
 4563             side_effect=['destination_backend', 'destination_pool']))
 4564         mock_move_check = self.mock_object(self.client, 'check_volume_move')
 4565         self.mock_object(self.library, '_get_dest_flexvol_encryption_value',
 4566                          mock.Mock(return_value=False))
 4567 
 4568         migration_compatibility = self.library.migration_check_compatibility(
 4569             self.context, fake_share.fake_share_instance(),
 4570             fake_share.fake_share_instance(), share_server=fake.SHARE_SERVER,
 4571             destination_share_server='dst_srv')
 4572 
 4573         expected_compatibility = {
 4574             'compatible': True,
 4575             'writable': True,
 4576             'nondisruptive': True,
 4577             'preserve_metadata': True,
 4578             'preserve_snapshots': True,
 4579         }
 4580         self.assertDictMatch(expected_compatibility, migration_compatibility)
 4581         data_motion.get_backend_configuration.assert_called_once_with(
 4582             'destination_backend')
 4583         mock_move_check.assert_called_once_with(
 4584             fake.SHARE_NAME, fake.VSERVER1, 'destination_pool',
 4585             encrypt_destination=False)
 4586         self.library._get_vserver.assert_has_calls(
 4587             [mock.call(share_server=fake.SHARE_SERVER),
 4588              mock.call(share_server='dst_srv')])
 4589 
 4590     def test_migration_check_compatibility_destination_type_is_encrypted(self):
 4591         self.library._have_cluster_creds = True
 4592         self.mock_object(self.library, '_get_backend_share_name',
 4593                          mock.Mock(return_value=fake.SHARE_NAME))
 4594         self.mock_object(data_motion