"Fossies" - the Fresh Open Source Software Archive

Member "manila-11.0.1/manila/tests/share/drivers/netapp/dataontap/client/test_client_cmode.py" (1 Feb 2021, 279527 Bytes) of package /linux/misc/openstack/manila-11.0.1.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_client_cmode.py": 11.0.0_vs_11.0.1.

    1 # Copyright (c) 2014 Alex Meade.  All rights reserved.
    2 # Copyright (c) 2015 Clinton Knight.  All rights reserved.
    3 # Copyright (c) 2015 Tom Barron.  All rights reserved.
    4 #
    5 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
    6 #    not use this file except in compliance with the License. You may obtain
    7 #    a copy of the License at
    8 #
    9 #         http://www.apache.org/licenses/LICENSE-2.0
   10 #
   11 #    Unless required by applicable law or agreed to in writing, software
   12 #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
   13 #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
   14 #    License for the specific language governing permissions and limitations
   15 #    under the License.
   16 
   17 import copy
   18 import hashlib
   19 import time
   20 from unittest import mock
   21 
   22 import ddt
   23 from oslo_log import log
   24 import six
   25 
   26 from manila import exception
   27 from manila.share.drivers.netapp.dataontap.client import api as netapp_api
   28 from manila.share.drivers.netapp.dataontap.client import client_base
   29 from manila.share.drivers.netapp.dataontap.client import client_cmode
   30 from manila import test
   31 from manila.tests.share.drivers.netapp.dataontap.client import fakes as fake
   32 
   33 
   34 @ddt.ddt
   35 class NetAppClientCmodeTestCase(test.TestCase):
   36 
   37     def setUp(self):
   38         super(NetAppClientCmodeTestCase, self).setUp()
   39 
   40         # Mock loggers as themselves to allow logger arg validation
   41         mock_logger = log.getLogger('mock_logger')
   42         self.mock_object(client_cmode.LOG,
   43                          'error',
   44                          mock.Mock(side_effect=mock_logger.error))
   45         self.mock_object(client_cmode.LOG,
   46                          'warning',
   47                          mock.Mock(side_effect=mock_logger.warning))
   48         self.mock_object(client_cmode.LOG,
   49                          'debug',
   50                          mock.Mock(side_effect=mock_logger.debug))
   51 
   52         self.mock_object(client_base.NetAppBaseClient,
   53                          'get_ontapi_version',
   54                          mock.Mock(return_value=(1, 20)))
   55 
   56         self.mock_object(client_base.NetAppBaseClient,
   57                          'get_system_version',
   58                          mock.Mock(return_value={
   59                              'version-tuple': (8, 3, 0),
   60                              'version': fake.VERSION,
   61                          }))
   62 
   63         self.client = client_cmode.NetAppCmodeClient(**fake.CONNECTION_INFO)
   64         self.client.connection = mock.MagicMock()
   65 
   66         self.vserver_client = client_cmode.NetAppCmodeClient(
   67             **fake.CONNECTION_INFO)
   68         self.vserver_client.set_vserver(fake.VSERVER_NAME)
   69         self.vserver_client.connection = mock.MagicMock()
   70 
   71     def _mock_api_error(self, code='fake', message='fake'):
   72         return mock.Mock(side_effect=netapp_api.NaApiError(code=code,
   73                                                            message=message))
   74 
   75     def test_init_features_ontapi_1_21(self):
   76 
   77         self.mock_object(client_base.NetAppBaseClient,
   78                          'get_ontapi_version',
   79                          mock.Mock(return_value=(1, 21)))
   80 
   81         self.client._init_features()
   82 
   83         self.assertFalse(self.client.features.BROADCAST_DOMAINS)
   84         self.assertFalse(self.client.features.IPSPACES)
   85         self.assertFalse(self.client.features.SUBNETS)
   86         self.assertFalse(self.client.features.FLEXVOL_ENCRYPTION)
   87 
   88     @ddt.data((1, 30), (1, 40), (2, 0))
   89     def test_init_features_ontapi_1_30(self, ontapi_version):
   90 
   91         self.mock_object(client_base.NetAppBaseClient,
   92                          'get_ontapi_version',
   93                          mock.Mock(return_value=ontapi_version))
   94 
   95         self.client._init_features()
   96 
   97         self.assertTrue(self.client.features.BROADCAST_DOMAINS)
   98         self.assertTrue(self.client.features.IPSPACES)
   99         self.assertTrue(self.client.features.SUBNETS)
  100 
  101     @ddt.data((1, 110), (2, 0))
  102     def test_init_features_ontap_1_110(self, ontapi_version):
  103 
  104         self.mock_object(client_base.NetAppBaseClient,
  105                          'get_ontapi_version',
  106                          mock.Mock(return_value=ontapi_version))
  107 
  108         self.client._init_features()
  109 
  110         self.assertTrue(self.client.features.BROADCAST_DOMAINS)
  111         self.assertTrue(self.client.features.IPSPACES)
  112         self.assertTrue(self.client.features.SUBNETS)
  113         self.assertTrue(self.client.features.FLEXVOL_ENCRYPTION)
  114 
  115     @ddt.data(((9, 1, 0), fake.VERSION_NO_DARE), ((8, 3, 2), fake.VERSION))
  116     @ddt.unpack
  117     def test_is_nve_supported_unsupported_release_or_platform(self, gen, ver):
  118 
  119         system_version = {'version-tuple': gen, 'version': ver}
  120         self.mock_object(client_base.NetAppBaseClient,
  121                          'get_system_version',
  122                          mock.Mock(return_value=system_version))
  123         self.mock_object(self.client,
  124                          'get_security_key_manager_nve_support',
  125                          mock.Mock(return_value=True))
  126         self.mock_object(self.client,
  127                          'list_cluster_nodes',
  128                          mock.Mock(return_value=fake.NODE_NAMES))
  129 
  130         result = self.client.is_nve_supported()
  131 
  132         self.assertFalse(result)
  133 
  134     def test_is_nve_supported_valid_platform_and_supported_release(self):
  135 
  136         system_version = {
  137             'version-tuple': (9, 1, 0),
  138             'version': fake.VERSION,
  139         }
  140         self.mock_object(client_base.NetAppBaseClient,
  141                          'get_system_version',
  142                          mock.Mock(return_value=system_version))
  143         self.mock_object(self.client,
  144                          'get_security_key_manager_nve_support',
  145                          mock.Mock(return_value=True))
  146         self.mock_object(self.client,
  147                          'list_cluster_nodes',
  148                          mock.Mock(return_value=fake.NODE_NAMES))
  149 
  150         result = self.client.is_nve_supported()
  151         self.assertTrue(result)
  152 
  153     def test_is_nve_supported_key_manager_not_enabled(self):
  154 
  155         system_version = {
  156             'version-tuple': (9, 1, 0),
  157             'version': fake.VERSION,
  158         }
  159         self.mock_object(client_base.NetAppBaseClient,
  160                          'get_system_version',
  161                          mock.Mock(return_value=system_version))
  162         self.mock_object(self.client,
  163                          'get_security_key_manager_nve_support',
  164                          mock.Mock(return_value=False))
  165         self.mock_object(self.client,
  166                          'list_cluster_nodes',
  167                          mock.Mock(return_value=fake.NODE_NAMES))
  168 
  169         result = self.client.is_nve_supported()
  170 
  171         self.assertFalse(result)
  172 
  173     def test_get_security_key_manager_nve_support_enabled(self):
  174         api_response = netapp_api.NaElement(
  175             fake.SECUTITY_KEY_MANAGER_NVE_SUPPORT_RESPONSE_TRUE)
  176         self.mock_object(self.client,
  177                          'send_request',
  178                          mock.Mock(return_value=api_response))
  179 
  180         result = self.client.get_security_key_manager_nve_support(
  181             fake.NODE_NAME)
  182 
  183         self.assertTrue(result)
  184         api_args = {'node': fake.NODE_NAME}
  185         self.client.send_request.assert_has_calls([
  186             mock.call('security-key-manager-volume-encryption-supported',
  187                       api_args)])
  188 
  189     def test_get_security_key_manager_nve_support_disabled(self):
  190         api_response = netapp_api.NaElement(
  191             fake.SECUTITY_KEY_MANAGER_NVE_SUPPORT_RESPONSE_FALSE)
  192         self.mock_object(self.client,
  193                          'send_request',
  194                          mock.Mock(return_value=api_response))
  195 
  196         result = self.client.get_security_key_manager_nve_support(
  197             fake.NODE_NAME)
  198 
  199         self.assertFalse(result)
  200         api_args = {'node': fake.NODE_NAME}
  201         self.client.send_request.assert_has_calls([
  202             mock.call('security-key-manager-volume-encryption-supported',
  203                       api_args)])
  204 
  205     def test_get_security_key_manager_nve_support_disabled_no_license(self):
  206         self.mock_object(self.client,
  207                          'send_request',
  208                          self._mock_api_error())
  209 
  210         result = self.client.get_security_key_manager_nve_support(
  211             fake.NODE_NAME)
  212 
  213         self.assertFalse(result)
  214 
  215         api_args = {'node': fake.NODE_NAME}
  216         self.client.send_request.assert_has_calls([
  217             mock.call('security-key-manager-volume-encryption-supported',
  218                       api_args)])
  219 
  220     @ddt.data((True, True, True), (False, None, False))
  221     @ddt.unpack
  222     def test_send_volume_move_request_success(self, validation_only,
  223                                               encrypt_dst, fv_encryption):
  224         self.mock_object(self.client, 'features',
  225                          mock.Mock(FLEXVOL_ENCRYPTION=fv_encryption))
  226         self.client._send_volume_move_request(fake.ROOT_VOLUME_NAME,
  227                                               fake.NODE_VSERVER_NAME,
  228                                               fake.SHARE_AGGREGATE_NAME,
  229                                               validation_only=validation_only,
  230                                               encrypt_destination=encrypt_dst)
  231 
  232     @ddt.data((True, True, False))
  233     @ddt.unpack
  234     def test_send_volume_move_request_failure(self, validation_only,
  235                                               encrypt_dst, fv_encrypt):
  236         self.mock_object(self.client, 'features',
  237                          mock.Mock(FLEXVOL_ENCRYPTION=fv_encrypt))
  238         self.assertRaises(exception.NetAppException,
  239                           self.client._send_volume_move_request,
  240                           fake.ROOT_VOLUME_NAME,
  241                           fake.NODE_VSERVER_NAME,
  242                           fake.SHARE_AGGREGATE_NAME,
  243                           validation_only=validation_only,
  244                           encrypt_destination=encrypt_dst)
  245 
  246     def test_invoke_vserver_api(self):
  247 
  248         self.client._invoke_vserver_api('fake-api', 'fake_vserver')
  249 
  250         self.client.connection.set_vserver.assert_has_calls(
  251             [mock.call('fake_vserver')])
  252         self.client.connection.invoke_successfully.assert_has_calls(
  253             [mock.call('fake-api', True)])
  254 
  255     def test_has_records(self):
  256         self.assertTrue(self.client._has_records(
  257             netapp_api.NaElement(fake.VSERVER_GET_ITER_RESPONSE)))
  258 
  259     def test_has_records_not_found(self):
  260         self.assertFalse(self.client._has_records(
  261             netapp_api.NaElement(fake.NO_RECORDS_RESPONSE)))
  262 
  263     @ddt.data((fake.VSERVER_GET_ITER_RESPONSE, 1),
  264               (fake.NO_RECORDS_RESPONSE, 0))
  265     @ddt.unpack
  266     def test_get_record_count(self, response, expected):
  267 
  268         api_response = netapp_api.NaElement(response)
  269 
  270         result = self.client._get_record_count(api_response)
  271 
  272         self.assertEqual(expected, result)
  273 
  274     def test_get_records_count_invalid(self):
  275 
  276         api_response = netapp_api.NaElement(
  277             fake.INVALID_GET_ITER_RESPONSE_NO_RECORDS)
  278 
  279         self.assertRaises(exception.NetAppException,
  280                           self.client._get_record_count,
  281                           api_response)
  282 
  283     def test_send_iter_request(self):
  284 
  285         api_responses = [
  286             netapp_api.NaElement(fake.STORAGE_DISK_GET_ITER_RESPONSE_PAGE_1),
  287             netapp_api.NaElement(fake.STORAGE_DISK_GET_ITER_RESPONSE_PAGE_2),
  288             netapp_api.NaElement(fake.STORAGE_DISK_GET_ITER_RESPONSE_PAGE_3),
  289         ]
  290         mock_send_request = self.mock_object(
  291             self.client, 'send_request',
  292             mock.Mock(side_effect=api_responses))
  293 
  294         storage_disk_get_iter_args = {
  295             'desired-attributes': {
  296                 'storage-disk-info': {
  297                     'disk-name': None,
  298                 }
  299             }
  300         }
  301         result = self.client.send_iter_request(
  302             'storage-disk-get-iter', api_args=storage_disk_get_iter_args,
  303             max_page_length=10)
  304 
  305         num_records = result.get_child_content('num-records')
  306         self.assertEqual('28', num_records)
  307         next_tag = result.get_child_content('next-tag')
  308         self.assertEqual('', next_tag)
  309 
  310         args1 = copy.deepcopy(storage_disk_get_iter_args)
  311         args1['max-records'] = 10
  312         args2 = copy.deepcopy(storage_disk_get_iter_args)
  313         args2['max-records'] = 10
  314         args2['tag'] = 'next_tag_1'
  315         args3 = copy.deepcopy(storage_disk_get_iter_args)
  316         args3['max-records'] = 10
  317         args3['tag'] = 'next_tag_2'
  318 
  319         mock_send_request.assert_has_calls([
  320             mock.call('storage-disk-get-iter', args1),
  321             mock.call('storage-disk-get-iter', args2),
  322             mock.call('storage-disk-get-iter', args3),
  323         ])
  324 
  325     def test_send_iter_request_single_page(self):
  326 
  327         api_response = netapp_api.NaElement(
  328             fake.STORAGE_DISK_GET_ITER_RESPONSE)
  329         mock_send_request = self.mock_object(
  330             self.client, 'send_request',
  331             mock.Mock(return_value=api_response))
  332 
  333         storage_disk_get_iter_args = {
  334             'desired-attributes': {
  335                 'storage-disk-info': {
  336                     'disk-name': None,
  337                 }
  338             }
  339         }
  340         result = self.client.send_iter_request(
  341             'storage-disk-get-iter', api_args=storage_disk_get_iter_args,
  342             max_page_length=10)
  343 
  344         num_records = result.get_child_content('num-records')
  345         self.assertEqual('4', num_records)
  346 
  347         args = copy.deepcopy(storage_disk_get_iter_args)
  348         args['max-records'] = 10
  349 
  350         mock_send_request.assert_has_calls([
  351             mock.call('storage-disk-get-iter', args),
  352         ])
  353 
  354     def test_send_iter_request_not_found(self):
  355 
  356         api_response = netapp_api.NaElement(fake.NO_RECORDS_RESPONSE)
  357         mock_send_request = self.mock_object(
  358             self.client, 'send_request',
  359             mock.Mock(return_value=api_response))
  360 
  361         result = self.client.send_iter_request('storage-disk-get-iter')
  362 
  363         num_records = result.get_child_content('num-records')
  364         self.assertEqual('0', num_records)
  365 
  366         args = {'max-records': client_cmode.DEFAULT_MAX_PAGE_LENGTH}
  367 
  368         mock_send_request.assert_has_calls([
  369             mock.call('storage-disk-get-iter', args),
  370         ])
  371 
  372     @ddt.data(fake.INVALID_GET_ITER_RESPONSE_NO_ATTRIBUTES,
  373               fake.INVALID_GET_ITER_RESPONSE_NO_RECORDS)
  374     def test_send_iter_request_invalid(self, fake_response):
  375 
  376         api_response = netapp_api.NaElement(fake_response)
  377         self.mock_object(self.client,
  378                          'send_request',
  379                          mock.Mock(return_value=api_response))
  380 
  381         self.assertRaises(exception.NetAppException,
  382                           self.client.send_iter_request,
  383                           'storage-disk-get-iter')
  384 
  385     def test_set_vserver(self):
  386         self.client.set_vserver(fake.VSERVER_NAME)
  387         self.client.connection.set_vserver.assert_has_calls(
  388             [mock.call('fake_vserver')])
  389 
  390     def test_vserver_exists(self):
  391 
  392         api_response = netapp_api.NaElement(fake.VSERVER_GET_ITER_RESPONSE)
  393         self.mock_object(self.client,
  394                          'send_iter_request',
  395                          mock.Mock(return_value=api_response))
  396 
  397         vserver_get_args = {
  398             'query': {'vserver-info': {'vserver-name': fake.VSERVER_NAME}},
  399             'desired-attributes': {'vserver-info': {'vserver-name': None}}
  400         }
  401 
  402         result = self.client.vserver_exists(fake.VSERVER_NAME)
  403 
  404         self.client.send_iter_request.assert_has_calls([
  405             mock.call('vserver-get-iter', vserver_get_args)])
  406         self.assertTrue(result)
  407 
  408     def test_vserver_exists_not_found(self):
  409 
  410         api_response = netapp_api.NaElement(fake.NO_RECORDS_RESPONSE)
  411         self.mock_object(self.client,
  412                          'send_request',
  413                          mock.Mock(return_value=api_response))
  414 
  415         result = self.client.vserver_exists(fake.VSERVER_NAME)
  416 
  417         self.assertFalse(result)
  418 
  419     def test_create_vserver_no_ipspace(self):
  420 
  421         self.mock_object(self.client, 'send_request')
  422 
  423         vserver_create_args = {
  424             'vserver-name': fake.VSERVER_NAME,
  425             'root-volume-security-style': 'unix',
  426             'root-volume-aggregate': fake.ROOT_VOLUME_AGGREGATE_NAME,
  427             'root-volume': fake.ROOT_VOLUME_NAME,
  428             'name-server-switch': {'nsswitch': 'file'}
  429         }
  430         vserver_modify_args = {
  431             'aggr-list': [{'aggr-name': aggr_name} for aggr_name
  432                           in fake.SHARE_AGGREGATE_NAMES],
  433             'vserver-name': fake.VSERVER_NAME
  434         }
  435 
  436         self.client.create_vserver(fake.VSERVER_NAME,
  437                                    fake.ROOT_VOLUME_AGGREGATE_NAME,
  438                                    fake.ROOT_VOLUME_NAME,
  439                                    fake.SHARE_AGGREGATE_NAMES,
  440                                    None)
  441 
  442         self.client.send_request.assert_has_calls([
  443             mock.call('vserver-create', vserver_create_args),
  444             mock.call('vserver-modify', vserver_modify_args)])
  445 
  446     def test_create_vserver_with_ipspace(self):
  447 
  448         self.client.features.add_feature('IPSPACES')
  449         self.mock_object(self.client, 'send_request')
  450 
  451         vserver_create_args = {
  452             'vserver-name': fake.VSERVER_NAME,
  453             'root-volume-security-style': 'unix',
  454             'root-volume-aggregate': fake.ROOT_VOLUME_AGGREGATE_NAME,
  455             'root-volume': fake.ROOT_VOLUME_NAME,
  456             'name-server-switch': {'nsswitch': 'file'},
  457             'ipspace': fake.IPSPACE_NAME,
  458         }
  459         vserver_modify_args = {
  460             'aggr-list': [{'aggr-name': aggr_name} for aggr_name
  461                           in fake.SHARE_AGGREGATE_NAMES],
  462             'vserver-name': fake.VSERVER_NAME
  463         }
  464 
  465         self.client.create_vserver(fake.VSERVER_NAME,
  466                                    fake.ROOT_VOLUME_AGGREGATE_NAME,
  467                                    fake.ROOT_VOLUME_NAME,
  468                                    fake.SHARE_AGGREGATE_NAMES,
  469                                    fake.IPSPACE_NAME)
  470 
  471         self.client.send_request.assert_has_calls([
  472             mock.call('vserver-create', vserver_create_args),
  473             mock.call('vserver-modify', vserver_modify_args)])
  474 
  475     def test_create_vserver_dp_destination(self):
  476 
  477         self.client.features.add_feature('IPSPACES')
  478         self.mock_object(self.client, 'send_request')
  479 
  480         vserver_create_args = {
  481             'vserver-name': fake.VSERVER_NAME,
  482             'ipspace': fake.IPSPACE_NAME,
  483             'vserver-subtype': fake.VSERVER_TYPE_DP_DEST,
  484         }
  485         vserver_modify_args = {
  486             'aggr-list': [{'aggr-name': aggr_name} for aggr_name
  487                           in fake.SHARE_AGGREGATE_NAMES],
  488             'vserver-name': fake.VSERVER_NAME
  489         }
  490 
  491         self.client.create_vserver_dp_destination(
  492             fake.VSERVER_NAME,
  493             fake.SHARE_AGGREGATE_NAMES,
  494             fake.IPSPACE_NAME)
  495 
  496         self.client.send_request.assert_has_calls([
  497             mock.call('vserver-create', vserver_create_args),
  498             mock.call('vserver-modify', vserver_modify_args)])
  499 
  500     def test_create_vserver_ipspaces_not_supported(self):
  501 
  502         self.assertRaises(exception.NetAppException,
  503                           self.client.create_vserver,
  504                           fake.VSERVER_NAME,
  505                           fake.ROOT_VOLUME_AGGREGATE_NAME,
  506                           fake.ROOT_VOLUME_NAME,
  507                           fake.SHARE_AGGREGATE_NAMES,
  508                           fake.IPSPACE_NAME)
  509 
  510     def test_get_vserver_root_volume_name(self):
  511 
  512         api_response = netapp_api.NaElement(
  513             fake.VSERVER_GET_ROOT_VOLUME_NAME_RESPONSE)
  514         self.mock_object(self.client,
  515                          'send_iter_request',
  516                          mock.Mock(return_value=api_response))
  517 
  518         vserver_get_args = {
  519             'query': {'vserver-info': {'vserver-name': fake.VSERVER_NAME}},
  520             'desired-attributes': {'vserver-info': {'root-volume': None}}
  521         }
  522 
  523         result = self.client.get_vserver_root_volume_name(fake.VSERVER_NAME)
  524 
  525         self.client.send_iter_request.assert_has_calls([
  526             mock.call('vserver-get-iter', vserver_get_args)])
  527         self.assertEqual(fake.ROOT_VOLUME_NAME, result)
  528 
  529     def test_get_vserver_root_volume_name_not_found(self):
  530 
  531         api_response = netapp_api.NaElement(fake.NO_RECORDS_RESPONSE)
  532         self.mock_object(self.client,
  533                          'send_iter_request',
  534                          mock.Mock(return_value=api_response))
  535 
  536         self.assertRaises(exception.NetAppException,
  537                           self.client.get_vserver_root_volume_name,
  538                           fake.VSERVER_NAME)
  539 
  540     def test_get_vserver_ipspace(self):
  541 
  542         self.client.features.add_feature('IPSPACES')
  543         api_response = netapp_api.NaElement(
  544             fake.VSERVER_GET_IPSPACE_NAME_RESPONSE)
  545         self.mock_object(self.client,
  546                          'send_iter_request',
  547                          mock.Mock(return_value=api_response))
  548 
  549         result = self.client.get_vserver_ipspace(fake.VSERVER_NAME)
  550 
  551         vserver_get_iter_args = {
  552             'query': {
  553                 'vserver-info': {
  554                     'vserver-name': fake.VSERVER_NAME,
  555                 },
  556             },
  557             'desired-attributes': {
  558                 'vserver-info': {
  559                     'ipspace': None,
  560                 },
  561             },
  562         }
  563         self.client.send_iter_request.assert_has_calls([
  564             mock.call('vserver-get-iter', vserver_get_iter_args)])
  565         self.assertEqual(fake.IPSPACE_NAME, result)
  566 
  567     def test_get_vserver_ipspace_not_supported(self):
  568 
  569         result = self.client.get_vserver_ipspace(fake.IPSPACE_NAME)
  570 
  571         self.assertIsNone(result)
  572 
  573     def test_get_vserver_ipspace_not_found(self):
  574 
  575         self.client.features.add_feature('IPSPACES')
  576         api_response = netapp_api.NaElement(fake.NO_RECORDS_RESPONSE)
  577         self.mock_object(self.client,
  578                          'send_iter_request',
  579                          mock.Mock(return_value=api_response))
  580 
  581         self.assertRaises(exception.NetAppException,
  582                           self.client.get_vserver_ipspace,
  583                           fake.IPSPACE_NAME)
  584 
  585     def test_ipspace_has_data_vservers(self):
  586 
  587         self.client.features.add_feature('IPSPACES')
  588         api_response = netapp_api.NaElement(fake.VSERVER_GET_ITER_RESPONSE)
  589         self.mock_object(self.client,
  590                          'send_iter_request',
  591                          mock.Mock(return_value=api_response))
  592 
  593         result = self.client.ipspace_has_data_vservers(fake.IPSPACE_NAME)
  594 
  595         vserver_get_iter_args = {
  596             'query': {
  597                 'vserver-info': {
  598                     'ipspace': fake.IPSPACE_NAME,
  599                     'vserver-type': 'data'
  600                 },
  601             },
  602             'desired-attributes': {
  603                 'vserver-info': {
  604                     'vserver-name': None,
  605                 },
  606             },
  607         }
  608         self.client.send_iter_request.assert_has_calls([
  609             mock.call('vserver-get-iter', vserver_get_iter_args)])
  610         self.assertTrue(result)
  611 
  612     def test_ipspace_has_data_vservers_not_supported(self):
  613 
  614         result = self.client.ipspace_has_data_vservers(fake.IPSPACE_NAME)
  615 
  616         self.assertFalse(result)
  617 
  618     def test_ipspace_has_data_vservers_not_found(self):
  619 
  620         self.client.features.add_feature('IPSPACES')
  621         api_response = netapp_api.NaElement(fake.NO_RECORDS_RESPONSE)
  622         self.mock_object(self.client,
  623                          'send_request',
  624                          mock.Mock(return_value=api_response))
  625 
  626         result = self.client.ipspace_has_data_vservers(fake.IPSPACE_NAME)
  627 
  628         self.assertFalse(result)
  629 
  630     def test_list_vservers(self):
  631 
  632         api_response = netapp_api.NaElement(
  633             fake.VSERVER_DATA_LIST_RESPONSE)
  634         self.mock_object(self.client,
  635                          'send_iter_request',
  636                          mock.Mock(return_value=api_response))
  637 
  638         result = self.client.list_vservers()
  639 
  640         vserver_get_iter_args = {
  641             'query': {
  642                 'vserver-info': {
  643                     'vserver-type': 'data'
  644                 }
  645             },
  646             'desired-attributes': {
  647                 'vserver-info': {
  648                     'vserver-name': None
  649                 }
  650             }
  651         }
  652         self.client.send_iter_request.assert_has_calls([
  653             mock.call('vserver-get-iter', vserver_get_iter_args)])
  654         self.assertListEqual([fake.VSERVER_NAME], result)
  655 
  656     def test_list_vservers_node_type(self):
  657 
  658         api_response = netapp_api.NaElement(
  659             fake.VSERVER_DATA_LIST_RESPONSE)
  660         self.mock_object(self.client,
  661                          'send_iter_request',
  662                          mock.Mock(return_value=api_response))
  663 
  664         result = self.client.list_vservers(vserver_type='node')
  665 
  666         vserver_get_iter_args = {
  667             'query': {
  668                 'vserver-info': {
  669                     'vserver-type': 'node'
  670                 }
  671             },
  672             'desired-attributes': {
  673                 'vserver-info': {
  674                     'vserver-name': None
  675                 }
  676             }
  677         }
  678         self.client.send_iter_request.assert_has_calls([
  679             mock.call('vserver-get-iter', vserver_get_iter_args)])
  680         self.assertListEqual([fake.VSERVER_NAME], result)
  681 
  682     def test_list_vservers_not_found(self):
  683 
  684         api_response = netapp_api.NaElement(
  685             fake.NO_RECORDS_RESPONSE)
  686         self.mock_object(self.client,
  687                          'send_request',
  688                          mock.Mock(return_value=api_response))
  689 
  690         result = self.client.list_vservers(vserver_type='data')
  691 
  692         self.assertListEqual([], result)
  693 
  694     def test_get_vserver_volume_count(self):
  695 
  696         api_response = netapp_api.NaElement(fake.VOLUME_COUNT_RESPONSE)
  697         self.mock_object(self.client,
  698                          'send_iter_request',
  699                          mock.Mock(return_value=api_response))
  700 
  701         result = self.client.get_vserver_volume_count()
  702 
  703         self.assertEqual(2, result)
  704 
  705     def test_delete_vserver_no_volumes(self):
  706 
  707         self.mock_object(self.client,
  708                          'get_vserver_info',
  709                          mock.Mock(return_value=fake.VSERVER_INFO))
  710         self.mock_object(self.client,
  711                          'get_vserver_root_volume_name',
  712                          mock.Mock(return_value=fake.ROOT_VOLUME_NAME))
  713         self.mock_object(self.vserver_client,
  714                          'get_vserver_volume_count',
  715                          mock.Mock(return_value=0))
  716         self.mock_object(self.client, '_terminate_vserver_services')
  717         self.mock_object(self.client, 'send_request')
  718 
  719         self.client.delete_vserver(
  720             fake.VSERVER_NAME,
  721             self.vserver_client,
  722             security_services=[fake.CIFS_SECURITY_SERVICE])
  723 
  724         self.client._terminate_vserver_services.assert_called_with(
  725             fake.VSERVER_NAME, self.vserver_client,
  726             [fake.CIFS_SECURITY_SERVICE])
  727 
  728         vserver_destroy_args = {'vserver-name': fake.VSERVER_NAME}
  729         self.client.send_request.assert_has_calls([
  730             mock.call('vserver-destroy', vserver_destroy_args)])
  731 
  732     def test_delete_vserver_one_volume(self):
  733 
  734         self.mock_object(self.client,
  735                          'get_vserver_info',
  736                          mock.Mock(return_value=fake.VSERVER_INFO))
  737         self.mock_object(self.client,
  738                          'get_vserver_root_volume_name',
  739                          mock.Mock(return_value=fake.ROOT_VOLUME_NAME))
  740         self.mock_object(self.vserver_client,
  741                          'get_vserver_volume_count',
  742                          mock.Mock(return_value=1))
  743         self.mock_object(self.client, 'send_request')
  744         self.mock_object(self.vserver_client, 'offline_volume')
  745         self.mock_object(self.vserver_client, 'delete_volume')
  746 
  747         self.client.delete_vserver(fake.VSERVER_NAME,
  748                                    self.vserver_client)
  749 
  750         self.vserver_client.offline_volume.assert_called_with(
  751             fake.ROOT_VOLUME_NAME)
  752         self.vserver_client.delete_volume.assert_called_with(
  753             fake.ROOT_VOLUME_NAME)
  754 
  755         vserver_destroy_args = {'vserver-name': fake.VSERVER_NAME}
  756         self.client.send_request.assert_has_calls([
  757             mock.call('vserver-destroy', vserver_destroy_args)])
  758 
  759     def test_delete_vserver_one_volume_already_offline(self):
  760 
  761         self.mock_object(self.client,
  762                          'get_vserver_info',
  763                          mock.Mock(return_value=fake.VSERVER_INFO))
  764         self.mock_object(self.client,
  765                          'get_vserver_root_volume_name',
  766                          mock.Mock(return_value=fake.ROOT_VOLUME_NAME))
  767         self.mock_object(self.vserver_client,
  768                          'get_vserver_volume_count',
  769                          mock.Mock(return_value=1))
  770         self.mock_object(self.client, 'send_request')
  771         self.mock_object(self.vserver_client,
  772                          'offline_volume',
  773                          self._mock_api_error(code=netapp_api.EVOLUMEOFFLINE))
  774 
  775         self.mock_object(self.vserver_client, 'delete_volume')
  776 
  777         self.client.delete_vserver(fake.VSERVER_NAME,
  778                                    self.vserver_client)
  779 
  780         self.vserver_client.offline_volume.assert_called_with(
  781             fake.ROOT_VOLUME_NAME)
  782         self.vserver_client.delete_volume.assert_called_with(
  783             fake.ROOT_VOLUME_NAME)
  784 
  785         vserver_destroy_args = {'vserver-name': fake.VSERVER_NAME}
  786         self.client.send_request.assert_has_calls([
  787             mock.call('vserver-destroy', vserver_destroy_args)])
  788         self.assertEqual(1, client_cmode.LOG.error.call_count)
  789 
  790     def test_delete_vserver_one_volume_api_error(self):
  791 
  792         self.mock_object(self.client,
  793                          'get_vserver_info',
  794                          mock.Mock(return_value=fake.VSERVER_INFO))
  795         self.mock_object(self.client,
  796                          'get_vserver_root_volume_name',
  797                          mock.Mock(return_value=fake.ROOT_VOLUME_NAME))
  798         self.mock_object(self.vserver_client,
  799                          'get_vserver_volume_count',
  800                          mock.Mock(return_value=1))
  801         self.mock_object(self.client, 'send_request')
  802         self.mock_object(self.vserver_client,
  803                          'offline_volume',
  804                          self._mock_api_error())
  805         self.mock_object(self.vserver_client, 'delete_volume')
  806 
  807         self.assertRaises(netapp_api.NaApiError,
  808                           self.client.delete_vserver,
  809                           fake.VSERVER_NAME,
  810                           self.vserver_client)
  811 
  812     def test_delete_vserver_multiple_volumes(self):
  813 
  814         self.mock_object(self.client,
  815                          'get_vserver_info',
  816                          mock.Mock(return_value=fake.VSERVER_INFO))
  817         self.mock_object(self.client,
  818                          'get_vserver_root_volume_name',
  819                          mock.Mock(return_value=fake.ROOT_VOLUME_NAME))
  820         self.mock_object(self.vserver_client,
  821                          'get_vserver_volume_count',
  822                          mock.Mock(return_value=2))
  823 
  824         self.assertRaises(exception.NetAppException,
  825                           self.client.delete_vserver,
  826                           fake.VSERVER_NAME,
  827                           self.vserver_client)
  828 
  829     def test_delete_vserver_not_found(self):
  830 
  831         self.mock_object(self.client,
  832                          'get_vserver_info',
  833                          mock.Mock(return_value=None))
  834 
  835         self.client.delete_vserver(fake.VSERVER_NAME,
  836                                    self.vserver_client)
  837 
  838         self.assertEqual(1, client_cmode.LOG.error.call_count)
  839 
  840     def test_terminate_vserver_services(self):
  841 
  842         self.mock_object(self.vserver_client, 'send_request')
  843 
  844         self.client._terminate_vserver_services(fake.VSERVER_NAME,
  845                                                 self.vserver_client,
  846                                                 [fake.CIFS_SECURITY_SERVICE])
  847 
  848         cifs_server_delete_args = {
  849             'admin-password': fake.CIFS_SECURITY_SERVICE['password'],
  850             'admin-username': fake.CIFS_SECURITY_SERVICE['user'],
  851         }
  852         self.vserver_client.send_request.assert_has_calls([
  853             mock.call('cifs-server-delete', cifs_server_delete_args)])
  854 
  855     def test_terminate_vserver_services_cifs_not_found(self):
  856 
  857         self.mock_object(self.vserver_client,
  858                          'send_request',
  859                          self._mock_api_error(
  860                              code=netapp_api.EOBJECTNOTFOUND))
  861 
  862         self.client._terminate_vserver_services(fake.VSERVER_NAME,
  863                                                 self.vserver_client,
  864                                                 [fake.CIFS_SECURITY_SERVICE])
  865 
  866         cifs_server_delete_args = {
  867             'admin-password': fake.CIFS_SECURITY_SERVICE['password'],
  868             'admin-username': fake.CIFS_SECURITY_SERVICE['user'],
  869         }
  870         self.vserver_client.send_request.assert_has_calls([
  871             mock.call('cifs-server-delete', cifs_server_delete_args)])
  872         self.assertEqual(1, client_cmode.LOG.error.call_count)
  873 
  874     def test_terminate_vserver_services_api_error(self):
  875 
  876         side_effects = [netapp_api.NaApiError(code='fake'), None]
  877         self.mock_object(self.vserver_client,
  878                          'send_request',
  879                          mock.Mock(side_effect=side_effects))
  880 
  881         self.client._terminate_vserver_services(fake.VSERVER_NAME,
  882                                                 self.vserver_client,
  883                                                 [fake.CIFS_SECURITY_SERVICE])
  884 
  885         cifs_server_delete_args = {
  886             'admin-password': fake.CIFS_SECURITY_SERVICE['password'],
  887             'admin-username': fake.CIFS_SECURITY_SERVICE['user'],
  888         }
  889         self.vserver_client.send_request.assert_has_calls([
  890             mock.call('cifs-server-delete', cifs_server_delete_args),
  891             mock.call('cifs-server-delete')])
  892         self.assertEqual(0, client_cmode.LOG.error.call_count)
  893 
  894     def test_list_cluster_nodes(self):
  895 
  896         api_response = netapp_api.NaElement(
  897             fake.SYSTEM_NODE_GET_ITER_RESPONSE)
  898         self.mock_object(self.client,
  899                          'send_request',
  900                          mock.Mock(return_value=api_response))
  901 
  902         result = self.client.list_cluster_nodes()
  903 
  904         self.assertListEqual([fake.NODE_NAME], result)
  905 
  906     def test_list_cluster_nodes_not_found(self):
  907 
  908         api_response = netapp_api.NaElement(fake.NO_RECORDS_RESPONSE)
  909         self.mock_object(self.client,
  910                          'send_request',
  911                          mock.Mock(return_value=api_response))
  912 
  913         result = self.client.list_cluster_nodes()
  914 
  915         self.assertListEqual([], result)
  916 
  917     def test_list_node_data_ports(self):
  918 
  919         self.mock_object(self.client,
  920                          'get_node_data_ports',
  921                          mock.Mock(return_value=fake.SPEED_SORTED_PORTS))
  922 
  923         result = self.client.list_node_data_ports(fake.NODE_NAME)
  924 
  925         self.assertSequenceEqual(fake.SPEED_SORTED_PORT_NAMES, result)
  926 
  927     def test_get_node_data_ports(self):
  928 
  929         api_response = netapp_api.NaElement(fake.NET_PORT_GET_ITER_RESPONSE)
  930         self.mock_object(self.client,
  931                          'send_iter_request',
  932                          mock.Mock(return_value=api_response))
  933 
  934         result = self.client.get_node_data_ports(fake.NODE_NAME)
  935 
  936         net_port_get_iter_args = {
  937             'query': {
  938                 'net-port-info': {
  939                     'node': fake.NODE_NAME,
  940                     'link-status': 'up',
  941                     'port-type': 'physical|if_group',
  942                     'role': 'data',
  943                 },
  944             },
  945             'desired-attributes': {
  946                 'net-port-info': {
  947                     'port': None,
  948                     'node': None,
  949                     'operational-speed': None,
  950                     'ifgrp-port': None,
  951                 },
  952             },
  953         }
  954 
  955         self.assertSequenceEqual(fake.SPEED_SORTED_PORTS, result)
  956         self.client.send_iter_request.assert_has_calls([
  957             mock.call('net-port-get-iter', net_port_get_iter_args)])
  958 
  959     def test_get_node_data_ports_not_found(self):
  960 
  961         api_response = netapp_api.NaElement(fake.NO_RECORDS_RESPONSE)
  962         self.mock_object(self.client,
  963                          'send_iter_request',
  964                          mock.Mock(return_value=api_response))
  965 
  966         result = self.client.get_node_data_ports(fake.NODE_NAME)
  967 
  968         self.assertSequenceEqual([], result)
  969 
  970     def test_sort_data_ports_by_speed(self):
  971 
  972         result = self.client._sort_data_ports_by_speed(
  973             fake.UNSORTED_PORTS_ALL_SPEEDS)
  974 
  975         self.assertSequenceEqual(fake.SORTED_PORTS_ALL_SPEEDS, result)
  976 
  977     def test_list_root_aggregates(self):
  978 
  979         api_response = netapp_api.NaElement(
  980             fake.AGGR_GET_ITER_ROOT_AGGR_RESPONSE)
  981         self.mock_object(self.client,
  982                          'send_iter_request',
  983                          mock.Mock(return_value=api_response))
  984 
  985         result = self.client.list_root_aggregates()
  986 
  987         aggr_get_iter_args = {
  988             'desired-attributes': {
  989                 'aggr-attributes': {
  990                     'aggregate-name': None,
  991                     'aggr-raid-attributes': {
  992                         'has-local-root': None,
  993                         'has-partner-root': None,
  994                     },
  995                 },
  996             }
  997         }
  998         self.assertSequenceEqual(fake.ROOT_AGGREGATE_NAMES, result)
  999         self.client.send_iter_request.assert_has_calls([
 1000             mock.call('aggr-get-iter', aggr_get_iter_args)])
 1001 
 1002     def test_list_non_root_aggregates(self):
 1003 
 1004         api_response = netapp_api.NaElement(
 1005             fake.AGGR_GET_ITER_NON_ROOT_AGGR_RESPONSE)
 1006         self.mock_object(self.client,
 1007                          'send_iter_request',
 1008                          mock.Mock(return_value=api_response))
 1009 
 1010         result = self.client.list_non_root_aggregates()
 1011 
 1012         aggr_get_iter_args = {
 1013             'query': {
 1014                 'aggr-attributes': {
 1015                     'aggr-raid-attributes': {
 1016                         'has-local-root': 'false',
 1017                         'has-partner-root': 'false',
 1018                     }
 1019                 },
 1020             },
 1021             'desired-attributes': {
 1022                 'aggr-attributes': {
 1023                     'aggregate-name': None,
 1024                 },
 1025             },
 1026         }
 1027         self.assertSequenceEqual(fake.SHARE_AGGREGATE_NAMES, result)
 1028         self.client.send_iter_request.assert_has_calls([
 1029             mock.call('aggr-get-iter', aggr_get_iter_args)])
 1030 
 1031     def test_list_aggregates(self):
 1032 
 1033         api_response = netapp_api.NaElement(fake.AGGR_GET_NAMES_RESPONSE)
 1034         self.mock_object(self.client,
 1035                          'send_iter_request',
 1036                          mock.Mock(return_value=api_response))
 1037 
 1038         result = self.client._list_aggregates()
 1039 
 1040         aggr_get_iter_args = {
 1041             'desired-attributes': {
 1042                 'aggr-attributes': {
 1043                     'aggregate-name': None,
 1044                 },
 1045             },
 1046         }
 1047         self.assertSequenceEqual(
 1048             fake.ROOT_AGGREGATE_NAMES + fake.SHARE_AGGREGATE_NAMES, result)
 1049         self.client.send_iter_request.assert_has_calls([
 1050             mock.call('aggr-get-iter', aggr_get_iter_args)])
 1051 
 1052     def test_list_aggregates_not_found(self):
 1053 
 1054         api_response = netapp_api.NaElement(fake.NO_RECORDS_RESPONSE)
 1055         self.mock_object(self.client,
 1056                          'send_request',
 1057                          mock.Mock(return_value=api_response))
 1058 
 1059         self.assertRaises(exception.NetAppException,
 1060                           self.client._list_aggregates)
 1061 
 1062     def test_list_vserver_aggregates(self):
 1063 
 1064         self.mock_object(self.vserver_client,
 1065                          'get_vserver_aggregate_capacities',
 1066                          mock.Mock(return_value=fake.VSERVER_AGGREGATES))
 1067 
 1068         result = self.vserver_client.list_vserver_aggregates()
 1069 
 1070         self.assertListEqual(list(fake.VSERVER_AGGREGATES.keys()), result)
 1071 
 1072     def test_list_vserver_aggregates_none_found(self):
 1073 
 1074         self.mock_object(self.vserver_client,
 1075                          'get_vserver_aggregate_capacities',
 1076                          mock.Mock(return_value={}))
 1077 
 1078         result = self.vserver_client.list_vserver_aggregates()
 1079 
 1080         self.assertListEqual([], result)
 1081 
 1082     @ddt.data((True, True), (True, False), (False, True), (False, False))
 1083     @ddt.unpack
 1084     def test_create_network_interface(self, broadcast_domains_supported,
 1085                                       use_vlans):
 1086 
 1087         self.client.features.add_feature('BROADCAST_DOMAINS',
 1088                                          broadcast_domains_supported)
 1089         self.mock_object(self.client, '_ensure_broadcast_domain_for_port')
 1090         self.mock_object(self.client, '_create_vlan')
 1091         self.mock_object(self.client, 'send_request')
 1092 
 1093         lif_create_args = {
 1094             'address': fake.IP_ADDRESS,
 1095             'administrative-status': 'up',
 1096             'data-protocols': [
 1097                 {'data-protocol': 'nfs'},
 1098                 {'data-protocol': 'cifs'}
 1099             ],
 1100             'home-node': fake.NODE_NAME,
 1101             'home-port': fake.VLAN_PORT if use_vlans else fake.PORT,
 1102             'netmask': fake.NETMASK,
 1103             'interface-name': fake.LIF_NAME,
 1104             'role': 'data',
 1105             'vserver': fake.VSERVER_NAME,
 1106         }
 1107         self.client.create_network_interface(fake.IP_ADDRESS,
 1108                                              fake.NETMASK,
 1109                                              fake.VLAN if use_vlans else None,
 1110                                              fake.NODE_NAME,
 1111                                              fake.PORT,
 1112                                              fake.VSERVER_NAME,
 1113                                              fake.LIF_NAME,
 1114                                              fake.IPSPACE_NAME,
 1115                                              fake.MTU)
 1116 
 1117         if use_vlans:
 1118             self.client._create_vlan.assert_called_with(
 1119                 fake.NODE_NAME, fake.PORT, fake.VLAN)
 1120         else:
 1121             self.assertFalse(self.client._create_vlan.called)
 1122 
 1123         if broadcast_domains_supported:
 1124             self.client._ensure_broadcast_domain_for_port.assert_called_with(
 1125                 fake.NODE_NAME, fake.VLAN_PORT if use_vlans else fake.PORT,
 1126                 fake.MTU, ipspace=fake.IPSPACE_NAME)
 1127         else:
 1128             self.assertFalse(
 1129                 self.client._ensure_broadcast_domain_for_port.called)
 1130 
 1131         self.client.send_request.assert_has_calls([
 1132             mock.call('net-interface-create', lif_create_args)])
 1133 
 1134     def test_create_vlan(self):
 1135 
 1136         self.mock_object(self.client, 'send_request')
 1137 
 1138         vlan_create_args = {
 1139             'vlan-info': {
 1140                 'parent-interface': fake.PORT,
 1141                 'node': fake.NODE_NAME,
 1142                 'vlanid': fake.VLAN
 1143             }
 1144         }
 1145         self.client._create_vlan(fake.NODE_NAME, fake.PORT, fake.VLAN)
 1146 
 1147         self.client.send_request.assert_has_calls([
 1148             mock.call('net-vlan-create', vlan_create_args)])
 1149 
 1150     def test_create_vlan_already_present(self):
 1151 
 1152         self.mock_object(self.client,
 1153                          'send_request',
 1154                          self._mock_api_error(code=netapp_api.EDUPLICATEENTRY))
 1155 
 1156         vlan_create_args = {
 1157             'vlan-info': {
 1158                 'parent-interface': fake.PORT,
 1159                 'node': fake.NODE_NAME,
 1160                 'vlanid': fake.VLAN
 1161             }
 1162         }
 1163         self.client._create_vlan(fake.NODE_NAME, fake.PORT, fake.VLAN)
 1164 
 1165         self.client.send_request.assert_has_calls([
 1166             mock.call('net-vlan-create', vlan_create_args)])
 1167         self.assertEqual(1, client_cmode.LOG.debug.call_count)
 1168 
 1169     def test_create_vlan_api_error(self):
 1170 
 1171         self.mock_object(self.client, 'send_request', self._mock_api_error())
 1172 
 1173         self.assertRaises(exception.NetAppException,
 1174                           self.client._create_vlan,
 1175                           fake.NODE_NAME,
 1176                           fake.PORT,
 1177                           fake.VLAN)
 1178 
 1179     def test_delete_vlan(self):
 1180 
 1181         self.mock_object(self.client, 'send_request')
 1182 
 1183         vlan_delete_args = {
 1184             'vlan-info': {
 1185                 'parent-interface': fake.PORT,
 1186                 'node': fake.NODE_NAME,
 1187                 'vlanid': fake.VLAN
 1188             }
 1189         }
 1190         self.client.delete_vlan(fake.NODE_NAME, fake.PORT, fake.VLAN)
 1191 
 1192         self.client.send_request.assert_has_calls([
 1193             mock.call('net-vlan-delete', vlan_delete_args)])
 1194 
 1195     def test_delete_vlan_still_used(self):
 1196 
 1197         self.mock_object(self.client,
 1198                          'send_request',
 1199                          self._mock_api_error(code=netapp_api.EAPIERROR,
 1200                                               message='Port already has a '
 1201                                               'lif bound. '))
 1202 
 1203         vlan_delete_args = {
 1204             'vlan-info': {
 1205                 'parent-interface': fake.PORT,
 1206                 'node': fake.NODE_NAME,
 1207                 'vlanid': fake.VLAN
 1208             }
 1209         }
 1210         self.client.delete_vlan(fake.NODE_NAME, fake.PORT, fake.VLAN)
 1211 
 1212         self.client.send_request.assert_has_calls([
 1213             mock.call('net-vlan-delete', vlan_delete_args)])
 1214         self.assertEqual(1, client_cmode.LOG.debug.call_count)
 1215 
 1216     def test_delete_vlan_api_error(self):
 1217 
 1218         self.mock_object(self.client, 'send_request', self._mock_api_error())
 1219 
 1220         self.assertRaises(exception.NetAppException,
 1221                           self.client.delete_vlan,
 1222                           fake.NODE_NAME,
 1223                           fake.PORT,
 1224                           fake.VLAN)
 1225 
 1226     @ddt.data(('10.10.10.0/24', '10.10.10.1', False),
 1227               ('fc00::/7', 'fe80::1', False),
 1228               ('0.0.0.0/0', '10.10.10.1', True),
 1229               ('::/0', 'fe80::1', True))
 1230     @ddt.unpack
 1231     def test_create_route(self, subnet, gateway, omit_destination):
 1232         api_response = netapp_api.NaElement(
 1233             fake.NET_ROUTES_CREATE_RESPONSE)
 1234         expected_api_args = {
 1235             'destination': subnet,
 1236             'gateway': gateway,
 1237             'return-record': 'true',
 1238         }
 1239         self.mock_object(
 1240             self.client, 'send_request', mock.Mock(return_value=api_response))
 1241 
 1242         destination = None if omit_destination else subnet
 1243         self.client.create_route(gateway, destination=destination)
 1244 
 1245         self.client.send_request.assert_called_once_with(
 1246             'net-routes-create', expected_api_args)
 1247 
 1248     def test_create_route_duplicate(self):
 1249         self.mock_object(client_cmode.LOG, 'debug')
 1250         expected_api_args = {
 1251             'destination': fake.SUBNET,
 1252             'gateway': fake.GATEWAY,
 1253             'return-record': 'true',
 1254         }
 1255         self.mock_object(
 1256             self.client, 'send_request',
 1257             mock.Mock(side_effect=self._mock_api_error(
 1258                 code=netapp_api.EAPIERROR, message='Duplicate route exists.')))
 1259 
 1260         self.client.create_route(fake.GATEWAY, destination=fake.SUBNET)
 1261 
 1262         self.client.send_request.assert_called_once_with(
 1263             'net-routes-create', expected_api_args)
 1264         self.assertEqual(1, client_cmode.LOG.debug.call_count)
 1265 
 1266     def test_create_route_api_error(self):
 1267         expected_api_args = {
 1268             'destination': fake.SUBNET,
 1269             'gateway': fake.GATEWAY,
 1270             'return-record': 'true',
 1271         }
 1272         self.mock_object(
 1273             self.client, 'send_request',
 1274             mock.Mock(side_effect=self._mock_api_error()))
 1275 
 1276         self.assertRaises(exception.NetAppException,
 1277                           self.client.create_route,
 1278                           fake.GATEWAY, destination=fake.SUBNET)
 1279 
 1280         self.client.send_request.assert_called_once_with(
 1281             'net-routes-create', expected_api_args)
 1282 
 1283     def test_create_route_without_gateway(self):
 1284         self.mock_object(self.client, 'send_request')
 1285         self.client.create_route(None, destination=fake.SUBNET)
 1286         self.assertFalse(self.client.send_request.called)
 1287 
 1288     def test_ensure_broadcast_domain_for_port_domain_match(self):
 1289 
 1290         port_info = {
 1291             'ipspace': fake.IPSPACE_NAME,
 1292             'broadcast-domain': fake.BROADCAST_DOMAIN,
 1293         }
 1294         self.mock_object(self.client,
 1295                          '_get_broadcast_domain_for_port',
 1296                          mock.Mock(return_value=port_info))
 1297         self.mock_object(self.client,
 1298                          '_broadcast_domain_exists',
 1299                          mock.Mock(return_value=True))
 1300         self.mock_object(self.client, '_create_broadcast_domain')
 1301         self.mock_object(self.client, '_modify_broadcast_domain')
 1302         self.mock_object(self.client, '_add_port_to_broadcast_domain')
 1303 
 1304         self.client._ensure_broadcast_domain_for_port(
 1305             fake.NODE_NAME, fake.PORT, fake.MTU, ipspace=fake.IPSPACE_NAME)
 1306 
 1307         self.client._get_broadcast_domain_for_port.assert_called_once_with(
 1308             fake.NODE_NAME, fake.PORT)
 1309         self.client._modify_broadcast_domain.assert_called_once_with(
 1310             fake.BROADCAST_DOMAIN, fake.IPSPACE_NAME, fake.MTU)
 1311         self.assertFalse(self.client._broadcast_domain_exists.called)
 1312         self.assertFalse(self.client._create_broadcast_domain.called)
 1313         self.assertFalse(self.client._add_port_to_broadcast_domain.called)
 1314 
 1315     @ddt.data(fake.IPSPACE_NAME, client_cmode.DEFAULT_IPSPACE)
 1316     def test_ensure_broadcast_domain_for_port_other_domain(self, ipspace):
 1317 
 1318         port_info = {
 1319             'ipspace': ipspace,
 1320             'broadcast-domain': 'other_domain',
 1321         }
 1322         self.mock_object(self.client,
 1323                          '_get_broadcast_domain_for_port',
 1324                          mock.Mock(return_value=port_info))
 1325         self.mock_object(self.client,
 1326                          '_broadcast_domain_exists',
 1327                          mock.Mock(return_value=True))
 1328         self.mock_object(self.client, '_create_broadcast_domain')
 1329         self.mock_object(self.client, '_modify_broadcast_domain')
 1330         self.mock_object(self.client, '_remove_port_from_broadcast_domain')
 1331         self.mock_object(self.client, '_add_port_to_broadcast_domain')
 1332 
 1333         self.client._ensure_broadcast_domain_for_port(
 1334             fake.NODE_NAME, fake.PORT, ipspace=fake.IPSPACE_NAME, mtu=fake.MTU)
 1335 
 1336         self.client._get_broadcast_domain_for_port.assert_called_once_with(
 1337             fake.NODE_NAME, fake.PORT)
 1338         self.client._remove_port_from_broadcast_domain.assert_called_once_with(
 1339             fake.NODE_NAME, fake.PORT, 'other_domain', ipspace)
 1340         self.client._broadcast_domain_exists.assert_called_once_with(
 1341             fake.BROADCAST_DOMAIN, fake.IPSPACE_NAME)
 1342         self.assertFalse(self.client._create_broadcast_domain.called)
 1343         self.client._modify_broadcast_domain.assert_called_once_with(
 1344             fake.BROADCAST_DOMAIN, fake.IPSPACE_NAME, fake.MTU)
 1345         self.client._add_port_to_broadcast_domain.assert_called_once_with(
 1346             fake.NODE_NAME, fake.PORT, fake.BROADCAST_DOMAIN,
 1347             fake.IPSPACE_NAME)
 1348 
 1349     def test_ensure_broadcast_domain_for_port_no_domain(self):
 1350 
 1351         port_info = {
 1352             'ipspace': fake.IPSPACE_NAME,
 1353             'broadcast-domain': None,
 1354         }
 1355         self.mock_object(self.client,
 1356                          '_get_broadcast_domain_for_port',
 1357                          mock.Mock(return_value=port_info))
 1358         self.mock_object(self.client,
 1359                          '_broadcast_domain_exists',
 1360                          mock.Mock(return_value=False))
 1361         self.mock_object(self.client, '_create_broadcast_domain')
 1362         self.mock_object(self.client, '_modify_broadcast_domain')
 1363         self.mock_object(self.client, '_remove_port_from_broadcast_domain')
 1364         self.mock_object(self.client, '_add_port_to_broadcast_domain')
 1365 
 1366         self.client._ensure_broadcast_domain_for_port(
 1367             fake.NODE_NAME, fake.PORT, ipspace=fake.IPSPACE_NAME, mtu=fake.MTU)
 1368 
 1369         self.client._get_broadcast_domain_for_port.assert_called_once_with(
 1370             fake.NODE_NAME, fake.PORT)
 1371         self.assertFalse(self.client._remove_port_from_broadcast_domain.called)
 1372         self.client._broadcast_domain_exists.assert_called_once_with(
 1373             fake.BROADCAST_DOMAIN, fake.IPSPACE_NAME)
 1374         self.client._create_broadcast_domain.assert_called_once_with(
 1375             fake.BROADCAST_DOMAIN, fake.IPSPACE_NAME, fake.MTU)
 1376         self.assertFalse(self.client._modify_broadcast_domain.called)
 1377         self.client._add_port_to_broadcast_domain.assert_called_once_with(
 1378             fake.NODE_NAME, fake.PORT, fake.BROADCAST_DOMAIN,
 1379             fake.IPSPACE_NAME)
 1380 
 1381     def test_get_broadcast_domain_for_port(self):
 1382 
 1383         api_response = netapp_api.NaElement(
 1384             fake.NET_PORT_GET_ITER_BROADCAST_DOMAIN_RESPONSE)
 1385         self.mock_object(self.client,
 1386                          'send_iter_request',
 1387                          mock.Mock(return_value=api_response))
 1388 
 1389         net_port_get_iter_args = {
 1390             'query': {
 1391                 'net-port-info': {
 1392                     'node': fake.NODE_NAME,
 1393                     'port': fake.PORT,
 1394                 },
 1395             },
 1396             'desired-attributes': {
 1397                 'net-port-info': {
 1398                     'broadcast-domain': None,
 1399                     'ipspace': None,
 1400                 },
 1401             },
 1402         }
 1403         result = self.client._get_broadcast_domain_for_port(fake.NODE_NAME,
 1404                                                             fake.PORT)
 1405 
 1406         expected = {
 1407             'broadcast-domain': fake.BROADCAST_DOMAIN,
 1408             'ipspace': fake.IPSPACE_NAME,
 1409         }
 1410         self.client.send_iter_request.assert_has_calls([
 1411             mock.call('net-port-get-iter', net_port_get_iter_args)])
 1412         self.assertEqual(expected, result)
 1413 
 1414     def test_get_broadcast_domain_for_port_port_not_found(self):
 1415 
 1416         api_response = netapp_api.NaElement(
 1417             fake.NO_RECORDS_RESPONSE)
 1418         self.mock_object(self.client,
 1419                          'send_iter_request',
 1420                          mock.Mock(return_value=api_response))
 1421 
 1422         self.assertRaises(exception.NetAppException,
 1423                           self.client._get_broadcast_domain_for_port,
 1424                           fake.NODE_NAME,
 1425                           fake.PORT)
 1426 
 1427     def test_get_broadcast_domain_for_port_domain_not_found(self):
 1428 
 1429         api_response = netapp_api.NaElement(
 1430             fake.NET_PORT_GET_ITER_BROADCAST_DOMAIN_MISSING_RESPONSE)
 1431         self.mock_object(self.client,
 1432                          'send_iter_request',
 1433                          mock.Mock(return_value=api_response))
 1434 
 1435         result = self.client._get_broadcast_domain_for_port(fake.NODE_NAME,
 1436                                                             fake.PORT)
 1437 
 1438         expected = {
 1439             'broadcast-domain': None,
 1440             'ipspace': fake.IPSPACE_NAME,
 1441         }
 1442         self.assertEqual(expected, result)
 1443 
 1444     def test_broadcast_domain_exists(self):
 1445 
 1446         api_response = netapp_api.NaElement(
 1447             fake.NET_PORT_BROADCAST_DOMAIN_GET_ITER_RESPONSE)
 1448         self.mock_object(self.client,
 1449                          'send_iter_request',
 1450                          mock.Mock(return_value=api_response))
 1451 
 1452         result = self.client._broadcast_domain_exists(fake.BROADCAST_DOMAIN,
 1453                                                       fake.IPSPACE_NAME)
 1454 
 1455         net_port_broadcast_domain_get_iter_args = {
 1456             'query': {
 1457                 'net-port-broadcast-domain-info': {
 1458                     'ipspace': fake.IPSPACE_NAME,
 1459                     'broadcast-domain': fake.BROADCAST_DOMAIN,
 1460                 },
 1461             },
 1462             'desired-attributes': {
 1463                 'net-port-broadcast-domain-info': None,
 1464             },
 1465         }
 1466         self.client.send_iter_request.assert_has_calls([
 1467             mock.call('net-port-broadcast-domain-get-iter',
 1468                       net_port_broadcast_domain_get_iter_args)])
 1469         self.assertTrue(result)
 1470 
 1471     def test_broadcast_domain_exists_not_found(self):
 1472 
 1473         api_response = netapp_api.NaElement(
 1474             fake.NO_RECORDS_RESPONSE)
 1475         self.mock_object(self.client,
 1476                          'send_request',
 1477                          mock.Mock(return_value=api_response))
 1478 
 1479         result = self.client._broadcast_domain_exists(fake.BROADCAST_DOMAIN,
 1480                                                       fake.IPSPACE_NAME)
 1481 
 1482         self.assertFalse(result)
 1483 
 1484     def test_create_broadcast_domain(self):
 1485 
 1486         self.mock_object(self.client, 'send_request')
 1487 
 1488         result = self.client._create_broadcast_domain(fake.BROADCAST_DOMAIN,
 1489                                                       fake.IPSPACE_NAME,
 1490                                                       fake.MTU)
 1491 
 1492         net_port_broadcast_domain_create_args = {
 1493             'ipspace': fake.IPSPACE_NAME,
 1494             'broadcast-domain': fake.BROADCAST_DOMAIN,
 1495             'mtu': fake.MTU,
 1496         }
 1497         self.assertIsNone(result)
 1498         self.client.send_request.assert_has_calls([
 1499             mock.call('net-port-broadcast-domain-create',
 1500                       net_port_broadcast_domain_create_args)])
 1501 
 1502     def test_modify_broadcast_domain(self):
 1503 
 1504         self.mock_object(self.client, 'send_request')
 1505 
 1506         result = self.client._modify_broadcast_domain(fake.BROADCAST_DOMAIN,
 1507                                                       fake.IPSPACE_NAME,
 1508                                                       fake.MTU)
 1509 
 1510         net_port_broadcast_domain_modify_args = {
 1511             'ipspace': fake.IPSPACE_NAME,
 1512             'broadcast-domain': fake.BROADCAST_DOMAIN,
 1513             'mtu': fake.MTU,
 1514         }
 1515         self.assertIsNone(result)
 1516         self.client.send_request.assert_called_once_with(
 1517             'net-port-broadcast-domain-modify',
 1518             net_port_broadcast_domain_modify_args)
 1519 
 1520     def test_delete_broadcast_domain(self):
 1521 
 1522         self.mock_object(self.client, 'send_request')
 1523 
 1524         result = self.client._delete_broadcast_domain(fake.BROADCAST_DOMAIN,
 1525                                                       fake.IPSPACE_NAME)
 1526 
 1527         net_port_broadcast_domain_delete_args = {
 1528             'ipspace': fake.IPSPACE_NAME,
 1529             'broadcast-domain': fake.BROADCAST_DOMAIN,
 1530         }
 1531         self.assertIsNone(result)
 1532         self.client.send_request.assert_has_calls([
 1533             mock.call('net-port-broadcast-domain-destroy',
 1534                       net_port_broadcast_domain_delete_args)])
 1535 
 1536     def test_delete_broadcast_domains_for_ipspace_not_found(self):
 1537 
 1538         self.mock_object(self.client,
 1539                          'get_ipspaces',
 1540                          mock.Mock(return_value=[]))
 1541         self.mock_object(self.client, '_delete_broadcast_domain')
 1542 
 1543         self.client._delete_broadcast_domains_for_ipspace(fake.IPSPACE_NAME)
 1544 
 1545         self.client.get_ipspaces.assert_called_once_with(
 1546             ipspace_name=fake.IPSPACE_NAME)
 1547         self.assertFalse(self.client._delete_broadcast_domain.called)
 1548 
 1549     def test_delete_broadcast_domains_for_ipspace(self):
 1550 
 1551         self.mock_object(self.client,
 1552                          'get_ipspaces',
 1553                          mock.Mock(return_value=fake.IPSPACES))
 1554         self.mock_object(self.client, '_delete_broadcast_domain')
 1555 
 1556         self.client._delete_broadcast_domains_for_ipspace(fake.IPSPACE_NAME)
 1557 
 1558         self.client.get_ipspaces.assert_called_once_with(
 1559             ipspace_name=fake.IPSPACE_NAME)
 1560         self.client._delete_broadcast_domain.assert_called_once_with(
 1561             fake.IPSPACES[0]['broadcast-domains'][0], fake.IPSPACE_NAME)
 1562 
 1563     def test_add_port_to_broadcast_domain(self):
 1564 
 1565         self.mock_object(self.client, 'send_request')
 1566 
 1567         add_port_to_broadcast_domain_args = {
 1568             'ipspace': fake.IPSPACE_NAME,
 1569             'broadcast-domain': fake.BROADCAST_DOMAIN,
 1570             'ports': {
 1571                 'net-qualified-port-name': ':'.join([fake.NODE_NAME,
 1572                                                      fake.VLAN_PORT])
 1573             }
 1574         }
 1575         result = self.client._add_port_to_broadcast_domain(
 1576             fake.NODE_NAME, fake.VLAN_PORT, fake.BROADCAST_DOMAIN,
 1577             fake.IPSPACE_NAME)
 1578 
 1579         self.assertIsNone(result)
 1580         self.client.send_request.assert_has_calls([
 1581             mock.call('net-port-broadcast-domain-add-ports',
 1582                       add_port_to_broadcast_domain_args)])
 1583 
 1584     def test_add_port_to_broadcast_domain_already_present(self):
 1585 
 1586         self.mock_object(self.client, 'send_request', self._mock_api_error(
 1587             code=netapp_api.
 1588             E_VIFMGR_PORT_ALREADY_ASSIGNED_TO_BROADCAST_DOMAIN))
 1589 
 1590         result = self.client._add_port_to_broadcast_domain(
 1591             fake.NODE_NAME, fake.VLAN_PORT, fake.BROADCAST_DOMAIN,
 1592             fake.IPSPACE_NAME)
 1593 
 1594         self.assertIsNone(result)
 1595 
 1596     def test_add_port_to_broadcast_domain_api_error(self):
 1597 
 1598         self.mock_object(self.client, 'send_request', self._mock_api_error())
 1599 
 1600         self.assertRaises(exception.NetAppException,
 1601                           self.client._add_port_to_broadcast_domain,
 1602                           fake.NODE_NAME,
 1603                           fake.VLAN_PORT,
 1604                           fake.BROADCAST_DOMAIN,
 1605                           fake.IPSPACE_NAME)
 1606 
 1607     def test_remove_port_from_broadcast_domain(self):
 1608 
 1609         self.mock_object(self.client, 'send_request')
 1610 
 1611         result = self.client._remove_port_from_broadcast_domain(
 1612             fake.NODE_NAME, fake.VLAN_PORT, fake.BROADCAST_DOMAIN,
 1613             fake.IPSPACE_NAME)
 1614 
 1615         net_port_broadcast_domain_remove_ports_args = {
 1616             'ipspace': fake.IPSPACE_NAME,
 1617             'broadcast-domain': fake.BROADCAST_DOMAIN,
 1618             'ports': {
 1619                 'net-qualified-port-name': ':'.join([fake.NODE_NAME,
 1620                                                      fake.VLAN_PORT])
 1621             }
 1622         }
 1623         self.assertIsNone(result)
 1624         self.client.send_request.assert_has_calls([
 1625             mock.call('net-port-broadcast-domain-remove-ports',
 1626                       net_port_broadcast_domain_remove_ports_args)])
 1627 
 1628     def test_network_interface_exists(self):
 1629 
 1630         api_response = netapp_api.NaElement(
 1631             fake.NET_INTERFACE_GET_ONE_RESPONSE)
 1632         self.mock_object(self.client,
 1633                          'send_iter_request',
 1634                          mock.Mock(return_value=api_response))
 1635 
 1636         net_interface_get_args = {
 1637             'query': {
 1638                 'net-interface-info': {
 1639                     'address': fake.IP_ADDRESS,
 1640                     'home-node': fake.NODE_NAME,
 1641                     'home-port': fake.VLAN_PORT,
 1642                     'netmask': fake.NETMASK,
 1643                     'vserver': fake.VSERVER_NAME}
 1644             },
 1645             'desired-attributes': {
 1646                 'net-interface-info': {
 1647                     'interface-name': None,
 1648                 }
 1649             }
 1650         }
 1651         result = self.client.network_interface_exists(
 1652             fake.VSERVER_NAME, fake.NODE_NAME, fake.PORT, fake.IP_ADDRESS,
 1653             fake.NETMASK, fake.VLAN)
 1654 
 1655         self.client.send_iter_request.assert_has_calls([
 1656             mock.call('net-interface-get-iter', net_interface_get_args)])
 1657         self.assertTrue(result)
 1658 
 1659     def test_network_interface_exists_not_found(self):
 1660 
 1661         api_response = netapp_api.NaElement(fake.NO_RECORDS_RESPONSE)
 1662         self.mock_object(self.client,
 1663                          'send_iter_request',
 1664                          mock.Mock(return_value=api_response))
 1665 
 1666         net_interface_get_args = {
 1667             'query': {
 1668                 'net-interface-info': {
 1669                     'address': fake.IP_ADDRESS,
 1670                     'home-node': fake.NODE_NAME,
 1671                     'home-port': fake.PORT,
 1672                     'netmask': fake.NETMASK,
 1673                     'vserver': fake.VSERVER_NAME}
 1674             },
 1675             'desired-attributes': {
 1676                 'net-interface-info': {
 1677                     'interface-name': None,
 1678                 }
 1679             }
 1680         }
 1681         result = self.client.network_interface_exists(
 1682             fake.VSERVER_NAME, fake.NODE_NAME, fake.PORT, fake.IP_ADDRESS,
 1683             fake.NETMASK, None)
 1684         self.client.send_iter_request.assert_has_calls([
 1685             mock.call('net-interface-get-iter', net_interface_get_args)])
 1686         self.assertFalse(result)
 1687 
 1688     def test_list_network_interfaces(self):
 1689 
 1690         api_response = netapp_api.NaElement(
 1691             fake.NET_INTERFACE_GET_ITER_RESPONSE)
 1692         self.mock_object(self.client,
 1693                          'send_iter_request',
 1694                          mock.Mock(return_value=api_response))
 1695 
 1696         net_interface_get_args = {
 1697             'desired-attributes': {
 1698                 'net-interface-info': {
 1699                     'interface-name': None,
 1700                 }
 1701             }
 1702         }
 1703 
 1704         result = self.client.list_network_interfaces()
 1705 
 1706         self.client.send_iter_request.assert_has_calls([
 1707             mock.call('net-interface-get-iter', net_interface_get_args)])
 1708         self.assertSequenceEqual(fake.LIF_NAMES, result)
 1709 
 1710     def test_list_network_interfaces_not_found(self):
 1711 
 1712         api_response = netapp_api.NaElement(fake.NO_RECORDS_RESPONSE)
 1713         self.mock_object(self.client,
 1714                          'send_request',
 1715                          mock.Mock(return_value=api_response))
 1716 
 1717         result = self.client.list_network_interfaces()
 1718 
 1719         self.assertListEqual([], result)
 1720 
 1721     def test_get_network_interfaces(self):
 1722 
 1723         api_response = netapp_api.NaElement(
 1724             fake.NET_INTERFACE_GET_ITER_RESPONSE)
 1725         self.mock_object(self.client,
 1726                          'send_iter_request',
 1727                          mock.Mock(return_value=api_response))
 1728 
 1729         result = self.client.get_network_interfaces()
 1730 
 1731         self.client.send_iter_request.assert_has_calls([
 1732             mock.call('net-interface-get-iter', None)])
 1733         self.assertSequenceEqual(fake.LIFS, result)
 1734 
 1735     def test_get_network_interfaces_filtered_by_protocol(self):
 1736 
 1737         api_response = netapp_api.NaElement(
 1738             fake.NET_INTERFACE_GET_ITER_RESPONSE_NFS)
 1739         self.mock_object(self.client,
 1740                          'send_iter_request',
 1741                          mock.Mock(return_value=api_response))
 1742 
 1743         result = self.client.get_network_interfaces(protocols=['NFS'])
 1744 
 1745         net_interface_get_args = {
 1746             'query': {
 1747                 'net-interface-info': {
 1748                     'data-protocols': {
 1749                         'data-protocol': 'nfs',
 1750                     }
 1751                 }
 1752             }
 1753         }
 1754 
 1755         self.client.send_iter_request.assert_has_calls([
 1756             mock.call('net-interface-get-iter', net_interface_get_args)])
 1757         self.assertListEqual(fake.NFS_LIFS, result)
 1758 
 1759     def test_get_network_interfaces_not_found(self):
 1760 
 1761         api_response = netapp_api.NaElement(fake.NO_RECORDS_RESPONSE)
 1762         self.mock_object(self.client,
 1763                          'send_iter_request',
 1764                          mock.Mock(return_value=api_response))
 1765 
 1766         result = self.client.get_network_interfaces()
 1767 
 1768         self.client.send_iter_request.assert_has_calls([
 1769             mock.call('net-interface-get-iter', None)])
 1770         self.assertListEqual([], result)
 1771 
 1772     def test_get_ipspaces(self):
 1773 
 1774         self.client.features.add_feature('IPSPACES')
 1775         api_response = netapp_api.NaElement(
 1776             fake.NET_IPSPACES_GET_ITER_RESPONSE)
 1777         self.mock_object(self.client,
 1778                          'send_iter_request',
 1779                          mock.Mock(return_value=api_response))
 1780 
 1781         result = self.client.get_ipspaces(ipspace_name=fake.IPSPACE_NAME)
 1782 
 1783         net_ipspaces_get_iter_args = {
 1784             'query': {
 1785                 'net-ipspaces-info': {
 1786                     'ipspace': fake.IPSPACE_NAME,
 1787                 },
 1788             },
 1789         }
 1790         self.client.send_iter_request.assert_has_calls([
 1791             mock.call('net-ipspaces-get-iter', net_ipspaces_get_iter_args)])
 1792         self.assertEqual(fake.IPSPACES, result)
 1793 
 1794     def test_get_ipspaces_not_found(self):
 1795 
 1796         self.client.features.add_feature('IPSPACES')
 1797         api_response = netapp_api.NaElement(fake.NO_RECORDS_RESPONSE)
 1798         self.mock_object(self.client,
 1799                          'send_iter_request',
 1800                          mock.Mock(return_value=api_response))
 1801 
 1802         result = self.client.get_ipspaces()
 1803 
 1804         net_ipspaces_get_iter_args = {}
 1805         self.client.send_iter_request.assert_has_calls([
 1806             mock.call('net-ipspaces-get-iter', net_ipspaces_get_iter_args)])
 1807         self.assertEqual([], result)
 1808 
 1809     def test_get_ipspaces_not_supported(self):
 1810 
 1811         self.mock_object(self.client, 'send_iter_request')
 1812 
 1813         result = self.client.get_ipspaces()
 1814 
 1815         self.assertFalse(self.client.send_iter_request.called)
 1816         self.assertEqual([], result)
 1817 
 1818     @ddt.data((fake.NET_IPSPACES_GET_ITER_RESPONSE, True),
 1819               (fake.NO_RECORDS_RESPONSE, False))
 1820     @ddt.unpack
 1821     def test_ipspace_exists(self, api_response, expected):
 1822 
 1823         self.client.features.add_feature('IPSPACES')
 1824         api_response = netapp_api.NaElement(api_response)
 1825         self.mock_object(self.client,
 1826                          'send_iter_request',
 1827                          mock.Mock(return_value=api_response))
 1828 
 1829         result = self.client.ipspace_exists(fake.IPSPACE_NAME)
 1830 
 1831         net_ipspaces_get_iter_args = {
 1832             'query': {
 1833                 'net-ipspaces-info': {
 1834                     'ipspace': fake.IPSPACE_NAME,
 1835                 },
 1836             },
 1837             'desired-attributes': {
 1838                 'net-ipspaces-info': {
 1839                     'ipspace': None,
 1840                 },
 1841             },
 1842         }
 1843         self.client.send_iter_request.assert_has_calls([
 1844             mock.call('net-ipspaces-get-iter', net_ipspaces_get_iter_args)])
 1845         self.assertEqual(expected, result)
 1846 
 1847     def test_ipspace_exists_not_supported(self):
 1848 
 1849         result = self.client.ipspace_exists(fake.IPSPACE_NAME)
 1850 
 1851         self.assertFalse(result)
 1852 
 1853     def test_create_ipspace(self):
 1854 
 1855         self.mock_object(self.client, 'send_request')
 1856 
 1857         self.client.create_ipspace(fake.IPSPACE_NAME)
 1858 
 1859         net_ipspaces_create_args = {'ipspace': fake.IPSPACE_NAME}
 1860         self.client.send_request.assert_has_calls([
 1861             mock.call('net-ipspaces-create', net_ipspaces_create_args)])
 1862 
 1863     def test_delete_ipspace(self):
 1864 
 1865         mock_delete_broadcast_domains_for_ipspace = self.mock_object(
 1866             self.client, '_delete_broadcast_domains_for_ipspace')
 1867         self.mock_object(self.client, 'send_request')
 1868 
 1869         self.client.delete_ipspace(fake.IPSPACE_NAME)
 1870 
 1871         net_ipspaces_destroy_args = {'ipspace': fake.IPSPACE_NAME}
 1872         mock_delete_broadcast_domains_for_ipspace.assert_called_once_with(
 1873             fake.IPSPACE_NAME)
 1874         self.client.send_request.assert_has_calls([
 1875             mock.call('net-ipspaces-destroy', net_ipspaces_destroy_args)])
 1876 
 1877     def test_get_ipspace_name_for_vlan_port(self):
 1878         self.client.features.add_feature('IPSPACES')
 1879         api_response = netapp_api.NaElement(fake.NET_PORT_GET_RESPONSE)
 1880         self.mock_object(self.client,
 1881                          'send_request',
 1882                          mock.Mock(return_value=api_response))
 1883 
 1884         ipspace = self.client.get_ipspace_name_for_vlan_port(
 1885             fake.NODE_NAME, fake.PORT, fake.VLAN)
 1886 
 1887         port = '%(port)s-%(id)s' % {'port': fake.PORT, 'id': fake.VLAN}
 1888         self.client.send_request.assert_called_once_with(
 1889             'net-port-get',
 1890             {'node': fake.NODE_NAME, 'port': port})
 1891         self.assertEqual(fake.IPSPACE_NAME, ipspace)
 1892 
 1893     def test_get_ipspace_name_for_vlan_port_no_ipspace_feature(self):
 1894         self.mock_object(self.client, 'send_request')
 1895 
 1896         ipspace = self.client.get_ipspace_name_for_vlan_port(
 1897             fake.NODE_NAME, fake.PORT, fake.VLAN)
 1898 
 1899         self.client.send_request.assert_not_called()
 1900         self.assertIsNone(ipspace)
 1901 
 1902     def test_get_ipspace_name_for_vlan_port_no_ipspace_found(self):
 1903         self.client.features.add_feature('IPSPACES')
 1904         self.mock_object(
 1905             self.client,
 1906             'send_request',
 1907             self._mock_api_error(code=netapp_api.EOBJECTNOTFOUND))
 1908 
 1909         ipspace = self.client.get_ipspace_name_for_vlan_port(
 1910             fake.NODE_NAME, fake.PORT, fake.VLAN)
 1911 
 1912         self.assertIsNone(ipspace)
 1913 
 1914     def test_get_ipspace_name_for_vlan_port_no_vlan(self):
 1915         self.client.features.add_feature('IPSPACES')
 1916         api_response = netapp_api.NaElement(fake.NET_PORT_GET_RESPONSE_NO_VLAN)
 1917         self.mock_object(self.client,
 1918                          'send_request',
 1919                          mock.Mock(return_value=api_response))
 1920 
 1921         ipspace = self.client.get_ipspace_name_for_vlan_port(
 1922             fake.NODE_NAME, fake.PORT, None)
 1923 
 1924         self.client.send_request.assert_called_once_with(
 1925             'net-port-get',
 1926             {'node': fake.NODE_NAME, 'port': fake.PORT})
 1927         self.assertEqual(fake.IPSPACE_NAME, ipspace)
 1928 
 1929     def test_get_ipspace_name_for_vlan_port_raises_api_error(self):
 1930         self.client.features.add_feature('IPSPACES')
 1931         self.mock_object(self.client,
 1932                          'send_request',
 1933                          mock.Mock(side_effect=self._mock_api_error()))
 1934 
 1935         self.assertRaises(netapp_api.NaApiError,
 1936                           self.client.get_ipspace_name_for_vlan_port,
 1937                           fake.NODE_NAME, fake.VLAN_PORT, None)
 1938 
 1939     def test_add_vserver_to_ipspace(self):
 1940 
 1941         self.mock_object(self.client, 'send_request')
 1942 
 1943         self.client.add_vserver_to_ipspace(fake.IPSPACE_NAME,
 1944                                            fake.VSERVER_NAME)
 1945 
 1946         net_ipspaces_assign_vserver_args = {
 1947             'ipspace': fake.IPSPACE_NAME,
 1948             'vserver': fake.VSERVER_NAME
 1949         }
 1950         self.client.send_request.assert_has_calls([
 1951             mock.call('net-ipspaces-assign-vserver',
 1952                       net_ipspaces_assign_vserver_args)])
 1953 
 1954     def test_get_node_for_aggregate(self):
 1955 
 1956         api_response = netapp_api.NaElement(
 1957             fake.AGGR_GET_NODE_RESPONSE).get_child_by_name(
 1958             'attributes-list').get_children()
 1959         self.mock_object(self.client,
 1960                          '_get_aggregates',
 1961                          mock.Mock(return_value=api_response))
 1962 
 1963         result = self.client.get_node_for_aggregate(fake.SHARE_AGGREGATE_NAME)
 1964 
 1965         desired_attributes = {
 1966             'aggr-attributes': {
 1967                 'aggregate-name': None,
 1968                 'aggr-ownership-attributes': {
 1969                     'home-name': None,
 1970                 },
 1971             },
 1972         }
 1973 
 1974         self.client._get_aggregates.assert_has_calls([
 1975             mock.call(
 1976                 aggregate_names=[fake.SHARE_AGGREGATE_NAME],
 1977                 desired_attributes=desired_attributes)])
 1978 
 1979         self.assertEqual(fake.NODE_NAME, result)
 1980 
 1981     def test_get_node_for_aggregate_none_requested(self):
 1982 
 1983         result = self.client.get_node_for_aggregate(None)
 1984 
 1985         self.assertIsNone(result)
 1986 
 1987     def test_get_node_for_aggregate_api_not_found(self):
 1988 
 1989         self.mock_object(self.client,
 1990                          'send_iter_request',
 1991                          mock.Mock(side_effect=self._mock_api_error(
 1992                              netapp_api.EAPINOTFOUND)))
 1993 
 1994         result = self.client.get_node_for_aggregate(fake.SHARE_AGGREGATE_NAME)
 1995 
 1996         self.assertIsNone(result)
 1997 
 1998     def test_get_node_for_aggregate_api_error(self):
 1999 
 2000         self.mock_object(self.client,
 2001                          'send_iter_request',
 2002                          self._mock_api_error())
 2003 
 2004         self.assertRaises(netapp_api.NaApiError,
 2005                           self.client.get_node_for_aggregate,
 2006                           fake.SHARE_AGGREGATE_NAME)
 2007 
 2008     def test_get_node_for_aggregate_not_found(self):
 2009 
 2010         api_response = netapp_api.NaElement(fake.NO_RECORDS_RESPONSE)
 2011         self.mock_object(self.client,
 2012                          'send_iter_request',
 2013                          mock.Mock(return_value=api_response))
 2014 
 2015         result = self.client.get_node_for_aggregate(fake.SHARE_AGGREGATE_NAME)
 2016 
 2017         self.assertIsNone(result)
 2018 
 2019     def test_get_cluster_aggregate_capacities(self):
 2020 
 2021         api_response = netapp_api.NaElement(
 2022             fake.AGGR_GET_SPACE_RESPONSE).get_child_by_name(
 2023             'attributes-list').get_children()
 2024         self.mock_object(self.client,
 2025                          '_get_aggregates',
 2026                          mock.Mock(return_value=api_response))
 2027 
 2028         result = self.client.get_cluster_aggregate_capacities(
 2029             fake.SHARE_AGGREGATE_NAMES)
 2030 
 2031         desired_attributes = {
 2032             'aggr-attributes': {
 2033                 'aggregate-name': None,
 2034                 'aggr-space-attributes': {
 2035                     'size-available': None,
 2036                     'size-total': None,
 2037                     'size-used': None,
 2038                 }
 2039             }
 2040         }
 2041 
 2042         self.client._get_aggregates.assert_has_calls([
 2043             mock.call(
 2044                 aggregate_names=fake.SHARE_AGGREGATE_NAMES,
 2045                 desired_attributes=desired_attributes)])
 2046 
 2047         expected = {
 2048             fake.SHARE_AGGREGATE_NAMES[0]: {
 2049                 'available': 45670400,
 2050                 'total': 943718400,
 2051                 'used': 898048000,
 2052             },
 2053             fake.SHARE_AGGREGATE_NAMES[1]: {
 2054                 'available': 4267659264,
 2055                 'total': 7549747200,
 2056                 'used': 3282087936,
 2057             },
 2058         }
 2059         self.assertDictEqual(expected, result)
 2060 
 2061     def test_get_cluster_aggregate_capacities_not_found(self):
 2062 
 2063         api_response = netapp_api.NaElement('none').get_children()
 2064         self.mock_object(self.client,
 2065                          '_get_aggregates',
 2066                          mock.Mock(return_value=api_response))
 2067 
 2068         result = self.client.get_cluster_aggregate_capacities(
 2069             fake.SHARE_AGGREGATE_NAMES)
 2070 
 2071         self.assertEqual({}, result)
 2072 
 2073     def test_get_cluster_aggregate_capacities_none_requested(self):
 2074 
 2075         result = self.client.get_cluster_aggregate_capacities([])
 2076 
 2077         self.assertEqual({}, result)
 2078 
 2079     def test_get_vserver_aggregate_capacities(self):
 2080 
 2081         api_response = netapp_api.NaElement(fake.VSERVER_GET_RESPONSE)
 2082         self.mock_object(self.vserver_client,
 2083                          'send_request',
 2084                          mock.Mock(return_value=api_response))
 2085 
 2086         result = self.vserver_client.get_vserver_aggregate_capacities()
 2087 
 2088         vserver_args = {
 2089             'desired-attributes': {
 2090                 'vserver-info': {
 2091                     'vserver-name': None,
 2092                     'vserver-aggr-info-list': {
 2093                         'vserver-aggr-info': {
 2094                             'aggr-name': None,
 2095                             'aggr-availsize': None
 2096                         }
 2097                     }
 2098                 }
 2099             }
 2100         }
 2101 
 2102         self.vserver_client.send_request.assert_has_calls([
 2103             mock.call('vserver-get', vserver_args)])
 2104         self.assertDictEqual(fake.VSERVER_AGGREGATES, result)
 2105 
 2106     def test_get_vserver_aggregate_capacities_partial_request(self):
 2107 
 2108         api_response = netapp_api.NaElement(fake.VSERVER_GET_RESPONSE)
 2109         self.mock_object(self.vserver_client,
 2110                          'send_request',
 2111                          mock.Mock(return_value=api_response))
 2112 
 2113         result = self.vserver_client.get_vserver_aggregate_capacities(
 2114             fake.SHARE_AGGREGATE_NAMES[0])
 2115 
 2116         expected = {fake.SHARE_AGGREGATE_NAMES[0]:
 2117                     fake.VSERVER_AGGREGATES[fake.SHARE_AGGREGATE_NAMES[0]]}
 2118         self.assertDictEqual(expected, result)
 2119 
 2120     def test_get_vserver_aggregate_capacities_aggregate_not_found(self):
 2121 
 2122         api_response = netapp_api.NaElement(
 2123             fake.VSERVER_GET_RESPONSE_NO_AGGREGATES)
 2124         self.mock_object(self.vserver_client,
 2125                          'send_request',
 2126                          mock.Mock(return_value=api_response))
 2127 
 2128         result = self.vserver_client.get_vserver_aggregate_capacities()
 2129 
 2130         self.assertDictEqual({}, result)
 2131         self.assertEqual(1, client_cmode.LOG.warning.call_count)
 2132 
 2133     def test_get_vserver_aggregate_capacities_vserver_not_found(self):
 2134 
 2135         api_response = netapp_api.NaElement(fake.NO_RECORDS_RESPONSE)
 2136         self.mock_object(self.vserver_client,
 2137                          'send_request',
 2138                          mock.Mock(return_value=api_response))
 2139 
 2140         self.assertRaises(exception.NetAppException,
 2141                           self.vserver_client.get_vserver_aggregate_capacities)
 2142 
 2143     def test_get_vserver_aggregate_capacities_none_requested(self):
 2144 
 2145         result = self.client.get_vserver_aggregate_capacities([])
 2146 
 2147         self.assertEqual({}, result)
 2148 
 2149     def test_get_aggregates(self):
 2150 
 2151         api_response = netapp_api.NaElement(fake.AGGR_GET_ITER_RESPONSE)
 2152         self.mock_object(self.client,
 2153                          'send_iter_request',
 2154                          mock.Mock(return_value=api_response))
 2155 
 2156         result = self.client._get_aggregates()
 2157 
 2158         self.client.send_iter_request.assert_has_calls([
 2159             mock.call('aggr-get-iter', {})])
 2160         self.assertListEqual(
 2161             [aggr.to_string() for aggr in api_response.get_child_by_name(
 2162                 'attributes-list').get_children()],
 2163             [aggr.to_string() for aggr in result])
 2164 
 2165     def test_get_aggregates_with_filters(self):
 2166 
 2167         api_response = netapp_api.NaElement(fake.AGGR_GET_SPACE_RESPONSE)
 2168         self.mock_object(self.client,
 2169                          'send_iter_request',
 2170                          mock.Mock(return_value=api_response))
 2171 
 2172         desired_attributes = {
 2173             'aggr-attributes': {
 2174                 'aggregate-name': None,
 2175                 'aggr-space-attributes': {
 2176                     'size-total': None,
 2177                     'size-available': None,
 2178                 }
 2179             }
 2180         }
 2181 
 2182         result = self.client._get_aggregates(
 2183             aggregate_names=fake.SHARE_AGGREGATE_NAMES,
 2184             desired_attributes=desired_attributes)
 2185 
 2186         aggr_get_iter_args = {
 2187             'query': {
 2188                 'aggr-attributes': {
 2189                     'aggregate-name': '|'.join(fake.SHARE_AGGREGATE_NAMES),
 2190                 }
 2191             },
 2192             'desired-attributes': desired_attributes
 2193         }
 2194 
 2195         self.client.send_iter_request.assert_has_calls([
 2196             mock.call('aggr-get-iter', aggr_get_iter_args)])
 2197         self.assertListEqual(
 2198             [aggr.to_string() for aggr in api_response.get_child_by_name(
 2199                 'attributes-list').get_children()],
 2200             [aggr.to_string() for aggr in result])
 2201 
 2202     def test_get_aggregates_not_found(self):
 2203 
 2204         api_response = netapp_api.NaElement(fake.NO_RECORDS_RESPONSE)
 2205         self.mock_object(self.client,
 2206                          'send_iter_request',
 2207                          mock.Mock(return_value=api_response))
 2208 
 2209         result = self.client._get_aggregates()
 2210 
 2211         self.client.send_iter_request.assert_has_calls([
 2212             mock.call('aggr-get-iter', {})])
 2213         self.assertListEqual([], result)
 2214 
 2215     def test_get_performance_instance_uuids(self):
 2216 
 2217         api_response = netapp_api.NaElement(
 2218             fake.PERF_OBJECT_INSTANCE_LIST_INFO_ITER_RESPONSE)
 2219         self.mock_object(self.client,
 2220                          'send_request',
 2221                          mock.Mock(return_value=api_response))
 2222 
 2223         result = self.client.get_performance_instance_uuids(
 2224             'system', fake.NODE_NAME)
 2225 
 2226         expected = [fake.NODE_NAME + ':kernel:system']
 2227         self.assertEqual(expected, result)
 2228 
 2229         perf_object_instance_list_info_iter_args = {
 2230             'objectname': 'system',
 2231             'query': {
 2232                 'instance-info': {
 2233                     'uuid': fake.NODE_NAME + ':*',
 2234                 }
 2235             }
 2236         }
 2237         self.client.send_request.assert_called_once_with(
 2238             'perf-object-instance-list-info-iter',
 2239             perf_object_instance_list_info_iter_args)
 2240 
 2241     def test_get_performance_counter_info(self):
 2242 
 2243         api_response = netapp_api.NaElement(
 2244             fake.PERF_OBJECT_COUNTER_LIST_INFO_WAFL_RESPONSE)
 2245         self.mock_object(self.client,
 2246                          'send_request',
 2247                          mock.Mock(return_value=api_response))
 2248 
 2249         result = self.client.get_performance_counter_info('wafl',
 2250                                                           'cp_phase_times')
 2251 
 2252         expected = {
 2253             'name': 'cp_phase_times',
 2254             'base-counter': 'total_cp_msecs',
 2255             'labels': fake.PERF_OBJECT_COUNTER_TOTAL_CP_MSECS_LABELS,
 2256         }
 2257         self.assertEqual(expected, result)
 2258 
 2259         perf_object_counter_list_info_args = {'objectname': 'wafl'}
 2260         self.client.send_request.assert_called_once_with(
 2261             'perf-object-counter-list-info',
 2262             perf_object_counter_list_info_args)
 2263 
 2264     def test_get_performance_counter_info_not_found(self):
 2265 
 2266         api_response = netapp_api.NaElement(
 2267             fake.PERF_OBJECT_COUNTER_LIST_INFO_WAFL_RESPONSE)
 2268         self.mock_object(self.client,
 2269                          'send_request',
 2270                          mock.Mock(return_value=api_response))
 2271 
 2272         self.assertRaises(exception.NotFound,
 2273                           self.client.get_performance_counter_info,
 2274                           'wafl',
 2275                           'invalid')
 2276 
 2277     def test_get_performance_counters(self):
 2278 
 2279         api_response = netapp_api.NaElement(
 2280             fake.PERF_OBJECT_GET_INSTANCES_SYSTEM_RESPONSE_CMODE)
 2281         self.mock_object(self.client,
 2282                          'send_request',
 2283                          mock.Mock(return_value=api_response))
 2284 
 2285         instance_uuids = [
 2286             fake.NODE_NAMES[0] + ':kernel:system',
 2287             fake.NODE_NAMES[1] + ':kernel:system',
 2288         ]
 2289         counter_names = ['avg_processor_busy']
 2290         result = self.client.get_performance_counters('system',
 2291                                                       instance_uuids,
 2292                                                       counter_names)
 2293 
 2294         expected = [
 2295             {
 2296                 'avg_processor_busy': '5674745133134',
 2297                 'instance-name': 'system',
 2298                 'instance-uuid': instance_uuids[0],
 2299                 'node-name': fake.NODE_NAMES[0],
 2300                 'timestamp': '1453412013',
 2301             }, {
 2302                 'avg_processor_busy': '4077649009234',
 2303                 'instance-name': 'system',
 2304                 'instance-uuid': instance_uuids[1],
 2305                 'node-name': fake.NODE_NAMES[1],
 2306                 'timestamp': '1453412013'
 2307             },
 2308         ]
 2309         self.assertEqual(expected, result)
 2310 
 2311         perf_object_get_instances_args = {
 2312             'objectname': 'system',
 2313             'instance-uuids': [
 2314                 {'instance-uuid': instance_uuid}
 2315                 for instance_uuid in instance_uuids
 2316             ],
 2317             'counters': [
 2318                 {'counter': counter} for counter in counter_names
 2319             ],
 2320         }
 2321         self.client.send_request.assert_called_once_with(
 2322             'perf-object-get-instances', perf_object_get_instances_args)
 2323 
 2324     def test_setup_security_services_ldap(self):
 2325 
 2326         self.mock_object(self.client, 'send_request')
 2327         self.mock_object(self.vserver_client, 'configure_ldap')
 2328 
 2329         self.client.setup_security_services([fake.LDAP_SECURITY_SERVICE],
 2330                                             self.vserver_client,
 2331                                             fake.VSERVER_NAME)
 2332 
 2333         vserver_modify_args = {
 2334             'name-mapping-switch': [
 2335                 {'nmswitch': 'ldap'},
 2336                 {'nmswitch': 'file'},
 2337             ],
 2338             'name-server-switch': [
 2339                 {'nsswitch': 'ldap'},
 2340                 {'nsswitch': 'file'},
 2341             ],
 2342             'vserver-name': fake.VSERVER_NAME
 2343         }
 2344         self.client.send_request.assert_has_calls([
 2345             mock.call('vserver-modify', vserver_modify_args)])
 2346         self.vserver_client.configure_ldap.assert_has_calls([
 2347             mock.call(fake.LDAP_SECURITY_SERVICE)])
 2348 
 2349     def test_setup_security_services_active_directory(self):
 2350 
 2351         self.mock_object(self.client, 'send_request')
 2352         self.mock_object(self.vserver_client, 'configure_active_directory')
 2353 
 2354         self.client.setup_security_services([fake.CIFS_SECURITY_SERVICE],
 2355                                             self.vserver_client,
 2356                                             fake.VSERVER_NAME)
 2357 
 2358         vserver_modify_args = {
 2359             'name-mapping-switch': [
 2360                 {'nmswitch': 'ldap'},
 2361                 {'nmswitch': 'file'},
 2362             ],
 2363             'name-server-switch': [
 2364                 {'nsswitch': 'ldap'},
 2365                 {'nsswitch': 'file'},
 2366             ],
 2367             'vserver-name': fake.VSERVER_NAME
 2368         }
 2369         self.client.send_request.assert_has_calls([
 2370             mock.call('vserver-modify', vserver_modify_args)])
 2371         self.vserver_client.configure_active_directory.assert_has_calls([
 2372             mock.call(fake.CIFS_SECURITY_SERVICE, fake.VSERVER_NAME)])
 2373 
 2374     def test_setup_security_services_kerberos(self):
 2375 
 2376         self.mock_object(self.client, 'send_request')
 2377         self.mock_object(self.client, 'create_kerberos_realm')
 2378         self.mock_object(self.vserver_client, 'configure_kerberos')
 2379 
 2380         self.client.setup_security_services([fake.KERBEROS_SECURITY_SERVICE],
 2381                                             self.vserver_client,
 2382                                             fake.VSERVER_NAME)
 2383 
 2384         vserver_modify_args = {
 2385             'name-mapping-switch': [
 2386                 {'nmswitch': 'ldap'},
 2387                 {'nmswitch': 'file'},
 2388             ],
 2389             'name-server-switch': [
 2390                 {'nsswitch': 'ldap'},
 2391                 {'nsswitch': 'file'},
 2392             ],
 2393             'vserver-name': fake.VSERVER_NAME
 2394         }
 2395         self.client.send_request.assert_has_calls([
 2396             mock.call('vserver-modify', vserver_modify_args)])
 2397         self.client.create_kerberos_realm.assert_has_calls([
 2398             mock.call(fake.KERBEROS_SECURITY_SERVICE)])
 2399         self.vserver_client.configure_kerberos.assert_has_calls([
 2400             mock.call(fake.KERBEROS_SECURITY_SERVICE, fake.VSERVER_NAME)])
 2401 
 2402     def test_setup_security_services_invalid(self):
 2403 
 2404         self.mock_object(self.client, 'send_request')
 2405 
 2406         self.assertRaises(exception.NetAppException,
 2407                           self.client.setup_security_services,
 2408                           [fake.INVALID_SECURITY_SERVICE],
 2409                           self.vserver_client,
 2410                           fake.VSERVER_NAME)
 2411 
 2412         vserver_modify_args = {
 2413             'name-mapping-switch': [
 2414                 {'nmswitch': 'ldap'},
 2415                 {'nmswitch': 'file'},
 2416             ],
 2417             'name-server-switch': [
 2418                 {'nsswitch': 'ldap'},
 2419                 {'nsswitch': 'file'},
 2420             ],
 2421             'vserver-name': fake.VSERVER_NAME
 2422         }
 2423         self.client.send_request.assert_has_calls([
 2424             mock.call('vserver-modify', vserver_modify_args)])
 2425 
 2426     @ddt.data({'tcp-max-xfer-size': 10000}, {}, None)
 2427     def test_enable_nfs(self, nfs_config):
 2428 
 2429         self.mock_object(self.client, 'send_request')
 2430         self.mock_object(self.client, '_enable_nfs_protocols')
 2431         self.mock_object(self.client, '_create_default_nfs_export_rules')
 2432         self.mock_object(self.client, '_configure_nfs')
 2433 
 2434         self.client.enable_nfs(fake.NFS_VERSIONS, nfs_config)
 2435 
 2436         self.client.send_request.assert_called_once_with('nfs-enable')
 2437         self.client._enable_nfs_protocols.assert_called_once_with(
 2438             fake.NFS_VERSIONS)
 2439         self.client._create_default_nfs_export_rules.assert_called_once_with()
 2440         if nfs_config:
 2441             self.client._configure_nfs.assert_called_once_with(nfs_config)
 2442         else:
 2443             self.client._configure_nfs.assert_not_called()
 2444 
 2445     @ddt.data((True, True, True), (True, False, False), (False, True, True))
 2446     @ddt.unpack
 2447     def test_enable_nfs_protocols(self, v3, v40, v41):
 2448 
 2449         self.mock_object(self.client, 'send_request')
 2450 
 2451         versions = []
 2452         if v3:
 2453             versions.append('nfs3')
 2454         if v40:
 2455             versions.append('nfs4.0')
 2456         if v41:
 2457             versions.append('nfs4.1')
 2458 
 2459         self.client._enable_nfs_protocols(versions)
 2460 
 2461         nfs_service_modify_args = {
 2462             'is-nfsv3-enabled': 'true' if v3 else 'false',
 2463             'is-nfsv40-enabled': 'true' if v40 else 'false',
 2464             'is-nfsv41-enabled': 'true' if v41 else 'false',
 2465             'showmount': 'true',
 2466             'is-v3-ms-dos-client-enabled': 'true',
 2467             'is-nfsv3-connection-drop-enabled': 'false',
 2468             'enable-ejukebox': 'false',
 2469         }
 2470         self.client.send_request.assert_called_once_with(
 2471             'nfs-service-modify', nfs_service_modify_args)
 2472 
 2473     def test_configure_nfs(self):
 2474         fake_nfs = {
 2475             'tcp-max-xfer-size': 10000,
 2476         }
 2477         self.mock_object(self.client, 'send_request')
 2478 
 2479         self.client._configure_nfs(fake_nfs)
 2480 
 2481         self.client.send_request.assert_called_once_with(
 2482             'nfs-service-modify', fake_nfs)
 2483 
 2484     def test_create_default_nfs_export_rules(self):
 2485 
 2486         class CopyingMock(mock.Mock):
 2487             def __call__(self, *args, **kwargs):
 2488                 args = copy.deepcopy(args)
 2489                 kwargs = copy.deepcopy(kwargs)
 2490                 return super(CopyingMock, self).__call__(*args, **kwargs)
 2491 
 2492         self.mock_object(self.client, 'send_request', CopyingMock())
 2493 
 2494         self.client._create_default_nfs_export_rules()
 2495 
 2496         export_rule_create_args = {
 2497             'client-match': '0.0.0.0/0',
 2498             'policy-name': 'default',
 2499             'ro-rule': {
 2500                 'security-flavor': 'any'
 2501             },
 2502             'rw-rule': {
 2503                 'security-flavor': 'never'
 2504             }
 2505         }
 2506         export_rule_create_args2 = export_rule_create_args.copy()
 2507         export_rule_create_args2['client-match'] = '::/0'
 2508         self.client.send_request.assert_has_calls([
 2509             mock.call('export-rule-create', export_rule_create_args),
 2510             mock.call('export-rule-create', export_rule_create_args2)])
 2511 
 2512     def test_configure_ldap(self):
 2513 
 2514         self.mock_object(self.client, 'send_request')
 2515 
 2516         self.client.configure_ldap(fake.LDAP_SECURITY_SERVICE)
 2517 
 2518         config_name = hashlib.md5(
 2519             six.b(fake.LDAP_SECURITY_SERVICE['id'])).hexdigest()
 2520 
 2521         ldap_client_create_args = {
 2522             'ldap-client-config': config_name,
 2523             'servers': {'ip-address': fake.LDAP_SECURITY_SERVICE['server']},
 2524             'tcp-port': '389',
 2525             'schema': 'RFC-2307',
 2526             'bind-password': fake.LDAP_SECURITY_SERVICE['password']
 2527         }
 2528         ldap_config_create_args = {
 2529             'client-config': config_name,
 2530             'client-enabled': 'true'
 2531         }
 2532 
 2533         self.client.send_request.assert_has_calls([
 2534             mock.call('ldap-client-create', ldap_client_create_args),
 2535             mock.call('ldap-config-create', ldap_config_create_args)])
 2536 
 2537     def test_configure_active_directory(self):
 2538 
 2539         self.mock_object(self.client, 'send_request')
 2540         self.mock_object(self.client, 'configure_dns')
 2541         self.mock_object(self.client, 'set_preferred_dc')
 2542 
 2543         self.client.configure_active_directory(fake.CIFS_SECURITY_SERVICE,
 2544                                                fake.VSERVER_NAME)
 2545 
 2546         cifs_server = (fake.VSERVER_NAME[0:8] +
 2547                        '-' +
 2548                        fake.VSERVER_NAME[-6:]).replace('_', '-').upper()
 2549 
 2550         cifs_server_create_args = {
 2551             'admin-username': fake.CIFS_SECURITY_SERVICE['user'],
 2552             'admin-password': fake.CIFS_SECURITY_SERVICE['password'],
 2553             'force-account-overwrite': 'true',
 2554             'cifs-server': cifs_server,
 2555             'organizational-unit': fake.CIFS_SECURITY_SERVICE['ou'],
 2556             'domain': fake.CIFS_SECURITY_SERVICE['domain'],
 2557         }
 2558 
 2559         self.client.configure_dns.assert_called_with(
 2560             fake.CIFS_SECURITY_SERVICE)
 2561         self.client.set_preferred_dc.assert_called_with(
 2562             fake.CIFS_SECURITY_SERVICE)
 2563         self.client.send_request.assert_has_calls([
 2564             mock.call('cifs-server-create', cifs_server_create_args)])
 2565 
 2566     def test_configure_active_directory_api_error(self):
 2567 
 2568         self.mock_object(self.client, 'send_request', self._mock_api_error())
 2569         self.mock_object(self.client, 'configure_dns')
 2570 
 2571         self.assertRaises(exception.NetAppException,
 2572                           self.client.configure_active_directory,
 2573                           fake.CIFS_SECURITY_SERVICE,
 2574                           fake.VSERVER_NAME)
 2575 
 2576     def test_create_kerberos_realm(self):
 2577 
 2578         self.mock_object(self.client, 'send_request')
 2579 
 2580         self.client.create_kerberos_realm(fake.KERBEROS_SECURITY_SERVICE)
 2581 
 2582         kerberos_realm_create_args = {
 2583             'admin-server-ip': fake.KERBEROS_SECURITY_SERVICE['server'],
 2584             'admin-server-port': '749',
 2585             'clock-skew': '5',
 2586             'comment': '',
 2587             'config-name': fake.KERBEROS_SECURITY_SERVICE['id'],
 2588             'kdc-ip': fake.KERBEROS_SECURITY_SERVICE['server'],
 2589             'kdc-port': '88',
 2590             'kdc-vendor': 'other',
 2591             'password-server-ip': fake.KERBEROS_SECURITY_SERVICE['server'],
 2592             'password-server-port': '464',
 2593             'realm': fake.KERBEROS_SECURITY_SERVICE['domain'].upper()
 2594         }
 2595 
 2596         self.client.send_request.assert_has_calls([
 2597             mock.call('kerberos-realm-create', kerberos_realm_create_args)])
 2598 
 2599     def test_create_kerberos_realm_already_present(self):
 2600 
 2601         self.mock_object(self.client,
 2602                          'send_request',
 2603                          self._mock_api_error(code=netapp_api.EDUPLICATEENTRY))
 2604 
 2605         self.client.create_kerberos_realm(fake.KERBEROS_SECURITY_SERVICE)
 2606 
 2607         kerberos_realm_create_args = {
 2608             'admin-server-ip': fake.KERBEROS_SECURITY_SERVICE['server'],
 2609             'admin-server-port': '749',
 2610             'clock-skew': '5',
 2611             'comment': '',
 2612             'config-name': fake.KERBEROS_SECURITY_SERVICE['id'],
 2613             'kdc-ip': fake.KERBEROS_SECURITY_SERVICE['server'],
 2614             'kdc-port': '88',
 2615             'kdc-vendor': 'other',
 2616             'password-server-ip': fake.KERBEROS_SECURITY_SERVICE['server'],
 2617             'password-server-port': '464',
 2618             'realm': fake.KERBEROS_SECURITY_SERVICE['domain'].upper()
 2619         }
 2620 
 2621         self.client.send_request.assert_has_calls([
 2622             mock.call('kerberos-realm-create', kerberos_realm_create_args)])
 2623         self.assertEqual(1, client_cmode.LOG.debug.call_count)
 2624 
 2625     def test_create_kerberos_realm_api_error(self):
 2626 
 2627         self.mock_object(self.client, 'send_request', self._mock_api_error())
 2628 
 2629         self.assertRaises(exception.NetAppException,
 2630                           self.client.create_kerberos_realm,
 2631                           fake.KERBEROS_SECURITY_SERVICE)
 2632 
 2633     def test_configure_kerberos(self):
 2634 
 2635         self.mock_object(self.client, 'send_request')
 2636         self.mock_object(self.client, 'configure_dns')
 2637         self.mock_object(self.client,
 2638                          'list_network_interfaces',
 2639                          mock.Mock(return_value=['lif1', 'lif2']))
 2640 
 2641         self.client.configure_kerberos(
 2642             fake.KERBEROS_SECURITY_SERVICE, fake.VSERVER_NAME)
 2643 
 2644         spn = self.client._get_kerberos_service_principal_name(
 2645             fake.KERBEROS_SECURITY_SERVICE, fake.VSERVER_NAME)
 2646 
 2647         kerberos_config_modify_args1 = {
 2648             'admin-password': fake.KERBEROS_SECURITY_SERVICE['password'],
 2649             'admin-user-name': fake.KERBEROS_SECURITY_SERVICE['user'],
 2650             'interface-name': 'lif1',
 2651             'is-kerberos-enabled': 'true',
 2652             'service-principal-name': spn
 2653         }
 2654         kerberos_config_modify_args2 = {
 2655             'admin-password': fake.KERBEROS_SECURITY_SERVICE['password'],
 2656             'admin-user-name': fake.KERBEROS_SECURITY_SERVICE['user'],
 2657             'interface-name': 'lif2',
 2658             'is-kerberos-enabled': 'true',
 2659             'service-principal-name': spn
 2660         }
 2661 
 2662         self.client.configure_dns.assert_called_with(
 2663             fake.KERBEROS_SECURITY_SERVICE)
 2664         self.client.send_request.assert_has_calls([
 2665             mock.call('kerberos-config-modify',
 2666                       kerberos_config_modify_args1),
 2667             mock.call('kerberos-config-modify',
 2668                       kerberos_config_modify_args2)])
 2669 
 2670     def test_configure_kerberos_no_network_interfaces(self):
 2671 
 2672         self.mock_object(self.client, 'send_request')
 2673         self.mock_object(self.client, 'configure_dns')
 2674         self.mock_object(self.client,
 2675                          'list_network_interfaces',
 2676                          mock.Mock(return_value=[]))
 2677 
 2678         self.assertRaises(exception.NetAppException,
 2679                           self.client.configure_kerberos,
 2680                           fake.KERBEROS_SECURITY_SERVICE,
 2681                           fake.VSERVER_NAME)
 2682 
 2683         self.client.configure_dns.assert_called_with(
 2684             fake.KERBEROS_SECURITY_SERVICE)
 2685 
 2686     def test_get_kerberos_service_principal_name(self):
 2687 
 2688         spn = self.client._get_kerberos_service_principal_name(
 2689             fake.KERBEROS_SECURITY_SERVICE, fake.VSERVER_NAME
 2690         )
 2691         self.assertEqual(fake.KERBEROS_SERVICE_PRINCIPAL_NAME, spn)
 2692 
 2693     def test_configure_dns_for_active_directory(self):
 2694 
 2695         self.mock_object(self.client, 'send_request')
 2696 
 2697         self.client.configure_dns(fake.CIFS_SECURITY_SERVICE)
 2698 
 2699         net_dns_create_args = {
 2700             'domains': {'string': fake.CIFS_SECURITY_SERVICE['domain']},
 2701             'name-servers': [{
 2702                 'ip-address': fake.CIFS_SECURITY_SERVICE['dns_ip']
 2703             }],
 2704             'dns-state': 'enabled'
 2705         }
 2706 
 2707         self.client.send_request.assert_has_calls([
 2708             mock.call('net-dns-create', net_dns_create_args)])
 2709 
 2710     def test_configure_dns_multiple_dns_ip(self):
 2711 
 2712         self.mock_object(self.client, 'send_request')
 2713         mock_dns_ips = ['10.0.0.1', '10.0.0.2', '10.0.0.3']
 2714         security_service = fake.CIFS_SECURITY_SERVICE
 2715         security_service['dns_ip'] = ', '.join(mock_dns_ips)
 2716 
 2717         self.client.configure_dns(security_service)
 2718 
 2719         net_dns_create_args = {
 2720             'domains': {'string': security_service['domain']},
 2721             'dns-state': 'enabled',
 2722             'name-servers': [{'ip-address': dns_ip} for dns_ip in mock_dns_ips]
 2723         }
 2724 
 2725         self.client.send_request.assert_has_calls([
 2726             mock.call('net-dns-create', net_dns_create_args)])
 2727 
 2728     def test_configure_dns_for_kerberos(self):
 2729 
 2730         self.mock_object(self.client, 'send_request')
 2731 
 2732         self.client.configure_dns(fake.KERBEROS_SECURITY_SERVICE)
 2733 
 2734         net_dns_create_args = {
 2735             'domains': {'string': fake.KERBEROS_SECURITY_SERVICE['domain']},
 2736             'name-servers': [{
 2737                 'ip-address': fake.KERBEROS_SECURITY_SERVICE['dns_ip']
 2738             }],
 2739             'dns-state': 'enabled'
 2740         }
 2741 
 2742         self.client.send_request.assert_has_calls([
 2743             mock.call('net-dns-create', net_dns_create_args)])
 2744 
 2745     def test_configure_dns_already_present(self):
 2746 
 2747         self.mock_object(self.client,
 2748                          'send_request',
 2749                          self._mock_api_error(code=netapp_api.EDUPLICATEENTRY))
 2750 
 2751         self.client.configure_dns(fake.KERBEROS_SECURITY_SERVICE)
 2752 
 2753         net_dns_create_args = {
 2754             'domains': {'string': fake.KERBEROS_SECURITY_SERVICE['domain']},
 2755             'name-servers': [{
 2756                 'ip-address': fake.KERBEROS_SECURITY_SERVICE['dns_ip']
 2757             }],
 2758             'dns-state': 'enabled'
 2759         }
 2760 
 2761         self.client.send_request.assert_has_calls([
 2762             mock.call('net-dns-create', net_dns_create_args)])
 2763         self.assertEqual(1, client_cmode.LOG.error.call_count)
 2764 
 2765     def test_configure_dns_api_error(self):
 2766 
 2767         self.mock_object(self.client, 'send_request', self._mock_api_error())
 2768 
 2769         self.assertRaises(exception.NetAppException,
 2770                           self.client.configure_dns,
 2771                           fake.KERBEROS_SECURITY_SERVICE)
 2772 
 2773     @ddt.data(
 2774         {
 2775             'server': '',
 2776             'check_feature': False
 2777         },
 2778         {
 2779             'server': ['10.0.0.2', '10.0.0.3'],
 2780             'check_feature': False
 2781         },
 2782         {
 2783             'server': '10.0.0.1',
 2784             'check_feature': False
 2785         },
 2786         {
 2787             'server': '10.0.0.1',
 2788             'check_feature': True
 2789         }
 2790     )
 2791     @ddt.unpack
 2792     def test_set_preferred_dc(self, server, check_feature):
 2793         if check_feature:
 2794             self.client.features.add_feature('CIFS_DC_ADD_SKIP_CHECK')
 2795 
 2796         self.mock_object(self.client, 'send_request')
 2797         security_service = copy.deepcopy(fake.CIFS_SECURITY_SERVICE)
 2798         security_service['server'] = ', '.join(server)
 2799 
 2800         self.client.set_preferred_dc(security_service)
 2801 
 2802         if server == '':
 2803             self.client.send_request.assert_not_called()
 2804         else:
 2805             preferred_dc_add_args = {
 2806                 'domain': fake.CIFS_SECURITY_SERVICE['domain'],
 2807                 'preferred-dc': [{'string': dc_ip} for dc_ip in server]
 2808             }
 2809 
 2810             if check_feature:
 2811                 preferred_dc_add_args['skip-config-validation'] = 'false'
 2812 
 2813             self.client.send_request.assert_has_calls([
 2814                 mock.call('cifs-domain-preferred-dc-add',
 2815                           preferred_dc_add_args)])
 2816 
 2817     def test_set_preferred_dc_api_error(self):
 2818 
 2819         self.mock_object(self.client, 'send_request', self._mock_api_error())
 2820         security_service = copy.deepcopy(fake.CIFS_SECURITY_SERVICE)
 2821         security_service['server'] = 'fake_server'
 2822 
 2823         self.assertRaises(exception.NetAppException,
 2824                           self.client.set_preferred_dc,
 2825                           security_service)
 2826 
 2827     def test_create_volume(self):
 2828 
 2829         self.mock_object(self.client, 'send_request')
 2830         self.mock_object(self.client, 'update_volume_efficiency_attributes')
 2831 
 2832         self.client.create_volume(
 2833             fake.SHARE_AGGREGATE_NAME, fake.SHARE_NAME, 100)
 2834 
 2835         volume_create_args = {
 2836             'containing-aggr-name': fake.SHARE_AGGREGATE_NAME,
 2837             'size': '100g',
 2838             'volume': fake.SHARE_NAME,
 2839             'volume-type': 'rw',
 2840             'junction-path': '/%s' % fake.SHARE_NAME,
 2841         }
 2842 
 2843         self.client.send_request.assert_called_once_with('volume-create',
 2844                                                          volume_create_args)
 2845 
 2846     @ddt.data({'qos_policy_group_name': None,
 2847                'adaptive_policy_group_name': None},
 2848               {'qos_policy_group_name': fake.QOS_POLICY_GROUP_NAME,
 2849                'adaptive_policy_group_name': None},
 2850               {'qos_policy_group_name': None,
 2851                'adaptive_policy_group_name':
 2852                    fake.ADAPTIVE_QOS_POLICY_GROUP_NAME},
 2853               )
 2854     @ddt.unpack
 2855     def test_create_volume_with_extra_specs(self, qos_policy_group_name,
 2856                                             adaptive_policy_group_name):
 2857         self.client.features.add_feature('ADAPTIVE_QOS')
 2858         self.mock_object(self.client, 'set_volume_max_files')
 2859         self.mock_object(self.client, 'enable_dedup')
 2860         self.mock_object(self.client, 'enable_compression')
 2861         self.mock_object(self.client, 'send_request')
 2862         self.mock_object(
 2863             self.client,
 2864             'get_volume_efficiency_status',
 2865             mock.Mock(return_value={'dedupe': False, 'compression': False}))
 2866 
 2867         self.client.create_volume(
 2868             fake.SHARE_AGGREGATE_NAME, fake.SHARE_NAME, 100,
 2869             thin_provisioned=True, language='en-US',
 2870             snapshot_policy='default', dedup_enabled=True,
 2871             compression_enabled=True, max_files=5000, snapshot_reserve=15,
 2872             qos_policy_group=qos_policy_group_name,
 2873             adaptive_qos_policy_group=adaptive_policy_group_name)
 2874 
 2875         volume_create_args = {
 2876             'containing-aggr-name': fake.SHARE_AGGREGATE_NAME,
 2877             'size': '100g',
 2878             'volume': fake.SHARE_NAME,
 2879             'junction-path': '/%s' % fake.SHARE_NAME,
 2880             'space-reserve': 'none',
 2881             'language-code': 'en-US',
 2882             'volume-type': 'rw',
 2883             'snapshot-policy': 'default',
 2884             'percentage-snapshot-reserve': '15',
 2885         }
 2886 
 2887         if qos_policy_group_name:
 2888             volume_create_args.update(
 2889                 {'qos-policy-group-name': qos_policy_group_name})
 2890         if adaptive_policy_group_name:
 2891             volume_create_args.update(
 2892                 {'qos-adaptive-policy-group-name': adaptive_policy_group_name})
 2893 
 2894         self.client.send_request.assert_called_with('volume-create',
 2895                                                     volume_create_args)
 2896         self.client.set_volume_max_files.assert_called_once_with(
 2897             fake.SHARE_NAME, fake.MAX_FILES)
 2898         self.client.enable_dedup.assert_called_once_with(fake.SHARE_NAME)
 2899         self.client.enable_compression.assert_called_once_with(fake.SHARE_NAME)
 2900 
 2901     def test_create_encrypted_volume(self):
 2902 
 2903         self.mock_object(self.client, 'send_request')
 2904         self.mock_object(self.client, 'update_volume_efficiency_attributes')
 2905         self.client.features.add_feature('FLEXVOL_ENCRYPTION')
 2906 
 2907         self.client.create_volume(
 2908             fake.SHARE_AGGREGATE_NAME, fake.SHARE_NAME, 100, encrypt=True)
 2909 
 2910         volume_create_args = {
 2911             'containing-aggr-name': fake.SHARE_AGGREGATE_NAME,
 2912             'size': '100g',
 2913             'volume': fake.SHARE_NAME,
 2914             'volume-type': 'rw',
 2915             'junction-path': '/%s' % fake.SHARE_NAME,
 2916             'encrypt': 'true',
 2917         }
 2918 
 2919         self.client.send_request.assert_called_once_with('volume-create',
 2920                                                          volume_create_args)
 2921 
 2922     def test_create_non_encrypted_volume(self):
 2923 
 2924         self.mock_object(self.client, 'send_request')
 2925         self.mock_object(self.client, 'update_volume_efficiency_attributes')
 2926         self.client.features.add_feature('FLEXVOL_ENCRYPTION')
 2927 
 2928         self.client.create_volume(
 2929             fake.SHARE_AGGREGATE_NAME, fake.SHARE_NAME, 100, encrypt=False)
 2930 
 2931         volume_create_args = {
 2932             'containing-aggr-name': fake.SHARE_AGGREGATE_NAME,
 2933             'size': '100g',
 2934             'volume': fake.SHARE_NAME,
 2935             'volume-type': 'rw',
 2936             'junction-path': '/%s' % fake.SHARE_NAME,
 2937         }
 2938 
 2939         self.client.send_request.assert_called_once_with('volume-create',
 2940                                                          volume_create_args)
 2941 
 2942     def test_create_encrypted_volume_not_supported(self):
 2943 
 2944         self.assertRaises(exception.NetAppException,
 2945                           self.client.create_volume,
 2946                           fake.SHARE_AGGREGATE_NAME,
 2947                           fake.SHARE_NAME,
 2948                           100,
 2949                           encrypt=True)
 2950 
 2951     def test_is_flexvol_encrypted_unsupported(self):
 2952 
 2953         self.client.features.add_feature('FLEXVOL_ENCRYPTION', supported=False)
 2954 
 2955         result = self.client.is_flexvol_encrypted(fake.SHARE_NAME,
 2956                                                   fake.VSERVER_NAME)
 2957 
 2958         self.assertFalse(result)
 2959 
 2960     def test_is_flexvol_encrypted_no_records_found(self):
 2961 
 2962         api_response = netapp_api.NaElement(fake.NO_RECORDS_RESPONSE)
 2963         self.mock_object(self.client,
 2964                          'send_iter_request',
 2965                          mock.Mock(return_value=api_response))
 2966 
 2967         result = self.client.is_flexvol_encrypted(fake.SHARE_NAME,
 2968                                                   fake.VSERVER_NAME)
 2969 
 2970         self.assertFalse(result)
 2971 
 2972     def test_is_flexvol_encrypted(self):
 2973 
 2974         self.client.features.add_feature('FLEXVOL_ENCRYPTION', supported=True)
 2975         api_response = netapp_api.NaElement(
 2976             fake.GET_VOLUME_FOR_ENCRYPTED_RESPONSE)
 2977         self.mock_object(self.client,
 2978                          'send_iter_request',
 2979                          mock.Mock(return_value=api_response))
 2980 
 2981         result = self.client.is_flexvol_encrypted(fake.SHARE_NAME,
 2982                                                   fake.VSERVER_NAME)
 2983 
 2984         volume_get_iter_args = {
 2985             'query': {
 2986                 'volume-attributes': {
 2987                     'encrypt': 'true',
 2988                     'volume-id-attributes': {
 2989                         'name': fake.SHARE_NAME,
 2990                         'owning-vserver-name': fake.VSERVER_NAME,
 2991                     }
 2992                 }
 2993             },
 2994             'desired-attributes': {
 2995                 'volume-attributes': {
 2996                     'encrypt': None,
 2997                 }
 2998             }
 2999         }
 3000 
 3001         self.client.send_iter_request.assert_called_once_with(
 3002             'volume-get-iter', volume_get_iter_args)
 3003 
 3004         self.assertTrue(result)
 3005 
 3006     def test_is_flexvol_encrypted_8_x_system_version_response(self):
 3007 
 3008         self.client.features.add_feature('FLEXVOL_ENCRYPTION', supported=True)
 3009         api_response = netapp_api.NaElement(
 3010             fake.GET_VOLUME_FOR_ENCRYPTED_OLD_SYS_VERSION_RESPONSE)
 3011         self.mock_object(self.client,
 3012                          'send_iter_request',
 3013                          mock.Mock(return_value=api_response))
 3014 
 3015         result = self.client.is_flexvol_encrypted(fake.SHARE_NAME,
 3016                                                   fake.VSERVER_NAME)
 3017 
 3018         volume_get_iter_args = {
 3019             'query': {
 3020                 'volume-attributes': {
 3021                     'encrypt': 'true',
 3022                     'volume-id-attributes': {
 3023                         'name': fake.SHARE_NAME,
 3024                         'owning-vserver-name': fake.VSERVER_NAME,
 3025                     }
 3026                 }
 3027             },
 3028             'desired-attributes': {
 3029                 'volume-attributes': {
 3030                     'encrypt': None,
 3031                 }
 3032             }
 3033         }
 3034 
 3035         self.client.send_iter_request.assert_called_once_with(
 3036             'volume-get-iter', volume_get_iter_args)
 3037 
 3038         self.assertFalse(result)
 3039 
 3040     def test_enable_dedup(self):
 3041 
 3042         self.mock_object(self.client, 'send_request')
 3043 
 3044         self.client.enable_dedup(fake.SHARE_NAME)
 3045 
 3046         sis_enable_args = {'path': '/vol/%s' % fake.SHARE_NAME}
 3047 
 3048         self.client.send_request.assert_called_once_with('sis-enable',
 3049                                                          sis_enable_args)
 3050 
 3051     def test_disable_dedup(self):
 3052 
 3053         self.mock_object(self.client, 'send_request')
 3054 
 3055         self.client.disable_dedup(fake.SHARE_NAME)
 3056 
 3057         sis_disable_args = {'path': '/vol/%s' % fake.SHARE_NAME}
 3058 
 3059         self.client.send_request.assert_called_once_with('sis-disable',
 3060                                                          sis_disable_args)
 3061 
 3062     def test_enable_compression(self):
 3063 
 3064         self.mock_object(self.client, 'send_request')
 3065 
 3066         self.client.enable_compression(fake.SHARE_NAME)
 3067 
 3068         sis_set_config_args = {
 3069             'path': '/vol/%s' % fake.SHARE_NAME,
 3070             'enable-compression': 'true'
 3071         }
 3072 
 3073         self.client.send_request.assert_called_once_with('sis-set-config',
 3074                                                          sis_set_config_args)
 3075 
 3076     def test_disable_compression(self):
 3077 
 3078         self.mock_object(self.client, 'send_request')
 3079 
 3080         self.client.disable_compression(fake.SHARE_NAME)
 3081 
 3082         sis_set_config_args = {
 3083             'path': '/vol/%s' % fake.SHARE_NAME,
 3084             'enable-compression': 'false'
 3085         }
 3086 
 3087         self.client.send_request.assert_called_once_with('sis-set-config',
 3088                                                          sis_set_config_args)
 3089 
 3090     def test_get_volume_efficiency_status(self):
 3091 
 3092         api_response = netapp_api.NaElement(fake.SIS_GET_ITER_RESPONSE)
 3093         self.mock_object(self.client,
 3094                          'send_iter_request',
 3095                          mock.Mock(return_value=api_response))
 3096 
 3097         result = self.client.get_volume_efficiency_status(fake.SHARE_NAME)
 3098 
 3099         sis_get_iter_args = {
 3100             'query': {
 3101                 'sis-status-info': {
 3102                     'path': '/vol/%s' % fake.SHARE_NAME,
 3103                 },
 3104             },
 3105             'desired-attributes': {
 3106                 'sis-status-info': {
 3107                     'state': None,
 3108                     'is-compression-enabled': None,
 3109                 },
 3110             },
 3111         }
 3112         self.client.send_iter_request.assert_has_calls([
 3113             mock.call('sis-get-iter', sis_get_iter_args)])
 3114 
 3115         expected = {'dedupe': True, 'compression': True}
 3116         self.assertDictEqual(expected, result)
 3117 
 3118     def test_get_volume_efficiency_status_not_found(self):
 3119 
 3120         api_response = netapp_api.NaElement(fake.NO_RECORDS_RESPONSE)
 3121         self.mock_object(self.client,
 3122                          'send_iter_request',
 3123                          mock.Mock(return_value=api_response))
 3124 
 3125         result = self.client.get_volume_efficiency_status(fake.SHARE_NAME)
 3126 
 3127         expected = {'dedupe': False, 'compression': False}
 3128         self.assertDictEqual(expected, result)
 3129 
 3130     def test_set_volume_max_files(self):
 3131 
 3132         self.mock_object(self.client, 'send_request')
 3133 
 3134         self.client.set_volume_max_files(fake.SHARE_NAME, fake.MAX_FILES)
 3135 
 3136         volume_modify_iter_api_args = {
 3137             'query': {
 3138                 'volume-attributes': {
 3139                     'volume-id-attributes': {
 3140                         'name': fake.SHARE_NAME,
 3141                     },
 3142                 },
 3143             },
 3144             'attributes': {
 3145                 'volume-attributes': {
 3146                     'volume-inode-attributes': {
 3147                         'files-total': fake.MAX_FILES,
 3148                     },
 3149                 },
 3150             },
 3151         }
 3152 
 3153         self.client.send_request.assert_called_once_with(
 3154             'volume-modify-iter', volume_modify_iter_api_args)
 3155 
 3156     def test_set_volume_name(self):
 3157 
 3158         self.mock_object(self.client, 'send_request')
 3159 
 3160         self.client.set_volume_name(fake.SHARE_NAME, 'new_name')
 3161 
 3162         volume_rename_api_args = {
 3163             'volume': fake.SHARE_NAME,
 3164             'new-volume-name': 'new_name',
 3165         }
 3166 
 3167         self.client.send_request.assert_called_once_with(
 3168             'volume-rename', volume_rename_api_args)
 3169 
 3170     def test_rename_vserver(self):
 3171 
 3172         vserver_api_args = {
 3173             'vserver-name': fake.VSERVER_NAME,
 3174             'new-name': fake.VSERVER_NAME_2,
 3175         }
 3176         self.mock_object(self.client, 'send_request')
 3177 
 3178         self.client.rename_vserver(fake.VSERVER_NAME, fake.VSERVER_NAME_2)
 3179 
 3180         self.client.send_request.assert_called_once_with(
 3181             'vserver-rename', vserver_api_args
 3182         )
 3183 
 3184     def test_modify_volume_no_optional_args(self):
 3185 
 3186         self.mock_object(self.client, 'send_request')
 3187         mock_update_volume_efficiency_attributes = self.mock_object(
 3188             self.client, 'update_volume_efficiency_attributes')
 3189 
 3190         self.client.modify_volume(fake.SHARE_AGGREGATE_NAME, fake.SHARE_NAME)
 3191 
 3192         volume_modify_iter_api_args = {
 3193             'query': {
 3194                 'volume-attributes': {
 3195                     'volume-id-attributes': {
 3196                         'containing-aggregate-name': fake.SHARE_AGGREGATE_NAME,
 3197                         'name': fake.SHARE_NAME,
 3198                     },
 3199                 },
 3200             },
 3201             'attributes': {
 3202                 'volume-attributes': {
 3203                     'volume-inode-attributes': {},
 3204                     'volume-language-attributes': {},
 3205                     'volume-snapshot-attributes': {},
 3206                     'volume-space-attributes': {
 3207                         'space-guarantee': 'volume',
 3208                     },
 3209                     'volume-autosize-attributes': {},
 3210                 },
 3211             },
 3212         }
 3213 
 3214         self.client.send_request.assert_called_once_with(
 3215             'volume-modify-iter', volume_modify_iter_api_args)
 3216         mock_update_volume_efficiency_attributes.assert_called_once_with(
 3217             fake.SHARE_NAME, False, False)
 3218 
 3219     @ddt.data((fake.QOS_POLICY_GROUP_NAME, None),
 3220               (None, fake.ADAPTIVE_QOS_POLICY_GROUP_NAME))
 3221     @ddt.unpack
 3222     def test_modify_volume_all_optional_args(self, qos_group,
 3223                                              adaptive_qos_group):
 3224         self.client.features.add_feature('ADAPTIVE_QOS')
 3225         self.mock_object(self.client, 'send_request')
 3226         mock_update_volume_efficiency_attributes = self.mock_object(
 3227             self.client, 'update_volume_efficiency_attributes')
 3228 
 3229         self.client.modify_volume(
 3230             fake.SHARE_AGGREGATE_NAME,
 3231             fake.SHARE_NAME,
 3232             thin_provisioned=True,
 3233             snapshot_policy=fake.SNAPSHOT_POLICY_NAME,
 3234             language=fake.LANGUAGE,
 3235             dedup_enabled=True,
 3236             compression_enabled=False,
 3237             max_files=fake.MAX_FILES,
 3238             qos_policy_group=qos_group,
 3239             adaptive_qos_policy_group=adaptive_qos_group,
 3240             autosize_attributes=fake.VOLUME_AUTOSIZE_ATTRS,
 3241             hide_snapdir=True)
 3242 
 3243         volume_modify_iter_api_args = {
 3244             'query': {
 3245                 'volume-attributes': {
 3246                     'volume-id-attributes': {
 3247                         'containing-aggregate-name': fake.SHARE_AGGREGATE_NAME,
 3248                         'name': fake.SHARE_NAME,
 3249                     },
 3250                 },
 3251             },
 3252             'attributes': {
 3253                 'volume-attributes': {
 3254                     'volume-inode-attributes': {
 3255                         'files-total': fake.MAX_FILES,
 3256                     },
 3257                     'volume-language-attributes': {
 3258                         'language': fake.LANGUAGE,
 3259                     },
 3260                     'volume-snapshot-attributes': {
 3261                         'snapshot-policy': fake.SNAPSHOT_POLICY_NAME,
 3262                         'snapdir-access-enabled': 'false'
 3263                     },
 3264                     'volume-space-attributes': {
 3265                         'space-guarantee': 'none',
 3266                     },
 3267                     'volume-autosize-attributes': fake.VOLUME_AUTOSIZE_ATTRS,
 3268                 },
 3269             },
 3270         }
 3271         if qos_group:
 3272             qos_update = {
 3273                 'volume-qos-attributes': {
 3274                     'policy-group-name': qos_group,
 3275                 },
 3276             }
 3277             volume_modify_iter_api_args[
 3278                 'attributes']['volume-attributes'].update(qos_update)
 3279         if adaptive_qos_group:
 3280             qos_update = {
 3281                 'volume-qos-attributes': {
 3282                     'adaptive-policy-group-name': adaptive_qos_group,
 3283                 },
 3284             }
 3285             volume_modify_iter_api_args[
 3286                 'attributes']['volume-attributes'].update(qos_update)
 3287 
 3288         self.client.send_request.assert_called_once_with(
 3289             'volume-modify-iter', volume_modify_iter_api_args)
 3290         mock_update_volume_efficiency_attributes.assert_called_once_with(
 3291             fake.SHARE_NAME, True, False)
 3292 
 3293     @ddt.data(
 3294         {'existing': (True, True), 'desired': (True, True)},
 3295         {'existing': (True, True), 'desired': (False, False)},
 3296         {'existing': (True, True), 'desired': (True, False)},
 3297         {'existing': (True, False), 'desired': (True, False)},
 3298         {'existing': (True, False), 'desired': (False, False)},
 3299         {'existing': (True, False), 'desired': (True, True)},
 3300         {'existing': (False, False), 'desired': (False, False)},
 3301         {'existing': (False, False), 'desired': (True, False)},
 3302         {'existing': (False, False), 'desired': (True, True)},
 3303     )
 3304     @ddt.unpack
 3305     def test_update_volume_efficiency_attributes(self, existing, desired):
 3306 
 3307         existing_dedupe = existing[0]
 3308         existing_compression = existing[1]
 3309         desired_dedupe = desired[0]
 3310         desired_compression = desired[1]
 3311 
 3312         self.mock_object(
 3313             self.client,
 3314             'get_volume_efficiency_status',
 3315             mock.Mock(return_value={'dedupe': existing_dedupe,
 3316                                     'compression': existing_compression}))
 3317         mock_enable_compression = self.mock_object(self.client,
 3318                                                    'enable_compression')
 3319         mock_disable_compression = self.mock_object(self.client,
 3320                                                     'disable_compression')
 3321         mock_enable_dedup = self.mock_object(self.client, 'enable_dedup')
 3322         mock_disable_dedup = self.mock_object(self.client, 'disable_dedup')
 3323 
 3324         self.client.update_volume_efficiency_attributes(
 3325             fake.SHARE_NAME, desired_dedupe, desired_compression)
 3326 
 3327         if existing_dedupe == desired_dedupe:
 3328             self.assertFalse(mock_enable_dedup.called)
 3329             self.assertFalse(mock_disable_dedup.called)
 3330         elif existing_dedupe and not desired_dedupe:
 3331             self.assertFalse(mock_enable_dedup.called)
 3332             self.assertTrue(mock_disable_dedup.called)
 3333         elif not existing_dedupe and desired_dedupe:
 3334             self.assertTrue(mock_enable_dedup.called)
 3335             self.assertFalse(mock_disable_dedup.called)
 3336 
 3337         if existing_compression == desired_compression:
 3338             self.assertFalse(mock_enable_compression.called)
 3339             self.assertFalse(mock_disable_compression.called)
 3340         elif existing_compression and not desired_compression:
 3341             self.assertFalse(mock_enable_compression.called)
 3342             self.assertTrue(mock_disable_compression.called)
 3343         elif not existing_compression and desired_compression:
 3344             self.assertTrue(mock_enable_compression.called)
 3345             self.assertFalse(mock_disable_compression.called)
 3346 
 3347     def test_set_volume_size(self):
 3348 
 3349         api_response = netapp_api.NaElement(fake.VOLUME_MODIFY_ITER_RESPONSE)
 3350         self.mock_object(self.client,
 3351                          'send_request',
 3352                          mock.Mock(return_value=api_response))
 3353 
 3354         self.client.set_volume_size(fake.SHARE_NAME, 10)
 3355 
 3356         volume_modify_iter_args = {
 3357             'query': {
 3358                 'volume-attributes': {
 3359                     'volume-id-attributes': {
 3360                         'name': fake.SHARE_NAME
 3361                     }
 3362                 }
 3363             },
 3364             'attributes': {
 3365                 'volume-attributes': {
 3366                     'volume-space-attributes': {
 3367                         'size': 10737418240,
 3368                     },
 3369                 },
 3370             },
 3371         }
 3372         self.client.send_request.assert_has_calls([
 3373             mock.call('volume-modify-iter', volume_modify_iter_args)])
 3374 
 3375     @ddt.data(True, False)
 3376     def test_set_volume_snapdir_access(self, hide_snapdir):
 3377         api_response = netapp_api.NaElement(
 3378             fake.VOLUME_MODIFY_ITER_RESPONSE)
 3379         self.mock_object(self.client,
 3380                          'send_request',
 3381                          mock.Mock(return_value=api_response))
 3382 
 3383         self.client.set_volume_snapdir_access(fake.SHARE_NAME, hide_snapdir)
 3384 
 3385         api_args = {
 3386             'query': {
 3387                 'volume-attributes': {
 3388                     'volume-id-attributes': {
 3389                         'name': fake.SHARE_NAME
 3390                     }
 3391                 }
 3392             },
 3393             'attributes': {
 3394                 'volume-attributes': {
 3395                     'volume-snapshot-attributes': {
 3396                         'snapdir-access-enabled': six.text_type(
 3397                             not hide_snapdir).lower(),
 3398                     },
 3399                 },
 3400             },
 3401         }
 3402         self.client.send_request.assert_called_once_with(
 3403             'volume-modify-iter', api_args)
 3404 
 3405     def test_set_volume_snapdir_access_api_error(self):
 3406 
 3407         api_response = netapp_api.NaElement(
 3408             fake.VOLUME_MODIFY_ITER_ERROR_RESPONSE)
 3409         self.mock_object(self.client,
 3410                          'send_request',
 3411                          mock.Mock(return_value=api_response))
 3412 
 3413         self.assertRaises(netapp_api.NaApiError,
 3414                           self.client.set_volume_size,
 3415                           fake.SHARE_NAME,
 3416                           10)
 3417 
 3418     @ddt.data(True, False)
 3419     def test_set_volume_filesys_size_fixed(self, filesys_size_fixed):
 3420         api_response = netapp_api.NaElement(
 3421             fake.VOLUME_MODIFY_ITER_RESPONSE)
 3422         self.mock_object(self.client,
 3423                          'send_request',
 3424                          mock.Mock(return_value=api_response))
 3425 
 3426         self.client.set_volume_filesys_size_fixed(fake.SHARE_NAME,
 3427                                                   filesys_size_fixed)
 3428 
 3429         api_args = {
 3430             'query': {
 3431                 'volume-attributes': {
 3432                     'volume-id-attributes': {
 3433                         'name': fake.SHARE_NAME
 3434                     }
 3435                 }
 3436             },
 3437             'attributes': {
 3438                 'volume-attributes': {
 3439                     'volume-space-attributes': {
 3440                         'is-filesys-size-fixed': six.text_type(
 3441                             filesys_size_fixed).lower(),
 3442                     },
 3443                 },
 3444             },
 3445         }
 3446         self.client.send_request.assert_called_once_with(
 3447             'volume-modify-iter', api_args)
 3448 
 3449     def test_set_volume_size_api_error(self):
 3450 
 3451         api_response = netapp_api.NaElement(
 3452             fake.VOLUME_MODIFY_ITER_ERROR_RESPONSE)
 3453         self.mock_object(self.client,
 3454                          'send_request',
 3455                          mock.Mock(return_value=api_response))
 3456 
 3457         self.assertRaises(netapp_api.NaApiError,
 3458                           self.client.set_volume_size,
 3459                           fake.SHARE_NAME,
 3460                           10)
 3461 
 3462     @ddt.data(None, 'ntfs')
 3463     def test_set_volume_security_style(self, security_style):
 3464 
 3465         api_response = netapp_api.NaElement(fake.VOLUME_MODIFY_ITER_RESPONSE)
 3466         self.mock_object(self.client,
 3467                          'send_request',
 3468                          mock.Mock(return_value=api_response))
 3469         kwargs = {'security_style': security_style} if security_style else {}
 3470 
 3471         self.client.set_volume_security_style(fake.SHARE_NAME, **kwargs)
 3472 
 3473         volume_modify_iter_args = {
 3474             'query': {
 3475                 'volume-attributes': {
 3476                     'volume-id-attributes': {
 3477                         'name': fake.SHARE_NAME
 3478                     }
 3479                 }
 3480             },
 3481             'attributes': {
 3482                 'volume-attributes': {
 3483                     'volume-security-attributes': {
 3484                         'style': security_style or 'unix',
 3485                     },
 3486                 },
 3487             },
 3488         }
 3489         self.client.send_request.assert_called_once_with(
 3490             'volume-modify-iter', volume_modify_iter_args)
 3491 
 3492     def test_set_volume_security_style_api_error(self):
 3493 
 3494         api_response = netapp_api.NaElement(
 3495             fake.VOLUME_MODIFY_ITER_ERROR_RESPONSE)
 3496         self.mock_object(self.client,
 3497                          'send_request',
 3498                          mock.Mock(return_value=api_response))
 3499 
 3500         self.assertRaises(netapp_api.NaApiError,
 3501                           self.client.set_volume_security_style,
 3502                           fake.SHARE_NAME,
 3503                           'ntfs')
 3504 
 3505     def test_volume_exists(self):
 3506 
 3507         api_response = netapp_api.NaElement(fake.VOLUME_GET_NAME_RESPONSE)
 3508         self.mock_object(self.client,
 3509                          'send_iter_request',
 3510                          mock.Mock(return_value=api_response))
 3511 
 3512         result = self.client.volume_exists(fake.SHARE_NAME)
 3513 
 3514         volume_get_iter_args = {
 3515             'query': {
 3516                 'volume-attributes': {
 3517                     'volume-id-attributes': {
 3518                         'name': fake.SHARE_NAME
 3519                     }
 3520                 }
 3521             },
 3522             'desired-attributes': {
 3523                 'volume-attributes': {
 3524                     'volume-id-attributes': {
 3525                         'name': None
 3526                     }
 3527                 }
 3528             }
 3529         }
 3530 
 3531         self.client.send_iter_request.assert_has_calls([
 3532             mock.call('volume-get-iter', volume_get_iter_args)])
 3533         self.assertTrue(result)
 3534 
 3535     def test_volume_exists_not_found(self):
 3536 
 3537         api_response = netapp_api.NaElement(fake.NO_RECORDS_RESPONSE)
 3538         self.mock_object(self.client,
 3539                          'send_request',
 3540                          mock.Mock(return_value=api_response))
 3541 
 3542         self.assertFalse(self.client.volume_exists(fake.SHARE_NAME))
 3543 
 3544     def test_snapshot_exists(self):
 3545 
 3546         api_response = netapp_api.NaElement(fake.VOLUME_GET_NAME_RESPONSE)
 3547         self.mock_object(self.client,
 3548                          'send_request',
 3549                          mock.Mock(return_value=api_response))
 3550 
 3551         result = self.client.snapshot_exists(fake.SNAPSHOT_NAME,
 3552                                              fake.SHARE_NAME)
 3553 
 3554         snapshot_get_iter_args = {
 3555             'query': {
 3556                 'snapshot-info': {
 3557                     'name': fake.SNAPSHOT_NAME,
 3558                     'volume': fake.SHARE_NAME,
 3559                 }
 3560             },
 3561             'desired-attributes': {
 3562                 'snapshot-info': {
 3563                     'name': None,
 3564                     'volume': None,
 3565                     'busy': None,
 3566                     'snapshot-owners-list': {
 3567                         'snapshot-owner': None,
 3568                     }
 3569                 }
 3570             }
 3571         }
 3572 
 3573         self.client.send_request.assert_has_calls([
 3574             mock.call('snapshot-get-iter', snapshot_get_iter_args)])
 3575         self.assertTrue(result)
 3576 
 3577     def test_snapshot_exists_not_found(self):
 3578         api_response = netapp_api.NaElement(fake.NO_RECORDS_RESPONSE)
 3579         self.mock_object(self.client,
 3580                          'send_request',
 3581                          mock.Mock(return_value=api_response))
 3582 
 3583         self.assertFalse(self.client.snapshot_exists(fake.SNAPSHOT_NAME,
 3584                                                      fake.SHARE_NAME))
 3585 
 3586     @ddt.data({
 3587         'api_response_xml': fake.SNAPSHOT_GET_ITER_UNAVAILABLE_RESPONSE,
 3588         'raised_exception': exception.SnapshotUnavailable,
 3589     }, {
 3590         'api_response_xml': fake.SNAPSHOT_GET_ITER_OTHER_ERROR_RESPONSE,
 3591         'raised_exception': exception.NetAppException,
 3592     })
 3593     @ddt.unpack
 3594     def test_snapshot_exists_error(self, api_response_xml, raised_exception):
 3595 
 3596         api_response = netapp_api.NaElement(api_response_xml)
 3597         self.mock_object(self.client,
 3598                          'send_request',
 3599                          mock.Mock(return_value=api_response))
 3600 
 3601         self.assertRaises(raised_exception,
 3602                           self.client.snapshot_exists,
 3603                           fake.SNAPSHOT_NAME,
 3604                           fake.SHARE_NAME)
 3605 
 3606     def test_get_aggregate_for_volume(self):
 3607 
 3608         api_response = netapp_api.NaElement(
 3609             fake.GET_AGGREGATE_FOR_VOLUME_RESPONSE)
 3610         self.mock_object(self.client,
 3611                          'send_iter_request',
 3612                          mock.Mock(return_value=api_response))
 3613 
 3614         result = self.client.get_aggregate_for_volume(fake.SHARE_NAME)
 3615 
 3616         volume_get_iter_args = {
 3617             'query': {
 3618                 'volume-attributes': {
 3619                     'volume-id-attributes': {
 3620                         'name': fake.SHARE_NAME
 3621                     }
 3622                 }
 3623             },
 3624             'desired-attributes': {
 3625                 'volume-attributes': {
 3626                     'volume-id-attributes': {
 3627                         'containing-aggregate-name': None,
 3628                         'name': None
 3629                     }
 3630                 }
 3631             }
 3632         }
 3633 
 3634         self.client.send_iter_request.assert_has_calls([
 3635             mock.call('volume-get-iter', volume_get_iter_args)])
 3636         self.assertEqual(fake.SHARE_AGGREGATE_NAME, result)
 3637 
 3638     def test_get_aggregate_for_volume_not_found(self):
 3639 
 3640         api_response = netapp_api.NaElement(fake.NO_RECORDS_RESPONSE)
 3641         self.mock_object(self.client,
 3642                          'send_iter_request',
 3643                          mock.Mock(return_value=api_response))
 3644 
 3645         self.assertRaises(exception.NetAppException,
 3646                           self.client.get_aggregate_for_volume,
 3647                           fake.SHARE_NAME)
 3648 
 3649     def test_volume_has_luns(self):
 3650 
 3651         api_response = netapp_api.NaElement(fake.LUN_GET_ITER_RESPONSE)
 3652         self.mock_object(self.client,
 3653                          'send_iter_request',
 3654                          mock.Mock(return_value=api_response))
 3655 
 3656         result = self.client.volume_has_luns(fake.SHARE_NAME)
 3657 
 3658         lun_get_iter_args = {
 3659             'query': {
 3660                 'lun-info': {
 3661                     'volume': fake.SHARE_NAME,
 3662                 },
 3663             },
 3664             'desired-attributes': {
 3665                 'lun-info': {
 3666                     'path': None,
 3667                 },
 3668             },
 3669         }
 3670 
 3671         self.client.send_iter_request.assert_has_calls([
 3672             mock.call('lun-get-iter', lun_get_iter_args)])
 3673         self.assertTrue(result)
 3674 
 3675     def test_volume_has_luns_not_found(self):
 3676 
 3677         api_response = netapp_api.NaElement(fake.NO_RECORDS_RESPONSE)
 3678         self.mock_object(self.client,
 3679                          'send_request',
 3680                          mock.Mock(return_value=api_response))
 3681 
 3682         result = self.client.volume_has_luns(fake.SHARE_NAME)
 3683 
 3684         self.assertFalse(result)
 3685 
 3686     def test_volume_has_junctioned_volumes(self):
 3687 
 3688         api_response = netapp_api.NaElement(
 3689             fake.VOLUME_GET_ITER_JUNCTIONED_VOLUMES_RESPONSE)
 3690         self.mock_object(self.client,
 3691                          'send_iter_request',
 3692                          mock.Mock(return_value=api_response))
 3693 
 3694         fake_junction_path = '/%s' % fake.SHARE_NAME
 3695         self.mock_object(self.client,
 3696                          'get_volume_junction_path',
 3697                          mock.Mock(return_value=fake_junction_path))
 3698 
 3699         result = self.client.volume_has_junctioned_volumes(fake.SHARE_NAME)
 3700 
 3701         volume_get_iter_args = {
 3702             'query': {
 3703                 'volume-attributes': {
 3704                     'volume-id-attributes': {
 3705                         'junction-path': fake_junction_path + '/*',
 3706                     },
 3707                 },
 3708             },
 3709             'desired-attributes': {
 3710                 'volume-attributes': {
 3711                     'volume-id-attributes': {
 3712                         'name': None,
 3713                     },
 3714                 },
 3715             },
 3716         }
 3717         self.client.send_iter_request.assert_has_calls([
 3718             mock.call('volume-get-iter', volume_get_iter_args)])
 3719         self.assertTrue(result)
 3720 
 3721     def test_volume_has_junctioned_volumes_no_junction_path(self):
 3722 
 3723         self.mock_object(self.client,
 3724                          'get_volume_junction_path',
 3725                          mock.Mock(return_value=''))
 3726 
 3727         result = self.client.volume_has_junctioned_volumes(fake.SHARE_NAME)
 3728 
 3729         self.assertFalse(result)
 3730 
 3731     def test_volume_has_junctioned_volumes_not_found(self):
 3732 
 3733         api_response = netapp_api.NaElement(fake.NO_RECORDS_RESPONSE)
 3734         self.mock_object(self.client,
 3735                          'send_request',
 3736                          mock.Mock(return_value=api_response))
 3737 
 3738         fake_junction_path = '/%s' % fake.SHARE_NAME
 3739         self.mock_object(self.client,
 3740                          'get_volume_junction_path',
 3741                          mock.Mock(return_value=fake_junction_path))
 3742 
 3743         result = self.client.volume_has_junctioned_volumes(fake.SHARE_NAME)
 3744 
 3745         self.assertFalse(result)
 3746 
 3747     def test_get_volume(self):
 3748 
 3749         api_response = netapp_api.NaElement(
 3750             fake.VOLUME_GET_ITER_VOLUME_TO_MANAGE_RESPONSE)
 3751         self.mock_object(self.client,
 3752                          'send_request',
 3753                          mock.Mock(return_value=api_response))
 3754 
 3755         result = self.client.get_volume(fake.SHARE_NAME)
 3756 
 3757         volume_get_iter_args = {
 3758             'query': {
 3759                 'volume-attributes': {
 3760                     'volume-id-attributes': {
 3761                         'name': fake.SHARE_NAME,
 3762                     },
 3763                 },
 3764             },
 3765             'desired-attributes': {
 3766                 'volume-attributes': {
 3767                     'volume-id-attributes': {
 3768                         'containing-aggregate-name': None,
 3769                         'junction-path': None,
 3770                         'name': None,
 3771                         'owning-vserver-name': None,
 3772                         'type': None,
 3773                         'style': None,
 3774                     },
 3775                     'volume-space-attributes': {
 3776                         'size': None,
 3777                     },
 3778                     'volume-qos-attributes': {
 3779                         'policy-group-name': None,
 3780                     },
 3781                 },
 3782             },
 3783         }
 3784 
 3785         expected = {
 3786             'aggregate': fake.SHARE_AGGREGATE_NAME,
 3787             'junction-path': '/%s' % fake.SHARE_NAME,
 3788             'name': fake.SHARE_NAME,
 3789             'type': 'rw',
 3790             'style': 'flex',
 3791             'size': fake.SHARE_SIZE,
 3792             'owning-vserver-name': fake.VSERVER_NAME,
 3793             'qos-policy-group-name': fake.QOS_POLICY_GROUP_NAME,
 3794         }
 3795         self.client.send_request.assert_has_calls([
 3796             mock.call('volume-get-iter', volume_get_iter_args)])
 3797         self.assertDictEqual(expected, result)
 3798 
 3799     def test_get_volume_no_qos(self):
 3800         api_response = netapp_api.NaElement(
 3801             fake.VOLUME_GET_ITER_NO_QOS_RESPONSE)
 3802         self.mock_object(self.client,
 3803                          'send_request',
 3804                          mock.Mock(return_value=api_response))
 3805 
 3806         result = self.client.get_volume(fake.SHARE_NAME)
 3807 
 3808         volume_get_iter_args = {
 3809             'query': {
 3810                 'volume-attributes': {
 3811                     'volume-id-attributes': {
 3812                         'name': fake.SHARE_NAME,
 3813                     },
 3814                 },
 3815             },
 3816             'desired-attributes': {
 3817                 'volume-attributes': {
 3818                     'volume-id-attributes': {
 3819                         'containing-aggregate-name': None,
 3820                         'junction-path': None,
 3821                         'name': None,
 3822                         'owning-vserver-name': None,
 3823                         'type': None,
 3824                         'style': None,
 3825                     },
 3826                     'volume-space-attributes': {
 3827                         'size': None,
 3828                     },
 3829                     'volume-qos-attributes': {
 3830                         'policy-group-name': None,
 3831                     },
 3832                 },
 3833             },
 3834         }
 3835 
 3836         expected = {
 3837             'aggregate': fake.SHARE_AGGREGATE_NAME,
 3838             'junction-path': '/%s' % fake.SHARE_NAME,
 3839             'name': fake.SHARE_NAME,
 3840             'type': 'rw',
 3841             'style': 'flex',
 3842             'size': fake.SHARE_SIZE,
 3843             'owning-vserver-name': fake.VSERVER_NAME,
 3844             'qos-policy-group-name': None,
 3845         }
 3846         self.client.send_request.assert_has_calls([
 3847             mock.call('volume-get-iter', volume_get_iter_args)])
 3848         self.assertDictEqual(expected, result)
 3849 
 3850     def test_get_volume_not_found(self):
 3851 
 3852         api_response = netapp_api.NaElement(fake.NO_RECORDS_RESPONSE)
 3853         self.mock_object(self.client,
 3854                          'send_request',
 3855                          mock.Mock(return_value=api_response))
 3856 
 3857         self.assertRaises(exception.StorageResourceNotFound,
 3858                           self.client.get_volume,
 3859                           fake.SHARE_NAME)
 3860 
 3861     def test_get_volume_not_unique(self):
 3862 
 3863         api_response = netapp_api.NaElement(
 3864             fake.VOLUME_GET_ITER_NOT_UNIQUE_RESPONSE)
 3865         self.mock_object(self.client,
 3866                          'send_request',
 3867                          mock.Mock(return_value=api_response))
 3868 
 3869         self.assertRaises(exception.NetAppException,
 3870                           self.client.get_volume,
 3871                           fake.SHARE_NAME)
 3872 
 3873     def test_get_volume_at_junction_path(self):
 3874 
 3875         api_response = netapp_api.NaElement(
 3876             fake.VOLUME_GET_ITER_VOLUME_TO_MANAGE_RESPONSE)
 3877         self.mock_object(self.client,
 3878                          'send_iter_request',
 3879                          mock.Mock(return_value=api_response))
 3880         fake_junction_path = '/%s' % fake.SHARE_NAME
 3881 
 3882         result = self.client.get_volume_at_junction_path(fake_junction_path)
 3883 
 3884         volume_get_iter_args = {
 3885             'query': {
 3886                 'volume-attributes': {
 3887                     'volume-id-attributes': {
 3888                         'junction-path': fake_junction_path,
 3889                     },
 3890                 },
 3891             },
 3892             'desired-attributes': {
 3893                 'volume-attributes': {
 3894                     'volume-id-attributes': {
 3895                         'containing-aggregate-name': None,
 3896                         'junction-path': None,
 3897                         'name': None,
 3898                         'type': None,
 3899                         'style': None,
 3900                     },
 3901                     'volume-space-attributes': {
 3902                         'size': None,
 3903                     }
 3904                 },
 3905             },
 3906         }
 3907         expected = {
 3908             'aggregate': fake.SHARE_AGGREGATE_NAME,
 3909             'junction-path': fake_junction_path,
 3910             'name': fake.SHARE_NAME,
 3911             'type': 'rw',
 3912             'style': 'flex',
 3913             'size': fake.SHARE_SIZE,
 3914         }
 3915         self.client.send_iter_request.assert_has_calls([
 3916             mock.call('volume-get-iter', volume_get_iter_args)])
 3917         self.assertDictEqual(expected, result)
 3918 
 3919     def test_get_volume_at_junction_path_not_specified(self):
 3920 
 3921         result = self.client.get_volume_at_junction_path(None)
 3922 
 3923         self.assertIsNone(result)
 3924 
 3925     def test_get_volume_at_junction_path_not_found(self):
 3926 
 3927         api_response = netapp_api.NaElement(fake.NO_RECORDS_RESPONSE)
 3928         self.mock_object(self.client,
 3929                          'send_iter_request',
 3930                          mock.Mock(return_value=api_response))
 3931         fake_junction_path = '/%s' % fake.SHARE_NAME
 3932 
 3933         result = self.client.get_volume_at_junction_path(fake_junction_path)
 3934 
 3935         self.assertIsNone(result)
 3936 
 3937     def test_get_volume_to_manage(self):
 3938 
 3939         api_response = netapp_api.NaElement(
 3940             fake.VOLUME_GET_ITER_VOLUME_TO_MANAGE_RESPONSE)
 3941         self.mock_object(self.client,
 3942                          'send_iter_request',
 3943                          mock.Mock(return_value=api_response))
 3944 
 3945         result = self.client.get_volume_to_manage(fake.SHARE_AGGREGATE_NAME,
 3946                                                   fake.SHARE_NAME)
 3947 
 3948         volume_get_iter_args = {
 3949             'query': {
 3950                 'volume-attributes': {
 3951                     'volume-id-attributes': {
 3952                         'containing-aggregate-name': fake.SHARE_AGGREGATE_NAME,
 3953                         'name': fake.SHARE_NAME,
 3954                     },
 3955                 },
 3956             },
 3957             'desired-attributes': {
 3958                 'volume-attributes': {
 3959                     'volume-id-attributes': {
 3960                         'containing-aggregate-name': None,
 3961                         'junction-path': None,
 3962                         'name': None,
 3963                         'type': None,
 3964                         'style': None,
 3965                         'owning-vserver-name': None,
 3966                     },
 3967                     'volume-space-attributes': {
 3968                         'size': None,
 3969                     },
 3970                     'volume-qos-attributes': {
 3971                         'policy-group-name': None,
 3972                     },
 3973                 },
 3974             },
 3975         }
 3976         expected = {
 3977             'aggregate': fake.SHARE_AGGREGATE_NAME,
 3978             'junction-path': '/%s' % fake.SHARE_NAME,
 3979             'name': fake.SHARE_NAME,
 3980             'type': 'rw',
 3981             'style': 'flex',
 3982             'size': fake.SHARE_SIZE,
 3983             'owning-vserver-name': fake.VSERVER_NAME,
 3984             'qos-policy-group-name': fake.QOS_POLICY_GROUP_NAME,
 3985         }
 3986         self.client.send_iter_request.assert_has_calls([
 3987             mock.call('volume-get-iter', volume_get_iter_args)])
 3988         self.assertDictEqual(expected, result)
 3989 
 3990     def test_get_volume_to_manage_not_found(self):
 3991 
 3992         api_response = netapp_api.NaElement(fake.NO_RECORDS_RESPONSE)
 3993         self.mock_object(self.client,
 3994                          'send_iter_request',
 3995                          mock.Mock(return_value=api_response))
 3996 
 3997         result = self.client.get_volume_to_manage(fake.SHARE_AGGREGATE_NAME,
 3998                                                   fake.SHARE_NAME)
 3999 
 4000         self.assertIsNone(result)
 4001 
 4002     @ddt.data({'qos_policy_group_name': None,
 4003                'adaptive_qos_policy_group_name': None},
 4004               {'qos_policy_group_name': fake.QOS_POLICY_GROUP_NAME,
 4005                'adaptive_qos_policy_group_name': None},
 4006               {'qos_policy_group_name': None,
 4007                'adaptive_qos_policy_group_name':
 4008                    fake.ADAPTIVE_QOS_POLICY_GROUP_NAME},
 4009               )
 4010     @ddt.unpack
 4011     def test_create_volume_clone(self, qos_policy_group_name,
 4012                                  adaptive_qos_policy_group_name):
 4013         self.client.features.add_feature('ADAPTIVE_QOS')
 4014         self.mock_object(self.client, 'send_request')
 4015         self.mock_object(self.client, 'split_volume_clone')
 4016         set_qos_adapt_mock = self.mock_object(
 4017             self.client,
 4018             'set_qos_adaptive_policy_group_for_volume')
 4019 
 4020         self.client.create_volume_clone(
 4021             fake.SHARE_NAME,
 4022             fake.PARENT_SHARE_NAME,
 4023             fake.PARENT_SNAPSHOT_NAME,
 4024             qos_policy_group=qos_policy_group_name,
 4025             adaptive_qos_policy_group=adaptive_qos_policy_group_name)
 4026 
 4027         volume_clone_create_args = {
 4028             'volume': fake.SHARE_NAME,
 4029             'parent-volume': fake.PARENT_SHARE_NAME,
 4030             'parent-snapshot': fake.PARENT_SNAPSHOT_NAME,
 4031             'junction-path': '/%s' % fake.SHARE_NAME
 4032         }
 4033 
 4034         if qos_policy_group_name:
 4035             volume_clone_create_args.update(
 4036                 {'qos-policy-group-name': fake.QOS_POLICY_GROUP_NAME})
 4037         if adaptive_qos_policy_group_name:
 4038             set_qos_adapt_mock.assert_called_once_with(
 4039                 fake.SHARE_NAME, fake.ADAPTIVE_QOS_POLICY_GROUP_NAME
 4040             )
 4041         self.client.send_request.assert_has_calls([
 4042             mock.call('volume-clone-create', volume_clone_create_args)])
 4043         self.assertFalse(self.client.split_volume_clone.called)
 4044 
 4045     @ddt.data(True, False)
 4046     def test_create_volume_clone_split(self, split):
 4047 
 4048         self.mock_object(self.client, 'send_request')
 4049         self.mock_object(self.client, 'split_volume_clone')
 4050 
 4051         self.client.create_volume_clone(fake.SHARE_NAME,
 4052                                         fake.PARENT_SHARE_NAME,
 4053                                         fake.PARENT_SNAPSHOT_NAME,
 4054                                         split=split)
 4055 
 4056         volume_clone_create_args = {
 4057             'volume': fake.SHARE_NAME,
 4058             'parent-volume': fake.PARENT_SHARE_NAME,
 4059             'parent-snapshot': fake.PARENT_SNAPSHOT_NAME,
 4060             'junction-path': '/%s' % fake.SHARE_NAME
 4061         }
 4062 
 4063         self.client.send_request.assert_has_calls([
 4064             mock.call('volume-clone-create', volume_clone_create_args)])
 4065         if split:
 4066             self.client.split_volume_clone.assert_called_once_with(
 4067                 fake.SHARE_NAME)
 4068         else:
 4069             self.assertFalse(self.client.split_volume_clone.called)
 4070 
 4071     @ddt.data(None,
 4072               mock.Mock(side_effect=netapp_api.NaApiError(
 4073                   code=netapp_api.EVOL_CLONE_BEING_SPLIT)))
 4074     def test_split_volume_clone(self, side_effect):
 4075 
 4076         self.mock_object(
 4077             self.client, 'send_request',
 4078             mock.Mock(side_effect=side_effect))
 4079 
 4080         self.client.split_volume_clone(fake.SHARE_NAME)
 4081 
 4082         volume_clone_split_args = {'volume': fake.SHARE_NAME}
 4083 
 4084         self.client.send_request.assert_has_calls([
 4085             mock.call('volume-clone-split-start', volume_clone_split_args)])
 4086 
 4087     def test_split_volume_clone_api_error(self):
 4088 
 4089         self.mock_object(self.client,
 4090                          'send_request',
 4091                          mock.Mock(side_effect=self._mock_api_error()))
 4092 
 4093         self.assertRaises(netapp_api.NaApiError,
 4094                           self.client.split_volume_clone,
 4095                           fake.SHARE_NAME)
 4096 
 4097     def test_get_clone_children_for_snapshot(self):
 4098 
 4099         api_response = netapp_api.NaElement(
 4100             fake.VOLUME_GET_ITER_CLONE_CHILDREN_RESPONSE)
 4101         self.mock_object(self.client,
 4102                          'send_iter_request',
 4103                          mock.Mock(return_value=api_response))
 4104 
 4105         result = self.client.get_clone_children_for_snapshot(
 4106             fake.SHARE_NAME, fake.SNAPSHOT_NAME)
 4107 
 4108         volume_get_iter_args = {
 4109             'query': {
 4110                 'volume-attributes': {
 4111                     'volume-clone-attributes': {
 4112                         'volume-clone-parent-attributes': {
 4113                             'name': fake.SHARE_NAME,
 4114                             'snapshot-name': fake.SNAPSHOT_NAME,
 4115                         },
 4116                     },
 4117                 },
 4118             },
 4119             'desired-attributes': {
 4120                 'volume-attributes': {
 4121                     'volume-id-attributes': {
 4122                         'name': None,
 4123                     },
 4124                 },
 4125             },
 4126         }
 4127         self.client.send_iter_request.assert_has_calls([
 4128             mock.call('volume-get-iter', volume_get_iter_args)])
 4129 
 4130         expected = [
 4131             {'name': fake.CLONE_CHILD_1},
 4132             {'name': fake.CLONE_CHILD_2},
 4133         ]
 4134         self.assertEqual(expected, result)
 4135 
 4136     def test_get_clone_children_for_snapshot_not_found(self):
 4137 
 4138         api_response = netapp_api.NaElement(fake.NO_RECORDS_RESPONSE)
 4139         self.mock_object(self.client,
 4140                          'send_iter_request',
 4141                          mock.Mock(return_value=api_response))
 4142 
 4143         result = self.client.get_clone_children_for_snapshot(
 4144             fake.SHARE_NAME, fake.SNAPSHOT_NAME)
 4145 
 4146         self.assertEqual([], result)
 4147 
 4148     def test_get_volume_junction_path(self):
 4149 
 4150         api_response = netapp_api.NaElement(
 4151             fake.VOLUME_GET_VOLUME_PATH_RESPONSE)
 4152         self.mock_object(self.client,
 4153                          'send_request',
 4154                          mock.Mock(return_value=api_response))
 4155 
 4156         result = self.client.get_volume_junction_path(fake.SHARE_NAME)
 4157 
 4158         volume_get_volume_path_args = {
 4159             'volume': fake.SHARE_NAME,
 4160             'is-style-cifs': 'false'
 4161         }
 4162 
 4163         self.client.send_request.assert_has_calls([
 4164             mock.call('volume-get-volume-path', volume_get_volume_path_args)])
 4165         self.assertEqual(fake.VOLUME_JUNCTION_PATH, result)
 4166 
 4167     def test_get_volume_junction_path_cifs(self):
 4168 
 4169         api_response = netapp_api.NaElement(
 4170             fake.VOLUME_GET_VOLUME_PATH_CIFS_RESPONSE)
 4171         self.mock_object(self.client,
 4172                          'send_request',
 4173                          mock.Mock(return_value=api_response))
 4174 
 4175         result = self.client.get_volume_junction_path(fake.SHARE_NAME,
 4176                                                       is_style_cifs=True)
 4177 
 4178         volume_get_volume_path_args = {
 4179             'volume': fake.SHARE_NAME,
 4180             'is-style-cifs': 'true'
 4181         }
 4182 
 4183         self.client.send_request.assert_has_calls([
 4184             mock.call('volume-get-volume-path', volume_get_volume_path_args)])
 4185         self.assertEqual(fake.VOLUME_JUNCTION_PATH_CIFS, result)
 4186 
 4187     def test_mount_volume_default_junction_path(self):
 4188 
 4189         self.mock_object(self.client, 'send_request')
 4190 
 4191         self.client.mount_volume(fake.SHARE_NAME)
 4192 
 4193         volume_mount_args = {
 4194             'volume-name': fake.SHARE_NAME,
 4195             'junction-path': '/%s' % fake.SHARE_NAME,
 4196         }
 4197 
 4198         self.client.send_request.assert_has_calls([
 4199             mock.call('volume-mount', volume_mount_args)])
 4200 
 4201     def test_mount_volume(self):
 4202 
 4203         self.mock_object(self.client, 'send_request')
 4204         fake_path = '/fake_path'
 4205 
 4206         self.client.mount_volume(fake.SHARE_NAME, junction_path=fake_path)
 4207 
 4208         volume_mount_args = {
 4209             'volume-name': fake.SHARE_NAME,
 4210             'junction-path': fake_path,
 4211         }
 4212 
 4213         self.client.send_request.assert_has_calls([
 4214             mock.call('volume-mount', volume_mount_args)])
 4215 
 4216     def test_offline_volume(self):
 4217 
 4218         self.mock_object(self.client, 'send_request')
 4219 
 4220         self.client.offline_volume(fake.SHARE_NAME)
 4221 
 4222         volume_offline_args = {'name': fake.SHARE_NAME}
 4223 
 4224         self.client.send_request.assert_has_calls([
 4225             mock.call('volume-offline', volume_offline_args)])
 4226 
 4227     def test_offline_volume_already_offline(self):
 4228 
 4229         self.mock_object(self.client,
 4230                          'send_request',
 4231                          mock.Mock(side_effect=self._mock_api_error(
 4232                              netapp_api.EVOLUMEOFFLINE)))
 4233 
 4234         self.client.offline_volume(fake.SHARE_NAME)
 4235 
 4236         volume_offline_args = {'name': fake.SHARE_NAME}
 4237 
 4238         self.client.send_request.assert_has_calls([
 4239             mock.call('volume-offline', volume_offline_args)])
 4240 
 4241     def test_offline_volume_api_error(self):
 4242 
 4243         self.mock_object(self.client,
 4244                          'send_request',
 4245                          mock.Mock(side_effect=self._mock_api_error()))
 4246 
 4247         self.assertRaises(netapp_api.NaApiError,
 4248                           self.client.offline_volume,
 4249                           fake.SHARE_NAME)
 4250 
 4251     def test__unmount_volume(self):
 4252 
 4253         self.mock_object(self.client, 'send_request')
 4254 
 4255         self.client._unmount_volume(fake.SHARE_NAME)
 4256 
 4257         volume_unmount_args = {
 4258             'volume-name': fake.SHARE_NAME,
 4259             'force': 'false'
 4260         }
 4261 
 4262         self.client.send_request.assert_has_calls([
 4263             mock.call('volume-unmount', volume_unmount_args)])
 4264 
 4265     def test__unmount_volume_force(self):
 4266 
 4267         self.mock_object(self.client, 'send_request')
 4268 
 4269         self.client._unmount_volume(fake.SHARE_NAME, force=True)
 4270 
 4271         volume_unmount_args = {'volume-name': fake.SHARE_NAME, 'force': 'true'}
 4272 
 4273         self.client.send_request.assert_has_calls([
 4274             mock.call('volume-unmount', volume_unmount_args)])
 4275 
 4276     def test__unmount_volume_already_unmounted(self):
 4277 
 4278         self.mock_object(self.client,
 4279                          'send_request',
 4280                          mock.Mock(side_effect=self._mock_api_error(
 4281                              netapp_api.EVOL_NOT_MOUNTED)))
 4282 
 4283         self.client._unmount_volume(fake.SHARE_NAME, force=True)
 4284 
 4285         volume_unmount_args = {'volume-name': fake.SHARE_NAME, 'force': 'true'}
 4286 
 4287         self.client.send_request.assert_has_calls([
 4288             mock.call('volume-unmount', volume_unmount_args)])
 4289 
 4290     def test__unmount_volume_api_error(self):
 4291 
 4292         self.mock_object(self.client,
 4293                          'send_request',
 4294                          mock.Mock(side_effect=self._mock_api_error()))
 4295 
 4296         self.assertRaises(netapp_api.NaApiError,
 4297                           self.client._unmount_volume,
 4298                           fake.SHARE_NAME,
 4299                           force=True)
 4300 
 4301     def test_unmount_volume(self):
 4302 
 4303         self.mock_object(self.client, '_unmount_volume')
 4304 
 4305         self.client.unmount_volume(fake.SHARE_NAME)
 4306 
 4307         self.client._unmount_volume.assert_called_once_with(fake.SHARE_NAME,
 4308                                                             force=False)
 4309         self.assertEqual(1, client_cmode.LOG.debug.call_count)
 4310         self.assertEqual(0, client_cmode.LOG.warning.call_count)
 4311 
 4312     def test_unmount_volume_api_error(self):
 4313 
 4314         self.mock_object(self.client,
 4315                          '_unmount_volume',
 4316                          self._mock_api_error())
 4317 
 4318         self.assertRaises(netapp_api.NaApiError,
 4319                           self.client.unmount_volume,
 4320                           fake.SHARE_NAME)
 4321 
 4322         self.assertEqual(1, self.client._unmount_volume.call_count)
 4323         self.assertEqual(0, client_cmode.LOG.debug.call_count)
 4324         self.assertEqual(0, client_cmode.LOG.warning.call_count)
 4325 
 4326     def test_unmount_volume_with_retries(self):
 4327 
 4328         side_effect = [netapp_api.NaApiError(code=netapp_api.EAPIERROR,
 4329                                              message='...job ID...')] * 5
 4330         side_effect.append(None)
 4331         self.mock_object(self.client,
 4332                          '_unmount_volume',
 4333                          mock.Mock(side_effect=side_effect))
 4334         self.mock_object(time, 'sleep')
 4335 
 4336         self.client.unmount_volume(fake.SHARE_NAME)
 4337 
 4338         self.assertEqual(6, self.client._unmount_volume.call_count)
 4339         self.assertEqual(1, client_cmode.LOG.debug.call_count)
 4340         self.assertEqual(5, client_cmode.LOG.warning.call_count)
 4341 
 4342     def test_unmount_volume_with_max_retries(self):
 4343 
 4344         side_effect = [netapp_api.NaApiError(code=netapp_api.EAPIERROR,
 4345                                              message='...job ID...')] * 30
 4346         self.mock_object(self.client,
 4347                          '_unmount_volume',
 4348                          mock.Mock(side_effect=side_effect))
 4349         self.mock_object(time, 'sleep')
 4350 
 4351         self.assertRaises(exception.NetAppException,
 4352                           self.client.unmount_volume,
 4353                           fake.SHARE_NAME)
 4354 
 4355         self.assertEqual(10, self.client._unmount_volume.call_count)
 4356         self.assertEqual(0, client_cmode.LOG.debug.call_count)
 4357         self.assertEqual(10, client_cmode.LOG.warning.call_count)
 4358 
 4359     def test_delete_volume(self):
 4360 
 4361         self.mock_object(self.client, 'send_request')
 4362 
 4363         self.client.delete_volume(fake.SHARE_NAME)
 4364 
 4365         volume_destroy_args = {'name': fake.SHARE_NAME}
 4366 
 4367         self.client.send_request.assert_has_calls([
 4368             mock.call('volume-destroy', volume_destroy_args)])
 4369 
 4370     def test_create_snapshot(self):
 4371 
 4372         self.mock_object(self.client, 'send_request')
 4373 
 4374         self.client.create_snapshot(fake.SHARE_NAME, fake.SNAPSHOT_NAME)
 4375 
 4376         snapshot_create_args = {
 4377             'volume': fake.SHARE_NAME,
 4378             'snapshot': fake.SNAPSHOT_NAME
 4379         }
 4380 
 4381         self.client.send_request.assert_has_calls([
 4382             mock.call('snapshot-create', snapshot_create_args)])
 4383 
 4384     @ddt.data({
 4385         'mock_return': fake.SNAPSHOT_GET_ITER_NOT_BUSY_RESPONSE,
 4386         'expected': {
 4387             'access-time': fake.SNAPSHOT_ACCESS_TIME,
 4388             'name': fake.SNAPSHOT_NAME,
 4389             'volume': fake.SHARE_NAME,
 4390             'busy': False,
 4391             'owners': set(),
 4392         }
 4393     }, {
 4394         'mock_return': fake.SNAPSHOT_GET_ITER_BUSY_RESPONSE,
 4395         'expected': {
 4396             'access-time': fake.SNAPSHOT_ACCESS_TIME,
 4397             'name': fake.SNAPSHOT_NAME,
 4398             'volume': fake.SHARE_NAME,
 4399             'busy': True,
 4400             'owners': {'volume clone'},
 4401         }
 4402     })
 4403     @ddt.unpack
 4404     def test_get_snapshot(self, mock_return, expected):
 4405 
 4406         api_response = netapp_api.NaElement(mock_return)
 4407         self.mock_object(self.client,
 4408                          'send_request',
 4409                          mock.Mock(return_value=api_response))
 4410 
 4411         result = self.client.get_snapshot(fake.SHARE_NAME, fake.SNAPSHOT_NAME)
 4412 
 4413         snapshot_get_iter_args = {
 4414             'query': {
 4415                 'snapshot-info': {
 4416                     'name': fake.SNAPSHOT_NAME,
 4417                     'volume': fake.SHARE_NAME,
 4418                 },
 4419             },
 4420             'desired-attributes': {
 4421                 'snapshot-info': {
 4422                     'access-time': None,
 4423                     'name': None,
 4424                     'volume': None,
 4425                     'busy': None,
 4426                     'snapshot-owners-list': {
 4427                         'snapshot-owner': None,
 4428                     }
 4429                 },
 4430             },
 4431         }
 4432         self.client.send_request.assert_has_calls([
 4433             mock.call('snapshot-get-iter', snapshot_get_iter_args)])
 4434         self.assertDictEqual(expected, result)
 4435 
 4436     @ddt.data({
 4437         'api_response_xml': fake.NO_RECORDS_RESPONSE,
 4438         'raised_exception': exception.SnapshotResourceNotFound,
 4439     }, {
 4440         'api_response_xml': fake.SNAPSHOT_GET_ITER_NOT_UNIQUE_RESPONSE,
 4441         'raised_exception': exception.NetAppException,
 4442     }, {
 4443         'api_response_xml': fake.SNAPSHOT_GET_ITER_UNAVAILABLE_RESPONSE,
 4444         'raised_exception': exception.SnapshotUnavailable,
 4445     }, {
 4446         'api_response_xml': fake.SNAPSHOT_GET_ITER_OTHER_ERROR_RESPONSE,
 4447         'raised_exception': exception.NetAppException,
 4448     })
 4449     @ddt.unpack
 4450     def test_get_snapshot_error(self, api_response_xml, raised_exception):
 4451 
 4452         api_response = netapp_api.NaElement(api_response_xml)
 4453         self.mock_object(self.client,
 4454                          'send_request',
 4455                          mock.Mock(return_value=api_response))
 4456 
 4457         self.assertRaises(raised_exception,
 4458                           self.client.get_snapshot,
 4459                           fake.SHARE_NAME,
 4460                           fake.SNAPSHOT_NAME)
 4461 
 4462     def test_rename_snapshot(self):
 4463 
 4464         self.mock_object(self.client, 'send_request')
 4465 
 4466         self.client.rename_snapshot(fake.SHARE_NAME,
 4467                                     fake.SNAPSHOT_NAME,
 4468                                     'new_snapshot_name')
 4469 
 4470         snapshot_rename_args = {
 4471             'volume': fake.SHARE_NAME,
 4472             'current-name': fake.SNAPSHOT_NAME,
 4473             'new-name': 'new_snapshot_name'
 4474         }
 4475         self.client.send_request.assert_has_calls([
 4476             mock.call('snapshot-rename', snapshot_rename_args)])
 4477 
 4478     def test_restore_snapshot(self):
 4479 
 4480         self.mock_object(self.client, 'send_request')
 4481 
 4482         self.client.restore_snapshot(fake.SHARE_NAME,
 4483                                      fake.SNAPSHOT_NAME)
 4484 
 4485         snapshot_restore_args = {
 4486             'volume': fake.SHARE_NAME,
 4487             'snapshot': fake.SNAPSHOT_NAME,
 4488         }
 4489         self.client.send_request.assert_has_calls([
 4490             mock.call('snapshot-restore-volume', snapshot_restore_args)])
 4491 
 4492     @ddt.data(True, False)
 4493     def test_delete_snapshot(self, ignore_owners):
 4494 
 4495         self.mock_object(self.client, 'send_request')
 4496 
 4497         self.client.delete_snapshot(
 4498             fake.SHARE_NAME, fake.SNAPSHOT_NAME, ignore_owners=ignore_owners)
 4499 
 4500         snapshot_delete_args = {
 4501             'volume': fake.SHARE_NAME,
 4502             'snapshot': fake.SNAPSHOT_NAME,
 4503             'ignore-owners': 'true' if ignore_owners else 'false',
 4504         }
 4505 
 4506         self.client.send_request.assert_has_calls([
 4507             mock.call('snapshot-delete', snapshot_delete_args)])
 4508 
 4509     def test_soft_delete_snapshot(self):
 4510 
 4511         mock_delete_snapshot = self.mock_object(self.client, 'delete_snapshot')
 4512         mock_rename_snapshot = self.mock_object(self.client, 'rename_snapshot')
 4513 
 4514         self.client.soft_delete_snapshot(fake.SHARE_NAME, fake.SNAPSHOT_NAME)
 4515 
 4516         mock_delete_snapshot.assert_called_once_with(
 4517             fake.SHARE_NAME, fake.SNAPSHOT_NAME)
 4518         self.assertFalse(mock_rename_snapshot.called)
 4519 
 4520     def test_soft_delete_snapshot_api_error(self):
 4521 
 4522         mock_delete_snapshot = self.mock_object(
 4523             self.client, 'delete_snapshot', self._mock_api_error())
 4524         mock_rename_snapshot = self.mock_object(self.client, 'rename_snapshot')
 4525 
 4526         self.client.soft_delete_snapshot(fake.SHARE_NAME, fake.SNAPSHOT_NAME)
 4527 
 4528         mock_delete_snapshot.assert_called_once_with(
 4529             fake.SHARE_NAME, fake.SNAPSHOT_NAME)
 4530         mock_rename_snapshot.assert_called_once_with(
 4531             fake.SHARE_NAME, fake.SNAPSHOT_NAME,
 4532             'deleted_manila_' + fake.SNAPSHOT_NAME)
 4533 
 4534     def test_prune_deleted_snapshots(self):
 4535 
 4536         deleted_snapshots_map = {
 4537             'vserver1': [{
 4538                 'name': 'deleted_snap_1',
 4539                 'volume': 'fake_volume_1',
 4540                 'vserver': 'vserver1',
 4541             }],
 4542             'vserver2': [{
 4543                 'name': 'deleted_snap_2',
 4544                 'volume': 'fake_volume_2',
 4545                 'vserver': 'vserver2',
 4546             }],
 4547         }
 4548         mock_get_deleted_snapshots = self.mock_object(
 4549             self.client, '_get_deleted_snapshots',
 4550             mock.Mock(return_value=deleted_snapshots_map))
 4551         mock_delete_snapshot = self.mock_object(
 4552             self.client, 'delete_snapshot',
 4553             mock.Mock(side_effect=[None, netapp_api.NaApiError]))
 4554         self.mock_object(
 4555             copy, 'deepcopy', mock.Mock(return_value=self.client))
 4556 
 4557         self.client.prune_deleted_snapshots()
 4558 
 4559         mock_get_deleted_snapshots.assert_called_once_with()
 4560         mock_delete_snapshot.assert_has_calls([
 4561             mock.call('fake_volume_1', 'deleted_snap_1'),
 4562             mock.call('fake_volume_2', 'deleted_snap_2'),
 4563         ], any_order=True)
 4564 
 4565     def test_get_deleted_snapshots(self):
 4566 
 4567         api_response = netapp_api.NaElement(
 4568             fake.SNAPSHOT_GET_ITER_DELETED_RESPONSE)
 4569         self.mock_object(self.client,
 4570                          'send_iter_request',
 4571                          mock.Mock(return_value=api_response))
 4572 
 4573         result = self.client._get_deleted_snapshots()
 4574 
 4575         snapshot_get_iter_args = {
 4576             'query': {
 4577                 'snapshot-info': {
 4578                     'name': 'deleted_manila_*',
 4579                     'busy': 'false',
 4580                 },
 4581             },
 4582             'desired-attributes': {
 4583                 'snapshot-info': {
 4584                     'name': None,
 4585                     'vserver': None,
 4586                     'volume': None,
 4587                 },
 4588             },
 4589         }
 4590         self.client.send_iter_request.assert_has_calls([
 4591             mock.call('snapshot-get-iter', snapshot_get_iter_args)])
 4592 
 4593         expected = {
 4594             fake.VSERVER_NAME: [{
 4595                 'name': 'deleted_manila_' + fake.SNAPSHOT_NAME,
 4596                 'volume': fake.SHARE_NAME,
 4597                 'vserver': fake.VSERVER_NAME,
 4598             }],
 4599         }
 4600         self.assertDictEqual(expected, result)
 4601 
 4602     def test_create_cg_snapshot(self):
 4603 
 4604         mock_start_cg_snapshot = self.mock_object(
 4605             self.client, '_start_cg_snapshot',
 4606             mock.Mock(return_value=fake.CG_SNAPSHOT_ID))
 4607         mock_commit_cg_snapshot = self.mock_object(
 4608             self.client, '_commit_cg_snapshot')
 4609 
 4610         self.client.create_cg_snapshot([fake.SHARE_NAME, fake.SHARE_NAME_2],
 4611                                        fake.SNAPSHOT_NAME)
 4612 
 4613         mock_start_cg_snapshot.assert_called_once_with(
 4614             [fake.SHARE_NAME, fake.SHARE_NAME_2], fake.SNAPSHOT_NAME)
 4615         mock_commit_cg_snapshot.assert_called_once_with(fake.CG_SNAPSHOT_ID)
 4616 
 4617     def test_create_cg_snapshot_no_id(self):
 4618 
 4619         mock_start_cg_snapshot = self.mock_object(
 4620             self.client, '_start_cg_snapshot', mock.Mock(return_value=None))
 4621         mock_commit_cg_snapshot = self.mock_object(
 4622             self.client, '_commit_cg_snapshot')
 4623 
 4624         self.assertRaises(exception.NetAppException,
 4625                           self.client.create_cg_snapshot,
 4626                           [fake.SHARE_NAME, fake.SHARE_NAME_2],
 4627                           fake.SNAPSHOT_NAME)
 4628 
 4629         mock_start_cg_snapshot.assert_called_once_with(
 4630             [fake.SHARE_NAME, fake.SHARE_NAME_2], fake.SNAPSHOT_NAME)
 4631         self.assertFalse(mock_commit_cg_snapshot.called)
 4632 
 4633     def test_start_cg_snapshot(self):
 4634 
 4635         self.mock_object(self.client, 'send_request')
 4636 
 4637         self.client._start_cg_snapshot([fake.SHARE_NAME, fake.SHARE_NAME_2],
 4638                                        fake.SNAPSHOT_NAME)
 4639 
 4640         cg_start_args = {
 4641             'snapshot': fake.SNAPSHOT_NAME,
 4642             'timeout': 'relaxed',
 4643             'volumes': [
 4644                 {'volume-name': fake.SHARE_NAME},
 4645                 {'volume-name': fake.SHARE_NAME_2},
 4646             ],
 4647         }
 4648 
 4649         self.client.send_request.assert_has_calls([
 4650             mock.call('cg-start', cg_start_args)])
 4651 
 4652     def test_commit_cg_snapshot(self):
 4653 
 4654         self.mock_object(self.client, 'send_request')
 4655 
 4656         self.client._commit_cg_snapshot(fake.CG_SNAPSHOT_ID)
 4657 
 4658         cg_commit_args = {'cg-id': fake.CG_SNAPSHOT_ID}
 4659 
 4660         self.client.send_request.assert_has_calls([
 4661             mock.call('cg-commit', cg_commit_args)])
 4662 
 4663     def test_create_cifs_share(self):
 4664 
 4665         self.mock_object(self.client, 'send_request')
 4666 
 4667         self.client.create_cifs_share(fake.SHARE_NAME)
 4668 
 4669         cifs_share_create_args = {
 4670             'path': '/%s' % fake.SHARE_NAME,
 4671             'share-name': fake.SHARE_NAME
 4672         }
 4673 
 4674         self.client.send_request.assert_has_calls([
 4675             mock.call('cifs-share-create', cifs_share_create_args)])
 4676 
 4677     def test_get_cifs_share_access(self):
 4678 
 4679         api_response = netapp_api.NaElement(
 4680             fake.CIFS_SHARE_ACCESS_CONTROL_GET_ITER)
 4681         self.mock_object(self.client,
 4682                          'send_iter_request',
 4683                          mock.Mock(return_value=api_response))
 4684 
 4685         result = self.client.get_cifs_share_access(fake.SHARE_NAME)
 4686 
 4687         cifs_share_access_control_get_iter_args = {
 4688             'query': {
 4689                 'cifs-share-access-control': {
 4690                     'share': fake.SHARE_NAME,
 4691                 },
 4692             },
 4693             'desired-attributes': {
 4694                 'cifs-share-access-control': {
 4695                     'user-or-group': None,
 4696                     'permission': None,
 4697                 },
 4698             },
 4699         }
 4700         self.client.send_iter_request.assert_has_calls([
 4701             mock.call('cifs-share-access-control-get-iter',
 4702                       cifs_share_access_control_get_iter_args)])
 4703 
 4704         expected = {
 4705             'Administrator': 'full_control',
 4706             'Administrators': 'change',
 4707             'Power Users': 'read',
 4708             'Users': 'no_access',
 4709         }
 4710         self.assertDictEqual(expected, result)
 4711 
 4712     def test_get_cifs_share_access_not_found(self):
 4713 
 4714         api_response = netapp_api.NaElement(fake.NO_RECORDS_RESPONSE)
 4715         self.mock_object(self.client,
 4716                          'send_iter_request',
 4717                          mock.Mock(return_value=api_response))
 4718 
 4719         result = self.client.get_cifs_share_access(fake.SHARE_NAME)
 4720 
 4721         self.assertEqual({}, result)
 4722 
 4723     @ddt.data(True, False)
 4724     def test_add_cifs_share_access(self, readonly):
 4725 
 4726         self.mock_object(self.client, 'send_request')
 4727 
 4728         self.client.add_cifs_share_access(fake.SHARE_NAME,
 4729                                           fake.USER_NAME,
 4730                                           readonly)
 4731 
 4732         cifs_share_access_control_create_args = {
 4733             'permission': 'read' if readonly else 'full_control',
 4734             'share': fake.SHARE_NAME,
 4735             'user-or-group': fake.USER_NAME
 4736         }
 4737 
 4738         self.client.send_request.assert_has_calls([
 4739             mock.call(
 4740                 'cifs-share-access-control-create',
 4741                 cifs_share_access_control_create_args)])
 4742 
 4743     @ddt.data(True, False)
 4744     def test_modify_cifs_share_access(self, readonly):
 4745 
 4746         self.mock_object(self.client, 'send_request')
 4747 
 4748         self.client.modify_cifs_share_access(fake.SHARE_NAME,
 4749                                              fake.USER_NAME,
 4750                                              readonly)
 4751 
 4752         cifs_share_access_control_modify_args = {
 4753             'permission': 'read' if readonly else 'full_control',
 4754             'share': fake.SHARE_NAME,
 4755             'user-or-group': fake.USER_NAME
 4756         }
 4757 
 4758         self.client.send_request.assert_has_calls([
 4759             mock.call(
 4760                 'cifs-share-access-control-modify',
 4761                 cifs_share_access_control_modify_args)])
 4762 
 4763     def test_remove_cifs_share_access(self):
 4764 
 4765         self.mock_object(self.client, 'send_request')
 4766 
 4767         self.client.remove_cifs_share_access(fake.SHARE_NAME, fake.USER_NAME)
 4768 
 4769         cifs_share_access_control_delete_args = {
 4770             'user-or-group': fake.USER_NAME,
 4771             'share': fake.SHARE_NAME
 4772         }
 4773 
 4774         self.client.send_request.assert_has_calls([
 4775             mock.call(
 4776                 'cifs-share-access-control-delete',
 4777                 cifs_share_access_control_delete_args)])
 4778 
 4779     def test_remove_cifs_share(self):
 4780 
 4781         self.mock_object(self.client, 'send_request')
 4782 
 4783         self.client.remove_cifs_share(fake.SHARE_NAME)
 4784 
 4785         cifs_share_delete_args = {'share-name': fake.SHARE_NAME}
 4786 
 4787         self.client.send_request.assert_has_calls([
 4788             mock.call('cifs-share-delete', cifs_share_delete_args)])
 4789 
 4790     def test_add_nfs_export_rule(self):
 4791 
 4792         mock_get_nfs_export_rule_indices = self.mock_object(
 4793             self.client, '_get_nfs_export_rule_indices',
 4794             mock.Mock(return_value=[]))
 4795         mock_add_nfs_export_rule = self.mock_object(
 4796             self.client, '_add_nfs_export_rule')
 4797         mock_update_nfs_export_rule = self.mock_object(
 4798             self.client, '_update_nfs_export_rule')
 4799 
 4800         self.client.add_nfs_export_rule(fake.EXPORT_POLICY_NAME,
 4801                                         fake.IP_ADDRESS,
 4802                                         False)
 4803 
 4804         mock_get_nfs_export_rule_indices.assert_called_once_with(
 4805             fake.EXPORT_POLICY_NAME, fake.IP_ADDRESS)
 4806         mock_add_nfs_export_rule.assert_called_once_with(
 4807             fake.EXPORT_POLICY_NAME, fake.IP_ADDRESS, False)
 4808         self.assertFalse(mock_update_nfs_export_rule.called)
 4809 
 4810     def test_add_nfs_export_rule_single_existing(self):
 4811 
 4812         mock_get_nfs_export_rule_indices = self.mock_object(
 4813             self.client, '_get_nfs_export_rule_indices',
 4814             mock.Mock(return_value=['1']))
 4815         mock_add_nfs_export_rule = self.mock_object(
 4816             self.client, '_add_nfs_export_rule')
 4817         mock_update_nfs_export_rule = self.mock_object(
 4818             self.client, '_update_nfs_export_rule')
 4819         mock_remove_nfs_export_rules = self.mock_object(
 4820             self.client, '_remove_nfs_export_rules')
 4821 
 4822         self.client.add_nfs_export_rule(fake.EXPORT_POLICY_NAME,
 4823                                         fake.IP_ADDRESS,
 4824                                         False)
 4825 
 4826         mock_get_nfs_export_rule_indices.assert_called_once_with(
 4827             fake.EXPORT_POLICY_NAME, fake.IP_ADDRESS)
 4828         self.assertFalse(mock_add_nfs_export_rule.called)
 4829         mock_update_nfs_export_rule.assert_called_once_with(
 4830             fake.EXPORT_POLICY_NAME, fake.IP_ADDRESS, False, '1')
 4831         mock_remove_nfs_export_rules.assert_called_once_with(
 4832             fake.EXPORT_POLICY_NAME, [])
 4833 
 4834     def test_add_nfs_export_rule_multiple_existing(self):
 4835 
 4836         mock_get_nfs_export_rule_indices = self.mock_object(
 4837             self.client, '_get_nfs_export_rule_indices',
 4838             mock.Mock(return_value=['2', '4', '6']))
 4839         mock_add_nfs_export_rule = self.mock_object(
 4840             self.client, '_add_nfs_export_rule')
 4841         mock_update_nfs_export_rule = self.mock_object(
 4842             self.client, '_update_nfs_export_rule')
 4843         mock_remove_nfs_export_rules = self.mock_object(
 4844             self.client, '_remove_nfs_export_rules')
 4845 
 4846         self.client.add_nfs_export_rule(fake.EXPORT_POLICY_NAME,
 4847                                         fake.IP_ADDRESS,
 4848                                         False)
 4849 
 4850         mock_get_nfs_export_rule_indices.assert_called_once_with(
 4851             fake.EXPORT_POLICY_NAME, fake.IP_ADDRESS)
 4852         self.assertFalse(mock_add_nfs_export_rule.called)
 4853         mock_update_nfs_export_rule.assert_called_once_with(
 4854             fake.EXPORT_POLICY_NAME, fake.IP_ADDRESS, False, '2')
 4855         mock_remove_nfs_export_rules.assert_called_once_with(
 4856             fake.EXPORT_POLICY_NAME, ['4', '6'])
 4857 
 4858     @ddt.data({'readonly': False, 'rw_security_flavor': 'sys'},
 4859               {'readonly': True, 'rw_security_flavor': 'never'})
 4860     @ddt.unpack
 4861     def test__add_nfs_export_rule(self, readonly, rw_security_flavor):
 4862 
 4863         self.mock_object(self.client, 'send_request')
 4864 
 4865         self.client._add_nfs_export_rule(fake.EXPORT_POLICY_NAME,
 4866                                          fake.IP_ADDRESS,
 4867                                          readonly)
 4868 
 4869         export_rule_create_args = {
 4870             'policy-name': fake.EXPORT_POLICY_NAME,
 4871             'client-match': fake.IP_ADDRESS,
 4872             'ro-rule': {
 4873                 'security-flavor': 'sys',
 4874             },
 4875             'rw-rule': {
 4876                 'security-flavor': rw_security_flavor,
 4877             },
 4878             'super-user-security': {
 4879                 'security-flavor': 'sys',
 4880             },
 4881         }
 4882         self.client.send_request.assert_has_calls(
 4883             [mock.call('export-rule-create', export_rule_create_args)])
 4884 
 4885     @ddt.data({'readonly': False, 'rw_security_flavor': 'sys', 'index': '2'},
 4886               {'readonly': True, 'rw_security_flavor': 'never', 'index': '4'})
 4887     @ddt.unpack
 4888     def test_update_nfs_export_rule(self, readonly, rw_security_flavor, index):
 4889 
 4890         self.mock_object(self.client, 'send_request')
 4891         self.client._update_nfs_export_rule(fake.EXPORT_POLICY_NAME,
 4892                                             fake.IP_ADDRESS,
 4893                                             readonly,
 4894                                             index)
 4895 
 4896         export_rule_modify_args = {
 4897             'policy-name': fake.EXPORT_POLICY_NAME,
 4898             'rule-index': index,
 4899             'client-match': fake.IP_ADDRESS,
 4900             'ro-rule': {
 4901                 'security-flavor': 'sys',
 4902             },
 4903             'rw-rule': {
 4904                 'security-flavor': rw_security_flavor,
 4905             },
 4906             'super-user-security': {
 4907                 'security-flavor': 'sys',
 4908             },
 4909         }
 4910 
 4911         self.client.send_request.assert_has_calls(
 4912             [mock.call('export-rule-modify', export_rule_modify_args)])
 4913 
 4914     def test_get_nfs_export_rule_indices(self):
 4915 
 4916         api_response = netapp_api.NaElement(fake.EXPORT_RULE_GET_ITER_RESPONSE)
 4917         self.mock_object(self.client,
 4918                          'send_iter_request',
 4919                          mock.Mock(return_value=api_response))
 4920 
 4921         result = self.client._get_nfs_export_rule_indices(
 4922             fake.EXPORT_POLICY_NAME, fake.IP_ADDRESS)
 4923 
 4924         export_rule_get_iter_args = {
 4925             'query': {
 4926                 'export-rule-info': {
 4927                     'policy-name': fake.EXPORT_POLICY_NAME,
 4928                     'client-match': fake.IP_ADDRESS,
 4929                 },
 4930             },
 4931             'desired-attributes': {
 4932                 'export-rule-info': {
 4933                     'vserver-name': None,
 4934                     'policy-name': None,
 4935                     'client-match': None,
 4936                     'rule-index': None,
 4937                 },
 4938             },
 4939         }
 4940         self.assertListEqual(['1', '3'], result)
 4941         self.client.send_iter_request.assert_has_calls([
 4942             mock.call('export-rule-get-iter', export_rule_get_iter_args)])
 4943 
 4944     def test_remove_nfs_export_rule(self):
 4945 
 4946         fake_indices = ['1', '3', '4']
 4947         mock_get_nfs_export_rule_indices = self.mock_object(
 4948             self.client, '_get_nfs_export_rule_indices',
 4949             mock.Mock(return_value=fake_indices))
 4950         mock_remove_nfs_export_rules = self.mock_object(
 4951             self.client, '_remove_nfs_export_rules')
 4952 
 4953         self.client.remove_nfs_export_rule(fake.EXPORT_POLICY_NAME,
 4954                                            fake.IP_ADDRESS)
 4955 
 4956         mock_get_nfs_export_rule_indices.assert_called_once_with(
 4957             fake.EXPORT_POLICY_NAME, fake.IP_ADDRESS)
 4958         mock_remove_nfs_export_rules.assert_called_once_with(
 4959             fake.EXPORT_POLICY_NAME, fake_indices)
 4960 
 4961     def test_remove_nfs_export_rules(self):
 4962 
 4963         fake_indices = ['1', '3']
 4964         self.mock_object(self.client, 'send_request')
 4965 
 4966         self.client._remove_nfs_export_rules(fake.EXPORT_POLICY_NAME,
 4967                                              fake_indices)
 4968 
 4969         self.client.send_request.assert_has_calls([
 4970             mock.call(
 4971                 'export-rule-destroy',
 4972                 {'policy-name': fake.EXPORT_POLICY_NAME, 'rule-index': '1'}),
 4973             mock.call(
 4974                 'export-rule-destroy',
 4975                 {'policy-name': fake.EXPORT_POLICY_NAME, 'rule-index': '3'})])
 4976 
 4977     def test_remove_nfs_export_rules_not_found(self):
 4978 
 4979         self.mock_object(self.client,
 4980                          'send_request',
 4981                          self._mock_api_error(code=netapp_api.EOBJECTNOTFOUND))
 4982 
 4983         self.client._remove_nfs_export_rules(fake.EXPORT_POLICY_NAME, ['1'])
 4984 
 4985         self.client.send_request.assert_has_calls([
 4986             mock.call(
 4987                 'export-rule-destroy',
 4988                 {'policy-name': fake.EXPORT_POLICY_NAME, 'rule-index': '1'})])
 4989 
 4990     def test_remove_nfs_export_rules_api_error(self):
 4991 
 4992         self.mock_object(self.client, 'send_request', self._mock_api_error())
 4993 
 4994         self.assertRaises(netapp_api.NaApiError,
 4995                           self.client._remove_nfs_export_rules,
 4996                           fake.EXPORT_POLICY_NAME,
 4997                           ['1'])
 4998 
 4999     def test_clear_nfs_export_policy_for_volume(self):
 5000 
 5001         mock_set_nfs_export_policy_for_volume = self.mock_object(
 5002             self.client, 'set_nfs_export_policy_for_volume')
 5003 
 5004         self.client.clear_nfs_export_policy_for_volume(fake.SHARE_NAME)
 5005 
 5006         mock_set_nfs_export_policy_for_volume.assert_called_once_with(
 5007             fake.SHARE_NAME, 'default')
 5008 
 5009     def test_set_nfs_export_policy_for_volume(self):
 5010 
 5011         self.mock_object(self.client, 'send_request')
 5012 
 5013         self.client.set_nfs_export_policy_for_volume(fake.SHARE_NAME,
 5014                                                      fake.EXPORT_POLICY_NAME)
 5015 
 5016         volume_modify_iter_args = {
 5017             'query': {
 5018                 'volume-attributes': {
 5019                     'volume-id-attributes': {
 5020                         'name': fake.SHARE_NAME,
 5021                     },
 5022                 },
 5023             },
 5024             'attributes': {
 5025                 'volume-attributes': {
 5026                     'volume-export-attributes': {
 5027                         'policy': fake.EXPORT_POLICY_NAME,
 5028                     },
 5029                 },
 5030             },
 5031         }
 5032         self.client.send_request.assert_has_calls([
 5033             mock.call('volume-modify-iter', volume_modify_iter_args)])
 5034 
 5035     def test_set_qos_policy_group_for_volume(self):
 5036 
 5037         self.mock_object(self.client, 'send_request')
 5038 
 5039         self.client.set_qos_policy_group_for_volume(fake.SHARE_NAME,
 5040                                                     fake.QOS_POLICY_GROUP_NAME)
 5041 
 5042         volume_modify_iter_args = {
 5043             'query': {
 5044                 'volume-attributes': {
 5045                     'volume-id-attributes': {
 5046                         'name': fake.SHARE_NAME,
 5047                     },
 5048                 },
 5049             },
 5050             'attributes': {
 5051                 'volume-attributes': {
 5052                     'volume-qos-attributes': {
 5053                         'policy-group-name': fake.QOS_POLICY_GROUP_NAME,
 5054                     },
 5055                 },
 5056             },
 5057         }
 5058         self.client.send_request.assert_called_once_with(
 5059             'volume-modify-iter', volume_modify_iter_args)
 5060 
 5061     def test_get_nfs_export_policy_for_volume(self):
 5062 
 5063         api_response = netapp_api.NaElement(
 5064             fake.VOLUME_GET_EXPORT_POLICY_RESPONSE)
 5065         self.mock_object(self.client,
 5066                          'send_iter_request',
 5067                          mock.Mock(return_value=api_response))
 5068 
 5069         result = self.client.get_nfs_export_policy_for_volume(fake.SHARE_NAME)
 5070 
 5071         volume_get_iter_args = {
 5072             'query': {
 5073                 'volume-attributes': {
 5074                     'volume-id-attributes': {
 5075                         'name': fake.SHARE_NAME,
 5076                     },
 5077                 },
 5078             },
 5079             'desired-attributes': {
 5080                 'volume-attributes': {
 5081                     'volume-export-attributes': {
 5082                         'policy': None,
 5083                     },
 5084                 },
 5085             },
 5086         }
 5087         self.assertEqual(fake.EXPORT_POLICY_NAME, result)
 5088         self.client.send_iter_request.assert_has_calls([
 5089             mock.call('volume-get-iter', volume_get_iter_args)])
 5090 
 5091     def test_get_nfs_export_policy_for_volume_not_found(self):
 5092 
 5093         api_response = netapp_api.NaElement(fake.NO_RECORDS_RESPONSE)
 5094         self.mock_object(self.client,
 5095                          'send_iter_request',
 5096                          mock.Mock(return_value=api_response))
 5097 
 5098         self.assertRaises(exception.NetAppException,
 5099                           self.client.get_nfs_export_policy_for_volume,
 5100                           fake.SHARE_NAME)
 5101 
 5102     def test_create_nfs_export_policy(self):
 5103 
 5104         self.mock_object(self.client, 'send_request')
 5105 
 5106         self.client.create_nfs_export_policy(fake.EXPORT_POLICY_NAME)
 5107 
 5108         export_policy_create_args = {'policy-name': fake.EXPORT_POLICY_NAME}
 5109         self.client.send_request.assert_has_calls([
 5110             mock.call('export-policy-create', export_policy_create_args)])
 5111 
 5112     def test_create_nfs_export_policy_already_present(self):
 5113 
 5114         self.mock_object(self.client,
 5115                          'send_request',
 5116                          self._mock_api_error(code=netapp_api.EDUPLICATEENTRY))
 5117 
 5118         self.client.create_nfs_export_policy(fake.EXPORT_POLICY_NAME)
 5119 
 5120         export_policy_create_args = {'policy-name': fake.EXPORT_POLICY_NAME}
 5121         self.client.send_request.assert_has_calls([
 5122             mock.call('export-policy-create', export_policy_create_args)])
 5123 
 5124     def test_create_nfs_export_policy_api_error(self):
 5125 
 5126         self.mock_object(self.client, 'send_request', self._mock_api_error())
 5127 
 5128         self.assertRaises(netapp_api.NaApiError,
 5129                           self.client.create_nfs_export_policy,
 5130                           fake.EXPORT_POLICY_NAME)
 5131 
 5132     def test_soft_delete_nfs_export_policy(self):
 5133 
 5134         self.mock_object(self.client, 'delete_nfs_export_policy')
 5135         self.mock_object(self.client, 'rename_nfs_export_policy')
 5136 
 5137         self.client.soft_delete_nfs_export_policy(fake.EXPORT_POLICY_NAME)
 5138 
 5139         self.client.delete_nfs_export_policy.assert_has_calls([
 5140             mock.call(fake.EXPORT_POLICY_NAME)])
 5141         self.assertFalse(self.client.rename_nfs_export_policy.called)
 5142 
 5143     def test_soft_delete_nfs_export_policy_api_error(self):
 5144 
 5145         self.mock_object(self.client,
 5146                          'delete_nfs_export_policy',
 5147                          self._mock_api_error())
 5148         self.mock_object(self.client, 'rename_nfs_export_policy')
 5149 
 5150         self.client.soft_delete_nfs_export_policy(fake.EXPORT_POLICY_NAME)
 5151 
 5152         self.client.delete_nfs_export_policy.assert_has_calls([
 5153             mock.call(fake.EXPORT_POLICY_NAME)])
 5154         self.assertTrue(self.client.rename_nfs_export_policy.called)
 5155 
 5156     def test_delete_nfs_export_policy(self):
 5157 
 5158         self.mock_object(self.client, 'send_request')
 5159 
 5160         self.client.delete_nfs_export_policy(fake.EXPORT_POLICY_NAME)
 5161 
 5162         export_policy_destroy_args = {'policy-name': fake.EXPORT_POLICY_NAME}
 5163         self.client.send_request.assert_has_calls([
 5164             mock.call('export-policy-destroy', export_policy_destroy_args)])
 5165 
 5166     def test_delete_nfs_export_policy_not_found(self):
 5167 
 5168         self.mock_object(self.client,
 5169                          'send_request',
 5170                          self._mock_api_error(code=netapp_api.EOBJECTNOTFOUND))
 5171 
 5172         self.client.delete_nfs_export_policy(fake.EXPORT_POLICY_NAME)
 5173 
 5174         export_policy_destroy_args = {'policy-name': fake.EXPORT_POLICY_NAME}
 5175         self.client.send_request.assert_has_calls([
 5176             mock.call('export-policy-destroy', export_policy_destroy_args)])
 5177 
 5178     def test_delete_nfs_export_policy_api_error(self):
 5179 
 5180         self.mock_object(self.client, 'send_request', self._mock_api_error())
 5181 
 5182         self.assertRaises(netapp_api.NaApiError,
 5183                           self.client.delete_nfs_export_policy,
 5184                           fake.EXPORT_POLICY_NAME)
 5185 
 5186     def test_rename_nfs_export_policy(self):
 5187 
 5188         self.mock_object(self.client, 'send_request')
 5189 
 5190         self.client.rename_nfs_export_policy(fake.EXPORT_POLICY_NAME,
 5191                                              'new_policy_name')
 5192 
 5193         export_policy_rename_args = {
 5194             'policy-name': fake.EXPORT_POLICY_NAME,
 5195             'new-policy-name': 'new_policy_name'
 5196         }
 5197         self.client.send_request.assert_has_calls([
 5198             mock.call('export-policy-rename', export_policy_rename_args)])
 5199 
 5200     def test_prune_deleted_nfs