"Fossies" - the Fresh Open Source Software Archive

Member "manila-8.1.3/manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_lib_base.py" (20 Jul 2020, 232534 Bytes) of package /linux/misc/openstack/manila-8.1.3.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.2_vs_8.1.3.

    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         self.mock_object(self.library,
 3032                          '_get_helper',
 3033                          mock.Mock(return_value=mock.Mock()))
 3034         self.mock_object(self.library, '_create_export',
 3035                          mock.Mock(return_value='fake_export_location'))
 3036         self.mock_object(self.library, '_unmount_orig_active_replica')
 3037         self.mock_object(self.library, '_handle_qos_on_replication_change')
 3038 
 3039         mock_dm_session = mock.Mock()
 3040         self.mock_object(data_motion, "DataMotionSession",
 3041                          mock.Mock(return_value=mock_dm_session))
 3042         self.mock_object(mock_dm_session, 'get_vserver_from_share',
 3043                          mock.Mock(return_value=fake.VSERVER1))
 3044 
 3045         replicas = self.library.promote_replica(
 3046             None, [self.fake_replica, self.fake_replica_2],
 3047             self.fake_replica_2, [], share_server=None)
 3048 
 3049         mock_dm_session.change_snapmirror_source.assert_called_once_with(
 3050             self.fake_replica, self.fake_replica, self.fake_replica_2,
 3051             mock.ANY
 3052         )
 3053         self.assertEqual(2, len(replicas))
 3054         actual_replica_1 = list(filter(
 3055             lambda x: x['id'] == self.fake_replica['id'], replicas))[0]
 3056         self.assertEqual(constants.REPLICA_STATE_OUT_OF_SYNC,
 3057                          actual_replica_1['replica_state'])
 3058         actual_replica_2 = list(filter(
 3059             lambda x: x['id'] == self.fake_replica_2['id'], replicas))[0]
 3060         self.assertEqual(constants.REPLICA_STATE_ACTIVE,
 3061                          actual_replica_2['replica_state'])
 3062         self.assertEqual('fake_export_location',
 3063                          actual_replica_2['export_locations'])
 3064         self.assertEqual(constants.STATUS_ACTIVE,
 3065                          actual_replica_2['access_rules_status'])
 3066         self.library._unmount_orig_active_replica.assert_called_once_with(
 3067             self.fake_replica, fake.VSERVER1)
 3068         self.library._handle_qos_on_replication_change.assert_called_once()
 3069 
 3070     def test_promote_replica_destination_unreachable(self):
 3071         self.mock_object(self.library,
 3072                          '_get_vserver',
 3073                          mock.Mock(return_value=(fake.VSERVER1,
 3074                                                  mock.Mock())))
 3075         self.mock_object(self.library,
 3076                          '_get_helper',
 3077                          mock.Mock(return_value=mock.Mock()))
 3078         self.mock_object(self.library, '_unmount_orig_active_replica')
 3079         self.mock_object(self.library, '_handle_qos_on_replication_change')
 3080 
 3081         self.mock_object(self.library, '_create_export',
 3082                          mock.Mock(return_value='fake_export_location'))
 3083         self.mock_object(
 3084             self.library, '_convert_destination_replica_to_independent',
 3085             mock.Mock(side_effect=exception.StorageCommunicationException))
 3086 
 3087         replicas = self.library.promote_replica(
 3088             None, [self.fake_replica, self.fake_replica_2],
 3089             self.fake_replica_2, [], share_server=None)
 3090 
 3091         self.assertEqual(1, len(replicas))
 3092         actual_replica = replicas[0]
 3093         self.assertEqual(constants.STATUS_ERROR,
 3094                          actual_replica['replica_state'])
 3095         self.assertEqual(constants.STATUS_ERROR,
 3096                          actual_replica['status'])
 3097         self.assertFalse(
 3098             self.library._unmount_orig_active_replica.called)
 3099         self.assertFalse(
 3100             self.library._handle_qos_on_replication_change.called)
 3101 
 3102     def test_promote_replica_more_than_two_replicas(self):
 3103         fake_replica_3 = copy.deepcopy(self.fake_replica_2)
 3104         fake_replica_3['id'] = fake.SHARE_ID3
 3105         fake_replica_3['replica_state'] = constants.REPLICA_STATE_OUT_OF_SYNC
 3106         self.mock_object(self.library,
 3107                          '_get_vserver',
 3108                          mock.Mock(return_value=(fake.VSERVER1,
 3109                                                  mock.Mock())))
 3110         self.mock_object(self.library, '_unmount_orig_active_replica')
 3111         self.mock_object(self.library, '_handle_qos_on_replication_change')
 3112         self.mock_object(self.library,
 3113                          '_get_helper',
 3114                          mock.Mock(return_value=mock.Mock()))
 3115 
 3116         self.mock_object(self.library, '_create_export',
 3117                          mock.Mock(return_value='fake_export_location'))
 3118         mock_dm_session = mock.Mock()
 3119         self.mock_object(data_motion, "DataMotionSession",
 3120                          mock.Mock(return_value=mock_dm_session))
 3121         self.mock_object(mock_dm_session, 'get_vserver_from_share',
 3122                          mock.Mock(return_value=fake.VSERVER1))
 3123 
 3124         replicas = self.library.promote_replica(
 3125             None, [self.fake_replica, self.fake_replica_2, fake_replica_3],
 3126             self.fake_replica_2, [], share_server=None)
 3127 
 3128         mock_dm_session.change_snapmirror_source.assert_has_calls([
 3129             mock.call(fake_replica_3, self.fake_replica, self.fake_replica_2,
 3130                       mock.ANY),
 3131             mock.call(self.fake_replica, self.fake_replica,
 3132                       self.fake_replica_2, mock.ANY)
 3133         ], any_order=True)
 3134 
 3135         self.assertEqual(3, len(replicas))
 3136         actual_replica_1 = list(filter(
 3137             lambda x: x['id'] == self.fake_replica['id'], replicas))[0]
 3138         self.assertEqual(constants.REPLICA_STATE_OUT_OF_SYNC,
 3139                          actual_replica_1['replica_state'])
 3140         actual_replica_2 = list(filter(
 3141             lambda x: x['id'] == self.fake_replica_2['id'], replicas))[0]
 3142         self.assertEqual(constants.REPLICA_STATE_ACTIVE,
 3143                          actual_replica_2['replica_state'])
 3144         self.assertEqual('fake_export_location',
 3145                          actual_replica_2['export_locations'])
 3146         actual_replica_3 = list(filter(
 3147             lambda x: x['id'] == fake_replica_3['id'], replicas))[0]
 3148         self.assertEqual(constants.REPLICA_STATE_OUT_OF_SYNC,
 3149                          actual_replica_3['replica_state'])
 3150         self.library._unmount_orig_active_replica.assert_called_once_with(
 3151             self.fake_replica, fake.VSERVER1)
 3152         self.library._handle_qos_on_replication_change.assert_called_once()
 3153 
 3154     def test_promote_replica_with_access_rules(self):
 3155         self.mock_object(self.library,
 3156                          '_get_vserver',
 3157                          mock.Mock(return_value=(fake.VSERVER1,
 3158                                                  mock.Mock())))
 3159         self.mock_object(self.library, '_unmount_orig_active_replica')
 3160         self.mock_object(self.library, '_handle_qos_on_replication_change')
 3161         mock_helper = mock.Mock()
 3162         self.mock_object(self.library,
 3163                          '_get_helper',
 3164                          mock.Mock(return_value=mock_helper))
 3165         self.mock_object(self.library, '_create_export',
 3166                          mock.Mock(return_value='fake_export_location'))
 3167 
 3168         mock_dm_session = mock.Mock()
 3169         self.mock_object(data_motion, "DataMotionSession",
 3170                          mock.Mock(return_value=mock_dm_session))
 3171         self.mock_object(mock_dm_session, 'get_vserver_from_share',
 3172                          mock.Mock(return_value=fake.VSERVER1))
 3173 
 3174         replicas = self.library.promote_replica(
 3175             None, [self.fake_replica, self.fake_replica_2],
 3176             self.fake_replica_2, [fake.SHARE_ACCESS], share_server=None)
 3177 
 3178         mock_dm_session.change_snapmirror_source.assert_has_calls([
 3179             mock.call(self.fake_replica, self.fake_replica,
 3180                       self.fake_replica_2, mock.ANY)
 3181         ], any_order=True)
 3182         self.assertEqual(2, len(replicas))
 3183         share_name = self.library._get_backend_share_name(
 3184             self.fake_replica_2['id'])
 3185         mock_helper.update_access.assert_called_once_with(self.fake_replica_2,
 3186                                                           share_name,
 3187                                                           [fake.SHARE_ACCESS])
 3188         self.library._unmount_orig_active_replica.assert_called_once_with(
 3189             self.fake_replica, fake.VSERVER1)
 3190         self.library._handle_qos_on_replication_change.assert_called_once()
 3191 
 3192     def test_unmount_orig_active_replica(self):
 3193         self.mock_object(share_utils, 'extract_host', mock.Mock(
 3194             return_value=fake.MANILA_HOST_NAME))
 3195         self.mock_object(data_motion, 'get_client_for_backend')
 3196         self.mock_object(self.library, '_get_backend_share_name', mock.Mock(
 3197             return_value=fake.SHARE_NAME))
 3198 
 3199         result = self.library._unmount_orig_active_replica(fake.SHARE)
 3200         self.assertIsNone(result)
 3201 
 3202     @ddt.data({'extra_specs': {'netapp:snapshot_policy': 'none'},
 3203                'have_cluster_creds': True},
 3204               # Test Case 2 isn't possible input
 3205               {'extra_specs': {'qos': True, 'netapp:maxiops': '3000'},
 3206                'have_cluster_creds': False})
 3207     @ddt.unpack
 3208     def test_handle_qos_on_replication_change_nothing_to_handle(
 3209             self, extra_specs, have_cluster_creds):
 3210 
 3211         self.library._have_cluster_creds = have_cluster_creds
 3212         self.mock_object(lib_base.LOG, 'exception')
 3213         self.mock_object(lib_base.LOG, 'info')
 3214         self.mock_object(share_types, 'get_extra_specs_from_share',
 3215                          mock.Mock(return_value=extra_specs))
 3216 
 3217         retval = self.library._handle_qos_on_replication_change(
 3218             self.mock_dm_session, self.fake_replica_2, self.fake_replica,
 3219             share_server=fake.SHARE_SERVER)
 3220 
 3221         self.assertIsNone(retval)
 3222         lib_base.LOG.exception.assert_not_called()
 3223         lib_base.LOG.info.assert_not_called()
 3224 
 3225     def test_handle_qos_on_replication_change_exception(self):
 3226         self.library._have_cluster_creds = True
 3227         extra_specs = {'qos': True, fake.QOS_EXTRA_SPEC: '3000'}
 3228         vserver_client = mock.Mock()
 3229         self.mock_object(lib_base.LOG, 'exception')
 3230         self.mock_object(lib_base.LOG, 'info')
 3231         self.mock_object(share_types, 'get_extra_specs_from_share',
 3232                          mock.Mock(return_value=extra_specs))
 3233         self.mock_object(self.library, '_get_vserver', mock.Mock(
 3234             return_value=(fake.VSERVER1, vserver_client)))
 3235         self.mock_object(self.library._client, 'qos_policy_group_exists',
 3236                          mock.Mock(return_value=True))
 3237         self.mock_object(self.library._client, 'qos_policy_group_modify',
 3238                          mock.Mock(side_effect=netapp_api.NaApiError))
 3239 
 3240         retval = self.library._handle_qos_on_replication_change(
 3241             self.mock_dm_session, self.fake_replica_2, self.fake_replica,
 3242             share_server=fake.SHARE_SERVER)
 3243 
 3244         self.assertIsNone(retval)
 3245         (self.mock_dm_session.remove_qos_on_old_active_replica
 3246          .assert_called_once_with(self.fake_replica))
 3247         lib_base.LOG.exception.assert_called_once()
 3248         lib_base.LOG.info.assert_not_called()
 3249         vserver_client.set_qos_policy_group_for_volume.assert_not_called()
 3250 
 3251     def test_handle_qos_on_replication_change_modify_existing_policy(self):
 3252         self.library._have_cluster_creds = True
 3253         extra_specs = {'qos': True, fake.QOS_EXTRA_SPEC: '3000'}
 3254         vserver_client = mock.Mock()
 3255         volume_name_on_backend = self.library._get_backend_share_name(
 3256             self.fake_replica_2['id'])
 3257         self.mock_object(lib_base.LOG, 'exception')
 3258         self.mock_object(lib_base.LOG, 'info')
 3259         self.mock_object(share_types, 'get_extra_specs_from_share',
 3260                          mock.Mock(return_value=extra_specs))
 3261         self.mock_object(self.library, '_get_vserver', mock.Mock(
 3262             return_value=(fake.VSERVER1, vserver_client)))
 3263         self.mock_object(self.library._client, 'qos_policy_group_exists',
 3264                          mock.Mock(return_value=True))
 3265         self.mock_object(self.library._client, 'qos_policy_group_modify')
 3266         self.mock_object(self.library, '_create_qos_policy_group')
 3267 
 3268         retval = self.library._handle_qos_on_replication_change(
 3269             self.mock_dm_session, self.fake_replica_2, self.fake_replica,
 3270             share_server=fake.SHARE_SERVER)
 3271 
 3272         self.assertIsNone(retval)
 3273         self.library._client.qos_policy_group_modify.assert_called_once_with(
 3274             'qos_' + volume_name_on_backend, '3000iops')
 3275         vserver_client.set_qos_policy_group_for_volume.assert_called_once_with(
 3276             volume_name_on_backend, 'qos_' + volume_name_on_backend)
 3277         self.library._create_qos_policy_group.assert_not_called()
 3278         lib_base.LOG.exception.assert_not_called()
 3279         lib_base.LOG.info.assert_called_once()
 3280 
 3281     def test_handle_qos_on_replication_change_create_new_policy(self):
 3282         self.library._have_cluster_creds = True
 3283         extra_specs = {'qos': True, fake.QOS_EXTRA_SPEC: '3000'}
 3284         vserver_client = mock.Mock()
 3285         self.mock_object(lib_base.LOG, 'exception')
 3286         self.mock_object(lib_base.LOG, 'info')
 3287         self.mock_object(share_types, 'get_extra_specs_from_share',
 3288                          mock.Mock(return_value=extra_specs))
 3289         self.mock_object(self.library, '_get_vserver', mock.Mock(
 3290             return_value=(fake.VSERVER1, vserver_client)))
 3291         self.mock_object(self.library._client, 'qos_policy_group_exists',
 3292                          mock.Mock(return_value=False))
 3293         self.mock_object(self.library._client, 'qos_policy_group_modify')
 3294         self.mock_object(self.library, '_create_qos_policy_group')
 3295 
 3296         retval = self.library._handle_qos_on_replication_change(
 3297             self.mock_dm_session, self.fake_replica_2, self.fake_replica,
 3298             share_server=fake.SHARE_SERVER)
 3299 
 3300         self.assertIsNone(retval)
 3301         self.library._create_qos_policy_group.assert_called_once_with(
 3302             self.fake_replica_2, fake.VSERVER1, {'maxiops': '3000'})
 3303         self.library._client.qos_policy_group_modify.assert_not_called()
 3304         lib_base.LOG.exception.assert_not_called()
 3305         lib_base.LOG.info.assert_called_once()
 3306 
 3307     def test_convert_destination_replica_to_independent(self):
 3308         self.mock_object(self.library,
 3309                          '_get_vserver',
 3310                          mock.Mock(return_value=(fake.VSERVER1,
 3311                                                  mock.Mock())))
 3312         self.mock_object(self.library,
 3313                          '_get_helper',
 3314                          mock.Mock(return_value=mock.Mock()))
 3315         self.mock_object(self.library, '_create_export',
 3316                          mock.Mock(return_value='fake_export_location'))
 3317 
 3318         replica = self.library._convert_destination_replica_to_independent(
 3319             None, self.mock_dm_session, self.fake_replica,
 3320             self.fake_replica_2, [], share_server=None)
 3321 
 3322         self.mock_dm_session.update_snapmirror.assert_called_once_with(
 3323             self.fake_replica, self.fake_replica_2)
 3324         self.mock_dm_session.break_snapmirror.assert_called_once_with(
 3325             self.fake_replica, self.fake_replica_2)
 3326 
 3327         self.assertEqual('fake_export_location',
 3328                          replica['export_locations'])
 3329         self.assertEqual(constants.REPLICA_STATE_ACTIVE,
 3330                          replica['replica_state'])
 3331 
 3332     def test_convert_destination_replica_to_independent_update_failed(self):
 3333         self.mock_object(self.library,
 3334                          '_get_vserver',
 3335                          mock.Mock(return_value=(fake.VSERVER1,
 3336                                                  mock.Mock())))
 3337         self.mock_object(self.library,
 3338                          '_get_helper',
 3339                          mock.Mock(return_value=mock.Mock()))
 3340         self.mock_object(self.library, '_create_export',
 3341                          mock.Mock(return_value='fake_export_location'))
 3342         self.mock_object(
 3343             self.mock_dm_session, 'update_snapmirror',
 3344             mock.Mock(side_effect=exception.StorageCommunicationException))
 3345 
 3346         replica = self.library._convert_destination_replica_to_independent(
 3347             None, self.mock_dm_session, self.fake_replica,
 3348             self.fake_replica_2, [], share_server=None)
 3349 
 3350         self.mock_dm_session.update_snapmirror.assert_called_once_with(
 3351             self.fake_replica, self.fake_replica_2)
 3352         self.mock_dm_session.break_snapmirror.assert_called_once_with(
 3353             self.fake_replica, self.fake_replica_2)
 3354 
 3355         self.assertEqual('fake_export_location',
 3356                          replica['export_locations'])
 3357         self.assertEqual(constants.REPLICA_STATE_ACTIVE,
 3358                          replica['replica_state'])
 3359 
 3360     def test_promote_replica_fail_to_set_access_rules(self):
 3361         fake_helper = mock.Mock()
 3362         fake_helper.update_access.side_effect = Exception
 3363         fake_access_rules = [
 3364             {'access_to': "0.0.0.0",
 3365              'access_level': constants.ACCESS_LEVEL_RO},
 3366             {'access_to': "10.10.10.10",
 3367              'access_level': constants.ACCESS_LEVEL_RW},
 3368         ]
 3369         self.mock_object(self.library,
 3370                          '_get_vserver',
 3371                          mock.Mock(return_value=(fake.VSERVER1,
 3372                                                  mock.Mock())))
 3373         self.mock_object(self.library, '_handle_qos_on_replication_change')
 3374         self.mock_object(self.library,
 3375                          '_get_helper',
 3376                          mock.Mock(return_value=fake_helper))
 3377         self.mock_object(self.library, '_create_export',
 3378                          mock.Mock(return_value='fake_export_location'))
 3379 
 3380         replicas = self.library.promote_replica(
 3381             None, [self.fake_replica, self.fake_replica_2],
 3382             self.fake_replica_2, fake_access_rules, share_server=None)
 3383 
 3384         self.mock_dm_session.change_snapmirror_source.assert_called_once_with(
 3385             self.fake_replica, self.fake_replica, self.fake_replica_2,
 3386             mock.ANY
 3387         )
 3388 
 3389         self.assertEqual(2, len(replicas))
 3390         actual_replica_1 = list(filter(
 3391             lambda x: x['id'] == self.fake_replica['id'], replicas))[0]
 3392         self.assertEqual(constants.REPLICA_STATE_OUT_OF_SYNC,
 3393                          actual_replica_1['replica_state'])
 3394         actual_replica_2 = list(filter(
 3395             lambda x: x['id'] == self.fake_replica_2['id'], replicas))[0]
 3396         self.assertEqual(constants.REPLICA_STATE_ACTIVE,
 3397                          actual_replica_2['replica_state'])
 3398         self.assertEqual('fake_export_location',
 3399                          actual_replica_2['export_locations'])
 3400         self.assertEqual(constants.SHARE_INSTANCE_RULES_SYNCING,
 3401                          actual_replica_2['access_rules_status'])
 3402         self.library._handle_qos_on_replication_change.assert_called_once()
 3403 
 3404     def test_convert_destination_replica_to_independent_with_access_rules(
 3405             self):
 3406         fake_helper = mock.Mock()
 3407         fake_helper.update_access.side_effect = Exception
 3408         fake_access_rules = [
 3409             {'access_to': "0.0.0.0",
 3410              'access_level': constants.ACCESS_LEVEL_RO},
 3411             {'access_to': "10.10.10.10",
 3412              'access_level': constants.ACCESS_LEVEL_RW},
 3413         ]
 3414         self.mock_object(self.library,
 3415                          '_get_vserver',
 3416                          mock.Mock(return_value=(fake.VSERVER1,
 3417                                                  mock.Mock())))
 3418         self.mock_object(self.library,
 3419                          '_get_helper',
 3420                          mock.Mock(return_value=fake_helper))
 3421         self.mock_object(self.library, '_create_export',
 3422                          mock.Mock(return_value='fake_export_location'))
 3423 
 3424         replica = self.library._convert_destination_replica_to_independent(
 3425             None, self.mock_dm_session, self.fake_replica,
 3426             self.fake_replica_2, fake_access_rules, share_server=None)
 3427 
 3428         self.mock_dm_session.update_snapmirror.assert_called_once_with(
 3429             self.fake_replica, self.fake_replica_2)
 3430         self.mock_dm_session.break_snapmirror.assert_called_once_with(
 3431             self.fake_replica, self.fake_replica_2)
 3432 
 3433         self.assertEqual('fake_export_location',
 3434                          replica['export_locations'])
 3435         self.assertEqual(constants.REPLICA_STATE_ACTIVE,
 3436                          replica['replica_state'])
 3437         self.assertEqual(constants.SHARE_INSTANCE_RULES_SYNCING,
 3438                          replica['access_rules_status'])
 3439 
 3440     def test_convert_destination_replica_to_independent_failed_access_rules(
 3441             self):
 3442         fake_helper = mock.Mock()
 3443         fake_access_rules = [
 3444             {'access_to': "0.0.0.0",
 3445              'access_level': constants.ACCESS_LEVEL_RO},
 3446             {'access_to': "10.10.10.10",
 3447              'access_level': constants.ACCESS_LEVEL_RW},
 3448         ]
 3449         self.mock_object(self.library,
 3450                          '_get_vserver',
 3451                          mock.Mock(return_value=(fake.VSERVER1,
 3452                                                  mock.Mock())))
 3453         self.mock_object(self.library,
 3454                          '_get_helper',
 3455                          mock.Mock(return_value=fake_helper))
 3456         self.mock_object(self.library, '_create_export',
 3457                          mock.Mock(return_value='fake_export_location'))
 3458 
 3459         replica = self.library._convert_destination_replica_to_independent(
 3460             None, self.mock_dm_session, self.fake_replica,
 3461             self.fake_replica_2, fake_access_rules, share_server=None)
 3462 
 3463         self.mock_dm_session.update_snapmirror.assert_called_once_with(
 3464             self.fake_replica, self.fake_replica_2)
 3465         self.mock_dm_session.break_snapmirror.assert_called_once_with(
 3466             self.fake_replica, self.fake_replica_2)
 3467 
 3468         fake_helper.assert_has_calls([
 3469             mock.call.set_client(mock.ANY),
 3470             mock.call.update_access(mock.ANY, mock.ANY, fake_access_rules),
 3471         ])
 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.STATUS_ACTIVE,
 3478                          replica['access_rules_status'])
 3479 
 3480     def test_safe_change_replica_source(self):
 3481         fake_replica_3 = copy.deepcopy(self.fake_replica_2)
 3482         fake_replica_3['id'] = fake.SHARE_ID3
 3483         fake_replica_3['replica_state'] = constants.REPLICA_STATE_OUT_OF_SYNC
 3484         replica = self.library._safe_change_replica_source(
 3485             self.mock_dm_session, self.fake_replica, self.fake_replica_2,
 3486             fake_replica_3, [self.fake_replica, self.fake_replica_2,
 3487                              fake_replica_3]
 3488         )
 3489         self.assertEqual([], replica['export_locations'])
 3490         self.assertEqual(constants.REPLICA_STATE_OUT_OF_SYNC,
 3491                          replica['replica_state'])
 3492 
 3493     def test_safe_change_replica_source_destination_unreachable(self):
 3494         self.mock_dm_session.change_snapmirror_source.side_effect = (
 3495             exception.StorageCommunicationException
 3496         )
 3497 
 3498         fake_replica_3 = copy.deepcopy(self.fake_replica_2)
 3499         fake_replica_3['id'] = fake.SHARE_ID3
 3500         fake_replica_3['replica_state'] = constants.REPLICA_STATE_OUT_OF_SYNC
 3501         replica = self.library._safe_change_replica_source(
 3502             self.mock_dm_session, self.fake_replica, self.fake_replica_2,
 3503             fake_replica_3, [self.fake_replica, self.fake_replica_2,
 3504                              fake_replica_3]
 3505         )
 3506         self.assertEqual([], replica['export_locations'])
 3507         self.assertEqual(constants.STATUS_ERROR,
 3508                          replica['replica_state'])
 3509         self.assertEqual(constants.STATUS_ERROR,
 3510                          replica['status'])
 3511 
 3512     def test_safe_change_replica_source_error(self):
 3513         self.mock_dm_session.change_snapmirror_source.side_effect = (
 3514             netapp_api.NaApiError(code=0)
 3515         )
 3516 
 3517         fake_replica_3 = copy.deepcopy(self.fake_replica_2)
 3518         fake_replica_3['id'] = fake.SHARE_ID3
 3519         fake_replica_3['replica_state'] = constants.REPLICA_STATE_OUT_OF_SYNC
 3520         replica = self.library._safe_change_replica_source(
 3521             self.mock_dm_session, self.fake_replica, self.fake_replica_2,
 3522             fake_replica_3, [self.fake_replica, self.fake_replica_2,
 3523                              fake_replica_3]
 3524         )
 3525         self.assertEqual([], replica['export_locations'])
 3526         self.assertEqual(constants.STATUS_ERROR,
 3527                          replica['replica_state'])
 3528 
 3529     def test_create_replicated_snapshot(self):
 3530         fake_replica_3 = copy.deepcopy(self.fake_replica_2)
 3531         fake_replica_3['id'] = fake.SHARE_ID3
 3532         replica_list = [self.fake_replica, self.fake_replica_2, fake_replica_3]
 3533         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 3534         fake_snapshot['share_id'] = self.fake_replica['id']
 3535         fake_snapshot_2 = copy.deepcopy(fake.SNAPSHOT)
 3536         fake_snapshot_2['id'] = uuidutils.generate_uuid()
 3537         fake_snapshot_2['share_id'] = self.fake_replica_2['id']
 3538         fake_snapshot_3 = copy.deepcopy(fake.SNAPSHOT)
 3539         fake_snapshot_3['id'] = uuidutils.generate_uuid()
 3540         fake_snapshot_3['share_id'] = fake_replica_3['id']
 3541         snapshot_list = [fake_snapshot, fake_snapshot_2, fake_snapshot_3]
 3542 
 3543         vserver_client = mock.Mock()
 3544         self.mock_object(self.library,
 3545                          '_get_vserver',
 3546                          mock.Mock(return_value=(fake.VSERVER1,
 3547                                                  vserver_client)))
 3548 
 3549         model_list = self.library.create_replicated_snapshot(
 3550             self.context, replica_list, snapshot_list,
 3551             share_server=fake.SHARE_SERVER)
 3552 
 3553         share_name = self.library._get_backend_share_name(
 3554             fake_snapshot['share_id'])
 3555         snapshot_name = self.library._get_backend_snapshot_name(
 3556             fake_snapshot['id'])
 3557         vserver_client.create_snapshot.assert_called_once_with(share_name,
 3558                                                                snapshot_name)
 3559         self.assertEqual(3, len(model_list))
 3560         for snapshot in model_list:
 3561             self.assertEqual(snapshot['provider_location'], snapshot_name)
 3562         actual_active_snapshot = list(filter(
 3563             lambda x: x['id'] == fake_snapshot['id'], model_list))[0]
 3564         self.assertEqual(constants.STATUS_AVAILABLE,
 3565                          actual_active_snapshot['status'])
 3566         actual_non_active_snapshot_list = list(filter(
 3567             lambda x: x['id'] != fake_snapshot['id'], model_list))
 3568         for snapshot in actual_non_active_snapshot_list:
 3569             self.assertEqual(constants.STATUS_CREATING, snapshot['status'])
 3570         self.mock_dm_session.update_snapmirror.assert_has_calls(
 3571             [mock.call(self.fake_replica, self.fake_replica_2),
 3572              mock.call(self.fake_replica, fake_replica_3)],
 3573             any_order=True
 3574         )
 3575 
 3576     def test_create_replicated_snapshot_with_creating_replica(self):
 3577         fake_replica_3 = copy.deepcopy(self.fake_replica_2)
 3578         fake_replica_3['id'] = fake.SHARE_ID3
 3579         fake_replica_3['host'] = None
 3580         replica_list = [self.fake_replica, self.fake_replica_2, fake_replica_3]
 3581         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 3582         fake_snapshot['share_id'] = self.fake_replica['id']
 3583         fake_snapshot_2 = copy.deepcopy(fake.SNAPSHOT)
 3584         fake_snapshot_2['id'] = uuidutils.generate_uuid()
 3585         fake_snapshot_2['share_id'] = self.fake_replica_2['id']
 3586         fake_snapshot_3 = copy.deepcopy(fake.SNAPSHOT)
 3587         fake_snapshot_3['id'] = uuidutils.generate_uuid()
 3588         fake_snapshot_3['share_id'] = fake_replica_3['id']
 3589         snapshot_list = [fake_snapshot, fake_snapshot_2, fake_snapshot_3]
 3590 
 3591         vserver_client = mock.Mock()
 3592         self.mock_object(self.library,
 3593                          '_get_vserver',
 3594                          mock.Mock(return_value=(fake.VSERVER1,
 3595                                                  vserver_client)))
 3596 
 3597         model_list = self.library.create_replicated_snapshot(
 3598             self.context, replica_list, snapshot_list,
 3599             share_server=fake.SHARE_SERVER)
 3600 
 3601         share_name = self.library._get_backend_share_name(
 3602             fake_snapshot['share_id'])
 3603         snapshot_name = self.library._get_backend_snapshot_name(
 3604             fake_snapshot['id'])
 3605         vserver_client.create_snapshot.assert_called_once_with(share_name,
 3606                                                                snapshot_name)
 3607         self.assertEqual(3, len(model_list))
 3608         for snapshot in model_list:
 3609             self.assertEqual(snapshot['provider_location'], snapshot_name)
 3610         actual_active_snapshot = list(filter(
 3611             lambda x: x['id'] == fake_snapshot['id'], model_list))[0]
 3612         self.assertEqual(constants.STATUS_AVAILABLE,
 3613                          actual_active_snapshot['status'])
 3614         actual_non_active_snapshot_list = list(filter(
 3615             lambda x: x['id'] != fake_snapshot['id'], model_list))
 3616         for snapshot in actual_non_active_snapshot_list:
 3617             self.assertEqual(constants.STATUS_CREATING, snapshot['status'])
 3618         self.mock_dm_session.update_snapmirror.assert_has_calls(
 3619             [mock.call(self.fake_replica, self.fake_replica_2)],
 3620             any_order=True
 3621         )
 3622 
 3623     def test_create_replicated_snapshot_no_snapmirror(self):
 3624         self.mock_dm_session.update_snapmirror.side_effect = [
 3625             None,
 3626             netapp_api.NaApiError(code=netapp_api.EOBJECTNOTFOUND)
 3627         ]
 3628         fake_replica_3 = copy.deepcopy(self.fake_replica_2)
 3629         fake_replica_3['id'] = fake.SHARE_ID3
 3630         replica_list = [self.fake_replica, self.fake_replica_2, fake_replica_3]
 3631         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 3632         fake_snapshot['share_id'] = self.fake_replica['id']
 3633         fake_snapshot_2 = copy.deepcopy(fake.SNAPSHOT)
 3634         fake_snapshot_2['id'] = uuidutils.generate_uuid()
 3635         fake_snapshot_2['share_id'] = self.fake_replica_2['id']
 3636         fake_snapshot_3 = copy.deepcopy(fake.SNAPSHOT)
 3637         fake_snapshot_3['id'] = uuidutils.generate_uuid()
 3638         fake_snapshot_3['share_id'] = fake_replica_3['id']
 3639         snapshot_list = [fake_snapshot, fake_snapshot_2, fake_snapshot_3]
 3640 
 3641         vserver_client = mock.Mock()
 3642         self.mock_object(self.library,
 3643                          '_get_vserver',
 3644                          mock.Mock(return_value=(fake.VSERVER1,
 3645                                                  vserver_client)))
 3646 
 3647         model_list = self.library.create_replicated_snapshot(
 3648             self.context, replica_list, snapshot_list,
 3649             share_server=fake.SHARE_SERVER)
 3650 
 3651         share_name = self.library._get_backend_share_name(
 3652             fake_snapshot['share_id'])
 3653         snapshot_name = self.library._get_backend_snapshot_name(
 3654             fake_snapshot['id'])
 3655         vserver_client.create_snapshot.assert_called_once_with(share_name,
 3656                                                                snapshot_name)
 3657         self.assertEqual(3, len(model_list))
 3658         for snapshot in model_list:
 3659             self.assertEqual(snapshot['provider_location'], snapshot_name)
 3660         actual_active_snapshot = list(filter(
 3661             lambda x: x['id'] == fake_snapshot['id'], model_list))[0]
 3662         self.assertEqual(constants.STATUS_AVAILABLE,
 3663                          actual_active_snapshot['status'])
 3664         actual_non_active_snapshot_list = list(filter(
 3665             lambda x: x['id'] != fake_snapshot['id'], model_list))
 3666         for snapshot in actual_non_active_snapshot_list:
 3667             self.assertEqual(constants.STATUS_CREATING, snapshot['status'])
 3668         self.mock_dm_session.update_snapmirror.assert_has_calls(
 3669             [mock.call(self.fake_replica, self.fake_replica_2),
 3670              mock.call(self.fake_replica, fake_replica_3)],
 3671             any_order=True
 3672         )
 3673 
 3674     def test_create_replicated_snapshot_update_error(self):
 3675         self.mock_dm_session.update_snapmirror.side_effect = [
 3676             None,
 3677             netapp_api.NaApiError()
 3678         ]
 3679         fake_replica_3 = copy.deepcopy(self.fake_replica_2)
 3680         fake_replica_3['id'] = fake.SHARE_ID3
 3681         replica_list = [self.fake_replica, self.fake_replica_2, fake_replica_3]
 3682         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 3683         fake_snapshot['share_id'] = self.fake_replica['id']
 3684         fake_snapshot_2 = copy.deepcopy(fake.SNAPSHOT)
 3685         fake_snapshot_2['id'] = uuidutils.generate_uuid()
 3686         fake_snapshot_2['share_id'] = self.fake_replica_2['id']
 3687         fake_snapshot_3 = copy.deepcopy(fake.SNAPSHOT)
 3688         fake_snapshot_3['id'] = uuidutils.generate_uuid()
 3689         fake_snapshot_3['share_id'] = fake_replica_3['id']
 3690         snapshot_list = [fake_snapshot, fake_snapshot_2, fake_snapshot_3]
 3691 
 3692         vserver_client = mock.Mock()
 3693         self.mock_object(self.library,
 3694                          '_get_vserver',
 3695                          mock.Mock(return_value=(fake.VSERVER1,
 3696                                                  vserver_client)))
 3697 
 3698         self.assertRaises(netapp_api.NaApiError,
 3699                           self.library.create_replicated_snapshot,
 3700                           self.context, replica_list, snapshot_list,
 3701                           share_server=fake.SHARE_SERVER)
 3702 
 3703     def test_delete_replicated_snapshot(self):
 3704         fake_replica_3 = copy.deepcopy(self.fake_replica_2)
 3705         fake_replica_3['id'] = fake.SHARE_ID3
 3706         replica_list = [self.fake_replica, self.fake_replica_2, fake_replica_3]
 3707         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 3708         fake_snapshot['share_id'] = self.fake_replica['id']
 3709         share_name = self.library._get_backend_share_name(
 3710             fake_snapshot['share_id'])
 3711         snapshot_name = self.library._get_backend_snapshot_name(
 3712             fake_snapshot['id'])
 3713         fake_snapshot['provider_location'] = snapshot_name
 3714         fake_snapshot_2 = copy.deepcopy(fake.SNAPSHOT)
 3715         fake_snapshot_2['id'] = uuidutils.generate_uuid()
 3716         fake_snapshot_2['share_id'] = self.fake_replica_2['id']
 3717         fake_snapshot_2['provider_location'] = snapshot_name
 3718         fake_snapshot_3 = copy.deepcopy(fake.SNAPSHOT)
 3719         fake_snapshot_3['id'] = uuidutils.generate_uuid()
 3720         fake_snapshot_3['share_id'] = fake_replica_3['id']
 3721         fake_snapshot_3['provider_location'] = snapshot_name
 3722 
 3723         snapshot_list = [fake_snapshot, fake_snapshot_2, fake_snapshot_3]
 3724 
 3725         vserver_client = mock.Mock()
 3726         vserver_client.get_snapshot.return_value = fake.CDOT_SNAPSHOT
 3727         self.mock_object(self.library,
 3728                          '_get_vserver',
 3729                          mock.Mock(return_value=(fake.VSERVER1,
 3730                                                  vserver_client)))
 3731 
 3732         self.library.delete_replicated_snapshot(
 3733             self.context, replica_list, snapshot_list,
 3734             share_server=fake.SHARE_SERVER)
 3735 
 3736         vserver_client.delete_snapshot.assert_called_once_with(share_name,
 3737                                                                snapshot_name)
 3738 
 3739         self.mock_dm_session.update_snapmirror.assert_has_calls(
 3740             [mock.call(self.fake_replica, self.fake_replica_2),
 3741              mock.call(self.fake_replica, fake_replica_3)],
 3742             any_order=True
 3743         )
 3744 
 3745     def test_delete_replicated_snapshot_replica_still_creating(self):
 3746         fake_replica_3 = copy.deepcopy(self.fake_replica_2)
 3747         fake_replica_3['id'] = fake.SHARE_ID3
 3748         fake_replica_3['host'] = None
 3749         replica_list = [self.fake_replica, self.fake_replica_2, fake_replica_3]
 3750         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 3751         fake_snapshot['share_id'] = self.fake_replica['id']
 3752         share_name = self.library._get_backend_share_name(
 3753             fake_snapshot['share_id'])
 3754         snapshot_name = self.library._get_backend_snapshot_name(
 3755             fake_snapshot['id'])
 3756         fake_snapshot['provider_location'] = snapshot_name
 3757         fake_snapshot_2 = copy.deepcopy(fake.SNAPSHOT)
 3758         fake_snapshot_2['id'] = uuidutils.generate_uuid()
 3759         fake_snapshot_2['share_id'] = self.fake_replica_2['id']
 3760         fake_snapshot_2['provider_location'] = snapshot_name
 3761         fake_snapshot_3 = copy.deepcopy(fake.SNAPSHOT)
 3762         fake_snapshot_3['id'] = uuidutils.generate_uuid()
 3763         fake_snapshot_3['share_id'] = fake_replica_3['id']
 3764         fake_snapshot_3['provider_location'] = snapshot_name
 3765 
 3766         snapshot_list = [fake_snapshot, fake_snapshot_2, fake_snapshot_3]
 3767 
 3768         vserver_client = mock.Mock()
 3769         vserver_client.get_snapshot.return_value = fake.CDOT_SNAPSHOT
 3770         self.mock_object(self.library,
 3771                          '_get_vserver',
 3772                          mock.Mock(return_value=(fake.VSERVER1,
 3773                                                  vserver_client)))
 3774 
 3775         self.library.delete_replicated_snapshot(
 3776             self.context, replica_list, snapshot_list,
 3777             share_server=fake.SHARE_SERVER)
 3778 
 3779         vserver_client.delete_snapshot.assert_called_once_with(share_name,
 3780                                                                snapshot_name)
 3781 
 3782         self.mock_dm_session.update_snapmirror.assert_has_calls(
 3783             [mock.call(self.fake_replica, self.fake_replica_2)],
 3784             any_order=True
 3785         )
 3786 
 3787     def test_delete_replicated_snapshot_missing_snapmirror(self):
 3788         self.mock_dm_session.update_snapmirror.side_effect = [
 3789             None,
 3790             netapp_api.NaApiError(code=netapp_api.EOBJECTNOTFOUND)
 3791         ]
 3792         fake_replica_3 = copy.deepcopy(self.fake_replica_2)
 3793         fake_replica_3['id'] = fake.SHARE_ID3
 3794         replica_list = [self.fake_replica, self.fake_replica_2, fake_replica_3]
 3795         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 3796         fake_snapshot['share_id'] = self.fake_replica['id']
 3797         share_name = self.library._get_backend_share_name(
 3798             fake_snapshot['share_id'])
 3799         snapshot_name = self.library._get_backend_snapshot_name(
 3800             fake_snapshot['id'])
 3801         fake_snapshot['provider_location'] = snapshot_name
 3802         fake_snapshot['busy'] = False
 3803 
 3804         fake_snapshot_2 = copy.deepcopy(fake.SNAPSHOT)
 3805         fake_snapshot_2['id'] = uuidutils.generate_uuid()
 3806         fake_snapshot_2['share_id'] = self.fake_replica_2['id']
 3807         fake_snapshot_2['provider_location'] = snapshot_name
 3808         fake_snapshot_3 = copy.deepcopy(fake.SNAPSHOT)
 3809         fake_snapshot_3['id'] = uuidutils.generate_uuid()
 3810         fake_snapshot_3['share_id'] = fake_replica_3['id']
 3811         fake_snapshot_3['provider_location'] = snapshot_name
 3812 
 3813         snapshot_list = [fake_snapshot, fake_snapshot_2, fake_snapshot_3]
 3814 
 3815         vserver_client = mock.Mock()
 3816         vserver_client.get_snapshot.return_value = fake_snapshot
 3817         self.mock_object(self.library,
 3818                          '_get_vserver',
 3819                          mock.Mock(return_value=(fake.VSERVER1,
 3820                                                  vserver_client)))
 3821 
 3822         self.library.delete_replicated_snapshot(
 3823             self.context, replica_list, snapshot_list,
 3824             share_server=fake.SHARE_SERVER)
 3825 
 3826         vserver_client.delete_snapshot.assert_called_once_with(share_name,
 3827                                                                snapshot_name)
 3828 
 3829         self.mock_dm_session.update_snapmirror.assert_has_calls(
 3830             [mock.call(self.fake_replica, self.fake_replica_2),
 3831              mock.call(self.fake_replica, fake_replica_3)],
 3832             any_order=True
 3833         )
 3834 
 3835     def test_delete_replicated_snapshot_update_error(self):
 3836         self.mock_dm_session.update_snapmirror.side_effect = [
 3837             None,
 3838             netapp_api.NaApiError()
 3839         ]
 3840         fake_replica_3 = copy.deepcopy(self.fake_replica_2)
 3841         fake_replica_3['id'] = fake.SHARE_ID3
 3842         replica_list = [self.fake_replica, self.fake_replica_2, fake_replica_3]
 3843         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 3844         fake_snapshot['share_id'] = self.fake_replica['id']
 3845         snapshot_name = self.library._get_backend_snapshot_name(
 3846             fake_snapshot['id'])
 3847         fake_snapshot['provider_location'] = snapshot_name
 3848         fake_snapshot['busy'] = False
 3849 
 3850         fake_snapshot_2 = copy.deepcopy(fake.SNAPSHOT)
 3851         fake_snapshot_2['id'] = uuidutils.generate_uuid()
 3852         fake_snapshot_2['share_id'] = self.fake_replica_2['id']
 3853         fake_snapshot_2['provider_location'] = snapshot_name
 3854         fake_snapshot_3 = copy.deepcopy(fake.SNAPSHOT)
 3855         fake_snapshot_3['id'] = uuidutils.generate_uuid()
 3856         fake_snapshot_3['share_id'] = fake_replica_3['id']
 3857         fake_snapshot_3['provider_location'] = snapshot_name
 3858 
 3859         snapshot_list = [fake_snapshot, fake_snapshot_2, fake_snapshot_3]
 3860 
 3861         vserver_client = mock.Mock()
 3862         vserver_client.get_snapshot.return_value = fake_snapshot
 3863         self.mock_object(self.library,
 3864                          '_get_vserver',
 3865                          mock.Mock(return_value=(fake.VSERVER1,
 3866                                                  vserver_client)))
 3867 
 3868         self.assertRaises(netapp_api.NaApiError,
 3869                           self.library.delete_replicated_snapshot,
 3870                           self.context, replica_list, snapshot_list,
 3871                           share_server=fake.SHARE_SERVER)
 3872 
 3873     def test_update_replicated_snapshot_still_creating(self):
 3874         vserver_client = mock.Mock()
 3875         vserver_client.snapshot_exists.return_value = False
 3876         self.mock_object(self.library,
 3877                          '_get_vserver',
 3878                          mock.Mock(return_value=(fake.VSERVER1,
 3879                                                  vserver_client)))
 3880         replica_list = [self.fake_replica, self.fake_replica_2]
 3881         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 3882         fake_snapshot['status'] = constants.STATUS_CREATING
 3883         fake_snapshot['share_id'] = self.fake_replica_2['id']
 3884         snapshot_name = self.library._get_backend_snapshot_name(
 3885             fake_snapshot['id'])
 3886         fake_snapshot['provider_location'] = snapshot_name
 3887 
 3888         model_update = self.library.update_replicated_snapshot(
 3889             replica_list, self.fake_replica_2, [fake_snapshot], fake_snapshot)
 3890 
 3891         self.assertIsNone(model_update)
 3892         self.mock_dm_session.update_snapmirror.assert_called_once_with(
 3893             self.fake_replica, self.fake_replica_2
 3894         )
 3895 
 3896     def test_update_replicated_snapshot_still_creating_no_host(self):
 3897         self.fake_replica_2['host'] = None
 3898         vserver_client = mock.Mock()
 3899         vserver_client.snapshot_exists.return_value = False
 3900         self.mock_object(self.library,
 3901                          '_get_vserver',
 3902                          mock.Mock(return_value=(fake.VSERVER1,
 3903                                                  vserver_client)))
 3904         replica_list = [self.fake_replica, self.fake_replica_2]
 3905         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 3906         fake_snapshot['status'] = constants.STATUS_CREATING
 3907         fake_snapshot['share_id'] = self.fake_replica_2['id']
 3908         snapshot_name = self.library._get_backend_snapshot_name(
 3909             fake_snapshot['id'])
 3910         fake_snapshot['provider_location'] = snapshot_name
 3911 
 3912         model_update = self.library.update_replicated_snapshot(
 3913             replica_list, self.fake_replica_2, [fake_snapshot], fake_snapshot)
 3914 
 3915         self.assertIsNone(model_update)
 3916         self.mock_dm_session.update_snapmirror.assert_called_once_with(
 3917             self.fake_replica, self.fake_replica_2
 3918         )
 3919 
 3920     def test_update_replicated_snapshot_no_snapmirror(self):
 3921         vserver_client = mock.Mock()
 3922         vserver_client.snapshot_exists.return_value = False
 3923         self.mock_dm_session.update_snapmirror.side_effect = (
 3924             netapp_api.NaApiError(code=netapp_api.EOBJECTNOTFOUND)
 3925         )
 3926         self.mock_object(self.library,
 3927                          '_get_vserver',
 3928                          mock.Mock(return_value=(fake.VSERVER1,
 3929                                                  vserver_client)))
 3930         replica_list = [self.fake_replica, self.fake_replica_2]
 3931         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 3932         fake_snapshot['status'] = constants.STATUS_CREATING
 3933         fake_snapshot['share_id'] = self.fake_replica_2['id']
 3934         snapshot_name = self.library._get_backend_snapshot_name(
 3935             fake_snapshot['id'])
 3936         fake_snapshot['provider_location'] = snapshot_name
 3937 
 3938         model_update = self.library.update_replicated_snapshot(
 3939             replica_list, self.fake_replica_2, [fake_snapshot], fake_snapshot)
 3940 
 3941         self.assertIsNone(model_update)
 3942         self.mock_dm_session.update_snapmirror.assert_called_once_with(
 3943             self.fake_replica, self.fake_replica_2
 3944         )
 3945 
 3946     def test_update_replicated_snapshot_update_error(self):
 3947         vserver_client = mock.Mock()
 3948         vserver_client.snapshot_exists.return_value = False
 3949         self.mock_dm_session.update_snapmirror.side_effect = (
 3950             netapp_api.NaApiError()
 3951         )
 3952         self.mock_object(self.library,
 3953                          '_get_vserver',
 3954                          mock.Mock(return_value=(fake.VSERVER1,
 3955                                                  vserver_client)))
 3956         replica_list = [self.fake_replica, self.fake_replica_2]
 3957         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 3958         fake_snapshot['status'] = constants.STATUS_CREATING
 3959         fake_snapshot['share_id'] = self.fake_replica_2['id']
 3960         snapshot_name = self.library._get_backend_snapshot_name(
 3961             fake_snapshot['id'])
 3962         fake_snapshot['provider_location'] = snapshot_name
 3963 
 3964         self.assertRaises(netapp_api.NaApiError,
 3965                           self.library.update_replicated_snapshot,
 3966                           replica_list, self.fake_replica_2,
 3967                           [fake_snapshot], fake_snapshot)
 3968 
 3969     def test_update_replicated_snapshot_still_deleting(self):
 3970         vserver_client = mock.Mock()
 3971         vserver_client.snapshot_exists.return_value = True
 3972         vserver_client.get_snapshot.return_value = fake.CDOT_SNAPSHOT
 3973         self.mock_object(self.library,
 3974                          '_get_vserver',
 3975                          mock.Mock(return_value=(fake.VSERVER1,
 3976                                                  vserver_client)))
 3977 
 3978         replica_list = [self.fake_replica]
 3979         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 3980         fake_snapshot['status'] = constants.STATUS_DELETING
 3981         fake_snapshot['share_id'] = self.fake_replica['id']
 3982         snapshot_name = self.library._get_backend_snapshot_name(
 3983             fake_snapshot['id'])
 3984         fake_snapshot['provider_location'] = snapshot_name
 3985 
 3986         model_update = self.library.update_replicated_snapshot(
 3987             replica_list, self.fake_replica, [fake_snapshot], fake_snapshot)
 3988 
 3989         self.assertIsNone(model_update)
 3990 
 3991     def test_update_replicated_snapshot_created(self):
 3992         vserver_client = mock.Mock()
 3993         vserver_client.snapshot_exists.return_value = True
 3994         self.mock_object(self.library,
 3995                          '_get_vserver',
 3996                          mock.Mock(return_value=(fake.VSERVER1,
 3997                                                  vserver_client)))
 3998         replica_list = [self.fake_replica]
 3999         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 4000         fake_snapshot['status'] = constants.STATUS_CREATING
 4001         fake_snapshot['share_id'] = self.fake_replica['id']
 4002         snapshot_name = self.library._get_backend_snapshot_name(
 4003             fake_snapshot['id'])
 4004         fake_snapshot['provider_location'] = snapshot_name
 4005 
 4006         model_update = self.library.update_replicated_snapshot(
 4007             replica_list, self.fake_replica, [fake_snapshot], fake_snapshot)
 4008 
 4009         self.assertEqual(constants.STATUS_AVAILABLE, model_update['status'])
 4010         self.assertEqual(snapshot_name, model_update['provider_location'])
 4011 
 4012     def test_update_replicated_snapshot_created_no_provider_location(self):
 4013         vserver_client = mock.Mock()
 4014         vserver_client.snapshot_exists.return_value = True
 4015         self.mock_object(self.library,
 4016                          '_get_vserver',
 4017                          mock.Mock(return_value=(fake.VSERVER1,
 4018                                                  vserver_client)))
 4019         replica_list = [self.fake_replica, self.fake_replica_2]
 4020         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 4021         fake_snapshot['status'] = constants.STATUS_ACTIVE
 4022         fake_snapshot['share_id'] = self.fake_replica['id']
 4023         snapshot_name = self.library._get_backend_snapshot_name(
 4024             fake_snapshot['id'])
 4025         fake_snapshot['provider_location'] = snapshot_name
 4026         fake_snapshot_2 = copy.deepcopy(fake.SNAPSHOT)
 4027         fake_snapshot_2['status'] = constants.STATUS_CREATING
 4028         fake_snapshot_2['share_id'] = self.fake_replica_2['id']
 4029 
 4030         model_update = self.library.update_replicated_snapshot(
 4031             replica_list, self.fake_replica_2,
 4032             [fake_snapshot, fake_snapshot_2], fake_snapshot_2)
 4033 
 4034         self.assertEqual(constants.STATUS_AVAILABLE, model_update['status'])
 4035         self.assertEqual(snapshot_name, model_update['provider_location'])
 4036 
 4037     def test_update_replicated_snapshot_deleted(self):
 4038         vserver_client = mock.Mock()
 4039         vserver_client.snapshot_exists.return_value = False
 4040         self.mock_object(self.library,
 4041                          '_get_vserver',
 4042                          mock.Mock(return_value=(fake.VSERVER1,
 4043                                                  vserver_client)))
 4044         replica_list = [self.fake_replica]
 4045         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 4046         fake_snapshot['status'] = constants.STATUS_DELETING
 4047         fake_snapshot['share_id'] = self.fake_replica['id']
 4048         snapshot_name = self.library._get_backend_snapshot_name(
 4049             fake_snapshot['id'])
 4050         fake_snapshot['provider_location'] = snapshot_name
 4051 
 4052         self.assertRaises(exception.SnapshotResourceNotFound,
 4053                           self.library.update_replicated_snapshot,
 4054                           replica_list, self.fake_replica, [fake_snapshot],
 4055                           fake_snapshot)
 4056 
 4057     def test_update_replicated_snapshot_no_provider_locations(self):
 4058         vserver_client = mock.Mock()
 4059         vserver_client.snapshot_exists.return_value = True
 4060         self.mock_object(self.library,
 4061                          '_get_vserver',
 4062                          mock.Mock(return_value=(fake.VSERVER1,
 4063                                                  vserver_client)))
 4064         replica_list = [self.fake_replica]
 4065         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 4066         fake_snapshot['status'] = constants.STATUS_CREATING
 4067         fake_snapshot['share_id'] = self.fake_replica['id']
 4068         fake_snapshot['provider_location'] = None
 4069 
 4070         model_update = self.library.update_replicated_snapshot(
 4071             replica_list, self.fake_replica, [fake_snapshot], fake_snapshot)
 4072 
 4073         self.assertIsNone(model_update)
 4074 
 4075     def _get_fake_replicas_and_snapshots(self):
 4076 
 4077         fake_replica_3 = copy.deepcopy(self.fake_replica_2)
 4078         fake_replica_3['id'] = fake.SHARE_ID3
 4079         fake_snapshot = copy.deepcopy(fake.SNAPSHOT)
 4080         fake_snapshot['share_id'] = self.fake_replica['id']
 4081         snapshot_name = self.library._get_backend_snapshot_name(
 4082             fake_snapshot['id'])
 4083         fake_snapshot['provider_location'] = snapshot_name
 4084         fake_snapshot_2 = copy.deepcopy(fake.SNAPSHOT)
 4085         fake_snapshot_2['id'] = uuidutils.generate_uuid()
 4086         fake_snapshot_2['share_id'] = self.fake_replica_2['id']
 4087         fake_snapshot_2['provider_location'] = snapshot_name
 4088         fake_snapshot_3 = copy.deepcopy(fake.SNAPSHOT)
 4089         fake_snapshot_3['id'] = uuidutils.generate_uuid()
 4090         fake_snapshot_3['share_id'] = fake_replica_3['id']
 4091         fake_snapshot_3['provider_location'] = snapshot_name
 4092         replica_list = [self.fake_replica, self.fake_replica_2, fake_replica_3]
 4093         snapshot_list = [fake_snapshot, fake_snapshot_2, fake_snapshot_3]
 4094         return replica_list, snapshot_list
 4095 
 4096     @ddt.data(True, False)
 4097     def test_revert_to_replicated_snapshot(self, use_snap_provider_location):
 4098 
 4099         replica_list, snapshot_list = self._get_fake_replicas_and_snapshots()
 4100         fake_replica, fake_replica_2, fake_replica_3 = replica_list
 4101         fake_snapshot, fake_snapshot_2, fake_snapshot_3 = snapshot_list
 4102 
 4103         if not use_snap_provider_location:
 4104             del fake_snapshot['provider_location']
 4105             del fake_snapshot_2['provider_location']
 4106             del fake_snapshot_3['provider_location']
 4107 
 4108         share_name = self.library._get_backend_share_name(
 4109             fake_snapshot['share_id'])
 4110         snapshot_name = self.library._get_backend_snapshot_name(
 4111             fake_snapshot['id'])
 4112 
 4113         vserver_client = mock.Mock()
 4114         vserver_client.get_snapshot.return_value = fake.CDOT_SNAPSHOT
 4115         vserver_client.list_snapmirror_snapshots.return_value = ['sm_snap']
 4116         self.mock_object(self.library,
 4117                          '_get_vserver',
 4118                          mock.Mock(return_value=(fake.VSERVER1,
 4119                                                  vserver_client)))
 4120 
 4121         self.library.revert_to_replicated_snapshot(
 4122             self.context, self.fake_replica, replica_list, fake_snapshot,
 4123             snapshot_list, share_server=fake.SHARE_SERVER)
 4124 
 4125         vserver_client.get_snapshot.assert_called_once_with(
 4126             share_name, snapshot_name)
 4127         vserver_client.list_snapmirror_snapshots.assert_called_once_with(
 4128             share_name)
 4129         vserver_client.delete_snapshot.assert_called_once_with(
 4130             share_name, 'sm_snap', ignore_owners=True)
 4131         vserver_client.restore_snapshot.assert_called_once_with(
 4132             share_name, snapshot_name)
 4133 
 4134         self.mock_dm_session.break_snapmirror.assert_has_calls(
 4135             [mock.call(self.fake_replica, self.fake_replica_2, mount=False),
 4136              mock.call(self.fake_replica, fake_replica_3, mount=False)],
 4137             any_order=True)
 4138         self.mock_dm_session.resync_snapmirror.assert_has_calls(
 4139             [mock.call(self.fake_replica, self.fake_replica_2),
 4140              mock.call(self.fake_replica, fake_replica_3)],
 4141             any_order=True)
 4142 
 4143     def test_revert_to_replicated_snapshot_not_found(self):
 4144 
 4145         replica_list, snapshot_list = self._get_fake_replicas_and_snapshots()
 4146         fake_snapshot, fake_snapshot_2, fake_snapshot_3 = snapshot_list
 4147         share_name = self.library._get_backend_share_name(
 4148             fake_snapshot['share_id'])
 4149         snapshot_name = self.library._get_backend_snapshot_name(
 4150             fake_snapshot['id'])
 4151 
 4152         vserver_client = mock.Mock()
 4153         vserver_client.get_snapshot.side_effect = netapp_api.NaApiError
 4154         vserver_client.list_snapmirror_snapshots.return_value = ['sm_snap']
 4155         self.mock_object(self.library,
 4156                          '_get_vserver',
 4157                          mock.Mock(return_value=(fake.VSERVER1,
 4158                                                  vserver_client)))
 4159 
 4160         self.assertRaises(
 4161             netapp_api.NaApiError, 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         self.assertFalse(vserver_client.list_snapmirror_snapshots.called)
 4168         self.assertFalse(vserver_client.delete_snapshot.called)
 4169         self.assertFalse(vserver_client.restore_snapshot.called)
 4170         self.assertFalse(self.mock_dm_session.break_snapmirror.called)
 4171         self.assertFalse(self.mock_dm_session.resync_snapmirror.called)
 4172 
 4173     def test_revert_to_replicated_snapshot_snapmirror_break_error(self):
 4174 
 4175         replica_list, snapshot_list = self._get_fake_replicas_and_snapshots()
 4176         fake_snapshot, fake_snapshot_2, fake_snapshot_3 = snapshot_list
 4177 
 4178         vserver_client = mock.Mock()
 4179         vserver_client.get_snapshot.return_value = fake.CDOT_SNAPSHOT
 4180         vserver_client.list_snapmirror_snapshots.return_value = ['sm_snap']
 4181         self.mock_object(self.library,
 4182                          '_get_vserver',
 4183                          mock.Mock(return_value=(fake.VSERVER1,
 4184                                                  vserver_client)))
 4185         self.mock_dm_session.break_snapmirror.side_effect = (
 4186             netapp_api.NaApiError)
 4187 
 4188         self.assertRaises(
 4189             netapp_api.NaApiError, self.library.revert_to_replicated_snapshot,
 4190             self.context, self.fake_replica, replica_list, fake_snapshot,
 4191             snapshot_list, share_server=fake.SHARE_SERVER)
 4192 
 4193     def test_revert_to_replicated_snapshot_snapmirror_break_not_found(self):
 4194 
 4195         replica_list, snapshot_list = self._get_fake_replicas_and_snapshots()
 4196         fake_replica, fake_replica_2, fake_replica_3 = replica_list
 4197         fake_snapshot, fake_snapshot_2, fake_snapshot_3 = snapshot_list
 4198         share_name = self.library._get_backend_share_name(
 4199             fake_snapshot['share_id'])
 4200         snapshot_name = self.library._get_backend_snapshot_name(
 4201             fake_snapshot['id'])
 4202 
 4203         vserver_client = mock.Mock()
 4204         vserver_client.get_snapshot.return_value = fake.CDOT_SNAPSHOT
 4205         vserver_client.list_snapmirror_snapshots.return_value = ['sm_snap']
 4206         self.mock_object(self.library,
 4207                          '_get_vserver',
 4208                          mock.Mock(return_value=(fake.VSERVER1,
 4209                                                  vserver_client)))
 4210         self.mock_dm_session.break_snapmirror.side_effect = (
 4211             netapp_api.NaApiError(code=netapp_api.EOBJECTNOTFOUND))
 4212 
 4213         self.library.revert_to_replicated_snapshot(
 4214             self.context, self.fake_replica, replica_list, fake_snapshot,
 4215             snapshot_list, share_server=fake.SHARE_SERVER)
 4216 
 4217         vserver_client.get_snapshot.assert_called_once_with(
 4218             share_name, snapshot_name)
 4219         vserver_client.list_snapmirror_snapshots.assert_called_once_with(
 4220             share_name)
 4221         vserver_client.delete_snapshot.assert_called_once_with(
 4222             share_name, 'sm_snap', ignore_owners=True)
 4223         vserver_client.restore_snapshot.assert_called_once_with(
 4224             share_name, snapshot_name)
 4225 
 4226         self.mock_dm_session.break_snapmirror.assert_has_calls(
 4227             [mock.call(self.fake_replica, self.fake_replica_2, mount=False),
 4228              mock.call(self.fake_replica, fake_replica_3, mount=False)],
 4229             any_order=True)
 4230         self.mock_dm_session.resync_snapmirror.assert_has_calls(
 4231             [mock.call(self.fake_replica, self.fake_replica_2),
 4232              mock.call(self.fake_replica, fake_replica_3)],
 4233             any_order=True)
 4234 
 4235     def test_revert_to_replicated_snapshot_snapmirror_resync_error(self):
 4236 
 4237         replica_list, snapshot_list = self._get_fake_replicas_and_snapshots()
 4238         fake_snapshot, fake_snapshot_2, fake_snapshot_3 = snapshot_list
 4239 
 4240         vserver_client = mock.Mock()
 4241         vserver_client.get_snapshot.return_value = fake.CDOT_SNAPSHOT
 4242         vserver_client.list_snapmirror_snapshots.return_value = ['sm_snap']
 4243         self.mock_object(self.library,
 4244                          '_get_vserver',
 4245                          mock.Mock(return_value=(fake.VSERVER1,
 4246                                                  vserver_client)))
 4247         self.mock_dm_session.resync_snapmirror.side_effect = (
 4248             netapp_api.NaApiError)
 4249 
 4250         self.assertRaises(
 4251             netapp_api.NaApiError, self.library.revert_to_replicated_snapshot,
 4252             self.context, self.fake_replica, replica_list, fake_snapshot,
 4253             snapshot_list, share_server=fake.SHARE_SERVER)
 4254 
 4255     def test_revert_to_replicated_snapshot_snapmirror_resync_not_found(self):
 4256 
 4257         replica_list, snapshot_list = self._get_fake_replicas_and_snapshots()
 4258         fake_replica, fake_replica_2, fake_replica_3 = replica_list
 4259         fake_snapshot, fake_snapshot_2, fake_snapshot_3 = snapshot_list
 4260         share_name = self.library._get_backend_share_name(
 4261             fake_snapshot['share_id'])
 4262         snapshot_name = self.library._get_backend_snapshot_name(
 4263             fake_snapshot['id'])
 4264 
 4265         vserver_client = mock.Mock()
 4266         vserver_client.get_snapshot.return_value = fake.CDOT_SNAPSHOT
 4267         vserver_client.list_snapmirror_snapshots.return_value = ['sm_snap']
 4268         self.mock_object(self.library,
 4269                          '_get_vserver',
 4270                          mock.Mock(return_value=(fake.VSERVER1,
 4271                                                  vserver_client)))
 4272         self.mock_dm_session.resync_snapmirror.side_effect = (
 4273             netapp_api.NaApiError(code=netapp_api.EOBJECTNOTFOUND))
 4274 
 4275         self.library.revert_to_replicated_snapshot(
 4276             self.context, self.fake_replica, replica_list, fake_snapshot,
 4277             snapshot_list, share_server=fake.SHARE_SERVER)
 4278 
 4279         vserver_client.get_snapshot.assert_called_once_with(
 4280             share_name, snapshot_name)
 4281         vserver_client.list_snapmirror_snapshots.assert_called_once_with(
 4282             share_name)
 4283         vserver_client.delete_snapshot.assert_called_once_with(
 4284             share_name, 'sm_snap', ignore_owners=True)
 4285         vserver_client.restore_snapshot.assert_called_once_with(
 4286             share_name, snapshot_name)
 4287 
 4288         self.mock_dm_session.break_snapmirror.assert_has_calls(
 4289             [mock.call(self.fake_replica, self.fake_replica_2, mount=False),
 4290              mock.call(self.fake_replica, fake_replica_3, mount=False)],
 4291             any_order=True)
 4292         self.mock_dm_session.resync_snapmirror.assert_has_calls(
 4293             [mock.call(self.fake_replica, self.fake_replica_2),
 4294              mock.call(self.fake_replica, fake_replica_3)],
 4295             any_order=True)
 4296 
 4297     def test_migration_check_compatibility_no_cluster_credentials(self):
 4298         self.library._have_cluster_creds = False
 4299         self.mock_object(data_motion, 'get_backend_configuration')
 4300         mock_warning_log = self.mock_object(lib_base.LOG, 'warning')
 4301 
 4302         migration_compatibility = self.library.migration_check_compatibility(
 4303             self.context, fake_share.fake_share_instance(),
 4304             fake_share.fake_share_instance(), share_server=None,
 4305             destination_share_server=fake.SHARE_SERVER)
 4306 
 4307         expected_compatibility = {
 4308             'compatible': False,
 4309             'writable': False,
 4310             'nondisruptive': False,
 4311             'preserve_metadata': False,
 4312             'preserve_snapshots': False,
 4313         }
 4314         self.assertDictMatch(expected_compatibility, migration_compatibility)
 4315         mock_warning_log.assert_called_once()
 4316         self.assertFalse(data_motion.get_backend_configuration.called)
 4317 
 4318     @ddt.data((None, exception.NetAppException),
 4319               (exception.Invalid, None))
 4320     @ddt.unpack
 4321     def test_migration_check_compatibility_extra_specs_invalid(
 4322             self, side_effect_1, side_effect_2):
 4323         self.library._have_cluster_creds = True
 4324         self.mock_object(self.library, '_get_backend_share_name',
 4325                          mock.Mock(return_value=fake.SHARE_NAME))
 4326         mock_exception_log = self.mock_object(lib_base.LOG, 'exception')
 4327         self.mock_object(share_types, 'get_extra_specs_from_share')
 4328         self.mock_object(self.library, '_check_extra_specs_validity',
 4329                          mock.Mock(side_effect=side_effect_1))
 4330         self.mock_object(self.library,
 4331                          '_check_aggregate_extra_specs_validity',
 4332                          mock.Mock(side_effect=side_effect_2))
 4333         self.mock_object(data_motion, 'get_backend_configuration')
 4334 
 4335         migration_compatibility = self.library.migration_check_compatibility(
 4336             self.context, fake_share.fake_share_instance(),
 4337             fake_share.fake_share_instance(), share_server=fake.SHARE_SERVER,
 4338             destination_share_server=None)
 4339 
 4340         expected_compatibility = {
 4341             'compatible': False,
 4342             'writable': False,
 4343             'nondisruptive': False,
 4344             'preserve_metadata': False,
 4345             'preserve_snapshots': False,
 4346         }
 4347         self.assertDictMatch(expected_compatibility, migration_compatibility)
 4348         mock_exception_log.assert_called_once()
 4349         self.assertFalse(data_motion.get_backend_configuration.called)
 4350 
 4351     def test_migration_check_compatibility_destination_not_configured(self):
 4352         self.library._have_cluster_creds = True
 4353         self.mock_object(self.library, '_get_backend_share_name',
 4354                          mock.Mock(return_value=fake.SHARE_NAME))
 4355         self.mock_object(
 4356             data_motion, 'get_backend_configuration',
 4357             mock.Mock(side_effect=exception.BadConfigurationException))
 4358         self.mock_object(self.library, '_get_vserver')
 4359         mock_exception_log = self.mock_object(lib_base.LOG, 'exception')
 4360         self.mock_object(share_utils, 'extract_host', mock.Mock(
 4361             return_value='destination_backend'))
 4362         self.mock_object(share_types, 'get_extra_specs_from_share')
 4363         self.mock_object(self.library, '_check_extra_specs_validity')
 4364         self.mock_object(self.library, '_check_aggregate_extra_specs_validity')
 4365         mock_vserver_compatibility_check = self.mock_object(
 4366             self.library, '_check_destination_vserver_for_vol_move')
 4367         self.mock_object(self.library, '_get_dest_flexvol_encryption_value',
 4368                          mock.Mock(return_value=False))
 4369 
 4370         migration_compatibility = self.library.migration_check_compatibility(
 4371             self.context, fake_share.fake_share_instance(),
 4372             fake_share.fake_share_instance(), share_server=fake.SHARE_SERVER,
 4373             destination_share_server=None)
 4374 
 4375         expected_compatibility = {
 4376             'compatible': False,
 4377             'writable': False,
 4378             'nondisruptive': False,
 4379             'preserve_metadata': False,
 4380             'preserve_snapshots': False,
 4381         }
 4382         self.assertDictMatch(expected_compatibility, migration_compatibility)
 4383         mock_exception_log.assert_called_once()
 4384         data_motion.get_backend_configuration.assert_called_once_with(
 4385             'destination_backend')
 4386         self.assertFalse(mock_vserver_compatibility_check.called)
 4387         self.assertFalse(self.library._get_vserver.called)
 4388 
 4389     @ddt.data(
 4390         utils.annotated(
 4391             'dest_share_server_not_expected',
 4392             (('src_vserver', None), exception.InvalidParameterValue)),
 4393         utils.annotated(
 4394             'src_share_server_not_expected',
 4395             (exception.InvalidParameterValue, ('dest_vserver', None))))
 4396     def test_migration_check_compatibility_errors(self, side_effects):
 4397         self.library._have_cluster_creds = True
 4398         self.mock_object(share_types, 'get_extra_specs_from_share')
 4399         self.mock_object(self.library, '_check_extra_specs_validity')
 4400         self.mock_object(self.library, '_check_aggregate_extra_specs_validity')
 4401         self.mock_object(self.library, '_get_backend_share_name',
 4402                          mock.Mock(return_value=fake.SHARE_NAME))
 4403         self.mock_object(data_motion, 'get_backend_configuration')
 4404         self.mock_object(self.library, '_get_vserver',
 4405                          mock.Mock(side_effect=side_effects))
 4406         mock_exception_log = self.mock_object(lib_base.LOG, 'exception')
 4407         self.mock_object(share_utils, 'extract_host', mock.Mock(
 4408             return_value='destination_backend'))
 4409         mock_compatibility_check = self.mock_object(
 4410             self.client, 'check_volume_move')
 4411 
 4412         migration_compatibility = self.library.migration_check_compatibility(
 4413             self.context, fake_share.fake_share_instance(),
 4414             fake_share.fake_share_instance(), share_server=fake.SHARE_SERVER,
 4415             destination_share_server=None)
 4416 
 4417         expected_compatibility = {
 4418             'compatible': False,
 4419             'writable': False,
 4420             'nondisruptive': False,
 4421             'preserve_metadata': False,
 4422             'preserve_snapshots': False,
 4423         }
 4424         self.assertDictMatch(expected_compatibility, migration_compatibility)
 4425         mock_exception_log.assert_called_once()
 4426         data_motion.get_backend_configuration.assert_called_once_with(
 4427             'destination_backend')
 4428         self.assertFalse(mock_compatibility_check.called)
 4429 
 4430     def test_migration_check_compatibility_incompatible_vservers(self):
 4431         self.library._have_cluster_creds = True
 4432         self.mock_object(share_types, 'get_extra_specs_from_share')
 4433         self.mock_object(self.library, '_check_extra_specs_validity')
 4434         self.mock_object(self.library, '_check_aggregate_extra_specs_validity')
 4435         self.mock_object(self.library, '_get_backend_share_name',
 4436                          mock.Mock(return_value=fake.SHARE_NAME))
 4437         self.mock_object(data_motion, 'get_backend_configuration')
 4438         mock_exception_log = self.mock_object(lib_base.LOG, 'exception')
 4439         get_vserver_returns = [
 4440             (fake.VSERVER1, mock.Mock()),
 4441             (fake.VSERVER2, mock.Mock()),
 4442         ]
 4443         self.mock_object(self.library, '_get_vserver',
 4444                          mock.Mock(side_effect=get_vserver_returns))
 4445         self.mock_object(share_utils, 'extract_host', mock.Mock(
 4446             side_effect=['destination_backend', 'destination_pool']))
 4447         mock_move_check = self.mock_object(self.client, 'check_volume_move')
 4448 
 4449         migration_compatibility = self.library.migration_check_compatibility(
 4450             self.context, fake_share.fake_share_instance(),
 4451             fake_share.fake_share_instance(), share_server=fake.SHARE_SERVER,
 4452             destination_share_server='dst_srv')
 4453 
 4454         expected_compatibility = {
 4455             'compatible': False,
 4456             'writable': False,
 4457             'nondisruptive': False,
 4458             'preserve_metadata': False,
 4459             'preserve_snapshots': False,
 4460         }
 4461         self.assertDictMatch(expected_compatibility, migration_compatibility)
 4462         mock_exception_log.assert_called_once()
 4463         data_motion.get_backend_configuration.assert_called_once_with(
 4464             'destination_backend')
 4465         self.assertFalse(mock_move_check.called)
 4466         self.library._get_vserver.assert_has_calls(
 4467             [mock.call(share_server=fake.SHARE_SERVER),
 4468              mock.call(share_server='dst_srv')])
 4469 
 4470     def test_migration_check_compatibility_client_error(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         mock_exception_log = self.mock_object(lib_base.LOG, 'exception')
 4478         self.mock_object(data_motion, 'get_backend_configuration')
 4479         self.mock_object(self.library, '_get_vserver',
 4480                          mock.Mock(return_value=(fake.VSERVER1, mock.Mock())))
 4481         self.mock_object(share_utils, 'extract_host', mock.Mock(
 4482             side_effect=['destination_backend', 'destination_pool']))
 4483         mock_move_check = self.mock_object(
 4484             self.client, 'check_volume_move',
 4485             mock.Mock(side_effect=netapp_api.NaApiError))
 4486         self.mock_object(self.library, '_get_dest_flexvol_encryption_value',
 4487                          mock.Mock(return_value=False))
 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         mock_move_check.assert_called_once_with(
 4506             fake.SHARE_NAME, fake.VSERVER1, 'destination_pool',
 4507             encrypt_destination=False)
 4508         self.library._get_vserver.assert_has_calls(
 4509             [mock.call(share_server=fake.SHARE_SERVER),
 4510              mock.call(share_server='dst_srv')])
 4511 
 4512     def test_migration_check_compatibility(self):
 4513         self.library._have_cluster_creds = True
 4514         self.mock_object(share_types, 'get_extra_specs_from_share')
 4515         self.mock_object(self.library, '_check_extra_specs_validity')
 4516         self.mock_object(self.library, '_check_aggregate_extra_specs_validity')
 4517         self.mock_object(self.library, '_get_backend_share_name',
 4518                          mock.Mock(return_value=fake.SHARE_NAME))
 4519         self.mock_object(data_motion, 'get_backend_configuration')
 4520         self.mock_object(self.library, '_get_vserver',
 4521                          mock.Mock(return_value=(fake.VSERVER1, mock.Mock())))
 4522         self.mock_object(share_utils, 'extract_host', mock.Mock(
 4523             side_effect=['destination_backend', 'destination_pool']))
 4524         mock_move_check = self.mock_object(self.client, 'check_volume_move')
 4525         self.mock_object(self.library, '_get_dest_flexvol_encryption_value',
 4526                          mock.Mock(return_value=False))
 4527 
 4528         migration_compatibility = self.library.migration_check_compatibility(
 4529             self.context, fake_share.fake_share_instance(),
 4530             fake_share.fake_share_instance(), share_server=fake.SHARE_SERVER,
 4531             destination_share_server='dst_srv')
 4532 
 4533         expected_compatibility = {
 4534             'compatible': True,
 4535             'writable': True,
 4536             'nondisruptive': True,
 4537             'preserve_metadata': True,
 4538             'preserve_snapshots': True,
 4539         }
 4540         self.assertDictMatch(expected_compatibility, migration_compatibility)
 4541         data_motion.get_backend_configuration.assert_called_once_with(
 4542             'destination_backend')
 4543         mock_move_check.assert_called_once_with(
 4544             fake.SHARE_NAME, fake.VSERVER1, 'destination_pool',
 4545             encrypt_destination=False)
 4546         self.library._get_vserver.assert_has_calls(
 4547             [mock.call(share_server=fake.SHARE_SERVER),
 4548              mock.call(share_server='dst_srv')])
 4549 
 4550     def test_migration_check_compatibility_destination_type_is_encrypted(self):
 4551         self.library._have_cluster_creds = True
 4552         self.mock_object(self.library, '_get_backend_share_name',
 4553                          mock.Mock(return_value=fake.SHARE_NAME))
 4554         self.mock_object(data_motion, 'get_backend_configuration')
 4555         self.mock_object(self.library, '_get_vserver',
 4556                          mock.Mock(return_value=(fake.VSERVER1, mock.Mock())))
 4557         self.mock_object(share_utils, 'extract_host', mock.Mock(
 4558             side_effect=['destination_backend', 'destination_pool']))
 4559         mock_move_check = self.mock_object(self.client, 'check_volume_move')
 4560         self.mock_object(self.library, '_get_dest_flexvol_encryption_value',
 4561                          mock.Mock(return_value=True))
 4562         self.mock_object(share_types, 'get_extra_specs_from_share',
 4563                          mock.Mock(return_value={'spec1': 'spec-data'}))
 4564         self.mock_object(self.library,
 4565                          '_check_extra_specs_validity')
 4566         self.mock_object(self.library,
 4567                          '_check_aggregate_extra_specs_validity')
 4568 
 4569         migration_compatibility = self.library.migration_check_compatibility(
 4570             self.context, fake_share.fake_share_instance(),
 4571             fake_share.fake_share_instance(), share_server=fake.SHARE_SERVER,
 4572             destination_share_server='dst_srv')
 4573 
 4574         expected_compatibility = {
 4575             'compatible': True,
 4576             'writable': True,
 4577             'nondisruptive': True,
 4578             'preserve_metadata': True,
 4579             'preserve_snapshots': True,
 4580         }
 4581         self.assertDictMatch(expected_compatibility, migration_compatibility)
 4582         data_motion.get_backend_configuration.assert_called_once_with(
 4583             'destination_backend')
 4584 
 4585         mock_move_check.assert_called_once_with(
 4586             fake.SHARE_NAME, fake.VSERVER1, 'destination_pool',
 4587             encrypt_destination=True)
 4588 
 4589         self.library._get_vserver.assert_has_calls(
 4590             [mock.call(share_server=fake.SHARE_SERVER),
 4591              mock.call(share_server='dst_srv')])
 4592 
 4593     def test_migration_start(self):
 4594         mock_info_log =